1 / 28

Metacircular Evaluation

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

bruno
Download Presentation

Metacircular Evaluation

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Metacircular Evaluation SICP Chapter 4 Mark Boady

  2. 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 • Why? • Extending an interpreted language • Debuggers

  3. Jikes RVM • A Java Research Virtual Machine written in Java • The RVM runs on the JVM • Used For Research in: • Garbage Collection • Dynamic Parallelization • Machine Learning for dynamic compilation • Dynamic Typing • Distributed VM

  4. Scheme Metacircular Evaluator • Eval • Takes an expression and an Environment • Environment = Variable Names and Values • Returns the result of evaluating the expression • Apply • Takes a Procedure and a list of arguments • Produces an expression for eval • (+ (* 4 5) 6)

  5. Eval Definition (define (evalexpenv)
  (cond ((self-evaluating? exp) exp)
        ((variable? exp) (lookup-variable-value expenv))
        ((quoted? exp) (text-of-quotation exp))
        ((assignment? exp) (eval-assignment expenv))
        ((definition? exp) (eval-definition expenv))
        ((if? exp) (eval-if expenv))
        ((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))))

  6. (define (bevalexpenv) (cond ((boolean? exp) exp) ((conjunct? exp) (beval-and expenv)) ((disjunct? exp) (beval-or expenv)) ((negate? exp) (beval-not expenv)) ((variable? exp) ... ; You'll need to supply your own function that takes a frame, returns the assoc. value (else (error "beval: illegal syntax")))))

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

  8. 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 • Apply • Determine the type of procedure • Add to the environment • Pass control to Eval

  9. Concept • We 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 procedure • Apply performs the actual procedure • With a primitive (like +) the underlying language handles it • With a custom procedure, we need to pass back to eval

  10. Metacircular

  11. Basic Example • (eval ‘(+ a 5) ‘((a 10) (b 7)) • Evaluate the expression a+5 with the variables a=10, b=7 • Eval starts with a procedure and sees it is an apply • Eval evaluates the inputs to the procedure • Looks up variable values in this case • Apply is asked to handle with (+ 10 5) • Apply can determine 10+5=15 using the underlying system

  12. Details • Getting the arguments of a Procedure • (apply (eval (operator exp) env)
                (list-of-values (operands exp) env))) • (define (list-of-values expsenv)
  (if (no-operands? exps)
      '()
      (cons (eval (first-operand exps) env)
            (list-of-values (rest-operands exps) env))))

  13. If Statements • (define (eval-if expenv)
  (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? (cdddrexp))) (cadddrexp) 'false))

  14. Evaluating Sequences • (define (eval-sequence expsenv)
  (cond ((last-exp? exps) (eval (first-expexps) env))
        (else (eval (first-expexps) env)
              (eval-sequence (rest-expsexps) env)))) • Evaluate the sequence of expressions in a procedure body

  15. Assigning Variables • (define (eval-assignment expenv)
  (set-variable-value! (assignment-variable exp)
                       (eval (assignment-value exp) env)
                       env)
  'ok) • set-variable-value! Bounds a value to a name

  16. Expressions • Basic functionality is implemented directly • Assignment • (define (assignment? exp)
  (tagged-list? exp 'set!))
(define (assignment-variable exp) (cadrexp))
(define (assignment-value exp) (caddrexp)) • Derived Expressions • Some functionality is implemented using existing functionality • Cond can be transformed into if statements • Let statements can be transformed in lambda expressions

  17. Derived Expressions • Let expressions are derived expressions, because • (let ((<var1> <exp1>) ... (<varn> <expn>))
  <body>) • is equivalent to • ((lambda (<var1> ... <varn>)
   <body>)
 <exp1>
 ...<expn>)

  18. Derived Expressions • (let ((a 4) (b 6)) (+ a b)) • Value 10 • ( (lambda (a b) (+ a b)) 4 6) • Value 10 • Wecanwrite a commandthatwilltranslate a let to a lambda. • Let eval handle the lambda commandusingexistingtools.

  19. 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>.

  20. 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.

  21. Environments • There are multiple scopes in the environment • We make changes to the most recent • Example: • Initial memory: ( ( (a b) (5 7) ) ) • A new function is called with inputs b=6, c=7 • We push a new set of variables into the environment • New Memory: ( ( (b c) (6 7) ) ( (a b) (5 7) ) ) • When the function call is over we remove it from the environment • New Memory: ( ( (a b) (5 7) ) )

  22. Environments (define (lookup-variable-value varenv)
  (define (env-loop env)
    (define (scan varsvals)
      (cond ((null? vars)
             (env-loop (enclosing-environment env)))
            ((eq? var (car vars))
             (car vals))
            (else (scan (cdrvars) (cdrvals)))))
    (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))

  23. Environments (define (lookup-variable-value varenv) (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 varsvals)       (cond ((null? vars) (env-loop (enclosing-environment env)))         ((eq? var (car vars)) (car vals))         (else (scan (cdrvars) (cdrvals))) ) )

  24. Primitives (define primitive-procedures (list (list 'car car) (list 'cdrcdr) (list 'cons cons) (list 'null? null?) (list '- -) (list '+ +) )) (define (apply-primitive-procedure procargs)
  (apply-in-underlying-scheme
   (primitive-implementation proc) args))

  25. Running the Evaluator • Load 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!

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

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

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

More Related