「10日くらいでできる!プログラミング言語自作入門」の続編#1-2a
(1) HL-12a
- 今回のテーマは、本当にちゃんとコード生成できているのかの確認、どこまで速くできそうかをちょっと確認、の2つです。
(前略)
int phrCmpPutIcX86(int pid, String phr, int pc, int *pi, int lenExpr, void *sub, int *err) → HL-11と同じなので省略
int codedump; [この行追加]
///////////////////////////////////////////////////////////////////////////////
int compile(String s)
{
(中略)
jp = 0;
putIcX86("60; 83_ec_7c;", 0, 0, 0, 0); // PUSHAD(); SUB(ESP,124);
+ dump0 = icq;
for (i = 0; i < 10; i++) {
tmp_flag[i] = 0;
}
tmpLabelNo = 0;
bd = lbd = 0;
for (pc = 0; pc < pc1; ) { // コンパイル開始.
(中略)
+ } else if (phrCmp(35, "code", pc)) {
+ for (pc++; tc[pc] != TcSemi; pc++) {
+ if (tc[pc] == TcComma) continue;
+ *icq = var[tc[pc]];
+ icq++;
+ }
+ ppc1 = pc + 1;
+ } else if (phrCmp(38, "codedump !!*0;", pc)) {
+ codedump = var[tc[wpc[0]]];
} else if (phrCmp( 8, "!!***0;", pc)) { // これはかなりマッチしやすいので最後にする.
e0 = expr(0);
} else
goto err;
tmpFree(e0);
tmpFree(e2);
if (e0 < 0 || e2 < 0) goto err;
pc = ppc1;
}
if (bd > 0) {
printf("block nesting error (bd=%d, lbd=%d, pc=%d, pc1=%d\n", bd, lbd, pc, pc1);
return -1;
}
+ dump1 = icq;
putIcX86("83_c4_7c; 61; c3;", 0, 0, 0, 0); // ADD(ESP,124); POPAD(); RET();
icq1 = icq;
(中略)
}
int run(String s)
{
if (compile(s) < 0)
return 1;
+ if (codedump == 0) {
void (*func)() = (void (*)()) ic;
t0 = clock();
func();
+ } else {
+ int i, i1 = dump1 - dump0;
+ for (i = 0; i < i1; i++) {
+ printf("%02x ", dump0[i]);
+ }
+ printf("\n(len=%d)\n", i1);
+ }
return 0;
}
(後略)
- 2つめのcode命令は、かなり強烈な命令です。16進数を並べると、それをそのまま機械語生成に加えます。ちょっと間違えただけでプログラムが暴走します。
- 私はこの命令を使って、「こういう機械語にしたら何秒で実行できるかなあ」みたいなことを試します。
- どちらもより詳しいことは、(2)や(3)で説明します。
(2)
次回に続く
こめんと欄