Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Subt. model interpreter: Structure of the interpreter ASP Derived expressions Core Test Data structures Utils A racket lib Proc / Primitive-Proc. Global.

Similar presentations


Presentation on theme: "1 Subt. model interpreter: Structure of the interpreter ASP Derived expressions Core Test Data structures Utils A racket lib Proc / Primitive-Proc. Global."— Presentation transcript:

1 1 Subt. model interpreter: Structure of the interpreter ASP Derived expressions Core 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

2 2 Subt. model interpreter: The testing mechanism Tests package: Should be run with every modification! The procedure test: Receives a single expression, e, and an expected value, v. Returns #t if and only if e evaluates to v. The procedure run-tests: Runs multiple number test expressions (test (derive-eval ‘(* 3 4)) => ‘(value 12)) (run-tests (test (derive-eval ‘(+ 3 4)) => ‘(value 7)) (test (derive-eval ‘(- 3 4)) => ‘(value -1)) (test (derive-eval ‘(/ 4 2)) => ‘(value 2))) (run-tests (test (derive-eval ‘(+ 3 4)) => ‘(value 7)) (test (derive-eval ‘(- 3 4)) => ‘(value -1)) (test (derive-eval ‘(/ 4 2)) => ‘(value 2)))

3 3 applicative -eval apply- procedure substituterename (define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((evaluator-value? exp) exp) ((application? exp) (let ((renamed-exp (rename exp))) (apply-procedure (applicative-eval (operator renamed-exp)) (list-of-values (operands renamed-exp))))) (else (error 'eval "unknown expression type: ~s" exp))))) (define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((evaluator-value? exp) exp) ((application? exp) (let ((renamed-exp (rename exp))) (apply-procedure (applicative-eval (operator renamed-exp)) (list-of-values (operands renamed-exp))))) (else (error 'eval "unknown expression type: ~s" exp))))) (define apply-procedure (lambda (procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (let ((parameters (procedure-parameters procedure)) (body (rename (procedure-body procedure)))) (eval-sequence (substitute body parameters arguments)))) (else (error 'apply "Unknown procedure type: ~s" procedure))))) (define apply-procedure (lambda (procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (let ((parameters (procedure-parameters procedure)) (body (rename (procedure-body procedure)))) (eval-sequence (substitute body parameters arguments)))) (else (error 'apply "Unknown procedure type: ~s" procedure))))) Subt. model interpreter: The core - components Core main-loop:

4 4 1.( (lambda(x) 2. (lambda(y) (y x))) 3. (lambda(x) (+ x y)) ) 1.( (lambda(x) 2. (lambda(y) (y x))) 3. (lambda(x) (+ x y)) ) Subt. model interpreter: The core – components The problem: (lambda(y) (y (lambda(x) (+ x y)))) (lambda(y) (y (lambda(x) (+ x y)))) y in line 2 is bound. y in line 3 is free. The free occurrence of y is now bound by the formal parameter. 1.( (lambda(x) 2. (lambda(y1) (y1 x))) 3. (lambda(x) (+ x y)) ) 1.( (lambda(x) 2. (lambda(y1) (y1 x))) 3. (lambda(x) (+ x y)) ) (lambda(y1) (y (lambda(x) (+ x y)))) (lambda(y1) (y (lambda(x) (+ x y)))) The solution: consistently rename bound occurrences and their binding instances: A reminder: Why do we need renaming?

5 5 Subt. model interpreter: The core – special forms 5 Supporting case expressions –syntax: ASP Derived expressions Core Data structures OR predicate + AND Consequence-exprs: Ordered. (case ( ). (else )) (case ( ). (else ))

6 6 Subt. model interpreter: The core – special forms 6 (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2))))))) (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2))))))) Supporting case expressions – usage example: control clauses last clause What are the components of a case expressions? What are the components of a case-clause? ASP Derived expressions Core Data structures

7 (define eval-special-form (lambda (exp) (cond ((quoted? exp) (make-value exp)) ((lambda? exp) (eval-lambda exp)) ((definition? exp) (eval-definition exp)) ((if? exp) (eval-if exp)) ((begin? exp) (eval-begin exp)) ((case? exp) (eval-case exp))))) (define eval-special-form (lambda (exp) (cond ((quoted? exp) (make-value exp)) ((lambda? exp) (eval-lambda exp)) ((definition? exp) (eval-definition exp)) ((if? exp) (eval-if exp)) ((begin? exp) (eval-begin exp)) ((case? exp) (eval-case exp))))) 7 Subt. model interpreter: The core – special forms Supporting case expressions as a special form Step 1: call the appropriate special evaluation procedure (define special-form? (lambda (exp) (or (quoted? exp) (lambda? exp) (definition? exp) (if? exp) (begin? exp) (case? exp)))) (define special-form? (lambda (exp) (or (quoted? exp) (lambda? exp) (definition? exp) (if? exp) (begin? exp) (case? exp)))) Step 2: Identify the expression as a special form ASP Derived expressions Core Data structures

