Steele and Sussman
46
The Art of the Interpreter
(DEFINE (EVAL EXP ENV)
(COND ((ATOM EXP)
(COND ((NUMBERP EXP) EXP)
(T (VALUE EXP ENV))))
((EQ (CAR EXP) 'QUOTE)
(CADR EXP))
((EQ (CAR EXP) 'LAMBDA)
(LIST '&PROCEDURE (CADR EXP) (CADDR EXP) ENV))
((EQ (CAR EXP) 'SETQ)
(EVSETQ (CADR EXP) (EVAL (CADDR EXP) ENV) ENV))
((EQ (CAR EXP) 'PROGN)
(EVPROGN (CDR EXP) ENV NIL))
((EQ (CAR EXP) 'COND)
(EVCOND (CDR EXP) ENV))
(T (APPLY (EVAL (CAR EXP) ENV)
(EVLIS (CDR EXP) ENV)
ENV))))
(DEFINE (APPLY FUN ARGS ENV)
(COND ((PRIMOP FUN) (PRIMOP-APPLY FUN ARGS))
((EQ (CAR FUN) '&PROCEDURE)
(EVAL (CADDR FUN)
(BIND (CADR FUN) ARGS (CADDDR FUN))))
((EQ (CAR FUN) 'LAMBDA)
(EVAL (CADDR FUN)
(BIND (CADR FUN) ARGS ENV)))
(T (ERROR))))
For VALUE
, LOOKUP
, and BIND
see Figure 3.
For EVCOND
and EVLIS
see see Figure 5.
For LOOKUP1
see Figure 10 (not Figure 3).
Figure 14
Interpreter with Both Open and Closed Procedures
Although this is the tradition, it doesn't work very well. The problem is that the lexical variables are not really lexical. Although lexical references cannot incorrectly refer to dynamically intended bindings, the reverse is not true. Dynamic variable references can be captured by bindings intended to be strictly lexical.
For example, we might want to write a procedure which packages up information about dealing with RADIX
:
(DEFINE (RADIX-10 FUN)
((LAMBDA (RADIX) (FUN))
10.))