我正试图通过定义自己的module-begin
来捕获扩展形式:
(define-syntax-rule (my-module-begin e ...)
(#%module-begin
e ...
(foo e ...)))
我是否纠正foo
的原始格式?如果是这样,foo
是否可以获取扩展的表单?
答案 0 :(得分:2)
要获取展开的表格,您需要以某种方式使用local-expand
。
您可能会考虑在每个这样的表达式上分别调用local-expand
:
#lang racket
(require syntax/parse/define
(for-syntax syntax/stx))
(define-simple-macro (my-module-begin e ...)
; define a function that expands it
#:do [(define (expand/mod-ctx e)
(local-expand e 'module '()))]
; get the expanded versions by calling that function on the e's
#:with (e-expanded ...) (stx-map expand/mod-ctx #'(e ...))
; use the expanded versions inside foo
(#%module-begin
e-expanded ...
(foo e-expanded ...)))
当e
形式为表达式(例如(+ 1 2)
或(let ([x 3] [y 4]) (make-list x y))
)时,此方法有效。但是,当e
表单可以是定义时,它将不起作用。
#%module-begin
中获得扩展版本支持在这些模块级定义中使用local-expand
的一种方法是在扩展前将其包装为球拍的#%module-begin
形式。这样一来,它就可以在一次调用local-expand
的情况下一起处理所有e
s 。
(define-simple-macro (my-module-begin e ...)
; get the expanded versions by calling that function on a
; *constructed* module-begin form
#:with (_ e-expanded ...) (local-expand #'(#%module-begin e ...) 'module-begin '())
; use the expanded versions inside foo
(#%module-begin
e-expanded ...
(foo e-expanded ...)))
这使Racket的#%module-begin
处理定义,完成后,您可以使用(_ e-expanded ...)
对其进行模式匹配。