OreScript時代の幕開け - yukobaの日記 http://d.hatena.ne.jp/yukoba/20071108/p1

巷で OreScript ブームが巻き起こる中、某所ではさらに局地的に Javascript での言語実装ブーム。

××さんが ******* を試作したり、西尾さんが python4js を試作したりして、うーむこんなおもしろそうなお祭りは看過できんでわないか。Ruby 成分の多い中谷としてはここはやっぱ Javascript で Ruby かっ！？

そういえばだれか Javascript でパーサ書いてはったよなあ。それを使わせてもらえば Ruby の構文木をさっくり得られて、ちょこちょこっとインタプリタ書いたら、FizzBuzz くらいなら動くんじゃないの？ という思いついてしまったからには、もう作ってみるしか。

というわけで言った者勝ち(笑)の JSRuby をこしらえてみました。

リンク先のページで簡単な演算や FizzBuzz の実行テストを行えます。一応 IE6, Firefox2, Opera9, Safari3β で動作確認はしてみました。Safari2 では RegExp.rightContext がサポートされていないそうなので動きません(amachang サンクス)。すいません。

コードは <script type="text/ruby"> で埋め込んであるのを拾って textarea に出しているので、編集して実行することもできるようにしてあります。

んが、正直今のところ「 Ruby で書かれた FizzBuzz を実行できる、Ruby っぽい何か」なので、普通の Ruby スクリプトを入れてもまだまず動きません(苦笑)。





実装範囲は

・演算子 +, -, *, /, ==, ..

・演算の優先順位は有効

・数値、文字列リテラル

・代入

・組み込み関数 puts

・if ～ then ～ elsif ～ else ～ end

・配列に対する each メソッド

以上！ って本当に FizzBuzz しか見てません……

とはいえ一応代入も if もちゃんと値を返すので、a=b=4 とか puts if x % 2 == 0 then "even" else "odd" end という書き方はちゃんとできます。

実装済みの範囲でも怪しいところはちらほら。特に前者はやばめ。

・パーサの時点で識別子をメソッドか変数か決定してしまっている(ミスった)

・Ruby の型を扱っていない（整数の割り算が実数になる、 .. 演算子が(javascriptの)配列を返す、など）

あと残念ながら、パーサは当初考えていた Gin ではなく、自前で再帰下降パーサを手書きしてます(隠れ左再帰を見つけられず、too much recursion を解消できなかった……)。

まあ半分ネタとはいえせっかく作ったので、上に書いた識別子の問題を解消し、ソースを分割、テストコードを付け、CodeRepos にアップさせてもらえれば、みんなでよってたかってつついてくれて、あれーいつの間にかできてる！ とか妄想中ｗ

フル実装は夢としても、どう書く？org の Rubyコードの７割がたが動く、くらいならかなり現実的な気もしますです。

この状態で使ってみようという人はいないと思いますが、簡単な使い方。

jsruby.js を組み込んで、

var parser = new RubyEngine .Parser(); var ruby = new RubyEngine .Interpreter(); ruby.run(parser.parse( " puts 2*3+4*5; 9*9*9 " ))

とやれば指定の ruby コードを実行します。

ruby.run() の返値は最終の式の評価なので、この場合 729 が返ってきます。

また、標準出力の値は ruby.stdout から取り出せます(この場合 "26

" が入っている)。

標準出力への書き出しは ruby.writeStdout() を上書きすることで変更できます。例えば ruby.run() の前に

ruby.writeStdout = function(st){ alert(st); }

と入れれば、都度ダイアログで表示されます。