Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10.

Similar presentations


Presentation on theme: "1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10."— Presentation transcript:

1 1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10

2 2 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) Efficiency: Env. model evaluator: Introduction

3 Env. model evaluator: Structure and implementation ASP Derived expressions Core Test Data structures Utils (a racket lib) Input text Data structures: New data structures: frame, environment A closure keeps the Env in which it has been created renaming and substitution functions are no longer needed

4 Env. model evaluator: Structure and implementation ASP Derived expressions Test Utils (a racket lib) Input text Core: Procedure application and evaluation of expressions is done with respect to a certain environment. Core Data structures ASP: No changes here!

5 5 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). '( (x foo) (4 ) ) A variable-value mapping. Each variable is bound to a single value only. Frame: Implemented as a substitution, i.e: as a list of 2 lists

6 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 … … E1E1 '((+ - …) (prim+ prim- …)) '((foo …) ( … )) t-g-e box-pointer diagram: box frame box 'procparamsbody E2E2 E3E3

7 7 Env. model evaluator: Evaluation example (1) Evaluating a definition expression: (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) (define eval-special-form (lambda (exp env) (cond... ((lambda? exp) (eval-lambda exp env)) ((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... ((lambda? exp) (eval-lambda exp env)) ((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))

8 8 Env. model evaluator: Evaluation example (1) Evaluating a definition expression: (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))) (attach-tag (list '(x) '(lambda (y) (+ x y)) t-g-e)) 'procedure)

9 9 Env. model evaluator: Evaluation example (1) Evaluating a definition expression: (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) (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)) Done! (add-binding! (make-binding f (list 'procedure '(x) '(lambda (y) (+ x y)) t-g-e)) )

10 10 Env. model evaluator: Evaluation example (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)))) > '(procedure (x) ((lambda (y) (+ x y))) t-g-e) The result is our representation of a procedure.

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

12 12 Can be regarded as a nested let expression. Similar to let, but defined variable can be used in the following 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? Evaluation rule for a let* expression: Env. model evaluator: Supporting let*

14 14 (define (let*? exp) (tagged-list? exp 'let*)) (define (let*? exp) (tagged-list? exp 'let*)) (define let*-bindings cadr) (define let*-body cddr) (define (let*-variables exp) (map car (let*-bindings exp))) (define (let*-variables exp) (map car (let*-bindings exp))) (define (let*-initial-values exp) (map cadr (let*-bindings exp))) (define (let*-initial-values exp) (map cadr (let*-bindings exp))) (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)) (define (make-let* bindings body) (append (list 'let* bindings) body)) (define (make-let* bindings body) (append (list 'let* bindings) body)) 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

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 "Unhandled derivision" exp))) (define (shallow-derive exp) (cond ((cond? exp) (cond->if exp))... ((let*? exp) (let*->nested-let exp)) (else "Unhandled derivision" 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 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-let '() body) (if (null? (cdr bindings)) (make-let bindings body) ;do-if-true (make-let ;do-if-false (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-let '() body) (if (null? (cdr bindings)) (make-let bindings body) ;do-if-true (make-let ;do-if-false (make-let-bindings (list (let*-first-variable exp)) (list (let*-first-initial-value exp))) (list (make-let* (cdr bindings) body)) ))))) (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 No changes to the core!

17 17 Env. model evaluator: Supporting let* - as a derived expression 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-let '() 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-let '() 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)) ))))) Q: The result is a let exp. Shouldn’t it be further derived? Q: What about the let* expression created by make-let*? Q: When the if-condition does not hold, we wrap the body parameter in a list. Why? (let*->nested-let (derive

18 18 Env. model evaluator: Supporting let* - as a derived expression 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-let '() 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-let '() 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)) ))))) Q: The result is a let exp. Shouldn’t it be further derived? A: Nah.. This is done by derive which calls itself until the result exp is not changed. 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 may consist of several expressions. (let*->nested-let (derive

19 19 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

20 20 (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

21 21 (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* Extend the Env with new frames for each variable. When no variables remain, evaluate the body.

22 22 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? Each time length is called, the interpreter: Uses the ASP to identify the body as an if exp. Extracts the required components for evaluation. 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.

23 23 Using the compiler, we distinguish analysis from evaluation. The compiler produces a procedure ready for execution, given an environment. The procedure returns the evaluation of the analyzed code with respect to the env. No analysis is performed during evaluation. (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:

24 (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 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 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 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 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

25 25 (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? Same as already done with the evaluator! 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?

26 26 (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*

27 27 4. Add the procedure analyze-let*: We “translate” the evaluator procedure, eval-let*, to an analyzer procedure: Inductively apply analyze to all sub expressions. Curry the env parameter. 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 ((helper (lambda (vars-lst vals-lst env) (if (null? vars-lst) (body env) (helper (cdr vars-lst) (cdr vals-lst) (extend-env (make-frame (list (car vars-lst)) (list ((car vals-lst) env))) env)))))) (lambda (env) ;letrc body – Currying (helper 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 ((helper (lambda (vars-lst vals-lst env) (if (null? vars-lst) (body env) (helper (cdr vars-lst) (cdr vals-lst) (extend-env (make-frame (list (car vars-lst)) (list ((car vals-lst) env))) env)))))) (lambda (env) ;letrc body – Currying (helper vars vals env)))))


Download ppt "1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10."

Similar presentations


Ads by Google