マクロの実装

自作 Lisp インタプリタで、まだ list もバッククォートも無いが、マクロがいちおう動作するようになった。

下の例は、 変数の値を1増やす incf マクロ。Warning として表示しているように、与えられた式を変形した上で、評価する。

Warning: form: (incf x) => (setq x (+ x 1))
toy-lisp> (defmacro incf(x)  (cons 'setq (cons x (cons (cons '+ (cons x (cons 1 nil))) nil))))

incf 
toy-lisp> (setq x 1)

x 
toy-lisp> (incf x)
Warning: form: (incf x) => (setq x (+ x 1))

x 
toy-lisp> x

2 

まがりなりにもマクロが動いたのはとてもうれしい。実装してみると、マクロ自体は単純なアイディアと良くわかる。

  • 普通の関数の評価は引数を評価してから環境に保存し、関数の本体を順に評価する。
  • マクロの場合は引数を評価せずに環境に保存し、マクロの本体を順に評価して新しい式を作り、それから新しい式を評価する。

説明が下手なので言葉で書くとまだ冗長だが、インタプリタのソースを見ると関数とマクロの部分はほとんどおんなじになっている。

TODO; まだ http://www.lisp.org/HyperSpec/Body/sec_3-1-2-1-2-2.html をぜんぜんカバーできていない。またマクロ展開のタイミング。