rowl0 実装完了

ブートストラッピングの第1段階rowl0の実装が終わりました。

  • rowlのサブセット言語
  • GNU assemblerで書いてある

こんな感じでrowlコードをアセンブリ言語コンパイルできます。

% cat hoge.rl
fib: (p0) {
    if (p0 < 2) {
        return 1;
    } else {
        return fib(p0-1) + fib(p0-2);
    };
};

export main;
main: () {
    syscall(1, fib(10));  # exit(). print系の代用
};
% ./rlc < hoge.rl > hoge.as
% as hoge.as -o hoge.o
% ld hoge.o -o hoge --nostdlib --entry=main
% ./hoge
% echo $?
89

rowl0で実装しているもの

  • 関数定義, 関数コール
  • if文, if-else文, while文, goto文, label文
  • 四則演算など(+,-,*,/,%,<,>,<=,>=,==,!=,単項+,単項-,単項!)
  • ポインタ, "*p = ...;" (void*のみ)
  • システムコール: syscall()
  • 名前付きグローバル変数: " x : 0; "
  • 名前付きグローバル配列(1次元のみ): " ary : [0,1,2,3]; "
  • 名前無しローカル変数
  • 整数定数
  • 文字定数(一部のエスケープシーケンスも)
  • 文字列定数
  • 一行コメント "#..."
  • マクロ定数的なもの "X => 100;"

構文についてはそのうち書きます。";"が多くて読みにくいかもしれないですが意図があってこうなっています。

アセンブラで実装するという都合上以下のような制限があります。

  • 名前管理ができない為、関数パラメータはp0,p1,...、ローカル変数はx0,x1,...という名前限定
  • 関数冒頭でallocate(n)命令で変数確保
f: (p0, p1) {
    allocate(1);
    x0 = p0+p1;
    return x0;
};
  • 変数はすべて符号無し32bit整数(アドレス含め)
  • しかし、8bit整数(char型)の配列のみは必要なので、以下の命令を[]演算子代わりに使う。
  • rowl2あたりで型推論を実装する。
wch(ary, i, c); # write char: *(ary+i) = c
rch(ary,i);     # read char: *(ary+i)

次はrowl0でrowl0自身のコンパイラを作るというブートストラッピングのメインループに入ります。