The interpreter
Derived Expressions (define derived? (lambda (exp) (or (if? exp) (function-definition? exp) (let? exp))))
Shallow-derive (define shallow-derive (lambda (exp) (cond ((if? exp) (if->cond exp)) ((function-definition? exp) (function-define->define exp)) ((let? exp) (let->combination exp)) (else (error ’shallow-derive "unhandled derivation: ~s" exp)))))
Recursive derivation (define (derive exp) (if (atomic? exp) exp (let ((mapped-derive-exp (map derive exp))) (if (not (derived? exp)) mapped-derive-exp (shallow-derive mapped-derive-exp)))
Concrete derivation
Cont.
let
Function-definition
Reminder
Core (applicative-substitution) Language expressions ASP The global environment Data structures+core Values Data structures+ core
We will start with the data structures, that actually do most of the work Then the core – evaluation rules will be rather easy
Values The Primitive-procedure ADT: 1. Constructor make-primitive-procedure: Attaches a tag to an implemented code argument. Type: [T -> Primitive-procedure]. 2. Identification predicate primitive-procedure?. Type: [T –> Boolean]. 3. Selector primitive-implementation: It retrieves the implemented code from a primitive procedure value. Type: [Primitive-procedure –> T].
Usage
(User) Procedure (define (make-procedure pars body) (attach-tag (cons pars body) ‘procedure)) …..
Other values (define (make-value x) (attach-tag (list x) ‘value))
Environment
frame
Initialization with primitives
Before introducing the constructor: A word on mutation So far we kept our code fully functional That is, no state required “define” is somewhat an exception, but mainly for convenience Recursive function definition is an exception to that, can be done without define, but requires fixpoint operation For implementing the global environment we want to be able to change bindings A functional solution is possible but messy We use an abstraction of mutation through the Box ADT of Dr. Racket It basically “wrappes” the object and allows (sort of ) a “pointer” to it
Global-env constructor
Defining the global-env (define the-global-environment (make-the-global-environment)) This expression is in the global scope of the interperter…
Selector:lookup
MUTATOR: add-binding!
Binding ADT
Using the environment
Eval-apply loop (applicative-eval exp) (apply-procedure proc args) Mutually recursive (why?)
eval
Eval-atomic
Lambda+definitions
If
application
Apply-primitive
substitute
“main” code of substitute
rename(exp)
“main” code of rename
Environment Model Formal algorithm Interpreter
Environment Model (Diagram)
Dynamic env-model
Interpreter for env. model What should be changed?
List of main changes ASP stays intact Data structures: Core: Support an Environment ADT Procedure ADT should include an environment pointer Core: Every eval function gets an environment as an additional parameter Uses it e.g. for lookup, and passes it on to recursive eval and apply calls apply of user procedures (closures) change to manage envs.
env
lookup
Adding binding in global env
Core:eval
Every eval now has env argument
apply-procedure
apply-procedure (cont.)
Dynamic-env interpreter What would you change?