8 Determining the evaluation rule for a case expression: 1.Evaluate the control. 2.Compare its value against compared components by order (assume numerical values). 3.Evaluate the actions of the 1 st clause where the compared value equals the control value. 4.If no such clause exists, evaluate the actions of the else-clause by order. 8 Subt. model interpreter: The core – special forms Step 3: Write the relevant special evaluation procedure Supporting case expressions as a special form (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2)…) (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2)…)

9 9 Subt. model interpreter: The core – special forms (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2)…) (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2)…) Step 3: Write the relevant special evaluation procedure (define (eval-case exp) (letrec ((eval-clauses (lambda (control clauses) (cond ((null? clauses) 'unspecified) ((or (case-last-clause? clauses) (= (app-eval (case-compared (case-first-clause clauses))) control)) (eval-sequence (case-actions (case-first-clause clauses)))) (else (eval-clauses control (case-rest-clauses clauses))))))) (eval-clauses (applicative-eval (case-control exp)) (case-clauses exp)))) (define (eval-case exp) (letrec ((eval-clauses (lambda (control clauses) (cond ((null? clauses) 'unspecified) ((or (case-last-clause? clauses) (= (app-eval (case-compared (case-first-clause clauses))) control)) (eval-sequence (case-actions (case-first-clause clauses)))) (else (eval-clauses control (case-rest-clauses clauses))))))) (eval-clauses (applicative-eval (case-control exp)) (case-clauses exp)))) Supporting case expressions as a special form

10 10 ; Signature: make-lambda(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] ; Signature: make-lambda(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] ; Signature: lambda-parameters(exp) ; Type: [LIST -> LIST(Symbol)] ; Signature: lambda-parameters(exp) ; Type: [LIST -> LIST(Symbol)] ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] ; Signature: lambda?(exp) ; Type: [T -> Boolean] ; Signature: lambda?(exp) ; Type: [T -> Boolean] Example: ADT and implementation for lambda expressions ; Signature: make-lambda(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] (define make-lambda (lambda (parameters body) (attach-tag (cons parameters body) 'lambda))) ; Signature: make-lambda(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] (define make-lambda (lambda (parameters body) (attach-tag (cons parameters body) 'lambda))) ; Signature: lambda-parameters(exp) ; Type: [LIST -> LIST(Symbol)] (define lambda-parameters (lambda (exp) (car (get-content exp)))) ; Signature: lambda-parameters(exp) ; Type: [LIST -> LIST(Symbol)] (define lambda-parameters (lambda (exp) (car (get-content exp)))) ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] (define lambda-body (lambda (exp) (cdr (get-content exp)))) ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] (define lambda-body (lambda (exp) (cdr (get-content exp)))) ; Signature: lambda?(exp) ; Type: [T -> Boolean] (define lambda? (lambda (exp) (tagged-by? exp 'lambda))) ; Signature: lambda?(exp) ; Type: [T -> Boolean] (define lambda? (lambda (exp) (tagged-by? exp 'lambda))) ASP Derived expressions Core Data structures Subt. model interpreter: The Abstract Syntax Parser (ASP)

11 11 Subt. model interpreter: The Abstract Syntax Parser (ASP) 11 ADT for case expressions (including ADT for case-clause): make-case(control case-clauses) Type: [Symbol*LIST -> CASE-Expression] make-case(control case-clauses) Type: [Symbol*LIST -> CASE-Expression] Constructor for case case?(exp) Type: [T -> Boolean] case?(exp) Type: [T -> Boolean] Predicate case-clauses(case-exp) Type: [CASE-Expression -> LIST] case-clauses(case-exp) Type: [CASE-Expression -> LIST] case-control(case-exp) Type: [CASE-Expression -> Symbol] case-control(case-exp) Type: [CASE-Expression -> Symbol] Selectors make-case-clause(compared actions) Type: [T*LIST -> CLAUSE-Expression] make-case-clause(compared actions) Type: [T*LIST -> CLAUSE-Expression] Constructor for case-clause Case-last-clause? Predicate case-actions Case-compared Selectors case-first-clause case-rest-clauses Usage example (client side): (make-case 'n (list (make-case-clause '0 '(0)) (make-case-clause '1 '(1)) (make-case-clause 'else '(+ (fib (- n 1)) (fib (– n 2)))))) (make-case 'n (list (make-case-clause '0 '(0)) (make-case-clause '1 '(1)) (make-case-clause 'else '(+ (fib (- n 1)) (fib (– n 2))))))

