The actual interpreter has been completed and "hooks" for the addition of game logic commands and variables have been added so expansion is painless. Garbage collection is done by periodically copying all relevant data and discarding the rest; this eliminates the problems with cycle detection that plague other implementations, and also keeps the system from leaking memory in the "What, me worry?" implementation.
The interpreter has been wholly rewritten to improve speed and memory usage.
The binding system was before more LISP-like, in that symbols were bound locally; now, symbols are bound globally through a pre-execution stage that sets the bindings the first time a variable or abstraction is executed.
Main aspects of future work include integrating the large integer routines into the interpreter and actually attaching the interpreter to the client and server software to allow for control of game logic.
An environment consists of a series of frames. There is a top-level frame which contains bindings from top-level variable names to data and which has no parent; subsequent frames also contain bindings from variable names to data, but also have parent frames whose data are also avaiable to objects with access to those frames, thus facilitating the idea of scope.
For example, the following code fragment:
(let* ((a 5)
(b (fun (a) (+ a 1))))
would produce a frame X containing the bindings a:5 and b:(fun...). Furthermore, when (b 2) is evaluated, a new frame Y is created, whose parent is X, and where the parameter a is bound to 2. Thus, when the expression (+ a 1) is evaluated, a is bound to 2 -- not 5 -- in Y, since the closest binding is used, and thus the expression evaluates to 3 instead of 6.
Garbage collection is an issue with any LISP or Scheme-like language. Reference counters cannot be used in Turing-complete versions, since cycles among frames can occur; thus, a method of cycle-detection or some other type of garbage collection must be used. R&D into this is occuring at this time.