昔書いたGrass言語用アセンブラwwww in Ruby*1。
easyGrass.rbという名前で保存して、test.egというファイルにDSLを書いて
./easyGrass.rb test.eg
のように渡すと、Grass言語に変換されます。
仕様wwww
関数定義は defun というメソッドに関数名と引数名を指定して、ブロック内に処理を書く感じ。例えば
defun(:hoge, :arg1, :arg2) { out[arg1] x = succ[succ[arg2]] out[x] }
定義した関数の呼び出し(関数適用)は
関数名[引数1, 引数2, ..]
という感じ。もちろん
関数名[引数1][引数2]
とか
x = 関数名[引数1] ; x[引数2]
でも同じ(Curry化)。
defunしたものなら「 関数名(引数1, ..) 」でも呼び出せるけど、関数を返す関数から受け取って変数に代入した場合は[]でないとうまく行かない*2。
初期環境にあるプリミティブは [:out, :succ, :w, :inp] という名前です*3。
おまけ機能で
defineY
というメソッドをソース中から呼び出すと、その場所にYコンビネータを"y"という名前で定義してくれます。
例えば ASCII文字0-255の文字コードを(wから)ずらっと一周表示するソースだと、再帰のためにYコンビネータを使って
defun(:loop0, :f, :x) { out[x] nx = succ[x] # nx = x+1 w[nx, w, f, nx] # if (nx==w) then w(nx) else f(nx) } defineY y[loop0,w]
とか書けます。