Hello!

This is a follow-up to the excellent answer by Alex Knauth on StackOverflow 
here: http://stackoverflow.com/a/38032107/324969 and this mailing-list thread: 
https://groups.google.com/forum/#!topic/racket-users/sS-pUUGp9o4

I'm trying to write a module meta-language mylang, which accepts a second 
language to which is passes the modified body, such that:

(module foo mylang typed/racket body)

is equivalent to:

(module foo typed/racket transformed-body)

The real-world goal is to transform the fully-expanded body (e.g. add a 
submodule, like the "doc" module added by scribble/lp2).

Alex came up with the implementation below. It puts the body into a dummy 
module, fully expands it, and extracts the (#%plain-module-begin . mod-body), 
patching it to require the user-provided lang. This works very well in all 
cases except when the body contains submodules.

In that case, I get an "require: namespace mismatch; reference to a module that 
is not available" error.

I'm rather clueless about how to solve that problem. I tried using local-expand 
with a 'module-begin context, but it then complains that x is unbound when the 
user-supplied language is typed/racket, and the error seems to be related to 
the submodules generated by TR.

Any suggestions?
Georges Dupéron




#lang racket

;; The language definition
(module mylang racket
  (provide (rename-out [-#%module-begin #%module-begin]))
  (define-syntax (-#%module-begin stx)
    (syntax-case stx ()
      [(_ lng . rest)
       (with-syntax ([#%module-begin (datum->syntax #f '#%module-begin)])
         ;; put the code in a module form, and fully expand that module
         (define mod-stx
           (local-expand
            #'(module ignored lng (#%module-begin . rest))
            'top-level
            (list)))
         ;; pattern-match on the #%plain-module-begin form to insert a require
         (syntax-case mod-stx (module #%plain-module-begin)
           [(module _ lng (#%plain-module-begin . mod-body))
            #`(#%plain-module-begin
                (#%require lng)
                .
                #,((make-syntax-introducer) #'mod-body))]))])))

;; A module using that language
(module foo (submod ".." mylang) typed/racket/base
  (module a-submod typed/racket/base
    (define x 1)
    (provide x))
  (require 'a-submod)
  (ann (+ x 1) Number))
(require 'foo)

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to