我刚刚开始深入研究 Racket 宏,并试图制作一个简洁的简单宏定义宏。我想扩展这样的表达式:
(macro id
(param) replacement1
(params ...) replacement2)
变成这样:
(define-syntax id
(syntax-rules ()
((id param) replacement1)
((id params ...) replacement2)))
所以原始表达式的 cddr 变成了表达式对(用于语法规则主体),并将 id 插入到每对表达式的 car 中。
当仅使用语法规则提供的模式匹配时,我在递归思考时遇到了麻烦(我一直想像操作普通列表一样操作表达式)。我应该使用什么样的模式?或者,我可以以某种方式将其作为普通列表进行操作,然后取消引用结果以用于扩展吗?
非常感谢
编辑 - 暂定解决方案,由 Taymon 的回答提供信息
我在这里的部分好奇心是关于摆脱那些配对括号。我研究了语法案例,但有点困惑,所以尝试纯粹使用模式匹配子语言来做。我最终使用 Taymon 的宏和另一个宏来“配对”给定的模板(它的行为有点像累加器函数):
(define-syntax-rule (macro-aux id ((param ...) expr) ...)
(define-syntax id
(syntax-rules ()
((id param ...) expr)
...)))
(define-syntax pairize
(syntax-rules ()
((pairize id (pairs ...) p b) (macro-aux id pairs ... (p b)))
((pairize id (pairs ...) p b rest ...) (pairize id (pairs ... (p b)) rest ...))))
(define-syntax macro
(syntax-rules ()
((macro id tpl-expr ...) (pairize id () tpl-expr ...))))