编辑:我已经确定了问题,并且我找到了一种解决方法(最后请参见更新2),但似乎应该有一种更有效的方法 - 我希望有人能想出一个。
我尝试使用我使用Racket / Scribble的make-at-reader作为 reader-expr 为include/reader
或{{1>生成的函数时遇到了麻烦(来自racket/include),我希望有人可以解释我做错了什么。
我使用了include-at/relative-to/reader
的一些参数来定义@ -forms(基本上是模板系统)的用法,基本上是这样的:
make-at-reader
我可以在(define cmd-readtable
(make-readtable #f #f 'non-terminating-macro <<myExtensionProcHere>>))
(define at-template-reader
(make-at-reader #:syntax? #t
#:inside? #t
#:command-char #\ƒ
#:command-readtable cmd-readtable
#:syntax-post-processor <<myFunctionHere>>))
的运行时使用,即使不是超级优雅也能正常工作。例如,如果我这样做,
call-with-input-file
我得到类似的东西,
((lambda (stx)
(syntax-case stx ()
[(a ...)
#'(string-append a ...)]))
(syntax->list
(call-with-input-file
"/path/to/my/file"
(lambda (in)
(at-template-reader 'test in)))))
使用'(string-append "string foo"
"\n"
(expression "bar")
"string baz")
和eval
进行评估。显而易见,所有语法对象都对应于文字字符串或计算字符串的表达式;但是,外部文件中的表达式需要访问模块上下文中的参数和其他一些定义。
但是,我更喜欢使用的是namespace-anchor->namespace
或include/reader
(可能更类似于web-server/templates中的include-at/relative-to/reader
),以便进行口译工作外部文件可以在编译时完成。但是,我试图在其中一种形式中使用我的include/template
已经完全不成功:更糟糕的是,它们只是在内存耗尽之前没有结果运行,所以我甚至不确定如何调试它们。我想我在这里有点过头了,我很欣赏任何人关于如何使这个工作的想法。
更新1: Asumu Takikawa在评论中询问是否与at-template-reader
一起使用。我现在已经尝试过了,而且它确实 - 或者更接近于使用#:inside? #f
更近似的工作,在我杀死它或者内存耗尽之前,它只是永远不会落地。 #:inside? #t
版本成功并返回值。 (它确实表现得很奇怪,我已经定义了一些逻辑,有时只返回最后一个值,但我想这可能是因为我做了一些假设只适用于#:inside? #f
- 模式;我正在寻找现在进入那个。)
这是否让任何人都知道#:inside? #t
版本可能出现的问题?我想知道它是否可能与#:inside? #t
的事实有关,它只返回一个表示整个外部文件的语法对象......
更新2:
我已经确定了问题,而且我现在有一个非常黑客的解决方法,但我希望有人可以向我解释正确的方法是做什么的。
首先,让我给出我在Asumu Takikawa的建议中尝试的#:inside? #t
函数的名称,以便我可以简洁地参考它:
#:inside? #f
我正在调用(define at-template-reader-OUTSIDE
(make-at-reader #:syntax? #t
#:inside? #f
#:command-char #\ƒ
#:command-readtable cmd-readtable
#:syntax-post-processor <<myFunctionHere>>))
和read-syntax
的{{1}}类功能之间存在重大差异,我通过玩at-template-reader
docs发现了这些功能(“返回一个列表,其元素是通过在at-template-reader-OUTSIDE
上调用(port->list [r in])
生成的,直到它生成eof”)。每次调用r
都会产生一个与源文件的下一个块相对应的语法对象,如预期的那样,直到最后一个产生in
。但是,每次调用at-template-reader-OUTSIDE
都会产生一个与整个源文件相对应的语法对象,并且永远不会产生eof
- 在第一次调用之后只返回空列表(作为语法对象)。这意味着呼叫at-template-reader
- 似乎eof
和朋友 - 永远不会回来。
我通过使用包装函数来实现这一点,如下所示:(在一个模块中,一切都处于正确的相位级别)
port->list
然而,这感觉很笨 - 我希望有人可以告诉我这样做的“正确”方法。