Original material by Eric Grimson

Slides:



Advertisements
Similar presentations
1 Programming Languages (CS 550) Mini Language Interpreter Jeremy R. Johnson.
Advertisements

Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is a good way to learn more about programming languages  Interpreters are.
1 Programming Languages (CS 550) Lecture Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
Chapter 3 Functional Programming. Outline Introduction to functional programming Scheme: an untyped functional programming language.
1 The metacircular evaluator Names Extend the calculator to store intermediate results as named values (define x (+ 4 5)) store result as x (+ x.
Metacircular Evaluation SICP Chapter 4 Mark Boady.
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.
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 SICP – October environment Trevor Darrell 32-D512 Office Hour: W web page:
Functional programming: LISP Originally developed for symbolic computing Main motivation: include recursion (see McCarthy biographical excerpt on web site).
SICP Interpretation part 1 Parts of an interpreter Arithmetic calculator Names Conditionals and if Store procedures in the environment.
6.001 SICP SICP – Evaluation I Recitation 11/19/2004 Eval review Evaluation examples define lambda apply New language elements.
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.
1 Continue Evaluator. 2 z9 true#t + twice Representing procedures (eval '(define twice (lambda (x) (+ x x))) GE) symbol primitive scheme procedure + symbol.
Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is aa good way to learn more about programming languages  Interpreters are.
1 The metacircular evaluator (Cont.) Defining new procedures (define (lambda? e) (tag-check e 'lambda)) (define (eval exp env) (cond ((number? exp)
Functional Programming Universitatea Politehnica Bucuresti Adina Magda Florea
CS220 Programming Principles 프로그래밍의 이해 2002 가을학기 Class 15: Meta-Circular Evaluator 한 태숙.
SICP Interpretation Parts of an interpreter Arithmetic calculator Names Conditionals and if Storing procedures in the environment Environment as.
1 The Evaluator. 2 Compiler vs. Interpreter Command Processing Unit The Computer Program in Low Level Machine Language Program in High Level Language.
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 Lecture 14: Assignment and the Environment Model (EM)
1/33 Basic Scheme February 8, 2007 Compound expressions Rules of evaluation Creating procedures by capturing common patterns.
1 Programming Languages (CS 550) Lecture 4 Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
1/ SICP Variations on a Scheme Scheme Evaluator – A Grand Tour Making the environment model concrete Defining eval defines the language –Provides.
Scheme in Scheme 2. What’s next  Adding set!  Dynamic vs. lexical variable scope  Extending mcscheme v1 with libraries  Can mcscheme execute mcscheme?
1 Vectors, binary search, and sorting. 2 We know about lists O(n) time to get the n-th item. Consecutive cons cell are not necessarily consecutive in.
SICP Interpretation part 2 Store operators in the environment Environment as explicit parameter Defining new procedures.
CS314 – Section 5 Recitation 9
Scheme in Scheme 1.
Operational Semantics of Scheme
Lecture 4: Metacircles Eval Apply David Evans
Abstract Syntax cs7100 (Prasad) L7AST.
Basic Scheme February 8, 2007 Compound expressions Rules of evaluation
Edited by Original material by Eric Grimson
6.001 SICP Variations on a Scheme
6.001 SICP Object Oriented Programming
The interpreter.
Interpreters Study Semantics of Programming Languages through interpreters (Executable Specifications) cs7100(Prasad) L8Interp.
The role of abstractions
September 4, 1997 Programming Languages (CS 550) Lecture 6 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts.
Env. Model Implementation
Nondeterministic Evaluation
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.
Abstract Syntax Prabhaker Mateti 1.
Dynamic Scoping Lazy Evaluation
The Metacircular Evaluator
What would be our focus ? Geometry deals with Declarative or “What is” knowledge. Computer Science deals with Imperative or “How to” knowledge 12/25/2018.
The Metacircular Evaluator (Continued)
Lecture 26: The Metacircular Evaluator Eval Apply
6.001 SICP Further Variations on a Scheme
Streams, Delayed Evaluation and a Normal Order Interpreter
Lecture #9 מבוא מורחב.
Lecture 12: Message passing The Environment Model
Lecture 13 - Assignment and the environments model Chapter 3
What would be our focus ? Geometry deals with Declarative or “What is” knowledge. Computer Science deals with Imperative or “How to” knowledge 2/23/2019.
6.001 SICP Environment model
6.001 SICP Explicit-control evaluator
6.001 SICP Explicit-control evaluator
6.001 SICP Variations on a Scheme
6.001 SICP Interpretation Parts of an interpreter
Introduction to the Lab
topics interpreters meta-linguistic abstraction eval and apply
Rehearsal: Lazy Evaluation Infinite Streams in our lazy evaluator
Lecture 25: The Metacircular Evaluator Eval Apply
Presentation transcript:

Original material by Eric Grimson 6.037 Lecture 4 Interpretation Original material by Eric Grimson Tweaked by Zev Benjamin, Nelson Elhage, Keegan McAllister, Mike Phillips, Alex Vandiver, Ben Vandiver, Leon Shen 1

Interpretation Parts of an interpreter Arithmetic calculator Meta-circular Evaluator (Scheme-in-scheme!) A slight variation: dynamic scoping 2 2 2

What is an interpreter? Interpreter Description of Computation Results Update of internal state 3 3 3

Why do we need an interpreter? Abstractions let us bury details and focus on use of modules to solve large systems We need a process to unwind abstractions at execution time to deduce meaning We have already seen such a process – the Environment Model Now want to describe that process as a procedure 4 4

Stages of an interpreter input to each stage Lexical analyzer "(average 40 (+ 5 5))" ( average 40 + 5 ) Parser 40 symbol average 5 symbol + average: <proc> +: <proc> ... Evaluator Printer 25 "25" 5 5

Role of each part of the interpreter Lexical analyzer break up input string into "words" called tokens Parser convert linear sequence of tokens to a tree like diagramming sentences in elementary school also convert self-evaluating tokens to their internal values e.g., #f is converted to the internal false value Evaluator follow language rules to convert parse tree to a value read and modify the environment as needed Printer convert value to human-readable output string 6 6

Our interpreters Only write evaluator and environment Use Scheme's reader for lexical analysis and parsing Use Scheme's printer for output To do this, our language must resemble Scheme Start with interpreter for simple arithmetic expressions 7 7

Arithmetic calculator Want to evaluate arithmetic expressions of two arguments, like: (plus* 24 (plus* 5 6)) 8 8

Arithmetic calculator (define (tag-check e sym) (and (pair? e) (eq? (car e) sym))) (define (sum? e) (tag-check e 'plus*))   (define (eval exp) (cond ((number? exp) exp) ((sum? exp) (eval-sum exp)) (else (error "unknown expression " exp)))) (define (eval-sum exp) (+ (eval (cadr exp)) (eval (caddr exp)))) (eval '(plus* 24 (plus* 5 6))) 9 9

We are just walking through a tree … 24 plus* 6 5 (eval ) 24 plus* 6 5 sum? checks the tag 10 10

We are just walking through a tree … (eval-sum ) 24 plus* 6 5 6 5 plus* (+ (eval 24) (eval )) (+ (eval 5) (eval 6)) 11 11

Arithmetic calculator (plus* 24 (plus* 5 6)) What are the argument and return values of eval each time it is called in the evaluation of this expression? (eval 5) 5 (eval 6) 6 (eval-sum '(plus* 5 6)) 11 (eval 24) 24 (eval '(plus* 5 6)) 11 (eval-sum '(plus* 24 (plus* 5 6))) 35 (eval '(plus* 24 (plus* 5 6))) 35 12 12

Things to observe cond determines the expression type No work to do on numbers Scheme's reader has already done the work It converts a sequence of characters like "24" to an internal binary representation of the number 24 …self-evaluating! eval-sum recursively calls eval on both argument expressions 13 13

The Metacircular Evaluator And now a complete Scheme interpreter written in Scheme Why? An interpreter makes things explicit e.g., procedures and procedure application in the environment model Provides a precise definition for what the Scheme language means Describing a process in a computer language forces precision and completeness Sets the foundation for exploring variants of Scheme Today: lexical vs. dynamic scoping 14

The Core Evaluator 1. eval/apply core apply eval Core evaluator proc args env expr (define (square x) (* x x)) (square 4) x = 4 (* x x) Core evaluator eval: evaluate expression by dispatching on type apply: apply procedure to argument values by evaluating procedure body 15 15

Metacircular evaluator (Scheme implemented in Scheme) (define (m-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) (m-eval (cond->if exp) env)) ((application? exp) (m-apply (m-eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression type -- EVAL" exp)))) primitives special forms application 17

Pieces of Eval&Apply (define (m-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) (m-apply (m-eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression type -- EVAL" exp)))) 18

Pieces of Eval&Apply (define (list-of-values exps env) (map (lambda (exp) (m-eval exp env)) exps)) 19

m-apply (define (m-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)))) 20

Side comment – procedure body The procedure body is a sequence of one or more expressions: (define (foo x) (do-something (+ x 1)) (* x 5)) In m-apply, we eval-sequence the procedure body. 21 21

Pieces of Eval&Apply (define (eval-sequence exps env) (cond ((last-exp? exps) (m-eval (first-exp exps) env)) (else (m-eval (first-exp exps) env) (eval-sequence (rest-exps exps) env)))) 22

Pieces of Eval&Apply (define (m-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) (m-apply (m-eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression type -- EVAL" exp)))) 23

Pieces of Eval&Apply (define (eval-assignment exp env) (set-variable-value! (assignment-variable exp) (m-eval (assignment-value exp) exp) env)) (define (eval-definition exp env) (define-variable! (definition-variable exp) (m-eval (definition-value exp) env) 24

Pieces of Eval&Apply (define (m-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) (m-apply (m-eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression type -- EVAL" exp)))) 25

Pieces of Eval&Apply (define (eval-if exp env) (if (m-eval (if-predicate exp) env) (m-eval (if-consequent exp) env) (m-eval (if-alternative exp) env))) 26

Pieces of Eval&Apply (define (m-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) (m-apply (m-eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression type -- EVAL" exp)))) 27

Implementation of lambda (eval '(lambda (x) (+ x x)) GE) (make-procedure '(x) '((+ x x)) GE) (list 'compound '(x) '((+ x x)) GE) This data structure is a procedure! + x GE compound 28 28

How the Environment Works manipulation 3. How the Environment Works E2 x: 10 plus: (procedure ...) E1 Abstractly – in our environment diagrams: Concretely – our implementation (as in textbook) list of values enclosing- environment list of variables frame x plus 10 E2 procedure 29 29

Extending the Environment plus: (procedure ...) E3 x: 4 y: 5 (extend-environment '(x y) '(4 5) E2) Abstractly Concretely E2 list of values list of variables frame x y 4 E3 5 E1 E3 (((x y) . (4 5)) ((x plus) . (10 (proc ..))) E1) E2 30 30

"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 (i.e. we reached end of list of vars), look in enclosing environment 31 31

Scanning the environment (details) (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 -- LOOKUP" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env)) 32

The Initial (Global) Environment primitives and initial env. 4. setup-environment (define (setup-environment) (let ((initial-env (extend-environment (primitive-procedure-names) (primitive-procedure-objects) the-empty-environment))) (define-variable! 'true #T initial-env) (define-variable! 'false #F initial-env) initial-env)) define initial variables we always want bind explicit set of "primitive procedures" here: use underlying Scheme procedures in other interpreters: assembly code, hardware, .... 33 33

Syntactic Abstraction syntax procedures 2. 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 syntax procedures eval/apply 34 34

Basic Syntax Routines to detect expressions (define (tagged-list? exp tag) (and (pair? exp) (eq? (car exp) tag))) 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)) Routines to manipulate expressions (define (no-operands? args) (null? args)) (define (first-operand args) (car args)) (define (rest-operands args) (cdr args)) 35 35

Example – Changing Syntax Suppose you wanted a "verbose" application syntax, i.e., instead of (<proc> <arg1> <arg2> . . .) use (CALL <proc> ARGS <arg1> <arg2> ...) Changes – only in the syntax routines! (define (application? exp) (tagged-list? exp 'CALL)) (define (operator app) (cadr app)) (define (operands app) (cdddr app)) 36 36

Implementing "Syntactic Sugar" Idea: Easy way to add alternative/convenient syntax Allows us to implement a simpler "core" in the evaluator, and support the alternative syntax by translating it into core syntax "let" as sugared procedure application: (let ((<name1> <val1>) (<name2> <val2>)) <body>) ((lambda (<name1> <name2>) <body>) <val1> <val2>) 37 37

Detect and Transform the Alternative Syntax (define (m-eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((quoted? exp) (text-of-quotation exp)) ... ((let? exp) (m-eval (let->combination exp) env)) ((application? exp) (m-apply (m-eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression" exp)))) 38 38

Let Syntax Transformation FROM (let ((x 23) (y 15)) (dosomething x y)) TO ( (lambda (x y) (dosomething x y)) 23 15 ) 39 39

Let Syntax Transformation (define (let? exp) (tagged-list? exp 'let)) (define (let-bound-variables let-exp) (map car (cadr let-exp))) (define (let-values let-exp) (map cadr (cadr let-exp))) (define (let-body let-exp) (cddr let-exp)) (define (let->combination let-exp) (let ((names (let-bound-variables let-exp)) (values (let-values let-exp)) (body (let-body let-exp))) (cons (make-lambda names body) values))) NOTE: only manipulates list structure, returning new list structure that acts as an expression 40 40

Details of let syntax transformation (let ((x 23) (y 15)) (dosomething x y)) let y x dosomething 23 15 41 41

Details of let syntax transformation dosomething 23 15 15 23 lambda y x dosomething y x 42 42

Defining Procedures (define foo (lambda (x) <body>)) (define (foo x) <body>) Semantic implementation – just another define: (define (eval-definition exp env) (define-variable! (definition-variable exp) (m-eval (definition-value exp) env) env)) Syntactic transformation: (define (definition-value exp) (if (symbol? (cadr exp)) (caddr exp) (make-lambda (cdadr exp) ;formal params (cddr exp)))) ;body 43 43

Read-Eval-Print Loop 5. read-eval-print loop (define (driver-loop) (prompt-for-input input-prompt) (let ((input (read))) (let ((output (m-eval input the-global-env))) (announce-output output-prompt) (display output))) (driver-loop)) 44 44

Variations on a Scheme More (not-so) stupid syntactic tricks Let with sequencing (let* ((x 4) (y (+ x 1))) . . . ) Infix notation ((4 * 3) + 7) instead of (+ (* 4 3) 7) Semantic variations Lexical vs dynamic scoping Lexical: defined by the program text Dynamic: defined by the runtime behavior 45

Diving in Deeper: Lexical Scope Scoping is about how free variables are looked up (as opposed to bound parameters) (lambda (x) (* x x)) How does our evaluator achieve lexical scoping? environment chaining procedures capture their enclosing lexical environment * is free x is bound (define (foo x y) …) (define (bar l) (define (baz m) …) …) 46 46

Diving in Deeper: Lexical Scope Why is our language lexically scoped? Because of the semantic rules we use for procedure application: “Drop a new frame" “Bind parameters to actual args in the new frame“ “Link frame to the environment in which the procedure was defined” (i.e., the environment surrounding the procedure in the program text) “Evaluate body in this new environment" (define (foo x y) …) (define (bar l) (define (baz m) …) …) 47 47

Lexical Scope & Environment Diagram (define (foo x y) (lambda (z) (+ x y z))) Will always evaluate (+ x y z) in a new environment inside the surrounding lexical environment. (define bar (foo 1 2)) (bar 3) GE p: x y body: ( (z) (+ x y z)) foo: bar: E1 x: 1 y: 2 p: z body: (+ x y z) z: 3 E2 (+ x y z) | E2 => 6 48 48

Suppose we use our usual environment model rules... Alternative Model: Dynamic Scoping Dynamic scope: Look up free variables in the caller's environment rather than the surrounding lexical environment Example: (define (pooh x) (bear 20)) (define (bear y) (+ x y)) (pooh 9) Suppose we use our usual environment model rules... pooh bear p: x b: (bear 20) p: y b: (+ x y) x: 9 (bear 20) y: 20 (+ x y) x not found 49 49

Dynamic Scope & Environment Diagram (define (pooh x) (bear 20)) Will evaluate (+ x y) in an environment that extends the caller's environment. (define (bear y) (+ x y)) (pooh 9) GE p: x body: (bear 20) pooh: bear: p: y body: (+ x y x: 9 E1 y: 20 E2 (+ x y) | E2 => 29 50 50

A "Dynamic" Scheme (define (m-eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ... ((lambda? exp) (make-procedure (lambda-parameters exp) (lambda-body exp) '*no-environment*)) ;CHANGE: no env ((application? exp) (d-apply (m-eval (operator exp) env) (list-of-values (operands exp) env) env)) ;CHANGE: add env (else (error "Unknown expression -- M-EVAL" exp)))) 51 51

A "Dynamic" Scheme – d-apply (define (d-apply procedure arguments calling-env) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments calling-env))) ;CHANGE: use calling env (else (error "Unknown procedure" procedure)))) 52 52

Evaluator Summary Scheme Evaluator – Know it Inside & Out Techniques for language design: Interpretation: eval/apply Semantics vs. syntax Syntactic transformations Able to design new language variants! Lexical scoping vs. Dynamic scoping 53 53