Presentation is loading. Please wait.

Presentation is loading. Please wait.

Compiler Structures 11. IC Generation: Control Structures Objectives

Similar presentations


Presentation on theme: "Compiler Structures 11. IC Generation: Control Structures Objectives"— Presentation transcript:

1 Compiler Structures 11. IC Generation: Control Structures Objectives
, Semester 2, 11. IC Generation: Control Structures Objectives describe IC generation for control structures if, if-else, while, loop examine the 'ctrl' language compiler

2 Overview 1. More SPIM 2. Control Structures in SPIM 3. Generating Prime Numbers 4. The 'ctrl' Language 5. The ctrl Parser 6. The Instruction Set 7. ctrlParser.c Coding 8. emulator.c Coding

3 In this lecture Front End Back End Source Program Lexical Analyzer
Syntax Analyzer In this lecture Semantic Analyzer Int. Code Generator Intermediate Code Code Optimizer Back End As I said earlier, there will be 5 homeworks, each of which will contribute to 5% of your final grade. You will have at least 2 weeks to complete each of the homeworks. Talking about algorithms really helps you learn about them, so I encourage you all to work in small groups. If you don’t have anyone to work with please either me or stop by my office and I will be sure to match you up with others. PLEASE make sure you all work on each problem; you will only be hurting yourself if you leach off of your partners. Problems are HARD! I will take into account the size of your group when grading your homework. Later in the course I will even have a contest for best algorithm and give prizes out for those who are most clever in their construct. I will allow you one late homework. You *must* write on the top that you are taking your late. Homework 1 comes out next class. Target Code Generator Target Lang. Prog.

4 1. More Spim Comparison operators Examples:
Comparison operators reg1 = reg2 OP reg3, where OP is gt, ge, lt, le, eq, etc. written as: <s>OP reg1, reg2, reg3 reg1 is set to 0 to mean false, non-zero for true Examples: sgt reg1,reg2,reg3 slt reg1,reg2,reg3 continued

5 SPIM generates new labels as needed.
Jump Instructions b label // unconditional branch to label <b>OP reg1,label conditional branch to label, based on reg1 value OP = eqz, neq, etc. SPIM generates new labels as needed.

6 2. Control Structures in SPIM
Constructs: if, if-else, switch, etc. while, for, etc.

7 Translating "if" Control Flow
lw $t0,y li $t1,0 // load integer sgt $t2,$t0,$t1 // > test beqz $t2,L2 // jump if false ...body... L2: if (y > 0) { ...body... } Control Flow

