1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the...

44
1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full. http://mitpress.mit.edu/sicp/full- text/book/book-Z-H-26.html
  • date post

    19-Dec-2015
  • Category

    Documents

  • view

    215
  • download

    0

Transcript of 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the...

Page 1: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

1

The Metacircular Evaluator

Chapter 4 Section 4.1

We will not cover every little detail in the lectures, so you MUST read Section 4.1 in

full.

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-26.html

Page 2: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

2

Compiler vs. Interpreter

CommandProcessing Unit

The Computer

Program in Low Level Machine Language

Program in High Level Language

Transformation

The Programmer

T

Page 3: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

3

A Compiler

CPU

Machine Level Program

High Level Program C

Inputs

Outputs

The Compiler turns the high level program instructions toInstructions understood by the machine.

Page 4: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

4

An Interpreter

CPU

High Level Program I

Inputs

Outputs

The Interpreter is a machine level program, which interprets and executes the high level program line after line…

Page 5: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

5

The Metacircular Evaluator

CPU

SchemeProgram

Inputs

Outputs

The Metacircular Evaluator is an Interpreter for Scheme on a machine whose machine language is Scheme.

ME

Page 6: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

6

The Environment Evaluation Model

1. To evaluate a combination (a compound expression other than a special form), evaluate the subexpressions and then apply the value of the operator subexpression to the values of the operand subexpressions.

2. To apply a compound procedure to a set of arguments, evaluate the body of the procedure in a new environment. To construct this environment, extend the environment part of the procedure object by a frame in which the formal parameters of the procedure are bound to the arguments to which the procedure is applied.

Page 7: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

7

The Eval/Apply Cycle

Page 8: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

8

The Meta-Circular Evaluator: Eval

(define (eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((quoted? exp) (text-of-quotation exp)) ((assignment? exp) (eval-assignment exp env)) ((definition? exp) (eval-definition exp env)) ((if? exp) (eval-if exp env)) ((lambda? exp) (make-procedure (lambda-parameters exp) (lambda-body exp) env)) ((begin? exp) (eval-sequence (begin-actions exp) env)) ((cond? exp) (eval (cond->if exp) env)) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression type -- EVAL" exp))))

Sp

e cial for ms

Page 9: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

9

The Meta-Circular Evaluator: Apply

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

(else (error "Unknown procedure type"

procedure))))

Page 10: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

10

Sample Execution

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

(driver-loop)

;;; M-Eval input:

(define (append x y)

(if (null? x) y (cons (car x) (append (cdr x) y))))

;;; M-Eval value:

ok

;;; M-Eval input:

(append '(a b c) '(d e f))

;;; M-Eval value:

(a b c d e f)

Page 11: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

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: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

12

Read returns a cons structure to eval

(eval )

2x+

define

54+

x

(eval )

Eval must now evaluate the expression and return a value…

Page 13: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

13

Plan of Our Presentation

• We will begin with a simple variant of the interpreter. In describing it we will break many of the abstraction layers and levels trying to give you a feel of what is really going on.

• This variant is similar to the MCE we will eventually construct, but not identical.

• We start by extending a simple “calculator” like evaluator to allow saving values in variables…I.e. have an environment.

Page 14: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

14

Start Simple: Names

• Extend a “calculator” to store intermediate results as named values

(define x (+ 4 5)) store result as x

(+ x 2) use that result

• Store bindings between names and values in a table

Page 15: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

15

 

