Racket Macro如何将Ellipses传递给Helper功能?

时间:2013-01-15 01:13:40

标签: macros racket ellipsis

假设:

(define-syntax (test stx)
  (syntax-case stx ()
    [(_ body ...)
     (with-syntax ([body0 (process-body #'(body ...))])
       #'body0)]))

我应该如何在助手中收到模式和省略号?我甚至不确定是否包裹身体......内部()是正确的,但我已经看到它并且它是唯一不会崩溃的东西。

process-body过程最终会使用包含extra()的语法。我可以尝试将其分开,但我只是想知道这样做的正确方法是什么。

process-body在之前和之后使用一些代码包装正文模式。而且,与define类似,我希望能够在一个列表中为宏提供多个表单而不是所有表单。因此,如果给定(form1)(form2),其中form2是省略号,则process-body应该(do-something)(form1)(form2)(do-something-else)。

(define-for-syntax (process-body body-syntax)
  (with-syntax ([stx body-syntax])
    (syntax/loc body-syntax
      (λ (request)
         stx))))

当然,当我在线定义模板时,我有这个工作,我想我可以在这里做,但有时模板变得笨拙,并且调用帮助器很好。

非常感谢。

作为尝试dyoo的第一个例子的编辑,我提供以下内容:

#lang racket

(define-syntax (test2 stx)
  (syntax-case stx ()
    [(_ body ...)
     (with-syntax ([(body0 ...) (process-body2 #'(body ...))])
       #'(begin body0 ...))]))

(define-for-syntax (process-body2 bodies)
  (with-syntax ([(body ...) bodies])
    (syntax/loc bodies
      (λ (request)
         body ...))))

(test2 (print "hi"))
  
    

λ:语法错误

  

1 个答案:

答案 0 :(得分:4)

with-syntax图案的左侧也可以有椭圆,以便可以使用以下内容:

(define-syntax (test stx)
  (syntax-case stx ()
    [(_ body ...)
     (with-syntax ([(body0 ...) (process-body #'(body ...))])
       #'(begin body0 ...))]))

基本思想是,如果process-body返回已转换的正文元素,我们就可以将它们与begin一起引入。


您的process-body定义也可以使用带有省略号的with-syntax。所以你可以这样做:

(define-for-syntax (process-body bodies)
  (with-syntax ([(body ...) bodies])
    (syntax/loc bodies
      (λ (request)
         body ...))))

如果这是process-body的定义,我们应该修改test,因为process-body的结果形状现在是一个完整的lambda表达式,所以我们可以直接返回它的结果:

(define-syntax (test stx)
  (syntax-case stx ()
    [(_ body ...)
     (process-body (syntax/loc stx (body ...)))]))

作为一个独立的例子:

#lang racket

(define-syntax (test stx)
  (syntax-case stx ()
    [(_ body ...)
     (process-body 
      (syntax/loc stx (body ...)))]))

(define-for-syntax (process-body bodies)
  (with-syntax ([(body ...) bodies])
    (syntax/loc bodies
      (λ (request)
        (printf "before the body\n")
        body ...
        (printf "after the body\n")))))


;; Let's try it:    
(define p 
  (test (displayln "hello") (displayln "world")))

(p 'should-be-a-request)