Final Project: JRacket

You may work with a partner for this project. If you choose to do so, only turn in one copy of the project with both of your names in a comment.

Get the startup code here.

For this project, you will write a Racket interpreter in Java. Your interpreter will support a larger subset of Racket than our in-class version (Mini-Racket), but you will not implement every feature of the entire language. Since I need a name for this language you're writing an interpreter for, I'll call it JRacket.

This project is structured similarly to our in-class Mini-Racket interpreter, but since we're in Java, we're using an OOP style. In other words, instead of having a single eval() function, we have a RacketExpression class with an eval() method that other expression classes will override.

The types of expressions you must support are:

Running the interpreter

Run the interpreter by running the main() method in the Main class. It should run "out of the box," though it's not particularly powerful at the start. You can type end at the prompt to quit the interpreter. You should be able to interact with the interpreter by typing in integers, booleans, or quoted expressions (these are already implemented for you):
>>> 4
==> 4
>>> #t
==> #t
>>> '(1 2 3)
      Evaluating: (quote (1 2 3))
==> (1 2 3)
>>> 'x
      Evaluating: (quote x)
==> x
The basic interpreter is flexible enough that if you make a parenthetical or syntactical mistake, it will detect it and not kick you out of the interpreter:
>>> '(3 4))
cs360.ParsingException: Too many closing parens in '(3 4)).  Already parsed [', [3, 4]]
>>> #tf
cs360.ParsingException: Cannot parse boolean value: #tf

Eval/Apply in JRacket

Because we're writing our interpreter in Java, instead of a having one eval() and one apply(), we have a RacketExpression class that has an abstract method eval() that subclasses will override. Furthermore, the RacketFunction class has an apply() method that its subclasses will override.

Diving in

What you will need to to is enhance the interpreter to deal with the types of expressions listed below. You should refer to the Mini-Racket implementation (and your class notes, the slides, etc) for guidance; we are implementing this interpreter in a very similar fashion.

The major difference between this interpreter and Mini-Racket's interpreter is that we have multiple eval() methods, since each Expression is a class. The first thing you should do is take a look at the eval() methods in RacketInteger and RacketBoolean and notice how they work (they're very simple). For instance, RacketInteger's eval() method reflects how in Mini-Racket we tested if an expression was a number and if so, we just returned the expression itself (because numbers, when evaluated, return themselves).

I suggest you add things in a slightly different order than we did in class:

Hints

Challenges

What to turn in

Through Moodle, turn in all of your files. You can just upload everything, or it's probably easier to just make a zip file and upload that.