From 9b302f4288960b762c86fdf05c57cb27c64e58cd Mon Sep 17 00:00:00 2001 From: Masahiro Oono Date: Tue, 26 Sep 2023 19:43:06 +0900 Subject: [PATCH] Separate run() processing at compile time and runtime --- main.c | 53 +++++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/main.c b/main.c index 2e02d06..a8207ea 100644 --- a/main.c +++ b/main.c @@ -262,51 +262,39 @@ void putIc(Opcode op, IntPtr p1, IntPtr p2, IntPtr p3, IntPtr p4) icp += 5; } -int run(String src) +int compile(String src) { - clock_t begin = clock(); - int nTokens = lexer(src, tc); tc[nTokens++] = Semicolon; // 末尾に「;」を付け忘れることが多いので、付けてあげる tc[nTokens] = tc[nTokens + 1] = tc[nTokens + 2] = tc[nTokens + 3] = Period; // エラー表示用 + icp = internalCodes; + int pc; - for (pc = 0; pc < nTokens; ++pc) { // ラベル定義命令を探して位置を登録 - if (match(4, "!!*0:", pc)) - vars[tc[pc]] = nextPc; // ラベル定義命令の次のpc値を変数に記憶させておく - } for (pc = 0; pc < nTokens;) { if (match(0, "!!*0 = !!*1;", pc)) { - vars[tc[wpc[0]]] = vars[tc[wpc[1]]]; + putIc(OpCpy, &vars[tc[wpc[0]]], &vars[tc[wpc[1]]], 0, 0); } else if (match(1, "!!*0 = !!*1 + !!*2;", pc)) { - vars[tc[wpc[0]]] = vars[tc[wpc[1]]] + vars[tc[wpc[2]]]; + putIc(OpAdd, &vars[tc[wpc[0]]], &vars[tc[wpc[1]]], &vars[tc[wpc[2]]], 0); } else if (match(2, "!!*0 = !!*1 - !!*2;", pc)) { - vars[tc[wpc[0]]] = vars[tc[wpc[1]]] - vars[tc[wpc[2]]]; + putIc(OpSub, &vars[tc[wpc[0]]], &vars[tc[wpc[1]]], &vars[tc[wpc[2]]], 0); } else if (match(3, "print !!*0;", pc)) { - printf("%d\n", vars[tc[wpc[0]]]); + putIc(OpPrint, &vars[tc[wpc[0]]], 0, 0, 0); } else if (match(4, "!!*0:", pc)) { // ラベル定義命令 - ; + vars[tc[wpc[0]]] = icp - internalCodes; // ラベル名の変数にその時のicpの相対位置を入れておく } else if (match(5, "goto !!*0;", pc)) { - pc = vars[tc[wpc[0]]]; - continue; + putIc(OpGoto, &vars[tc[wpc[0]]], 0, 0, 0); } else if (match(6, "if (!!*0 !!*1 !!*2) goto !!*3;", pc) && Equal <= tc[wpc[1]] && tc[wpc[1]] <= Gtr) { - int lhs = vars[tc[wpc[0]]], op = tc[wpc[1]], rhs = vars[tc[wpc[2]]]; - int dest = vars[tc[wpc[3]]]; - if (op == Equal && lhs == rhs) { pc = dest; continue; } - if (op == NotEq && lhs != rhs) { pc = dest; continue; } - if (op == LesEq && lhs <= rhs) { pc = dest; continue; } - if (op == GtrEq && lhs >= rhs) { pc = dest; continue; } - if (op == Les && lhs < rhs) { pc = dest; continue; } - if (op == Gtr && lhs > rhs) { pc = dest; continue; } + putIc(OpJeq + (tc[wpc[1]] - Equal), &vars[tc[wpc[3]]], &vars[tc[wpc[0]]], &vars[tc[wpc[2]]], 0); } else if (match(7, "time;", pc)) { - printf("time: %.3f[sec]\n", (clock() - begin) / (double) CLOCKS_PER_SEC); + putIc(OpTime, 0, 0, 0, 0); } else if (match(8, ";", pc)) { ; @@ -316,7 +304,16 @@ int run(String src) } pc = nextPc; } - return 0; + putIc(OpEnd, 0, 0, 0, 0); + + IntPtr *end = icp; + Opcode op; + for (icp = internalCodes; icp < end; icp += 5) { // goto先の設定 + op = (Opcode) icp[0]; + if (OpGoto <= op && op <= OpJgt) + icp[1] = (IntPtr) (internalCodes + *icp[1]); + } + return end - internalCodes; err: printf("Syntax error: %s %s %s %s\n", tokenStrs[tc[pc]], tokenStrs[tc[pc + 1]], tokenStrs[tc[pc + 2]], tokenStrs[tc[pc + 3]]); return 1; @@ -363,6 +360,14 @@ void exec() } } +int run(String src) +{ + if (compile(src) < 0) + return 1; + exec(); + return 0; +} + String removeTrailingSemicolon(String str, size_t len) { for (int i = len - 1; i >= 0; --i) { if (str[i] != ';')