Presentation is loading. Please wait.

Presentation is loading. Please wait.

מבוא מורחב למדעי המחשב בשפת Scheme תרגול 11. Metacircular Evaluator 4.1, pages 362-398 definitions file on web 2.

Similar presentations


Presentation on theme: "מבוא מורחב למדעי המחשב בשפת Scheme תרגול 11. Metacircular Evaluator 4.1, pages 362-398 definitions file on web 2."— Presentation transcript:

1 מבוא מורחב למדעי המחשב בשפת Scheme תרגול 11

2 Metacircular Evaluator 4.1, pages 362-398 definitions file on web 2

3 Overview 1. Eval, apply 2. Change definition 3. Add let, let* 4. Add special forms and, or 5. Abstraction of frame scanning 3

4 4 Evaluator: a program that determines meaning of expressions in a programming language. Metacircular: written in the same language that it evaluates

5 Read-Eval-Print Loop (define (driver-loop) 1. PRINT PROMPT (prompt-for-input input-prompt) 2. READ INPUT EXPRESSION (let ((input (read))) 3. EVALUATE EXPRESSION (let ((output (mc-eval input the-global-environment))) … 4. PRINT RESULT (user-print output) 5. LOOP (driver-loop)))))) 5

6 Eval-Apply Mutual recursion between eval and apply To evaluate a compound expression means to evaluate the sub-expressions recursively, then apply the operator to the arguments. To apply a function to arguments means to evaluate the body of the function in a new environment. 6

7 Eval Evaluate expression in given environment (define (mc-eval exp env) (cond ((self-evaluating? exp) exp) … ((application? exp) (mc-apply (mc-eval (operator exp) env) (list-of-values (operands exp) env))) The name mc-eval is used to differ from the primitive eval 7

8 Apply Apply procedure to list of arguments (define (mc-apply procedure arguments) … (eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments (procedure-environment procedure)))) The name mc-apply is used to differ from the primitive apply 8

9 Change definition from (define x 7) to (x := 7) and from (define (square x) (* x x)) to ((square x) := (* x x)) 9

10 Change eval case from: (define (definition? exp) (tagged-list? exp 'define)) (define (tagged-list? exp tag) (if (pair? exp) (eq? (car exp) tag) false)) to: (define (definition? exp) (and (pair? exp) (pair? (cdr exp)) (eq? (cadr exp) ':=))) 10

11 Change selectors (define (definition-variable exp) (if (symbol? (cadr exp)) (cadr exp) (caadr exp))) (define (definition-value exp) (if (symbol? (cadr exp)) (caddr exp) (make-lambda (cdadr exp) (cddr exp)))) (car (caar (cdar 11

12 Adding let, let* Rearranging as another expression 12

13 let (let (( ) … ( )) ) is equivalent to ((lambda ( … ) ) … ) add a syntactic transformation let->combination 13

14 let - case in eval ((let? exp) (mc-eval (let->combination exp) env)) (define (let? exp) (tagged-list? exp ‘let)) let - predicate 14

15 let - constructors (define (make-combination function expressions) (cons function expressions)) 15

16 let - selectors (define (let-bindings exp) (cadr exp)) (define (let-body exp) (cddr exp)) (define (let-variables exp) (map car (let-bindings exp))) (define (let-expressions exp) (map cadr (let-bindings exp))) 16

17 let - evaluation (define (let->combination exp) (make-combination (make-lambda (let-variables exp) (let-body exp)) (let-expressions exp))) 17

18 let* The bindings of are performed sequentially. Each binding is made in an environment in which all of the preceding bindings are visible. (let* ((x 3) (y (+ x 2)) (z (+ x y 5))) (* x z)) > 39 18

19 let* (let* (( )… ( )) ) is equivalent to (let (( )) (let* (( )… ( )) )) add a syntactic transformation let*->nested-let 19

20 let* - example (let* (( ) ( )) ) = (let (( )) (let* ( )) )) = (let (( )) (let* () ))) = (let (( )) (let () ))) 20

21 let* - case in eval ((let*? exp) (mc-eval (let*->nested-let exp) env)) 21

22 let* - constructors (define (make-let bindings body) (cons ‘let (cons bindings body))) (define (make-let* bindings body) (cons ‘let* (cons bindings body))) 22

23 let* - predicates (define (let*? exp) (tagged-list exp ‘let*)) (define (no-bindings? bindings) (null? bindings)) 23

24 let* - selectors (define (let*-bindings exp) (cadr exp)) (define (let*-body exp) (cddr exp)) (define (let*-first-binding bindings) (car bindings)) (define (let*-rest-bindings bindings) (cdr bindings)) 24

