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 interpreters we have seen for FunJay and NestFunJay. 'RayJay is an add-on to FunJay, not NestFunJay, but the 'RayJay interpreter will encorporate ideas from the NestFunJay interpreter---for example, static information will be stored in public instance variables in the abssyntree classes.
Copy the file from the class directory and untar it.
cp ~tvandrun/Public/cs365/proj6.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.InterpreterVisitor
is given to you.
It is similar to the interpreter for NestFunJay,
except the parts dealing with nested functions is removed and
it has stubs for visitng things related to arrays.
Note the following instance variables in the abssyntree classes
for storing information computed by the type checker:
Call
and CallStmt
each
have proc
, a reference to the procedure being called.
IndexedVariable
, LeftHandSide
and Variable
each have isGlobal
and offset
to indicate where to find the memory location for the variable.
If isGlobal
is true, then offset
is
an absolute address; otherwise, it is the offset from the start of
the stack frame.
(These are the only ones you really need to care about.)
Print
has type
indicating
the type of the value to be printed.
Procedure
has frameSize
,
indicating the size of that procedure's stack frame.
Program
has mainFrameSize
,
indicating the size of the stack frame for main()
.
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
(stored in the instance variables).
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.
See relevant methods in funjay.AbstractMu
.
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 funjay.AbstractMu.IllegalAccessException
.
Your code should catch this and display an appropriate error message,
not a stack trace.
Your error message should indicate whether the illegal access was the
target of the assignment, another part of the lefthand side, or
an indexed variable.
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 exception.
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 visit(CallStmt)
.
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.all/ubuntu/cs365/turnin/xxxxxx/proj5
where "xxxxxx" is [alisa|andrew|becca|cheney|daniel|drew|johncharles|kendall|turk]. I will grade your project by running it against a collection of test files.