[plt-scheme] embedding mzscheme in c

From: George Demmy (gdemmy at member.fsf.org)
Date: Fri Mar 28 11:32:40 EST 2003

I'm looking through "Inside PLT MzScheme" (Inside) with an eye toward
embedding mzscheme into an existing c application. The current (on the
PLT website as of yesterday) version of "Inside" makes reference to
the deprecated "scheme_rep" function, as mentioned in
MzScheme_200.txt. It was a little confusing working linearly through
"Inside", but a examination of other resources turned up the answers.

Google turned up:

http://www.cs.utah.edu/plt/mailarch/plt-scheme-2001/msg00571.html

but not much else on dropping into a repl from c. I've extended the
embedding example in "Inside" to include an example of how to drop
into a repl. I've posted it here in hopes it might be useful to
someone else looking to embed mzscheme into c, and offer this as,
perhaps, a tiny contribution to the next iteration of
"Inside". Comments are welcome. If help in needed keeping this
document up-to-date, I'd be willing to help.

 From what I've seen so far, mzscheme is a *beautiful* system. Thanks!

George


To build:

* Save example as "foo.c"

* The comment at the end of the function shows how to compile and link
  the code. You may need different include and library paths to
  reflect where PLT is installed on your system. In emacs, you can
  evaluate this expression, then compile and link the example using
  "compile".

Running:

By default, the example executes a read-eval-print-loop. Given a '-c'
option, it evaluates the command line arguments that follow as scheme
expressions.

foo.c starts here:
#include <unistd.h>
#include "scheme.h"

static int
repl(void)
{
  scheme_eval(scheme_apply(scheme_builtin_value("read-eval-print-loop"),
                           0,
                           NULL),
              scheme_basic_env());
  return 0;
}

// evaluate expressions in argv, snarfed from "Inside PLT MzScheme"

static int
eval_argv(int argc, char *argv[])
{
  Scheme_Env *e = scheme_basic_env();
  Scheme_Object *curout = scheme_get_param(scheme_config,
                                           MZCONFIG_OUTPUT_PORT);
  int i;

  for (i = 0; i < argc; ++i) {
    if (scheme_setjmp(scheme_error_buf))
      return -1; // evaluation error
    scheme_display(scheme_eval_string(argv[i], e), curout);
    scheme_display(scheme_make_character('\n'), curout);
  }
  return 0;
}

int
main(int argc, char *argv[])
{
  switch (getopt(argc, argv, "c")) { // parse command line look for "-c"
  case -1:
    return repl();
  case 'c':
    return eval_argv(argc - optind, argv + optind);
  default:
    return -1;
  }
  return 0;
}

/*
  (set (make-local-variable 'compile-command)
       (mapconcat #'identity
                 '("gcc -Wall -g"
                   "-I/usr/local/plt/include"
                   "-o foo"
                   "foo.c"
                   "/usr/local/plt/lib/libmzscheme.a"
                   "/usr/local/plt/lib/libmzgc.a"
                   "-ldl -lm") ; dynamic link loader and math libs
                   " "))
*/



Posted on the users mailing list.