310 likes | 418 Views
Code Generation. Read Pages 357-359, 386-389, 410-416 Homework Lab 4. Precedence & Associativity of Operators. + - ! * / mod + - < > <= >= != == & || =. Example: Arithmetic Expressions. exprE ::= exprE || exprD | exprD exprD ::= exprD && exprC | exprC
E N D
Code Generation Read Pages 357-359, 386-389, 410-416 Homework Lab 4
Precedence & Associativityof Operators + - ! * / mod + - < > <= >= != == & || =
Example: Arithmetic Expressions exprE ::= exprE||exprD | exprD exprD ::= exprD&&exprC | exprC exprC ::= exprCRelOpexprB | exprB exprB ::= exprBAddOpexprA | exprA exprA ::= exprAMulOp expr1 | expr1 expr1 ::= (exprE) | id | literal
Coding the expressions BNF void exprE( args?? ) { exprD(); while (nextToken == “||”) { match(||) exprE() } }
Coding the expressions BNF void expr1( args?? ) { switch(nextToken) { case id : Load( id); match(id); break; case literal : match(id); Load( id); break; case ‘(‘ : match (‘(‘); expr(); match(‘)’); break; default : Error!! }
Examples • Example 25: (x+z)*12 • http://jhelum.cs.iastate.edu/cgi-bin/comp.cgi • Ex. 26 : x – y- z
Memory in Your Compiler • A function has an address that indicates where the code begins for the function • main() is a function in C++ • The interpreter will use 3 registers for your project • L: points to the top of the system stack (beginning of the current activation record) • G: points to the beginning of the statics • P: points to the current instruction. Initially set to the beginning of main()
Memory Layout • Statics are variable declared as “globals” • This can be forced in C++ with the static keyword • Memory is allocated at compile time • The stack starts at the end of the statics and grows down • The heap starts at the bottom and grows up Code : Jmp : Code : Start : Static Vars. Stack Heap
Memory Example Symbol Table ID type level addr X int 0 0 Y int 0 4 K char 0 8 R real 0 9 • The address given in the symbol table, then G is determined and these addr’s are offsets
Memory Example Cont. X = Y; LOAD G + 4 STORE G + 0
Preliminaries for every program • After Code is Complete load the address of G • pop G – then G has the address of the begin of statics • If there are automatic variables the value is stored with the activationRecord & we do the same with L • L points to the first address after the statics, that is G + size of the last item on the symbol table + the last address on the symbol table • When the beginning of main is found we can do the same with P
Consider the following intxvoid f() {int xvoid g() {int q, r} // end g void h( int a, int b ) {int x} // end h} // end fintyvoid g() {int x} // end ginth() {inta,b} • Global • f g h • g h • Draw the Symbol Table!
Consider “case” statement & warnings for unreachable code • case( x ) { 1,5: A 3: B 2,7: C default: D} • A-D are representing code blocks • Consider diagram 28
case statement cont. void case() { match(“caseToken”) match(‘(’)expr() //leaves value of expression on stack match(‘)’) emit(LoadIM) // loads first case statement on eval stack save=currentAddress // saves a space in the target code’s emit(0) // memory to put the low value in :caseBlockList() // sends back the low and high values //now go back into memory to “save” and put // the actual value of low in } • Homework: Lab 5
Type Casting • If t, r, & s are floatst = r+s • Then the following code needs to be generated Load 4 r Load 4 sAddF Store 4 t
Type Casting • In general we have expressions in the form: op = op1 command op2, where command could be + - % * op1 op2 op command I I R I I R R R • Now create a table for /
Type Casting • Every expression must return a type • Once all operands have been type checked we can determine the type of operation that needs to be performed • Example : x+y*z is the + an ADDF or ADD • Draw the tree with types
Type Casting • Example: t = r + s • If the expression is actually integer addition, then backpatch the FLTs with NOOPs • Load 4 rFLT NOOPLoad 4 sFLT NOOPAddF AddStore 4 t
Assignment Statement • <lvalue> = <expr> • need to know the type and address of the lvalue • need to know the type of the expr
Assignment Statement void assign() {lvalue(type1, address, storage class) // storage class - auto(L) or static(G) match(‘=’)expr(type2) // type checking stuff if (type1 == “int” && type2 == “real”) // truncate type2 to int else if (type1 == “real” && type2 == “int”)// FLT type2(expr result) . . .
Code Generation • emit (store) // possibly pass storage class? • emit1 (opcode) // emits one byte • emit2 (address) // emits two bytes • emit4 (real value) // emits 4 bytes. I will give you one function for float and another for int • backpatch1(value, address) // opcode • backpatch2(value, address) // address • backpatch4(value, address) // value
Code Generation • To set up any program registers must be initialized • Consider what happens with: http://jhelum.cs.iastate.edu/cgi-bin/comp.cgi • The symbol table holds the address of main() since it is a function • The size of activation records and how items are stored in it are determined at run time
If statements if expr.boolcodeblock Type type;match(if)expr(type)if(type!=bool)error(“type mismatch in if statement”)emit1(BNO) // branch 10 bytes past PC if value on stack is not 0saveAdd=curAddemit2(0, curAdd)save=curAddcodeblock();emit2(curAdd-save, saveAdd) • Draw the diagram!
If-else • if <expr1> {CB1}else if <expr2> {CB2}else {CB3} • Example 31 • Homework: Lab 6
while <expr> <cb> match(while)exadd=curaddexpr(type)if (type != bool) error(“type mismatch”)emit1(BNO)saveadd = curaddemit2(0, curadd)save=curaddcodeblock()emit1(JMP)emit2(exadd, curadd)emit2(curadd-save, saveadd) • Draw the diagram!
For loop for id expr.int step expr.int Codeblock Match("forToken"); SymTab(ID, const) if(!st.for_insert(symadd)) error(" SYMBOL ALREADY EXISTS !! "); addrStep = symadd->addr; Match("idToken"); Expression(type);
For loop cont. // INITIALIZE THE LOOP VARIABLE emit1(STLR4); emit2(addrStep); if(type != INTEGER) error("TYPE MISMATCH IN FOR LOOP!!! "); step = Step(); addr1 = curr_addr; Expression(type);
For loop cont. //check if the condition is satisfied emit1(LDLR4); emit2(addrStep); emit1(SUB); emit1(TNN); emit1(BYES); //condition not satisfied emit1(3); emit1(JMPD); //jump out of for loop addr2 = curr_addr; emit2(0);
For loop cont. if(type != INTEGER) error(" TYPE MISMATCH IN THE FOR LOOP ... !!! "); CodeBlock(); emit1(LDLR4); emit2(addrStep); emit1(LDM4); emit4(step); emit1(ADD); emit1(STLR4); emit2(addrStep);
For loop cont. //jump back to for loop emit1(JMPD); emit2(addr1); BackPatch2(curr_addr, addr2); • Draw the diagram!