5

我发现自己定义的语法参数除了名称之外具有相同的定义,因此我决定编写一个宏以使其更简单:

(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)

但是,不必重复宏名称,我希望能够只写:

(test-case-parameter a b c)

但是我不知道如何使用普通的省略号语法来做到这一点,因为我需要将所有内容包装在 abegin中,这将创建一个新的范围,并且我想要所有的语法参数,就好像我已经把它们写在了顶部等级。实现这一目标的正确方法是什么?

4

2 回答 2

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)

你可以在 DrRacket 的 Macro Stepper 中看到begin顶层拼接是如何工作的:

拼接开始宏步进器

于 2016-09-25T18:59:55.260 回答
1

创建一个接受多个标识符的新宏,并让它扩展为使用单个标识符的版本的一系列用法。

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

(define-syntax (test-case-parameter-helper stx)
  (syntax-parse stx
    [(_test-case-parameter-helper parameter:id)
     (syntax/loc stx
       (define-syntax-parameter parameter
         (lambda (stx)
           (raise-syntax-error stx "Can only be used inside test-case."))))]))

(define-syntax (test-case-parameter stx)
  (syntax-parse stx
    [(_test-case-parameter parameter:id ...)
     (syntax/loc stx
       (begin
         (test-case-parameter-helper parameter)
         ...))]))

(test-case-parameter a b c)
于 2016-09-25T18:57:56.517 回答