Go to the previous, next section.

How to get started with libguile

Here is an elementary first program, learn0, to get going with libguile. The program is in a single source file learn0.c:

#include <stdio.h>

/* the include file for guile */
#include <gscm.h>

static GSCM_status guile_init()
{
#if 0				/* don't need any of these extra packages */
  scm_init_ctax();
  scm_init_unix();
  scm_init_posix();
  scm_init_ioext();
  scm_init_gtcl();
  scm_init_gtk();
#endif /* 0 */
}

main(int argc, char *argv[])
{
  GSCM_status status;
  GSCM_top_level toplev;
  char *eval_answer;
  char input_str[200];
  int done;

  printf("hello guile\n");

  /* start a scheme interpreter */
  status = gscm_run_scm(argc, argv, 0, stdout, stderr, guile_init, 0, "#t");
  if (status != GSCM_OK) {
    fputs(gscm_error_msg(status), stderr);
    fputc('\n', stderr);
    exit(1);
  }

  /* create the top level environment */
  status = gscm_create_top_level(&toplev);
  if (status != GSCM_OK) {
    fputs(gscm_error_msg(status), stderr);
    fputc('\n', stderr);
    exit(1);
  }

  /* for fun, evaluate some simple scheme expressions here */
  status = gscm_eval_str(NULL, toplev, "(define (square x) (* x x))");
  status = gscm_eval_str(NULL, toplev, "(define (factorial n) (if (= n 1) 1 (* n (factorial (- n 1)))))");
  status = gscm_eval_str(NULL, toplev, "(square 9)");
  status = gscm_eval_str(NULL, toplev, "(factorial 100)");

  /* now sit in a scheme eval loop: I input the expressions, have guile
   * evaluate them, and then get another expression.
   */
  done = 0;
  while (!done) {
    if (gets(input_str) == NULL || strcmp(input_str, "quit") == 0) {
      done = 1;
    } else {
      status = gscm_eval_str(NULL, toplev, input_str);
    }
  }

  /* now clean up and quit */
  gscm_destroy_top_level(toplev);
  exit(0);
}

If you name this program learn0.c, it can now be compiled with:

gcc -g -I/packages/include/guile -c learn0.c -o learn0.o
gcc -o learn0 learn0.o -L/packages/lib/scm -L/packages/lib -lguile -lm

The program is simple: it creates a scheme interpreter, passes a couple of strings to it that define new scheme functions square and factorial, and then a couple of strings that invoke those functions.

It then goes into a read-eval loop, so you could type one-line scheme expressions to it and have them evaluated. For example:

<shell-prompt> ./learn0
hello guile

SLIB "2a2" on GUILE iii on UNIX 
edit GUILE ".init" to set (scheme-implementation-version) 
(IMPLEMENTATION-VICINITY) is "/packages/lib/gls/" 
type (slib:report) for configuration

learn0> (print (sin 1.3))
963.55818541719e-3 
learn0> (print (factorial 10))
3628800 
learn0> (quit)

ERROR: unbound variable:   %gscm-indirect
<shell-prompt>

You should notice the key steps involved in this learn0 program:

  1. #include <gscm.h>
  2. You need a guile_init()-like routine, which could even be trivial like the one in this example, to pass to gscm_run_scm(). This allows you to tell rscm_run_scm() which optional guile packages to use. Note that in this example I am only interested in the scheme interpreter, and not in the extra packages, so all the extra package initialization has been #if-ed out.
  3. You must invoke gscm_run_scm() and gscm_create_top_level() at the beginning of your program. This sets up the scheme interpreter to which you can then pass strings for evaluation.
  4. You pass strings to the scheme interpreter with the gscm_eval_str() routine.
  5. You quite with gscm_destroy_top_level() (which currently gives some silly error message).
  6. You link your program with -lguile.

Go to the previous, next section.