Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

Similar presentations


Presentation on theme: "1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can."— Presentation transcript:

1 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can be utilized to gain further improvements that cannot be achieved using the substitution model (The analyzer/compiler) Env. model evaluator: Motivation

2 Env. model evaluator: Structure and implementation Data Structures: New data structures: frame, environment Additional procedures are added to handle the new ADTs A closure keeps the Env in which it was created. Renaming and substitution are no longer needed! ASP Derived expressions Test Data structures Utils A racket lib Proc / Primitive-Proc. Global Environment. Op. semantics (evaluation rules) Special forms ADT per expressions An abstraction barrier Used by all evaluators Parser substitution values Core

3 Env. model evaluator: Structure and implementation ASP Derived expressions Test Data structures Utils A racket lib Proc / Primitive-Proc. Global Environment. Op. semantics (evaluation rules) Special forms ADT per expressions An abstraction barrier Used by all evaluators Parser substitution values Core Core: Procedure application (apply procedure) and evaluation of expressions are done with respect to a certain environment. Tests: Updated accordingly.

4 4 Env. model evaluator: Structure and implementation Box, unbox: The global environment may change (E.g., by definitions). Values that may change should be boxed (similar to pointers). # + Binding: implemented as a Pair A correspondence between a variable and its value. ‘((x foo) (4 )) A substitution from variables to values. Each variable is bound to a single value. Frame: Implemented as a substitution

5 5 Environment: Implemented as a list of boxed frames A finite sequence of frames in which the last frames is the-global-environment. Env. model evaluator: Structure and implementation … … E1 box-pointer diagram: frame t-g-e ‘((foo …) ( )) ‘((+ - …) (prim+ prim- …)) box proc paramsbody frame E2 E3

6 6 Env. model evaluator: Evaluation examples (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env)) ((application? exp) (apply-procedure (env-eval (operator exp) env) (list-of-values (operands exp) env))) (else (error 'eval "unknown expression type: ~s" exp))))) (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env)) ((application? exp) (apply-procedure (env-eval (operator exp) env) (list-of-values (operands exp) env))) (else (error 'eval "unknown expression type: ~s" exp))))) Reminder: env-eval (interpreter-core.rkt)

