symbol-macrolet で shadowing しなきゃならん special-form
書いてて気づいたんだけど、単純に除外するんじゃなくて、たとえば (let (foo ...) ...) なら foo は symbol-macro じゃないけど他の bar とかは symbol-macro になるから、bar とかはちゃんと置換しなきゃいけないんだ。うん。
で。
- 関数で lexical scope を作ることはできないんで、関数は放置
- macro は macroexpand すれば消えてなくなるので無視
- つまり special-form さえ気にすればおk
(do-all-symbols (sym) (if (special-form-p sym) (format t "~S~%" sym)))
から関係ありそうなのを列挙。
lexical environment
- macrolet ???
- let*
- labels
- let
- multiple-value-bind
- flet
- function (lambda)
macroexpand した後で macrolet が残ってるってありえないよーな。
forms using symbol as 'tag'
- throw
- return-from
- go
- catch
- tagbody
- block
other: eval-when
:compile-toplevel とか symbol-macro で変換されても困るだろ。
追記 (2009-07-11 12:02)
そもそも constant は symbol macro にできないみたい @sbcl。keyword symbol が constantp だなんて知らなかった。
other: quote
これはどーなんかなぁ。
(macroexpand '(defmacro foo () foo)) => (progn nil (system:*fset 'foo '(macro nil (block foo foo))))
とか見ると quote されてるのはそのままにしとくのが楽そうなんだけど。
sbcl で試してみたら
(let ((bar 'I-AM-BAR)) (symbol-macrolet ((foo bar)) (list foo 'foo))) => (I-AM-BAR FOO)
で quoted symbol はそのままみたい。
Each reference to symbol as a variable within the lexical scope of symbol-macrolet is expanded by the normal macro expansion process;
CLHS: Special Operator SYMBOL-MACROLET
だから quote されてたら放置でいーのか。
あと、すっげー気になるっていうか、どーにもできない気がするのが si:*byte-code。