Generating Intermediate Code


Page visited times since September 14, 1998.

Read Chapter 7.

Translate package

Most of your work will be in the Translate package. These are the classes that you need to implement (if you follow the directions in the book)
  1. Frag, DataFrag, ProcFrag, and FragList: The result of translating a Tiger program to intermediate code will be a FragList (which is list of Frag objects). A DataFrag is emitted for each string constant that appears in the source program. A ProcFrag is emitted for each function in the source program.
  2. Exp, Ex, Nx, Cx, RelCx, IfThenElseExp: The descriptions of these classes are scattered throughout Chapter 7. The ultimate goal is to generate a Tree.Exp representation of the source program. There could be widely different Tree.Exp representations of the same source text, and these classes help us translate among the representations. You should begin with implementing Exp, Ex, Nx, and Cx by copying the code given at the beginning of the Chapter. Add the remaining classes as needed.
  3. Translate: This is the main class in the package Translate. It should be written in conjuction with the modifications to Semant described below.

Semant Package

The Semant class has to be modified as follows:
  1. The constructor for Semant should create an instance of Translate.Translate (call it trans in the following discussion) that will be used to convert Tiger's AST to a Translate.Exp representation.
  2. Each of the methods in Semant is now modified according to the following general idea.
      ExpTy transExp (Absyn.IntExp e) {
        return new ExpTy(trans.intExp(e.value), INT);
      }
    
    Instead of returning "null" as the result of translation to intermediate code, each method calls a helper method in Translate.Translate to convert the AST to intermediate code. The corresponding method in Translate.Translate in our example is:
      public Exp intExp (int i) {
        return new Ex (new Tree.CONST(i));
      }
    
  3. The Semant class gets a bit complicated because it has to know about a current label that it should use in the translation of BreakExp. If you have implemented the check that every BreakExp is properly nested, you are mostly there. Instead of keeping track of whether you are within a loop or not, you need to keep track of the label of the current enclosing loop. Use that label when translating a BreakExp as follows:
      ...
      private Temp.Label breakScope;
      ...
      ExpTy transExp (Absyn.BreakExp e) {
        ... // check if properly nested 
        return new ExpTy(trans.breakExp(breakScope), VOID);
      }
    
    In Translate.Translate, we would then have:
      public Exp breakExp (Temp.Label lab) {
        return new Nx(new Tree.JUMP(lab));
      }
    
    which would translate a "break" as a jump to the label of the enclosing loop.

Other Modifications

As you would expect, I have not described a full list of the changes you have to make. You have a lot of freedom and don't be afraid to make decisions! You will certainly need to make extensions to the Frame classes (both the abstract one and the machine-specific one) and there are a few other things to do in Semant. Finally depending on how you set up your classes, write a main class that takes the name of a Tiger file and prints out the generated intermediate code.
sabry@cs.uoregon.edu