yarv2llvm近況
先週のyarv2llvmの開発はそんなに時間は取っていないのですが、ずっとデバッグでした。Unsafeのサポートの為シビアに定数の畳み込みを行う必要があり、畳み込みが甘いところを直すと、既存のプログラムの型推論が失敗するということの繰り返しでした。何とか、Unsafeをサポートしつつ既存のプログラムが動くようになって、Threadのランタイムを書き始めています。
書き始めてすぐにランタイムは思いっきり機種依存で条件コンパイルが必要になることに気づきました。条件コンパイルだけなのでプリプロセッサを作ってもいいのですが、どうせなのでマクロをサポートすることにしました。こんな感じで書くことを考えています。
define_macro :native_thread_create do |arg| th = arg[0] hostos = Config::CONFIG['host_os'] case hostos when "cygwin" `native_thread_create_win32(th)` when "linux" `native_thread_create_pthread(th)` else raise "Unsupported OS #{hostos}" end end
マクロについては、
http://cloud.github.com/downloads/miura1729/yarv2llvm/yarv2llvm-ura.pdf
に沿ったものにする予定です。今は、YARVをRubyに戻す処理を書いています。
追記
YARVをRubyに戻す処理はこんな感じです。
http://github.com/miura1729/yarv2llvm/blob/17267a94ab8009d0262d7cea536a795d38e9390e/lib/yarv2ruby.rb
制御構造を戻すのが大変です。RubyにGOTOが欲しいとここまで思った人はかっていなかったでしょう。まじでGOTO欲しいです。
追記2
ステートマシンを利用するとGOTOを実現できることを思い出したので対応できた。ちょうど、Javascriptでスレッドを実現したり、LSIの順序回路を記述するFSMみたいな感じ。こんな感じのコード。
while true __state = nil case __state when nil a = 10 __state = :label_35 next __state = :label_11 when :label_11 nil __state = :label_35 next __state = :label_14 when :label_14 p(2) a = ((a) - (1)) __state = :label_35 when :label_35 if (((a) == (1)) ) then __state = :label_14 next end __state = :label_44 when :label_44 return (nil) return end end