ILOC Support -- files and instructions and API's
To use ILOC, you'll want two files -- and I'm providing a third that
may be of general use.
ILOC.java
contains most of the ILOC support, including
- class IlocInstr (including static makeInstr)
- class Opcode
For reasons that will be of interest later, ILOC requires the existence
of a class Declaration. This can be a dummy (empty) class for now
-- though creating it is part of the current assignment.
Reg.java
has class Reg, which is used by ILOC.
Main.java is a utility
file. It provides a function, "main", which can be called out of
Parser.cup once the parse has finished: that way, the rest of the
programming doesn't have to be in the confines of Parser.cup but can be
in a normal Java file.
If you use Main.java, then your Parser.cup should look something
like
StmtList result = (StmtList)( new Parser(s,sf).parse().value );
System.out.println("Result of Parse: " + result);
Main.main(result); // rest of processing will be in Main.
If you use my Main.main (and probably also if you write your own),
StmtList will need an emit() function.
ILOC API's
An ILOC program is a sequential sequence of ILOC instructions (class
IlocInstr), which are kept in a "memory" area within ILOC.
ILOC instructions work with registers (class Reg). You get a new,
previously unused register by invoking the constructor: "new
Reg()". Each Reg has a unique number, monotonically increasing.
For now, we can assume there are an unlimited number of Reg's
available, so we'll not be concerned with "freeing" them after their
last use.
ILOC instructions include an opcode, which is enumerated in the class
Opcode. Some useful values include Opcode.ADD, Opcode.SUB,
Opcode.OUTPUTR. (These are actually the same as defined by the
textbook, except that I've added OUTPUTR for convenience).
To create an ILOC instruction, you generally use the function
IlocInstr.makeInstr.
Here's an example:
IlocInstr.makeInstr(Opcode.LOADI,
regz, 0);
The function is actually overloaded. The first argument is the
desired operation code (Opcode). Here are some signatures:
// reg, reg => reg: used
for 3-address arithmetic
static void makeInstr(Opcode a_op, Reg a_targ, Reg a_sr1,
Reg a_sr2)
// Only one source (integer
literal); used for LOADI
static void makeInstr(Opcode a_op, Reg a_targ, int
a_const)
// a source Register, no target: used
for OUTPUTR
static void makeInstr(Opcode a_op, Reg a_sr1)
When you invoke makeInstr, an instruction is created AND saved in the
memory area. automatically.