Yet Another Grass 処理系

http://github.com/mame/grass-misc/tree/master/
こないだ作った Grass インタプリタyagi.rb (Yet Another Grass Interpreter) という名前にしておきました。
yagc.rb は Grass コンパイラ (というほど大したことしないけど) で、Grass のプログラムを Ruby に翻訳するツール。

$ ./yagc.rb hello.www > hello.rb

$ ruby19 hello.rb; echo
Hello, world!

初めて Proc#curry を使った。
yagd.rb は逆コンパイラで、yagc.rb で生成した Ruby プログラムを Grass に戻すツール。

$ ./yagd.rb hello.rb > hello2.www

$ ./yagi.rb hello2.www; echo
Hello, world!

$ diff hello.www hello2.www

とりあえずこのくらい。まじめにやれば 500B は切れる。はず。

$ ruby19 -e 'p File.read("hello.www").gsub(/[^wWv]/m, "").size'
519

追記
hello.www のネタばれ。





実は計算方法自体は rst76 さんのコードを拝借してます。

wwWWwWWWwvwWWwWwwwwwwvWWwwwwWWWwWWWWwWWWWWwWWWWWWwWWWWWWWwWWWWWWWwWWWwvwWWWWWWW
wvWwwWWWWWWWWWWwWWWWWWWWWWWWWWWwwWWWWwWWWWWWWWWwWWWWWWWWWwwwwwWWWWWWWWWWWWwvwWW
WWWWWWWWWWWWWWwvWwwwwwWWwwwwWWWWWWWWWWWWWWWWWWWWWWWwWWWWWWWWWWWWwWWWWWwvwWWWWWW
WWWWWWWWWWWWWWWWWwvWwwwwwWWwwwvwWWWWWWWWWWWWWWWWWWWWWWWWWWWWWwvwWWwwwwwwwwwwwwW
WWwwwwwwwwwwwWWWWwwwwwwwwwwwwwwwwwwWWWWWWWWWWWWWWWWWWWWWWwwwWWWWWWwWWWWWWWwwwww
vwWWWwwwwWWWWwwWWWWWwwwwwwwwwwwWWWWWWwwwwwwwwwwwwwwwwwwwwwvWWWwwwwwwwwwwwwwwwWW
WWwwwwwwWWWWWwwwwwwwwwwWWWWWWwWWWWWWwWWWWWWww

ポイントは

  • id を定義しない (id を定義して id Out するより、出力の直前でイータ展開 (λx. Out x) を定義した方が安上がり)
  • λx. Out x を用意した直後で出力関数を定義する (Out や値が近くなる)

です。あとは細かい最適化。