Racket 如何告诉“makemoduleevaluator”使用像#lang那样的定制阅读器?
我试图在给定的字符串(而不是文件)上执行定制的#lang。我们把它叫做花椰菜 安装程序 我的语言定义如下: 西兰花/main.rktRacket 如何告诉“makemoduleevaluator”使用像#lang那样的定制阅读器?,racket,Racket,我试图在给定的字符串(而不是文件)上执行定制的#lang。我们把它叫做花椰菜 安装程序 我的语言定义如下: 西兰花/main.rkt (模块读卡器支架/底座 (需要花椰菜/私人/阅读器) (提供读语法));基本上是一个复制品 西兰花/private/reader.rkt (提供 (改名为 [我的阅读] [我的读取语法读取语法]) (定义(我的读入) (语法->基准 (我的阅读语法#f in))) (定义(我的读取语法src in) (使用语法([parse tree(parse src(mak
(模块读卡器支架/底座
(需要花椰菜/私人/阅读器)
(提供读语法));基本上是一个复制品
西兰花/private/reader.rkt
(提供
(改名为
[我的阅读]
[我的读取语法读取语法])
(定义(我的读入)
(语法->基准
(我的阅读语法#f in)))
(定义(我的读取语法src in)
(使用语法([parse tree(parse src(make tokenizer in src)));吹牛
(上下文)
#(模块程序西兰花/专用/扩展器)
(解析树)
西兰花/private/expander.rkt
(提供
(重命名为[module begin#%module begin]))
(定义语法规则(模块begin expr)
(#%模块开始
(提供膳食)
(定义膳食(转换表达));某种计算
它以经典的方式工作得相当好:
花椰菜
你好,世界!
将产生:
(模块程序西兰花/专用/扩展器
(节目
(句子(单词“Hello”)(单词“world”))
然后将扩展到:
(提供膳食)
(定义膳食(清单42-38));结果是为了这个例子,不要介意
但我试图将其应用于从网络请求中获取的任意字符串,并将结果发送回。
这一次,情况变得更复杂了。
以下是我尝试过的:
试试看
(定义文本“Hello world!”)
(定义评估员(制作评估员的花椰菜文本);错误:找不到#%
(评估员餐)
试试看
(定义文本“Hello world!”)
(定义模块(花椰菜阅读语法#f(打开输入字符串文本)))
(定义计算器(使模块计算器#:语言“花椰菜/专用/扩展模块”)
(评估员餐);错误:未定义膳食
试试看
(定义文本“Hello world!”)
(定义计算器(生成模块计算器(字符串附加“#lang brocoli”文本)))
(评估员餐);错误:未定义膳食
试试第四种(它有效,但不是我想要的)
(定义文本“Hello world!”)
(定义模块(花椰菜阅读语法#f(打开输入字符串文本)))
(定义ns(生成基本命名空间))
(评估模块ns)
(命名空间需要“”程序ns)
(定义结果(评估结果))
最后一个结果工作正常,但它不使用沙箱,而是直接使用eval
。我确信有更好的方法,但我不知道出了什么问题。我建议使用
read lang module
将字符串转换为表示模块的语法对象。然后使用生成模块求值器
我非常接近
我必须要求在evaluator中生成模块(这意味着从扩展器中提供#%app
,#%top
,#%top交互
,要求
和引用
)
(定义计算器(生成模块计算器(字符串附加“#lang brocoli\n”文本)))
(评估者’(要求“项目”);缺步
(评估员餐)
我发现这个解决方案的奇怪之处在于,它的行为与文档中所述的不同:
>(定义基本模块评估
(制作模块评估器’(模块m球拍/底座
(稍后定义(f)
(稍后定义5)))
>(稍后评估基本模块)
5.