void emitEnd() { TreeNode *temp = (TreeNode*)tab->lookup((char*)"main"); //if(temp == NULL) //{ // printf("ERROR(LINKER): Procedure main is not defined\n"); //} if(temp != NULL) { backPatchJumpToHere(0, (char*)"Jump to init [backpatch]"); emitComment((char*)"BEGIN Init"); emitRM((char*)"LD", GP, 0, GP, (char*)"Set the global pointer"); emitComment((char*)"BEGIN init of globals"); //start int gloads = goff2; SymTabEntry* intable = (SymTabEntry*)tab->firstSymTabEntry(); intable = (SymTabEntry*)tab->nextSymTabEntry(intable); //skip null //intable = (SymTabEntry*)tab->nextSymTabEntry(intable); TreeNode* tmp = (TreeNode*)tab->lookup(intable->name); while(tmp != NULL) { if(tmp->kind.decl == varK) { if(!tmp->isArray) { params = 1; codeGen(tmp); } else { emitRM2((char*)"LDC", AC, tmp->size - 1, AC3, (char*)"load size of array", tmp->attr.name); emitRM2((char*)"ST", AC, tmp->location + 1, 0, (char*)"save size of array", tmp->attr.name); } } tmp=tmp->sibling; } emitComment((char*)"END init of globals"); emitRM((char*)"LDA", FP, goff, GP, (char*)"set first frame at end of globals"); emitRM((char*)"ST", FP, 0, FP, (char*)"store old fp (point to self)"); emitRM((char*)"LDA", AC, 1, PC, (char*)"Return address in ac"); emitRM((char*)"LDA", PC, temp->location - emitSkip(0) - 1, PC, (char*)"Jump to main"); emitRO((char*)"HALT", 0, 0, 0, (char*)"DONE!"); emitComment((char*)"END Init"); } }
/* Procedure codeGen generates code to a code * file by traversal of the syntax tree. The * second parameter (codefile) is the file name * of the code file, and is used to print the * file name as a comment in the code file */ void codeGen(TreeNode * syntaxTree, char * codefile) { char * s = (char *) malloc(strlen(codefile)+7); strcpy(s,"File: "); strcat(s,codefile); emitComment("TINY Compilation to TM Code"); emitComment(s); /* generate standard prelude */ emitComment("Standard prelude:"); emitRM("LD",mp,0,ac,"load maxaddress from location 0"); emitRM("ST",ac,0,ac,"clear location 0"); emitComment("End of standard prelude."); /* generate code for TINY program */ cGen(syntaxTree); /* finish */ emitComment("End of execution."); emitRO("HALT",0,0,0,""); }
/* Procedure genExp generates code at an expression node */ static void genExp( TreeNode * tree) { int loc; TreeNode * p1, * p2; switch (tree->kind.exp) { case ConstK : if (TraceCode) emitComment("-> Const") ; /* gen code to load integer constant using LDC */ emitRM("LDC",ac,tree->attr.val,0,"load const"); if (TraceCode) emitComment("<- Const") ; break; /* ConstK */ case IdK : if (TraceCode) emitComment("-> Id") ; loc = st_lookup(tree->attr.name); emitRM("LD",ac,loc,gp,"load id value"); if (TraceCode) emitComment("<- Id") ; break; /* IdK */ case OpK : if (TraceCode) emitComment("-> Op") ; p1 = tree->child[0]; p2 = tree->child[1]; /* gen code for ac = left arg */ cGen(p1); /* gen code to push left operand */ emitRM("ST",ac,tmpOffset--,mp,"op: push left"); /* gen code for ac = right operand */ cGen(p2); /* now load left operand */ emitRM("LD",ac1,++tmpOffset,mp,"op: load left"); switch (tree->attr.op) { case PLUS : emitRO("ADD",ac,ac1,ac,"op +"); break; case MINUS : emitRO("SUB",ac,ac1,ac,"op -"); break; case TIMES : emitRO("MUL",ac,ac1,ac,"op *"); break; case OVER : emitRO("DIV",ac,ac1,ac,"op /"); break; case LT : emitRO("SUB",ac,ac1,ac,"op <") ; emitRM("JLT",ac,2,pc,"br if true") ; emitRM("LDC",ac,0,ac,"false case") ; emitRM("LDA",pc,1,pc,"unconditional jmp") ; emitRM("LDC",ac,1,ac,"true case") ; break; case EQ : emitRO("SUB",ac,ac1,ac,"op ==") ; emitRM("JEQ",ac,2,pc,"br if true"); emitRM("LDC",ac,0,ac,"false case") ; emitRM("LDA",pc,1,pc,"unconditional jmp") ; emitRM("LDC",ac,1,ac,"true case") ; break; default: emitComment("BUG: Unknown operator"); break; } /* case op */ if (TraceCode) emitComment("<- Op") ; break; /* OpK */ default: break; } } /* genExp */
/* Procedure genStmt generates code at a statement node */ static void genStmt( TreeNode * tree) { TreeNode * p1, * p2, * p3; int savedLoc1,savedLoc2,currentLoc; int loc; switch (tree->kind.stmt) { case IfK : if (TraceCode) emitComment("-> if") ; p1 = tree->child[0] ; p2 = tree->child[1] ; p3 = tree->child[2] ; /* generate code for test expression */ cGen(p1); savedLoc1 = emitSkip(1) ; emitComment("if: jump to else belongs here"); /* recurse on then part */ cGen(p2); savedLoc2 = emitSkip(1) ; emitComment("if: jump to end belongs here"); currentLoc = emitSkip(0) ; emitBackup(savedLoc1) ; emitRM_Abs("JEQ",ac,currentLoc,"if: jmp to else"); emitRestore() ; /* recurse on else part */ cGen(p3); currentLoc = emitSkip(0) ; emitBackup(savedLoc2) ; emitRM_Abs("LDA",pc,currentLoc,"jmp to end") ; emitRestore() ; if (TraceCode) emitComment("<- if") ; break; /* if_k */ case RepeatK: if (TraceCode) emitComment("-> repeat") ; p1 = tree->child[0] ; p2 = tree->child[1] ; savedLoc1 = emitSkip(0); emitComment("repeat: jump after body comes back here"); /* generate code for body */ cGen(p1); /* generate code for test */ cGen(p2); emitRM_Abs("JEQ",ac,savedLoc1,"repeat: jmp back to body"); if (TraceCode) emitComment("<- repeat") ; break; /* repeat */ case AssignK: if (TraceCode) emitComment("-> assign") ; /* generate code for rhs */ cGen(tree->child[0]); /* now store value */ loc = st_lookup(tree->attr.name); emitRM("ST",ac,loc,gp,"assign: store value"); if (TraceCode) emitComment("<- assign") ; break; /* assign_k */ case ReadK: emitRO("IN",ac,0,0,"read integer value"); loc = st_lookup(tree->attr.name); emitRM("ST",ac,loc,gp,"read: store value"); break; case WriteK: /* generate code for expression to write */ cGen(tree->child[0]); /* now output it */ emitRO("OUT",ac,0,0,"write ac"); break; default: break; } } /* genStmt */
void montador(FILE *out, tipoInstr tipo, int valor, int reg){ static int memOffset = 0; switch(tipo){ case INSTR_INICIO: emitComment(out, "INICIO" ); emitRM(out, "LD",mp,0,ac,"load maxaddress from location 0"); emitRM(out, "ST",ac,0,ac,"clear location 0"); break; case INSTR_FIM: emitComment(out, "FIM" ); emitRO(out, "HALT",0,0,0,""); break; case INSTR_STORE_MEMORIA: emitComment(out, "STORE" ); emitRM(out, "ST",reg,valor,gp,"carrega endereco de memoria valor de gp em reg"); break; case INSTR_STORE_MEMORIA_TEMP: emitComment(out, "STORE TEMPORARIO" ); emitRM(out, "ST",reg,memOffset,mp,"carrega endereco de memoria valor de mp em reg"); memOffset--; break; case INSTR_LOAD_MEMORIA: emitComment(out, "LOAD" ); emitRM(out, "LD",reg,valor,gp,"carrega para reg o que tem no endereco de memoria valor que esta no gp"); break; case INSTR_LOAD_CTE: emitComment(out, "LOAD CONSTANTE" ); emitRM(out, "LDC",reg,valor,0,"carrega NUM em reg"); break; case INSTR_LOAD_MEMORIA_TEMP: emitComment(out, "LOAD O QUE ESTA NO TOPO DA PILHA DOS TEMPORARIOS" ); memOffset++; emitRM(out, "LD",reg,memOffset,mp,"carrega para reg o que tem no endereco de memoria valor que esta no mp"); break; case INSTR_WRITE: emitComment(out, "WRITE"); emitRO(out, "OUT",ac,0,0,"write ac"); break; case INSTR_TEMP_ACS: emitComment(out, "PASSA VALOR PARA AC0 E AC1"); memOffset++; emitRM(out, "LD",ac,memOffset,mp,"carrega em ac o que tem no endereco de memoria valor de mp"); memOffset++; emitRM(out, "LD",ac1,memOffset,mp,"carrega em ac1 o que tem no endereco de memoria valor de mp"); break; case INSTR_READ: emitComment(out, "READ"); emitRO(out, "IN", reg, 0, 0, "le valor para o registrador"); emitRM(out, "ST", reg, valor, gp, "armazena valor de reg para endereco de memoria valor de gp"); break; case INSTR_ADD: emitComment(out, "ADICAO"); emitRO(out, "ADD",ac,ac1,ac,"ac = ac1 + ac"); emitRM(out, "ST",ac,memOffset,mp,"armazena valor da soma na memoria mp"); memOffset--; break; case INSTR_SUB: emitComment(out, "SUBTRACAO"); emitRO(out, "SUB",ac,ac1,ac,"ac = ac1 - ac"); emitRM(out, "ST",ac,memOffset,mp,"armazena valor da subtracao na memoria mp"); memOffset--; break; case INSTR_MULT: emitComment(out, "MULTIPLICACAO"); emitRO(out, "MUL",ac,ac1,ac,"ac = ac1 * ac"); emitRM(out, "ST",ac,memOffset,mp,"armazena valor da multiplicacao na memoria mp"); memOffset--; break; case INSTR_DIV: emitComment(out, "DIVISAO"); emitRO(out, "DIV",ac,ac1,ac,"ac = ac1 / ac"); emitRM(out, "ST",ac,memOffset,mp,"armazena valor da divisao na memoria mp"); memOffset--; break; case INSTR_REL_MENOR: emitComment(out, "RELACAO: MENOR"); emitRO(out, "SUB",ac,ac1,ac,""); emitRM(out, "JLT",ac,4,pc,"a - b < 0 ? Se sim, pule para armazenar true"); break; case INSTR_REL_MENOR_IGUAL: emitComment(out, "RELACAO: MENOR IGUAL"); emitRO(out, "SUB",ac,ac1,ac,"op - entre ac e ac1"); emitRM(out, "JLE",ac,4,pc,"a - b <= 0 ? Se sim, pule para armazenar true"); break; case INSTR_REL_MAIOR: emitComment(out, "RELACAO: MAIOR"); emitRO(out, "SUB",ac,ac1,ac,""); emitRM(out, "JGT",ac,4,pc,"a - b > 0 ? Se sim, pule para armazenar true"); break; case INSTR_REL_MAIOR_IGUAL: emitComment(out, "RELACAO: MAIOR IGUAL"); emitRO(out, "SUB", ac, ac1, ac, "op - entre ac e ac1"); emitRM(out, "JGE", ac, 4, pc, "a-b>=0 ? Se sim, pula para armazenar true"); break; case INSTR_REL_IGUAL: emitComment(out, "RELACAO: IGUAL"); emitRO(out, "SUB",ac,ac1,ac,""); emitRM(out, "JEQ",ac,4,pc,"a - b == 0 ? Se sim, pule para armazenar true"); break; case INSTR_REL_DIF: emitComment(out, "RELACAO: DIFERENTE"); emitRO(out, "SUB",ac,ac1,ac,"op - entre ac e ac1"); emitRM(out, "JNE",ac,4,pc,"a - b != 0 ? Se sim, pule para armazenar true"); break; case INSTR_REL_AND: emitComment(out, "OPERACAO LOGICA: AND"); emitRM(out, "JEQ", ac, 3, pc, "ac == 0? Se sim, avalia como falso"); emitRM(out, "JEQ", ac1, 2, pc, "ac1 == 0? Se sim, avalia como falso"); emitRM(out, "LDC",ac,0,0,""); emitRM(out, "JEQ",ac,4,pc,"Se nenhum dos dois é falso, avalia como verdadeiro"); break; case INSTR_REL_OR: emitComment(out, "OPERACAO LOGICA: OR"); emitRM(out, "JNE", ac, 5, pc, "ac != 0? Se sim, avalia como true"); emitRM(out, "JNE", ac1, 4, pc, "ac1 != 0? Se sim, avalia como true"); emitComment(out, "se nenhum dos dois e verdadeiro, avalia como falso, nao pula"); break; case INSTR_STORE_REL: emitComment(out, "STORE RESULTADO DA RELACAO"); emitRM(out, "LDC",ac,0,0,"false"); emitRM(out, "ST",ac,memOffset,mp,"armazena false no topo"); emitRM(out, "LDC",ac,0,0,""); emitRM(out, "JEQ",ac,2,pc,"Pula para o if"); emitRM(out, "LDC",ac,1,0,"true"); emitRM(out, "ST",ac,memOffset,mp,"armazena true no topo"); memOffset--; break; case INSTR_JUMP_REL_FALSE: emitComment(out, "JUMP se o valor da relacao for false"); memOffset++; emitRM(out, "LD",ac,memOffset,mp,""); emitRM(out, "JEQ",ac,valor,pc,"Pula para o else"); break; case INSTR_JUMP: emitComment(out, "JUMP"); emitRM(out, "LDC",ac,0,0,""); emitRM(out, "JEQ",ac,valor,pc,"Pula incondicionalmente para pc+valor"); break; default: emitComment(out, "ERRO" ); break; } }
void codeGen(TreeNode* currnode) { bool texp = false; while(currnode != NULL) { if(currnode->nodekind==DeclK) { switch(currnode->kind.decl) { case varK: codeGen(currnode->child[0]); t2 = (TreeNode*)tab->lookup(currnode->attr.name); if(t2 == NULL && currnode->isArray) { emitRM2((char*)"LDC", AC, currnode->size - 1, AC3, (char*)"load size of array", currnode->attr.name); emitRM2((char*)"ST", AC, currnode->location + 1, FP, (char*)"save size of array", currnode->attr.name); } if(t2 == NULL && currnode->child[0] != NULL) emitRM2((char*)"ST", AC, currnode->location, FP, (char*)"Store variable", currnode->attr.name); if(t2 != NULL && currnode->child[0] != NULL) codeGen(currnode->child[0]); break; case paramK: break; case funcK: //printf("test\n"); t1 = (TreeNode*)tab->lookup(currnode->attr.name); t1->location = emitSkip(0); currnode->location = t1->location; toff = 0; framesize = currnode->size; //toff = 0 - t1->size; emitComment2((char*)"BEGIN function", currnode->attr.name); if(currnode->isPre) emitRM((char*)"ST", AC, -1, FP, (char*)"Store return address"); else emitRM((char*)"ST", AC, -1, FP, (char*)"Store return address."); codeGen(currnode->child[0]); codeGen(currnode->child[1]); if(currnode->isPre) { switch(currnode->pnum) { case 0://input emitRO((char*)"IN", RT, RT, RT, (char*)"Grab int input"); emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address"); emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp"); emitRM((char*)"LDA", PC, 0, AC, (char*)"Return"); break; case 1://output emitRM((char*)"LD", AC, -2, FP, (char*)"Load parameter"); emitRO((char*)"OUT", AC, AC, AC, (char*)"Output integer"); emitRM((char*)"LDC", RT, 0, AC3, (char*)"Set return to 0"); emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address"); emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp"); emitRM((char*)"LDA", PC, 0, AC, (char*)"Return"); break; case 2://inputb emitRO((char*)"INB", RT, RT, RT, (char*)"Grab bool input"); emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address"); emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp"); emitRM((char*)"LDA", PC, 0, AC, (char*)"Return"); break; case 3://ouptutb emitRM((char*)"LD", AC, -2, FP, (char*)"Load parameter"); emitRO((char*)"OUTB", AC, AC, AC, (char*)"Output bool"); emitRM((char*)"LDC", RT, 0, AC3, (char*)"Set return to 0"); emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address"); emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp"); emitRM((char*)"LDA", PC, 0, AC, (char*)"Return"); break; case 4://inputc emitRO((char*)"INC", RT, RT, RT, (char*)"Grab char input"); emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address"); emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp"); emitRM((char*)"LDA", PC, 0, AC, (char*)"Return"); break; case 5://outputc emitRM((char*)"LD", AC, -2, FP, (char*)"Load parameter"); emitRO((char*)"OUTC", AC, AC, AC, (char*)"Output char"); emitRM((char*)"LDC", RT, 0, AC3, (char*)"Set return to 0"); emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address"); emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp"); emitRM((char*)"LDA", PC, 0, AC, (char*)"Return"); break; case 6://outnl emitRO((char*)"OUTNL", AC, AC, AC, (char*)"Output a newline"); emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address"); emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp"); emitRM((char*)"LDA", PC, 0, AC, (char*)"Return"); } } if(!currnode->isPre) { emitComment((char*)"Add standard closing in case there is no return statement"); emitRM((char*)"LDC", RT, 0, AC3, (char*)"Set return value to 0"); emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address"); emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp"); emitRM((char*)"LDA", PC, 0, AC, (char*)"Return"); } emitComment2((char*)"END of function", currnode->attr.name); toff = 0; break; } //in_exp = false; } else if(currnode->nodekind==StmtK) switch(currnode->kind.stmt) { case ifK: int breakk; int breakk2; emitComment((char*)"IF"); currloc2 = emitSkip(0); ifexp = true; codeGen(currnode->child[0]); ifexp = false; emitRM((char*)"JGT", AC, 1, PC, (char*)"Jump to then part"); emitComment((char*)"THEN"); skiploc2 = breakk2; breakk2 = emitSkip(1); codeGen(currnode->child[1]); if(currnode->child[2] != NULL) { emitComment((char*)"ELSE"); breakk = emitSkip(1); backPatchJumpToHere(breakk2, (char*)"Jump around the THEN [backpatch]"); codeGen(currnode->child[2]); backPatchJumpToHere(breakk, (char*)"Jump around the ELSE [backpatch]"); } else backPatchJumpToHere(breakloc, (char*)"Jump around the THEN [backpatch]"); emitComment((char*)"ENDIF"); break; case returnK: emitComment((char*)"RETURN"); if (currnode->child[0] != NULL) { codeGen(currnode->child[0]); // generate any return value //t2 = (TreeNode*)tab->lookup(currnode->attr.name); if(currnode->child[0] != NULL) { if(currnode->child[0]->scopeT == local || currnode->child[0]->scopeT == param) offReg = 1; else offReg = 0; } if(currnode->child[0]->isArray) { if(currnode->scopeT == param) emitRM2((char*)"LD", AC1, currnode->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); else emitRM2((char*)"LDA", AC, currnode->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); emitRM2((char*)"SUB", AC, AC1, AC, (char*)"Compute offset for", currnode->attr.name); emitRM2((char*)"LD", AC, 0, AC, (char*)"load the value", currnode->attr.name); } emitRM((char*)"LDA", RT, 0, AC, (char*)"Copy result to rt register"); // save in return register } // emit return sequence emitRM((char*)"LD", AC, OFPOFF, FP, (char*)"Load return address"); emitRM((char*)"LD", FP, RETURN_OFFSET, FP, (char*)"Adjust fp"); emitRM((char*)"LDA", PC, 0, AC, (char*)"Return"); break; case compoundK: emitComment((char*)"BEGIN compound statement"); codeGen(currnode->child[0]); codeGen(currnode->child[1]); emitComment((char*)"END compound statement"); break; case breakK: emitComment((char*)"BREAK"); emitRM((char*)"LDA", PC, breakloc - emitSkip(0) - 1, PC, (char*)"break"); break; case foreachK: break; case whileK: int currloc; int skiploc; emitComment((char*)"WHILE"); currloc = emitSkip(0); // save location to return to codeGen(currnode->child[0]); // generate code for test emitRM((char*)"JGT", AC, 1, PC, (char*)"Jump to while part"); // test and jump emitComment((char*)"DO"); skiploc = breakloc; // save the old break statement return point breakloc = emitSkip(1); // addr of instr that jumps to end of loop // this is also the backpatch point codeGen(currnode->child[1]); // generate body of loop emitRMAbs((char*)"LDA", PC, currloc, (char*)"go to beginning of loop"); // jump to top of loop backPatchJumpToHere(breakloc, (char*)"No more loop [backpatch]"); // backpatch jump to end of loop at breakloc breakloc = skiploc; // restore for break statement emitComment((char*)"ENDWHILE"); break; } else if(currnode->nodekind==ExpK) { int offReg = 1; if(!in_exp) { emitComment((char*)"EXPRESSION STMT"); in_exp = true; } switch(currnode->kind.exp) { codeGen(currnode->child[0]); case opK: texp = inexp; inexp = currnode->expType == Bool; opexp = true; //tempparam = params; //params = 1; codeGen(currnode->child[0]); opexp = false; //params = tempparam; if(currnode->child[1] != NULL) { emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save left side"); if(!currnode->child[1]->isArray) codeGen(currnode->child[1]); else { codeGen(currnode->child[1]->child[0]); t2 = (TreeNode*)tab->lookup(currnode->child[1]->attr.name); if(t2 != NULL) { if(t2->scopeT == local || t2->scopeT == param) offReg = 1; else offReg = 0; } if(currnode->child[1]->scopeT == param) { if(currnode->child[1]->child[0] != NULL) emitRM2((char*)"LD", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[1]->attr.name); else emitRM2((char*)"LD", AC, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[1]->attr.name); } else { if(currnode->child[0] != NULL) { emitRO((char*)"SUB", AC, AC1, AC, (char*)"Computer offset of value"); emitRM((char*)"LD", AC, 0, AC, (char*)"Load the value"); } } } emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Load left into ac1"); } switch(currnode->attr.op) { case ltK: emitRO((char*)"SUB", AC1, AC1, AC, (char*)"Op <"); emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case"); emitRM((char*)"JLT", AC1, 1, PC, (char*)"Jump if true"); emitRM((char*)"LDC", AC, 0, AC3, (char*)"False case"); break; case gtK: emitRO((char*)"SUB", AC1, AC1, AC, (char*)"Op <"); emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case"); emitRM((char*)"JGT", AC1, 1, PC, (char*)"Jump if true"); emitRM((char*)"LDC", AC, 0, AC3, (char*)"False case"); break; case equivK: emitRO((char*)"SUB", AC1, AC1, AC, (char*)"Op =="); emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case"); emitRM((char*)"JEQ", AC1, 1, PC, (char*)"Jump if true"); emitRM((char*)"LDC", AC, 0, AC3, (char*)"False case"); break; case neqK: emitRO((char*)"SUB", AC, AC1, AC, (char*)"Op !="); emitRM((char*)"JEQ", AC, 1, PC, (char*)"Jump if true"); emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case"); break; case modK: emitRO((char*)"DIV", AC2, AC1, AC, (char*)"Op %"); emitRO((char*)"MUL", AC2, AC2, AC, (char*)""); emitRO((char*)"SUB", AC, AC1, AC2, (char*)""); break; case UminusK: emitRM((char*)"LDC", AC1, 0, AC3, (char*)"Load 0"); emitRO((char*)"SUB", AC, AC1, AC, (char*)"Op unary -"); break; case UmultiK: emitRO((char*)"MUL", AC, currnode->size + 1, AC, (char*)"Load array size"); break; case minusK: emitRO((char*)"SUB", AC, AC1, AC, (char*)"Op -"); break; case plusK: emitRO((char*)"ADD", AC, AC1, AC, (char*)"Op +"); break; case multiK: emitRO((char*)"MUL", AC, AC1, AC, (char*)"Op *"); break; case divideK: emitRO((char*)"DIV", AC, AC1, AC, (char*)"Op /"); break; case lteqK: emitRO((char*)"SUB", AC1, AC1, AC, (char*)"Op <="); emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case"); emitRM((char*)"JLE", AC1, 1, PC, (char*)"Jump if true"); emitRM((char*)"LDC", AC, 0, AC3, (char*)"False case"); break; case gteqK: emitRO((char*)"SUB", AC1, AC1, AC, (char*)"Op >="); emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case"); emitRM((char*)"JGE", AC1, 1, PC, (char*)"Jump if true"); emitRM((char*)"LDC", AC, 0, AC3, (char*)"False case"); break; case notK: emitRM((char*)"LDA", AC, 1, AC2, (char*)"Not load address"); emitRO((char*)"SUB", AC, AC1, AC, (char*)"Op Not"); break; case andK: emitRM((char*)"JEQ", AC, 1, PC, (char*)"Op AND"); emitRM((char*)"LDA", AC, 0, AC2, (char*)""); break; case orK: emitRM((char*)"JEQ", AC, 1, PC, (char*)"Op OR"); emitRM((char*)"LDA", AC, 0, AC2, (char*)""); break; } inexp = texp; break; case constK: if(currnode->expType == Int) emitRM((char*)"LDC", AC, currnode->attr.val, AC3, (char*)"Load constant"); if(currnode->expType == Bool) { if(currnode->attr.bval) emitRM((char*)"LDC", AC, 1, AC3, (char*)"Load constant"); else emitRM((char*)"LDC", AC, 0, AC3, (char*)"Load constant"); } if(currnode->expType == Char) emitRM((char*)"LDC",AC, currnode->attr.string[1], AC3, (char*)"Load constant"); break; case idK: codeGen(currnode->child[0]); t2 = (TreeNode*)tab->lookup(currnode->attr.name); if(t2 != NULL) { if(currnode->scopeT == local || currnode->scopeT == param) offReg = 1; else offReg = 0; } if(currnode->isArray) { if((params != 0 && !inexp) || opexp || ifexp) { if(currnode->scopeT == param) { //emitRM2((char*)"LD", AC1, currnode->location, FP, (char*)"Load address of base of array", currnode->attr.name); if(currnode->child[0] != NULL) emitRM2((char*)"LD", AC1, currnode->location, offReg, (char*)"Load address of base of array", currnode->attr.name); else emitRM2((char*)"LD", AC, currnode->location, offReg, (char*)"Load address of base of array", currnode->attr.name); } else { if(currnode->child[0] != NULL) emitRM2((char*)"LDA", AC1, currnode->location, offReg, (char*)"Load address of base of array", currnode->attr.name); else emitRM2((char*)"LDA", AC, currnode->location, offReg, (char*)"Load address of base of array", currnode->attr.name); } if(currnode->child[0] != NULL) { emitRO((char*)"SUB", AC, AC1, AC, (char*)"Compute offset of value"); emitRM((char*)"LD", AC, 0, AC, (char*)"load the value"); } } //in = true; } else if(currnode->scopeT != param && currnode->scopeT != local) emitRM2((char*)"LD", AC, currnode->location, offReg, (char*)"Load variable", currnode->attr.name); else emitRM2((char*)"LD", AC, currnode->location, offReg, (char*)"Load variable", currnode->attr.name); break; case assignK: texp = inexp; inexp = true; switch(currnode->attr.op) { case peqK: if(currnode->child[0]->isArray) { codeGen(currnode->child[0]); emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save index"); } codeGen(currnode->child[1]); t2 = (TreeNode*)tab->lookup(currnode->child[0]->attr.name); if(t2 != NULL) { if(t2->scopeT == local || t2->scopeT == param) offReg = 1; else offReg = 0; } if(currnode->child[1]->isArray) { if(currnode->child[1]->scopeT == param) emitRM2((char*)"LD", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); else emitRM2((char*)"LDA", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); emitRO((char*)"SUB", AC, AC1, AC, (char*)"Compute offset of value"); emitRM((char*)"LD", AC, 0, AC2, (char*)"Load the value"); } if(currnode->child[0]->isArray) { emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Restore index"); if(currnode->child[0]->scopeT == param) emitRM2((char*)"LD", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); else emitRM2((char*)"LDA", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); emitRO((char*)"SUB", AC2, AC2, AC1, (char*)"Compute offset of value"); emitRM2((char*)"LD", AC1, 0, AC2, (char*)"loah lhs variable", currnode->child[0]->attr.name); emitRO((char*)"ADD", AC, AC1, AC, (char*)"op +="); // decrement emitRM2((char*)"ST", AC, 0, AC2, (char*)"Store variable", currnode->child[0]->attr.name); } else { emitRM2((char*)"LD", AC1, currnode->child[0]->location, offReg, (char*)"load lhs variable", currnode->child[0]->attr.name); // load mutable emitRO((char*)"ADD", AC, AC1, AC, (char*)"op +="); // decrement emitRM2((char*)"ST", AC, currnode->child[0]->location, offReg, (char*)"Store variable", currnode->child[0]->attr.name); // store mutable } break; case meqK: if(currnode->child[0]->isArray) { codeGen(currnode->child[0]); emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save index"); } codeGen(currnode->child[1]); t2 = (TreeNode*)tab->lookup(currnode->child[0]->attr.name); if(t2 != NULL) { if(t2->scopeT == local || t2->scopeT == param) offReg = 1; else offReg = 0; } if(currnode->child[1]->isArray) { if(currnode->child[1]->scopeT == param) emitRM2((char*)"LD", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); else emitRM2((char*)"LDA", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); emitRO((char*)"SUB", AC, AC1, AC, (char*)"Compute offset of value"); emitRM((char*)"LD", AC, 0, AC2, (char*)"Load the value"); } if(currnode->child[0]->isArray) { emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Restore index"); if(currnode->child[0]->scopeT == param) emitRM2((char*)"LD", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); else emitRM2((char*)"LDA", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); emitRO((char*)"SUB", AC2, AC2, AC1, (char*)"Compute offset of value"); emitRM2((char*)"LD", AC1, 0, AC2, (char*)"loah lhs variable", currnode->child[0]->attr.name); emitRO((char*)"SUB", AC, AC1, AC, (char*)"op -="); // decrement emitRM2((char*)"ST", AC, 0, AC2, (char*)"Store variable", currnode->child[0]->attr.name); } else { emitRM2((char*)"LD", AC1, currnode->child[0]->location, offReg, (char*)"load lhs variable", currnode->child[0]->attr.name); // load mutable emitRO((char*)"SUB", AC, AC1, AC, (char*)"op -="); // decrement emitRM2((char*)"ST", AC, currnode->child[0]->location, offReg, (char*)"Store variable", currnode->child[0]->attr.name); // store mutable } break; case eqK: if(currnode->child[0]->isArray) { codeGen(currnode->child[0]); emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save index"); } codeGen(currnode->child[1]); t2 = (TreeNode*)tab->lookup(currnode->child[0]->attr.name); if(t2 != NULL) { if(t2->scopeT == local || t2->scopeT == param) offReg = 1; else offReg = 0; } if(currnode->child[1]->isArray) { if(currnode->child[1]->scopeT == param) emitRM2((char*)"LD", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[1]->attr.name); else emitRM2((char*)"LDA", AC1, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); emitRO((char*)"SUB", AC, AC1, AC, (char*)"Compute offset of value"); emitRM((char*)"LD", AC, 0, AC, (char*)"Load the value"); } if(currnode->child[0]->isArray) { emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Restore index"); if(currnode->child[0]->scopeT == param) emitRM2((char*)"LD", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); else emitRM2((char*)"LDA", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); emitRO((char*)"SUB", AC2, AC2, AC1, (char*)"Compute offset of value"); emitRM2((char*)"ST", AC, 0, AC2, (char*)"Store variable", currnode->child[0]->attr.name); } else emitRM2((char*)"ST", AC, currnode->child[0]->location, offReg, (char*)"Store variable", currnode->child[0]->attr.name); break; case ppK: if(currnode->child[0]->isArray) { codeGen(currnode->child[0]); emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save index"); } //codeGen(currnode->child[0]); t2 = (TreeNode*)tab->lookup(currnode->child[0]->attr.name); if(t2 != NULL) { if(t2->scopeT == local || t2->scopeT == param) offReg = 1; else offReg = 0; } if(currnode->child[0]->isArray) { emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Restore index"); if(currnode->child[0]->scopeT == param) emitRM2((char*)"LD", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); else emitRM2((char*)"LDA", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); emitRO((char*)"SUB", AC2, AC2, AC1, (char*)"Compute offset of the value"); emitRM2((char*)"LD", AC, 0, AC2, (char*)"load lhs variable", currnode->child[0]->attr.name); // load mutable emitRM2((char*)"LDA", AC, 1, AC, (char*)"increment value of", currnode->child[0]->attr.name); // decrement emitRM2((char*)"ST", AC, 0, AC2, (char*)"Store variable", currnode->child[0]->attr.name); } else { emitRM2((char*)"LD", AC, currnode->child[0]->location, offReg, (char*)"load lhs variable", currnode->child[0]->attr.name); // load mutable emitRM2((char*)"LDA", AC, 1, AC, (char*)"increment value of", currnode->child[0]->attr.name); // decrement emitRM2((char*)"ST", AC, currnode->child[0]->location, offReg, (char*)"Store variable", currnode->child[0]->attr.name); // store mutable } break; case mmK: if(currnode->child[0]->isArray) { codeGen(currnode->child[0]); emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save index"); } //codeGen(currnode->child[0]); t2 = (TreeNode*)tab->lookup(currnode->child[0]->attr.name); if(t2 != NULL) { if(t2->scopeT == local || t2->scopeT == param) offReg = 1; else offReg = 0; } if(currnode->child[0]->isArray) { emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Restore index"); if(currnode->child[0]->scopeT == param) emitRM2((char*)"LD", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); else emitRM2((char*)"LDA", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name); emitRO((char*)"SUB", AC2, AC2, AC1, (char*)"Compute offset of the value"); emitRM2((char*)"LD", AC, 0, AC2, (char*)"load lhs variable", currnode->child[0]->attr.name); // load mutable emitRM2((char*)"LDA", AC, -1, AC, (char*)"increment value of", currnode->child[0]->attr.name); // decrement emitRM2((char*)"ST", AC, 0, AC2, (char*)"Store variable", currnode->child[0]->attr.name); } else { emitRM2((char*)"LD", AC, currnode->child[0]->location, offReg, (char*)"load lhs variable", currnode->child[0]->attr.name); // load mutable emitRM2((char*)"LDA", AC, -1, AC, (char*)"increment value of", currnode->child[0]->attr.name); // decrement emitRM2((char*)"ST", AC, currnode->child[0]->location, offReg, (char*)"Store variable", currnode->child[0]->attr.name); // store mutable } break; inexp = texp; } inexp = false; break; case callK: texp = inexp; inexp = false; int ttemp = toff; TreeNode *tmp = currnode->child[0]; //emitComment((char*)"EXPRESSION STMT"); emitComment2((char*)"\t\t\tBegin call to ", currnode->attr.name); emitRM((char*)"ST", FP, toff - framesize, 1, (char*)"Store old fp in ghost frame"); toff -= 2; while(tmp != NULL) { params++; emitComment((char*)"\t\t\tLoad param 1"); codeGen(tmp); emitRM((char*)"ST", AC, toff-- - framesize,FP, (char*)"Store parameter"); paramoff--; tmp = tmp->sibling; params--; } toff = ttemp; paramoff = -2; //t1 = (TreeNode*)tab->lookup(currnode->attr.name); emitComment2((char*)"\t\t\tJump to", currnode->attr.name); emitRM((char*)"LDA", FP, toff - framesize, 1, (char*)"Load address of new frame"); emitRM((char*)"LDA", AC, 1, PC, (char*)"Return address in ac"); //FIX THE DAMN symbtable TreeNode* t = (TreeNode*)tab->lookup(currnode->attr.name); emitRM2((char*)"LDA", PC, t->location - emitSkip(0) - 1, PC, (char*)"CALL", t->attr.name); emitRM((char*)"LDA", AC, 0, RT, (char*)"Save the result in ac"); emitComment2((char*)"\t\t\tEnd call to", currnode->attr.name); emitComment((char*)"EXPRESSION STMT"); calloff += 2; inexp = texp; break; }//end switch exp in_exp = false; }//end expK //else printf("Unknown node kind"); if(params == 0) currnode = currnode->sibling; else currnode = NULL; }//end while }//end function