/* generate code for an if/elseif statement */ void genIf(node *stmt, codelabel *endif) { node *expr = stmt->internal.child[0]; node *thenstmts = stmt->internal.child[1]; /* stmtlist */ node *elsestmt = stmt->internal.child[2]; /* Nelseif/Nelse */ codelabel elselabel; if(elsestmt) { //make sure there is an else initLabel(&elselabel, "else"); genCondExpr(expr, FALSE, &elselabel); } else { genCondExpr(expr, FALSE, endif); } genStmtList(thenstmts, endif); if(elsestmt) { outputCmd("jmp", 0); outputLabel(endif); placeLabel(&elselabel); genStmt(elsestmt, endif); } }
Sym firstLexicalOutputTpl(Arc const* a) const { StateIdContainer const& tails = a->tails_; for (StateIdContainer::const_iterator i = tails.begin(), e = tails.end(); i != e; ++i) { Sym const sym = outputLabel(*i); if (sym.isLexical()) return sym; } return NoSymbol; }
bool anyLabel(F const& f, bool alsoNolabel = false) const { for (StateId state = 0, e = size(); state < e; ++state) { Sym i = inputLabel(state); Sym o = outputLabel(state); if (alsoNolabel || i != NoSymbol) if (f(state, i, o)) return true; } return false; }
/* generate code for a while statement */ void genWhile(node *stmt, codelabel *endwhile) { codelabel loop; initLabel(&loop, "while"); loop.referenced = TRUE; //do this because we place the label before we output here placeLabel(&loop); genCondExpr(stmt->internal.child[0], FALSE, endwhile); genStmtList(stmt->internal.child[1], &loop); outputCmd("jmp", 0); outputLabel(&loop); }
/* generate code for a return statement */ void genReturn(node *stmt, codelabel *next) { if(stmt->internal.child[0]) { opdesc *op = genExpr(stmt->internal.child[0]); op = forceToSpecificReg(op, eax, stmt->unk.line); freeOp(op); } if (next != &funend) { outputCmd("jmp", stmt->internal.line); outputLabel(&funend); } else { outputCmd(NULL, stmt->internal.line); /* do nothing -- fall through */ } // Note that you don't need to output a "jmp" // statement if next is the same as &funend }
Sym label(StateId state, LabelType labelType) const { return labelType == kOutput ? outputLabel(state) : inputLabel(state); }