car
is present but cadr
is not
since cadr
may be implemented with help of
car
and cdr
.
To implement an interpreter is then simple: just compile an interpreter written in Scheme (and add support for the global environment that is, a way to convert symbols to locations of the global variables they represent). I chose instead to implement a naive interpreter directly in Java, since this is more readable than compiled code and is far easier to explain. Unfortunately, this doubles the size of the runtime support library, making it over 3000 lines of Java.
The Jaja interpreter, the compiler and, soon, the bootstrap process (ie compiling the compiler and additional libraries) are used since fall 1996 in several lectures given at University Paris 6 and École Polytechnique. These lectures are centered on embedded languages, how to interpret them, how to compile them, how to make them use the resources of the implementation language.
In Jaja, I used different OO styles in many places to show various ways to implement some features (even inner classes): this is intentional! I also have a bunch of exercises that deal with Jaja and these finer points. These exercises propose variations around Jaja, alternate implementations, additional features, etc.
The first version of Jaja was written in Java 1.0.2. The current version uses Java 1.1.7.
Jaja may be used as a stand-alone program or as an applet. It seems to work on PC with:
You may run concurrently two instances of the Jaja applet in the same page and interact with two logically separate Scheme interpreters sharing the same immutable predefined library but not the same global mutable environment.
Here is Jaja downloaded from a jar file:
The runtime library has been weakly tested not to talk of the interpreter. However the compiler had been heavily tested. The Java source files of Jaja and its (javadoc'ed) documentation are available under the Gnu General Public License, version 2. Do you like it zipped (with sources and documentation) or jarred (with compiled classes only) ? The entire Jaja system with the compiler and tons of unrelated things may be found via online. For any of them, send bugs or remarks to Christian.Queinnec@lip6.fr .
java Jaja.Textual
or as a window-based interpreter, again from a shell (be sure to be in a directory containing the Jaja subdirectory), with:
java Jaja.FromOS
or as an applet from an html page as shown above in this very page.
You may exit from Jaja by simulating an end of file in textual mode
(usually CTRL-D) or by calling the exit
unary function.
Visit another page to stop an applet!
There is a variety of ways to load this interpreter (as an applet or a textual application, from a jar file, a zip file, a directory of individual class files, with hidden options, etc.) make difficult to test them all. Here are some hints to check if Jaja do not work.
Additional functions such as (help)
,
(oblist)
and (exit n)
are
available. The eval
and load
functions (you
may even give an url to load
remote Scheme files) are
also supported.
A recent addition is (detach fun args...)
which
detaches a thread that applies fun
on
args...
and throws away the resulting value.
(load "boot1.scm")
The interpreter does not support macro: no define
(use
set!
instead), no letrec
... But it does
support a tower of macroexpansion
interpreters with the eval-in-expansion-world
toplevel macro which allows you to define your own macroexpansion
mechanism!
To use the derived syntaxes of Scheme (named let, define, and etc.), you may use the bootm1.scm file. This file defines a macroexpansion engine (an expand function) that converts standard Scheme into the pure Scheme kernel understood by Jaja. You must load it at the macro-level ie, just say:
(eval-in-expansion-world (begin (load "boot1.scm") (load "bootm1.scm") ) )
These two files are packed in the
jar/zip distributed files from which they may be loaded. These files
are also available from the original Jaja site. Here is boot1.scm and here is bootm1.scm. Human, go away! These
files are computer-generated to be computer-readable. These files use
a uninitialized-let special form that introduces local
bindings that are initially uninitialized: they raise an error if read
before being initialized. This special form allows to define
letrec as a regular macro in Scheme.
define
, letrec
...
Soon the compiler will be available as a single, loadable file.
Other Scheme implementations in Java exist: