Previous | Table of Contents | Next |
Let us consider init_scwm_procs first; it is simpler to define new functions than to add new types. Here is SCWMs 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 structureslists, 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 strings 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 |