In this project, you will complete a compiler for SwiJay (called
JaySea, inspired by javac
) which
produces Java VM assembly (which can then be used to
generate classfiles).
You should mainly think of this as a compiler for Jay, except that one extra tricky part--switch statements---is added at the end.
Many other pieces are provided for you, and can be found in a tar file.
cp ~tvandrun/Public/cs365/proj9.tar .
The system works like this.
The script jaysea
feeds a Jay program into the
ML-written compiler, which produces a file in Java bytecode assembly
(actually a Jasmin input file).
For example,
./jaysea Euclid.swijay
will produce Euclid.jj
.
Then the Java assembler Jasmin can be used to produce the classfile.
For example,
jasmin Euclid.jj
will produce Euclid.class
.
Now
java Euclid
will run the program.
Your task is finishing the compilation functions in
compile.sml
.
For all Jay statements and expressions, what series of
instructions needs to be emitted, and how does that
affect the stack?
Some specifics:
compileStmt()
and compileExpr()
functions (and add any helper functions you deep necessary).
compileStmt()
(skip, block, and loop)
and compileExpr()
(binary expression).
Currently those functions will emit no code for
the other kinds of expressions.
get()
.
This will return an integer (a local variable number)
for a given identifier (a local variable name).
emit()
function
takes a string and an integer;
the integer is the effect that the instruction has on the stack.
This keeps track of stack depth consistency and
the maximum stack depth.
Make use of these resources:
Make your changes to JaySea incrementally. First implement prints and int literals, and then compile a program that just prints an int literal and make sure it works. Then gradually add other statements and expressions.
Do switch statements last.
Switch statements can be compiled to the instruction
lookupswitch
(or, if you're really ambitious, tableswitch
).
Remember that the statements inside a switch are
called InSwitchStatement
s.
In my version, I wrote a helper function called
compileInSwitchStmt()
, analogous
to compileStmt()
.
As you work, I recommend you have
both Jay and Java versions of your test files.
Compile the Java versions and disassemble them with
javap
to see what the result might look like.
Your output does not have to be identical to what javac
produces--often there is an equivalent series of instructions that
you'll find are easier to produce---but javac
can guide you through some of the knottier statements.
All you need is a compiler that produces programs that work
to get full credit.
But there are some optimizations you could perform for which
I will award extra credit.
For example, if (x > 0)...
would naively
be complied by loading x, pushing 0, generating the
sequence for >, and then ifne
,
but a more efficient version would load x and use if_icmpgt
.
Also, x = x + 1;
could be done using the
iinc
instruction.
Some switch statements can be compiled to a tableswitch
instead of a lookupswitch
.
To turn in this project, please copy your compile.sml
and, if you did any optimizations for extra credit,
a text file describing what you did
to the turn-in directory I will prepare for you:
/cslab/class/cs365/turnin/proj9/xxxxx
where "xxxxx" is [lily|chet|christopher|tim|david|ben|caleb]
Due: Wed, April 28, 5:00 pm UTC-12. For those of you who have not used up your late days, Fri, April 30 (the last day of classes) at 5:00 pm is the absolute deadline for this project, meaning that even if you still have all three of your late days left, you may apply no more than two late days to this project.