(define (definition? exp) (tag-check exp 'define)) (define (eval exp) (cond ((number? exp) exp) ((symbol? exp) (lookup exp)) ((sum? exp) (eval-sum exp)) ((definition? exp) (eval-definition exp)) (else (error "unknown expression " exp)))) (define environment (make-frame nil nil)) (define (lookup name) (lookup-variable-value name environment)) (define (eval-definition exp) (let ((name (cadr exp)) (defined-to-be (eval (caddr exp)))) (add-binding-to-frame! name defined-to-be environment) ‘undefined))

  

Page 16: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

16

The Environment Representation

list ofvalues

list ofvariables

frame

x y 4 5

Note: we are assuming an environment Consisting of a single frame

Page 17: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

17

(define (make-frame variables values) (cons variables values))

(define (lookup-variable-value var frame)

(define (scan vars vals) (cond ((null? vars) (error "Unbound variable" var))

((eq? var (car vars) (car vals)) (else (scan (cdr vars) (cdr vals)))))

(let ((vars (car frame)) (vals (cdr frame))) (scan vars vals)))

(define (add-binding-to-frame! var val frame) (set-car! frame (cons var (car frame))) (set-cdr! frame (cons val (cdr frame))))

Page 18: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

18

Evaluation Example

(eval '(define x (+ 4 5)))

(eval '(+ 4 5))

(eval 4) ==> 4

(eval 5) ==> 5

==> 9

==> undefined

(eval '(+ x 2))

(eval 'x) ==> 9

(eval 2) ==> 2

==> 11

(define x (+ 4 5))(+ x 2)

9x

names values

Page 19: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

19

Things to observe

• Use scheme function symbol? to check for a name• the reader converts sequences of characters like "x" to

symbols in the parse tree

• Can use any implementation of the environment,in particular we could use put and get from previous lectures.

•eval-definition recursively calls eval on the second subtree but not on the first one

•eval-definition returns a special undefined value

Page 20: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

20

Conditionals and If

• Extend the calculator to handle conditionals and if:

(if (> y 6) (+ y 2) 15)

•> an operation that returns a boolean•if an operation that evaluates the first subexp,

checks if value is true or false

Page 21: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

21

 

(define (greater? exp) (tag-check exp ’>))(define (if? exp) (tag-check exp 'if)) (define (eval exp) (cond ((number? exp) exp) ((symbol? exp) (lookup exp)) ((sum? exp) (eval-sum exp)) ((greater? exp) (eval-greater exp)) ((definition? exp) (eval-definition exp)) ((if? exp) (eval-if exp)) (else (error "unknown expression " exp)))) (define (eval-greater exp) (> (eval (cadr exp)) (eval (caddr exp))))  

Page 22: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

22

(define (eval-if exp) (if (true? (eval (if-predicate exp))) (eval (if-consequent exp)) (eval (if-alternative exp))))

(define (if-predicate exp) (cadr exp))(define (if-consequent exp) (caddr exp))(define (if-alternative exp) (if (not (null? (cdddr exp))) (cadddr exp) 'false))

(define (true? x) (not (or (eq? x #f) (eq? x ‘false)))

(define (false? x) (or (eq? x #f) (eq? x ‘false)) (eval '(define y 9))(eval '(if (> y 6) (+ y 2) 15)) 

Page 23: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

23

We are just walking through a tree …

(eval )

6y>

if

6y> 2y+

15

Then (eval ) or (eval 15 )

2y+

Page 24: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

24

Evaluation of

(eval '(if (> y 6) (+ y 2) 15))

(eval '(> y 6))

(eval 'y) ==> 9

(eval 6) ==> 6

==> #t

(eval '(+ y 2))

(eval 'y) ==> 9

(eval 2) ==> 2

==> 11

==> 11

Page 25: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

25

Things to observe

•eval-greater is just like eval-sum from page 1• recursively call eval on both argument expressions• call scheme > to compute the value

•eval-if does not call eval on all argument expressions:• call eval on the predicate

• call eval on the consequent or on the alternative but not both

Page 26: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

26

Store operators in the environment

• Want to add lots of operators but keep eval short

• Operations like + and > are similar• evaluate all the argument subexpressions• perform the operation on the resulting values

• Call this standard pattern an application• Implement a single case in eval for all applications

• Approach:•eval the first subexpression of an application• put a name in the environment for each operation• put a value if that name is a procedure• apply the procedure to the operands

Page 27: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

27

 

(define (application? exp) (pair? exp)) (define (eval exp) (cond ((number? exp) exp) ((symbol? exp) (lookup exp)) ((definition? exp) (eval-definition exp)) ((if? exp) (eval-if exp)) ((application? exp) (apply (eval (car exp)) (map eval (cdr exp)))) (else (error "unknown expression " exp)))) ;; rename scheme’s apply so we can reuse the name(define scheme-apply apply) (define (apply procedure arguments) (if (primitive-procedure? procedure) (apply-primitive-procedure procedure arguments) (error "operator not a procedure: " procedure)))

(define (apply-primitive-procedure proc args) (scheme-apply (primitive-implementation proc) args))

Page 28: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

28

 

 (define prim-tag 'primitive)(define (make-primitive scheme-proc) (list prim-tag scheme-proc))(define (primitive-procedure? exp) (tag-check exp prim-tag))(define (primitive-implementation prim) (cadr prim)) (define environment (make-frame nil nil))(add-binding-to-frame! environment ’+ (make-primitive +))(add-binding-to-frame! environment ’> (make-primitive >))(add-binding-to-frame! environment 'true #t) (eval '(define z 9))(eval '(+ 9 6)) (eval '(if true 10 15))  

Page 29: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

29

The Environment after first “define”

symbolprimitive

schemeprocedure

>symbol

primitive

schemeprocedure

+

z 9

true #t

>

+

Name Value

Page 30: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

30

Evaluation of (+ 9 6)

(eval '(+ 9 6))(apply (eval +) (map eval '(9 6)))(apply '(primitive #[add]) (list (eval 9) (eval 6))

(apply '(primitive #[add]) '(9 6))(scheme-apply (primitive-implementation '(primitive #[add])) '(9 6))

(scheme-apply #[add] '(9 6))15

Page 31: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

31

Evaluation of (if true 10 15)

(eval '(if true 10 15))(eval-if '(if true 10 15))(if (true? (eval 'true)) ...)(if (true? (lookup 'true))) ...)(if (true? #t) ...)(eval 10)10

Apply is never called!

Page 32: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

32

Things to observe

• Applications must be the last case in eval • No tag check

• Applications evaluate all subexpressions• Expressions that need special handling, like if,

get their own case in eval

Page 33: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

33

The Environment as an Explicit Parameter

• Change from(eval '(+ 6 4))

to(eval '(+ 6 4) environment)

• All procedures that call eval have extra argument•lookup and define use the environment from the

argument• No other change from earlier evaluator

Page 34: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

34

The Environment as an Explicit Parameter 

;This change is boring! Exactly the same functionality as #4. 

(define (eval exp env) (cond ((number? exp) exp) ((symbol? exp) (lookup exp env)) ((definition? exp) (eval-defininition exp env)) ((if? exp) (eval-if exp env)) ((application? exp) (apply (eval (car exp) env) (map (lambda (exp) (eval exp env)) (cdr exp)))) (else (error "unknown expression " exp))))

(define (lookup name env) (lookup-variable-value name env)) 

Page 35: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

35

 

(define (eval-define exp env) (let ((name (cadr exp)) (defined-to-be (eval (caddr exp) env))) (add-binding-to-frame! name defined-to-be env) ‘undefined)) (define (eval-if exp env) (if (true? (eval (if-predicate exp) env)) (eval (if-consequent exp) env) (eval (if-alternative exp) env)))

The Environment as an Explicit Parameter (Continued)

Page 36: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

36

Defining New Procedures

• Want to add new procedures• For example, a scheme program:

(define twice (lambda (x) (+ x x)))(twice 4)

• Strategy:• Add a case for lambda to eval

– the value of lambda is a compound procedure• Extend apply to handle compound procedures• Implement environment model

We will go over this example in more detail next lecture!

Page 37: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

37

 

(define (lambda? exp) (tag-check exp 'lambda)) (define (eval exp env) (cond ((number? exp) exp) ((symbol? exp) (lookup exp env)) ((define? exp) (eval-define exp env)) ((if? exp) (eval-if exp env)) ((lambda? exp) (eval-lambda exp env)) ((application? exp) (apply (eval (car exp) env) (map (lambda (e) (eval e env)) (cdr exp)))) (else (error "unknown expression " exp)))) (define (eval-lambda exp env) (make-procedure (lambda-parameters exp) (lambda-body exp) env))

(define (lambda-parameters exp) (cadr exp))(define (lambda-body exp) (cddr exp))

(define (make-procedure parameters body env) (list 'procedure parameters body env))

p: b:

Page 38: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

38

 

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

(define (compound-procedure? exp) (tag-check exp ‘procedure)) (define (procedure-parameters compound) (cadr compound))(define (procedure-body compound) (caddr compound))(define (procedure-env compound) (cadddr compound))

Page 39: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

39

(define (eval-sequence exps env) (cond ((last-exp? exps) (eval (first-exp exps) env)) (else (eval (first-exp exps) env) (eval-sequence (rest-exps exps) env))))

(define (last-exp? seq) (null? (cdr seq)))(define (first-exp seq) (car seq))(define (rest-exps seq) (cdr seq))

Page 40: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

40

How the Environment Works• Abstractly – in our

environment diagrams:

• Concretely – our implementation (as in SICP)

E2 x: 10plus: (procedure ...)

E1

environmentmanipulation

3.

list ofvalues

enclosing-environment

list ofvariables

frame

x plus 10

E2

procedure

Page 41: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

41

Extending the Environment•(extend-environment '(x y) '(4 5) E2)

E1

E2 x: 10plus: (procedure ...)

E3 x: 4y: 5

Abstractly

ConcretelyE2

list ofvalues

list ofvariables

frame

x y 4

E3

5

E1

Page 42: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

42

(define (extend-environment vars vals base-env) (if (= (length vars) (length vals)) (cons (make-frame vars vals) base-env) (if (< (length vars) (length vals)) (error "Too many arguments supplied" vars vals) (error "Too few arguments supplied" vars vals))))

Page 43: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

43

"Scanning" the environment

• Look for a variable in the environment...

• Look for a variable in a frame...– loop through the list of vars and list of vals in parallel– detect if the variable is found in the frame

• If not found in frame (out of variables in the frame),look in enclosing environment

Page 44: 1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.

44

Summary and Next Lecture

• Go over some parts of the material again to help you better understand it

• Show how to put everything together, a running evaluator• Show how the environments work in more detail• Explain “Macros” like the “cond” transformation