LANGUAGE TRANSLATORS: WEEK 24 TRANSLATION TO ‘INTERMEDIATE’ CODE (overview) Labs this week: Tutorial Exercises on Code Generation
REVIEW …. n Lexical Analysis - produces token sequence n Parsing - produces abstract syntax tree --- JavaCup and Interpreter Generation --- n Semantic Analysis - produces symbol table This week (briefly): Run Time Memory Management Intermediate Code Creation
Overview.. There are HUNDREDS (N) of programming languages (C, ADA, Fortran, Java, C++, Algol, Pascal, Modula, Miranda, Haskell, Scheme..) and several different language paradigms (Functional, Logical, Imperative + OO variants..) There are many (M) different ARCHITECTURES - (Intel, SPARC, VAX..) So we need N * M complete compilers....Or N ‘front ends’ + M ‘back ends’
Complexity of HLPL High Level PLs have n static and dynamic data structures n modules / objects n recursion, embedded function calls.. n Various forms of selection / iteration All have to be translated (eventually) into an executable- machine code (in a very simple language such as in Hugh Osborne’s Little Man Computer!?) with space for data, returned values, passed parameters
Typical Layout of an “Executable” RUN-TIME STACKhigh address free memory STATIC DATA MACHINE CODElow level
Run time management of local data If Programs had all global, static data and didn’t pass parameters to subprograms, things would be easy! Subroutine/function/procedure/method all need parameter passing rules.. E.g consider C - like function: foo(int x, y) { int z; … } x and y receive values initially, and they may change. After execution the space for x, y and z can be re-used...foo will be the address of the ‘returned’ value.
C-like Example.. int x = 0; int p(int a){ int b … int q(int c,d){ … return c+d+b+x;} ; return q(2*a,b)}; x = p(x+1);...
Stack Frames/Activation Records n The compiler creates a frame ‘template’ for each function (procedure, subroutine…) n During ‘runtime’, each invocation of a function causes a new stack frame to be created and the stack pointer moved down. n The same function can be invoked many times and have many stack frames at the same time (as in recursion). n Invocations need to be able to address frames higher up (via ‘static links’) n At the end of the ‘lifetime’ of the current frame, the stack pointer in moved up to the start of the current frame, and what is below it can be re-used.
Abstract Machine Code Generation Assume we have a target code which can store to, and fetch from memory, and can do basic arithmetic on values in registers in the CPU: ABSTRACT MACHINE INSTRUCTIONS: STORE T Y - store the contents of T in the space pointed to by Y FETCH X T - fetch the contents of X and put it into the temporary (register) T TIMES T1 T2 T3 - get the contents of registers T1,T2, multiply them, and put the result into temporary T3 GOTO LABEL - control jump to the line marked ‘label’ GOTO T1 LABEL_X LABEL_Y - conditional control jump
Abstract Machine Code Generation We will design code that ‘prints out’ the AMC, when input with the n abstract syntax tree n symbol table of a simple high level program. We will consider: - expressions, assignment, loops, recursion
“Expression” -> Abstract Machine Code INPUTS the abstract syntax tree of an expression and the SYMBOL TABLE at that point in the program;OUTPUTS the AMC program and STORES the value of the expression in a register. register generate_Exp_code( Expression_Tree E, Symbol_Table ST) = { register store1,store2,store3,store4; memory_reference variable_ref; case E instanceof Variable :/* E is a variable */ variable_ref = get_reference( E, ST) ;/* Find address from Sym Table */ store1 = free_register;/* Store the contents of variable_ref print( "FETCH ", variable_ref, store1, " ; ");/* in a free register */ return store1; E instanceof Times : /* E is a times operation LHS x RHS*/ store2 = generate_Exp_code(E.lhs, ST); /* Generate code for LHS */ store3 = generate_Exp_code(E.rhs, ST); /* Generate code for RHS */ store4 = free_register; print( "TIMES ", store2, store3, store4);/* Multiply register values together */ return store4;/* and return final register reference */ E instanceof Etc Etc.… END CASE }
“Assignment” -> Abstract Machine Code INPUTS the abstract syntax tree of an assignment statement and the SYMBOL TABLE at that point in the program: OUTPUTS the AMC program void generate_Stm_code( Syntax_Tree X, Symbol_Table ST) = …….. CASE X instanceof AssignmentStm { memory_reference variable_ref; register temp; variable_ref = get_reference( X.lhs, ST) ; /* -finds the reference of the LHS variable from the SYMBOL TABLE */ temp = generate_Exp_code(X.rhs, ST); /* -prints code for RHS, puts the value of the RHS into a register */ print( "STORE ", temp, variable_ref, " ; ") } …….
“While” => Abstract Machine Code /* While X.Exp Do X.Stm */ …... case X instanceof WhileStm { int i = 0; memory_reference variable_ref; register temp; print(label(i),”;”); i++ ; temp = generate_Exp_code(X.Exp, ST); print(“GOTO”, temp, label(i), label(i+1),”;”); print(label(i),”;”); i++ ; generate_Stm_code( Syntax_Tree X.Stm, Symbol_Table ST); print(“GOTO”, label(i-2),”;”); print(label(i),”;”); } …….
Exercises and Follow on work.. Go through exercises at the end of the handout, in labs Read Chapters 6 and 7 in Appel’s book Read Chapters 7 and 8 in online book (link from week 11 on Course Website)