1

我想制作一个帮助宏来编写匹配扩展。我有这样的事情:

(define-match-expander my-expander
  (λ (stx)
    (let* ([dat (cdr (syntax-e stx))]
           [var1 (car dat))]
           [var2 (cadr dat)])
      ;transformer goes here )))

所以我想要一个宏来做这个让绑定。我从这样的事情开始:

(define-syntax-rule (define-my-expander (id vars ...) body)
  (define-match-expander id
    (λ (stx)
      (match-let ([(vars ...) (cdr (syntax-e stx))])
        body))))

但未match-let在转换时间中定义。

第一个问题是有没有其他方法可以做到这一点(我的意思是制作这个扩展器)?也许 plt-scheme 中已经有类似的东西我不知道,或者我在某种程度上做错了。

不管第一个问题的答案如何,如果我想将变量列表绑定到宏内的值列表,我应该怎么做?

编辑:结合 Eli 的答案宏现在看起来像这样:

(define-syntax-rule (define-my-expander (id vars ...) body)
  (define-match-expander id
    (λ (stx)
      (syntax-case stx ()
        [(_ vars ...)
         body]))))
4

1 回答 1

4

我不知道你想要达到什么目标,但我猜这是朝着正确的方向发展:

(define-match-expander my-expander
  (lambda (stx)
    (syntax-case stx ()
      [(_ (var1 var2) stuff ...)
       ;; use #'var1 #'var2 and #'(stuff ...) here
       ])))

事情是syntax-e用来“解包”一个语法对象并给你它所拥有的东西——但实际的内容可能会让你感到惊讶。例如,(foo . (bar))将具有与 . 稍有不同的内容(foo bar)。所以一般来说,syntax-case用来为你做模式匹配要容易得多。除了更容易之外,它还会在出现错误时给出一些合理的错误消息,而不是你的代码。

于 2010-01-12T21:01:08.813 回答