12 (define case? (lambda (exp) (tagged-by? exp 'case))) (define case? (lambda (exp) (tagged-by? exp 'case))) (define make-case-clause (lambda (compared actions) (cons compared actions))) (define make-case-clause (lambda (compared actions) (cons compared actions))) (define make-case (lambda (control case-clauses) (attach-tag (cons control case-clauses) 'case))) (define make-case (lambda (control case-clauses) (attach-tag (cons control case-clauses) 'case))) (define case-control (lambda (case-exp) (car (get-content case-exp)))) (define case-control (lambda (case-exp) (car (get-content case-exp)))) (define case-clauses (lambda (case-exp) (cdr (get-content case-exp)))) (define case-clauses (lambda (case-exp) (cdr (get-content case-exp)))) (define case-compared car) (define case-actions cdr) (define case-first-clause (lambda (clauses) (car clauses))) (define case-first-clause (lambda (clauses) (car clauses))) (define case-rest-clauses (lambda (clauses) (cdr clauses))) (define case-rest-clauses (lambda (clauses) (cdr clauses))) (define case-last-clause? (lambda (clauses) (and (null? (cdr clauses)) (eq? (case-compared (case-first-clause clauses)) 'else)))) (define case-last-clause? (lambda (clauses) (and (null? (cdr clauses)) (eq? (case-compared (case-first-clause clauses)) 'else)))) 12 Adding the implementation of the ADT: Constructor Selectors Predicate Subt. model interpreter: The Abstract Syntax Parser (ASP)

13 13 Subt. model interpreter: Derived expressions Example: deriving a case expression (case e (1 (doSomething)) (2 (* e 2)) (else e)) (case e (1 (doSomething)) (2 (* e 2)) (else e)) (if (= e 1) (doSomething) (if (= e 2) (* e 2) e)) (if (= e 1) (doSomething) (if (= e 2) (* e 2) e)) Any problem? (let ((ex e)) (if (= ex 1) (doSomething) (if (= ex 2) (* ex 2) ex))) (let ((ex e)) (if (= ex 1) (doSomething) (if (= ex 2) (* ex 2) ex)))

14 14 Subt. model interpreter: Derived expressions ASP Derived expressions Core Data structures Shallow- derive derive Recursively applies shallow-derive Derive? How? 1.Edit Derive? to consider the new exp as derived. 2.Edit Shallow-derive to call the relevant translation procedure. 3.Add a shallow translation procedure. Identifies the derived expression, calls the appropriate shallow translation procedure: ((cond? exp) (cond->if exp)) ⁞ ((let? exp) (let->combination exp)) Why? Smaller, simpler core! (let ((x 1)) x)  ((lambda(x) x) 1)

15 15 (define derive (lambda (exp) (if (atomic? exp) exp (let ((derived-exp (let ((mapped-derive-exp (map derive exp))) (if (not (derived? exp)) mapped-derive-exp (shallow-derive mapped-derive-exp))))) (if (equal? exp derived-exp) exp (derive derived-exp)))))) (define derive (lambda (exp) (if (atomic? exp) exp (let ((derived-exp (let ((mapped-derive-exp (map derive exp))) (if (not (derived? exp)) mapped-derive-exp (shallow-derive mapped-derive-exp))))) (if (equal? exp derived-exp) exp (derive derived-exp)))))) Subt. model interpreter: Derived expressions (define derived? (lambda (exp) (or (cond? exp) (function-definition? exp) (let? exp) (letrec? exp)))) (define derived? (lambda (exp) (or (cond? exp) (function-definition? exp) (let? exp) (letrec? exp)))) (define shallow-derive (lambda (exp) (cond ((cond? exp) (cond->if exp)) ((function-definition? exp) (function-define->define exp)) ((let? exp) (let->combination exp)) ((letrec? exp) (letrec->let exp)) (else "Unhandled derivision" exp)))) (define shallow-derive (lambda (exp) (cond ((cond? exp) (cond->if exp)) ((function-definition? exp) (function-define->define exp)) ((let? exp) (let->combination exp)) ((letrec? exp) (letrec->let exp)) (else "Unhandled derivision" exp))))

16 16 ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] ADT for the procedure data-structure (closure) : ; Signature: make-procedure(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] ; Signature: make-procedure(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] ; Signature: procedure-parameters(exp) ; Type: [LIST -> LIST(Symbol)] ; Signature: procedure-parameters(exp) ; Type: [LIST -> LIST(Symbol)] ; Signature: Compound-procedure?(exp) ; Type: [T -> Boolean] ; Signature: Compound-procedure?(exp) ; Type: [T -> Boolean] ASP Derived expressions Core Data structures Subt. model interpreter: Data Structures

