mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-21 14:49:18 +02:00
122 lines
4.2 KiB
Text
122 lines
4.2 KiB
Text
|
|
Chibi-Scheme
|
|
--------------
|
|
|
|
Minimal Scheme Implementation for use as an Extension Language
|
|
|
|
http://synthcode.com/wiki/chibi-scheme/
|
|
|
|
|
|
Chibi-Scheme is a very small but mostly complete R5RS Scheme
|
|
implementation using a reasonably fast custom VM. Chibi-Scheme tries
|
|
as much as possible not to trade its small size by cutting corners,
|
|
and provides full continuations, both low and high-level hygienic
|
|
macros based on syntactic-closures, string ports and exceptions.
|
|
Chibi-Scheme is written in highly portable C and supports multiple
|
|
simultaneous VM instances to run.
|
|
|
|
To build, just run "make". This will provide a shared library
|
|
"libchibi-scheme", as well as a sample "chibi-scheme" command-line
|
|
repl. The "chibi-scheme-static" make target builds an equivalent
|
|
static executable.
|
|
|
|
You can edit the file config.h for a number of settings, mostly
|
|
disabling features to make the executable smaller. You can specify
|
|
standard options directly as arguments to make, for example
|
|
|
|
make CFLAGS=-Os
|
|
|
|
to optimize for size, or
|
|
|
|
make LDFLAGS=-L/usr/local/lib CPPFLAGS=-I/usr/local/include
|
|
|
|
to compile against a library installed in /usr/local.
|
|
|
|
By default Chibi uses a custom, precise, non-moving GC. You can link
|
|
against the Boehm conservative GC by editing the config file, or
|
|
directly from make with:
|
|
|
|
make USE_BOEHM=1
|
|
|
|
See the file main.c for an example of using chibi-scheme as a library.
|
|
The essential functions to remember are:
|
|
|
|
#include <chibi/eval.h>
|
|
|
|
sexp_make_eval_context(NULL, NULL, NULL)
|
|
returns a new context with a fresh stack and primitive environment
|
|
|
|
sexp_load_standard_env(context, env, version)
|
|
loads the init.scm file in primitive environment env
|
|
(version should be SEXP_FIVE)
|
|
|
|
sexp_destroy_context(context)
|
|
free a context and all associated memory
|
|
|
|
sexp_eval(context, expr, env)
|
|
evaluates an s-expression in an environment
|
|
env can be NULL to use the context's default env
|
|
|
|
sexp_eval_string(context, str)
|
|
reads an s-expression from str and evaluates it
|
|
|
|
sexp_load(context, file, env)
|
|
read and eval all top-level forms from file
|
|
|
|
sexp_context_env(context)
|
|
a macro returning the environment associated with a context
|
|
|
|
sexp_env_define(context, env, symbol, value)
|
|
define a variable in an environment
|
|
|
|
A minimal module system is provided by default. Currently you can
|
|
load the following SRFIs with (import (srfi N)):
|
|
|
|
0, 1, 2, 6, 8, 9, 11, 16, 26, 27, 33, 46, 62, 69, 98
|
|
|
|
although 0, 46 and 62 are built into the default environment so
|
|
there's no need to import them.
|
|
|
|
LOAD is extended to accept an optional environment argument, like
|
|
EVAL. You can also LOAD shared libraries in addition to Scheme source
|
|
files - in this case the function sexp_init_library is automatically
|
|
called with the following signature:
|
|
|
|
sexp_init_library(sexp context, sexp environment)
|
|
|
|
To define new primitive functions from C, use sexp_define_foreign,
|
|
which takes a Scheme environment, a name, a number of arguments the C
|
|
function takes (not counting the context argument), and a C function.
|
|
|
|
/* sexp_define_foreign(context, env, name, num_args, f) */
|
|
|
|
sexp add (sexp context, sexp x, sexp y) {
|
|
return sexp_fx_add(x, y);
|
|
}
|
|
|
|
sexp_define_foreign(context, env, "add", 2, add);
|
|
|
|
You can also define functions with a single optional argument:
|
|
|
|
sexp_define_foreign_opt(context, env, "add", 2, add, sexp_make_fixnum(1));
|
|
|
|
See the SRFI-69 implementation for more detailed examples of this.
|
|
|
|
You can define new data types with SRFI-9. This is just syntactic
|
|
sugar for the following more primitive type constructors:
|
|
|
|
(register-simple-type <name-string> <num-fields>)
|
|
=> <type-id> ; a fixnum
|
|
|
|
(make-type-predicate <opcode-name-string> <type-id>)
|
|
=> <opcode> ; takes 1 arg, returns #t iff that arg is of the type
|
|
|
|
(make-constructor <constructor-name-string> <type-id>)
|
|
=> <opcode> ; takes 0 args, returns a newly allocated instance of type
|
|
|
|
(make-getter <getter-name-string> <type-id> <field-index>)
|
|
=> <opcode> ; takes 1 args, retrieves the field located at the index
|
|
|
|
(make-setter <setter-name-string> <type-id> <field-index>)
|
|
=> <opcode> ; takes 2 args, sets the field located at the index
|
|
|