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?
© Copyright 2026 Paperzz