gpt4 book ai didi

racket - 如何使用自定义#%module-begin 维护定义功能?

转载 作者:行者123 更新时间:2023-12-04 09:13:12 26 4
gpt4 key购买 nike

我想对我的自定义语言生成的字符串做一些事情,例如显示它们。我创建了一个类似这样的模块开始:

(define-syntax (module-begin stx)
(syntax-case stx ()
[(_ EXPR ...)
#'(display (apply string-append (filter string? (list EXPR ...))))]))

但是,这使我无法在语言中使用定义。我收到错误“定义:在表达式上下文中不允许”。

如何在不失去使用 define 和其他顶级表达式的能力的情况下获取字符串?我是否需要事先获取所有定义并将它们移到开头?

最佳答案

简短的回答

使用make-wrapping-module-begin为你做艰苦的工作。

(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请注意,您一次获得一个模块主体表达式,而不是一次获得所有表达式。

长答案

您无权注册模块级定义,请解释 require形式等。只有宏扩展器和原语 #%plain-module-begin表格可以做到这一点。所以你的 module-begin宏必须与他们合作。

您的宏必须使用 local-expand部分扩展每个模块级别的表单,以便您可以区分以下内容:
  • 模块级定义
  • requireprovide表格
  • begin序列,需要拼接到模块体
  • 表达式

  • 当你得到一个定义或 requireprovide表格,你只要把它扔给真正的 #%plain-module-begin原始。您处理的表达式;再一次,无论你喜欢什么。对于 begin表格,您在子表格上重复出现。代码看起来像这样:
    (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)]))

    所有的新代码基本上都是 make-wrapping-module-begin正在自动为你做。

    关于racket - 如何使用自定义#%module-begin 维护定义功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45786187/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com