Sussman and Steele | December 22, 1975 | 35 | Implementation of the Interpreter |
so that execution can be resumed at EVLIS1
when the evaluation of the component returns with a value. It then sets up **EXP**
to point to the component to be evaluated and dispatches to AEVAL
.
(DEFUN EVLIS () (COND ((NULL **UNEVLIS**) (SETQ **EVLIS** (REVERSE **EVLIS**)) (COND ((ATOM (CAR **EVLIS**)) (SETQ **VAL** (APPLY (CAR **EVLIS**) (CDR **EVLIS**))) (RESTORE)) ((EQ (CAAR **EVLIS**) 'LAMBDA) (SETQ **ENV** (PAIRLIS (CADAR **EVLIS**) (CDR **EVLIS**) **ENV**) **EXP** (CADDAR **EVLIS**) **PC** 'AEVAL)) ((EQ (CAAR **EVLIS**) 'BETA) (SETQ **ENV** (PAIRLIS (CADR (CADAR **EVLIS**)) (CDR **EVLIS**) (CADDAR **EVLIS**)) **EXP** (CADDR (CADAR **EVLIS**)) **PC** 'AEVAL)) ((EQ (CAAR **EVLIS**) 'DELTA) (SETQ **CLINK** (CADAR **EVLIS**)) (RESTORE)) (T (ERROR '|BAD FUNCTION - EVARGLIST| **EXP** 'FAIL-ACT)))) (T (SAVEUP 'EVLIS1) (SETQ **EXP** (CAR **UNEVLIS**) **PC** 'AEVAL))))
The purpose of EVLIS1
is to gobble up the value, passed in the **VAL**
register, of the subexpression just evaluated. It saves this value on the list in the **EVLIS**
register, pops off the unevaluated subexpression from the **UNEVLIS**
register, and dispatches back to EVLIS
.
(DEFUN EVLIS1 () (SETQ **EVLIS** (CONS **VAL** **EVLIS**) **UNEVLIS** (CDR **UNEVLIS**) **PC** 'EVLIS))
Here is the code for the various AINT
s. On arrival at the instruction for an AINT
, **EXP**
contains the expression whose functional position contains the name of the AINT
. None of the arguments have been evaluated, and no new control frame has been created. Note that each AINT
is defined by the presence of an AINT
property on the property list of the LISP atom which is its name. The value of this property is the LISP
function which is the first "instruction" of the AINT
.
EVALUATE
is similar to the LISP function EVAL
; it evaluates its argument, which should result in a s-expression, which is then fed back into the SCHEME expression evaluator (AEVAL
).