コンパイラを VM で動かす - Scheme VM を書く
「Scheme のコード => VM が実行可能なコード」を担当するコンパイラは Scheme で書かれていて Gauche で動いています。
VM が Scheme 処理系としてある程度成熟してきたので、Gauche の助けを借りず自分自身でコンパイラを動かせたら良いなという試み。
やることを列挙しておこう。
- コンパイラが正しく動くかを検証する
- Gauche 上の VM でコンパイル済みのコンパイラを動かしテストを通す
- C++ 上の VM でコンパイル済みのコンパイラを動かしテストを通す
- セーフモードを作る
- write の対応が必要
- compiler が *primitive-names* に依存している
- eval を実装する
- マクロを実装する
コンパイラの出力が正しいか検証する
コンパイラ on Gauche とコンパイラ on Vm on Gauche の出力が全く等しいかの検証。
compiling :(+ 4 3 10) ==> NG [Gauche output] : (CONSTANT 4 (ARGUMENT (CONSTANT 3 (NUMBER_ADD (ARGUMENT (CONSTANT 10 (NUMBER_ADD (HALT)))))))) [VM output ] : (CONSTANT 10 (ARGUMENT (CONSTANT 3 (ARGUMENT (CONSTANT 4 (NUMBER_ADD (NUMBER_ADD (HALT))))))))
このように簡単にテストできるようにした。
今回の例は fold の定義が間違っていました。
何度か躓きつつも全てにおいて同じ出力を得られた。
C++ VM の外部コンパイラを入れ換える
C++ VM の外部コンパイラをコンパイラ on VM on Gauche にする。
うぉ。遅いな。
コンパイルに3秒くらいかかるぞ。
それはともかくコンパイル結果は正しいようで、C++ VM でテストコードが全て通った。
しばらくは Makefile で
# 安全コンパイラ #COMPILER = ./gmosh.scm compile # 危険コンパイラ COMPILER = ./gmosh.scm exec ./compiler.scm compile
と切り分けておく。
コンパイラを C++ VM で動かす
コンパイラを C++ VM で動かします。
いちおう動きました。
write/display の実装をきちんとしていないのできっと出力がおかしくなることでしょう。