Read Sections 5.5, 5.6, and 5.7 of EOPL for background. Feel free to use the parser from the model solution if you have trouble with yours.
e ::= n | #t | #f | () | (quote x) | x | (if e e e) | (lambda (x ...) e) | (let ((x e) ...) e) | (let* ((x e) ...) e) | (e e ...)where
n
is a number, x
is a
variable, and ...
means zero or more of the previous
item. Interpret free variables from the following set
as primitives:
+ * - / = not eq? symbol? number? cons car cdr pair?(You may add to this set at your discretion.) Environments should map variables to values. Lambda-expressions should be represented as procedures.
The composition of your parser and this interpreter should be called
eval1
(that is, eval1
takes an S-expression,
parses it, and evaluates it).
eval2
.
e ::= ... | (set! x e) | (letrec ((x f) ...) e) | (begin e e ...)where
f
must be a lambda-expression.
Environments should now map variables to boxes.
The composition of your parser and this interpreter should
be called eval3
.
e ::= ... | (dynamic-let ((x e) ...) e)Variables bound by
dynamic-let
should
have dynamic extent (fluid binding). See EOPL 5.7.2.
There is no need to build a separate interpreter for part 4.
Simply include dynamic-let
in eval3
.