定义多个顶级表单的球拍宏?

Jos*_*vin 5 macros define-syntax variadic racket toplevel

我发现自己使用相同的定义来定义语法参数,除了它们的名称,所以我决定编写一个宏来使这更简单:

(define-syntax (test-case-parameter stx)
  (syntax-parse stx
    [(_ parameter:id)
     #'(define-syntax-parameter parameter
         (lambda (stx)
           (raise-syntax-error stx "Can only be used inside test-case.")))]))

(test-case-parameter a)
(test-case-parameter b)
(test-case-parameter c)
Run Code Online (Sandbox Code Playgroud)

然而,我不想重复宏名称,我希望能够写:

(test-case-parameter a b c)
Run Code Online (Sandbox Code Playgroud)

但是我没有看到如何使用普通的省略号语法来实现这一点,因为我需要将所有内容包装在一个begin可以创建新范围的内容中,并且我希望所有的语法参数就好像我已经为每个顶部写了一样水平.什么是正确的方法来实现这一目标?

Ale*_*uth 5

答案是使用begin.begin很奇怪,因为它在顶层具有与在表达式上下文中不同的行为.在顶层,它具有您希望此宏所需的拼接行为,但在表达式上下文中具有您所指的范围行为.

所以你可以这样定义你的宏:

#lang racket
(require racket/stxparam (for-syntax syntax/parse))

(define-syntax (define-test-case-parameters stx)
  (syntax-parse stx
    [(_ parameter:id ...)
     #'(begin
         (define-syntax-parameter parameter
           (lambda (stx)
             (raise-syntax-error stx "Can only be used inside test-case.")))
         ...)]))

(define-test-case-parameters a b c)
Run Code Online (Sandbox Code Playgroud)

您可以begin在DrRacket中的宏步进器中看到顶级拼接的工作原理:

剪接开始宏步进