5

I found myself defining syntax parameters with identical definitions except for their name so I decided to write a macro to make this simpler:

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

However instead of having to repeat the macro name I would like to be able to just write:

(test-case-parameter a b c)

But I don't see how to do this using the normal ellipses syntax, because I would need to wrap everything in a begin which would create a new scope, and I want all of the syntax parameters as if I had written them each of the top level. What's the right way to accomplish this?

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)

beginDrRacket のマクロ ステッパーでトップレベルのスプライシングがどのように機能するかを確認できます。

スプライシング開始マクロステッパー

于 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 に答える