CTacAddr* CAstStatIf::ToTac(CCodeBlock *cb, CTacLabel *next) { CTacLabel* truelabel = cb->CreateLabel("if_true"); // true label CTacLabel* falselabel = cb->CreateLabel("if_false"); // false label _cond->ToTac(cb, truelabel, falselabel); // calculate condition CAstStatement *s = _ifBody; cb->AddInstr(truelabel); // install true label while(s != NULL) { // TAC of ifBody CTacLabel* tempnext = cb->CreateLabel(); s->ToTac(cb, tempnext); cb->AddInstr(tempnext); s = s->GetNext(); } cb->AddInstr(new CTacInstr(opGoto, next)); // skip to next s = _elseBody; cb->AddInstr(falselabel); // install false label while(s != NULL) { // TAC of elseBody CTacLabel* tempnext = cb->CreateLabel(); s->ToTac(cb, tempnext); cb->AddInstr(tempnext); s = s->GetNext(); } cb->AddInstr(new CTacInstr(opGoto, next)); // goto next return NULL; }
CTacAddr* CAstStatWhile::ToTac(CCodeBlock *cb, CTacLabel *next) { assert(cb != NULL && next != NULL); CAstExpression *cond = GetCondition(); CAstStatement *body = GetBody(); CTacLabel *while_cond = cb->CreateLabel("while_cond"); CTacLabel *c_true = cb->CreateLabel("while_body"); // while condition begins cb->AddInstr(while_cond); CTacAddr *tCond = cond->ToTac(cb, c_true, next); if(dynamic_cast<CAstDesignator*>(cond)) { // if cond is a single boolean cb->AddInstr(new CTacInstr(opEqual, c_true, tCond, new CTacConst(1))); cb->AddInstr(new CTacInstr(opGoto, next)); } // while body starts.. cb->AddInstr(c_true); while(body) { CTacLabel *while_next = cb->CreateLabel("while_next"); body->ToTac(cb, while_next); cb->AddInstr(while_next); body = body->GetNext(); } cb->AddInstr(new CTacInstr(opGoto, while_cond)); return NULL; }
CTacAddr* CAstStatIf::ToTac(CCodeBlock *cb, CTacLabel *next) { assert(cb != NULL && next != NULL); CAstExpression *cond = GetCondition(); CAstStatement *ifBody = GetIfBody(); CAstStatement *elseBody = GetElseBody(); CTacLabel *c_true = cb->CreateLabel("if_true"); CTacLabel *c_false = cb->CreateLabel("if_false"); // starting with translate condition CTacAddr *tCond = cond->ToTac(cb, c_true, c_false); if(dynamic_cast<CAstDesignator*>(cond)) { // if cond is a single boolean cb->AddInstr(new CTacInstr(opEqual, c_true, tCond, new CTacConst(1))); cb->AddInstr(new CTacInstr(opGoto, c_false)); } // if_body starts.. cb->AddInstr(c_true); while(ifBody) { CTacLabel *if_next = cb->CreateLabel("if_next"); ifBody->ToTac(cb, if_next); cb->AddInstr(if_next); ifBody = ifBody->GetNext(); } cb->AddInstr(new CTacInstr(opGoto, next)); // if else_body exists, else_body starts.. cb->AddInstr(c_false); if(elseBody) { while(elseBody) { CTacLabel *else_next = cb->CreateLabel("else_next"); elseBody->ToTac(cb, else_next); cb->AddInstr(else_next); elseBody = elseBody->GetNext(); } cb->AddInstr(new CTacInstr(opGoto, next)); } return NULL; }
CTacAddr* CAstScope::ToTac(CCodeBlock *cb) { assert (cb != NULL); CAstStatement *s = GetStatementSequence(); while(s != NULL) { // statements -> TAC. connect each by "next" label CTacLabel *next = cb->CreateLabel(); s->ToTac(cb, next); cb->AddInstr(next); s = s->GetNext(); } cb->CleanupControlFlow(); // clean up control flow return NULL; }
CTacAddr* CAstScope::ToTac(CCodeBlock *cb) { assert(cb != NULL); CAstStatement *s = GetStatementSequence(); // ToTac for all statement sequence. while (s != NULL) { CTacLabel *next = cb->CreateLabel(); s->ToTac(cb, next); cb->AddInstr(next); s = s->GetNext(); } // clean up all unnecessary labels. cb->CleanupControlFlow(); return NULL; }
CTacAddr* CAstStatWhile::ToTac(CCodeBlock *cb, CTacLabel *next) { CTacLabel* lcond = cb->CreateLabel("while_cond"); // condition label CTacLabel* lbody = cb->CreateLabel("while_body"); // body label cb->AddInstr(lcond); // install condition label _cond->ToTac(cb, lbody, next); cb->AddInstr(lbody); CAstStatement *s = _body; while(s != NULL) { CTacLabel *tempnext = cb->CreateLabel(); s->ToTac(cb, tempnext); cb->AddInstr(tempnext); s = s->GetNext(); } cb->AddInstr(new CTacInstr(opGoto, lcond)); return NULL; }