static void swap() { int left_var = variable(), right_var = variable(); int reg_one = next_register(), reg_two = next_register(); CodeGen(LOAD, reg_one, left_var, EMPTY_FIELD); CodeGen(LOAD, reg_two, right_var, EMPTY_FIELD); CodeGen(STORE, left_var, reg_two, EMPTY_FIELD); CodeGen(STORE, right_var, reg_one, EMPTY_FIELD); }
static int expr() { int reg, left_reg, right_reg; switch (token) { case '+': next_token(); left_reg = expr(); right_reg = expr(); reg = next_register(); CodeGen(ADD, reg, left_reg, right_reg); return reg; case '*': next_token(); left_reg = expr(); right_reg = expr(); reg = next_register(); CodeGen(MUL, reg, left_reg, right_reg); return reg; case '-': next_token(); left_reg = expr(); right_reg = expr(); reg = next_register(); CodeGen(SUB, reg, left_reg, right_reg); return reg; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return digit(); case 'a': case 'b': case 'c': case 'd': case 'e': return variable(); default: ERROR("Symbol %c unknown\n", token); exit(EXIT_FAILURE); } }
int main(int argc, char *argv[]) { const char *outfilename = "tinyL.out"; char *input; FILE *infile; printf("------------------------------------------------\n"); printf(" Compiler for tinyL\n Fall 2015\n"); printf("------------------------------------------------\n"); if (argc != 2) { ERROR("Use of command:\n compile <tinyL file>\n"); exit(EXIT_FAILURE); } infile = fopen(argv[1], "r"); if (!infile) { ERROR("Cannot open input file \"%s\"\n", argv[1]); exit(EXIT_FAILURE); } outfile = fopen(outfilename, "w"); if (!outfile) { ERROR("Cannot open output file \"%s\"\n", outfilename); exit(EXIT_FAILURE); } input = read_input(infile); buffer = input; CodeGen(LOADI, 1024, 0, EMPTY_FIELD); /* set base register to 1024 */ program(); printf("\nCode written to file \"%s\".\n\n", outfilename); free(input); fclose(infile); fclose(outfile); return EXIT_SUCCESS; }
static void read() { next_token(); if (!is_identifier(token)) { ERROR("Expected identifier\n"); exit(EXIT_FAILURE); } CodeGen(READ, token, EMPTY_FIELD, EMPTY_FIELD); next_token(); }
static void assign() { int var = variable(); if (token == '=') { next_token(); int reg = expr(); CodeGen(STORE, var, reg, EMPTY_FIELD); } else { ERROR("Syntax Error: In assignment, expected '='.\n"); } }
static void print() { switch (token) { case '!': next_token(); CodeGen(WRITE, token, EMPTY_FIELD, EMPTY_FIELD); next_token(); return ; } }
static void assign() { char id; int right_reg; id = token; next_token(); next_token(); right_reg = expr(); CodeGen(STORE, id, right_reg, EMPTY_FIELD); return; }
static void read() { switch (token) { case '?': next_token(); CodeGen(READ, token, EMPTY_FIELD, EMPTY_FIELD); next_token(); return; } }
static int variable() /* only called for R-values */ { int reg; if(!is_identifier(token)){ ERROR("Expected identifier\n"); exit(EXIT_FAILURE); } reg = next_register(); CodeGen(LOAD, reg, token, EMPTY_FIELD); next_token(); return reg; }
static int variable() { int reg; if (!is_identifier(token)) { ERROR("Expected identifier\n"); exit(EXIT_FAILURE); } reg = next_register(); CodeGen(LOADAI, 0, (token-'a')*4, reg); /* token - 'a' is offset of varible, *4 for byte address */ next_token(); return reg; }
static int digit() { int reg; if (!is_digit(token)) { ERROR("Expected digit\n"); exit(EXIT_FAILURE); } reg = next_register(); CodeGen(LOADI, to_digit(token), reg, EMPTY_FIELD); next_token(); return reg; }
static void print() { next_token(); if(is_identifier(token)){ char variable = token; CodeGen(OUTPUTAI, variable,EMPTY_FIELD,EMPTY_FIELD); next_token(); }else { ERROR("Expected a variable"); exit(EXIT_FAILURE); } /* YOUR CODE GOES HERE */ }
static void print() /* variables are handled explicitly without recursive call */ { if (token != '!') { ERROR("Expected print statement\n"); exit(EXIT_FAILURE); } next_token(); if (!is_identifier(token)) { ERROR("Expected identifier\n"); exit(EXIT_FAILURE); } CodeGen(WRITE, token, EMPTY_FIELD, EMPTY_FIELD); next_token(); }
static void print() { if(token != '!'){ ERROR("Expected '!', got %c\n", token); exit(EXIT_FAILURE); } next_token(); if(!is_identifier(token)){ ERROR("Expected identifier, got %c\n", token); exit(EXIT_FAILURE); } int offset = (token-'a')*4; next_token(); CodeGen(OUTPUTAI, 0, offset, EMPTY_FIELD); }
static void assign() { int reg; if(!is_identifier(token)){ ERROR("Identifier expected, got %c\n", token); exit(EXIT_FAILURE); } int offset = (token-'a')*4; next_token(); if(token != '='){ ERROR("Expected '=', got %c\n", token); exit(EXIT_FAILURE); } next_token(); reg = expr(); CodeGen(STOREAI, reg, 0, offset); }
static void assign() { char ident; int reg; if (!is_identifier(token)) { ERROR("Expected identifier\n"); exit(EXIT_FAILURE); } ident = token; next_token(); if (token != '=') { ERROR("Expected equal sign for assignment statement\n"); exit(EXIT_FAILURE); }; next_token(); reg = expr(); CodeGen(STORE, ident, reg, EMPTY_FIELD); }
static void assign() { char variable = token; next_token(); if(token == '=') { next_token(); int x = expr(); CodeGen(STOREAI, variable, x, EMPTY_FIELD); next_token(); }else{ ERROR("Expected '=' "); exit(EXIT_FAILURE); } /* YOUR CODE GOES HERE */ }
int CodeGen(NODPTR ptr) { int t1, t2, t; switch(ptr->NodeType) { case CONST: t = getFreeReg(); fprintf(fp, "MOV R%d %d\n", t, ptr->value); return t; break; case VARIABLE: t = getFreeReg(); fprintf(fp, "MOV R%d [%d]\n", t, ptr->stptr->binding); return t; break; case RD: t = getFreeReg(); fprintf(fp,"IN R%d\n", t); fprintf(fp, "MOV [%d] R%d\n", ptr->Lptr->stptr->binding, t); reg[t] = 0; return 0; break; //Recursive cases. case WE: t2 = CodeGen(ptr->Lptr); t1 = getFreeReg(); fprintf(fp, "MOV R%d R%d \n", t1, t2); fprintf(fp,"OUT R%d\n", t1); reg[t1] = 0; reg[t2] = 0; return 0; break; case PLUS: t1 = CodeGen(ptr->Rptr); t2 = CodeGen(ptr->Lptr); fprintf(fp, "ADD R%d R%d\n", t2, t1); reg[t1] = 0; return t2; break; case MINUS: t1 = CodeGen(ptr->Rptr); t2 = CodeGen(ptr->Lptr); fprintf(fp, "SUB R%d R%d\n", t2, t1); reg[t1] = 0; return t2; break; case MUL: t1 = CodeGen(ptr->Rptr); t2 = CodeGen(ptr->Lptr); fprintf(fp, "MUL R%d R%d\n", t2, t1); reg[t1] = 0; return t2; break; case DIV: t1 = CodeGen(ptr->Rptr); t2 = CodeGen(ptr->Lptr); fprintf(fp, "DIV R%d R%d\n", t2, t1); reg[t1] = 0; return t2; break; case SEQ: CodeGen(ptr->Lptr); if(ptr->Rptr) CodeGen(ptr->Rptr); return 0; break; case EQUAL: t1 = CodeGen(ptr->Rptr); fprintf(fp, "MOV [%d] R%d\n", ptr->Lptr->stptr->binding, t1); return 0; break; } }
int CodeGen(tnode* t) { int r,r1,r2; int value; int loc,l1,l2; //r is the root of AST //returntype of CodeGen is int that is it returns the register Number switch(t->NODETYPE) { case NUM: value=t->val; r=getReg(); fprintf(fp,"MOV R%d, %d\n",r,value); return r; break; case ID: loc=t->var-'a'; r=getReg(); fprintf(fp, "MOV R%d, [%d]\n",r,loc); return r; break; case PLUS: r1=CodeGen(t->left); r2=CodeGen(t->right); fprintf(fp, "ADD R%d, R%d\n",r1,r2); freeReg(); return r1; break; case MINUS: r1=CodeGen(t->left); r2=CodeGen(t->right); fprintf(fp, "SUB R%d, R%d\n",r1,r2); freeReg(); return r1; break; case MUL: r1=CodeGen(t->left); r2=CodeGen(t->right); fprintf(fp, "MUL R%d, R%d\n",r1,r2); freeReg(); return r1; break; case DIV: r1=CodeGen(t->left); r2=CodeGen(t->right); fprintf(fp, "DIV R%d, R%d\n",r1,r2); freeReg(); return r1; break; case MOD: r1=CodeGen(t->left); r2=CodeGen(t->right); fprintf(fp, "MOD R%d, R%d\n",r1,r2); freeReg(); return r1; break; case LT: r1=CodeGen(t->left); r2=CodeGen(t->right); fprintf(fp, "LT R%d, R%d\n",r1,r2); freeReg(); return r1; break; case GT: r1=CodeGen(t->left); r2=CodeGen(t->right); fprintf(fp, "GT R%d, R%d\n",r1,r2); freeReg(); return r1; break; case EQ: r1=CodeGen(t->left); r2=CodeGen(t->right); fprintf(fp, "EQ R%d, R%d\n",r1,r2); freeReg(); return r1; break; case EQUALS: r1=getBinding(t->left); r2=CodeGen(t->right); fprintf(fp, "MOV [R%d], R%d\n",r1,r2); freeReg(); freeReg(); return 0; break; case READ: r=getBinding(t->left); r1=getReg(); fprintf(fp, "IN R%d\n",r1); fprintf(fp, "MOV [R%d], R%d\n",r,r1); freeReg(); freeReg(); return 0; break; case WRITE: r=CodeGen(t->left); fprintf(fp, "OUT R%d\n",r); freeReg(); return 0; break; case IF: l1=getLabel(); r=CodeGen(t->left); r1=getReg(); fprintf(fp, "MOV R%d, 0\n",r1); fprintf(fp, "NE R%d, R%d\n",r,r1); fprintf(fp, "JZ R%d, L%d\n",r,l1); freeReg(); freeReg(); CodeGen(t->right); fprintf(fp, "L%d:\n",l1); return 0; break; case WHILE: { l1=getLabel(); l2=getLabel(); fprintf(fp, "L%d:\n",l1); r=CodeGen(t->left); r1=getReg(); fprintf(fp, "MOV R%d, 0\n",r1); fprintf(fp, "NE R%d, R%d\n",r,r1); fprintf(fp, "JZ R%d, L%d\n",r,l2); freeReg(); freeReg(); CodeGen(t->right); fprintf(fp, "JMP L%d\n",l1); fprintf(fp, "L%d:\n",l2); return 0; } break; case CONNECT: CodeGen(t->left); CodeGen(t->right); return 0; break; } }
int CodeGen(NODPTR ptr) { int t1, t2, t, b; switch(ptr->NodeType) { case CONST: t = regcount++; fprintf(Fp, "MOV R%d %d\t//\tMoving constant to a register.\n", t, ptr->value); return t; break; case TRUE: t = regcount++; fprintf(Fp, "MOV R%d %d\t//\tMoving true(1) to a register.\n", t, ptr->value); return t; break; case FALSE: t = regcount++; fprintf(Fp, "MOV R%d %d\t//\tMoving false(0) to a register.\n", t, ptr->value); return t; break; case VARIABLE: t1 = regcount++; if(ptr->Lstptr) { b = ptr->Lstptr->binding; t2 = regcount++; // Need another register for storing base pointer. fprintf(Fp, "MOV R%d BP\t//\tMoving base pointer to a register.\n", t2); fprintf(Fp, "MOV R%d %d\t//\tStoring the relative address of the variable.\n", t1, b); fprintf(Fp, "ADD R%d R%d\t//\tAdding it with base pointer for absol. address\n", t1, t2); fprintf(Fp, "MOV R%d [R%d]\t//\tMoving variable contents to register.\n", t1, t1); regcount--; } else { b = ptr->Gstptr->binding; fprintf(Fp, "MOV R%d %d\t//\tThe variable is global,so absolute address is used", t1, b); fprintf(Fp, "MOV R%d [R%d]\t//\tMoving variable contents to register.\n", t1, t1); } return t1; break; //Recursive cases. case ARRAY: t1 = CodeGen(ptr->Rptr); t = regcount++; b = ptr->Lptr->Gstptr->binding; fprintf(Fp, "MOV R%d %d\t//\tMoving binding field.\n", t, b); fprintf(Fp, "ADD R%d R%d\t//\tAdding binding with the offset.\n", t1, t); if(ArrFlag == 1) fprintf(Fp, "MOV R%d [R%d]\t//\t...and loading it onto a register.\n", t1,t1); regcount--; /*If ArrayFlag == 1 t1 will contain the value otherwise t1 will contain the absolute address */ return t1; break; case RD: t = regcount++; fprintf(Fp,"IN R%d\t\t//\tReading from input.\n", t); if(ptr->Lptr->Lstptr) b = ptr->Lptr->Lstptr->binding; else b = ptr->Lptr->Gstptr->binding; if(ptr->Lptr->NodeType == VARIABLE) fprintf(Fp, "MOV [%d] R%d\t//\tMoving the read content to variable.\n", b, t); else { // Done inorder to generate code to obtain array binding field. ArrFlag = 0; t1 = CodeGen(ptr->Lptr); ArrFlag = 1; fprintf(Fp, "MOV [R%d] R%d\t//\tMoving the read content to an array.\n", t1, t); regcount--; } regcount--; break; case WE: t = CodeGen(ptr->Lptr); fprintf(Fp,"OUT R%d\t\t//\tOutput the register content\n", t); regcount--; return 0; break; case PLUS: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "ADD R%d R%d\t//\tPLUS\n", t1, t2); regcount--; return t1; break; case MINUS: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "SUB R%d R%d\t//\tMINUS\n", t1, t2); regcount--; return t1; break; case MUL: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "MUL R%d R%d\t//\tMUL\n", t1, t2); regcount--; return t1; break; case DIV: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "DIV R%d R%d\t//\tDIV\n", t1, t2); regcount--; return t1; break; case SEQ: CodeGen(ptr->Lptr); if(ptr->Rptr) CodeGen(ptr->Rptr); return 0; break; case FUNC: fprintf(Fp, "PUSH R0\n"); // 1. Push dummy value for storing return value. for(t = 0; t < 8; t++) fprintf(Fp, "PUSH R%d\n", t); // 2.Pushing machine status. fprintf(Fp, "PUSH BP\n"); // 3. Storing caller's BP NODPTR tmp = ptr->list; while(tmp) { t = CodeGen(tmp); // 4.Pushing the parameters. fprintf(Fp, "PUSH R%d\n", t); tmp = tmp->next; } fprintf("CALL F%d\n", ptr->Lptr->Gstptr->binding); // 5.Calling the function. // After function call. tmp = ptr->list; while(tmp) // 1. poping parameters { fprintf(Fp, "POP R0\n"); tmp = tmp->next; } fprintf(Fp, "POP BP\n"); //2 .Restoring BP for(t = 7; t >= 0; t--) fprintf(Fp, "POP R%d\n", t); // 2.Restoring machine status. t1 = regcount++; fprintf("MOV R%d [SP]\n", t1);//3. Copying back the return value. return t1; break; case EQUAL: t1 = CodeGen(ptr->Rptr); if(ptr->Lptr->Lstptr) b = ptr->Lptr->Lstptr->binding; else b = ptr->Lptr->Gstptr->binding; if(ptr->Lptr->NodeType == VARIABLE) fprintf(Fp, "MOV [%d] R%d\t//\tAssigning register contents to variable\n", b, t1); else { // Done inorder to generate code to obtain array binding field. ArrFlag = 0; t2 = CodeGen(ptr->Lptr); ArrFlag = 1; fprintf(Fp, "MOV [R%d] R%d\t//\tAssigning register contents to array\n", t2, t1); regcount--; } regcount--; return 0; break; case GT: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "GT R%d R%d\t//\tGreater than.\n", t1, t2); regcount--; return t1; break; case LT: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "LT R%d R%d\t//\tLesser than.\n", t1, t2); regcount--; return t1; break; case GTE: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "GE R%d R%d\t//\tGreater than or equal.\n", t1, t2); regcount--; return t1; break; case LTE: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "LE R%d R%d\t//\tLesser than or equal.\n", t1, t2); regcount--; return t1; break; case ISEQUAL: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "EQ R%d R%d\t//\tIs equal.\n", t1, t2); regcount--; return t1; break; case NE: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "NE R%d R%d\t//\tIs not equal.\n", t1, t2); regcount--; return t1; break; case AND: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "MUL R%d R%d\t//\tAND operation.\n", t1, t2); regcount--; return t1; break; case OR: t1 = CodeGen(ptr->Lptr); t2 = CodeGen(ptr->Rptr); fprintf(Fp, "ADD R%d R%d\t//\tOR operation.\n", t1, t2); fprintf(Fp, "MOV R%d %d\t//\tOR operation.\n", t2, 0); fprintf(Fp, "NE R%d R%d\t//\tOR operation.\n", t1, t2); regcount--; return t1; break; case NOT: t = regcount++; t1 = CodeGen(ptr->Lptr); fprintf(Fp, "MOV R%d %d\t//\tNOT operation.\n", t, 1); fprintf(Fp, "SUB R%d R%d\t//\tNOT operation.\n", t, t1); regcount--; return t; break; case IF_THEN: t1 = Branching_Label++; t = CodeGen(ptr->Lptr); fprintf(Fp, "JZ R%d L%d\t// If then\n", t, t1); regcount--; // Freeing the register. CodeGen(ptr->Rptr); fprintf(Fp, "L%d:\t\t// Endif\n",t1); return 0; break; case IF_THEN_ELSE: t = CodeGen(ptr->Lptr); // Two labels are needed for if else t1 = Branching_Label++; t2 = Branching_Label++; fprintf(Fp, "JZ R%d L%d\t// If then else\n", t, t1); regcount--; // Freeing the register. CodeGen(ptr->Mptr); fprintf(Fp, "JMP L%d\n", t2); fprintf(Fp, "L%d:\t\t// ...else\n", t1); CodeGen(ptr->Rptr); fprintf(Fp, "L%d:\t\t// End if else\n",t2); return 0; break; case DO_WHILE: // Two labels are needed for while do t1 = Branching_Label++; t2 = Branching_Label++; fprintf(Fp, "L%d:\n",t1); t = CodeGen(ptr->Lptr); fprintf(Fp, "JZ R%d L%d\t// While do\n", t, t2); regcount--; // Freeing the register. CodeGen(ptr->Rptr); fprintf(Fp, "JMP L%d\t\t// Endwhile\n", t1); fprintf(Fp, "L%d:\n",t2); return 0; break; } }
static void print() { int var = variable(); CodeGen(WRITE, var, EMPTY_FIELD, EMPTY_FIELD); }
static void read() { int var = variable(); CodeGen(READ, var, EMPTY_FIELD, EMPTY_FIELD); }