1 6.001 SICP Explicit-control evaluator Big ideas: how to connect evaluator to machine instructions how to achieve tail recursion Obfuscation: tightly.

Slides:



Advertisements
Similar presentations
How SAS implements structured programming constructs
Advertisements

Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
Scheme in Scheme?!? …the metacircular evaluator….
1 The metacircular evaluator Names Extend the calculator to store intermediate results as named values (define x (+ 4 5)) store result as x (+ x.
1 Programming Languages (CS 550) Operational Semantics of Scheme using Substitution and the Lambda Calculus Jeremy R. Johnson TexPoint fonts used in EMF.
Metacircular Evaluation SICP Chapter 4 Mark Boady.
1 Programming Languages (CS 550) Lecture 7 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts used in EMF. Read.
מבוא מורחב למדעי המחשב תרגול 13 Lazy Evaluation. Lazy Evaluation Implementation Two types of values – Delayed Values – Actual Values Introduce two functions.
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.
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 11. Metacircular Evaluator 4.1, pages definitions file on web 2.
(define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((list-form? exp) (eval-list.
1 Lecture 18 Continue Evaluator. 2 z9 true#t + twice Representing procedures (eval '(define twice (lambda (x) (+ x x))) GE) symbol primitive scheme procedure.
6.001 SICP 1 Normal (Lazy) Order Evaluation Memoization Streams.
David Evans CS200: Computer Science University of Virginia Computer Science Lecture 26: In Praise of Idleness.
Functional programming: LISP Originally developed for symbolic computing Main motivation: include recursion (see McCarthy biographical excerpt on web site).
Lexical vs. Dynamic Scope …where do I point to?. Intro… Remember in Scheme whenever we call a procedure we pop a frame and point it to where the procedure.
SICP Variations on a Scheme Scheme Evaluator – A Grand Tour Techniques for language design: Interpretation: eval/apply Semantics vs. syntax Syntactic.
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
Scheme More MCE examples. Q1 new special form which defines global variables (static ) search the global environment – Variable exists: does nothing,
SICP Variations on a Scheme (2) Beyond Scheme – designing language variants: Lazy evaluation Complete conversion – normal order evaluator Upward.
The environment model evaluator and compiler 1 The env model evaluator Motivation In one word: Efficiency Saves repeated renaming and substitution: Using.
1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.
1 Continue Evaluator. 2 z9 true#t + twice Representing procedures (eval '(define twice (lambda (x) (+ x x))) GE) symbol primitive scheme procedure + symbol.
1 The metacircular evaluator (Cont.) Defining new procedures (define (lambda? e) (tag-check e 'lambda)) (define (eval exp env) (cond ((number? exp)
CSC 3210 Computer Organization and Programming Chapter 1 THE COMPUTER D.M. Rasanjalee Himali.
1/ SICP Computability What we've seen... Deep question #1: –Does every expression stand for a value? Deep question #2: –Are there things we can't.
CS220 Programming Principles 프로그래밍의 이해 2002 가을학기 Class 15: Meta-Circular Evaluator 한 태숙.
COMPUTER PROGRAMMING. Iteration structures (loops) There may be a situation when you need to execute a block of code several number of times. In general,
The environment-based operational semantics Chapter
SICP Register Machines what and why datapaths instructions abstract operations.
ITCS 3181 Logic and Computer Systems 2015 B. Wilkinson Slides4-2.ppt Modification date: March 23, Procedures Essential ingredient of high level.
1 Lecture 20 Lazy Evaluation Continued (4.2.1, 4.2.2) MC-eval examples from exams (Time permitting)
1 Read-Eval-Print Loop (define (driver-loop) (prompt-for-input input-prompt) (let ((input (read))) (let ((output (eval input the-global-env))) (announce-output.
Basic Scheme February 8, 2007 Compound expressions Rules of evaluation Creating procedures by capturing common patterns.
1/33 Basic Scheme February 8, 2007 Compound expressions Rules of evaluation Creating procedures by capturing common patterns.
Programming Fundamentals. Topics to be covered Today Recursion Inline Functions Scope and Storage Class A simple class Constructor Destructor.
1 Programming Languages (CS 550) Lecture 4 Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10.
Fall 2008Programming Development Techniques 1 Topic 17 Assignment, Local State, and the Environment Model of Evaluation Section 3.1 & 3.2.
1 Lecture 19 Dynamic Scoping Lazy Evaluation (4.2.1, 4.2.2)
1/ SICP Variations on a Scheme Scheme Evaluator – A Grand Tour Making the environment model concrete Defining eval defines the language –Provides.
CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp.
1 Lecture 19 Review last lecture on evaluator, Dynamic Scoping Lazy Evaluation (4.2.1, 4.2.2)
1 The Evaluator. 2 Compiler vs. Interpreter Command Processing Unit The Computer Program in Low Level Machine Language Program in High Level Language.
Evaluators for Functional Programming 1. How to describe (specify) a programming language? 1.Syntax: atoms, primitives, combination and abstraction means.
6.037 Lecture 7B Scheme Variants Normal Order Lazy Evaluation Streams Edited by Mike Phillips & Ben Vandiver Original Material by Eric Grimson & Duane.
SICP Interpretation part 2 Store operators in the environment Environment as explicit parameter Defining new procedures.
CS314 – Section 5 Recitation 9
Operational Semantics of Scheme
Basic Scheme February 8, 2007 Compound expressions Rules of evaluation
6.001 SICP Variations on a Scheme
6.001 SICP Compilation Context: special purpose vs. universal machines
Env. Model Implementation
6.001 SICP Stacks and recursion
The Metacircular Evaluator
Lecture 23 Pages : Separating Syntactic Analysis from Execution. We omit many details so you have to read the section in the book. The halting.
Dynamic Scoping Lazy Evaluation
The Metacircular Evaluator
The Metacircular Evaluator (Continued)
6.001 SICP Further Variations on a Scheme
Streams, Delayed Evaluation and a Normal Order Interpreter
6.001 SICP Explicit-control evaluator
Languages and Compilers (SProg og Oversættere)
6.001 SICP Explicit-control evaluator
6.001 SICP Variations on a Scheme
Lecture 2 מבוא מורחב.
6.001 SICP Interpretation Parts of an interpreter
Introduction to the Lab
Lecture 2 מבוא מורחב.
Rehearsal: Lazy Evaluation Infinite Streams in our lazy evaluator
Presentation transcript:

SICP Explicit-control evaluator Big ideas: how to connect evaluator to machine instructions how to achieve tail recursion Obfuscation: tightly optimized instruction sequence Background eval-dispatch & helpers define, if, begin Applications

2 Code example: sfact (define sfact (lambda (n prod) (display prod) (if (= n 1) prod (sfact (- n 1) (* n prod))))) What is displayed when (sfact 4 1) executes? What is returned as the value? Does sfact describe an iterative or recursive process? iterative

3 Goal: a tail-recursive evaluator The stack should not grow if the procedure being evaluated is iterative Most Java, Pascal systems are not tail-recursive, so they cannot use recursive procedures as loops Key technique: tail-call optimization If optimization not used, stack grows each time around the loop: (eval-application '(sfact 4 1) GE) BOTTOM (eval-sequence '((display n) (if...)) E1) (eval '(if (= n 1)...) E1) (eval-if '(if (= n 1)...) E1) (eval '(sfact 3 4) E1) (eval-application '(sfact 3 4) E1) TOP Value needed at start is the same as value returned here

4 Example register machine: instructions (controller test-b (test (op =) (reg b) (const 0)) (branch (label gcd-done)) (assign t (op rem) (reg a) (reg b)) (assign a (reg b)) (assign b (reg t)) (goto (label test-b)) gcd-done) label operations

5 Register machine ab = 0 rem t instructions sequencer program counter condition sequencer: nextPC <- PC + 1 activate instruction at PC PC <- nextPC start again

6 Machine for EC-EVAL 7 registers expexpression to be evaluated envcurrent environment continuereturn point val resulting value unevlist of unevaluated expressions (operand lists, sequences) temporary register(elsewhere) procoperator value (apply only) arglargument values (apply only) Many abstract operations syntax, environment model, primitive procedures Eval Apply

7 Main entry point: eval-dispatch ; inputs: exp expression to evaluate ; env environment ; continue return point ; output: val value of expression ; writes: all (except continue) ; stack: unchanged eval-dispatch (test (op self-evaluating?) (reg exp)) (branch (label ev-self-eval)) (test (op variable?) (reg exp)) (branch (label ev-variable))... (goto (label unknown-expression-type))

8 Eval helpers: same contract as eval-dispatch ev-self-eval (assign val (reg exp)) (goto (reg continue)) return value is expression itself ev-variable (assign val (op lookup-variable-value) (reg exp) (reg env)) (goto (reg continue)) uses abstract op which is part of environment model

9 Eval helpers ev-lambda (assign unev (op lambda-parameters) (reg exp)) (assign exp (op lambda-body) (reg exp)) (assign val (op make-procedure) (reg unev) (reg exp) (reg env)) (goto (reg continue)) remember our Scheme code for this: (define (eval-lambda exp env) (make-procedure (lambda-parameters exp) (lambda-body exp) env)) exp and unev both used as temporary registers

10 Recursive call to eval: ev-definition ev-definition (assign unev (op definition-variable) (reg exp)) (save unev) (save env) (save continue) (assign exp (op definition-value) (reg exp)) (assign continue (label ev-definition-1)) (goto (label eval-dispatch)) ev-definition-1 (restore continue) (restore env) (restore unev) (perform (op define-variable!) (reg unev) (reg val) (reg env)) (assign val (const ok)) (goto (reg continue))

11 Ev-definition Why are unev, env, and continue saved? Used after recursive call, written by eval-dispatch Why is exp used in the recursive call? Specified as input register by eval-dispatch contract env is also specified as an input register, but not assigned Expression of define is evaluated in current environment Why is unev used in line 1? Temporary storage. Could use any other register.

12 Optimized recursive call to eval: ev-if ev-if (save exp) (save env) (save continue) (assign continue (label ev-if-decide)) (assign exp (op if-predicate) (reg exp)) (goto (label eval-dispatch)) ev-if-decide (restore continue) (restore env) (restore exp) (test (op true?) (reg val)) (branch (label ev-if-consequent)) ev-if-alternative (assign exp (op if-alternative) (reg exp)) (goto (label eval-dispatch)) ev-if-consequent (assign exp (op if-consequent) (reg exp)) (goto (label eval-dispatch)) Note – no stack usage for alternative or consequent

13 ev-if Normal recursive call to eval for predicate Tail-call optimization in both consequent and alternative no saves or restores this is necessary to make loops like sfact iterative Alternative case without the optimization: ev-if-alternative (save continue) (assign continue (label alternative1)) (assign exp (op if-alternative) (reg exp)) (goto (label eval-dispatch)) alternative1 (restore continue) (goto (reg continue))

14 Sequences (1) ; an eval helper, same contract as eval-dispatch ev-begin (save continue) (assign unev (op begin-actions) (reg exp)) (goto (label ev-sequence)) ; ev-sequence: used by begin and apply (lambda bodies) ; ; inputs: unev list of expressions ; env environment in which to evaluate ; stack top value is return point ; writes: all (calls eval without saving) ; output: val ; stack: top value removed

15 Sequences (2) ev-sequence (assign exp (op first-exp) (reg unev)) (test (op last-exp?) (reg unev)) (branch (label ev-sequence-last-exp)) (save unev) (save env) (assign continue (label ev-sequence-continue)) (goto (label eval-dispatch)) ev-sequence-continue (restore env) (restore unev) (assign unev (op rest-exps) (reg unev)) (goto (label ev-sequence)) ev-sequence-last-exp (restore continue) (goto (label eval-dispatch))

16 ev-sequence Tail-call optimization on eval of last expression in sequence necessary so loops like sfact are iterative Result should be in val, but never use val tail call to eval puts final result in val results of earlier calls to eval are ignored Why have return point on top of stack? avoid saving and restoring every time around loop purely a performance optimization can't do the same with unev and env because they are used inside the loop aka – a HACK!

17 Applications ev-application eval helper ev-appl-operator ev-appl-operand-loop apply-dispatch apply (eval (operator exp) env) (map (lambda (e) (eval e env)) (operands exp))

18 apply-dispatch ; inputs: proc procedure to be applied ; argl list of arguments ; stack top value is return point ; writes: all (calls ev-sequence) ; output: val ; stack: top value removed apply-dispatch (test (op primitive-procedure?) (reg proc)) (branch (label primitive-apply)) (test (op compound-procedure?) (reg proc)) (branch (label compound-apply)) (goto (label unknown-procedure-type))

19 Apply helpers primitive-apply (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) (restore continue) (goto (reg continue)) compound-apply (assign unev (op procedure-parameters) (reg proc)) (assign env (op procedure-environment) (reg proc)) (assign env (op extend-environment) (reg unev) (reg argl) (reg env)) (assign unev (op procedure-body) (reg proc)) (goto (label ev-sequence))

20 apply-dispatch Why have return point on top of stack? ev-sequence needs it on top of stack has to be saved on stack to do ev-appl-operator performance optimization: leave it on stack if possible compound-apply Calls ev-sequence rather than eval-dispatch Body of procedure might be a sequence Tail-call optimization Necessary for tail recursion Env and unev used as part of call required by ev-sequence contract Env and unev used in first two lines Local temporaries. Could use any register.

21 ev-application (save continue) ev-appl-operator (assign unev (op operands) (reg exp)) (save env) (save unev) (assign exp (op operator) (reg exp)) (assign continue (label ev-appl-did-operator)) (goto (label eval-dispatch)) ev-appl-did-operator (restore unev) (restore env) (assign proc (reg val))

22 ev-application Leave continue on the stack, untouched, until –primitive-apply, OR –end of ev-sequence of body in compound-apply ev-appl-operator Normal call to eval-dispatch unev : save the list of operand expressions env : will be needed to evaluate operand expressions At end: Put operator in proc. Why use proc ? Answer: If there are no arguments, will call apply- dispatch immediately (next slide)

23 Map over list of operand expressions (assign argl (op empty-arglist)) (test (op no-operands?) (reg unev)) (branch (label apply-dispatch)) (save proc) ev-appl-operand-loop (save argl) (assign exp (op first-operand) (reg unev)) (test (op last-operand?) (reg unev)) (branch (label ev-appl-last-arg)) ;; eval one operand (next slide) ev-appl-last-arg (assign continue (label ev-appl-accum-last-arg)) (goto (label eval-dispatch)) ev-appl-accum-last-arg (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl)) (restore proc) (goto (label apply-dispatch))

24 Eval one operand (save env) (save unev) (assign continue (label ev-appl-accumulate-arg)) (goto (label eval-dispatch)) ev-appl-accumulate-arg (restore unev) (restore env) (restore argl) (assign argl (op adjoin-arg) (reg val) (reg argl)) (assign unev (op rest-operands) (reg unev)) (goto (label ev-appl-operand-loop))

25 ev-appl-operand-loop First three lines: check for no operands (avoid first-operand on empty) Why save proc at beginning, restore at very end? call eval in loop, its contract says it writes proc one of the operand expressions might be an application Same reasoning applies to argl Why save argl inside the loop, proc outside it? need to change argl every time around the loop Why is (save argl) before the branch to ev-appl-last-arg? logically goes with the saves in eval one operand a needless optimization that saves one instruction

26 Trial simulation Label Exp Env Val Proc Argl Unev Cont Stack Eval (fact 3) GE REP Eval fact GE (3) didop REP GE (3) Didop fact GE [proc] (3) didop REP GE (3) Oploop fact GE [proc] [proc] () (3) didop REP [proc] Lastarg 3 GE [proc] [proc] () (3) didop REP [proc] () Eval 3 GE [proc] [proc] () (3) a-l-a REP [proc] () A-l-a 3 GE 3 [proc] () (3) a-l-a REP [proc] () Apply 3 GE 3 [proc] (3) (3) a-l-a REP Seq 3 E1 3 [proc] (3) ((if.)) a-l-a REP Seqlst (if..) E1 3 [proc] (3) ((if.)) a-l-a REP Eval (if..) E1 3 [proc] (3) ((if.)) REP

27 Trial simulation Label Exp Env Val Proc Argl Unev Cont Stack Eval (fact 3) GE REP …skip some steps… Eval (if..) E1 3 [proc] (3) ((if.)) REP Eval (= n 1) E1 3 [proc] (3) ((if.)) dec (if.) E1 REP …skip some steps – contract says that when get to decide we have… Dec (= n 1) E1 #f [proc] (3) ((if.)) dec (if.) E1 REP Eval (* n (f.)) E1 #f [proc] (3) ((if.)) REP Eval * E1 #f [proc] (3) (n (f.)) did REP E1 (n (f.)) Did * E1 [mul] [proc] (3) (n (f.)) did REP E1 (n (f.)) Oploop * E1 [mul] [mul] () (n (f.)) did REP [mul] …skip some steps – just look up value of n, then get to… Eval (f..) E1 [mul] (3) ((f.)) a-l-a REP [mul] (3)

28 Trial simulation Label Exp Env Val Proc Argl Unev Cont Stack Eval (fact 3) GE REP …skip some steps… Eval (fact E1 a-l-a REP [mul] (3) (- n 1)) …skip some steps – by contract, know that we get to… Eval (fact E2 a-l-a REP [mul] (3) (- n 1)) a-l-a [mul] (2)

29 Summary Have seen details of EC-EVAL Differentiated necessary optimizations for tail recursion performance optimizations Key idea is that we can connect evaluation through a machine model to support idea of universal evaluation