300 likes | 488 Views
Lesson 7. CDT301 – Compiler Theory , Spring 2011 Teacher : Linus Källberg. Outline. Stack machine code Generating stack machine code using SDT. Stack machine code. Stack machine code. Values are kept on a stack Operations pop operands and push the result
E N D
Lesson 7 CDT301 – CompilerTheory, Spring 2011 Teacher: Linus Källberg
Outline • Stack machine code • Generating stack machine code using SDT
Stack machinecode • Values are kept on a stack • Operations pop operands and push the result • Similar to postfix notation
Examples of stack machines • Early architectures (around 1960) • Java Virtual Machine • Floating-point part of x86 • Adobe's PostScript • Trac42VM
Trac42VM code • x + y: RVALINT x RVALINT y ADD • z = x * y: LVAL z RVALINT x RVALINT y MULT ASSINT
Trac42VM code if(x < 0) y = 0 - x; elsey = x; RVALINT x PUSHINT 0 LTINT BRF label1 LVAL y PUSHINT 0 RVALINT x SUB ASSINT BRA label2 [label1] LVAL y RVALINT x ASSINT [label2] …
Exercise (1) What does this code store in x? Tip: “run” it with some different values on a and b, and then draw conclusions. LVAL x RVALINT a RVALINT b LTINT BRF label1 RVALINT b BRA label2 [label1] RVALINT a [label2] ASSINT
Exercise (2) Write Trac42VM code for this Trac42 program: while(i < 10) ++i; Hint: the code above is equivalent to loop_start: if(i >= 10) gotoloop_exit; i = i + 1; gotoloop_start; loop_exit: … (If labels and gotoswere allowed in Trac42, that is)
Making function calls • Declare room for the return value: DECL @ • Evaluate the arguments • Leave the results on the stack • Jump to the subroutine: BSR the_function
In the function • Symbolic names for the parameters • Returning from the function: • Evaluate the return value • Store it: LVAL @ ASSINT • Return from the subroutine: RTS
After the function call • Pop the arguments • (Pop the return value)
Function call example 1 int squared(int x) { returnx*x; } int trac42(void) { intfour; four = squared(2); return0; } [squared] LVAL @ RVALINT x RVALINT x MULT ASSINT RTS [trac42] DECL four LVAL four DECL @ PUSHINT 2 BSR squared POP 1 ASSINT LVAL @ PUSHINT 0 ASSINT RTS
Function call example 2 int squared(int x) { returnx*x; } int trac42(void) { squared(3 + 3); return0; } [squared] LVAL @ RVALINT x RVALINT x MULT ASSINT RTS [trac42] DECL @ PUSHINT 3 PUSHINT 3 ADD BSR squared POP 1 POP 1 LVAL @ PUSHINT 0 ASSINT RTS
Exercise (3) Starting from [trac42], “execute” the code here to the right. Source program: int squared(int x) { return x*x; } int trac42(void) { int ten; ten = squared(1 + 2) + 1; return 0; } [squared] LVAL @ RVALINT x RVALINT x MULT ASSINT RTS [trac42] DECL ten LVAL ten DECL @ PUSHINT 1 PUSHINT 2 ADD BSR squared POP 1 PUSHINT 1 ADD ASSINT LVAL @ PUSHINT 0 ASSINT RTS
Trac42VM code for expressions expr → expr + num { print(“PUSHINT “); print(num.value); print(“\nADD\n”) } | expr – num { print(“PUSHINT “); print(num.value); print(“\nSUB\n”) } | num { print(“PUSHINT “); print(num.value); print(“\n”) }
Trac42VM code for expressions expr → num { print(“PUSHINT “); print(num.value); print(“\n”) } rest rest → + num { print(“PUSHINT “); print(num.value); print(“\nADD\n”) } rest | - num { print(“PUSHINT “); print(num.value); print(“\nSUB\n”) } rest | ε
A recursive descent parser voidexpr() { if (lookahead == NUM) { intnum_value = attribute; match(NUM); printf(“PUSHINT %d\n“, num_value); rest(); } else error(); }
A recursive descent parser void rest() { int num_value; switch (lookahead) { case '+': match('+'); num_value = attribute; match(NUM); printf(“PUSHINT %d\n”, num_value); printf(“ADD\n”); rest(); break; case '-': ...analogous ... default: break; // Epsilon } }
Generating labels if_stmt → if ( cond ) block if_tail if_tail→ ε | else block
Generating labels • Format of translated if-else statement: Evaluate condition BRF “else” label “True” block BRA “after” label [“else” label] “Else” block [“after” label]
Generating labels voidif_stmt() { char* else_label, * after_label; match(IF); match( '(' ); cond(); match( ')' ); // Generate new labels else_label = get_new_label(); after_label = get_new_label(); // "True" block printf(" BRF %s\n", else_label); // Jump past "true" block if false block(); printf(" BRA %s\n", after_label); // Jump past "else" block // "Else" block printf("[%s]\n", else_label); // Generate "else" label if_tail(); // This might or might not generate any code printf("[%s]\n", after_label); // Generate "after" label }
Exercise (4) Given is the following translation scheme. expr → expr * factor { print("MULT\n") } | factor factor → ! factor { print("NOT\n") } | num { print("PUSHINT "); print(num.value); print("\n") } • Rewrite it to remove all left recursion. • Draw the parse tree for “1 * 2 * !3”, with the semantic actions embedded (with dashed edges). • Traverse the tree and “execute” the semantic actions.
Conclusion • Stack machine code • Generating stack machine code using SDT
Next time • Bottom-up parsing