metacircular evaluation

28
Metacircular Evaluation SICP Chapter 4 Mark Boady

Upload: bruno

Post on 23-Feb-2016

43 views

Category:

Documents


0 download

DESCRIPTION

Metacircular Evaluation. SICP Chapter 4 Mark Boady. Metacircular Evaluator. An interpreter built for a language using the same language as it is interpreting. We will be looking at a Scheme interpreter written in scheme Read Chapter 4 of SICP for a more detailed look at this interpreter - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Metacircular  Evaluation

Metacircular Evaluation

SICP Chapter 4Mark Boady

Page 2: Metacircular  Evaluation

Metacircular EvaluatorAn interpreter built for a language using the same

language as it is interpreting.We will be looking at a Scheme interpreter written

in schemeRead Chapter 4 of SICP for a more detailed look at

this interpreterWhy?

Extending an interpreted languageDebuggers

Page 3: Metacircular  Evaluation

Jikes RVMA Java Research Virtual Machine written in JavaThe RVM runs on the JVMUsed For Research in:

Garbage CollectionDynamic ParallelizationMachine Learning for dynamic compilationDynamic TypingDistributed VM

Page 4: Metacircular  Evaluation

Scheme Metacircular EvaluatorEval

Takes an expression and an Environment Environment = Variable Names and Values

Returns the result of evaluating the expressionApply

Takes a Procedure and a list of argumentsProduces an expression for eval

(+ (* 4 5) 6)

Page 5: Metacircular  Evaluation

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

Page 6: Metacircular  Evaluation

(define (beval exp env) (cond ((boolean? exp) exp) ((conjunct? exp) (beval-and exp env))

((disjunct? exp) (beval-or exp env)) ((negate? exp) (beval-not exp env)) ((variable? exp) ... ; You'll need to supply your own

function that takes a frame, returns the assoc. value (else (error "beval: illegal syntax")))))

Page 7: Metacircular  Evaluation

