#lang scheme/base
(require (planet bzlib/base)
"resolve.ss"
(for-template scheme/base)
syntax/stx
)
(define (require-unify stx)
(define (resolve spec)
(syntax-case spec (only-in
except-in
prefix-in
rename-in
combine-in
only-meta-in
for-syntax
for-template
for-label
for-meta
lib
planet
file
)
((only-in inner in ...)
#`(only-in #,(resolve #'inner) in ...))
((except-in inner in ...)
#`(except-in #,(resolve #'inner) in ...))
((prefix-in prefix inner)
#`(prefix-in prefix #,(resolve #'inner)))
((rename-in inner in ...)
#`(rename-in #,(resolve #'inner) in ...))
((combine-in inner ...)
#`(combine-in #,@(syntax-map resolve #'(inner ...))))
((only-meta-in phase inner ...)
#`(only-meta-in phase #,@(syntax-map resolve #'(inner ...))))
((for-syntax inner ...)
#`(for-syntax #,@(syntax-map resolve #'(inner ...))))
((for-template inner ...)
#`(for-template #,@(syntax-map resolve #'(inner ...))))
((for-label inner ...)
#`(for-label #,@(syntax-map resolve #'(inner ...))))
((for-meta phase inner ...)
#`(for-meta phase #,@(syntax-map resolve #'(inner ...))))
((lib str ...)
(raise-syntax-error 'require "lib is deprecated." #'(lib str ...)))
((file str)
(raise-syntax-error 'require "file is deprecated." #'(file str)))
((planet spec ...)
(raise-syntax-error 'require "planet is deprecated." #'(planet spec ...)))
(mod-path
(resolve-module-path (syntax->datum #'mod-path))
#'mod-path)
(mod-path
(datum->syntax stx
(list (datum->syntax stx 'planet) #'mod-path)))))
(syntax-case stx ()
((~ spec ...)
(datum->syntax stx (cons (datum->syntax stx 'require)
(syntax-map resolve #'(spec ...)))))
))
(define (provide-unify stx)
(define (resolve-path path)
(syntax-case path ()
(path
(resolve-module-path (syntax->datum #'path))
#'path)
(path
(datum->syntax stx
(list (datum->syntax stx 'planet) #'path)))))
(define (resolve spec)
(syntax-case spec (all-defined-out
all-from-out
rename-out
except-out
prefix-out
struct-out
combine-out
protect-out
for-meta
for-syntax
for-template
for-label
)
((all-defined-out)
#'(all-defined-out))
((all-from-out inner ...)
#`(all-from-out #,@(syntax-map resolve-path #'(inner ...))))
((rename-out id ...)
#`(rename-out id ...))
((except-out inner ...)
#`(except-out #,@(syntax-map resolve #'(inner ...))))
((prefix-out prefix inner)
#`(prefix-out prefix #,(resolve #'inner)))
((struct-out id)
#'(struct-out id))
((combine-out inner ...)
#`(combine-out #,@(syntax-map resolve #'(inner ...))))
((protect-out inner ...)
#`(protect-out #,@(syntax-map resolve #'(inner ...))))
((for-meta phase inner ...)
#`(for-meta phase #,@(syntax-map resolve #'(inner ...))))
((for-syntax inner ...)
#`(for-syntax #,@(syntax-map resolve #'(inner ...))))
((for-template inner ...)
#`(for-template #,@(syntax-map resolve #'(inner ...))))
((for-label phase inner ...)
#`(for-label #,@(syntax-map resolve #'(inner ...))))
(id
(symbol? (syntax->datum #'id))
#'id)
(err
(raise-syntax-error 'provide "invalid provide-spec: ~s" (syntax->datum #'err)))
))
(syntax-case stx ()
((~ spec ...)
(datum->syntax stx (cons (datum->syntax stx 'provide)
(syntax-map resolve #'(spec ...)))))
))
(define (require->require/unify stx)
(datum->syntax stx (cons (datum->syntax stx 'require/unify)
(stx-cdr stx))))
(define (provide->provide/unify stx)
(datum->syntax stx (cons (datum->syntax stx 'provide/unify)
(stx-cdr stx))))
(provide require-unify provide-unify
require->require/unify
provide->provide/unify
)