【问题标题】:How to 'require' a Racket module that doesn't have a #lang header line?如何“要求”没有#lang 标题行的 Racket 模块?
【发布时间】:2019-05-18 08:34:45
【问题描述】:

作为许多可能的示例之一,break-example.rkt 将是一个完全有效的 Java 程序,但 Racket 需要的 #lang mini-java 标头除外。

例如如果我在 Racket 中编写了 Java 解释器/编译器作为 Racket 模块语言,我怎么能说,“require 这个文件 Main.java 是用模块语言 mini-java 编写的,但没有任何特定于 Racket标题”?

(请注意,我对 Racket 的实践经验几乎为零。我正在针对 Racket + DrRacket 的特定用例对此进行评估,顺便说一下,这与 Java 无关。我搜索了文档,但是找不到任何方法来实现这一点。)

【问题讨论】:

  • include/reader 表单可能对您有所帮助;我现在无法尝试,但也许你可以尝试一下
  • @AlexKnauth 试图让你的答案发挥作用,在搜索过程中,我发现groups.google.com/d/msg/racket-users/ECtWwJ7ti60/zB2UVQFCKAAJ 提出了基本相同的问题。
  • 似乎正在使用动态机制在运行时使用eval-syntaxdynamic-require 读取、编译和评估mini-java。这会评估它是否将其放入命名空间,但如果 mini-java 程序提供标识符,则这些标识符在文件的其余部分将不可用,就像您使用 (require racket/list) 时一样。 include/reader 表单将在编译时读取和编译 mini-java,并使其提供的任何标识符可用于所需文件

标签: racket


【解决方案1】:

我现在无法运行或测试它,但也许您可以从这里开始并进行试验。它使用的主要是include/reader

#lang racket
(require racket/include
         syntax/parse/define
         (for-syntax racket/syntax
                     racket/port
                     syntax/modread))

(define-simple-macro (require/mini-java path)
  #:with modname (generate-temporary #'path)
  (begin
    (include/reader path (mini-java-reader 'modname))
    (require 'modname)))

(begin-for-syntax
  ;; Symbol -> [Any InputPort -> Syntax]
  (define ((mini-java-reader modname) src input)
    (cond
      [(port-closed? input) eof]
      [else
       (define stx
         (with-module-reading-parameterization
           (lambda ()
             (read-syntax src
               (input-port-append #t
                 (open-input-string "#lang mini-java\n")
                 input)))))
       (close-input-port input)
       (syntax-parse stx
         [(module _ l . b)
          #`(module #,modname l . b)])])))

【讨论】:

  • 谢谢!似乎在正确的轨道上,但还不能让它工作,我收到错误“include/reader: read error (read: #lang not enabled in the current context)”。这是否与read-accept-reader 参数有关?我尝试在几个地方使用(parameterize ([read-accept-reader #t]) ...something...),但这似乎并没有使它起作用......
  • with-module-reading-parameterization 的调用应该在其 thunk 的主体中将 read-accept-reader 参数设置为 true,并且在该主体中对 read-syntax 的调用是应该需要的......除非有另一个调用读者的上下文
  • 我没有专门用#lang mini-java 测试过,但我只是用#lang sweet-exp racket 测试过,发现了一个无限循环错误,我刚刚在编辑中修复了它。它现在适用于那种语言......我不确定#lang mini-java 可能有什么不同,你能告诉我任何相关的信息吗?
  • mini-java 只是一个例子。我试图让你的示例代码与#lang sweet-exp racket 一起工作,但这仍然会产生同样的错误。我的源代码:gist.github.com/marnix/55361d56e67692ab32696abc80229f1d (rev 1)。
  • 我正在使用 DrRacket 版本 6.11 [3m](在 Linux 上),而我只看到最新版本是 7.2。这可能是一个 6 对 7 的问题吗? [我将尝试使用 7.2,并在那里尝试上面的代码。]
猜你喜欢
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
  • 2016-01-24
  • 2015-11-18
  • 1970-01-01
  • 2018-02-26
  • 2021-05-31
相关资源
最近更新 更多