Racket 如何使用自定义#%模块开始维护定义功能?
我想用我的自定义语言生成的字符串做一些事情,例如显示它们。我创建了一个模块,开始如下操作:Racket 如何使用自定义#%模块开始维护定义功能?,racket,Racket,我想用我的自定义语言生成的字符串做一些事情,例如显示它们。我创建了一个模块,开始如下操作: (define-syntax (module-begin stx) (syntax-case stx () [(_ EXPR ...) #'(display (apply string-append (filter string? (list EXPR ...))))])) (define-syntax (module-begin stx) (syntax-case stx (
(define-syntax (module-begin stx)
(syntax-case stx ()
[(_ EXPR ...)
#'(display (apply string-append (filter string? (list EXPR ...))))]))
(define-syntax (module-begin stx)
(syntax-case stx ()
[(_ form ...)
#'(#%plain-module-begin (wrap-module-form form) ...)]))
(define-syntax (wrap-module-form stx)
(syntax-case stx ()
[(_ form)
(let ([e-form (local-expand #'form 'module #f)])
(syntax-case e-form (begin define-syntaxes define-values #%require #%provide)
[(define-syntaxes . _)
e-form]
[(define-values . _)
e-form]
[(#%require . _)
e-form]
[(#%provide . _)
e-form]
[(begin inner-form ...)
#'(begin (wrap-module-form inner-form) ...)]
[expr
#'(wrap-expression expr)]))]))
(define-syntax (wrap-expression stx)
(syntax-case stx ()
[(_ expr) #'(println expr)]))
但是,这阻止我在语言中使用define。我得到错误“define:表达式上下文中不允许”
如何在不失去使用define和其他顶级表达式的能力的情况下获取字符串?我是否需要事先获取所有定义并将其移到开头?简短答案
使用开始包装模块
为您完成这项艰巨的工作
(require syntax/wrap-modbeg)
(define-syntax module-begin (make-wrapping-module-begin #'wrap-expression))
(define-syntax (wrap-expression stx)
(syntax-case stx ()
[(_ expr) #'(println expr)]))
更改wrap expression
以对表达式执行任何操作。它不适用于定义、require
forms等。请注意,一次只能得到一个模块体表达式,而不是一次得到所有表达式
长话短说
您无权注册模块级定义、解释require
表单等。只有宏扩展器和原语\%plain module begin
表单才能执行此操作。因此,您的模块begin
宏必须与它们配合
宏必须使用local expand
部分展开每个模块级窗体,以便区分以下各项:
- 模块级定义
和要求
表格提供
序列,需要拼接到模块主体中开始
- 表情
require
或provide
表单时,您只需将其扔到真正的#%plain模块begin
原语。你处理的表达方式;再说一遍,不管你喜欢什么。对于begin
表单,您的重复出现在子表单上。代码如下所示:
(define-syntax (module-begin stx)
(syntax-case stx ()
[(_ EXPR ...)
#'(display (apply string-append (filter string? (list EXPR ...))))]))
(define-syntax (module-begin stx)
(syntax-case stx ()
[(_ form ...)
#'(#%plain-module-begin (wrap-module-form form) ...)]))
(define-syntax (wrap-module-form stx)
(syntax-case stx ()
[(_ form)
(let ([e-form (local-expand #'form 'module #f)])
(syntax-case e-form (begin define-syntaxes define-values #%require #%provide)
[(define-syntaxes . _)
e-form]
[(define-values . _)
e-form]
[(#%require . _)
e-form]
[(#%provide . _)
e-form]
[(begin inner-form ...)
#'(begin (wrap-module-form inner-form) ...)]
[expr
#'(wrap-expression expr)]))]))
(define-syntax (wrap-expression stx)
(syntax-case stx ()
[(_ expr) #'(println expr)]))
所有新代码基本上都是
使包装模块开始
自动为您所做的。感谢您提供了详细而全面的答案。我有一个后续问题,尽管这表明了我的无知。如何根据我的问题将表达式包装到列表中?正如您所说,wrap extension宏一次只能处理一个表达式。