如何编写维护本地状态的宏?
这似乎有效,它是一个宏,根据扩展的次数扩展为连续的整数。
;; Library (test macro-state)
(library
(test macro-state)
(export get-count incr-count)
(import (rnrs))
(define *count* 0)
(define (get-count) *count*)
(define (incr-count) (set! *count* (+ *count* 1)))
)
;; Program
(import (rnrs) (for (test macro-state) expand))
(define-syntax m
(lambda (x)
(syntax-case x ()
((m) (begin (incr-count) (datum->syntax #'m (get-count)))))))
(write (list (m) (m) (m)))
(newline)
;; prints (1 2 3)
但这对我来说很笨拙,因为宏状态 *count*
和宏 m
本身位于不同的模块中。在 r6rs 中是否有更好的方法来执行此操作,最好是不将实现拆分为两个模块的方法?
编辑
我应该明确指出,虽然这个示例只是一个宏,但实际上我正在寻找一种在多个宏需要共享状态时有效的方法。
This seems to work, it's a macro that expands to successive integers depending on how many times it has been expanded.
;; Library (test macro-state)
(library
(test macro-state)
(export get-count incr-count)
(import (rnrs))
(define *count* 0)
(define (get-count) *count*)
(define (incr-count) (set! *count* (+ *count* 1)))
)
;; Program
(import (rnrs) (for (test macro-state) expand))
(define-syntax m
(lambda (x)
(syntax-case x ()
((m) (begin (incr-count) (datum->syntax #'m (get-count)))))))
(write (list (m) (m) (m)))
(newline)
;; prints (1 2 3)
But it's clumsy to me because the macro state *count*
and the macro m
itself are in different modules. Is there a better way to do this in r6rs, preferably one that doesn't split the implementation over two modules?
EDIT
I should make it clear that although this example is just a single macro, in reality I'm looking for a method that works when multiple macros need to share state.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以将状态设置为宏转换器的本地状态:
编辑添加:在Racket中,你也可以这样做:
但我不认为 R6RS 有任何与
begin-for-syntax
相对应的东西。You can make the state local to the macro transformer:
Edited to add: In Racket, you can also do this:
But I don't think R6RS has anything that corresponds to
begin-for-syntax
.