CS61A Notes Week 13: Interpreters

Similar documents
TAIL RECURSION, SCOPE, AND PROJECT 4 11

6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

Logo Features We'll first present a sample Logo program, and then discuss each component separately.

6.037 Lecture 4. Interpretation. What is an interpreter? Why do we need an interpreter? Stages of an interpreter. Role of each part of the interpreter

SCHEME AND CALCULATOR 5b

STRUCTURE AND INTERPRETATION COMPUTER PROGRAMS >>> COMPUTER SCIENCE IN THE NEWS. CS61A Lecture 23 Py TODAY REVIEW: INTERPRETATION 7/26/2012 READ PRINT

UNIVERSITY of CALIFORNIA at Berkeley Department of Electrical Engineering and Computer Sciences Computer Sciences Division

STRUCTURE AND INTERPRETATION COMPUTER PROGRAMS COMPUTER SCIENCE IN THE NEWS. CS61A Lecture 23 Py TODAY 7/26/2012

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

ENVIRONMENT DIAGRAMS AND RECURSION 2

INTERPRETERS 8. 1 Calculator COMPUTER SCIENCE 61A. November 3, 2016

Discussion 12 The MCE (solutions)

CS61A Lecture 23 Py. Jom Magrotker UC Berkeley EECS July 26, 2012

Programming Project #4: A Logo Interpreter Summer 2005

Key Differences Between Python and Java

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

CS61A Discussion Notes: Week 11: The Metacircular Evaluator By Greg Krimer, with slight modifications by Phoebus Chen (using notes from Todd Segal)

Functional Programming. Pure Functional Programming

Parsing Scheme (+ (* 2 3) 1) * 1

Interpreters and Tail Calls Fall 2017 Discussion 8: November 1, 2017 Solutions. 1 Calculator. calc> (+ 2 2) 4

CS61A Summer 2010 George Wang, Jonathan Kotker, Seshadri Mahalingam, Eric Tzeng, Steven Tang

Sprite an animation manipulation language Language Reference Manual

CS61A Notes Week 1A: Basics, order of evaluation, special forms, recursion

Building up a language SICP Variations on a Scheme. Meval. The Core Evaluator. Eval. Apply. 2. syntax procedures. 1.

INTERPRETERS AND TAIL CALLS 9

Public-Service Announcement

Basic Syntax - First Program 1

TUPLES AND RECURSIVE LISTS 5

EXPRESSIONS, STATEMENTS, AND FUNCTIONS 1

Fall Semester, The Metacircular Evaluator. Today we shift perspective from that of a user of computer langugaes to that of a designer of

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

Turtles All The Way Down

\n is used in a string to indicate the newline character. An expression produces data. The simplest expression

Typescript on LLVM Language Reference Manual

Chapter 1 Summary. Chapter 2 Summary. end of a string, in which case the string can span multiple lines.

Streams, Delayed Evaluation and a Normal Order Interpreter. CS 550 Programming Languages Jeremy Johnson

Intro. Scheme Basics. scm> 5 5. scm>

Python Boot Camp. Day 3

Assignment 7: functions and closure conversion (part 1)

Spring 2018 Discussion 7: March 21, Introduction. 2 Primitives

VLC : Language Reference Manual

MORE SCHEME. 1 What Would Scheme Print? COMPUTER SCIENCE MENTORS 61A. October 30 to November 3, Solution: Solutions begin on the following page.

61A Lecture 2. Wednesday, September 4, 2013

Final Exam Solutions. Structure and Interpretation of Computer Programs. Fall 2011 /12 /16 /12 /18 /10 /12 /80 INSTRUCTIONS

SCHEME INTERPRETER GUIDE 4

Fall 2017 Discussion 7: October 25, 2017 Solutions. 1 Introduction. 2 Primitives

ENVIRONMENT MODEL: FUNCTIONS, DATA 18

EXPRESSIONS, STATEMENTS, AND FUNCTIONS 1

There are four numeric types: 1. Integers, represented as a 32 bit (or longer) quantity. Digits sequences (possibly) signed are integer literals:

CS 61A Interpreters, Tail Calls, Macros, Streams, Iterators. Spring 2019 Guerrilla Section 5: April 20, Interpreters.

Intro. Classes & Inheritance

Flow Control: Branches and loops

Introduction to Computer Programming CSCI-UA 2. Review Midterm Exam 1

Operational Semantics of Cool

Functions CHAPTER 5. FIGURE 1. Concrete syntax for the P 2 subset of Python. (In addition to that of P 1.)

