// 非初期化配列[array(n1, n2, ...)] のコードを生成する static int genArray0(int node, int n, int d) { int typ = syGetType(node); int rVal = syGetRVal(node); int lVal = syGetLVal(node); int lab = -1; // この次元の最初のラベル if (typ==SySEMI) { // 最後の次元でなければ if (syGetType(rVal)!=SyCNST) // 定数でなければエラー error("バグ...genArray0_1"); int cnt = syGetLVal(rVal); // 現在の配列サイズを調べ int ln = genArray0(lVal, n*cnt, d-1); // 入れ子の配列を生成し for (int i=0; i<n; i=i+1) { // 前の次元の要素数分の int l = newLab(); // ラベルを生成し if (lab==-1) lab = l; // この次元の最初を記憶し printLab(l); // .Ln1 DW .Ly1 for (int j=0; j<cnt; j=j+1) { // DW .Ly1 vmDwLab(ln); // ... ln = ln + 1; // を生成する } } } else if (typ==SyCNST) { // 最後の次元なら for (int i=0; i<n; i=i+1) { // 前の次元の要素数分の int l = newLab(); // ラベルを生成し if (lab==-1) lab = l; // この次元の最初を記憶し printLab(l); // if (d==1) // 1次元バイト配列なら vmBs(lVal); // .Ln BS N を生成 else // そうでなければ vmWs(lVal); // .Ln WS N を生成する } } else error("バグ...genArray0_2"); // 定数でなければエラー return lab; }
// 配列の初期化コード生成 static void genList0(int node, int dim, boolean byt) { int typ = syGetType(node); int lVal = syGetLVal(node); int rVal = syGetRVal(node); if (typ==SySEMI) { // リストの途中 genList0(lVal, dim, byt); // 左から genList0(rVal, dim, byt); // 右の順番で辿る } else if (dim==0) { // コード生成すべき深さ if (byt) { // バイト配列の末端 if (syGetType(node)!=SyCNST) error("バグ...genList0"); // 定数だけ OK vmDbCns(syGetLVal(node)); // DB XX を生成 } else { // ワード配列(ポインタ含む) genDW(node); // DW XX を生成 } } else if (typ==SyLIST) { // 初期化配列を発見 if (dim==1) { // コード生成直前 int lab = newLab(); // 配列の先頭に sySetRVal(node, lab); // ラベルを生成し printLab(lab); // rVal に記録 } genList0(lVal, dim-1, rVal==1); // 配列の本体を辿る } else if (typ==SyARRY) { // 非初期化配列が含まれていた if (dim==1) genArray(node); // 非初期化配列生成 } }
// while 文 と for 文 static void genWhl(int node) { int tmpLabB = brkLab; // ラベルを保存 int tmpLabC = cntLab; int loopLab = newLab(); // 条件式のラベル int sta = syGetRVal(node); // 本文 + 再初期化 boolean jb = jmpBlock(syGetLVal(sta)); // 本文は JMP で終わる cntLab = -1; // continue 時のジャンプ先 brkLab = -1; // break 時のジャンプ先 if (syGetRVal(sta)==SyNULL) cntLab = loopLab; // 再初期化がない場合 printLab(loopLab); // ループ先頭のラベル if (syGetLVal(node)!=SyNULL) { // 条件式がある場合 struct Label* bLab = newLabel(0); // ループ脱出用ラベル genCnd(syGetLVal(node), false, bLab); // falseならジャンプ brkLab = bLab->no; // break 時にも使用する free(bLab); } traceTree(syGetLVal(sta)); // 本文の解析 if (syGetRVal(sta)!=SyNULL && // 再初期化がある場合 (!jb || cntLab!=-1)) { // 再初期化に到達するなら printLab(cntLab); // continue 時のジャンプ先 traceTree(syGetRVal(sta)); // 再初期化を解析 jb = false; // 再初期化はJMPで終わらない } if (!jb) vmJmp(loopLab); // 条件式に戻る printLab(brkLab); // break 時のジャンプ先 cntLab = tmpLabC; brkLab = tmpLabB; }
// return 文 static void genRet(int node) { if (syGetLVal(node)!=SyNULL) { // 返す値があれば struct Expr *c = newExpr(); // Expr を割り当て genExpr(syGetLVal(node), c); // 返す式を処理し値をロード vmMReg(); // ハードウェアレジスタに free(c); // 移動する } int root = syGetRoot(); if (root!=node && syGetRVal(root)!=node) { // 関数の最後の文でないなら if (retLab==-1) retLab = newLab(); // ラベルを割り当て vmJmp(retLab); // そこにジャンプする } }
void FilterGraph::update() { LabModel oldlab(getCurrentLabModel()); LabModel newLab(formatLabModel()); newLab.uid = oldlab.uid; newLab.name = oldlab.name; remove_filters_from_database(oldlab.filterList, database); remove_connections_from_database(oldlab.connectionList, database); database.updateLab(newLab); update_chklist(); }
// if-else 文 static void genEls(int node) { struct Label* elsLab = newLabel(0); // ラベルを割り当てる int ifNode = syGetLVal(node); // if 文部分 genCnd(syGetLVal(ifNode), false, elsLab); // 条件式がfalseならジャンプ traceTree(syGetRVal(ifNode)); // 本文の解析 int ifLab = -1; if (!jmpBlock(syGetRVal(ifNode))) { ifLab = newLab(); // ラベルを割り当てる vmJmp(ifLab); // if 文の後ろにジャンプ } printLab(elsLab->no); // else 節 traceTree(syGetRVal(node)); // else 節の本文解析 printLab(ifLab); free(elsLab); }
// do-while 文 static void genDo(int node) { int tmpLabB = brkLab; // ラベルを保存 int tmpLabC = cntLab; int loopLab = newLab(); // 先頭のラベル struct Label *lLab = newLabel(0); lLab->no = loopLab; cntLab = -1; // 条件式のラベル brkLab = -1; // ループ脱出時のラベル printLab(loopLab); traceTree(syGetLVal(node)); // 本文の解析 printLab(cntLab); genCnd(syGetRVal(node), true, lLab); // 条件式 true ならジャンプ printLab(brkLab); cntLab = tmpLabC; brkLab = tmpLabB; free(lLab); }
// genLogExpr を使用して論理値を求める static void genLOpExpr(int node, struct Expr* c) { int op = syGetType(node); // 論理和か論理積か int lab0 = newLab(); // 論理式の最後 struct Label *lab1 = newLabel(0); // 途中で結果が出たとき struct Label *lab2 = newLabel(1); // 途中で結果が出たとき int rNode = genLogExpr(node, c, 1, lab2, lab1); // コード生成 genExpr(rNode, c); // 最後の項の論理値を求める if (op==SyOR) // || なら vmBoolOR(lab2->no, lab1->no, lab0); // BOOLOR マクロ命令を生成 else // && なら vmBoolAND(lab2->no, lab1->no, lab0); // BOOLAND マクロ命令を生成 free(lab1); free(lab2); }
CRLab::CRLab( ) { labGrid = NULL; newLab(); }
// 文字列を生成しラベル番号を返す int genStr(char *str, int len) { int lab = newLab(); // ラベルを割り付け printLab(lab); vmStr(str); // .Ln STRING "xxxx" を出力 return lab; // ラベル番号を返す }
// continue 文 static void genCnt(int node) { if (cntLab==-1) cntLab = newLab(); // 必要ならラベルを割り当てる vmJmp(cntLab); // JMP cntLab }
// break 文 static void genBrk(int node) { if (brkLab==-1) brkLab = newLab(); // 必要ならラベルを割り当てる vmJmp(brkLab); // JMP brkLab }
// 条件ジャンプ命令の生成 static void boolJmp(boolean tf, struct Expr* c, struct Label *lab) { if (lab->no == -1) lab->no = newLab(); // 未割当てなら割当てる if (tf) vmJT(lab->no); // JT lab else vmJF(lab->no); // JF lab }