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; }
ostream& CAstStatIf::print(ostream &out, int indent) const { string ind(indent, ' '); out << ind << "if cond" << endl; _cond->print(out, indent+2); out << ind << "if-body" << endl; if (_ifBody != NULL) { CAstStatement *s = _ifBody; do { s->print(out, indent+2); s = s->GetNext(); } while (s != NULL); } else out << ind << " empty." << endl; out << ind << "else-body" << endl; if (_elseBody != NULL) { CAstStatement *s = _elseBody; do { s->print(out, indent+2); s = s->GetNext(); } while (s != NULL); } else out << ind << " empty." << endl; return out; }
bool CAstStatIf::TypeCheck(CToken *t, string *msg) const { CAstExpression *cond = GetCondition(); bool result = true; if (!cond->TypeCheck(t, msg)) return false; if (cond->GetType() != CTypeManager::Get()->GetBool()) { if (t != NULL) *t = cond->GetToken(); if (msg != NULL) *msg = "boolean expression expected."; return false; } try { CAstStatement *ifBody = GetIfBody(); CAstStatement *elseBody = GetElseBody(); while (result && (ifBody != NULL)) { result = ifBody->TypeCheck(t, msg); ifBody = ifBody->GetNext(); } while (result && (elseBody != NULL)) { result = elseBody->TypeCheck(t, msg); elseBody = elseBody->GetNext(); } } catch (...) { result = false; } return result; }
void CAstScope::toDot(ostream &out, int indent) const { string ind(indent, ' '); CAstNode::toDot(out, indent); CAstStatement *s = GetStatementSequence(); if (s != NULL) { string prev = dotID(); do { s->toDot(out, indent); out << ind << prev << " -> " << s->dotID() << " [style=dotted];" << endl; prev = s->dotID(); s = s->GetNext(); } while (s != NULL); } vector<CAstScope*>::const_iterator it = _children.begin(); while (it != _children.end()) { CAstScope *s = *it++; s->toDot(out, indent); out << ind << dotID() << " -> " << s->dotID() << ";" << endl; } }
ostream& CAstScope::print(ostream &out, int indent) const { string ind(indent, ' '); out << ind << "CAstScope: '" << _name << "'" << endl; out << ind << " symbol table:" << endl; _symtab->print(out, indent+4); out << ind << " statement list:" << endl; CAstStatement *s = GetStatementSequence(); if (s != NULL) { do { s->print(out, indent+4); s = s->GetNext(); } while (s != NULL); } else { out << ind << " empty." << endl; } out << ind << " nested scopes:" << endl; if (_children.size() > 0) { for (size_t i=0; i<_children.size(); i++) { _children[i]->print(out, indent+4); } } else { out << ind << " empty." << endl; } out << ind << endl; return out; }
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; }
bool CAstStatIf::TypeCheck(CToken *t, string *msg) const { if(!_cond->TypeCheck(t, msg)) return false; // Do TypeCheck on condition expression if(!_cond->GetType()->IsBoolean()) { if(t != NULL) *t = _cond->GetToken(); if(msg != NULL) *msg = "boolean expression expected."; return false; } bool result = true; CAstStatement *s = _ifBody; while(result && (s != NULL)) { // Do TypeCheck on all ifBody-statements result = s->TypeCheck(t, msg); s = s->GetNext(); } s = _elseBody; while(result && (s != NULL)) { // Do TypeCheck on all elseBody-statements result = s->TypeCheck(t, msg); s = s->GetNext(); } return result; }
void CAstStatIf::toDot(ostream &out, int indent) const { string ind(indent, ' '); CAstNode::toDot(out, indent); _cond->toDot(out, indent); out << ind << dotID() << "->" << _cond->dotID() << ";" << endl; if (_ifBody != NULL) { CAstStatement *s = _ifBody; if (s != NULL) { string prev = dotID(); do { s->toDot(out, indent); out << ind << prev << " -> " << s->dotID() << " [style=dotted];" << endl; prev = s->dotID(); s = s->GetNext(); } while (s != NULL); } } if (_elseBody != NULL) { CAstStatement *s = _elseBody; if (s != NULL) { string prev = dotID(); do { s->toDot(out, indent); out << ind << prev << " -> " << s->dotID() << " [style=dotted];" << endl; prev = s->dotID(); s = s->GetNext(); } while (s != 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; }
bool CAstScope::TypeCheck(CToken *t, string *msg) const { bool result = true; try { CAstStatement *s = _statseq; while(result && (s != NULL)) { // do TypeCheck for all statements under this scope result = s->TypeCheck(t, msg); s = s->GetNext(); } vector<CAstScope*>::const_iterator it = _children.begin(); while(result && (it != _children.end())) { // do TypeCheck for all scopes under this scope result = (*it)->TypeCheck(t, msg); it++; } } catch(...) { result = false; } return result; }