Hopefully by now you've seen enough of the Jay family examples that you understand the basic structure of the Jay interpreters and can think in terms of the visitor pattern. The intent in this project is that you can focus on the new feature we're implementing.
In this project you will complete the 'RayJay interpreter by making a few very specific changes to the old FunJay interpreter.
Copy the file from the class directory and untar it.
cp ~tvandrun/Public/cs365/proj5.tar . tar xvf proj6.tar
The contents will be similar to previous projects.
The class with the main method is rayjay.RayJay
.
A class rayjay.astvisitor.InterpretingVisitor
is given to you.
It is identical to the interpreter for FunJay,
except that it has stubs for visitng things related to arrays.
Your primary task is to fill-in the following methods:
visit(Assignment)
: First we visit the
right hand side of the assignment and get a result.
Next, we visit the left hand side and get a memory location.
Finally, we store the expression's result in the memory location.
visit(LeftHandSIde)
: Given a left hand side
that could be an indexed variable, find the memory location
that corresponds to it.
Hints:
a
,
then all you need to do is look up that variable's location in the environment.
(gammaM
).
a[5][2][7]
,
then finding the appropriate address will take some work.
a
refers to the starting address;
then look 5 positions away from there;
there you'll find another address stored;
follow the address stored in a[5]
and jump 2
positions away from there; etc.
visit(LeftHandSide)
right in
visit(Assignment)
, and delete visit(LeftHandSide)
.
I wouldn't do it that way, however.
Instead, you're going to need to have some way for visit(LeftHandSide)
to communicate its result back to visit(Assignment)
---i.e.,
an instance variable.
visit(IndexedVariable)
: This will be very similar
to visit(LeftHandSide)
, but will store its
result in result
, like visit methods for other kinds of
Expressions.
visit(Creation)
: This is the hard one.
Consider an example: new int[3][4][5]
.
To implement this, you must
h
, the top of the heap, accordingly.
int[][][]
).
int[][]
int[]
int[][]
to
the starting address of the 12 arrays.
All arrays are dynamic, like in Java. This means two array variables can be aliases of the same array. Also a method could create an array and return it. Thus arrays must be allocated on the heap.
Unlike Java, 'RayJay will do no bounds checking on
array accesses, on either end.
If the program contains, for example
someArray[-5]
, then we will simply let it trample on
memory, as in C.
Remember, however, that this is the interpreter's
"memory", stored in the array mu
.
The underlying Java implementation (which you're writing)
still should not try to read outside of mu
, which
would of course throw a ArrayIndexOutOfBoundsException
.
Take note that the stack and heap grow towards each other, and we're doing no garbage collection, so it may happen that they may collide and run out of room.
Thus there are three possible run-time errors that a 'RayJay program may commit:
mu
) altogether.
The first of these, if left unchecked, would result in
your program throwing an
ArrayIndexOutOfBoundsException
.
The others would result in wierd behavior.
Rather, you must check for all of these.
If the 'RayJay program commits any of these, your
interpreter must halt, and an appropriate error message
(identifying which of these four errors has occurred)
must be displayed.
(Error 2 is already handled for you in the method allocate()
.
Error 1 needs to be handled in visit(LeftHandSide)
,
visit(IndexedVariable)
, and visit(Assignment)
.
Error 3 needs to be handled in visit(Creation)
.)
Copy your InterpreterVisitor.java
to
/cslab/class/cs365/turnin/proj5/xxxxxx
where "xxxxxx" is [lily|chet|christopher|tim|david|ben|caleb]. I will grade your project by running it against a collection of test files.
DUE: Wednesday, Feb 17, 5:00 pm.