[plt-scheme] inexpressible module imports
At Sun, 9 Nov 2008 09:55:11 -0500, Dave Herman wrote:
> Since we called syntax->datum, we need to call `syntax-local-
> introduce' on any variables that come from the input, so that any
> introduced references won't be captured.
I recommend that you instead use the context of the original
`#%module-begin' expression with `datum->syntax', as in the code below,
instead of trying to recreate that context via
`syntax-local-introduce'.
> But I can't come up with any plausible combination of arguments to
> `datum->syntax' and insertions of `syntax-local-introduce' into the
> compiler to get that reference to `newline' to refer to the imported
> name. [...] Is
> there something secret about module-imports?
I think there's probably a bug here related to module imports ---
probably because the module context of the identifiers in question has
been stripped away, and yet the identifiers don't have any marks that
suggest that they were macro-introduced (since the
`syntax-local-introduce' cancels a later mark). So, I'll look into that
more.
Meanwhile, I think the approach below will work better in general. I
also wonder why you're stripping away all the lexical context up front,
so that you have to recreate it later. Why not build the compiler
around syntax objects, which not only help you track context but also
help track source locations?
----------------------------------------
;; module.ss
#lang scheme/base
(require (for-syntax scheme/base)
(for-syntax "compile.ss"))
(define-syntax (module-begin stx)
(syntax-case stx ()
[(_ import definition expression)
(with-syntax ([program (compile-program stx
(syntax->datum #'import)
(syntax->datum #'definition)
(syntax->datum #'expression))])
#'(#%plain-module-begin program))]))
(provide (except-out (all-from-out scheme/base) #%module-begin)
(rename-out [module-begin #%module-begin]))
----------------------------------------
;; compile.ss
#lang scheme/base
(require scheme/match)
(require (for-template scheme/base))
(provide compile-program)
(define (compile-program ctx import definition reference)
#`(begin
#,(compile-import ctx import)
#,(compile-definition ctx definition)
(print #,(compile-reference ctx reference))
(newline)))
(define (compile-import ctx import)
(match import
[(list 'import mod (list (? symbol? external) (? symbol? internal)))
(let ([external-id (datum->syntax #'here external)]
[internal-id (datum->syntax ctx internal)])
#`(require (rename-in #,mod [#,external-id #,internal-id])))]))
(define (compile-definition ctx definition)
(match definition
[(list 'define (? symbol? x) (? number? n))
(let ([id (datum->syntax ctx x)])
#`(define #,id #,n))]))
(define (compile-reference ctx reference)
(datum->syntax ctx reference))