#lang scheme/base (require "../private/planet.ss") (require (for-syntax scheme/base scheme/list syntax/boundmap (cce syntax) "static-rep.ss" "syntax-meta.ss" "../proof/wrapper.ss") mzlib/etc "keywords.ss" "dynamic-rep.ss" "../lang/defun.ss" "../lang/defthm.ss" "../proof/event.ss") (provide module-macro) (define-for-syntax (matcher . ids) (let* ([table (make-free-identifier-mapping)]) (for ([id ids]) (free-identifier-mapping-put! table id #t)) (lambda (stx) (syntax-case stx () [(name . _) (identifier? #'name) (free-identifier-mapping-get table #'name (lambda () #f))] [_ #f])))) (define-for-syntax (expand-export port id) (let* ([source (port/static-source port)] [concrete (port/static-concrete port)] [internals (port/static-sig-names/internal port)] [externals (port/static-sig-names/external port)] [arguments (port/static-sig-args port)]) (with-syntax ([exp/dynamic id] [(put ...) externals] [(get ...) internals] [(tmp ...) (generate-temporaries externals)] [((arg ...) ...) arguments]) (dracula-special-event concrete (syntax/loc source (define-values () (begin (interface/dynamic-put-function! exp/dynamic 'put (lambda (arg ...) (get arg ...))) ... (values)))))))) (define-for-syntax (expand-import port id) (let* ([source (port/static-source port)] [abstract (port/static-abstract port)] [internals (port/static-sig-names/internal port)] [externals (port/static-sig-names/external port)] [arguments (port/static-sig-args port)] [axioms (port/static-con-names/internal port)]) (with-syntax ([imp/dynamic id] [(get ...) externals] [(put ...) internals] [(tmp ...) (generate-temporaries externals)] [((arg ...) ...) arguments] [(ax ...) axioms]) (dracula-special-event abstract (syntax/loc source (begin (define tmp (interface/dynamic-get-function imp/dynamic 'get)) ... (defun put (arg ...) (tmp arg ...)) ... (defaxiom ax 't) ...)))))) (define-for-syntax (expand-definition def) def) (define-for-syntax (expand-exports mod id) (map (lambda (port) (expand-export port id)) (module/static-exports mod))) (define-for-syntax (expand-imports mod id) (map (lambda (port) (expand-import port id)) (module/static-imports mod))) (define-for-syntax (expand-definitions mod) (map expand-definition (module/static-definitions mod))) (define-for-syntax (expand-dynamic stx) (syntax-case stx () [(_ static-name) (let* ([import-name #'imp/dynamic] [export-name #'exp/dynamic] [mod/static (syntax->meta #'static-name)] [source (module/static-source mod/static)]) (with-syntax ([(imp ...) (expand-imports mod/static import-name)] [(exp ...) (expand-exports mod/static export-name)] [(def ...) (expand-definitions mod/static)] [original source] [dynamic-name (refresh-identifier (module/static-dynamic mod/static))]) (syntax/loc source (define dynamic-name (make-module/dynamic (lambda (imp/dynamic) (#%annotate-part static-name original (let ([exp/dynamic (empty-interface/dynamic)]) (begin-with-definitions (#%annotate-term imp) ... (#%annotate-term def) ... (#%annotate-term exp) ... (interface/dynamic-join exp/dynamic imp/dynamic))))))))))])) (define-for-syntax (parse-port rev-ports stx) (syntax-case stx () [(_ ifc [ext int] ...) (let* ([ifc (syntax->meta #'ifc)]) (make-port/static stx ifc (map cons (syntax->list #'(ext ...)) (syntax->list #'(int ...))) (map (lambda (inc) (or (findf (lambda (port) (interface/static-external=? inc (port/static-interface port))) rev-ports) (syntax-error stx "no im/export of ~a (required by ~a)" (syntax-e (interface/static-name inc)) (syntax-e (interface/static-name ifc))))) (interface/static-includes ifc))))])) (define-for-syntax (parse-ports prior stx-list) (if (null? stx-list) null (let* ([port (parse-port prior (car stx-list))]) (cons port (parse-ports (cons port prior) (cdr stx-list)))))) (define-for-syntax (parse-exports imports stx-list) (parse-ports imports stx-list)) (define-for-syntax (parse-imports stx-list) (parse-ports null stx-list)) (define-for-syntax (expand-static stx) (syntax-case stx () [(_ static-name original . body) (let* ([forms (syntax->list #'body)] [imps (filter (matcher #'import) forms)] [exps (filter (matcher #'export) forms)] [defs (filter-not (matcher #'import #'export) forms)]) (with-syntax ([(imp ...) imps] [(exp ...) exps] [(def ...) defs]) (syntax/loc #'original (define-syntax static-name (make-syntax-meta (let* ([imports (#%app parse-imports (list #'imp ...))] [exports (#%app parse-exports imports (list #'exp ...))] [definitions (list #'def ...)]) (make-module/static #'static-name #'dynamic-name #'original imports exports definitions)) (expand-keyword "cannot be used as an expression"))))))])) (define-for-syntax (expand-module stx) (syntax-case stx () [(_ static-name body ...) (parameterize ([current-syntax stx]) (with-syntax ([original stx]) (syntax/loc stx (begin (define-syntaxes (define-static) expand-static) (define-syntaxes (define-dynamic) expand-dynamic) (define-static static-name original body ...) (define-dynamic static-name)))))])) (define-syntax module-macro expand-module)