CSSE 304 Assignment #13 (interpreter milestone #1) Updated for Fall, 2018

Similar documents
Project 2: Scheme Interpreter

Project 5 - The Meta-Circular Evaluator

Project 5 - The Meta-Circular Evaluator

COMP 105 Homework: Type Systems

Computer Science 21b (Spring Term, 2015) Structure and Interpretation of Computer Programs. Lexical addressing

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

;;; Determines if e is a primitive by looking it up in the primitive environment. ;;; Define indentation and output routines for the output for

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

;; definition of function, fun, that adds 7 to the input (define fun (lambda (x) (+ x 7)))

Documentation for LISP in BASIC

Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

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

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

Comp 311: Sample Midterm Examination

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

A Brief Introduction to Scheme (II)

regsim.scm ~/umb/cs450/ch5.base/ 1 11/11/13

Principles of Programming Languages

Announcements. The current topic: Scheme. Review: BST functions. Review: Representing trees in Scheme. Reminder: Lab 2 is due on Monday at 10:30 am.

Discussion 12 The MCE (solutions)

CS 275 Name Final Exam Solutions December 16, 2016

CS 360 Programming Languages Interpreters

4.2 Variations on a Scheme -- Lazy Evaluation

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

Building a system for symbolic differentiation

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

A Small Interpreted Language

Write a procedure powerset which takes as its only argument a set S and returns the powerset of S.

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

C311 Lab #3 Representation Independence: Representation Independent Interpreters

6.001 Notes: Section 15.1

Introduction to Scheme

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


University of Massachusetts Lowell

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

CS 314 Principles of Programming Languages

CS450: Structure of Higher Level Languages Spring 2018 Assignment 7 Due: Wednesday, April 18, 2018

Scheme: Strings Scheme: I/O

Functional Programming. Pure Functional Programming

An Introduction to Scheme

CS61A Notes Week 6: Scheme1, Data Directed Programming You Are Scheme and don t let anyone tell you otherwise

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

CS61A Midterm 2 Review (v1.1)

Lecture 12: Conditional Expressions and Local Binding

An Explicit Continuation Evaluator for Scheme

Building a system for symbolic differentiation

SCHEME AND CALCULATOR 5b

Essentials of Programming Languages Language

Project 1: Scheme Pretty-Printer

Syntactic Sugar: Using the Metacircular Evaluator to Implement the Language You Want

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

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

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

CS 314 Principles of Programming Languages

CSCI 3155: Lab Assignment 6

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

Normal Order (Lazy) Evaluation SICP. Applicative Order vs. Normal (Lazy) Order. Applicative vs. Normal? How can we implement lazy evaluation?

