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
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.