mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-21 14:49:18 +02:00
Official chibi-scheme repository
include/chibi | ||
lib | ||
opt | ||
tests | ||
tools | ||
.hgignore | ||
eval.c | ||
gc.c | ||
main.c | ||
Makefile | ||
mkfile | ||
opcodes.c | ||
README | ||
sexp.c | ||
TODO | ||
VERSION |
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