ganley.org -> Software by Joe Ganley -> JavaScript Lisp Interpreter |
I wanted to get a feel for just how powerful JavaScript
is as a programming language (as opposed to just a scripting
language), so I sat down one evening and wrote this.
It turns out that it was quite good for this application, since it is
so flexible - dynamically sized arrays are used throughout, and
associative arrays make the symbol table quite easy.
A fairly complete set of Lisp instructions are implemented (see
below).
The choice of instructions and some of the implementations of the
composite functions were taken from Roger Rohrbach's
Lisp
in Awk interpreter.
The syntax is standard, and only integer arithmetic is available.
This is Lisp, not Scheme - scoping is dynamic.
Since this is pretty much a toy, it doesn't do much in the way of
error handling.
However, it should work on correct Lisp code; if it breaks on code you
believe to be correct, please send me mail at
joe@ganley.org.
To see the source code, just View-Source on this page; but see the
copying restrictions below.
The interpreter implements the following instructions as primitives:
(eq s1 s2 ... sn)
(< z1 z2 ... zn)
(and s1 s2 ... sn)
(cond (p1 [s1])
(p2 [s2]) ...
(pn [sn]))
(car s)
(cdr s)
(cons e s)
(atom s)
(list s1 s2 ... sn)
(quote s)
(set e s)
(eval s)
(lambda (a1 a2 ... an)
s1 s2 ... sm)
In addition, the following are defined as composite functions;
i.e. they're defined in Lisp itself as functions of the above
primitives.
(null s)
(equal x y)
(append x y)
(member e s)
(last s)
(reverse s)
(remove e s)
(mapcar f s)
(apply f s)
(len s)
(flatten s)
You are free to copy this code and modify it as you wish, provided
that (a) my header comment in the code is not removed, (b) you make
apparent as both a comment in the code and visibly on the web page
that contains it that you have modified it, and (c) the following
message appears visibly on the web page that contains the code:
(+ z1 z2 ... zn)
(- z1 z2 ... zn)
(* z1 z2 ... zn)
(/ z1 z2 ... zn)
Returns z1 {+|-|*|/}
z2 {+|-|*|/} ... {+|-|*|/}
zn.
(= s1 s2 ... sn)
Returns t if the si are all the
same object, nil otherwise.
(> z1 z2 ... zn)
Returns t if the zi are in
ascending or descending order, respectively, or nil
otherwise.
(or s1 s2 ... sn)
Returns t if the si are all
non-nil (and) or if any
si is non-nil (or).
Evaluates arguments from left to right and stops when the return value
is determined.
Evaluates the pi left to right.
When one is found to be non-nil, if the corresponding
si exists, it is returned; otherwise, the
value of pi itself is returned.
If no pi is non-nil, then nil
is returned.
Returns the first element of the list s.
If s is not a list, returns nil.
Returns the tail of the list s, i.e. s
with its first element removed.
If s is not a list, returns nil.
Returns a new list whose car is e and
whose cdr is s.
Returns t if s is an atom (i.e. not a list),
nil otherwise.
Returns a list whose elements are the (evaluated)
si.
Returns s uninterpreted.
Sets e to the evaluated value of s.
The value of e must be a symbol, i.e. [a-z][a-z0-9]*.
Evaluates s and returns the result.
When used at the head of a list, assigns the next n elements of
the list to the symbols ai and then
evaluates the si in order, returning the
value of sm.
The standard car and cdr composites
cadr, cddr, caar, cddr,
cadar, cddar, cdadr, caddr.
(not s)
Returns t if s is nil, nil
otherwise.
Tests equality, where equality of lists means structural equality, not
that they are the same object as with eq.
Appends the lists x and y.
Returns t if e is in the list
s, nil otherwise.
Returns the last element in the list s.
Returns the list s with the elements in reverse order.
Returns s with all occurences of element e
removed.
Returns a list resulting from applying the function f
to each element of s.
Calls the the function f with argument list
s.
Returns the number of elements in the list s.
Returns the flattened version of the list s, i.e. a
list containing the atoms in s in order.
Portions copyright © 1997
Joe Ganley.
The HTML code to produce this message:
Portions copyright © 1997 <A HREF="http://ganley.org/">Joe Ganley</A>.