(module metadata mzscheme
(require (lib "contract.ss")
(lib "etc.ss")
(lib "list.ss")
(planet "combinators.ss" ("cce" "combinators.plt" 1 4))
"syntax-errors.scm"
"idmap.scm"
"tags.scm"
"sharing.scm")
(define-struct ifc-meta (orig name sigs args cons exprs))
(define-struct mod-meta (orig name impl itags etags ifcs share))
(provide/contract
[ifc-meta? (-> any/c boolean?)]
[interface-meta
(-> syntax?
identifier?
(alistof identifier? (listof identifier?))
(alistof identifier? syntax?)
ifc-meta?)]
[ifc-original (-> ifc-meta? syntax?)]
[ifc-name (-> ifc-meta? identifier?)]
[ifc-funs (-> ifc-meta? (listof identifier?))]
[ifc-fun? (-> ifc-meta? identifier? boolean?)]
[ifc-args (-> ifc-meta? identifier? (listof identifier?))]
[ifc-thms (-> ifc-meta? (listof identifier?))]
[ifc-rule (-> ifc-meta? identifier? syntax?)]
[mod-meta? (-> any/c boolean?)]
[module-meta
(-> syntax?
identifier?
identifier?
(alistof identifier? ifc-meta?)
(alistof identifier? ifc-meta?)
(listof (listof identifier?))
mod-meta?)]
[mod-original (-> mod-meta? syntax?)]
[mod-name (-> mod-meta? identifier?)]
[mod-impl (-> mod-meta? identifier?)]
[mod-imports (-> mod-meta? (listof identifier?))]
[mod-exports (-> mod-meta? (listof identifier?))]
[mod-ifc (-> mod-meta? identifier? ifc-meta?)]
[mod-import-sharing (-> mod-meta? sharing?)]
[mod-export-sharing (-> mod-meta? sharing?)]
)
(define ifc-original ifc-meta-orig)
(define ifc-name ifc-meta-name)
(define ifc-funs ifc-meta-sigs)
(define ifc-thms ifc-meta-cons)
(define (ifc-args ifc id)
(idmap-get (ifc-meta-args ifc) id (lambda () (ifc-fun-not-found! ifc id))))
(define (ifc-rule ifc id)
(idmap-get (ifc-meta-exprs ifc) id (lambda () (ifc-thm-not-found! ifc id))))
(define (ifc-fun-not-found! ifc id)
(syntax-error id "no function ~s in interface ~s"
(syntax-e id) (syntax-e (ifc-meta-name ifc))))
(define (ifc-thm-not-found! ifc id)
(syntax-error id "no theorem ~s in interface ~s"
(syntax-e id) (syntax-e (ifc-meta-name ifc))))
(define (ifc-fun? ifc id)
(idmap-member? (ifc-meta-args ifc) id))
(define (interface-meta original name signatures contracts)
(make-ifc-meta
original
name
(map car signatures)
(alist->idmap signatures)
(map car contracts)
(alist->idmap contracts)))
(define mod-original mod-meta-orig)
(define mod-name mod-meta-name)
(define mod-impl mod-meta-impl)
(define mod-imports mod-meta-itags)
(define mod-exports mod-meta-etags)
(define (module-meta original name implementation imports exports sharing)
(let* ([itags (map car imports)]
[etags (map car exports)]
[ifcs (alist->idmap (append imports exports))]
[tagged (pairs->tagged (append imports exports))])
(make-mod-meta
original name implementation
itags etags ifcs
(sharing-add-clauses sharing #t (empty-sharing tagged)))))
(define (pairs->tagged pairs)
(apply append (map pair->tagged pairs)))
(define (pair->tagged pair)
(ifc->tagged (car pair) (cdr pair)))
(define (ifc->tagged tag ifc)
(map (curry tag-id tag)
(append (ifc-funs ifc) (ifc-thms ifc))))
(define mod-export-sharing mod-meta-share)
(define (mod-import-sharing meta)
(let* ([exports
(apply append
(map (lambda (tag) (ifc->tagged tag (mod-ifc meta tag)))
(mod-exports meta)))])
(sharing-remove (mod-meta-share meta) exports)))
(define (mod-ifc mod id)
(idmap-get (mod-meta-ifcs mod) id (lambda () (mod-tag-not-found! mod id))))
(define (mod-tag-not-found! mod id)
(syntax-error id "no interface tag ~s in module ~s"
(syntax-e id) (syntax-e (mod-meta-name mod))))
)