6.001/Recitation 21
Rob Speer
< 6.001
[edit]
The metacircular evaluator
You know the idea by now: we want to implement Scheme in Scheme.
Terminology for my recitations: 0-Scheme is MIT Scheme or DrScheme. It has things like 0-procedures and 0-environments in it. We'll be writing an evaluator in it which runs 1-Scheme, which has 1-procedures and 1-environments.
What we will borrow from 0-Scheme:
- The lexical parser
- Numbers
- Strings
- The symbol table (but remember that a 0-symbol is a 1-variable)
- Pairs (we're sloppy!)
What we will not borrow:
-
eval(duh) - Environments
- Procedures
- Booleans
- Why handle booleans differently than numbers or strings? Well, it doesn't take too much effort to define our own booleans, and Gerry and Hal wanted the illustrative example of having 0-booleans be different from 1-booleans.
So let's write this thing. Here's a start:
(define (eval exp env)
(cond ((self-evaluating? exp) exp)
((variable? exp) (lookup-variable-value exp env))
((quoted? exp) (text-of-quotation exp))
((assignment? exp) (eval-assignment exp env))
((definition? exp) (eval-definition exp env))
((if? exp) (eval-if exp env))
((lambda? exp)
(make-procedure (lambda-parameters exp)
(lambda-body exp)
env))
((begin? exp)
(eval-sequence (begin-actions exp) env))
((cond? exp) (eval (cond->if exp) env))
((application? exp)
(apply (eval (operator exp) env)
(list-of-values (operands exp) env)))
(else
(error "Unknown expression type -- EVAL" exp))))
Things we need to define now are:
Really easy things self-evaluating? variable? quoted? assignment? definition? if? lambda? begin? cond? application? Harder things list-of-values eval-assignment eval-definition eval-if make-procedure eval-sequence cond->if ; eh, this one is time-consuming, let's skip it apply
... plus some helper functions, presumably.
Finally, we need to make an initial environment.
[edit]
If there's time
This evaluator is not very extendable. We should rewrite it as data-directed programming.
Side benefit: we can make define-macro work! Unhygenically.
