简体   繁体   English

球拍宏中的未绑定变量

[英]unbound variable in racket macro

I am testing a wrapper macro around the racket syntax-case macro.我正在围绕 racket syntax-case宏测试包装器宏。 At step 1, it does nothing interesting and simply passes through all the parts to syntax-case directly as follows:在第 1 步,它没有做任何有趣的事情,只是将所有部分直接传递给syntax-case ,如下所示:

#lang racket

;; definition
(define-syntax guarded-syntax-case
  (lambda (x)
      (syntax-case x ()
        ((guarded-syntax-case y (literal ...) clause ...)
         #'(syntax-case y (literal ...) clause ...)
         ))))

;; test case
(define-syntax (binop stx)
  (guarded-syntax-case stx () ; *problem site*
        [(_ op n1 n2) #'(op n1 n2)]))

But this simple case fails with the following error at the empty brackets () labeled with problem site labeled in above code:但是这个简单的案例失败了,在上面代码中标有问题站点的空括号()处出现以下错误:

; ....rkt:11:27: #%app: missing procedure expression;
;  probably originally (), which is an illegal empty application
;   after encountering unbound identifier (which is possibly the real problem):
;    guarded-syntax-case
;   in: (#%app)

I couldn't figure out what could be wrong in this simple pass-through macro.我不知道这个简单的传递宏有什么问题。 The error message seems to suggest that there is a unbound variable somewhere, which I couldn't identify.错误消息似乎表明某处有一个未绑定的变量,我无法识别。 I would think that the literal... should be matched to empty.我认为literal...应该匹配为空。

Could someone help explain what went wrong and how to fix the macro?有人可以帮助解释出了什么问题以及如何修复宏吗?

The problem is that guarded-syntax-case is not recognized as a macro in the correct phase .问题是guarded-syntax-case在正确的阶段没有被识别为宏。 In particular, when you (define-syntax guarded-syntax-case...) in your program, you define the macro guarded-syntax-case that is available in phase 0. But forms in (define-syntax (binop stx)...) must be in phase 1.特别是,当您在程序中使用(define-syntax guarded-syntax-case...)时,您定义了在阶段 0 中可用的宏guarded-syntax-case 。但是(define-syntax (binop stx)...)必须在第一阶段。

There are two ways to correct the mistake.有两种方法可以纠正错误。

  1. You can wrap (define-syntax guarded-syntax-case...) inside begin-for-syntax .您可以将(define-syntax guarded-syntax-case...)包装在begin-for-syntax中。 However, doing so would require syntax-case and other stuff to be available in phase 2. So you need an additional (require (for-meta 2 racket/base)) .但是,这样做需要在第 2 阶段提供syntax-case和其他内容。因此您需要一个额外的(require (for-meta 2 racket/base)) Here's the full code:这是完整的代码:
#lang racket

(require (for-meta 2 racket/base))

;; definition
(begin-for-syntax
  (define-syntax guarded-syntax-case
    (lambda (x)
      (syntax-case x ()
        ((guarded-syntax-case y (literal ...) clause ...)
         #'(syntax-case y (literal ...) clause ...))))))

;; test case
(define-syntax (binop stx)
  (guarded-syntax-case stx () ; *problem site*
                       [(_ op n1 n2) #'(op n1 n2)]))

(binop + 1 2) ;=> 3
  1. Alternatively, you can define a (sub)module that provides guarded-syntax-case , and then require the (sub)module with for-syntax .或者,您可以定义一个提供guarded-syntax-case的(子)模块,然后使用for-syntax require该(子)模块。 Here's the full code:这是完整的代码:
#lang racket

(module lib racket
  (provide guarded-syntax-case)
  ;; definition
  (define-syntax guarded-syntax-case
    (lambda (x)
      (syntax-case x ()
        ((guarded-syntax-case y (literal ...) clause ...)
         #'(syntax-case y (literal ...) clause ...))))))

(require (for-syntax 'lib))

;; test case
(define-syntax (binop stx)
  (guarded-syntax-case stx () ; *problem site*
                       [(_ op n1 n2) #'(op n1 n2)]))

(binop + 1 2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM