这是场景:给定形式[sym ...]
的模式(例如 [a b]
和 [a b c d]
( 我想生成(使用宏(函数,这些函数连接模式中的符号,但也将它们作为参数提供。例如,[a b]
转换为以下形式的内容
(define (ab a b)
body)
在这篇文章中,有人通过一个名为 signal-list
的语法类帮助我生成函数的名称。在下面的代码中,我可以将signals
模式变量与形式(sig ...)
的模式相匹配,然后我可以使用它来生成所需的函数定义。
(define-syntax (define-something stx)
(syntax-parse stx
[(_ (signals:signal-list body ...))
(syntax-parse #'signals
[(sig ...)
#'(define (signals.concatenated-ids sig ...)
body ...)])]))
与此宏匹配的示例:
(define-something
([a b] 'body))
扩展到(define (ab a b) 'body)
但是,如果我想生成多个函数定义,宏如何工作?例如:
(define-something
([a b] 'body)
([c d e] 'body))
=>
(begin (define (ab a b) 'body)
(define (cde c d e) 'body))
我可以在第一个语法解析的模式中添加一个省略号:
(_ (signals:signal-list body ...) ...)
但是我不能使用第二个语法解析来匹配signals
因为它需要一个省略号。有没有不同的方法来"解构"signals
以便我可以将其内容用作函数的形式参数,这与使用省略号兼容?
要直接回答您的问题,您可以将#'(signals ...)
(代替您现有的#'signals
(传递给内部syntax-parse
调用。
作为概念证明,我编写了宏的syntax-case
版本(因为我还不知道syntax-parse
(。您应该能够调整相同的技术来轻松syntax-parse
:
(define-syntax (define-something outerstx)
(define (make-name paramstx)
(datum->syntax outerstx
(string->symbol
(apply string-append
(map symbol->string (syntax->datum paramstx))))))
(define (make-names innerstx)
(syntax-case innerstx ()
(()
#'())
(((param ...) rest ...)
(with-syntax ((name (make-name #'(param ...)))
((next ...) (make-names #'(rest ...))))
#'(name next ...)))))
(syntax-case outerstx ()
((_ ((param ...) body ...)
...)
(with-syntax (((name ...) (make-names #'((param ...) ...))))
#'(define-values (name ...)
(values (lambda (param ...)
body ...)
...))))))