使用`include / reader`

时间:2016-02-18 07:59:14

标签: macros include racket scribble

编辑:我已经确定了问题,并且我找到了一种解决方法(最后请参见更新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->namespaceinclude/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

然而,这感觉很笨 - 我希望有人可以告诉我这样做的“正确”方法。

0 个答案:

没有答案