// DND void CodeGen::visitGMainFuncDec(GMainFuncDec *gmainfuncdec) { if(!dontMindMeJustCollectingGlobals) { curScope = string("main"); emit(".text"); emitLabel("_start"); emit("adr \tsp, \tstackEnd \t@@ setup stack pointer, full descending"); emit("BL rtsinit"); emit("PUSH\t{ip,\tlr}"); //gmainfuncdec->identifier_->accept(this); //printf("@@ yo, in main regAt(a) and (b) are %d, %d\n", //regAtName(string("a")), regAtName(string("b") )); //printf("@@ and in the data structure:\n"); //printf("@@ ...%d, %d\n", //regVarsInScope[paramsForFunction[string("sum")].front()], //regVarsInScope[paramsForFunction[string("sum")].back()]); gmainfuncdec->liststatement_->accept(this); /*freeRegs(regsInScope); regsInScope = 0;*/ freeScopeVars(); emitLabel("main_end"); //emit(".end"); emit("\t BL halt\n"); emit("POP \t{ip,\tpc}"); // This line *SHOULD* come first, but whatevs. } }
void Else::gen(int b, int a){ int label1 = newLabel(); int label2 = newLabel(); test->jumping(0,label2); emitLabel(label1); stmt1->gen(label1, a); std::stringstream gt; gt<<"goto L"<<a; emit(gt.str()); emitLabel(label2); stmt2->gen(label2,a); }
// EXPR1 && EXPR2 // DND void CodeGen::visitCAExprAnd(CAExprAnd *caexprand) { curExpr.push(maxExpr++); int reg1 = allocRegs(1); string andAfter = getLabel(curScope, "and", maxExpr, "after"); caexprand->conditionalandexpression_->accept(this); emitCmd("MOV", reg1, 0); emitCmd("MOV", 0, "#0"); emitCmd("CMP", reg1, 0); emitCmd("BEQ", andAfter); emitCmd("MOV", 0, "#1"); caexprand->equalityexpression_->accept(this); emitCmd("MOV", reg1, 0); emitCmd("MOV", 0, "#0"); emitCmd("CMP", reg1, 0); emitCmd("MOVNE", 0, "#1"); emitLabel(andAfter); curExpr.pop(); freeRegs(1); }
// DND void CodeGen::visitGVFuncDec(GVFuncDec *gvfuncdec) { gvfuncdec->identifier_->accept(this); curScope = string(tempString); if(dontMindMeJustCollectingGlobals) { // Empty list paramsForFunction[curScope] = list<string>(); gvfuncdec->listformalparam_->accept(this); } if(!dontMindMeJustCollectingGlobals) { emitLabel(curScope); emit("PUSH\t{r1-r11, lr}"); int counter = 0; int formParamHere; gvfuncdec->listformalparam_->accept(this); paramNum = 1; gvfuncdec->block_->accept(this); freeScopeVars(); cout << curScope << "_end:\n"; emit("POP\t{r1-r11, pc}"); } }
void Do::gen(int b, int a) { after = a; int label = newLabel(); stmt->gen(b,label); emitLabel(label); test->jumping(b,0); }
/* * Emit ASC code for a then statment as part of IF-THEN. * Assumes the corresposding statement or matched_stat code has already * been emitted. */ void emitThenStat() { /* we don't have a symbol pointer, so just pass in non-null */ CHECK_CAN_EMIT(1); emitComment("Bottom of IF-THEN as part of IF-THEN"); emitLabel(STMT_LEN, "%s%d", LABEL_PREFIX, peekLabelStackTop(labelStack)); popLabels(labelStack); }
/* * Emit ASC code for an else statement * Assumes the corresponding statement code is already generated. */ void emitElseStat() { /* we don't have a symbol pointer, so just pass in non-null */ CHECK_CAN_EMIT(1); emitComment("Bottom of ELSE stat"); emitLabel(STMT_LEN, "%s%d", LABEL_PREFIX, peekLabelStackTop(labelStack) + 1); popLabels(labelStack); }
/* * Emit code for the end of a while loop. */ void emitEndWhile() { /* we don't have a symbol pointer, so just pass in non-null */ CHECK_CAN_EMIT(1); emitComment("End of WHILE loop %s%d", LOOP_PREFIX, peekLabelStackTop(loopLabelStack)); emitLabel(STMT_LEN, "%s%d", LOOP_PREFIX, peekLabelStackTop(loopLabelStack) + 1); popLabels(loopLabelStack); }
void CodeGen::visitEInt(EInt *eint) { visitInteger(eint->integer_); // BOOKMARK // stringstream temp; // temp << "#" << tempInt; // emitCmd("MOV", 0, temp.str()); // THIS IS WHAT'S CAUSING ALL THE SHIT. DEAL WITH IT TOMORROW string intAfter = getLabel(curScope, "intLit", curDataNum, "after"); string intLabel = getLabel(curScope, "intLit", curDataNum, "data"); cout << "\tB \t" << intAfter << "\n"; emitLabel(intLabel); cout << ".int\t" << tempInt << "\n"; printf(".align 4\n"); //cout << "\"\n .align 4\n"; emitLabel(intAfter); cout << "\tLDR \tr12,\t=" << intLabel << "\n"; cout << "\tLDR \tr0,\t [r12]\n"; curDataNum++; }
void While::gen(int b, int a) { after = a; test->jumping(0,a); int label = newLabel(); emitLabel(label); stmt->gen(label,b); std::stringstream gt; gt<<"goto L"<<b; emit(gt.str()); }
/* * Beginning of a while loop */ void emitBeginWhile() { /* we don't have a symbol pointer, so just pass in non-null */ CHECK_CAN_EMIT(1); /* Reserve loop labels. One for the top, one for the bottom */ reserveLabels(loopLabelStack, 2); emitComment("Top of WHILE loop %s%d", LOOP_PREFIX, peekLabelStackTop(loopLabelStack)); emitLabel(STMT_LEN, "%s%d", LOOP_PREFIX, peekLabelStackTop(loopLabelStack)); }
// DND void CodeGen::visitSWhile(SWhile *swhile) { if(!dontMindMeJustCollectingGlobals) { curWhile.push(maxWhile++); string startWhile = getLabel(curScope, "while", curWhile.top(), "start"); string endWhile = getLabel(curScope, "while", curWhile.top(), "end"); emitLabel(startWhile); swhile->expression_->accept(this); emitCmd("CMP", 0, "#0"); emitCmd("BEQ", endWhile); swhile->statement_->accept(this); emitCmd("B", startWhile); emitLabel(endWhile); curWhile.pop(); } }
// DND void CodeGen::visitSIfElse(SIfElse *sifelse) { if(!dontMindMeJustCollectingGlobals) { curIfElse.push(maxIfElse++); string elseBlock = getLabel(curScope, "ifElse", curIfElse.top(), "elseBlock"); string elseEnd = getLabel(curScope, "ifElse", curIfElse.top(), "end"); sifelse->expression_->accept(this); emitCmd("CMP", 0, "#0"); emitCmd("BEQ", elseBlock); sifelse->statement_1->accept(this); emitCmd("B", elseEnd); emitLabel(elseBlock); sifelse->statement_2->accept(this); emitLabel(elseEnd); curIfElse.pop(); } }
/* * Emit ASC code for a then statment as part of IF-THEN-ELSE. * Assumes the corresposding statement or matched_stat code has already * been emitted. */ void emitThenMatchedStat() { /* we don't have a symbol pointer, so just pass in non-null */ CHECK_CAN_EMIT(1); emitComment("Bottom of an IF-THEN."); emitComment("Either THEN was executed, so GOTO,"); emitComment("or land at %s%d if 'expr' was false", LABEL_PREFIX, peekLabelStackTop(labelStack)); emitStmt(STMT_LEN, "GOTO %s%d", LABEL_PREFIX, peekLabelStackTop(labelStack) + 1); emitLabel(STMT_LEN, "%s%d", LABEL_PREFIX, peekLabelStackTop(labelStack)); }
void Seq::gen(int b, int a) { if (*stmt1 == *Stmt::StmtNULL) { stmt2->gen(b, a); } else if (*stmt2 == *Stmt::StmtNULL) { stmt1->gen(b, a); } else { int label = newLabel(); stmt1->gen(b, label); emitLabel(label); stmt2->gen(label,a); } }
// DND void CodeGen::visitSIf(SIf *sif) { if(!dontMindMeJustCollectingGlobals) { curIf.push(maxIf++); string endIf = getLabel(curScope, "if", curIf.top(), "end"); sif->expression_->accept(this); emitCmd("CMP", 0, "#0"); emitCmd("BEQ", endIf); sif->statement_->accept(this); emitLabel(endIf); curIf.pop(); } }
void If::gen(int b, int a) { int label = newLabel(); test->jumping(0,a); emitLabel(label); stmt->gen(label,a); }
void processStatement(SymbolTable *table, Node *ptr) { Node *p; char label1[LABEL_SIZE]={0}, label2[LABEL_SIZE]={0}; switch(ptr->token.tokenNumber) { case COMPOUND_ST: p = ptr->son->next; p = p->son; while (p) { processStatement(table, p); p = p->next; } break; case EXP_ST: if (ptr->son != NULL) { processOperator(table, ptr->son); } break; case RETURN_ST: if (ptr->son != NULL) { p = ptr->son; if (p->noderep == NONTERM) { processOperator(table, p); } else { rv_emit(table, p); } emit0("retv"); } else emit0("ret"); flag_returned=1; break; case IF_ST: genLabel(label1); processCondition(table, ptr->son); emitJump("fjp", label1); processStatement(table, ptr->son->next); emitLabel(label1); break; case IF_ELSE_ST: genLabel(label1); genLabel(label2); processCondition(table, ptr->son); emitJump("fjp", label1); processStatement(table, ptr->son->next); emitJump("ujp", label2); emitLabel(label1); processStatement(table, ptr->son->next->next); emitLabel(label2); break; case WHILE_ST: genLabel(label1); genLabel(label2); emitLabel(label1); processCondition(table, ptr->son); emitJump("fjp", label2); processStatement(table, ptr->son->next); emitJump("ujp", label1); emitLabel(label2); break; default: fprintf(file, "not yet implemented.\n"); break; } }
void CodeGen::visitFCall(FCall *fcall) { if(!dontMindMeJustCollectingGlobals) { isFCall = true; // VISIT IDENT, GET FUNCNAME fcall->identifier_->accept(this); tempName = tempString; // Name of func is in tempName int reg1 = 0; isRTS = true; if ((tempName.compare(string("printi")) != 0) && (tempName.compare(string("printc")) != 0) && (tempName.compare(string("printb")) != 0) && (tempName.compare(string("halt")) != 0) && (tempName.compare(string("getchar")) != 0) && (tempName.compare(string("prints")) != 0)) { isRTS = false; } if(isRTS) { //reg1 = allocRegs(1); //emitCmd("MOV", reg1, 0); DONT_MOVE = true; } } // GET PARAMETERS fcall->listexpression_->accept(this); if(!dontMindMeJustCollectingGlobals) { regVarStack.push(regVarsInScope); savedTopReg = topRegister; topRegister = 1; bool isPrintS = (tempName.compare(string("prints")) == 0); bool isGetChar = (tempName.compare(string("getchar")) == 0); // PRINTS // PRINTS SPECIAL CASE string printLabel = getLabel(curScope, "prints", curStringNum, "print"); if(isPrintS) { cout << "\tMOV\tr12,\tr0\n"; cout << "\tPUSH\t {r1-r12}\n"; cout << "\tB \t" << printLabel << "\n"; string stringLabel = getLabel(curScope, "prints", curStringNum, "string"); emitLabel(stringLabel); cout << ".ascii\t\"" << replaceEscapes(tempString); printf("\\0\"\n.align 4\n"); //cout << "\"\n .align 4\n"; emitLabel(printLabel); cout << "\tLDR \tr0,\t=" << stringLabel << "\n"; curStringNum++; emitCmd("BL", tempName); cout << "\tPOP\t {r1-r12}\n"; cout << "\tMOV\tr0,\tr12\n"; } // ********************CALL THE FUNCTION ******************* else if(isRTS && !isPrintS && !isGetChar) { cout << "\tMOV\tr12,\tr0\n"; cout << "\tPUSH\t {r1-r12}\n"; emitCmd("BL", tempName); cout << "\tPOP \t {r1-r12}\n"; cout << "\tMOV\tr0,\tr12\n"; } else if(isGetChar) { cout << "\tPUSH\t {r1-r12}\n"; emitCmd("BL", tempName); cout << "\tPOP \t {r1-r12}\n"; } else if(!isRTS) { emitCmd("BL", tempName); } // CLEANUP //if (!isRTS) //{ regVarsInScope = regVarStack.top(); regVarStack.pop(); topRegister = savedTopReg; // } isFCall = false; } }