continue evaluator

47
1 Continue Evaluator

Upload: saniya

Post on 22-Jan-2016

36 views

Category:

Documents


1 download

DESCRIPTION

Continue Evaluator. symbol procedure. symbol +. symbol x. Representing procedures. ( eval '(define twice (lambda (x) (+ x x))) GE). symbol primitive. scheme procedure +. Representing the Environment. Abstractly. (eval ‘(twice 4)) ( extend-environment ' (x) ' (4) GE). - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Continue Evaluator

1

Continue Evaluator

Page 2: Continue Evaluator

2

z 9

true #t

+

twice

Representing procedures

(eval '(define twice (lambda (x) (+ x x))) GE)

symbolprimitive

schemeprocedure +

symbolprocedure

symbol+

symbolx

Page 3: Continue Evaluator

3

Representing the Environment

• (eval ‘(twice 4))• (extend-environment '(x) '(4) GE) GE x: 10

+: (primitive ...)twice: (procedure ..)

E1 x: 4

Abstractly

Concretely

GE

list ofvalues

list ofvariables

frame

x 4

E1

x

10

+ twice primitive

Page 4: Continue Evaluator

4

Representing the Environment

• (eval ‘(twice 5))• (extend-environment '(x) '(5) GE)

GE

list ofvalues

list ofvariables

frame

x 4

E1

x

10

+ twice primitive

x 5

E2

Page 5: Continue Evaluator

5

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

(define (frame-variables frame) (car frame))(define (frame-values frame) (cdr frame))

(define (enclosing-environment env) (cdr env))(define (first-frame env) (car env))

Page 6: Continue Evaluator

6

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

(define (eval-definition exp env) (let ((name (cadr exp)) (defined-to-be (eval (caddr exp) env))) (define-variable! name defined-to-be env) ‘undefined))

Page 7: Continue Evaluator

Assignments

(define (eval-assignment exp env) (set-variable-value! (assignment-variable exp) (eval (assignment-value exp) env) env) 'ok)

(define (assignment? exp) (tagged-list? exp 'set!))

(define (assignment-variable exp) (cadr exp))

(define (assignment-value exp) (caddr exp))

Page 8: Continue Evaluator

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

Page 9: Continue Evaluator

9

Initialization primitives andinitial env.

(define the-empty-environment '())

(define the-global-environment (setup-environment))

(define (setup-environment) (let ((initial-env (extend-environment (primitive-procedure-names) (primitive-procedure-objects) the-empty-environment))) (define-variable! 'true #t initial-env) (define-variable! 'false #f initial-env) initial-env))

Page 10: Continue Evaluator

10

(define primitive-procedure (list (list 'car car) (list 'cdr cdr) (list 'cons cons) (list 'null? null?) (list '+ +);; more primitives ))

(define (primitive-procedure-names) (map car primitive-procedures))

(define (primitive-procedure-objects) (map (lambda (proc) (list 'primitive (cadr proc))) primitive-procedures))

Page 11: Continue Evaluator

11

Read-Eval-Print Loop

(define input-prompt ";;; M-Eval input:")(define output-prompt ";;; M-Eval value:")

(define (prompt-for-input string) (newline) (newline) (display string) (newline))

(define (announce-output string) (newline) (display string) (newline))

(define (driver-loop) (prompt-for-input input-prompt) (let ((input (read))) (let ((output (eval input the-global-env))) (announce-output output-prompt) (user-print output))) (driver-loop))

Page 12: Continue Evaluator

Apply (reminder)

(define (apply procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments (procedure-env procedure)))) (else (error "Unknown procedure type -- APPLY" procedure))))

Page 13: Continue Evaluator

15

Execution Examples

• An iterative algorithm in scheme

(eval '(define odd (lambda (n) (odd (- n 2)))) GE)

• A recursive algorithm in scheme

(eval '(define sum (lambda (n) (+ n (sum (- n 1))))) GE)

• Base case and if check omitted from both algorithmsto simplify the example

Page 14: Continue Evaluator

16

(eval '(define odd (lambda (n) (odd (- n 2)))) GE)

(eval '(odd 4) GE)

[call apply, which creates E1: n = 4, then eval body of odd]

(eval '(odd (- n 2)) E1)

(apply (eval 'odd E1) (list (eval '(- n 2) E1)))

[skip some steps in which (- n 2) ==> 2](apply (list ’procedure '(n) '(odd (- n 2)) GE) '(2))

[apply creates E2: n = 2, then eval body of odd]

(eval '(odd (- n 2)) E2))• No pending operations on the recursive call to eval

Page 15: Continue Evaluator

17

(eval '(define sum (lambda (n) (+ n (sum (- n 1))))) GE)

(eval '(sum 4) GE)

[call apply, which creates E1: n = 4, then eval body of sum]

(eval '(+ n (sum (- n 1))) E1)

(apply '(primitive #[add]) (list (eval 'n E1) (eval '(sum (- n 1)) E1)))

[skip some steps in which (- n 1) ==> 3]

(apply '(primitive #[add]) (list 4 (apply (eval 'sum E1) '(3))))

[apply creates E2: n = 3, then eval body of sum]

(apply '(primitive #[add])(list 4 (eval '(+ n (sum (- n 1))) E2))

• There are pending operations on the recursive call to eval

Page 16: Continue Evaluator

18

Summary

• Cycle between eval and apply is the core of the evaluator• eval calls apply with operator and argument values• apply calls eval with expression and environment

• What is still missing from scheme ?• Some special forms• data types other than numbers and booleans

Page 17: Continue Evaluator

19

Note: Syntactic Abstraction

• Semantics• What the language means• Model of computation

• Syntax• Particulars of writing expressions• E.g. how to signal different expressions

• Separation of syntax and semantics: allows one to easily alter syntax

eval/applysyntax

procedures

Page 18: Continue Evaluator

20

Basic Syntax

• Routines to detect expressions(define (if? exp) (tagged-list? exp 'if))(define (lambda? exp) (tagged-list? exp 'lambda))(define (application? exp) (pair? exp))

• Routines to get information out of expressions(define (operator app) (car app))(define (operands app) (cdr app))(define (first-operand args) (car args))(define (rest-operands args) (cdr args))

• Routines to build expressions(define (make-if predicate consequent alternative) (list 'if predicate consequent alternative))

Page 19: Continue Evaluator

21

Example – Changing Syntax

• Suppose you wanted a "verbose" application syntax:

(CALL <proc> ARGS <arg1> <arg2> ...)

• Changes – only in the syntax routines!

(define (application? exp) (tagged-list? 'CALL))

(define (operator app) (cadr app))

(define (operands app) (cdddr app))

Page 20: Continue Evaluator

22

Implementing "Syntactic Sugar"

• Idea:• Implement a simple fundamental "core" in the evaluator• Easy way to add alternative/convenient syntax?

• "let" as sugared procedure application:

(let ((<name1> <val1>) (<name2> <val2>)) <body>)

((lambda (<name1> <name2>) <body>) <val1> <val2>)

Page 21: Continue Evaluator

23

Detect and Transform the Alternative Syntax

(define (eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((quoted? exp) (text-of-quotation exp)) . . . ((cond? exp) (eval (cond->if exp) env)) ((let? exp) (eval (let->combination exp) env)) ((application? exp) (apply (eval (operator exp) env)

(list-of-values (operands exp) env))) (else (error "Unknown expression" exp))))

Page 22: Continue Evaluator

24

Implementing cond: Syntax procedures

(define (cond-clauses exp) (cdr exp))

(define (cond-else-clause? clause) (eq? (cond-predicate clause) 'else))

(define (cond-predicate clause) (car clause))

(define (cond-actions clause) (cdr clause))

(cond ((= x 23) (+ x 1))

(else (- x 1)))

(if (= x 23) (+ x 1) (- x 1))

Page 23: Continue Evaluator

25

Cond syntax

(cond ((= x 23) (+ x 1))

(else (- x 1)))

cond

else

23x=

1x+

1x-

Page 24: Continue Evaluator

26

Transforming sequence of expression toan expression

(define (sequence->exp seq) (cond ((null? seq) seq) ((last-exp? seq) (first-exp seq)) (else (make-begin seq))))

(define (make-begin seq) (cons 'begin seq))

2x*

car y

begin

Page 25: Continue Evaluator

27

Implementing cond (Cont.)

(cond ((= x 23) (+ x 1))

(else (- x 1)))

(if (= x 23) (+ x 1) (- x 1))

Page 26: Continue Evaluator

28

Implementing cond

(define (cond->if exp) (expand-clauses (cond-clauses exp)))

(define (expand-clauses clauses) (if (null? clauses) 'false ; no else clause (let ((first (car clauses)) (rest (cdr clauses))) (if (cond-else-clause? first) (if (null? rest) (sequence->exp (cond-actions first)) (error "ELSE clause isn't last -- COND->IF" clauses)) (make-if (cond-predicate first) (sequence->exp (cond-actions first)) (expand-clauses rest))))))

Page 27: Continue Evaluator

29

Details of cond syntax transformation

(cond ((= x 23) (+ x 1))

(else (- x 1)))

cond

else

23x=

1x+

1x-

Page 28: Continue Evaluator

30

Details of cond syntax transformation

(expand-clauses

else

23x=

1x+

1x-

)

Page 29: Continue Evaluator

31

Details of cond syntax transformation

first

else

23x=

1x+

1x-

rest

Page 30: Continue Evaluator

32

Details of cond syntax transformation

23x=

1x+

else

1x-

(make-if

(expand-clauses ))

Page 31: Continue Evaluator

33

Details of cond syntax transformation

23x=

1x+

1x-

(make-if

)

Page 32: Continue Evaluator

34

Details of cond syntax transformation

23x=

1x+

1x-

if

Page 33: Continue Evaluator

35

Named Procedures

Support (define (foo <parm>) <body>)

(define (eval-definition exp env) (define-variable! (definition-variable exp) (eval (definition-value exp) env) env))

(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) ;formal params

(cddr exp)))) ;body

Page 34: Continue Evaluator

Different frame implementation

(define make-frame

(lambda (variables values)

(lambda (var)

(cond ((empty? variables) empty)

((eq? var (car variables))

(make-binding (car variables) (car values)))

(else

(apply (make-frame (cdr variables) (cdr values))

(list var))))

))

New ADT: Box (whose implementation is a black box) for mutable objects!

Details omitted

36

Page 35: Continue Evaluator

Substitution Model Instead of the Env. Model

• What changes to the evaluator are required?

37

Page 36: Continue Evaluator

Substitution Model Instead of the Env. Model

• Main changes:• No generation (and passing as parameters) of

environments (only global environment is generated)– Scoping is handled differently (see next)

• No support of assignment– Assignment does not fit well in the functional

programming framework• Besides application, support of other operations stays

almost intact– Omit the environment parameter, and use global

env. Instead• Application requires some work

38

Page 37: Continue Evaluator

(define applicative-eval

(lambda (exp)

(cond ((atomic? exp) (eval-atomic exp))

((application? exp)

(let ((renamed-exp (rename exp)))

(apply-procedure

(applicative-eval (operator renamed-exp))

(list-of-values (operands renamed-exp)))))

(else

(error "Unknown expression type -- EVAL" exp)))))

39

Page 38: Continue Evaluator

(define apply-procedure

(lambda (procedure arguments)

(cond ((primitive-procedure? procedure)

(apply-primitive-procedure procedure arguments))

((compound-procedure? procedure)

(eval-sequence

(substitute (procedure-body procedure)

(procedure-parameters procedure)

arguments)))

(else

(error "Unknown procedure type -- APPLY" procedure)))))

40

Page 39: Continue Evaluator

substitute

(define substitute

(letrec ((substitute-var-val

(lambda (exp var val)

(cond ((variable? exp)

(if (eq? exp var) val exp))

((or (number? exp)

(boolean? exp) (quoted? exp) ) exp)

((value? exp)

(substitute-var-val-in-value exp var val))

(else

(map (lambda(e) (substitute-var-val e var val)) exp)))) )

41

Page 40: Continue Evaluator

rename

42

• Implementation can be found in lecture notes• Idea: rename the formal arguments of the closure as well

as all occurrences of them in the body• To distinguish from other variables with the same name

that are e.g. in the global scope

Page 41: Continue Evaluator

Auxiliary function

(define (make-new-names old-names)

(if (null? old-names) ‘()

(cons (gensym)

(make-new-names (cdr old-names)))))))

This should be inside the code of rename, put as external for clarification!

43

Page 42: Continue Evaluator

One more auxiliary function

• (define (replace val-exp)

(cond ((or (evaluator-symbol? val-exp)

(primitive-procedure? val-exp)) val-exp)

((evaluator-list? val-exp)

(make-list (map rename (list-content val-exp))))

((compound-procedure? val-exp)

(let* ((params (procedure-parameters val-exp))

(new-params (make-new-names params))

(renamed-subs-body (map rename

(procedure-body val-exp)))

(renamed-body (substitute renamed-subs-body params new-params)))

(make-procedure new-params renamed-body))))

44

Page 43: Continue Evaluator

Finally- rename

(define (rename exp)

(cond ((atomic? exp) exp)

((lambda? exp)

(let* ((params (lambda-parameters exp))

(new-params (make-new-names params))

(renamed-subs (map rename exp)))

(substitute renamed-subs params new-params)) )

((evaluator-value? exp) (replace exp))

(else (map rename exp))

45

Page 44: Continue Evaluator

Lists

• (define (evaluator-value? val)

(or (evaluator-symbol? val) (evaluator-list? val)

(primitive-procedure? val)

(compound-procedure? val))))• (define (list-form? exp)

(or (tagged-list? exp ’cons) (tagged-list? exp ’list)

(tagged-list? exp ’append))))• (define (eval-list lst) (make-list (apply-primitive-procedure

(eval (operator lst))

(list-of-values (operands lst))))))

46

Page 45: Continue Evaluator

The Analyzer

• Main idea: separate the syntactic analysis from evaluation

• Main observation: this corresponds to separating the management of expressions from those of the enviornments

• Simplest analysis:

(define (analyze-self-evaluating exp) (lambda (env) exp))

48

Page 46: Continue Evaluator

The Analyzer (cont.)

(define (analyze-quoted exp) (let ((qval (text-of-quotation exp))) (lambda (env) qval)))

(define (analyze-definition exp)

(let ((var (definition-variable exp))

(val (analyze (definition-value exp))))

(lambda (env)

(if (not (eq? env the-global-environment))

(error ’eval "non global definition: ~s" exp)

(begin

(add-binding! (make-binding var

(val the-global-environment)))

’ok))))))

49

Page 47: Continue Evaluator

The Analyzer (cont.)

• (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))))))

And so on…

50