mini python
Pythonインタプリタと、それに並行してVMを書いている。
インタプリタのほうは、あとはビルトイン関数を揃えて、動作がおかしなところを調整してゆけばひとまず動くようにはなりそうだ。とはいえ、そこかしこに効率化の余地は残されているし、現状GCはOSのメモリ管理(笑)なので、BohemGCを組み込んでみたりとやることは見つけようと思えばいくらでもみつけられる。
VMのほうは、亀のペースで進行中。構文木→VM命令列の翻訳器の完成度が50%、VM命令列実行器の完成度が5%くらい。
構文木から直接命令列への変換はなかなか難しいなぁ、と思いながら作業中。コンパイラの本とか、id:higepon さんのところの話を読んで、中間表現に一旦変換してから、VM命令列に変換したほうが最適化もかけやすいし、(多分)頭の中が整理されてこんがらがることがなさそうだとは思っているのだけれど、今回は時間の関係上中間表現をじっくり考えていられない。
翻訳器のほうで1つ悩んでいる問題として、def 文をどう扱うか、というのがある。
pythonとかスクリプト言語の場合、ファイルよ読み込んで実行する場合のエントリーポイントはファイルの先頭になる。で、先頭から1つ1つ命令を実行していくのだけれど、関数定義にぶちあたったときにどうすんべ、というのが今の悩み。関数定義自体は、その場で実行するものではないからスキップしなきゃいけないんだけど、命令列に変換するときに関数の中身の定義を、どこか後ろのほうにまとめて押しやってしまうか、あるいはその場に関数定義を置いといて、それをgotoなどで避けるようにするか。現在は後者にしてあるけど、これって普通なのかなー。それとも他にスマートなやりかたがあるんだろうか。
Example
Python コード
... print bar def foo(a): .... print 1 + 2
定義を別の場所に
... VM_PUSH(bar) VM_CALL(print) VM_DEFUN(foo) VM_PUSH(1) VM_PUSH(2) VM_CALL(add) VM_CALL(print) ... VM_END() ; defun of foo VM_ ...
定義をスキップ
... VM_PUSH(bar) VM_CALL(print) VM_DEFUN(foo) GOTO(end_of_foo) ... end_of_foo: VM_PUSH(1) VM_PUSH(2) VM_CALL(add) VM_CALL(print) ... VM_END()