トップ 差分 一覧 Farm ソース 検索 ヘルプ RSS ログイン

Forthを作ってみる / Forthを32ビット化する

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

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