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 forms
  • begin 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

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -