Upload
anthony-miller
View
221
Download
0
Embed Size (px)
Citation preview
Lesson 7
CDT301 – Compiler Theory, Spring 2011Teacher: Linus Källberg
2
Outline
• Stack machine code• Generating stack machine code using SDT
STACK MACHINE CODE
3
Stack machine code
• Values are kept on a stack• Operations pop operands and push the
result– Similar to postfix notation
4
Examples of stack machines
• Early architectures (around 1960)• Java Virtual Machine• Floating-point part of x86• Adobe's PostScript• Trac42VM
5
Trac42VM code
• x + y:RVALINT xRVALINT yADD
• z = x * y:LVAL zRVALINT xRVALINT yMULTASSINT
6
Trac42VM codeif (x < 0) y = 0 - x;else y = 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] …
7
Trac42VM
8
Instruction(s) FunctionPUSHINT x Push the constant xDECL l Declare a variable named l. For function return
values, the reserved name @ can be used.RVALINT l Push the contents (the “r-value”) of variable lLVAL l Push the address (the “l-value”) to the variable lPOP n Pop n elementsASSINT Pop a value x, pop a stack address a, and then store
x to aNOT Pop a value x, then push 1 if x == 0, otherwise 0
Trac42VM
9
Instruction(s) FunctionADD, SUB, MULT, DIV, EQINT, LTINT, LEINT
Pop two operands, perform the operation (the right operand is the first popped), and then push the result. The boolean operators return 0 for false and 1 for true.
[l] Adds the code label lBRA l Jump to the label lBRF l Pop a value, and if 0 jump to the label lBSR l Jump to the subroutine labelled lRTS Return from the current subroutine
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
10
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) goto loop_exit; i = i + 1; goto loop_start;loop_exit: …
(If labels and gotos were allowed in Trac42, that is)11
Making function calls
1. Declare room for the return value:DECL @
2. Evaluate the arguments– Leave the results on the stack
3. Jump to the subroutine:BSR the_function
12
In the function
• Symbolic names for the parameters• Returning from the function:
1. Evaluate the return value2. Store it:
LVAL @ASSINT
3. Return from the subroutine:RTS 13
After the function call
1. Pop the arguments2. (Pop the return value)
14
Function call example 1int squared(int x) { return x*x;}
int trac42(void) { int four; four = squared(2); return 0;}
[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
15
Function call example 2int squared(int x) { return x*x;}
int trac42(void) { squared(3 + 3); return 0;}
[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
16
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
17
GENERATING STACK MACHINE CODE USING SDT
18
Trac42VM code for expressionsexpr → 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”) }
19
Trac42VM code for expressionsexpr → 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
| ε20
A recursive descent parser
void expr() {if (lookahead == NUM) {
int num_value = attribute;match(NUM);printf(“PUSHINT %d\n“, num_value);rest();
}else error();
}21
A recursive descent parservoid 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}
}
22
Generating labels
if_stmt → if ( cond ) block if_tailif_tail → ε
| else block
23
Generating labels• Format of translated if-else statement:
Evaluate condition BRF “else” label “True” block BRA “after” label[“else” label] “Else” block[“after” label]
24
Generating labelsvoid if_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}
25
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") }
a) Rewrite it to remove all left recursion.b) Draw the parse tree for “1 * 2 * !3”, with the semantic
actions embedded (with dashed edges).c) Traverse the tree and “execute” the semantic actions.
26
Conclusion
• Stack machine code• Generating stack machine code using SDT
27
Next time
• Bottom-up parsing
28