Previous Table of Contents Next


4.4.1. Adding Functions to Guile

Let us consider init_scwm_procs first; it is simpler to define new functions than to add new types. Here is SCWM’s code, abbreviated:

     void
     init_scwm_procs(void)
     {
       …
       gh_new_procedure(“bind-key”, bind_key, 3, 0, 0);
       …
       gh_new_procedure(“get-window”, get_window, 0, 3, 0);
       …
       gh_new_procedure(“raise-window”, raise_window, 0, 1, 0);
       gh_new_procedure(“lower-window”, lower_window, 0, 1, 0);
       …
       gh_new_procedure(“iconify”, iconify, 0, 1, 0);
       gh_new_procedure(“deiconify”, deiconify, 0, 1, 0);
       gh_new_procedure(“iconified?”, iconified_p, 0, 1, 0);
       …
       gh_new_procedure(“menu?”, menu_p, 1, 0, 0);
       gh_new_procedure(“color?”, color_p, 1, 0, 0);
       gh_new_procedure(“font?”, font_p, 1, 0, 0);
       gh_new_procedure(“window?”, window_p, 1, 0, 0);
       …
     }

The init_scwm_procs function is actually much longer and consists entirely of calls to gh_new_procedure similar to those shown; I selected a few familiar or interesting entries to show here.

As a simple example, consider the following line:

     gh_new_procedure(“lower-window”, lower_window, 0, 1, 0);

This defines a new Scheme function called lower-window, implemented by the C function lower_window. The new Scheme function takes no required arguments and one optional argument and does not accept “rest” arguments. Thus, the Scheme expression (lower-window w) causes Guile to call the C function lower_window with the value of w as its sole argument. The complete code for lower_window is as follows, with annotations:

     /* The SCM type represents a Scheme value.  */
     SCM
     lower_window(SCM win)
     {
      /* Ensure that this function will not be interrupted by the user.  */
      SCM_REDEFER_INTS;

      /* Make sure argument is a valid window object, or was omitted;
         otherwise, raise an error. If omitted, set win to the current
         window. Include the name of this function in the error message. */
      VALIDATE(win, “lower-window”);

      /* win is a Scheme value; extract the pointer to the SCWM window
         structure from win, then call the function to lower window.  */
         LowerWindow(SCWMWINDOW(win));

      /* Allow interrupts again. */
      SCM_REALLOW_INTS;

      /* SCM_BOOL_T is the Scheme it value.  */
      return SCM_BOOL_T;
     }

Notice that, although Guile ensures that the function is passed the correct number of arguments, the function itself must check the types of its arguments. Because Scheme is a dynamically typed language, each value carries an indication of its type; the VALIDATE macro uses that typing information to assure that the argument to lower-window is plausible, and the SCWMWINDOW macro strips it off to yield a pointer to the underlying SCWM window structure. The other functions declared in init_scwm_procs are generally more complex than lower_window, but they have the same essential structure.

The C code of a Guile-based application frequently wants to operate on ordinary Scheme data structures—lists, vectors, symbols, and so on. Guile provides C functions to perform every operation available at the Scheme level and often provides C code direct access to the internal representations. For example, given a Scheme string, the Guile SCM_LENGTH macro returns its length, and the SCM_CHARS macro returns a pointer to the string’s contents, an array of characters. Most of the standard Scheme procedures are implemented by C functions, visible to Guile clients; for example, applications can call the C function scm_cons, which is the underlying implementation of the Scheme procedure cons.


Previous Table of Contents Next