口上
これとか
- [わーい\(^O^)/Whitespaceインタプリタできたよー]
http://d.hatena.ne.jp/hayamiz/20080325/1206403241
これとか
http://d.hatena.ne.jp/yuyarin/20080325/1206382820
に釣られて, 自分でもWhitespaceのインタプリタ書いてみた.
Rubyで.
#最初はSchemeでやろうかと思ったけど, えらく時間がかかりそうなのでやめた.
コードはこれ↓
http://www.hpcs.cs.tsukuba.ac.jp/~kanbayashi/whitespace.rb
説明
こういう時に決まって試すのはHello Worldですね↓
#ちゃんとコードが書いてあるのでよーく目をこらして見てみましょう
ref http://ja.wikipedia.org/wiki/Hello_world%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E4%B8%80%E8%A6%A7#Whitespace
これをhello.wsというファイルに保存して, 実行してやると
$ruby whitespace.rb hello.ws
Hello WorldINTERPRETER: interpretation ended.
動いた!!
initializeメソッド内の@out_op変数をtrueにするとディスアセンブルもできる.
$ruby whitespace.rb hello.ws
exec_stack_push_a_number 72
exec_io_out_a_char
exec_stack_push_a_number 101
exec_io_out_a_char
exec_stack_push_a_number 108
exec_io_out_a_char
exec_stack_push_a_number 108
exec_io_out_a_char
exec_stack_push_a_number 111
exec_io_out_a_char
exec_stack_push_a_number 32
exec_io_out_a_char
exec_stack_push_a_number 87
exec_io_out_a_char
exec_stack_push_a_number 111
exec_io_out_a_char
exec_stack_push_a_number 114
exec_io_out_a_char
exec_stack_push_a_number 108
exec_io_out_a_char
exec_stack_push_a_number 100
exec_io_out_a_char
exec_stack_push_a_number 10
exec_io_out_a_char
exec_flow_exit
Hello WorldINTERPRETER: interpretation ended.
仕様については一応全部実装したつもり.
公式ページのExample(http://compsoc.dur.ac.uk/whitespace/examples.php)は全部ちゃんと動いたので多分, バグはない・・・・かなと思う.
実装の話
かなりぐだぐだな実装.
パーサのところとかはすごい愚直な実装になってる. 各オペレーションのパターンをキー, 解釈のためのメソッドをハンドラとして登録できるようなパーサのクラスを作ればもっと美しく, 少ないコードで書けたはず.
あと, パフォーマンスとかを考えると, プログラム全体を読み込んだら, それを中間言語に変換してメモリに載せておくようなのが普通なのではないかと思うけど, 僕のはそんな事してなくて, ソースコードの同じ箇所を複数回通過する時は, その回数だけパースするようになってる. なのでループが100回まわったら100回パースする. だめぽ.
書いてみた感想
ラベルの解釈周りでちょっとしたバグにはまったけど, 他のところは結構すんなり動いた. ちょっと拍子抜け. ただ運がよかっただけかもしれないけど.
Future Work
whitespace製のでかいプログラムを動かしてみたい.
誰かwhitespaceのコードを吐き出すトランスレータとか書いてないのかな?
#追記
id:hayamizの実装(http://d.hatena.ne.jp/hayamiz/20080325/1206403241)を見てみたら, 正規表現を使ってパースしてた.
確かにこの程度の規模だったら正規表現でできるはずだ.
くそー, そこには考えが至らなかったぜ.
ちなみに, id:yuyarinのコードも読んでみたけど, 処理の内容は撲のと大体同じだった.
やっぱ普通はこういうコード書くよね.
#追記 4/5 16:40
文字列の入力のところにバグがあったので直した