The metacircular evaluator (Cont.) - PowerPoint PPT Presentation

About This Presentation
Title:

The metacircular evaluator (Cont.)

Description:

6. Defining new procedures (define (lambda? e) (tag-check e 'lambda)) (define (eval exp env) ... (make-procedure (lambda-parameters exp) (lambda-body exp) env) ... – PowerPoint PPT presentation

Number of Views:23
Avg rating:3.0/5.0
Slides: 39
Provided by: duaneb3
Category:

less

Transcript and Presenter's Notes

Title: The metacircular evaluator (Cont.)


1
The metacircular evaluator (Cont.)
2
6. Defining new procedures   (define (lambda? e)
(tag-check e '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))
3
   (eval '(define twice (lambda (x) ( x x))) GE)
4
Implementation of lambda
  • (eval '(lambda (x) ( x x)) GE)
  • (eval-lambda '(lambda (x) ( x x)) GE)
  • (make-procedure '(x) (( x x)) GE)
  • (list procedure '(x) (( x x)) GE)

5
Naming the procedure
  • (eval '(define twice (lambda (x) ( x x)))
    GE)

names values z 9 true t twice
symbolprocedure
6
6. Defining new procedures   (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))
7
(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))
8
How the Environment Works
  • Abstractly in our environment diagrams
  • Concretely our implementation (as in SICP)

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

Concretely
10
(define (extend-environment vars vals base-env)
(if ( (length vars) (length vals)) (cons
(make-frame vars vals) base-env) (if (lt
(length vars) (length vals)) (error
"Too many arguments supplied" vars vals)
(error "Too few arguments supplied" vars
vals))))
11
(eval '(twice 4) GE)
12
Implementation of apply (1)
  • (eval '(twice 4) GE)
  • (apply (eval 'twice GE) (map (lambda (e)
    (eval e GE)) '(4)))
  • (apply (list 'procedure '(x) (( x x)) GE)
    '(4))
  • (eval-seq (( x x)) (extend-environment
    '(x) '(4) GE))
  • (eval '( x x) E1)

13
Implementation of apply (2)
  • (eval '( x x) E1)
  • (apply (eval E1) (map (lambda (e) (eval e
    E1)) '(x x)))
  • (apply '(primitive add) (list (eval 'x E1)
    (eval 'x E1)))
  • (apply '(primitive add) '(4 4))
  • (scheme-apply add '(4 4))
  • 8

14
"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

15
(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 (enclosing-environment env) (cdr env))
(define (frame-variables frame) (car
frame)) (define (frame-values frame) (cdr frame))
16
(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-define exp env) (let ((name
(cadr exp)) (defined-to-be (eval
(caddr exp) env))) (define-variable! name
defined-to-be env) undefined))
17
The Initial (Global) Environment
(define (setup-environment) (let ((initial-env
(extend-environment (primitive-procedure-n
ames)
(primitive-procedure-objects)
the-empty-environment)))
(define-variable! 'true t initial-env)
(define-variable! 'false f initial-env)
initial-env))
(define the-empty-environment '())
(define the-global-environment (setup-environment)
)
18
Is eval an iterative or recursive algorithm?
  • It depends on the scheme program being evaluated
  • 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

19
  • (eval '(define odd (lambda (n) (odd (- n
    2)))) GE)
  • gt undefined
  • (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) gt 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

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

21
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

22
SICPs version of 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-gtif exp) env)) ((application?
exp) (apply (eval (operator exp) env)
(list-of-values (operands exp)
env))) (else (error "Unknown
expression type -- EVAL" exp))))
23
Note some minor differences like
(define (self-evaluating? exp) (cond ((number?
exp) true) ((string? exp) true)
(else false)))
(define (variable? exp) (symbol? exp))
(define (list-of-values exps env) (if
(no-operands? exps) '() (cons (eval
(first-operand exps) env)
(list-of-values (rest-operands exps) env))))
24
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

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

26
Example Changing Syntax
  • Suppose you wanted a "verbose" application
    syntax
  • (CALL ltprocgt ARGS ltarg1gt ltarg2gt ...)
  • Changes only in the syntax routines!
  • (define (application? exp) (tagged-list? 'CALL))
  • (define (operator app) (cadr app))
  • (define (operands app) (cdddr app))

27
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 ((ltname1gt ltval1gt)
  • (ltname2gt ltval2gt))
  • ltbodygt)
  • ((lambda (ltname1gt ltname2gt) ltbodygt)
  • ltval1gt ltval2gt)

28
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-gtif exp) env))
  • ((let? exp)
  • (eval (let-gtcombination exp) env))
  • ((application? exp)
  • (apply (eval (operator exp) env)
  • (list-of-values
  • (operands exp)
    env)))
  • (else (error "Unknown expression" exp))))

29
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))
30
Cond syntax
(cond (( x 23) ( x 1)) (else (- x 1)))

cond
else
-
x

x

x
31
Transforming sequence of expression toan
expression
(define (sequence-gtexp seq) (cond ((null? seq)
seq) ((last-exp? seq) (first-exp seq))
(else (make-begin seq)))) (define
(make-begin seq) (cons 'begin seq))
32
Implementing cond (Cont.)
(cond (( x 23) ( x 1)) (else (- x 1)))

(if ( x 23) ( x 1) (- x 1))
33
Implementing cond
(define (cond-gtif 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-gtexp (cond-actions first))
(error "ELSE clause isn't last -- COND-gtIF"
clauses))
(make-if (cond-predicate first)
(sequence-gtexp (cond-actions first))
(expand-clauses rest))))))
34
Details of cond syntax transformation
(cond (( x 23) ( x 1)) (else (- x 1)))

cond
else
-
x

x

x
35
Details of cond syntax transformation
(expand-clauses
else
-
x

x
)

x
36
Details of cond syntax transformation
rest
first
else
-
x

x

x
37
Details of cond syntax transformation
(make-if
))
(expand-clauses
else
-
x
38
Details of cond syntax transformation
(make-if
)
39
Details of cond syntax transformation
if
40
Named Procedures Syntax vs. Semantics
  • (define (foo ltparmgt) ltbodygt)
  • Semantic implementation just another define
  • (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

41
Read-Eval-Print Loop
  • (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))

(define (prompt-for-input string) (newline)
(newline) (display string) (newline)) (define
(announce-output string) (newline) (display
string) (newline)) (define (user-print object)
(if (compound-procedure? object) (display
(list 'compound-procedure
(procedure-parameters object)
(procedure-body object)
'ltprocedure-envgt)) (display object)))
(define input-prompt " M-Eval input") (define
output-prompt " M-Eval value")
Write a Comment
User Comments (0)
About PowerShow.com