Presentation is loading. Please wait.

Presentation is loading. Please wait.

Env. Model Implementation

Similar presentations


Presentation on theme: "Env. Model Implementation"— Presentation transcript:

1 Env. Model Implementation
& Analyzer Practice Session #11

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

3 Env. model evaluator: Structure and implementation
Input text ASP Data structures Core Derived expressions Utils (a racket lib) Test Data structures: New data structures: frame, environment A closure keeps the Env in which it has been created Additional procedures are added to handle new ADTs Renaming and Substitution are no longer needed

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

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 <procedure(x) x>) ) 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 Env. model evaluator: Structure and implementation
Environment: Implemented as a list of boxed frames A finite sequence of frames in which the last frames is the-global-environment. E1 '((+ - …) (prim+ prim- …)) '((foo …) ( … )) t-g-e box-pointer diagram: box frame 'proc params body E2 E3

7 Env. model evaluator: Evaluation example (1)
Evaluating a definition expression: > (env-eval (derive '(define f (lambda (x) (lambda (y) (+ x y))))) t-g-e) (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env)) ...))) (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))

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

9 Env. model evaluator: Evaluation example (1)
Evaluating a definition expression: > (env-eval (derive '(define f (lambda (x) (lambda (y) (+ x y))))) t-g-e) (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env)) ...))) (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)) Done! (add-binding! (make-binding f (list 'procedure '(x) '(lambda (y) (+ x y)) t-g-e)) )

10 Env. model evaluator: Evaluation example (2)
Evaluating a user procedure: > (derive-eval 'f t-g-e) (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form 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) We look up f in the given env. The result is our representation of a procedure.

11 Env. model evaluator: Evaluation example (3)
Evaluating an application of a user procedure: > (env-eval '(define g (f 1) ) t-g-e) (apply-procedure (‘procedure (x) ((lambda (y) (+ x y))) 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) GE x: 1

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

13 Env. model evaluator: Supporting let*
Evaluation rule for a let* expression: An expression (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm), with respect to environment E0, is defined as follows: E E0 * make-frame [(v1),(env-eval e1 E0)] E E1 * make-frame [(v2),(env-eval e2 E1)] ... En En-1* make-frame [(vn),(env-eval en En-1)] (env-eval b1 En) ... (env-eval bm-1 En) Return (env-eval bm En) Q: How would the evaluation rule for let look like? A: e1…en will be evaluated with respect to E0. A new frame mapping (v1…vn) to (e1…en) will extend E0 to creating a new environment, E1.

14 Env. model evaluator: Supporting let* - as a derived expression
1. Add the required ADT procedures to the ASP (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*-initial-values exp) (map cadr (let*-bindings exp))) (define (let*-first-variable exp) (caar (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 body) (append (list 'let* bindings) body)) Data structures Core ASP Derived expressions (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

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))) 3. Modify the procedure shallow-derive (define (shallow-derive exp) (cond ((cond? exp) (cond->if exp)) ... ((let*? exp) (let*->nested-let exp)) (else "Unhandled derivision" exp))) Data structures Core ASP Derived expressions (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

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) ;dit (make-let ;dif (make-let-bindings (list (let*-first-variable exp)) (list (let*-first-initial-value exp))) (list (make-let* (cdr bindings) body)) ))))) No changes to the core! Data structures Core ASP Derived expressions (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

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-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)) ))))) (derive (let*->nested-let 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.

18 DONE Env. model evaluator: Supporting let* - as a special form
1. Add the required ADT procedures to the ASP DONE Data structures Core ASP Derived expressions (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

19 Env. model evaluator: Supporting let* - as a special form
2. Modify the procedure special-form? (define (special-form? exp) (or (quoted? exp) (lambda? exp) (definition? exp) (if? exp) (begin? exp) (let*? exp))) 3. Modify eval-special-form (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)))) Data structures Core ASP Derived expressions (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

20 Env. model evaluator: Supporting let* - as a special form
4. Add the procedure eval-let* (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)))) Extend the Env with new frames for each variable. When no variables remain, evaluate the body.

21 Env. model Compiler: Motivation
Special form? (define length (lambda (lst) (if (null? lst) (+ 1 (length (cdr lst)))))) What is length? What is + ? Each time length is called, the interpreter: Uses the ASP to identify the body as an if exp. Extracts the required components for evaluation. Looks-up variables. 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 Env. model Compiler: Introduction
Interpreter vs Compiler: 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) <body>)) (define analyze (lambda (exp) (lambda (env) <analyzed -body>))) env-eval: [Exp*Env->Scheme-Type] compiler: [Exp->[Env->Scheme-Type]]

23 Env. model Compiler: Comparing with env-eval
The analyze procedure: (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)))) 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))) Evaluator (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))))) Analyzer

24 Env. model Compiler: Supporting let*
As a derived expression? Same as already done with the evaluator! As a special form? 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: (define (analyze-special-form exp) (cond ((quoted? exp) (analyze-quoted exp)) ((lambda? exp) (analyze-lambda exp)) ((let*? exp) (analyze-let* exp))))

25 Env. model evaluator: Supporting let* - as a special form
4. Add the procedure eval-let* (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))))

26 Env. model Compiler: Supporting let*
4. Add the procedure analyze-let*: We “translate” the evaluator procedure, eval-let*, to an analyzer procedure: First, Curry the env parameter. Next, inductively apply analyze to all sub expressions. (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 "Env. Model Implementation"

Similar presentations


Ads by Google