CS109A ML Notes for the Week of 1/16/96. Using ML. ML can be used as an interactive language. We. shall use a version running under UNIX, called

Lexical vs. Dynamic Scope

The SPL Programming Language Reference Manual

Operational Semantics. One-Slide Summary. Lecture Outline

Control and Environments Fall 2017 Discussion 1: August 30, Control. If statements. Boolean Operators

CONTROL AND ENVIRONMENTS 1

Implementing Recursion

Environment Diagrams. Administrivia. Agenda Step by Step Environment Diagram Stuff. The Rules. Practice it s on! What are The Rules?

VENTURE. Section 1. Lexical Elements. 1.1 Identifiers. 1.2 Keywords. 1.3 Literals

In addition to the correct answer, you MUST show all your work in order to receive full credit.

Functions CHAPTER 5. FIGURE 1. Concrete syntax for the P 2 subset of Python. (In addition to that of P 1.)

This exam is worth 70 points, or about 23% of your total course grade. The exam contains 15 questions.

Why do we need an interpreter? SICP Interpretation part 1. Role of each part of the interpreter. 1. Arithmetic calculator.

The PCAT Programming Language Reference Manual

Scheme Basics > (butfirst '(help!)) ()

Lexical Considerations

d-file Language Reference Manual

C ONTROL AND H IGHER O RDER F UNCTIONS

CS61A Midterm 2 Review (v1.1)

Lecture Outline. COOL operational semantics. Operational Semantics of Cool. Motivation. Notation. The rules. Evaluation Rules So Far.

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8

Programming Languages Third Edition

Introduction to Scheme

GIS 4653/5653: Spatial Programming and GIS. More Python: Statements, Types, Functions, Modules, Classes

Variables, expressions and statements

CS1 Lecture 3 Jan. 22, 2018

Assignment 7: functions and closure conversion

DINO. Language Reference Manual. Author: Manu Jain

Lexical Considerations

Control and Environments Fall 2017 Discussion 1: August 30, 2017 Solutions. 1 Control. If statements. Boolean Operators

61A Lecture 2. Friday, August 28, 2015

Principles of Programming Languages 2017W, Functional Programming

April 2 to April 4, 2018

The Environment Model. Nate Foster Spring 2018

CS 61A Control and Environments Spring 2018 Discussion 1: January 24, Control. If statements. Boolean Operators

MetacircularScheme! (a variant of lisp)

CMSC 330: Organization of Programming Languages

DRAWING ENVIRONMENT DIAGRAMS

Variables. Substitution

INF4820: Algorithms for Artificial Intelligence and Natural Language Processing. Common Lisp Fundamentals

Spoke. Language Reference Manual* CS4118 PROGRAMMING LANGUAGES AND TRANSLATORS. William Yang Wang, Chia-che Tsai, Zhou Yu, Xin Chen 2010/11/03

COSC252: Programming Languages: Semantic Specification. Jeremy Bolton, PhD Adjunct Professor

Programming Languages

DaMPL. Language Reference Manual. Henrique Grando

Environments

Transcription:

CS61A Notes Week 13: Interpreters Read-Eval Loop Unlike Python, the result of evaluating an expression is not automatically printed. Instead, Logo complains if the value of any top-level expression is not None.? 2 You do not say what to do with 2. In Logo, any top-level expression (i.e., an expression that is not an operand of another expression) must evaluate to None. The print procedure always outputs None, and so printing does not cause an error. Multiple call expressions may appear on the same line of Logo, and the interpreter will evaluate each one. When a top-level expression evaluates to a non-none value, the remaining expressions on the line are ignored. Evaluator Logo is evaluated one line at a time. The sentence returned from parse_line is passed to the eval_line function, which evaluates each expression in the line. The eval_line function repeatedly calls logo_eval, which evaluates the next full expression in the line until the line has been evaluated completely, then returns the last value. The logo_eval function evaluates a single expression. The form of a multi-element expression in Logo can be determined by inspecting its first element. Each form of expression as its own evaluation rule. 1. A primitive expression (a word that can be interpreted as a number, True, or False) evaluates to itself. 2. A variable (a string that start with : ) is looked up in the environment. 3. A definition (which starts with to ) is handled as a special case. 4. A quoted expression evaluates to the text of the quotation, which is a string without the preceding quote. Sentences (represented as Python lists) are also considered to be quoted; they evaluate to themselves. 5. A call expression looks up the operator name in the current environment and applies the procedure that is bound to that name. 1. Fill in the code for logo_eval def logo_eval(line, env): token = line.pop() if : return elif : #check if primitive #check if variable return env.lookup_variable(variable_name(token)) elif : #check if definition return eval_definition(line, env) else: procedure = env.procedures.get(token, None) if not procedure: error('i do not know how to {0}.'.format(token)) return apply_procedure(procedure, line, env) 1

2. How many calls to eval and apply on the following lines of code?? sum 1 2? sum word 1 2 3 More Dynamic Scope Recall that Python uses Lexical Scoping, which controls what frame a newly created frame points to. Lexical Scoping says: when calling a function, create a new frame that exts the environment that the function was defined in. Logo, however, uses a different rule - it uses Dynamic Scoping. Dynamic Scoping says: when calling a function, create a new frame that exts the current frame.? make "x 3? to scope :x helper 5? to helper :y print (sentence :x :y)? scope 4 ; expects 4 5 Under lexical scope, this would return something along the lines of [3 5]. However, with dynamic scope, helper has access to the :x variable as it exts the frame with that variable. Thus, we up with a sentence of 4 5 printed to the screen.? to bar :n output sentence :n baz :n+1? to baz :m output sentence :n :m? make n 7? bar 10 1. What is the result of this using lexical scope? Dynamic scope? 2. Draw an environment diagram for both. 2

Assignment Logo supports binding names to values. As in Python, a Logo environment consists of a sequence of frames, and each frame can have at most one value bound to a given name. In Logo, names are bound with the make procedure, which takes as arguments a name and a value:? make "x 2 The values bound to names are retrieved by evaluating expressions that begin with a colon:? print :x 2 Assignment rules: 1. if the name is already bound, make re-binds that name in the first frame in which the name is bound (automatic non-local Python assignment) 2. If the name is not bound, make binds the name in the global frame Given:? to foo :n make n 6 make m 7 print bar :n print :n? to bar :m make n 4 make m 8 output :m 1. What is printed when we call foo 10? 2. What is printed when we call print :n? How about print :m? 3

Procedures Logo supports user-defined procedures using definitions that begin with the to keyword. The first line of a definition gives the name of the new procedure, followed by the formal parameters as variables. The lines that follow constitute the body of the procedure, which can span multiple lines and must with a line that contains only the token Logo's application process for a user-defined procedure is similar to the process in Python. Applying a procedure to a sequence of arguments begins by exting an environment with a new frame, binding the formal parameters of the procedure to the argument values, and then evaluating the lines of the body of the procedure in the environment that starts with that new frame. class Procedure(object): """ A Logo procedure, either primitive or user-defined name: The name of the procedure. For primitive procedures with multiple names, only one is stored here. arg_count: Number of arguments required by the procedure. body: A Logo procedure body is either: a Python function, if isprimitive == True a list of lines, if isprimitive == False isprimitive: whether the procedure is primitive. """ def init (self, name, arg_count, body, isprimitive=false,...): self.name = name self.arg_count = arg_count self.body = body self.isprimitive = isprimitive... Write the primitives section of logo_apply. Remember that it might not always be the case that the procedure will work on a given argument, so we should use some exception handling here. def logo_apply(proc, args): if : else:... #You do not have to write this part 4

Environments First, let s review how lookup works for variables in environments: 1. Look for binding for variable of that name in the current frame. 2. If binding exists, return the value. 3. If not, look in your enclosing frame. 4. If you reach the global environment without finding a value, raise an error. How are we going to implement this in an interpret? We first have to understand how to represent environments and frames inside our program. The concept of a frame is simple - a frame tells us variables and their values. Thus we can think of a frame as a set of bindings. We will implement a frame as a dictionary, whose keys are variables names and values are the variables values in that frame. For example, consider the following:? to qux :a :b :c output (sum :a :b :c)? qux 1 2 3 When we call qux 1 2 3, the frame generated by that call can be represented as { a : 1, b : 2, c : 3}. Now that we ve defined frames, it s intuitive to define an environment as a list of frames. The list is ordered, and we denote one of the list to be the current frame, and the other to be the global frame. Each frame is adjacent to the frame that points to it, and the frame that it points to. Suppose we made these calls in logo:? to garply :m output foo :m*2? to foo :m output bar :m/2? to bar :n output 5? show garply 4 1. Just before garply finishes outputting it s result, what does the list of frames look like? 5

2. Finish the definition of the Environment class: class Environment(object): """An environment holds procedure (global) and name bindings in frames.""" def init (self, get_continuation_line=none): self.get_continuation_line = get_continuation_line self.procedures = load_primitives() # The first frame is a list of the global frame def push_frame(self, frame): """Add a new frame, which contains new bindings.""" def pop_frame(self): """Discard the last frame.""" 6