25 let* - evaluation (define (let*->nested-let exp) (if (no-bindings? (let*-bindings exp)) (make-let (let*-bindings exp) (let*-body exp)) (make-let (list (let*-first-binding (let*-bindings exp)) ; ((v1 e1)) (make-let* (let*-rest-bindings (let*-bindings exp)) (let*-body exp)))) 25

26 Special forms: and, or Direct evaluation 26

27 and, or - cases in eval (define (mc-eval exp env) (cond ((self-evaluating? exp) exp) … ((and? exp) (eval-and (and-exps exp) env)) ((or? exp) (eval-or (or-exps exp) env)) ((application? exp) (mc-apply (mc-eval (operator exp) env) (list-of-values (operands exp) env))) 27

28 and, or - predicates (define (and? exp) (tagged-list? exp ‘and)) (define (or? exp) (tagged-list? exp ‘or)) (define (no-exps? exps) (null? exps)) (define (last-exp? exps) (null? (cdr exps))) 28

29 and, or - selectors (define (and-exps exp) (cdr exp)) (define (or-exps exp) (cdr exp)) (define (first-exp exps) (car exps)) (define (rest-exps exps) (cdr exps)) 29

30 and - evaluation from left to right EvaluationReturn value Any expression evaluates to false false All expressions evaluate to true value of last expression No expressionstrue

31 and - evaluation (define (eval-and exps env) (if (no-exps? exps) true (let ((first (mc-eval (first-exp exps) env))) (if (false? first) false (if (last-exp? exps) first (eval-and (rest-exps exps) env))))) 31

32 or - evaluation from left to right 32 EvaluationReturn value Any expression evaluates to true value of last expression All expressions evaluate to false false No expressionsfalse

33 or - evaluation (define (eval-or exps env) (if (no-exps? exps) false (let ((first (mc-eval (first-exp exps) env))) (if (true? first) first ;(if (last-exp? exps) false (eval-or (rest-exps exps) env))))) 33

34 Abstraction of frame scanning Exercise 4.12 34

35 35 Frames A frame is a set of bindings, represented as a pair of two lists: variables and values Constructor (make-frame variables values) Selectors (frame-variables frame) (frame-values frame) Mutator (add-binding-to-frame! var val frame)

36 36 Environments An environment consists of its first frame and an enclosing environment Constructor (extend-environment vars vals base-env) Selectors (first-frame env) (enclosing-environment env) Predefined environments the-global-environment the-empty-environment

37 37 Frame Scanning Performed by: lookup-variable-value invoked when evaluating names set-variable-value! invoked when evaluating set! expressions define-value! invoked when evaluating definitions

38 38 lookup-variable-value (define (lookup-variable-value var env) (define (env-loop env) (define (scan vars vals) (cond ((null? vars) (env-loop (enclosing-environment env))) ((eq? var (car vars)) (car vals)) (else (scan (cdr vars) (cdr vals))))) (if (eq? env the-empty-environment) (error "Unbound variable" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env))

39 39 set-variable-value! (define (set-variable-value! var val env) (define (env-loop env) (define (scan vars vals) (cond ((null? vars) (env-loop (enclosing-environment env))) ((eq? var (car vars)) (set-car! vals val)) (else (scan (cdr vars) (cdr vals))))) (if (eq? env the-empty-environment) (error "Unbound variable -- SET!" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env))

40 40 define-variable! (define (define-variable! var val env) (let ((frame (first-frame env))) (define (scan vars vals) (cond ((null? vars) (add-binding-to-frame! var val frame)) ((eq? var (car vars)) (set-car! vals val)) (else (scan (cdr vars) (cdr vals))))) (scan (frame-variables frame) (frame-values frame))))

41 41 All procedures are alike! Scan the frame for the variable’s name –If found, success operation (return value / set value) –If not in frame, failure operation (continue to next frame / add binding) Error on empty environment (if this can happen) We can get better abstraction –Capturing common patterns –Hiding frame scanning / mutation

42 42 Generic frame scan (define (scan-first-frame var env succeed fail) (define (scan vars vals) (cond ((null? vars) (fail)) ((eq? var (car vars)) (succeed vals)) (else (scan (cdr vars) (cdr vals))))) (if (eq? env the-empty-environment) (error "Unbound variable" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame)))))

43 43 lookup-variable-value (define (lookup-variable-value var env) (define (succeed vals) (get-binding-value vals)) (define (fail) (scan-first-frame var (enclosing-environment env) succeed fail)) (scan-first-frame var env succeed fail)) (define (get-binding-value vals) (car vals))

44 44 set-variable-value! (define (set-variable-value! var val env) (define (succeed vals) (set-binding-value! vals val)) (define (fail) (scan-first-frame var (enclosing-environment env) succeed fail)) (scan-first-frame var env succeed fail)) (define (set-binding-value! vals val) (set-car! vals val))

45 45 define-variable! (define (define-variable! var val env) (define (succeed vals) (set-binding-value! vals val)) (define (fail) (add-binding-to-frame! var val (first-frame env))) (scan-first-frame var env succeed fail))


Download ppt "מבוא מורחב למדעי המחשב בשפת Scheme תרגול 11. Metacircular Evaluator 4.1, pages 362-398 definitions file on web 2."

Similar presentations


Ads by Google