CIS4/681 { Articial Intelligence 2 > (insert-sort '( )) ( ) 2 More Complicated Recursion So far everything we have dened requires

CS 314 Principles of Programming Languages. Lecture 16

Essentials of Programming Languages Language

CS 61A Discussion 8: Scheme. March 23, 2017

CS 342 Lecture 7 Syntax Abstraction By: Hridesh Rajan

Procedural abstraction SICP Data abstractions. The universe of procedures forsqrt. Procedural abstraction example: sqrt

Lecture 3: Expressions

B The SLLGEN Parsing System

Functional Programming. Pure Functional Languages

MASSACHVSETTS INSTITVTE OF TECHNOLOGY Department of Electrical Engineering and Computer Science. Issued: Wed. 26 April 2017 Due: Wed.

6.001 Notes: Section 6.1

Turtles All The Way Down

Functional Programming. Pure Functional Languages

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

SCHEME The Scheme Interpreter. 2 Primitives COMPUTER SCIENCE 61A. October 29th, 2012

An Explicit-Continuation Metacircular Evaluator

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

Lab 1: Silver Dollar Game 1 CSCI 2101B Fall 2018

From Syntactic Sugar to the Syntactic Meth Lab:

6.037 Lecture 7B. Scheme Variants Normal Order Lazy Evaluation Streams

This exam is worth 30 points, or 18.75% of your total course grade. The exam contains

Sample Final Exam Questions

CS164: Programming Assignment 2 Dlex Lexer Generator and Decaf Lexer

A LISP Interpreter in ML

Functional Languages. Hwansoo Han

Organization of Programming Languages CS3200/5200N. Lecture 11

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

Scheme Tutorial. Introduction. The Structure of Scheme Programs. Syntax

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

Fall 2018 Discussion 8: October 24, 2018 Solutions. 1 Introduction. 2 Primitives

(scheme-1) has lambda but NOT define

Overview. CS301 Session 3. Problem set 1. Thinking recursively

SEER AKADEMI LINUX PROGRAMMING AND SCRIPTINGPERL 7

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

LECTURE 16. Functional Programming

Principles of Programming Languages

Repetition Structures

Loop structures and booleans

Scheme: Data. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Monday, April 3, Glenn G.

User-defined Functions. Conditional Expressions in Scheme

6.821 Programming Languages Handout Fall MASSACHVSETTS INSTITVTE OF TECHNOLOGY Department of Electrical Engineering and Compvter Science

Principles of Programming Languages 2017W, Functional Programming

Transcription:

CSSE 304 Assignment #13 (interpreter milestone #1) Updated for Fall, 2018 Deliverables: Your code (submit to PLC server). A13 participation survey (on Moodle, by the day after the A13 due date). This is a pair assignment (possibly with a few solo or trio groups). My intention (for this and other interpreter assignments) is not that you will divide-and-conquer, but that you will instead get together to do the work (i.e., pair programming) so that everyone is involved in the solutions of all parts, and everyone understands all of it. We expect everyone to understand all of the code that your team submits, and that you will do your best to make sure that both of you understand it. For each interpreter assignment, there will be a brief survey on Moodle in which you will be asked verify that this is the case. When you submit your code Only one group member should submit your final version; it will show up as the final submission for all if you include all usernames on the PLC server's submission page (only necessary for final submission that is to be graded). If your interpreter code is distributed over several files (We are giving you both single-file and multi-file starting code): a. Your main file should be main.ss. It should load the other files. The argument to each load statement should be just a filename, not a full pathname. There is an example of this in the multi-file starting code. b. Create a.zip file containing your source files, including main.ss. You do not have to include chez-init.ss in your.zip file, but it will not break anything if you do. Do not include any folders in your.zip file! c. Submit that.zip file to the A13 assignment on the server. The questions in the Moodle survey (We really do expect you to write something significant for the last question):

Late day usage for pair assignment: Perhaps (on this or a future interpreter assignment) one partner (A) will run out of late days while the other partner (B) still has late days left. If this happens, partner A's score will be based on the best submission before the due date, while Partner B's score will be based on the best submission before the late day deadline. If you are a potential Partner B in this situation, the best thing you can do for both of you is to push your partner to work with you early so you can submit this interpreter milestone early; then partner A will have a late day to use if you both need it for a later assignment. Collaborative test case development: If you think you have good test case(s) that cover things (or combinations of things) that the current test cases don't cover, please post them in the interpreter project folder on Piazza. We may add some of your test cases to the ones that the grading program uses. If we use your test case(s), we will give you some bonus homework points. Even if we don't use your new tests, it will be good for everyone to have a richer test bed. (120 points) programming problem This assignment is not conceptually difficult, but there are many details to understand and to implement. The simple parser and interpreter presented in class can be obtained from http://www.rose-hulman.edu/class/csse/csse304/201810/homework/assignment_13/a13-multiple-files.zip (a separate file for each major part of the code, perhaps easiest for the development process), or http://www.rose-hulman.edu/class/csse/csse304/201810/homework/assignment_13/all.ss (a single file containing all of the starting code, easiest to submit, because you do not have to make a ZIP file each time) Your first job is to understand the given code, and then you will add features to the given parser and interpreter. You should substitute part or all of your own A11 parser for the simple parser that we provide. Some of the code that you need to add to your interpreter will be done in class or is in the EoPL book. Don't just blindly add it to your code; instead be sure that you understand everything as you are adding it. The interpreted language: The textbook describes an alternate, Pascal-like syntax for the interpreted language. The authors' rationale is that you are less likely to get confused between the interpreted language and the implementation language (Scheme) in which you implement the interpreter. However, we think you can handle interpreting Scheme-like syntax without much confusion, and the benefits of writing a Scheme-like interpreter outweigh the disadvantages. For one thing, you can be sure that your interpreter is getting the correct answer for most expressions, because you can simply input the same expressions directly into Petite Chez Scheme and see what Scheme returns. Thus, whenever an exercise in the book describes a different syntax, you should use standard Scheme syntax instead. Summary: The major features that you are to add to the interpreted language in this assignment are: additional primitive procedures (the ones that are needed in order to evaluate the test cases) literals Boolean constants #t, and #f quoted values, such as '( ), '(a b c), '(a b. (c)), '#(2 5 4) string literals, such as "abc" if two-armed only: i.e., (if test-exp then-exp else-exp) You ll add one-armed if later. let (not let* or named let yet; those will appear in later assignments; don't remove them from your parser, though) lambda (just the normal lambda with a proper list of arguments) variable-argument lambda gets added later. rep and eval-one-exp (two alternative interfaces to your interpreter, described below) We suggest that you thoroughly test each feature before adding the next one. Augmenting unparse-exp whenever you augment parse-exp is a good idea, to help you with debugging.

A more detailed description of what you are to do: For each feature in this and subsequent interpreter assignments, the syntax and semantics should be the same as Scheme's unless we specify otherwise. Add the Boolean constants #t, and #f to the interpreted language, along with quoted data, such as lists and vectors. Also add string literals such as "abcd". You do not need to add any string-manipulation procedures yet, but it will be nice to at least be able to use strings for output messages. Add vector literals (as with strings, Scheme will do the "real" parsing; your parse-exp simply needs to call vector? to see if an expression is a vector). Add if expressions to the interpreted language. Most of the code is in the textbook, but you will have to adapt it to recognize and use Boolean and other literal values in addition to the numeric values. In the book's interpreted language, the authors represent true and false by numbers. In Scheme (and thus in your interpreter), any non-false value should be treated as true. The number 0 is a true value in Scheme (and in your interpreted language), but 0 is the false value in the textbook's language). Note: Recall that if has two forms, with and without an "else" expression. Your interpreter must eventually support both, but for this assignment only the "with" version (i.e.two-armed if) is required in this assignment. Add several primitive procedures including +, -, *, /, add1, sub1, zero?, not, = and < (and the other numeric comparison operators), and also cons, car, cdr, list, null?, assq, eq?, equal?, atom?, length, list- >vector, list?, pair?, procedure?, vector->list, vector, make-vector, vector-ref, vector?, number?, symbol?, set-car!, set-cdr!, vector-set!, display, newline to your interpreter. Add the c**r and c***r procedures (where each "*" stands for an "a" or "d"). Note: You may use built-in Scheme procedures in your implementation of most of the primitive procedures, as we do in the starting code that is provided for you. At least one of the above procedures has a much simpler implementation, and at least one cannot be implemented by using the corresponding Scheme procedure. You may want to enhance the prim-proc mechanism from the provided code so that a prim-proc knows how many arguments it can take, and reports an error if the interpreted code attempts to apply it with an incorrect number of arguments. Otherwise, this incorrect code will default to a Scheme error message such as "Exception in cadr", which will make no sense to the author of the interpreted code. Add let (not named-let yet) expressions to the interpreter, with the standard Scheme syntax: (let ([var exp] ) body1 body2 ). The... in this description is basically the same thing as the Kleene * (like the notation we used in define-syntax); it means "zero or more occurrences of the previous item". Every let expression must have at least one body. (The parser work should have been done in a previous assignment). It is okay for you to interpret named let as well, but this is not required until a later assignment, and will be easier after we discuss letrec implementation in class. Add code similar to that in EoPL 3.2, allowing let expressions to be directly interpreted. Recall that after the extended environment is created, the bodies are executed in order, and the value of the last body is returned. We suggest that you test this code and understand it thoroughly before you go on to implement lambda. Add lambda expressions of the form (lambda (var...) body1 body2...). See the description of rep (short for "read-eval-print") below for a description of what to print if a closure is part of the final value of an expression entered interactively in the interpreter. Section 3.3 of EoPL may be helpful. In later assignments, you'll add many syntactic and semantic forms, including define, let*, letrec, and set!

YOU ARE TO PROVIDE TWO INTERFACES TO YOUR INTERPRETER A. A normal interactive interface (read-eval-print loop) (rep) This interface will be used primarily for your interactive testing of your interpreter and to facilitate interaction if you bring the interpreter to us for help. The user should load your code, type (rep) and start entering Scheme expressions. Your read-eval-print loop should display a prompt that is different from the normal Scheme prompt. It should read and evaluate an expression, print the value, and then prompt for the next expression. If the value happens to be (or contain) a closure, your interpreter should not print the internal representation of the closure, but instead it should print <interpreter-procedure>. For debugging purposes, you might want to write a separate procedure called rep-debug that behaves like rep, except that it displays the internal representation of everything that it prints, including procedures. Using trace on your eval-exp procedure can be a big help, but be prepared to wade through a lot of output! If the user types (exit) as an input expression to your interpreter, (some later version of) your interpreter should exit and simply return to the Scheme top-level; for now it is okay if your interpreter crashes. What happens when the user enters illegal Scheme code or encounters a run-time error? Ideally, the interpreter should print an error message and return to the "read" portion of the "read-eval-print" loop. Think about how you might do that. But we do not expect you to do it for this assignment. Again it can just crash your interpreter. A sample transcript follows: > (rep) --> (+ 3 5) 8 --> (list 6 (lambda (x) x) 7) (6 <interpreter-procedure> 7) --> (cons 'a '(b c d)) (a b c d) --> (let ([a 4]) (+ a 6)) 10 --> ((lambda (x) ((lambda (y) (+ x y)) 5)) 6) 11 --> (let ([t '(3 4)]) (if (< (car t) 1) 7 (let () (set-car! t (+ 1 (cadr t))) (cons (cadr t) (car t))))) (4. 5) --> (((lambda (f) ((lambda (x) (f (lambda (y) ((x x) y)))) (lambda (x) (f (lambda (y) ((x x) y)))))) (lambda (g) (lambda (n) (if (zero? n) 1 (* n (g (- n 1))))))) 6) 720 -->(exit)

B. single-procedure interface: (eval-one-exp parsed-expression) In addition to the (rep) interactive interface, you must provide the procedure eval-one-exp. The code below is intended to clarify its function, not to make you rewrite your interpreter. You will of course need to adapt it to your particular program. It may be possible to arrange things so that your rep procedure can call eval-one-exp. (define eval-one-exp ; you ll add a local environment argument. (lambda (exp) (eval-exp (parse-exp exp)))))) >(eval-one-exp '(- (* 2 3) (* 6 3))) -12 > Note that eval-one-exp does not have to be available to the user when running your interpreter interactively. It only has to be available from the normal Scheme prompt. The interpreter test cases will call this procedure. Testing of your rep will need to be done by hand. Important notes about local environments and the global environment. 1. Every local environment is static (we cannot add variables to a local environment after its initial creation) 2. The global environment is dynamic (we can use define to add variables to it). 3. Thus it does not make logical sense to have any local environments be extensions of the global environment (although this will not show up until A17). 4. Here is another, more practical and immediate reason for not having local envs extend the global env: debugging! a. You are likely to want to trace eval-exp and other procedures that take a local env as on argument. b. If each step in the trace includes the entire global environment, it may take a long time for your machine to display the trace, and an even longer time for you to scroll back and find the part of the trace that you are looking for. c. If you come to us for debugging help, we will probably ask you to show me a trace. If we see the above phenomenon, it is likely that we will ask you to fix it by separating the global environment form the local environments, then come back to us for help. 5. Bottom line: Our advice on having local environments extend the global environment. Don t do it. When you make a top-level call to eval-exp, you should pass the empty environment, not the global environment. This will require changing some of the code that we gave you, but it will be worth it!