7 7 Env. model evaluator: Evaluation examples 1. Evaluating a definition expression: (define eval-special-form (lambda (exp env) (cond... ((definition? exp) (if (not (eq? env t-g-e)) (error 'eval "non global definition: ~s" exp) (eval-definition exp)))...))) (define eval-special-form (lambda (exp env) (cond... ((definition? exp) (if (not (eq? env t-g-e)) (error 'eval "non global definition: ~s" exp) (eval-definition exp)))...))) (define eval-definition (lambda (exp) (add-binding! (make-binding (definition-variable exp) (env-eval (definition-value exp) t-g-e))) 'ok)) (define eval-definition (lambda (exp) (add-binding! (make-binding (definition-variable exp) (env-eval (definition-value exp) t-g-e))) 'ok)) (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env))...))) (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env))...))) > (env-eval (derive '(define f (lambda (x) (lambda (y) (+ x y))))) t-g-e)

8 8 Env. model evaluator: Evaluation examples (define eval-special-form (lambda (exp env) (cond... ((lambda? exp) (eval-lambda exp env))...))) (define eval-special-form (lambda (exp env) (cond... ((lambda? exp) (eval-lambda exp env))...))) > (env-eval (derive '(define f (lambda (x) (lambda (y) (+ x y))))) t-g-e) (define eval-lambda (lambda (exp env) (make-procedure (lambda-parameters exp) (lambda-body exp) env))) (define eval-lambda (lambda (exp env) (make-procedure (lambda-parameters exp) (lambda-body exp) env))) (define make-procedure (lambda (parameters body env) (attach-tag (list parameters body env) 'procedure))) (define make-procedure (lambda (parameters body env) (attach-tag (list parameters body env) 'procedure))) (make-procedure '(x) '(lambda (y) (+ x y)) t-g-e) P: x B: (lambda (y) (+ x y)) t-g-e 1. Evaluating a definition expression: Textual annotation: @t-g-e

9 9 Env. model evaluator: Evaluation examples > (env-eval (derive '(define f (lambda (x) (lambda (y) (+ x y))))) t-g-e) (add-binding! (make-binding ‘f @t-g-e)) 1. Evaluating a definition expression: (define eval-special-form (lambda (exp env) (cond... ((definition? exp) (if (not (eq? env t-g-e)) (error 'eval "non global definition: ~s" exp) (eval-definition exp)))...))) (define eval-special-form (lambda (exp env) (cond... ((definition? exp) (if (not (eq? env t-g-e)) (error 'eval "non global definition: ~s" exp) (eval-definition exp)))...))) (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env))...))) (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env))...))) (define eval-definition (lambda (exp) (add-binding! (make-binding (definition-variable exp) (env-eval (definition-value exp) t-g-e))) 'ok)) (define eval-definition (lambda (exp) (add-binding! (make-binding (definition-variable exp) (env-eval (definition-value exp) t-g-e))) 'ok)) Done!

10 10 Env. model evaluator: Evaluation examples 2. Evaluating a user procedure: (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env))...))) (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env))...))) > (derive-eval 'f) (define eval-atomic (lambda (exp env) (if (or (number? exp) (boolean? exp) (null? exp)) exp (lookup-variable-value exp env)))) (define eval-atomic (lambda (exp env) (if (or (number? exp) (boolean? exp) (null? exp)) exp (lookup-variable-value exp env)))) > @t-g-e

11 x: 1 GE 11 Env. model evaluator: Evaluation examples 3. Evaluating an application of a user procedure: > (derive-eval '(define g (f 1)) ) (apply-procedure @t-g-e (1)) Create a new frame where x maps to 1 (make-frame ‘(x) ‘(1)) Extend the environment (extend-env new-frame t-g-e) Evaluate the body (eval-sequence body new-env)

12 12 Can be regarded as a nested let expression. Similar to let, but each defined variable can be used in subsequent definitions. > (let ((a 1) (c (* a 2))) (+ a c)) > (define a 10) Env. model evaluator: Supporting let* Reminder: What is a let* expression? Example: > (let* ((a 1) (c (* a 2))) (+ a c)) > (let* ((a 1) (c (* a 2))) (+ a c)) > (let ((a 1)) (let ((c (* a 2))) (+ a c))) > (let ((a 1)) (let ((c (* a 2))) (+ a c))) > ((λ (a) ((λ (c) (+ a c)) (* a 2)) 1) > ((λ (a) ((λ (c) (+ a c)) (* a 2)) 1) > 3 = = > 21

13 13 An expression (let* ((v 1 e 1 ) (v 2 e 2 ) … (v n e n )) b 1 b 2 … b m ), with respect to environment E0, is defined as follows: E 1 E 0 * make-frame [(v 1 ),(env-eval e 1 E 0 )] E 2 E 1 * make-frame [(v 2 ),(env-eval e 2 E 1 )]... E n E n-1 * make-frame [(v n ),(env-eval e n E n-1 )] (env-eval b 1 E n )... (env-eval b m-1 E n ) Return (env-eval b m E n ) Q: How would the evaluation rule for let look like? A: e 1 …e n will be evaluated with respect to E 0. A new frame mapping (v 1 …v n ) to (e 1 …e n ) will extend E 0, creating a new environment, E 1. Evaluation rule for a let* expression: Env. model evaluator: Supporting let*

14 14 Env. model evaluator: Supporting let* - as a derived expression 1. Add the required ADT procedures to the ASP (let* ((v 1 e 1 ) (v 2 e 2 ) … (v n e n )) b 1 b 2 … b m ) ASP Derived expressions Core Data structures (define let*? (lambda (exp) (tagged-by? exp 'let*))) (define let*-initial-values (lambda (exp) (map cadr (let*-bindings exp)))) (define let*-initial-values (lambda (exp) (map cadr (let*-bindings exp)))) (define let*-bindings (lambda (exp) (car (get-content exp)))) (define let*-bindings (lambda (exp) (car (get-content exp)))) (define let*-body (lambda (exp) (cdr (get-content exp)))) (define let*-body (lambda (exp) (cdr (get-content exp)))) (define let*-variables (lambda (exp) (map car (let*-bindings exp)))) (define let*-variables (lambda (exp) (map car (let*-bindings exp)))) (define make-let* (lambda (bindings body) (attach-tag (cons bindings body) 'let*))) (define make-let* (lambda (bindings body) (attach-tag (cons bindings body) 'let*))) (define (let*-first-variable exp) (caar (let*-bindings exp))) (define (let*-first-variable exp) (caar (let*-bindings exp))) (define (let*-first-initial-value exp) (cadar (let*-bindings exp))) (define (let*-first-initial-value exp) (cadar (let*-bindings exp))) (define (make-let*-bindings vars vals) (map list vars vals)) (define (make-let*-bindings vars vals) (map list vars vals))

15 15 Env. model evaluator: Supporting let* - as a derived expression 2. Modify the procedure derived? (define (derived? exp) (or (cond? exp) (function-definition? exp) (let? exp) (let*? exp))) (define (derived? exp) (or (cond? exp) (function-definition? exp) (let? exp) (let*? exp))) (define (shallow-derive exp) (cond ((cond? exp) (cond->if exp))... ((let*? exp) (let*->nested-let exp)) (else (error "Unhandled " exp)))) (define (shallow-derive exp) (cond ((cond? exp) (cond->if exp))... ((let*? exp) (let*->nested-let exp)) (else (error "Unhandled " exp)))) 3. Modify the procedure shallow-derive (let* ((v 1 e 1 ) (v 2 e 2 ) … (v n e n )) b 1 b 2 … b m ) ASP Derived expressions Core Data structures

16 16 Env. model evaluator: Supporting let* - as a derived expression Q: The result is a let exp. Shouldn’t it be further derived? A: Nah, derive recursively calls itself until the result exp does not change. Q: What about the let* expression created by make-let*? A: Nope. derive is recursively called for all sub expressions. Q: When the if-condition does not hold, we wrap the body parameter in a list. Why? A: Since the body of a let expression may consist of several expressions. 4. Add a translation procedure let*->nested-let (define (let*->nested-let exp) (let ((bindings (let*-bindings exp)) (body (let*-body exp))) (if (null? bindings) (make-lambda '() body) (if (null? (cdr bindings)) (make-let bindings body) ;dit (make-let ;dif (make-let*-bindings (list (let*-first-variable exp)) (list (let*-first-initial-value exp))) (list (make-let* (cdr bindings) body)) ))))) (define (let*->nested-let exp) (let ((bindings (let*-bindings exp)) (body (let*-body exp))) (if (null? bindings) (make-lambda '() body) (if (null? (cdr bindings)) (make-let bindings body) ;dit (make-let ;dif (make-let*-bindings (list (let*-first-variable exp)) (list (let*-first-initial-value exp))) (list (make-let* (cdr bindings) body)) ))))) (let*->nested-let (derive

17 17 Env. model evaluator: Supporting let* - as a special form 1. Add the required ADT procedures to the ASP (let* ((v 1 e 1 ) (v 2 e 2 ) … (v n e n )) b 1 b 2 … b m ) ASP Derived expressions Core Data structures DONE

18 18 (define (special-form? exp) (or (quoted? exp) (lambda? exp) (definition? exp) (if? exp) (begin? exp) (let*? exp))) (define (special-form? exp) (or (quoted? exp) (lambda? exp) (definition? exp) (if? exp) (begin? exp) (let*? exp))) (define (eval-special-form exp env) (cond ((quoted? exp) (text-of-quotation exp)) ((lambda? exp) (eval-lambda exp env)) … ((let*? exp) (eval-let* exp env)))) (define (eval-special-form exp env) (cond ((quoted? exp) (text-of-quotation exp)) ((lambda? exp) (eval-lambda exp env)) … ((let*? exp) (eval-let* exp env)))) (let* ((v 1 e 1 ) (v 2 e 2 ) … (v n e n )) b 1 b 2 … b m ) ASP Derived expressions Core Data structures Env. model evaluator: Supporting let* - as a special form 2. Modify the procedure special-form? 3. Modify eval-special-form

19 19 (define (eval-let* exp env) (let ((vars (let*-variables exp)) (vals (let*-initial-values exp)) (body (let*-body exp))) (letrec ((helper (lambda (vars-lst vals-lst env) (if (null? vars-lst) (eval-sequence body env) (helper (cdr vars-lst) (cdr vals-lst) (extend-env (make-frame (list (car vars-lst)) (list (env-eval (car vals-lst) env))) env)))))) (helper vars vals env)))) (define (eval-let* exp env) (let ((vars (let*-variables exp)) (vals (let*-initial-values exp)) (body (let*-body exp))) (letrec ((helper (lambda (vars-lst vals-lst env) (if (null? vars-lst) (eval-sequence body env) (helper (cdr vars-lst) (cdr vals-lst) (extend-env (make-frame (list (car vars-lst)) (list (env-eval (car vals-lst) env))) env)))))) (helper vars vals env)))) Env. model evaluator: Supporting let* - as a special form 4. Add the procedure eval-let*, direct approach: Extend the environment with a new frame per variable. When no variables remain, evaluate the body.

20 20 (define (eval-let* exp env) (let ((body (let*-body exp))) (if (null? (let*-bindings exp)) (eval-sequence body env) (let ((first-var (let*-first-variable exp)) (first-val (let*-first-initial-value exp)) (rest-bindings (let*-rest-bindings exp))) (eval-let* (make-let* rest-bindings body) (extend-env (make-frame (list first-var) (list (env-eval first-val env))) env) ))))) (define (eval-let* exp env) (let ((body (let*-body exp))) (if (null? (let*-bindings exp)) (eval-sequence body env) (let ((first-var (let*-first-variable exp)) (first-val (let*-first-initial-value exp)) (rest-bindings (let*-rest-bindings exp))) (eval-let* (make-let* rest-bindings body) (extend-env (make-frame (list first-var) (list (env-eval first-val env))) env) ))))) Env. model evaluator: Supporting let* - as a special form 4. Add the procedure eval-let*, code generation approach:

21 21 Env. model Compiler: Motivation (define length (lambda (lst) (if (null? lst) 0 (* 1 (length (cdr lst)))))) (define length (lambda (lst) (if (null? lst) 0 (* 1 (length (cdr lst)))))) Special form? What is * ? What’s fact? Each time fact is called, the interpreter: Uses the ASP to identify the body as an if exp, Extracts the required components for evaluation, Looks-up variables, etc. To avoid repeated analysis, the compiler: Analyzes a given expression in static (compilation) time. Returns a procedure that awaits an environment argument. Once applied, it evaluates the analyzed expression with respect to the given environment. No further Analysis is performed!

22 22 Using the compiler, we distinguish analysis from evaluation. The compiler returns a procedure ready for execution. Given an env, the procedure will compute the analyzed code with respect to that env. No analysis is performed during computation. (define env-eval (lambda (exp env) )) (define env-eval (lambda (exp env) )) (define analyze (lambda (exp) (lambda (env) ))) (define analyze (lambda (exp) (lambda (env) ))) Env. model Compiler: Introduction env-eval: [Exp*Env->Scheme-Type] compiler: [Exp->[Env->Scheme-Type] Interpreter vs Compiler:

23 (define (analyze exp) (cond ((atomic? exp) (analyze-atomic exp)) ((special-form? exp) (analyze-special-form exp)) ((application? exp) (analyze-application exp)) (else (error "Unknown expression type -- EVAL“ exp)))) (define (analyze exp) (cond ((atomic? exp) (analyze-atomic exp)) ((special-form? exp) (analyze-special-form exp)) ((application? exp) (analyze-application exp)) (else (error "Unknown expression type -- EVAL“ exp)))) Env. model Compiler: Comparing with env-eval The analyze procedure: Handling an if expression: (define eval-if (lambda (exp env) (if (true? (env-eval (if-predicate exp) env)) (env-eval (if-consequent exp) env) (env-eval (if-alternative exp) env)))) (define eval-if (lambda (exp env) (if (true? (env-eval (if-predicate exp) env)) (env-eval (if-consequent exp) env) (env-eval (if-alternative exp) env)))) (define analyze-if (lambda (exp) (let ((pred (analyze (if-predicate exp))) (consequent (analyze (if-consequent exp))) (alternative (analyze (if-alternative exp)))) (lambda (env) (if (true? (pred env)) (consequent env) (alternative env)))))) (define analyze-if (lambda (exp) (let ((pred (analyze (if-predicate exp))) (consequent (analyze (if-consequent exp))) (alternative (analyze (if-alternative exp)))) (lambda (env) (if (true? (pred env)) (consequent env) (alternative env)))))) Evaluator Analyzer

24 24 (define (analyze-special-form exp) (cond ((quoted? exp) (analyze-quoted exp)) ((lambda? exp) (analyze-lambda exp)) … ((let*? exp) (analyze-let* exp)))) (define (analyze-special-form exp) (cond ((quoted? exp) (analyze-quoted exp)) ((lambda? exp) (analyze-lambda exp)) … ((let*? exp) (analyze-let* exp)))) As a derived expression? Already done in the ASP! 1. Add the required ADT procedures to the ASP 2. identify a let* expression as a special form 3. Modify the procedure analyze-special-form: Env. model Compiler: Supporting let* As a special form?

25 25 Env. model Compiler: Supporting let* (define (analyze-let* exp) (let ((vars (let*-variables exp)) (vals (map analyze (let*-initial-values exp))) (body (analyze-sequence (let*-body exp)))) (letrec ((fold (lambda (vars-lst vals-lst env) (if (null? vars-lst) (body env) (fold (cdr vars-lst) (cdr vals-lst) (extend-env (make-frame (list (car vars-lst)) (list ((car vals-lst) env))) env)))))) (lambda (env) (fold vars vals env))))) (define (analyze-let* exp) (let ((vars (let*-variables exp)) (vals (map analyze (let*-initial-values exp))) (body (analyze-sequence (let*-body exp)))) (letrec ((fold (lambda (vars-lst vals-lst env) (if (null? vars-lst) (body env) (fold (cdr vars-lst) (cdr vals-lst) (extend-env (make-frame (list (car vars-lst)) (list ((car vals-lst) env))) env)))))) (lambda (env) (fold vars vals env))))) 4. Add the procedure analyze-let*: “Translate” eval-let*, to an analyzer procedure: Curry the env parameter. Inductively analyze all sub expressions.


Download ppt "1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can."

Similar presentations


Ads by Google