Forthを32ビット化する
私が作ったForth、moiforthは、数値の型がchar型である。元々実用性を考えていないとはいえ、-128〜127までの数しか扱えないのはあんまりなので、もう少し何とかしよう。というわけで、扱える数値を、いきなり32ビットにする。
push
まず、push()の引数をlongにする。
/** * 値をスタックに積む */ void push(char val) { pos--; stack[pos] = val; }
これを、以下のように変える。
void push(long val) { pos = pos - 4; *(long *)(stack + pos) = val; }
pop
pop()は、戻り値をlongにする。
/** * スタックから値を取り出す */ char pop(void) { return stack[pos++]; }
から、次のように変える。
long pop(void) { long val = *(long *)(stack + pos); pos += 4; return val; }
parse
parse()で内部コードに数値を内部コード化する部分をlongにする。
} else if (isnumber(token)) { prog[idx] = CODE_PUSH; prog[idx + 1] = atoi(token); idx += 2;
これを、このように変更。
} else if (isnumber(token)) { prog[idx] = CODE_PUSH; *(long *)(prog + idx + 1) = atol(token); idx += 5;
proc_prog
proc_prog()のPUSH処理は、
case CODE_PUSH: push(prog[prog_cnt + 1]); prog_cnt += 2; break;
を、次のように変更。
case CODE_PUSH: push(*(long *)(prog + prog_cnt + 1)); prog_cnt += 5; break;
plus
plus()は、push()、pop()を呼び出しているため、変更が必要である。
/** * 加算する */ void plus(void) { char a, b, c; a = pop(); b = pop(); c = a + b; push(c); }
以下のように変更する。
void plus(void) { long a, b, c; a = pop(); b = pop(); c = a + b; push(c); }
print()もplus()同様に修正する。
/** * 表示する */ void print(void) { char a; a = pop(); printf("%d", a); }
これを、
/** * 表示する */ void print(void) { long a; a = pop(); printf("%d", a); }
のように変更した。
全部書くの疲れた
以下省略。やった事は、
- push/popするときの、カウンタの増減量を1バイトから4バイトにした
- 変数の型をcharからlongに変更した
実行してみた。
$ ./moiforth.exe >65535 65535 + . 131070>
大きな数が扱えるようになった。
moiforth-0.7.zip