home *** CD-ROM | disk | FTP | other *** search
/ ftp.ee.pdx.edu / 2014.02.ftp.ee.pdx.edu.tar / ftp.ee.pdx.edu / pub / users / Harry / compilers / p8 / IR.java < prev    next >
Text File  |  2006-01-29  |  34KB  |  933 lines

  1. // --------------------------- IR ------------------------------
  2. //
  3. // This file contains the classes used to represent an
  4. // Intermediate Representation instruction.
  5. //
  6. // Harry Porter -- 04/13/03
  7. //
  8.  
  9. class IR {
  10.  
  11.     //
  12.     // Constants - These are the op-codes for the IR instructions
  13.     //
  14.     static final int OPassign = 1;
  15.     static final int OPloadAddr = 2;
  16.     static final int OPstore = 3;
  17.     static final int OPloadIndirect = 4;
  18.     static final int OPiadd = 5;
  19.     static final int OPisub = 6;
  20.     static final int OPimul = 7;
  21.     static final int OPidiv = 8;
  22.     static final int OPimod = 9;
  23.     static final int OPineg = 10;
  24.     static final int OPfadd = 11;
  25.     static final int OPfsub = 12;
  26.     static final int OPfmul = 13;
  27.     static final int OPfdiv = 14;
  28.     static final int OPfneg = 15;
  29.     static final int OPitof = 16;
  30.     static final int OPcall = 17; 
  31.     static final int OPparam = 18;
  32.     static final int OPresultTo = 19;
  33.     static final int OPmainEntry = 20;
  34.     static final int OPmainExit = 21;
  35.     static final int OPprocEntry = 22;
  36.     static final int OPformal = 23;
  37.     static final int OPreturnExpr = 24;
  38.     static final int OPreturnVoid = 25;
  39.     static final int OPlabel = 26;
  40.     static final int OPgoto = 27;
  41.     static final int OPgotoiEQ = 28;
  42.     static final int OPgotoiNE = 29;
  43.     static final int OPgotoiLT = 30;
  44.     static final int OPgotoiLE = 31;
  45.     static final int OPgotoiGT = 32;
  46.     static final int OPgotoiGE = 33;
  47.     static final int OPgotofEQ = 34;
  48.     static final int OPgotofNE = 35;
  49.     static final int OPgotofLT = 36;
  50.     static final int OPgotofLE = 37;
  51.     static final int OPgotofGT = 38;
  52.     static final int OPgotofGE = 39;
  53.     static final int OPcomment = 40;
  54.     static final int OPalloc = 41;
  55.     static final int OPreadInt = 42;
  56.     static final int OPreadFloat = 43;
  57.     static final int OPwriteInt = 44;
  58.     static final int OPwriteFloat = 45;
  59.     static final int OPwriteString = 46;
  60.     static final int OPwriteBoolean = 47;
  61.     static final int OPwriteNewline = 48;
  62.  
  63.     //
  64.     // Static Fields -- This is the linked list of IR instructions.
  65.     //
  66.     static IR firstInstruction;               // Pointer to head
  67.     static IR lastInstruction;                // Pointer to tail
  68.  
  69.  
  70.  
  71.     //
  72.     // Fields  -- These fields describe one IR instruction.  Instructions
  73.     //            are kept in a linked list, using the field "next".  The
  74.     //            "op" field tells what kind of instruction it is, e.g.,
  75.     //            OPassign, OPiadd, OPgoto,...  Each instruction will
  76.     //            have zero or more operands, which will be stored in the
  77.     //            fields "result", "arg1", "arg2", "str", or "iValue".
  78.     //
  79.     int         op;
  80.     Ast.Node    result;
  81.     Ast.Node    arg1;
  82.     Ast.Node    arg2;
  83.     String      str;
  84.     int         iValue;
  85.     IR          next;
  86.  
  87.  
  88.  
  89.     //
  90.     // Constructor -- Create a new IR instruction and link it into the
  91.     //                linked list of instructions.  The op-code is filled
  92.     //                in, but none of the operands are filled in; this is
  93.     //                the responsibility of the caller.
  94.     //
  95.     IR (int o) {
  96.         super();
  97.         op = o;
  98.         next = null;
  99.         if (firstInstruction == null) {
  100.             firstInstruction = this;
  101.         } else {
  102.             lastInstruction.next = this;
  103.         }
  104.         lastInstruction = this;
  105.     }
  106.  
  107.  
  108.  
  109.     //
  110.     // Each of these methods is used to generate a new IR instruction.
  111.     // The new instruction is added to the end of the list of instructions.
  112.     //
  113.     // assign:  result := arg
  114.     //
  115.             static void assign (Ast.Node result, Ast.Node arg) {
  116.                 IR inst = new IR (OPassign);
  117.                 inst.result = result;
  118.                 inst.arg1 = arg;
  119.             }
  120.     //
  121.     // loadAddr:  result := &arg
  122.     //
  123.             static void loadAddr (Ast.Node result, Ast.Node arg) {
  124.                 IR inst = new IR (OPloadAddr);
  125.                 inst.result = result;
  126.                 inst.arg1 = arg;
  127.             }
  128.     //
  129.     // store:  *result := arg
  130.     //
  131.             static void store (Ast.Node result, Ast.Node arg) {
  132.                 IR inst = new IR (OPstore);
  133.                 inst.result = result;
  134.                 inst.arg1 = arg;
  135.             }
  136.     //
  137.     // loadIndirect:  result := *arg
  138.     //
  139.             static void loadIndirect (Ast.Node result, Ast.Node arg) {
  140.                 IR inst = new IR (OPloadIndirect);
  141.                 inst.result = result;
  142.                 inst.arg1 = arg;
  143.             }
  144.     //
  145.     // iadd:  result := arg1 + arg2 (int)
  146.     //
  147.             static void iadd (Ast.Node result, Ast.Node arg1, Ast.Node arg2) {
  148.                 IR inst = new IR (OPiadd);
  149.                 inst.result = result;
  150.                 inst.arg1 = arg1;
  151.                 inst.arg2 = arg2;
  152.             }
  153.     //
  154.     // isub:  result := arg1 - arg2 (int)
  155.     //
  156.             static void isub (Ast.Node result, Ast.Node arg1, Ast.Node arg2) {
  157.                 IR inst = new IR (OPisub);
  158.                 inst.result = result;
  159.                 inst.arg1 = arg1;
  160.                 inst.arg2 = arg2;
  161.             }
  162.     //
  163.     // imul:  result := arg1 * arg2 (int)
  164.     //
  165.             static void imul (Ast.Node result, Ast.Node arg1, Ast.Node arg2) {
  166.                 IR inst = new IR (OPimul);
  167.                 inst.result = result;
  168.                 inst.arg1 = arg1;
  169.                 inst.arg2 = arg2;
  170.             }
  171.     //
  172.     // idiv:  result := arg1 DIV arg2 (int)
  173.     //
  174.             static void idiv (Ast.Node result, Ast.Node arg1, Ast.Node arg2) {
  175.                 IR inst = new IR (OPidiv);
  176.                 inst.result = result;
  177.                 inst.arg1 = arg1;
  178.                 inst.arg2 = arg2;
  179.             }
  180.     //
  181.     // imod:  result := arg1 MOD arg2 (int)
  182.     //
  183.             static void imod (Ast.Node result, Ast.Node arg1, Ast.Node arg2) {
  184.                 IR inst = new IR (OPimod);
  185.                 inst.result = result;
  186.                 inst.arg1 = arg1;
  187.                 inst.arg2 = arg2;
  188.             }
  189.     //
  190.     // ineg:  result := - arg (int)
  191.     //
  192.             static void ineg (Ast.Node result, Ast.Node arg) {
  193.                 IR inst = new IR (OPineg);
  194.                 inst.result = result;
  195.                 inst.arg1 = arg;
  196.             }
  197.     //
  198.     // fadd:  result := arg1 + arg2 (float)
  199.     //
  200.             static void fadd (Ast.Node result, Ast.Node arg1, Ast.Node arg2) {
  201.                 IR inst = new IR (OPfadd);
  202.                 inst.result = result;
  203.                 inst.arg1 = arg1;
  204.                 inst.arg2 = arg2;
  205.             }
  206.     //
  207.     // fsub:  result := arg1 - arg2 (float)
  208.     //
  209.             static void fsub (Ast.Node result, Ast.Node arg1, Ast.Node arg2) {
  210.                 IR inst = new IR (OPfsub);
  211.                 inst.result = result;
  212.                 inst.arg1 = arg1;
  213.                 inst.arg2 = arg2;
  214.             }
  215.     //
  216.     // fmul:  result := arg1 * arg2 (float)
  217.     //
  218.             static void fmul (Ast.Node result, Ast.Node arg1, Ast.Node arg2) {
  219.                 IR inst = new IR (OPfmul);
  220.                 inst.result = result;
  221.                 inst.arg1 = arg1;
  222.                 inst.arg2 = arg2;
  223.             }
  224.     //
  225.     // fdiv:  result := arg1 / arg2 (float)
  226.     //
  227.             static void fdiv (Ast.Node result, Ast.Node arg1, Ast.Node arg2) {
  228.                 IR inst = new IR (OPfdiv);
  229.                 inst.result = result;
  230.                 inst.arg1 = arg1;
  231.                 inst.arg2 = arg2;
  232.             }
  233.     //
  234.     // fneg:  result := - arg (float)
  235.     //
  236.             static void fneg (Ast.Node result, Ast.Node arg) {
  237.                 IR inst = new IR (OPfneg);
  238.                 inst.result = result;
  239.                 inst.arg1 = arg;
  240.             }
  241.     //
  242.     // itof:  result := intToFloat(arg)
  243.     //
  244.             static void itof (Ast.Node result, Ast.Node arg) {
  245.                 IR inst = new IR (OPitof);
  246.                 inst.result = result;
  247.                 inst.arg1 = arg;
  248.             }
  249.     //
  250.     // call:  call proc
  251.     //
  252.             static void call (Ast.ProcDecl arg) {
  253.                 IR inst = new IR (OPcall);
  254.                 inst.arg1 = arg;
  255.             }
  256.     //
  257.     // param:  param int,arg
  258.     //
  259.             static void param (int i, Ast.Node arg) {
  260.                 IR inst = new IR (OPparam);
  261.                 inst.iValue = i;
  262.                 inst.arg1 = arg;
  263.             }
  264.     //
  265.     // resultTo:  resultTo result
  266.     //
  267.             static void resultTo (Ast.Node result) {
  268.                 IR inst = new IR (OPresultTo);
  269.                 inst.result = result;
  270.             }
  271.     //
  272.     // mainEntry:  mainEntry body
  273.     //
  274.             static void mainEntry (Ast.Body arg) {
  275.                 IR inst = new IR (OPmainEntry);
  276.                 inst.arg1 = arg;
  277.             }
  278.     //
  279.     // mainExit:  mainExit
  280.     //
  281.             static void mainExit () {
  282.                 IR inst = new IR (OPmainExit);
  283.             }
  284.     //
  285.     // procEntry:  procEntry proc
  286.     //
  287.             static void procEntry (Ast.ProcDecl proc) {
  288.                 IR inst = new IR (OPprocEntry);
  289.                 inst.arg1 = proc;
  290.             }
  291.     //
  292.     // formal:  formal int,form
  293.     //
  294.             static void formal (int i, Ast.Formal form) {
  295.                 IR inst = new IR (OPformal);
  296.                 inst.iValue = i;
  297.                 inst.arg1 = form;
  298.             }
  299.     //
  300.     // returnExpr:  return arg
  301.     //
  302.             static void returnExpr (Ast.Node arg) {
  303.                 IR inst = new IR (OPreturnExpr);
  304.                 inst.arg1 = arg;
  305.             }
  306.     //
  307.     // returnVoid:  return
  308.     //
  309.             static void returnVoid () {
  310.                 IR inst = new IR (OPreturnVoid);
  311.             }
  312.     //
  313.     // label:  label:
  314.     //
  315.             static void label (String lab) {
  316.                 IR inst = new IR (OPlabel);
  317.                 inst.str = lab;
  318.             }
  319.     //
  320.     // goto:  goto label
  321.     //
  322.             static void go_to (String lab) {
  323.                 IR inst = new IR (OPgoto);
  324.                 inst.str = lab;
  325.             }
  326.     //
  327.     // gotoiEQ:  if arg1==arg2 then goto result (integer)
  328.     //
  329.             static void gotoiEQ (Ast.Node arg1, Ast.Node arg2, String lab) {
  330.                 IR inst = new IR (OPgotoiEQ);
  331.                 inst.arg1 = arg1;
  332.                 inst.arg2 = arg2;
  333.                 inst.str = lab;
  334.             }
  335.     //
  336.     // gotoiNE:  if arg1!=arg2 then goto result (integer)
  337.     //
  338.             static void gotoiNE (Ast.Node arg1, Ast.Node arg2, String lab) {
  339.                 IR inst = new IR (OPgotoiNE);
  340.                 inst.arg1 = arg1;
  341.                 inst.arg2 = arg2;
  342.                 inst.str = lab;
  343.             }
  344.     //
  345.     // gotoiLT:  if arg1<arg2 then goto result (integer)
  346.     //
  347.             static void gotoiLT (Ast.Node arg1, Ast.Node arg2, String lab) {
  348.                 IR inst = new IR (OPgotoiLT);
  349.                 inst.arg1 = arg1;
  350.                 inst.arg2 = arg2;
  351.                 inst.str = lab;
  352.             }
  353.     //
  354.     // gotoiLE:  if arg1<=arg2 then goto result (integer)
  355.     //
  356.             static void gotoiLE (Ast.Node arg1, Ast.Node arg2, String lab) {
  357.                 IR inst = new IR (OPgotoiLE);
  358.                 inst.arg1 = arg1;
  359.                 inst.arg2 = arg2;
  360.                 inst.str = lab;
  361.             }
  362.     //
  363.     // gotoiGT:  if arg1>arg2 then goto result (integer)
  364.     //
  365.             static void gotoiGT (Ast.Node arg1, Ast.Node arg2, String lab) {
  366.                 IR inst = new IR (OPgotoiGT);
  367.                 inst.arg1 = arg1;
  368.                 inst.arg2 = arg2;
  369.                 inst.str = lab;
  370.             }
  371.     //
  372.     // gotoiGE:  if arg1>=arg2 then goto result (integer)
  373.     //
  374.             static void gotoiGE (Ast.Node arg1, Ast.Node arg2, String lab) {
  375.                 IR inst = new IR (OPgotoiGE);
  376.                 inst.arg1 = arg1;
  377.                 inst.arg2 = arg2;
  378.                 inst.str = lab;
  379.             }
  380.     //
  381.     // gotofEQ:  if arg1==arg2 then goto result (float)
  382.     //
  383.             static void gotofEQ (Ast.Node arg1, Ast.Node arg2, String lab) {
  384.                 IR inst = new IR (OPgotofEQ);
  385.                 inst.arg1 = arg1;
  386.                 inst.arg2 = arg2;
  387.                 inst.str = lab;
  388.             }
  389.     //
  390.     // gotofNE:  if arg1!=arg2 then goto result (float)
  391.     //
  392.             static void gotofNE (Ast.Node arg1, Ast.Node arg2, String lab) {
  393.                 IR inst = new IR (OPgotofNE);
  394.                 inst.arg1 = arg1;
  395.                 inst.arg2 = arg2;
  396.                 inst.str = lab;
  397.             }
  398.     //
  399.     // gotofLT:  if arg1<arg2 then goto result (float)
  400.     //
  401.             static void gotofLT (Ast.Node arg1, Ast.Node arg2, String lab) {
  402.                 IR inst = new IR (OPgotofLT);
  403.                 inst.arg1 = arg1;
  404.                 inst.arg2 = arg2;
  405.                 inst.str = lab;
  406.             }
  407.     //
  408.     // gotofLE:  if arg1<=arg2 then goto result (float)
  409.     //
  410.             static void gotofLE (Ast.Node arg1, Ast.Node arg2, String lab) {
  411.                 IR inst = new IR (OPgotofLE);
  412.                 inst.arg1 = arg1;
  413.                 inst.arg2 = arg2;
  414.                 inst.str = lab;
  415.             }
  416.     //
  417.     // gotofGT:  if arg1>arg2 then goto result (float)
  418.     //
  419.             static void gotofGT (Ast.Node arg1, Ast.Node arg2, String lab) {
  420.                 IR inst = new IR (OPgotofGT);
  421.                 inst.arg1 = arg1;
  422.                 inst.arg2 = arg2;
  423.                 inst.str = lab;
  424.             }
  425.     //
  426.     // gotofGE:  if arg1>=arg2 then goto result (float)
  427.     //
  428.             static void gotofGE (Ast.Node arg1, Ast.Node arg2, String lab) {
  429.                 IR inst = new IR (OPgotofGE);
  430.                 inst.arg1 = arg1;
  431.                 inst.arg2 = arg2;
  432.                 inst.str = lab;
  433.             }
  434.     //
  435.     // comment:  ! ...string...
  436.     //
  437.             static void comment (String s) {
  438.                 IR inst = new IR (OPcomment);
  439.                 inst.str = s;
  440.             }
  441.     //
  442.     // alloc:  result := alloc(arg)
  443.     //
  444.             static void alloc (Ast.Node result, Ast.Node arg) {
  445.                 IR inst = new IR (OPalloc);
  446.                 inst.result = result;
  447.                 inst.arg1 = arg;
  448.             }
  449.     //
  450.     // readInt:  result := readInt()
  451.     //
  452.             static void readInt (Ast.Node result) {
  453.                 IR inst = new IR (OPreadInt);
  454.                 inst.result = result;
  455.             }
  456.     //
  457.     // readFloat:  result := readFloat()
  458.     //
  459.             static void readFloat (Ast.Node result) {
  460.                 IR inst = new IR (OPreadFloat);
  461.                 inst.result = result;
  462.             }
  463.     //
  464.     // writeInt:  writeInt arg
  465.     //
  466.             static void writeInt (Ast.Node arg) {
  467.                 IR inst = new IR (OPwriteInt);
  468.                 inst.arg1 = arg;
  469.             }
  470.     //
  471.     // writeFloat:  writeFloat arg
  472.     //
  473.             static void writeFloat (Ast.Node arg) {
  474.                 IR inst = new IR (OPwriteFloat);
  475.                 inst.arg1 = arg;
  476.             }
  477.     //
  478.     // writeString:  writeString nameOfConstant
  479.     //
  480.             static void writeString (String name) {
  481.                 IR inst = new IR (OPwriteString);
  482.                 inst.str = name;
  483.             }
  484.     //
  485.     // writeBoolean:  writeBoolean arg
  486.     //
  487.             static void writeBoolean (Ast.Node arg) {
  488.                 IR inst = new IR (OPwriteBoolean);
  489.                 inst.arg1 = arg;
  490.             }
  491.     //
  492.     // writeNewline:  writeNewline
  493.     //
  494.             static void writeNewline () {
  495.                 IR inst = new IR (OPwriteNewline);
  496.             }
  497.  
  498.  
  499.  
  500.     // printIR ()
  501.     //
  502.     // This routine prints out the list of IR instructions.
  503.     //
  504.     static void printIR ()
  505.         throws LogicError
  506.     {
  507.  
  508.         // // This print is for Project 9 data...
  509.         // System.out.println ("maxLexicalLevel = " + Main.generator.maxLexicalLevel);
  510.  
  511.         // // These prints are for Project 10 data...
  512.         //    System.out.println ("=====  String List Follows  =====");
  513.         //    for (Ast.StringConst s = Main.generator.stringList; s != null; s = s.next) {
  514.         //        System.out.println ("   " + s.nameOfConstant + ":  \"" + s.sValue + "\"");
  515.         //    }
  516.         //    System.out.println ("=====  Float List Follows  =====");
  517.         //    for (Ast.RealConst r = Main.generator.floatList; r != null; r = r.next) {
  518.         //        System.out.println ("   " + r.nameOfConstant + ":  " + r.rValue);
  519.         //    }
  520.  
  521.         System.out.println ("=====  Intermediate Code Follows  =====");
  522.         for (IR inst = firstInstruction; inst != null; inst = inst.next) {
  523.             switch (inst.op) {
  524.                 case OPassign:
  525.                     System.out.print ("                ");
  526.                     printANode (inst.result);
  527.                     System.out.print (" := ");
  528.                     printANode (inst.arg1);
  529.                     System.out.println ();
  530.                     break;
  531.                 case OPloadAddr:
  532.                     System.out.print ("                ");
  533.                     printANode (inst.result);
  534.                     System.out.print (" := &");
  535.                     printANode (inst.arg1);
  536.                     System.out.println ();
  537.                     break;
  538.                 case OPstore:
  539.                     System.out.print ("                *");
  540.                     printANode (inst.result);
  541.                     System.out.print (" := ");
  542.                     printANode (inst.arg1);
  543.                     System.out.println ();
  544.                     break;
  545.                 case OPloadIndirect:
  546.                     System.out.print ("                ");
  547.                     printANode (inst.result);
  548.                     System.out.print (" := *");
  549.                     printANode (inst.arg1);
  550.                     System.out.println ();
  551.                     break;
  552.                 case OPiadd:
  553.                     System.out.print ("                ");
  554.                     printANode (inst.result);
  555.                     System.out.print (" := ");
  556.                     printANode (inst.arg1);
  557.                     System.out.print (" + ");
  558.                     printANode (inst.arg2);
  559.                     System.out.println ("\t\t(integer)");
  560.                     break;
  561.                 case OPisub:
  562.                     System.out.print ("                ");
  563.                     printANode (inst.result);
  564.                     System.out.print (" := ");
  565.                     printANode (inst.arg1);
  566.                     System.out.print (" - ");
  567.                     printANode (inst.arg2);
  568.                     System.out.println ("\t\t(integer)");
  569.                     break;
  570.                 case OPimul:
  571.                     System.out.print ("                ");
  572.                     printANode (inst.result);
  573.                     System.out.print (" := ");
  574.                     printANode (inst.arg1);
  575.                     System.out.print (" * ");
  576.                     printANode (inst.arg2);
  577.                     System.out.println ("\t\t(integer)");
  578.                     break;
  579.                 case OPidiv:
  580.                     System.out.print ("                ");
  581.                     printANode (inst.result);
  582.                     System.out.print (" := ");
  583.                     printANode (inst.arg1);
  584.                     System.out.print (" DIV ");
  585.                     printANode (inst.arg2);
  586.                     System.out.println ("\t\t(integer)");
  587.                     break;
  588.                 case OPimod:
  589.                     System.out.print ("                ");
  590.                     printANode (inst.result);
  591.                     System.out.print (" := ");
  592.                     printANode (inst.arg1);
  593.                     System.out.print (" MOD ");
  594.                     printANode (inst.arg2);
  595.                     System.out.println ("\t\t(integer)");
  596.                     break;
  597.                 case OPineg:
  598.                     System.out.print ("                ");
  599.                     printANode (inst.result);
  600.                     System.out.print (" := - ");
  601.                     printANode (inst.arg1);
  602.                     System.out.println ("\t\t(integer)");
  603.                     break;
  604.                 case OPfadd:
  605.                     System.out.print ("                ");
  606.                     printANode (inst.result);
  607.                     System.out.print (" := ");
  608.                     printANode (inst.arg1);
  609.                     System.out.print (" + ");
  610.                     printANode (inst.arg2);
  611.                     System.out.println ("\t\t(float)");
  612.                     break;
  613.                 case OPfsub:
  614.                     System.out.print ("                ");
  615.                     printANode (inst.result);
  616.                     System.out.print (" := ");
  617.                     printANode (inst.arg1);
  618.                     System.out.print (" - ");
  619.                     printANode (inst.arg2);
  620.                     System.out.println ("\t\t(float)");
  621.                     break;
  622.                 case OPfmul:
  623.                     System.out.print ("                ");
  624.                     printANode (inst.result);
  625.                     System.out.print (" := ");
  626.                     printANode (inst.arg1);
  627.                     System.out.print (" * ");
  628.                     printANode (inst.arg2);
  629.                     System.out.println ("\t\t(float)");
  630.                     break;
  631.                 case OPfdiv:
  632.                     System.out.print ("                ");
  633.                     printANode (inst.result);
  634.                     System.out.print (" := ");
  635.                     printANode (inst.arg1);
  636.                     System.out.print (" / ");
  637.                     printANode (inst.arg2);
  638.                     System.out.println ("\t\t(float)");
  639.                     break;
  640.                 case OPfneg:
  641.                     System.out.print ("                ");
  642.                     printANode (inst.result);
  643.                     System.out.print (" := - ");
  644.                     printANode (inst.arg1);
  645.                     System.out.println ("\t\t(float)");
  646.                     break;
  647.                 case OPitof:
  648.                     System.out.print ("                ");
  649.                     printANode (inst.result);
  650.                     System.out.print (" := intToFloat (");
  651.                     printANode (inst.arg1);
  652.                     System.out.println (")");
  653.                     break;
  654.                 case OPcall:
  655.                     System.out.print ("                call ");
  656.                     System.out.println (((Ast.ProcDecl) inst.arg1).id);
  657.                     break;
  658.                 case OPparam:
  659.                     System.out.print ("                param ");
  660.                     System.out.print (inst.iValue + ",");
  661.                     printANode (inst.arg1);
  662.                     System.out.println ();
  663.                     break;
  664.                 case OPresultTo:
  665.                     System.out.print ("                resultTo ");
  666.                     printANode (inst.result);
  667.                     System.out.println ();
  668.                     break;
  669.                 case OPmainEntry:
  670.                     // Framesize is now printed in "printOffsets"...
  671.                     // System.out.println ("                mainEntry frameSize=" +
  672.                     //                     ((Ast.Body) inst.arg1).frameSize);
  673.                     System.out.println ("                mainEntry");
  674.                     break;
  675.                 case OPmainExit:
  676.                     System.out.println ("                mainExit");
  677.                     break;
  678.                 case OPprocEntry:
  679.                     System.out.print ("                procEntry ");
  680.                     Ast.ProcDecl pd = (Ast.ProcDecl) inst.arg1;
  681.                     System.out.print (pd.id);
  682.                     // Also print lexLevel and frameSize to make sure they're correct...
  683.                     System.out.println (",lexLevel=" + pd.lexLevel +
  684.                                         ",frameSize=" + pd.body.frameSize);
  685.                     break;
  686.                 case OPformal:
  687.                     System.out.print ("                formal ");
  688.                     System.out.print (inst.iValue + ",");
  689.                     printANode (inst.arg1);
  690.                     System.out.println ();
  691.                     break;
  692.                 case OPreturnExpr:
  693.                     System.out.print ("                returnExpr ");
  694.                     printANode (inst.arg1);
  695.                     System.out.println ();
  696.                     break;
  697.                 case OPreturnVoid:
  698.                     System.out.print ("                returnVoid ");
  699.                     System.out.println ();
  700.                     break;
  701.                 case OPlabel:
  702.                     System.out.println ("        " + inst.str + ":");
  703.                     break;
  704.                 case OPgoto:
  705.                     System.out.print ("                goto ");
  706.                     System.out.println (inst.str);
  707.                     break;
  708.                 case OPgotoiEQ:
  709.                     System.out.print ("                if ");
  710.                     printANode (inst.arg1);
  711.                     System.out.print (" = ");
  712.                     printANode (inst.arg2);
  713.                     System.out.println (" then goto " + inst.str + "\t\t(integer)");
  714.                     break;
  715.                 case OPgotoiNE:
  716.                     System.out.print ("                if ");
  717.                     printANode (inst.arg1);
  718.                     System.out.print (" != ");
  719.                     printANode (inst.arg2);
  720.                     System.out.println (" then goto " + inst.str + "\t\t(integer)");
  721.                     break;
  722.                 case OPgotoiLT:
  723.                     System.out.print ("                if ");
  724.                     printANode (inst.arg1);
  725.                     System.out.print (" < ");
  726.                     printANode (inst.arg2);
  727.                     System.out.println (" then goto " + inst.str + "\t\t(integer)");
  728.                     break;
  729.                 case OPgotoiLE:
  730.                     System.out.print ("                if ");
  731.                     printANode (inst.arg1);
  732.                     System.out.print (" <= ");
  733.                     printANode (inst.arg2);
  734.                     System.out.println (" then goto " + inst.str + "\t\t(integer)");
  735.                     break;
  736.                 case OPgotoiGT:
  737.                     System.out.print ("                if ");
  738.                     printANode (inst.arg1);
  739.                     System.out.print (" > ");
  740.                     printANode (inst.arg2);
  741.                     System.out.println (" then goto " + inst.str + "\t\t(integer)");
  742.                     break;
  743.                 case OPgotoiGE:
  744.                     System.out.print ("                if ");
  745.                     printANode (inst.arg1);
  746.                     System.out.print (" >= ");
  747.                     printANode (inst.arg2);
  748.                     System.out.println (" then goto " + inst.str + "\t\t(integer)");
  749.                     break;
  750.                 case OPgotofEQ:
  751.                     System.out.print ("                if ");
  752.                     printANode (inst.arg1);
  753.                     System.out.print (" = ");
  754.                     printANode (inst.arg2);
  755.                     System.out.println (" then goto " + inst.str + "\t\t(float)");
  756.                     break;
  757.                 case OPgotofNE:
  758.                     System.out.print ("                if ");
  759.                     printANode (inst.arg1);
  760.                     System.out.print (" != ");
  761.                     printANode (inst.arg2);
  762.                     System.out.println (" then goto " + inst.str + "\t\t(float)");
  763.                     break;
  764.                 case OPgotofLT:
  765.                     System.out.print ("                if ");
  766.                     printANode (inst.arg1);
  767.                     System.out.print (" < ");
  768.                     printANode (inst.arg2);
  769.                     System.out.println (" then goto " + inst.str + "\t\t(float)");
  770.                     break;
  771.                 case OPgotofLE:
  772.                     System.out.print ("                if ");
  773.                     printANode (inst.arg1);
  774.                     System.out.print (" <= ");
  775.                     printANode (inst.arg2);
  776.                     System.out.println (" then goto " + inst.str + "\t\t(float)");
  777.                     break;
  778.                 case OPgotofGT:
  779.                     System.out.print ("                if ");
  780.                     printANode (inst.arg1);
  781.                     System.out.print (" > ");
  782.                     printANode (inst.arg2);
  783.                     System.out.println (" then goto " + inst.str + "\t\t(float)");
  784.                     break;
  785.                 case OPgotofGE:
  786.                     System.out.print ("                if ");
  787.                     printANode (inst.arg1);
  788.                     System.out.print (" >= ");
  789.                     printANode (inst.arg2);
  790.                     System.out.println (" then goto " + inst.str + "\t\t(float)");
  791.                     break;
  792.                 case OPcomment:
  793.                     System.out.println ("! " + inst.str);
  794.                     break;
  795.                 case OPalloc:
  796.                     System.out.print ("                ");
  797.                     printANode (inst.result);
  798.                     System.out.print (" := alloc (");
  799.                     printANode (inst.arg1);
  800.                     System.out.println (")");
  801.                     break;
  802.                 case OPreadInt:
  803.                     System.out.print ("                readInt ");
  804.                     printANode (inst.result);
  805.                     System.out.println ();
  806.                     break;
  807.                 case OPreadFloat:
  808.                     System.out.print ("                readFloat ");
  809.                     printANode (inst.result);
  810.                     System.out.println ();
  811.                     break;
  812.                 case OPwriteInt:
  813.                     System.out.print ("                writeInt ");
  814.                     printANode (inst.arg1);
  815.                     System.out.println ();
  816.                     break;
  817.                 case OPwriteFloat:
  818.                     System.out.print ("                writeFloat ");
  819.                     printANode (inst.arg1);
  820.                     System.out.println ();
  821.                     break;
  822.                 case OPwriteString:
  823.                     System.out.print ("                writeString ");
  824.                     System.out.println (inst.str);
  825.                     break;
  826.                 case OPwriteBoolean:
  827.                     System.out.print ("                writeBoolean ");
  828.                     printANode (inst.arg1);
  829.                     System.out.println ();
  830.                     break;
  831.                 case OPwriteNewline:
  832.                     System.out.println ("                writeNewline");
  833.                     break;
  834.                 default:
  835.                     throw new LogicError ("Unexpected Opcode in PrintIR");
  836.             }
  837.         }
  838.         System.out.println ("=======================================");
  839.     }
  840.  
  841.  
  842.  
  843.     // printANode (p)
  844.     //
  845.     // For some IR instructions, "result", "arg1", and/or "arg2" will be a pointer
  846.     // to an AST node.  This routine is called by printIR to print such arguments.
  847.     //
  848.     static void printANode (Ast.Node p)
  849.         throws LogicError
  850.     {
  851.         if (p == null) {
  852.             System.out.print ("*****NULL*****");
  853.             throw new LogicError ("Some IR instruction has a null operand");
  854.         } else if (p instanceof Ast.VarDecl) {
  855.             System.out.print (((Ast.VarDecl) p).id);
  856.         } else if (p instanceof Ast.Formal) {
  857.             System.out.print (((Ast.Formal) p).id);
  858.         } else if (p instanceof Ast.IntegerConst) {
  859.             System.out.print (((Ast.IntegerConst) p).iValue);
  860.         } else if (p instanceof Ast.RealConst) {
  861.             System.out.print (((Ast.RealConst) p).rValue);
  862.         } else {
  863.             System.out.print ("*****????*****");
  864.             throw new LogicError ("Some IR instruction has a bad operand");
  865.         }
  866.     }
  867.  
  868.  
  869.  
  870.     // printOffsets (body)
  871.     //
  872.     // This method is passed a pointer to the AST. It runs through it, printing
  873.     // the offsets in all Formal and VarDecl nodes in the following format.
  874.     //
  875.     //    Printing Offset Information...
  876.     //       MAIN BODY:
  877.     //         FrameSize = 112
  878.     //         Offsets of local variables:
  879.     //           -4      i
  880.     //           -8      j
  881.     //       <...Offsets for procedures...>
  882.     //
  883.     static void printOffsets (Ast.Body body) {
  884.         System.err.println ("Printing Offset Information...");
  885.         System.err.println ("  MAIN BODY:");
  886.         System.err.println ("    FrameSize = " + body.frameSize);
  887.         System.err.println ("    Offsets of local variables:");
  888.         for (Ast.VarDecl vd = body.varDecls; vd != null; vd =vd.next) {
  889.             System.err.println ("      " + vd.offset + "\t" + vd.id);
  890.         }
  891.         for (Ast.ProcDecl pr = body.procDecls; pr != null; pr = pr.next) {
  892.             printOffsetsInProcDecl (pr);
  893.         }
  894.     }
  895.  
  896.  
  897.  
  898.     // printOffsetsInProcDecl (procDecl)
  899.     //
  900.     // This method is passed a pointer to a ProcDecl. It runs through it, printing
  901.     // the offsets in all Formal and VarDecl nodes.  It then runs through all
  902.     // nested procedures, doing the same.
  903.     //
  904.     //     PROCEDURE foo:
  905.     //       Offsets of formals:
  906.     //         68        z1
  907.     //         72        z2
  908.     //         76        z3
  909.     //       Offsets of local variables:
  910.     //         -4        v1
  911.     //         -8        v2
  912.     //         -12       w1
  913.     //
  914.     static void printOffsetsInProcDecl (Ast.ProcDecl procDecl) {
  915.         System.err.println ("  PROCEDURE " + procDecl.id + ":");
  916.         System.err.println ("    FrameSize = " + procDecl.body.frameSize);
  917.         System.err.println ("    Lex Level = " + procDecl.lexLevel);
  918.         System.err.println ("    Offsets of formals:");
  919.         for (Ast.Formal form = procDecl.formals; form != null; form = form.next) {
  920.             System.err.println ("      " + form.offset + "\t" + form.id);
  921.         }
  922.         System.err.println ("    Offsets of local variables:");
  923.         for (Ast.VarDecl vd = procDecl.body.varDecls; vd != null; vd = vd.next) {
  924.             System.err.println ("      " + vd.offset + "\t" + vd.id);
  925.         }
  926.         for (Ast.ProcDecl pr = procDecl.body.procDecls; pr != null; pr = pr.next) {
  927.             printOffsetsInProcDecl (pr);
  928.         }
  929.     }
  930.  
  931.  
  932. }
  933.