The interperter

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:
– 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?