Apply Definition(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 -- APPLY" procedure))))

Page 8: Metacircular  Evaluation

What do eval and apply do?Eval

Takes the expression and determines what the expression is

Passes the work to a helper function that evaluates the specific type

For procedures, pass control to apply

ApplyDetermine the type of procedureAdd to the environmentPass control to Eval

Page 9: Metacircular  Evaluation

ConceptWe want to eval (+ 4 5)((application? exp)

         (apply (eval (operator exp) env)                (list-of-values (operands exp) env)))

List-of-values evaluates the inputs to the procedureApply performs the actual procedureWith a primitive (like +) the underlying language

handles itWith a custom procedure, we need to pass back to eval

Page 10: Metacircular  Evaluation

Metacircular

Page 11: Metacircular  Evaluation

Basic Example(eval ‘(+ a 5) ‘((a 10) (b 7))Evaluate the expression a+5 with the variables a=10,

b=7Eval starts with a procedure and sees it is an applyEval evaluates the inputs to the procedure

Looks up variable values in this caseApply is asked to handle with (+ 10 5)Apply can determine 10+5=15 using the underlying

system

Page 12: Metacircular  Evaluation

DetailsGetting the arguments of a Procedure(apply (eval (operator exp) env)                (list-of-

values (operands exp) env)))(define (list-of-values exps env)  (if (no-

operands? exps)      '()      (cons (eval (first-operand exps) env)            (list-of-values (rest-operands exps) env))))

Page 13: Metacircular  Evaluation

If Statements(define (eval-if exp env)  (if (true? (eval (if-

predicate exp) env))      (eval (if-consequent exp) env)      (eval (if-alternative exp) env)))

Only Evaluate based on the true case(define (true? X) (not (eq? x false)))(define (if-alternative exp) (if (not (null? (cdddr exp))) (cadddr exp) 'false))

Page 14: Metacircular  Evaluation

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

Evaluate the sequence of expressions in a procedure body

Page 15: Metacircular  Evaluation

Assigning Variables(define (eval-assignment exp env)  (set-variable-

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

set-variable-value! Bounds a value to a name

Page 16: Metacircular  Evaluation

ExpressionsBasic functionality is implemented directlyAssignment

(define (assignment? exp)  (tagged-list? exp 'set!))(define (assignment-variable exp) (cadr exp))(define (assignment-value exp) (caddr exp))

Derived ExpressionsSome functionality is implemented using existing

functionality Cond can be transformed into if statements Let statements can be transformed in lambda expressions

Page 17: Metacircular  Evaluation

Derived ExpressionsLet expressions are derived expressions, because(let ((<var1> <exp1>) ... (<varn> <expn>))

  <body>)is equivalent to((lambda (<var1> ... <varn>)   <body>) <exp1>

... <expn>)

Page 18: Metacircular  Evaluation

Derived Expressions(let ((a 4) (b 6)) (+ a b))

Value 10( (lambda (a b) (+ a b)) 4 6)

Value 10

We can write a command that will translate a let to a lambda.

Let eval handle the lambda command using existing tools.

Page 19: Metacircular  Evaluation

Environment(lookup-variable-value <var> <env>)

returns the value that is bound to the symbol <var> in the environment <env>, or signals an error if the variable is unbound.

(extend-environment <variables> <values> <base-env>) returns a new environment, consisting of a new

frame in which the symbols in the list <variables> are bound to the corresponding elements in the list <values>, where the enclosing environment is the environment <base-env>.

Page 20: Metacircular  Evaluation

Environment(define-variable! <var> <value> <env>)

adds to the first frame in the environment <env> a new binding that associates the variable <var> with the value <value>.

(set-variable-value! <var> <value> <env>)changes the binding of the variable <var> in the

environment <env> so that the variable is now bound to the value <value>, or signals an error if the variable is unbound.

Page 21: Metacircular  Evaluation

EnvironmentsThere are multiple scopes in the environmentWe make changes to the most recentExample:

Initial memory: ( ( (a b) (5 7) ) )A new function is called with inputs b=6, c=7We push a new set of variables into the environmentNew Memory: ( ( (b c) (6 7) ) ( (a b) (5 7) ) )When the function call is over we remove it from the

environmentNew Memory: ( ( (a b) (5 7) ) )

Page 22: Metacircular  Evaluation

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

Page 23: Metacircular  Evaluation

Environments(define (lookup-variable-value var env)

(env-loop env))(define (env-loop env)    (if  (eq? env the-empty-environment)        (error "Unbound variable" var)        (let 

((frame (first-frame env)))           (scan (frame-variables frame) (frame-values frame))

)))(define (scan vars vals)      (cond 

((null? vars) (env-loop (enclosing-environment env)))        ((eq? var (car vars)) (car vals))        (else (scan (cdr vars) (cdr vals)))

) )

Page 24: Metacircular  Evaluation

Primitives(define primitive-procedures

(list (list 'car car)(list 'cdr cdr)(list 'cons cons)(list 'null? null?)(list '- -) (list '+ +)

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

Page 25: Metacircular  Evaluation

Running the EvaluatorLoad the File

(load "ch4-mcevalM.scm")Initialize the Global Environment

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

Initialize the Evaluator (driver-loop)

We can now execute code!

Page 26: Metacircular  Evaluation

Running(load "ch4-mcevalM.scm")(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 27: Metacircular  Evaluation

Driver Loop(define input-prompt ";;; M-Eval input:")(define output-prompt ";;; M-Eval value:")(define (driver-loop)  (prompt-for-input input-prompt)  (let ((input (read)))    (let ((output (eval input the-global-environment)))      (announce-output output-prompt)      (user-print output)))  (driver-loop))(define (prompt-for-input string)  (newline) (newline) (display string) (newline))

Page 28: Metacircular  Evaluation

Environments(define (setup-environment)

(let ((initial-env

(extend-environment (primitive-procedure-names)

(primitive-procedure-objects)

the-empty-environment)))

(define-variable! 'true true initial-env)

(define-variable! 'false false initial-env)

initial-env))