macro.pm

PerlVMを直接いじるのは大変だが,PPIとソースフィルタを使えば比較的簡単にPerlを拡張できるかもしれない,と思ってモジュールを書いてみた。
macro - An implementation of macro processor
このmacro.pmはcpp(1)に似たマクロを提供する。

use macro
    add      => sub{ $_[0] + $_[1] },
    addprint => sub{ print add($_[0], $_[1]), "\n" };
addprint(40, 2); # => 42

これがコンパイル時に以下のように展開される。

do{ print do{ (40) + (2) }, "\n" };

PPIのロードとパースに非常に時間が掛かるためコンパイル速度が低下するが*1,関数の呼び出しを行わないので実行速度は劇的に上昇する。
しかし!PPIの制限がキツイ。まず,1.203の時点ではクォートの中まではパースしてくれない。だからたとえば, qq{ ${macro()} } や s{...}{macro()}e のmacro()は展開されない。また,PPIAPIもまだ不十分のようで,macro.pmではやむを得ず非公開APIを使っている箇所もある。
とはいえ,PPIはすばらしく面白い。これはいろいろ遊べそうだ。

*1:実際には,Module::Compileに似た仕組みでコンパイル済みソースコードをキャッシュするのでコンパイル速度も問題にならない。なお,最初はModule::Compileで実装しようとしたが,うまく行かなかったのでコンパイルモジュールは独自に実装した。