よく考えるとマクロの引数は評価しちゃいけなかったんだ。
defmacro :foo {|x| "print \'foo -> #{x}\'"}
で
foo(1 + 1)
は
print '2'ではなく、print '1+1'にしないといけなかった。これを実現するには、
- Rubyインタープリタから抽象構文木(AST)を得るような拡張ライブラリを作る
- Rubyのパーサーを作る
- バイトコードから逆コンパイルする
が方法としてあると思います。3の逆コンパイルが面白そうで、実は簡単な気がするのでこれをちょっと検討します。でも、ちょっと最適化を強化するとすぐ動かなくなりそうです。