In this assignment you will be implementing a Scheme interpreter in Java. To make this a little less tedious we have provided you with an implementation of a SchemeObject class hierarchy. Functions for reading in SchemeObjects from an InputStream have also been provided. This is the same functionality that you implemented in Assignment 4 in Miranda. In section on 03/01/01 we will discuss the code you have been given to start with; however, this does not mean that you should wait until section to get started. Your goal in this assignment is to use the provided code and implement a Scheme interpreter.
Do this before section on 03/01/01.
These will be discussed in section on 03/01/01.
Complete the following. Follow the usual turn in requirements of submitting an electronic copy of your source code and turning in a hardcopy with test cases. For your electronic copy and your hardcopy you should include a README file with an explanation of your class structure, a description of how to run your interpreter, and a justification of your design decisions. This README will be graded.
Like Assignment 4, this assignment does not tell you exactly what to do. Instead you need to exercise good design choices. Your goal is to write a Scheme interpreter in Java using the partial SchemeObject hierarchy and parser provided (you may modify these). You must support the following special forms: define, set!, lambda, if, cond, let, and quote. You must support the following primitive functions: +, -, *, , <, eq?, equal?, cons, car, cdr, set-car!, set-cdr!, and list. You may refer to R4RS for a detailed specification of what all of these do. You must support the following Scheme data types: functions, integers, reals, strings, booleans, and lists. You do not have to support characters, vectors (arrays), rational numbers, tail-recursive optimization, or variable argument length user defined functions.
Below are some hints that you may choose to follow when completing this assignment.
Do yourself a favor and test that this works before you try the next step. Independently testing subcomponents of a complicated program is a very time saving debugging practice.
Create functionality for easily creating SchemeLists of length between zero and at least four. I.e. implement the Scheme list function in Java. Also create the functionality of mapping a scheme function over a list to create a new list. For example, mapping an instance of SchemeCarFunction over a list of lists would give the list containing the first element of each list. These were useful when manipulating cons-cells in Scheme, they will also be useful when manipulating your Scheme cons-cells in Java.
Create an environment containing primitive bindings for primitive functions: +, -, *, list, car, cdr, and apply.