【问题标题】:Racket macro that defines multiple top-level forms?定义多个顶级表单的球拍宏?
【发布时间】:2017-02-03 01:46:31
【问题描述】:

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

(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 中,这将创建一个新范围,并且我想要所有语法参数,就好像我有把他们每一个写在顶层。实现此目的的正确方法是什么?

【问题讨论】:

    标签: macros racket variadic toplevel define-syntax


    【解决方案1】:

    答案是使用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)
    

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-09
        • 2013-06-23
        • 2022-12-18
        相关资源
        最近更新 更多