コンパイラを VM で動かす - Scheme VM を書く


Scheme のコード => VM が実行可能なコード」を担当するコンパイラScheme で書かれていて Gauche で動いています。
VMScheme 処理系としてある程度成熟してきたので、Gauche の助けを借りず自分自身でコンパイラを動かせたら良いなという試み。


やることを列挙しておこう。

コンパイラの出力が正しいか検証する

コンパイラ 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 の実装をきちんとしていないのできっと出力がおかしくなることでしょう。

コンパイラの出力が正しいか検証する2

今度は3つのコンパイラの出力が全て同じであることを検証します。(長い道のりだな)。


一発目のテストでコケました(笑)。

compiling (0/257) : #t
 ==> NG
 [Gauche output ] : "(CONSTANT #t (HALT))"
 [VM output     ] : "(CONSTANT #t (HALT))"
 [VM(C++) output] : "(CONSTANT #t\0 (19))"
*** ERROR: Stopped.

今日はがんばったのでここまで。

雑談 - 混乱

コンパイラコンパイル済みコードを出力して、それをVMが実行するとコンパイル済みコードが出てくる。
ぐるぐるぐるぐる。
コンパイラVM で動いているときに VM がエラーになるので、そのときの実行コードを眺めるともうわけわかめ