void doLinear(ostream &o, uint i, Span *s, uint n, State *next){ for(;;){ State *bg = s[0].to; while(n >= 3 && s[2].to == bg && (s[1].ub - s[0].ub) == 1){ if(s[1].to == next && n == 3){ indent(o, i); genIf(o, "!=", s[0].ub); genGoTo(o, bg); return; } else { indent(o, i); genIf(o, "==", s[0].ub); genGoTo(o, s[1].to); } n -= 2; s += 2; } if(n == 1){ if(bg != next){ indent(o, i); genGoTo(o, s[0].to); } return; } else if(n == 2 && bg == next){ indent(o, i); genIf(o, ">=", s[0].ub); genGoTo(o, s[1].to); return; } else { indent(o, i); genIf(o, "<=", s[0].ub - 1); genGoTo(o, bg); n -= 1; s += 1; } } }
void doBinary(ostream &o, uint i, Span *s, uint n, State *next){ if(n <= 4){ doLinear(o, i, s, n, next); } else { uint h = n/2; indent(o, i); genIf(o, "<=", s[h-1].ub - 1); o << "{\n"; doBinary(o, i+1, &s[0], h, next); indent(o, i); o << "\t} else {\n"; doBinary(o, i+1, &s[h], n - h, next); indent(o, i); o << "\t}\n"; } }
// 構文木をトレースする static void traceTree(int node) { if (node==SyNULL) return; // 何も無い int ty = syGetType(node); if (ty==SyIF) genIf(node); // if 文 else if (ty==SyELS) genEls(node); // if-else 文 else if (ty==SyWHL) genWhl(node); // while 文 else if (ty==SyDO) genDo(node); // do-while 文 else if (ty==SyBRK) genBrk(node); // break 文 else if (ty==SyCNT) genCnt(node); // continue 文 else if (ty==SyRET) genRet(node); // retrun 文 else if (ty==SyBLK || ty==SySEMI) { // ブロック traceTree(syGetLVal(node)); // 先に左側をコード生成 traceTree(syGetRVal(node)); // 次に右側をコード生成 } else if (ty==SyVAR) { // ローカル変数宣言 ; // 特にやることがない } else { // 式文 struct Expr *c = newExpr(); // 式の状態を管理するデータ genBoolExpr(node, c); // 式を処理する pop(c); // スタックにあれば捨てる free(c); // 管理データを解放 } }
/* Generate code for a statement (vardecl, assign, funcall, * return, if/elseif/else, or while). */ void genStmt(node *stmtnode, codelabel *next) { switch (stmtnode->internal.type) { case Nvardecl: genVardecl(stmtnode); break; case Nassign: genAssign(stmtnode); break; case Nfuncall: /* later */ genCall(stmtnode); break; case Nreturn: genReturn(stmtnode, next); break; case Nif: case Nelseif: genIf(stmtnode, next); break; case Nelse: genStmtList(stmtnode->internal.child[0], next); break; case Nwhile: genWhile(stmtnode, next); break; default: assert(FALSE); /* should never get here */ } }