macroexpand-all

執拗な再帰マクロ展開 - 象徴ヶ淵 を見て「あー、あー(詳細は後述)」とか思ったので書き始めてみた。のだけど思ったよりめんどかったので、途中まで書いて GitHub に突っ込んどいた=>http://github.com/bowbow99/xyzzy.macroexpand-all/tree

とりあえず単純に operand も全部 macroexpand した場合の問題点を簡単に。以下 MACRO という macro があるとして。

macro call ではない場合

以下の (MACRO ...) という部分が展開されてもらっては困る。

(let ((MACRO ...)) ...)
(multiple-value-bind (MACRO ...) ...)
(labels ((MACRO (MACRO ...) ...)) ...)
(lambda (MACRO ...) ...)

macrolet によって定義された local-macros

2種類ある。まず macroexpand-all が受け取った form に macrolet form が含まれる場合。もうひとつ macroexpand-all の外側に存在する local-macros(これは素の macroexpand でも env を渡さないと展開してくれない)。

labels, flet, macrolet による shadowing

shadowing って用語が正しいのかよくわからんけど。

(defmacro MACRO () :GLOBAL)
=> MACRO

(labels ((MACRO () :LABELS))
  ;; 以下の (MACRO) で呼び出されるのは、global-macro MACRO ではなく
  ;; local-function MACRO になる
  (MACRO))
=> :LABELS

参考リンク