Next: GH Input/Output, Previous: Memory allocation and garbage collection, Up: GH
Many of the Scheme primitives are available in the gh_
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 R5RS. But I will point out that when a procedure takes a
variable number of arguments (such as gh_list), you should pass
the constant SCM_UNDEFINED from C to signify the end of the list.
Corresponds to the Scheme
(define name val): it binds a value to the given name (which is a C string). Returns the new object.
These correspond to the Scheme
(cons a b)and(list l0 l1 ...)procedures. Note thatgh_listis a C macro that invokesscm_listify.
... — C Function: SCM gh_car (SCM obj)
Likewise
gh_cdrthroughgh_cXr, where X can be replaced by combinations of “a” and “d” up to length four. These correspond to the Scheme(car ls),(cdr ls), etc.
Modifies the CAR of pair to be value. This is equivalent to the Scheme procedure
(set-car! ...).
Modifies the CDR of pair to be value. This is equivalent to the Scheme procedure
(set-cdr! ...).
gh_appendtakes args, which is a list of lists(list1 list2 ...), and returns a list containing all the elements of the individual lists.A typical invocation of
gh_appendto append 5 lists together would begh_append(gh_list(l1, l2, l3, l4, l5, SCM_UNDEFINED));The functions
gh_append2,gh_append2,gh_append3andgh_append4are convenience routines to make it easier for C programs to form the list of lists that goes as an argument togh_append.
Returns a new list that has the same elements as ls but in the reverse order. Note that this is implemented as a macro which calls
scm_reverse.
These functions return the first sublist of ls whose CAR is x. They correspond to
(memq x ls),(memv x ls)and(member x ls), and hence use (respectively)eq?,eqv?andequal?to do comparisons.If x does not appear in ls, the value
SCM_BOOL_F(not the empty list) is returned.Note that these functions are implemented as macros which call
scm_memq,scm_memvandscm_memberrespectively.
These functions search an association list (list of pairs) alist for the first pair whose CAR is x, and they return that pair.
If no pair in alist has x as its CAR, the value
SCM_BOOL_F(not the empty list) is returned.Note that these functions are implemented as macros which call
scm_assq,scm_assvandscm_assocrespectively.
These correspond to the Scheme
(make-vector n fill),(vector a b c ...)(vector-ref v i)(vector-set v i value)(vector-length v)(list->vector ls)procedures.The correspondence is not perfect for
gh_vector: this routine takes a list ls instead of the individual list elements, thus making it identical togh_list_to_vector.There is also a difference in gh_vector_length: the value returned is a C
unsigned longinstead of an SCM object.
Get the given element from a uniform vector v; ilist is a list (or possibly a single integer) of indices, and its length is the dimension of the uniform vector.
Return a newly allocated list of the objects contained in the elements of vector.
Call the Scheme procedure proc, with the elements of args as arguments. args must be a proper list.
Call the Scheme procedure proc with no arguments (
gh_call0), one argument (gh_call1), and so on. You can get the same effect by wrapping the arguments up into a list, and callinggh_apply; Guile provides these functions for convenience.
Corresponds to the Scheme
catchandthrowprocedures, which in Guile are provided as primitives.
[TODO] gh_standard_handler(void *data, SCM tag, SCM throw_args)
These correspond to the Scheme
eq?,eqv?andequal?predicates.
The GH interface can access the Guile top-level obarrays directly, or consult the module system in various ways. See the hello-guile program for a working example of the following two functions:
Look up a symbol with a given name sname in the Guile top-level, and return the object to which it is bound, or
SCM_UNDEFINED.
Look up a symbol with a given name in module m, which may be a vector (obarray implementation satisfying
SCM_VECTORP), a list of symbols, a string that can bescm_readas a list of symbols, or #f. In the latter case, consult the Guile top-level and return the object to which the symbol is bound. In the other cases, usescm_module_refon a list of symbols (constructed if necessary) and return the value of the given name in the module named by that list. Signal error if either the specified module is not loaded, or if the given name is not found in the module.
/* hello-guile.c --- list features one per line or lookup variable values
*
* Copyright (C) 2002, 2007, 2008 Thien-Thi Nguyen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/* Usage: hello-guile
Usage: hello-guile VARIABLE
Usage: hello-guile -m MODULE VARIABLE
Usage: hello-guile -l MODULE VARIABLE
This example basically shows how to use gh_lookup and gh_module_lookup,
as well as the gh_enter booting mechanism (there are others). The intent
is to stay within the "GH" interface.
The "-m" option looks for VARIABLE in MODULE (but note that if MODULE is
not loaded an error is signalled). The "-l" variant loads MODULE first
before doing the lookup. See Makefile.am rule `installcheck-local' in this
directory for example invocations. */
#include <stdlib.h>
#include <string.h>
#include <guile/gh.h>
static void
hello_guile (int argc, char **argv)
{
if (1 == argc)
{
SCM features = gh_lookup ("*features*");
while (! gh_null_p (features))
{
gh_display (gh_car (features));
gh_newline ();
features = gh_cdr (features);
}
}
else
{
char *modulename = "(guile-user)";
int idx = 1;
/* Handle "-m MODULE" option. */
if ('-' == argv[1][0] && 'm' == argv[1][1])
{
modulename = argv[2];
idx += 2;
}
/* Handle "-l MODULE" option. */
if ('-' == argv[1][0] && 'l' == argv[1][1])
{
char *use_modules = malloc (255 + strlen (argv[2]));
sprintf (use_modules, "(use-modules %s)", argv[2]);
gh_eval_str (use_modules);
modulename = argv[2];
idx += 2;
}
gh_display (gh_module_lookup (gh_str02scm (modulename), argv[idx]));
gh_newline ();
}
}
int
main (int argc, char **argv)
{
gh_enter (argc, argv, hello_guile);
return EXIT_SUCCESS; /* never reached */
}
/* hello-guile.c ends here */