17 17 Subt. model interpreter: Data Structures The Global Environment: A substitution between variables and values. (define make-the-global-environment (lambda () (let* ((primitive-procedures (list (list ‘car car) (list ‘cdr cdr) (list ‘cons cons) (list ‘null? null?) (list ‘+ +) (list ‘* *) (list ‘/ /) (list ‘> >) ;more primitives… )) (prim-variables (map car primitive-procedures)) (prim-values (map (lambda (x) (make-primitive-procedure (cadr x))) primitive-procedures))) (make-sub prim-variables prim-values)) )) (define make-the-global-environment (lambda () (let* ((primitive-procedures (list (list ‘car car) (list ‘cdr cdr) (list ‘cons cons) (list ‘null? null?) (list ‘+ +) (list ‘* *) (list ‘/ /) (list ‘> >) ;more primitives… )) (prim-variables (map car primitive-procedures)) (prim-values (map (lambda (x) (make-primitive-procedure (cadr x))) primitive-procedures))) (make-sub prim-variables prim-values)) )) ASP Derived expressions Core Data structures

18 18 Subt. model interpreter: Data Structures Getting the value of a variable in the GE: Implemented as a look-up procedure. (define get-value-of-variable (lambda (sub var) (letrec ((lookup (lambda (vars vals) (cond ((or (empty-sub sub) (not (member var vars))) (error ‘get-value-of-variable…)) ((eq? var (car vars)) (car vals)) (else (lookup (cdr vars) (cdr vals))))))) (lookup (get-variables sub) (get-values sub))))) (define get-value-of-variable (lambda (sub var) (letrec ((lookup (lambda (vars vals) (cond ((or (empty-sub sub) (not (member var vars))) (error ‘get-value-of-variable…)) ((eq? var (car vars)) (car vals)) (else (lookup (cdr vars) (cdr vals))))))) (lookup (get-variables sub) (get-values sub))))) ASP Derived expressions Core Data structures

19 19 Subt. model interpreter: Data Structures The substitution ADT: (define substitute (lambda (expr variables values) (if (evaluator-value? expr) (substitution-application-to-value (make-sub variables values) expr) (substitution-application-to-expr (make-sub variables values) expr)) )) (define substitute (lambda (expr variables values) (if (evaluator-value? expr) (substitution-application-to-value (make-sub variables values) expr) (substitution-application-to-expr (make-sub variables values) expr)) )) (define substitution-application-to-expr (lambda (sub expr) (cond ((empty-sub? sub) expr) ((or (number? expr) (boolean? expr) (quoted? expr)) expr) (else (let ((vars (get-variables sub)) (values (get-values sub))) (cond ((variable? expr) (if (member expr vars) (get-value-of-variable sub expr (lambda () expr)) expr)) ; a list of expressions, lambda, application, cond. (else (map (lambda (e) (substitute e vars values)) expr)))))) )) (define substitution-application-to-expr (lambda (sub expr) (cond ((empty-sub? sub) expr) ((or (number? expr) (boolean? expr) (quoted? expr)) expr) (else (let ((vars (get-variables sub)) (values (get-values sub))) (cond ((variable? expr) (if (member expr vars) (get-value-of-variable sub expr (lambda () expr)) expr)) ; a list of expressions, lambda, application, cond. (else (map (lambda (e) (substitute e vars values)) expr)))))) ))

20 20 Subt. model interpreter: Data Structures The substitution ADT: (define substitute (lambda (expr variables values) (if (evaluator-value? expr) (substitution-application-to-value (make-sub variables values) expr) (substitution-application-to-expr (make-sub variables values) expr)) )) (define substitute (lambda (expr variables values) (if (evaluator-value? expr) (substitution-application-to-value (make-sub variables values) expr) (substitution-application-to-expr (make-sub variables values) expr)) )) (define substitution-application-to-value (lambda (sub val-expr) (let ((vars (get-variables sub)) (values (get-values sub))) (cond ((primitive-procedure? val-expr) val-expr) ((value? val-expr) (if (atomic? (value-content val-expr)) val-expr (make-value (map (lambda (e) (substitute e vars values)) (value-content val-expr))))) ((compound-procedure? val-expr) (make-procedure (procedure-parameters val-expr) (map (lambda (e) (substitute e vars values)) (procedure-body val-expr)))))) )) (define substitution-application-to-value (lambda (sub val-expr) (let ((vars (get-variables sub)) (values (get-values sub))) (cond ((primitive-procedure? val-expr) val-expr) ((value? val-expr) (if (atomic? (value-content val-expr)) val-expr (make-value (map (lambda (e) (substitute e vars values)) (value-content val-expr))))) ((compound-procedure? val-expr) (make-procedure (procedure-parameters val-expr) (map (lambda (e) (substitute e vars values)) (procedure-body val-expr)))))) ))


Download ppt "1 Subt. model interpreter: Structure of the interpreter ASP Derived expressions Core Test Data structures Utils A racket lib Proc / Primitive-Proc. Global."

Similar presentations


Ads by Google