#lang scheme/base
(require "../require.ss"
scheme/match
(planet bzlib/base)
)
(define (require-exp? exp)
(if (syntax? exp)
(require-exp? (syntax->datum exp))
(match exp
((list-rest 'require rest)
exp)
(else #f))))
(define (provide-exp? exp)
(if (syntax? exp)
(provide-exp? (syntax->datum exp))
(match exp
((list-rest 'provide rest) exp)
(else #f))))
(define (transform-require exp)
(if (syntax? exp)
(require->require/unify exp)
(syntax->datum (transform-require (datum->syntax #f exp)))))
(define (transform-provide exp)
(if (syntax? exp)
(provide->provide/unify exp)
(syntax->datum (transform-provide (datum->syntax #f exp)))))
(define (transform-body body)
(let ((reqs (map transform-require (filter require-exp? body)))
(provs (map transform-provide (filter provide-exp? body)))
(rest (filter (lambda (exp)
(and (not (require-exp? exp))
(not (provide-exp? exp))))
body)))
(append reqs rest provs)))
(define (wrap in read) (let* ((body (transform-body (let loop ((acc '()))
(let ((v (read in)))
(if (eof-object? v)
(reverse acc)
(loop (cons v acc)))))))
(path (object-name in))
(name (if (path? path)
(let-values (((base name dir?)
(split-path path)))
(string->symbol
(path->string
(path-replace-suffix name #""))))
'page)))
(let ((module `(module ,name scheme/base
(require (planet bzlib/unify))
. ,body)))
module)))
(define (m-read (in (current-input-port)))
(wrap in read))
(define (m-read-syntax (src #f) (in (current-input-port)))
(wrap in (lambda (in)
(read-syntax src in))))
(provide (rename-out (m-read read)
(m-read-syntax read-syntax)))