2016-09-25 27 views
4

我發現自己定義與除了自己的名字相同的定義語法參數,所以我決定寫一個宏,使這個簡單的:定義多個頂級表單的球拍宏?

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

但我不明白如何使用正常的省略號語法要做到這一點,因爲我需要換一個begin一切這將創建一個新的範疇,我希望所有的語法參數就好像我已經將它們寫入每個頂層一樣。什麼是正確的方式來實現這一目標?

+2

那麼,答案是使用'begin'。 'begin'很奇怪,因爲它在頂級與表達式上下文中有兩種不同的行爲。在頂層,它具有你想要的這種宏的拼接行爲,但是在表達式上下文中有你所指的範圍行爲。 –

回答

4

答案是使用beginbegin很奇怪,因爲它在頂層具有不同於行爲的表達上下文。在頂層,它具有你想要的這種宏的拼接行爲,但是在表達式上下文中有你所指的範圍行爲。

所以,你可以定義宏是這樣的:

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

你可以看到begin頂級拼接在宏步進是如何工作的DrRacket:

splicing-begin-macro-stepper

+0

謝謝,不知道它有特殊情況下的行爲;) –

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)