(define-record-type module-store (make-module-store* root) module-store? (root module-store-root)) (define-record-type namespace (make-namespace* root) namespace? (root namespace-root)) (define-record-type module-definition (make-module-definition direct-requires direct-requires-for-syntax bindings syntax-bindings) module-definition? (direct-requires module-definition-direct-requires) (direct-requires-for-syntax module-definition-direct-requires-for-syntax) (bindings module-definition-bindings) (syntax-bindings module-definition-syntax-bindings)) (define kernel-url "http://srfi.schemers.org/srfi-N/kernel-language.scm") ;; ^^ is this a good idea? (define (make-module-store) (make-module-store* (make-hash-table 'equal))) (define (make-kernel-module-store) ;; %%% this needs lots more thought (let ((store (make-module-store))) (hash-table-put! (module-store-root store) 'srfi-N-kernel (make-module-definition '() '() '() ;; should include stx-manipulation procs? (initial-eenv))) ;; ?? store)) (define (make-namespace) (make-namespace* (make-hash-table))) (define (compile-named-module-form! module-store module-name module-form) ...) (define lookup-or-compile-module-definition! (let () (define (compile-module-by-url! module-store module-url) ;; Future: support proper URLs here, deal with relative URLs, all that muck (let ((module-form (with-input-from-file module-url (lambda () (let ((form (read))) (cond ((eof-object? form) (error "Could not read module" module-url)) ((not (eof-object? (read))) (error "Expected a single form in module source file" module-url)) (else form))))))) (if (not (and (pair? module-form) (eq? 'module (car module-form)) (pair? (cdr module-form)) (symbol? (cadr module-form)) (pair? (cddr module-form)) (or (symbol? (caddr module-form)) (string? (caddr module-form)) (list? (caddr module-form))))) (error "Illegal module definition syntax in module source file" module-url) (compile-named-module-form! module-store module-url module-form)))) (lambda (module-store module-url) (let ((definition (hash-table-get (module-store-root module-store) module-url (lambda () (compile-module-by-url! module-store module-url))))) (if (module-definition? definition) definition (error "Could not find module" module-url definition)))))) (define invoke-module! (let () (define (visit-module! module-url phase module-store namespace) (let ((module-definition (lookup-or-compile-module-definition! module-store module-url))) (for-each (lambda (required-url) (visit-module! required-url phase module-store namespace)) (module-definition-direct-requires module-definition)) (for-each (lambda (required-url) (visit-module! required-url (+ phase 1) module-store namespace) (invoke-module! required-url (+ phase 1) module-store namespace)) (module-definition-direct-requires-for-syntax module-definition)) (for-each (lambda (binding-name parsed-exp) (install-module-binding! namespace module-url binding-name phase (parsed-exp-eval parsed-exp phase namespace))) (module-definition-syntax-bindings module-definition)))) (define (invoke-module! module-url phase module-store namespace) (let ((module-definition (lookup-or-compile-module-definition! module-store module-url))) (for-each (lambda (required-url) (invoke-module! required-url phase module-store namespace)) (module-definition-direct-requires module-definition)) (for-each (lambda (binding-name parsed-exp) (install-module-binding! namespace module-url binding-name phase (parsed-exp-eval parsed-exp namespace))) (module-definition-bindings module-definition)))) (lambda (module-store module-url namespace) (invoke-module! module-url 0 module-store namespace) namespace)))