Computer Science Department
Programming Methods Laboratory

Compilation     winter 00/01
Ecole Polytechnique Federale de Lausanne
Assignment 5
12.01.01

This assigment focuses on the implementation of the code generation of our j0 compiler. We generate assembler code for a simple RISC processor. An emulator assembles and executes the code. Here is the source code of the emulator: Emulator.java A description of the processor was handed out in the lecture. You can find an instruction summary here. For your implementation, we provide several supporting classes:
  • Code.java represents the generated code. It provides some basic operations to emit instructions and to give out the code in assembly form.
  • Generator.java contains the general code generation visitor. This is the file where you should implement a code generation scheme for every language construct.
  • Instructions.java describes the target architecture by providing constants for instructions, registers etc.
  • Item.java contains some items for supporting delayed code generation.
  • Predef.java provides predefined symbols. You should add a call to Predef.enterAll to the analyzeTree method in Analyzer.java. It should look similar to this version:
        public static Scope analyzeTree(Tree tree) {
            Scope initialScope = new Scope(null);
    	Predef.enterAll(initialScope);
            tree.apply(new Analyzer(initialScope));
            return initialScope;
        }
    
1) Start with generating code for simple arithmetic expressions. Then proceed with supporting arrays. For this phase you can assume that there is only one function without parameters containing all the code.

2) Integrate conditional items in order to be able to compile loops, conditional jumps and shortcut evaluation of & and |. Note that the implementation of shortcut evaluation is optional.

3) Implement function definitions and function calls. Please note that the compilation scheme for functions presented in the lecture leaves out allocation of block-local variables. You have basically two choices to allocate them:

  • you traverse the body of the function and find all local variables before generating code; in this case all variables are allocated at the beginning of the function and deallocated at the end.
  • variables of a block are allocated on the stack when entering the block and deallocated when leaving. (beware of implementing the return statement inside of nested blocks correctly)
In J0, the main function has the following signature:
    void main();
The J0 compiler has to emit code for calling the main function after setting up the global variables. A J0 program without a main function terminates immediately.

You should present your solution in the tutorial on Friday, 09.02.01. This time, there will be also an oral exam about the lecture. For this purpose please make sure that every member of your group will be there. You can subscribe your group for a specific time and a specific examiner on a list which can be found on our whiteboard on floor 3 of building INR.