20. THE EVALUATOR
The evaluator is the mechanism that executes LISP programs. It is the heart of any LISP implementation.
More precisely, the evaluator performs a computation on a form and returns any values that the computation produces. In order to produce the value of subforms of a list the evaluator may be called recursively on that subform.
The language specification requires that any Common LISP implementation must document its evaluation strategy. An implementation may be purely interpretive, for instance; others can be purely compiled; there is a wide middle ground between these two points which most implementations, including this one, occupy.
Furthermore, macros can be expanded as part of the evaluation process or as a completely different pass.
The language specification states that all correct programs will run in the same way irregardless of the implementations' evaluation strategy; however, incorrect programs may vary in results.
The evaluation strategy in Star Sapphire is as follows.
Macros are evaluated separately from the evaluator; it is assumed that the form submitted to the evaluator is aready completely expanded. The language specification warns that code which depends on the exact time that a macro is expanded will not be portable.
The evaluation process is two-stage. First a pass known as the canonicalizer is invoked which transforms the input form into an intermediate format. This is still a LISP form, 1) but lexical variables have been converted into a data object which specifies the stack location that the variable refers to; and 2) runtime functions have been converted into indices into a function table so that the form can be rapidly evaluated.
The second pass is the evaluator per se. This pass actually interprets the canonicalized form.
The function eval is the main user interface to the evaluator; this will run the canonicalizer and then the evaluator on a form.
eval
The following function returns t if a form always evaluates to the same thing:
constantp