(import (rnrs))
(define-syntax $
(lambda (x)
(define (build k es)
(define $ (datum->syntax k '$))
(define (build-es es)
(let loop ((es es) (r '()))
(cond ((null? es) (reverse r))
((and (identifier? (car es))
(free-identifier=? $ (car es)))
(append (reverse r) (list (loop (cdr es) '()))))
(else
(loop (cdr es) (cons (car es) r))))))
#`(#,@(build-es es)))
(syntax-case x ()
((k es ...)
(build #'k #'(es ...))))))
(define (print . args)
($ for-each display args) (newline))
($ newline)
($ for-each print
$ list 1 2 3)
なんというか、syntax-caseを使っているのは単にS式を直接扱いたかっただけという・・・僕の頭ではマクロ展開中に値を貯めてとか、分解してとかが無理だった・・・動作はmosh、Ypsilon、Sagittariusで確認。恐らく、syntax-caseの動作としては信頼が出来る順に確認してるはず(moshはpsyntax使っているので多分マクロ周りの信頼が高い、はず・・・)
マクロ展開中に式を分解したりするのってどうやって考えれば身につくのだろうか?低レベルのマクロが書けると面倒になってS式そのままいじってしまう・・・
No comments:
Post a Comment