racket - How to maintain define functionality with custom #%module-begin? -
i want strings produced custom language, example display them. i've created module-begin this:
(define-syntax (module-begin stx) (syntax-case stx () [(_ expr ...) #'(display (apply string-append (filter string? (list expr ...))))]))
however, prevents me using define in language. error "define: not allowed in expression context".
how can grab strings without losing ability use define , other top-level expressions? need grab define's beforehand , move them beginning?
the short answer
use make-wrapping-module-begin
hard work you.
(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)]))
change wrap-expression
whatever want expressions. isn't applied definitions, require
forms, etc. note module-body expressions 1 @ time, not @ once.
the long answer
you not have power register module-level definitions, interpret require
forms, etc. macro expander , primitive #%plain-module-begin
form can that. module-begin
macro has cooperate them.
your macro must use local-expand
partially expand each module-level form can distinguish between following:
- module-level definitions
require
,provide
formsbegin
sequences, need spliced module body- expressions
when definition or require
or provide
form, toss real #%plain-module-begin
primitive. expressions handle; again, like. , begin
forms, recur on sub-forms. code looks this:
(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)]))
all new code make-wrapping-module-begin
doing automatically.
Comments
Post a Comment