8 Translating "if-else" Control Flow
if (y > 0) { ...body1... } else { ...body2... lw $t0,y li $t1,0 sgt $t2,$t0,$t1 // > test beqz $t2,L2 // jump if false ...body1... b L3 L2: ...body2... L3: Control Flow

9 Translating "while" Control Flow
L25: lw $t0,x li $t1,100 slt $t2,$t0,$t1 // < test beqz $t2,L26 // jump if false ...body... b L25 L26: while (x < 100) { ...body... } Control Flow

10 Example lw $t0,x li $t1,100 L25: slt $t2,$t0,$t1 beqz $t2,L26 addi $t0,$t0,1 b L25 L26: while (x < 100) { x = x + 1; }

11 For  while can be translated to: this is the value in max
for (i=0; i < max; i++) body; can be translated to: i=0; while (i < max) { ...body... i = i+1; } li $t0,0 li $t1,100 L25: slt $t2,$t0,$t1 beqz $t2,L body... addi $t0,$t0,1 b L25 L26:

12 3. Generating Prime Numbers
(in SPIM) print 2; print ' '; for (i = 3; i <= 100; i++) { divides = 0; for (j = 2; j <= i/2; j++) { if (i%j == 0) divides = 1; } if (divides == 0) { print i;

13 Outer Loop for (i = 3; i <= 100; i++)
li $t0, 3 // t0 (i) = 3 li $t1,100 // t1 = max value l1: sle $t7,$t0,$t1 // is (i <= 100) ? beqz $t7, l2 // jump to l2 if false ... addi $t0,$t0,1 // i = i+1 b l1 l2:

14 Inner Loop for (j = 2; j <= i/2; j++)
li $t2,2 // t2 (j) = 2 li $t7,2 // t7 = divisor (2) div $t3,$t0,$t7 // t3 = i/2 l3: sle $t7,$t2,$t3 // is (j <= i/2) ? beqz $t7,l4 // jump to l4 if false ... addi $t2,$t2,1 // j = j+1 b l3 l4:

15 If Tests if (i%j == 0) rem $t7,$t0,$t2 // t7 = i%j (remainder) bnez $t7,l5 // jump to l5 if i/j != 0 li $t4,1 // t4 (divides) = 1 l5: ... bnez $t4,l6 // jump to l6 if divides != 0 print i print l6: if (divides == 0)

16 4. The "ctrl" Language (At last) a new grammar: continued
program ::= { { statement }* } statement ::= ID '=' cond ';' | 'print' [ STRING ] [ cond ] ';' | 'while' '(' cond ')' statement | 'if' '(' cond ')' statement [ 'else' statement ] | '{' { statement }* '}' continued

17 cond ::= expr [ ('>'|'>='|'<'|'<='|'=='|'!=') expr ]
expr ::= term { ( '+' | '-' ) term } term ::= factor { ('*' | '/' ) factor } factor ::= '(' expr ')' | INT | ID

18 Example Programs test0.txt ifTest.txt
x = 2; print x; y = 3 + x; print "y = " y; ifTest.txt x = 2; if (x > 5) y = 1; else y = 2; print y; continued

19 whileTest.txt sum = 0; x = 5; while (x > 0) { sum = sum + x;
x = x - 1; } print "sum = " sum;

20 Differences from Expressions Lang.
ctrl uses semicolon (;) to separate statements left and right braces ({...}) for statement blocks control structures: if, else, and while, a print command condition operators: >, >=, <, <=, ==, !=

21 5. The ctrl Parser ctrlParse.c is very similar to exprParse3.c:
it builds a parse tree for the input file intermediate code (IC) is generated from the parse tree, and saved to a file the IC is executed by a separate emulator

22 Usage stores intermediate code in codeGen.txt test0.txt ctrlParse
> gcc -Wall -o ctrlParse ctrlParse.c > ./ctrlParse < test0.txt stores intermediate code in codeGen.txt test0.txt ctrlParse codeGen.txt

23 codeGen.txt: PUSH 2 test0.txt x = 2; print x; y = 3 + x;
STORE x PUSHS "" LOAD x PRINT PUSH 3 ADD STORE y PUSHS "y = " LOAD y STOP test0.txt x = 2; print x; y = 3 + x; print "y = " y;

24 Emulator Usage emulator.c is a new program with the same name as the
emulator used with exprParse3.c > ./emulator codeGen.txt Reading code from codeGen.txt x being declared 2 y being declared y = 5 Finished codeGen.txt emulator it runs the intermediate code

25 6. The Instruction Set The instructions refer to 5 data structures used in the emulator a symbol table, a stack (seen in exprParse3) code storage array, label locations array, program counter

26 The Emulator's Data Structures
a symbol table of IDs and their integer values a stack of integers or strings for evaluating expressions and printing x 4 stack "foo" symbol table 2 continued

27 . . . . . . . . . code storage array, code[] "2" "x" "0" 1 5 label
PUSH STORE LABEL . . . . . . 1 5 label locations array, labelLocs[] . . . 5 1 2 3 if label x is at code index (address) i then labelLocs[x] == i e.g. label 0 at address 5 continued

28 program counter, pc the program counter stores the current code address (index) which is being executed

29 Initializing the Data Structures
When the emulator loads the instructions file, the code is stored in code[], and labelLocs[] is initialized. When execution starts, pc is set to 0, and the symbol table and stack are used as needed.

30 The Instructions (overview)
Load/store: LOAD <id>, STORE <id>, PUSH <int> Printing: PUSHS <string>, PRINT Control Flow: LABEL <int>, JMPZ <int>, JMP <int> Conditions: GT, GE, LT, LE, EQ, NE Math: MULT, ADD, MINUS, DIV

31 Some of the Instructions
LOAD <id> // get <id>'s value from symbol table, and push onto stack STORE <id> // copy stack top into symbol table entry for <id> continued

32 PUSH <int> // push integer onto stack
PUSHS <string> // push the string PRINT can print a string, or an integer, or a string followed by an integer these values are obtained by popping one or two values off the stack continued

33 LABEL <int> JMPZ <int> JMP <int>
labelLocs[ <int> ] is assigned the address of this LABEL when the code is loaded JMPZ <int> pop the stack, and jump to labelLocs[<int>] if the popped value is 0 jumping is done by changing the pc JMP <int> jump to labelLocs[<int>] pc = labelLocs[<int>]

34 MULT pop two stack values, multiply them, push result back ADD, MINUS, DIV same for these ops

35 7. ctrlParse.c Coding ctrlParse.c has a very similar structure to exprParse3.c parse functions are derived from the grammar they build a parse tree for the program code generation functions convert the tree to instructions

36 main() int main(void) /* parse, print the tree, then generate code which is stored in CODE_FNM */ { Tree *t; nextToken(); t = program(); match(SCANEOF); printTree(t, 0); printf(" \n"); generateCode(CODE_FNM, t); return 0; }

37 7.1. Parsing Functions The non-terminals are:
program, statement, cond, expr, term, factor The parsing functions are: program(), statement(), condition(), expression(), term(), factor() and parsePrint() and parseIf() to deal with the complex parsing of the print and if statements

38 program() Tree *program(void) // program ::= { { statement }* } { Tree *t, *left, *statTree; left = NULL; dprint("Parsing program\n"); while (currToken != SCANEOF) { statTree = statement(); t = makeTreeNode(SEMICOLON, left, statTree); left = t; } return left; } // end of program()

39 Tree Structure for Program
A program is a sequence of statements: s1; s2; s3; which becomes the tree: left ;3 ;2 s3 ;1 s2 s1 NULL

40 statement() continued
Tree *statement(void) /* statement ::= ID '=' cond ';' | 'print' [ STRING ] [ cond ] ';' | 'while' '(' cond ')' statement | 'if' '(' cond ')' statement [ 'else' statement ] | '{' { statement }* '}' */ { Tree *t, *idTree, *condTree, *statTree; Tree *left; // used for { stats } dprint("Parsing statement\n"); : continued

41 if (currToken == ID) { // ID '=' cond ';' idTree = makeIDLeaf(tokString); match(ID); match(ASSIGNOP); condTree = condition(); match(SEMICOLON); t = makeTreeNode(ASSIGNOP, idTree, condTree); } else if (currToken == PRINT) t = parsePrint(); : continued

42 WHILE t cond stat else if (currToken == WHILE) { // 'while' '(' cond ')' statement match(WHILE); match(LPAREN); condTree = condition(); match(RPAREN); statTree = statement(); t = makeTreeNode(WHILE, condTree, statTree); } else if (currToken == IF) t = parseIf(); : continued

43 else if (currToken == LBRACE) { match(LBRACE); // '{' { statement }
else if (currToken == LBRACE) { match(LBRACE); // '{' { statement }* '}' left = NULL; while (currToken != RBRACE) { statTree = statement(); t = makeTreeNode(SEMICOLON,left,statTree); left = t; } t = left; match(RBRACE); else syntax_error(currToken); return t; } // end of statement()

44 parseIf() Tree *parseIf(void) //'if' '(' cond ')' statement ['else' statement] { Tree *t, *condTree,*thenStat,*elseStat,*subTree; dprint("Parsing if\n"); match(IF); match(LPAREN); condTree = condition(); match(RPAREN); thenStat = statement(); if (currToken == ELSE) { match(ELSE); elseStat = statement(); } : continued

45 t IF cond ELSE else elseStat = NULL; subTree = makeTreeNode(ELSE, thenStat, elseStat); // node for two-way branch t = makeTreeNode(IF, condTree, subTree); return t; } // end of parseIf() then stat else stat

46 7.2. Code Generation Code generation writes instructions into the codeGen.txt file based on the parse tree created by the parsing functions.

47 generateCode() void generateCode(char *fnm, Tree *t) { FILE *fp; if ((fp = fopen(fnm, "w")) == NULL) { printf("Could not write to %s\n", fnm); exit(1); } else { printf("Writing code to %s\n", fnm); codeGen(fp, t); fprintf(fp, "STOP\n"); fclose(fp); } // end of generateCode()

48 codeGen() codeGen() recurses over the tree to find statement subtrees below SEMICOLON nodes. It then converts the tree nodes into instructions. The node types: ASSIGNOP, PRINT, WHILE, IF, ID, INT, PLUSOP, MINUSOP, MULTOP, DIVOP, GT, GE, LT, LE, EQ, NE continued

49 The conversion for ASSIGNOP, ID, INT, and the math operations (PLUSOP, MINUSOP, MULTOP, and DIVOP) are very similar to exprParse3.c In this part, I'll only look at how the subtrees for WHILE and IF are translated to instructions.

50 void codeGen(FILE. fp, Tree. t) { SymbolInfo. si; char
void codeGen(FILE *fp, Tree *t) { SymbolInfo *si; char *id; if (t == NULL) return; Token tok = TreeOper(t); if (tok == SEMICOLON) { // recurse over tree codeGen(fp, TreeLeft(t)); codeGen(fp, TreeRight(t)); } : continued

51 else if (tok == ASSIGNOP) { // id = expr char
else if (tok == ASSIGNOP) { // id = expr char *id = TreeID(TreeLeft(t)); getIDEntry(id); // don't use Symbol info codeGen(fp, TreeRight(t)); fprintf(fp, " STORE %s\n", id); } else if (tok == PRINT) codePrint(fp, t); else if (tok == WHILE) codeWhile(fp, t); else if (tok == IF) codeIf(fp, t); : // more code not shown } // end of codeGen()

52 codeWhile() Tree  instructions LABEL l-start // code for cond
JMPZ l-end // code for stat JMP l-start LABEL l-end WHILE cond stat

53 void codeWhile(FILE. fp, Tree
void codeWhile(FILE *fp, Tree *t) { int startLabel = labelCounter; labelCounter++; int endLabel = labelCounter; fprintf(fp, "LABEL %d\n", startLabel); codeGen(fp, TreeLeft(t)); // condition fprintf(fp, "JMPZ %d\n", endLabel); codeGen(fp, TreeRight(t)); // statement fprintf(fp, "JMP %d\n", startLabel); fprintf(fp, "LABEL %d\n", endLabel); } // end of codeWhile() WHILE t cond stat

54 while Code Generation whileTest.txt sum = 0; x = 5; while (x > 0) {
PUSH 0 STORE sum PUSH 5 STORE x LABEL 0 LOAD x GT JMPZ 1 LOAD sum ADD PUSH 1 MINUS JMP 0 LABEL 1 PUSHS "sum = " PRINT STOP whileTest.txt sum = 0; x = 5; while (x > 0) { sum = sum + x; x = x - 1; } print "sum = " sum;

55 codeIf() Tree  instructions continued // code for cond JMPZ l-else
// code for then JMP l-end LABEL l-else // code for else LABEL l-end IF cond ELSE then stat else stat continued

56 An if statement with no else part.
// code for cond JMPZ l-end // code for then LABEL l-end cond ELSE N then stat

57 t IF void codeIf(FILE *fp, Tree *t) // t is node(IF, condTree, subTree) { Tree *subTree; subTree = TreeRight(t); // subTree == node(ELSE, thenStat, elseStat) int endLabel = labelCounter; labelCounter++; codeGen(fp, TreeLeft(t)); // condition if (TreeRight(subTree) == NULL) { // no else fprintf(fp, "JMPZ %d\n", endLabel); codeGen(fp, TreeLeft(subTree)); // then part } : cond ELSE then stat else stat continued

58 else { // there is an else int elseLabel = labelCounter; labelCounter++; fprintf(fp, "JMPZ %d\n", elseLabel); codeGen(fp, TreeLeft(subTree)); // then part fprintf(fp, "JMP %d\n", endLabel); fprintf(fp, "LABEL %d\n", elseLabel); codeGen(fp, TreeRight(subTree)); // else part } fprintf(fp, "LABEL %d\n", endLabel); } // end of codeIf()

59 if Code generation ifTest.txt else end
PUSH 2 STORE x LOAD x PUSH 5 GT JMPZ 1 PUSH 1 STORE y JMP 0 LABEL 1 LABEL 0 PUSHS "" LOAD y PRINT STOP ifTest.txt x = 2; if (x > 5) y = 1; else y = 2; print y; else end

60 8. emulator.c Coding The instructions in codeGen.txt are loaded into the code[] array and labelLocs[], and the code starts being executed by execCode(). "2" "x" "0" PUSH STORE LABEL . . . . . . code[] 1 5 labelLocs[] . . . 5 1 2 3

61 execCode() void execCode(void) { pc = 0; while (1) // STOP causes execution to stop processCmd( code[pc] ); }

62 processCmd() processCmd() deals with the different instructions that may be stored in a code[] struct: STOP, STORE, LOAD, PUSH, PUSHS, LABEL, JMPZ, JMP, PRINT, ADD, MINUS, MULT, DIV, GT, GE, LT, LE, EQ, NE

63 MemLoc is the type of the code[] struct. e.g. m1 cmdTok arg "2"
void processCmd(MemLoc ml) { SymbolInfo *si; CmdToken cmdTok; int v1, v2; cmdTok = ml.cmdTok; sprintf(currInst, "%d. %s %s", pc+1, cmdTokSyms[cmdTok], ml.arg); // make a string showing current inst. if (cmdTok == STOP) { printf("Finished\n"); exit(0); } : PUSH cmdTok arg "2" continued

64 else if (cmdTok == STORE) { // STORE <id> // pop stack top onto symTable for id si = getIDEntry(ml.arg); si->value = pop(); pc++; } else if (cmdTok == LOAD) { // LOAD <id> // load value for id from symTable onto stack if ((si = lookupID(ml.arg)) == NULL) { printf("%s) Error: load cannot find %s\n", currInst, ml.arg); exit(1); push(si->value); : continued

65 else if (cmdTok == PUSH) { // PUSH <id> // push int onto stack push( atoi(ml.arg) ); pc++; } else if (cmdTok == PUSHS) { // PUSHS <string> // push string onto stack pushStr( ml.arg ); : continued

66 else if (cmdTok == LABEL) // LABEL is a no-op pc++; else if (cmdTok == JMPZ) { // JMPZ <label> // jump if popped value is 0 if (pop() == 0) // make the jump pc = labelLocs[ atoi(ml.arg) ]; else } else if (cmdTok == JMP) // JMP <LABEL> // jump to label location : } // end of processCmd()

67 8.1. Execution Example Execute the instructions for whileTest.txt. The code and labels are loaded into code[] and labelLocs[]: "0" "5" "0" PUSH STORE PUSH STORE LABEL . . . code[] "sum" "x" 1 2 3 4 labelLocs[] . . . 4 18 1 2 3 continued

68 whileTest.txt and Code whileTest.txt continued sum = 0; x = 5;
PUSH 0 STORE sum PUSH 5 STORE x LABEL 0 LOAD x GT JMPZ 1 LOAD sum ADD PUSH 1 MINUS JMP 0 LABEL 1 PUSHS "sum = " PRINT STOP whileTest.txt sum = 0; x = 5; while (x > 0) { sum = sum + x; x = x - 1; } print "sum = " sum; continued

69 The code is executed in execCode() using the pc, symbol table, and stack.
. . . symbol table program counter, pc


Download ppt "Compiler Structures 11. IC Generation: Control Structures Objectives"

Similar presentations


Ads by Google