如何捕获展开的表格?

时间:2018-08-17 16:10:06

标签: racket

我正试图通过定义自己的module-begin来捕获扩展形式:

(define-syntax-rule (my-module-begin e ...)
  (#%module-begin            
   e ...
  (foo e ...)))

我是否纠正foo的原始格式?如果是这样,foo是否可以获取扩展的表单?

1 个答案:

答案 0 :(得分:2)

要获取展开的表格,您需要以某种方式使用local-expand

第1部分,不完整的解决方案

您可能会考虑在每个这样的表达式上分别调用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表单可以是定义时,它将不起作用。

第2部分,从Racket的#%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 ...)对其进行模式匹配。