The goal of this project is to reason about the semanics of object-oriented features of a language by translating from a language with object (OJay) to a language without (RecJay).
Copy and untar the framework for this project.
cp ~tvandrun/Public/cs365/proj7.tar . tar xvf proj7.tar
You'll see that this contains many things.
First, there are the directories recjay
and jay
.
These consitute the RecJay interpreter.
absyn.sml
, as usual, contains ML datatypes
which model the abstract syntax trees.
Make sure you can relate this to the OJay grammar.
Next, notice ojay2RecJay.sml
.
This is the file you will be modifying.
The file ojay2RecJay-main.py
is an
executable script (in Python) which takes an OJay file, executes
the translater (in ML) to produce a RecJay file,
and executes the RecJay interpreter (in Java) on the resulting file.
The files A.ojay
, Plain.ojay
,
NullThis.ojay
,
and Factorial.ojay
are sample input files,
(but Factorial.ojay
is the only interesting one.
The file ojay2RecJay.sml
is set up much like
prettyPrint.sml
for Jay (think back to Project 2).
It contains a series of functions like printProg()
and printStatement()
, each of which returns a string.
Its purpose is to take an OJay program as an abstract syntax tree
and produce an equivalent RecJay program.
Much of it is written for you.
The program A.ojay
contains only code that is also
valid Jay code, and ojay2RecJay.sml
already handles it.
(You can run ./ojay2RecJay-main.py A.ojay
out of the box).
What it doesn't handle is the translation of classes. That is your task.
Before doing any coding, you should first determine
a translation strategy from OJay to RecJay.
Take Factorial.ojay
as an example.
What you need to do is determine what needs to be produced
for an equivalent RecJay program.
How are classes translated?
How are methods translated?
How are invocations translated?
Once you have a strategy, there are six places in the code that you need to write or modify:
printProg()
the code current just ignores
classes.
You need to print out equivalent records and procedures.
printClazzes()
and
printClazz()
need to be written.
(printClazzes()
isn't hard, it's just a matter of
applying printClazz()
to all the classes.
I'm omitting it from what I give you because otherwise it
would give away too much of the solution).
printMeth()
needs to be written.
Invocation
case of
the function printStatement()
needs to be written.
Var
case of the function
printExpression()
needs to be fixed.
InvocationExpression
case of the function
printExpression()
needs to be written,
although it will be almost identical to
printStatement(Invocation)
.
Take notice that almost every function takes tm
,
the type map (a string * string list
,
a mapping from identifiers to type names), as a parameter.
The type map will need to change based on context to
accomodate global variables, local variables,
fields, and formal parameters.
Most of the functions you will need to modify or write
also take fields
, a list of the names of the
fields of the class in which the method, statement,
or expression is found.
(If the statement or expression appears in the main method,
then this list is empty.)
clName
,
the name of the class that it appears in.
Included in ojay2RecJay.sml
are a few
functions that you might find useful (I used them
in my implementation):
addTypeMap()
makeFieldList()
takes a list of declarations and
produces a list of variables declared in those declarations.
This is particularly useful in getting the list of fields
in a class (hence the name).
printFormParams()
prints formal
parameters, beginning with a comma.
printActParams()
is similar to
printFormParams()
, but for actual parameters.
In addition, you are permitted to change anything in
ojay2RecJay.sml
to suit your solution better,
but I don't expect that you would need to modify anything besides
the places mentioned above.
Hint: The difficult part of translating classes is that in
RecJay, records go before the main method but procedures go after.
So, each class will need to be divided into two parts which will
end up in different places in the resulting RecJay program.
This can be accomplished by having printClazzes
and printClazz
each return a pair of strings
rather than just a single string.
Unfortunately, if something is wrong in the RecJay
you produce (which, from my experience on this project, is
very likely), you will not get an error message
when you use ojay2RecJay.py
.
However, ojay2RecJay.py
will produce
the .recjay
, which you can inspect and
also use to reun recjay.RecJay
manually.
For example, say you have a sample program X.ojay
.
When you run ojay2RecJay.py X.ojay
,
you see SML running, but X.ojay
doesn't run
and you don't get an error message either.
In that case, look at the file X.recjay
and run
java recjay.RecJay X.recjay
Also, I will make ojayasjava.py
and recjayasjava.py
available
at ~tvandrun/Public/cs365/util
Copy your ojay2RecJay.sml
to
/cslab.all/ubuntu/cs365/turnin/xxxxxx/proj7
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.
DUE: Monday, March 26, 5:00 pm.