Adding the ingredients enabling macros - &rest in argument lists,
backquote and its comma and @ syntax, the
defmacro facility, the
- was not very difficult. The result is a smmall and fast yet capable
macro system. A few examples are on the following pad:
Considering the above, it is pretty clear that this project is not expected to run some existing Lisp or Scheme code "as is". Some porting is required; many primitives may be missing, some behave differently.
In a nutshell, this project implements a flavor of lisp featuring the following.
Scoping rules are implied by the workings of execution contexts from section 10 of ECMA-262. For instance, lisp closures are lexical (with the smallest lexical scope being a JS function definition), clean and are pretty efficient in comparison to the rest of the JS runtime.
scope of the corresponding active context.
var statement and also
has scope of the corresponding active context. Left-hand side of
assignment may contain arbitrarily expressions as part of property
Atoms in lisp is everything between blanks and list
delimiters. and in this system atoms can be used
creatively. Specifically, it is possible to intentionally write
a.b.c. Another, contrived one is
a.b.c.d-x+y+z[?1:2][++p*q--/*r*/]. Casing is preserved, so
(qUote x 1) translates to
Take a look at the source of this HTML page. The lisp
system is initialized with a script include tag. After that, global
object Lisp contains the lisp functions and the translator as its
properties. The lisp functions are then exported to become available as
toplevel definitions with
Lisp.use_package(). One can
skip this step, using
Lisp as name qualifier, which
sometimes can be more appropriate.
The code that drive the interactive pads is not part of the lisp system. Yet the code shows some handy ways to invoke the translator and perhaps is reusable as well.