在 Racket 中重新绑定名称 `module`
Rebinding the name `module` in Racket
我想让 Racket 评估 .kicad_mod 文件的语法,这些文件是以下形式的 s 表达式数据:
(module LED-10MM (layer F.Cu) (tedit 55BDE3C5)
(descr "LED 10mm")
...)
我希望能够混合使用 Racket 和 "kicad_mod" 语法,所以我试图重新定义 module
函数。作为开始,我尝试了:
;kicad_mod.rkt
#lang racket
(provide
(except-out (all-from-out racket) #%module-begin module)
(rename-out [module-begin #%module-begin]))
(define kicad_module "you got me")
(define-syntax-rule (module-begin expr ...)
(#%module-begin
(provide (rename-out [kicad_module module]))))
以及在加载端最终起作用的方法(虽然不是在 drracket 中,而是直接使用球拍解释器):
;main.rkt
#lang racket
(module kicad_mod "kicad_mod.rkt")
(require 'kicad_mod)
(println module)
; => "you got me"
但是,如果我尝试任何其他方式,它都会失败:
1.
;main.rkt
#lang racket
(require "kicad_mod.rkt")`
导致错误:
main.rkt:3:9: module: bad syntax
in: module
context...:
standard-module-name-resolver
2.
;main.rkt
#lang s-exp "kicad_mod.rkt"
(println module)
导致标准输出无输出
这不是答案,但我不能在评论中写代码。
这看起来很奇怪 - 表达式不应该在输出中吗?
(define-syntax-rule (module-begin expr ...)
(#%module-begin
(provide (rename-out [kicad_module module]))))
也许
(define-syntax-rule (module-begin expr ...)
(#%module-begin
(provide (rename-out [kicad_module module]))
expr ...))
或
(define-syntax-rule (module-begin expr ...)
(#%module-begin
(provide (rename-out [kicad_module module]))
'expr ...))
?
尽管这不是完整的答案。
我所做的事情没有多大意义,因为我不理解 #%module-begin
重新定义以及在什么上下文中调用代码。
如果您修改 kicad_mod.rkt
以包含像 soegaard 建议的引用表达式:
(define-syntax-rule (module-begin expr ...)
(#%module-begin
(provide (rename-out [kicad_module module]))
'expr ...))
并拥有:
;main.rkt
#lang s-exp "kicad_mod.rkt"
(println module)
你实际上在 stdout 上得到了 '(println module)
的输出。所以 (provide (rename-out...
是在模块的上下文中使用我们的新语言调用的,就在表达式之前执行(如果你像 soegaard 最初的建议那样从 expr
中删除引号)。
我真正想要的是在那之前重新定义module
,同时我正在重新定义#%module-begin
:
;kicad_mod.rkt
#lang racket
(provide
(except-out (all-from-out racket) #%module-begin module)
(rename-out [module-begin #%module-begin])
(rename-out [kicad_module module]))
(define kicad_module "you got me")
(define-syntax-rule (module-begin expr ...)
(#%module-begin
expr ...))
这将与上面使用 #lang s-exp
的 main.rkt
一起正常工作。您仍然需要 #%module-begin
绑定,尽管如果您想使用 #lang s-exp
,此时它什么都不做。无论如何它以后都会派上用场的,我相信。
我想让 Racket 评估 .kicad_mod 文件的语法,这些文件是以下形式的 s 表达式数据:
(module LED-10MM (layer F.Cu) (tedit 55BDE3C5)
(descr "LED 10mm")
...)
我希望能够混合使用 Racket 和 "kicad_mod" 语法,所以我试图重新定义 module
函数。作为开始,我尝试了:
;kicad_mod.rkt
#lang racket
(provide
(except-out (all-from-out racket) #%module-begin module)
(rename-out [module-begin #%module-begin]))
(define kicad_module "you got me")
(define-syntax-rule (module-begin expr ...)
(#%module-begin
(provide (rename-out [kicad_module module]))))
以及在加载端最终起作用的方法(虽然不是在 drracket 中,而是直接使用球拍解释器):
;main.rkt
#lang racket
(module kicad_mod "kicad_mod.rkt")
(require 'kicad_mod)
(println module)
; => "you got me"
但是,如果我尝试任何其他方式,它都会失败:
1.
;main.rkt
#lang racket
(require "kicad_mod.rkt")`
导致错误:
main.rkt:3:9: module: bad syntax
in: module
context...:
standard-module-name-resolver
2.
;main.rkt
#lang s-exp "kicad_mod.rkt"
(println module)
导致标准输出无输出
这不是答案,但我不能在评论中写代码。
这看起来很奇怪 - 表达式不应该在输出中吗?
(define-syntax-rule (module-begin expr ...)
(#%module-begin
(provide (rename-out [kicad_module module]))))
也许
(define-syntax-rule (module-begin expr ...)
(#%module-begin
(provide (rename-out [kicad_module module]))
expr ...))
或
(define-syntax-rule (module-begin expr ...)
(#%module-begin
(provide (rename-out [kicad_module module]))
'expr ...))
?
我所做的事情没有多大意义,因为我不理解 #%module-begin
重新定义以及在什么上下文中调用代码。
如果您修改 kicad_mod.rkt
以包含像 soegaard 建议的引用表达式:
(define-syntax-rule (module-begin expr ...)
(#%module-begin
(provide (rename-out [kicad_module module]))
'expr ...))
并拥有:
;main.rkt
#lang s-exp "kicad_mod.rkt"
(println module)
你实际上在 stdout 上得到了 '(println module)
的输出。所以 (provide (rename-out...
是在模块的上下文中使用我们的新语言调用的,就在表达式之前执行(如果你像 soegaard 最初的建议那样从 expr
中删除引号)。
我真正想要的是在那之前重新定义module
,同时我正在重新定义#%module-begin
:
;kicad_mod.rkt
#lang racket
(provide
(except-out (all-from-out racket) #%module-begin module)
(rename-out [module-begin #%module-begin])
(rename-out [kicad_module module]))
(define kicad_module "you got me")
(define-syntax-rule (module-begin expr ...)
(#%module-begin
expr ...))
这将与上面使用 #lang s-exp
的 main.rkt
一起正常工作。您仍然需要 #%module-begin
绑定,尽管如果您想使用 #lang s-exp
,此时它什么都不做。无论如何它以后都会派上用场的,我相信。