The Guile interpreter is essentially Aubrey Jaffer's SCM interpreter (see section `Overview' in SCM: a portable scheme interpreter) with some modifications to make it suitable as an embedded interpreter.
Part of the modification has been to provide a restricted interface to
limit access to the SCM internals; this is called the gscm_
interface, or libguile interface.
If you are programming with Guile, you should only use the C
subroutines described in this manual, which all begin with
gscm_.
If instead you are extending Guile, you have the entire SCM source to play with. This manual will not help you at all, but you can consult Aubrey Jaffer's SCM manual (see section `Internals' in SCM: a portable scheme interpreter).
If you are adding a module to Guile, I recommend that you stick
to the gscm_ interface: this interface is guaranteed to not
change drastically, while the SCM internals might change as Guile is
developed.
To use libguile, you must have the following toward the beginning of your C source:
#include <guile/gscm.h>
When you link, you will have to add at least -lguile to the list
of libraries. If you are using more of Guile than the basic scheme
interpreter, you will have to add more libraries.
-lgtcltk -ltk4.1 -ltcl7.5
-lX11.
-lgoonix.
-lthreads.
If you use these extra packages, make sure you look at section Starting and controlling the interpreter: it will show you what startup code you need to initialize each of these extra libraries.
The following C constants and data types are defined in libguile:
gscm_ routines. Its value is meant
to be interpreted by gscm_error_msg() if it is not
GSCM_OK.
gscm_ calls when there was no error.
In almost every case, your first gscm_ call will be
init_proc() is invoked to initialize particular Guile
packages.
This next batch of routines are the ones that can be included in the
routine init_proc() passed to gscm_run_scm.
After initializing the interpreter with gscm_run_scm, you need to
create a top level. The top level variable you obtain will be
used for most future libguile calls.
At the end, when you are done with scheme, you can invoke:
If a routine returns a value of type GSCM_status, we can get a
human-readable representation of what the error condition was by
invoking:
gscm_error_msg. Here's the typical example of the use of
GSCM_status:
status = gscm_some_function_returning_status(...);
if (status != GSCM_OK) {
fputs(gscm_error_msg(status), stderr);
fputc('\n', stderr);
exit(1);
}
Here is how the various possible error codes are defined in `gscm.h':
#define GSCM_OK 0 #define GSCM_QUIT 1 #define GSCM_RESTART 2 #define GSCM_ILLEGALLY_REENTERED 3 #define GSCM_OUT_OF_MEM 4 #define GSCM_ERROR_OPENING_FILE 5 #define GSCM_ERROR_OPENING_INIT_FILE 6
Once you have an interpreter running, and you have created a top level environment, you can ask the interpreter to evaluate scheme code. There are two calls that implement this:
malloc-ed by gscm_eval_str, so after using
the value of *answer, you should free it. If answer is
NULL, the evaluation result is not returned to the caller
Also note that the line of code in scheme_code must be a well
formed scheme expression. If you have many lines of code you must
either concatenate them into one string, or use gscm_eval_file().
gscm_eval_str(), except that a whole file
is evaluated instead of a string.
The real interface between C and scheme comes when you can write new scheme procedures in C. This is done through the routine
(*fn)(). The scheme procedure will require req arguments,
and accept opt optional arguments. The procedure will be
documented by the documentation string doc. [Note: it is not yet
clear how documentation strings will evolve in Guile.]
There are several important considerations to be made when writing the C routine (*fn)().
First of all the C routine has to return type SCM.
Second, all arguments passed to the C funcion will be of type
SCM.
Third: the C routine is now subject to scheme flow control, which means that it could be interrupted at any point, and then reentered. This means that you have to be very careful with operations such as allocating memory, modifying static data ...
Fourth: to get around the latter issue, you can use
GSCM_DEFER_INTS and GSCM_ALLOW_INTS.
Guile provides mechanisms to convert data between C and scheme. This
allows new builtin procedures to understand their arguments (which are
of type SCM) and return values of type SCM.
#f if x is zero, #t otherwise.
Note the distinction between the str and str0: the former returns with C null-terminated strings; the latter returns a scheme string.
Also note that the string procedures take a pointer to the scheme object obj, and that they return the string in a volatile location *str_out.
Many of the scheme primitives are available in the gscm_
interface; they take and return objects of type SCM, and one could
basically use them to write C code that mimics scheme code.
I will list these routines here without much explanation, since what
they do is the same as documented in section `Standard Procedures' in R4RS. But I will point out that when a procedure takes a
variable number of arguments (such as gscm_list), you should pass
the constant SCM_EOL from C to signify the end of the list.
(define name val): it binds a value to
the given name (which is a C string).
(cons a b) and (list l0 l1
...) procedures.
(set-car! ...) and (set-cdr!
...) procedures.
(caadar ls) procedures etc ...
(vector n fill), (vref v i)
and (vset v i value) procedures.
(lambda (...) (...)); the second curries a procedure by fixing
the first argument.
(apply proc args ...)
catch and throw procedures,
which in Guile are provided as primitives.
eq?, eqv? and equal?
predicates.