Moving unit system from mzscheme->scheme/base, reformatting and small changes

as necessary.  Ran the quiet testsuite, unit tests, and setup-plt, all good.

svn: r17582
This commit is contained in:
Stevie Strickland 2010-01-08 21:44:42 +00:00
parent d846d22b9e
commit 73d68593af
7 changed files with 2879 additions and 2883 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,136 +1,135 @@
(module unit-runtime mzscheme
(require-for-syntax "unit-syntax.ss")
(provide define-syntax/err-param
undefined (rename make-a-unit make-unit) unit-import-sigs unit-export-sigs unit-go unit? unit-deps
check-unit check-no-imports check-sigs check-deps check-helper)
(define-syntax define-syntax/err-param
(syntax-rules ()
((_ (name arg) body)
(define-syntax (name arg)
(parameterize ((error-syntax arg))
body)))))
;; initial value
(define undefined (letrec ([x x]) x))
#lang scheme/base
;; for named structures
(define insp (current-inspector))
(require (for-syntax "unit-syntax.ss" scheme/base))
(provide define-syntax/err-param
undefined (rename-out [make-a-unit make-unit]) unit-import-sigs unit-export-sigs unit-go unit? unit-deps
check-unit check-no-imports check-sigs check-deps check-helper)
;; (make-unit (listof (cons symbol symbol)) (listof (cons symbol symbol)) (listof nat) thunk)
;; Runtime representation of a unit
(define-struct unit (import-sigs export-sigs deps go))
;; For units with inferred names, generate a struct that prints using the name:
(define (make-naming-constructor type name)
(let-values ([(struct: make- ? -accessor -mutator)
(make-struct-type name type 0 0 #f null insp)])
make-))
;; Make a unit value (call by the macro expansion of `unit')
(define (make-a-unit name num-imports exports deps go)
((if name
(make-naming-constructor
struct:unit
(string->symbol (format "unit:~a" name)))
make-unit)
num-imports exports deps go))
(define-syntax define-syntax/err-param
(syntax-rules ()
((_ (name arg) body)
(define-syntax (name arg)
(parameterize ((error-syntax arg))
body)))))
;; check-unit : X symbol ->
;; ensure that u is a unit value
(define (check-unit u name)
(unless (unit? u)
(raise
(make-exn:fail:contract
(format "~a: result of unit expression was not a unit: ~e" name u)
(current-continuation-marks)))))
;; check-helper : (vectorof (cons symbol (vectorof (cons symbol symbol)))))
; (vectorof (cons symbol (vectorof (cons symbol symbol)))))
;; symbol symbol ->
;; ensure that the unit's signatures match the expected signatures.
(define (check-helper sub-sig super-sig name import?)
(define t (make-hash-table 'equal))
(let loop ([i (sub1 (vector-length sub-sig))])
(when (>= i 0)
(let ([v (cdr (vector-ref sub-sig i))])
(let loop ([j (sub1 (vector-length v))])
(when (>= j 0)
(let ([vj (vector-ref v j)])
(hash-table-put! t vj
(if (hash-table-get t vj #f)
'amb
#t)))
(loop (sub1 j)))))
(loop (sub1 i))))
(let loop ([i (sub1 (vector-length super-sig))])
(when (>= i 0)
(let* ([v0 (vector-ref (cdr (vector-ref super-sig i)) 0)]
[r (hash-table-get t v0 #f)])
(when (or (eq? r 'amb) (not r))
(let ([tag (if (pair? v0) (car v0) #f)]
[sub-name (car (vector-ref super-sig i))]
[err-str (if r
;; initial value
(define undefined (letrec ([x x]) x))
;; for named structures
(define insp (current-inspector))
;; (make-unit (listof (cons symbol symbol)) (listof (cons symbol symbol)) (listof nat) thunk)
;; Runtime representation of a unit
(define-struct unit (import-sigs export-sigs deps go))
;; For units with inferred names, generate a struct that prints using the name:
(define (make-naming-constructor type name)
(let-values ([(struct: make- ? -accessor -mutator)
(make-struct-type name type 0 0 #f null insp)])
make-))
;; Make a unit value (call by the macro expansion of `unit')
(define (make-a-unit name num-imports exports deps go)
((if name
(make-naming-constructor
struct:unit
(string->symbol (format "unit:~a" name)))
make-unit)
num-imports exports deps go))
;; check-unit : X symbol ->
;; ensure that u is a unit value
(define (check-unit u name)
(unless (unit? u)
(raise
(make-exn:fail:contract
(format "~a: result of unit expression was not a unit: ~e" name u)
(current-continuation-marks)))))
;; check-helper : (vectorof (cons symbol (vectorof (cons symbol symbol)))))
; (vectorof (cons symbol (vectorof (cons symbol symbol)))))
;; symbol symbol ->
;; ensure that the unit's signatures match the expected signatures.
(define (check-helper sub-sig super-sig name import?)
(define t (make-hash))
(let loop ([i (sub1 (vector-length sub-sig))])
(when (>= i 0)
(let ([v (cdr (vector-ref sub-sig i))])
(let loop ([j (sub1 (vector-length v))])
(when (>= j 0)
(let ([vj (vector-ref v j)])
(hash-set! t vj
(if (hash-ref t vj #f)
'amb
#t)))
(loop (sub1 j)))))
(loop (sub1 i))))
(let loop ([i (sub1 (vector-length super-sig))])
(when (>= i 0)
(let* ([v0 (vector-ref (cdr (vector-ref super-sig i)) 0)]
[r (hash-ref t v0 #f)])
(when (or (eq? r 'amb) (not r))
(let ([tag (if (pair? v0) (car v0) #f)]
[sub-name (car (vector-ref super-sig i))]
[err-str (if r
"supplies multiple times"
"does not supply")])
(raise
(make-exn:fail:contract
(cond
[(and import? tag)
(format "~a: unit argument expects an import for tag ~a with signature ~a, which this usage context ~a"
name
tag
sub-name
err-str)]
[import?
(format "~a: unit argument expects an untagged import with signature ~a, which this usage context ~a"
name
sub-name
err-str)]
[tag
(format "~a: this usage context expects a unit with an export for tag ~a with signature ~a, which the given unit ~a"
name
tag
sub-name
err-str)]
[else
(format "~a: this usage context expects a unit with an untagged export with signature ~a, which the given unit ~a"
name
sub-name
err-str)])
(current-continuation-marks))))))
(loop (sub1 i)))))
;; check-deps : (hash-tableof (cons symbol (or symbol #f)) (cons symbol symbol)) unit symbol ->
;; The hash table keys are the tag and runtime signature id
;; The values are the name of the signature and the linkage
(define (check-deps dep-table unit name)
(for-each
(λ (dep)
(let ([r (hash-table-get dep-table dep #f)])
(when r
(raise
(make-exn:fail:contract
(if (car dep)
(format "~a: initialization dependent signature ~a with tag ~a is supplied from a later unit with link ~a"
name (car r) (car dep) (cdr r))
(format "~a: untagged initialization dependent signature ~a is supplied from a later unit with link ~a"
name (car r) (cdr r)))
(cond
[(and import? tag)
(format "~a: unit argument expects an import for tag ~a with signature ~a, which this usage context ~a"
name
tag
sub-name
err-str)]
[import?
(format "~a: unit argument expects an untagged import with signature ~a, which this usage context ~a"
name
sub-name
err-str)]
[tag
(format "~a: this usage context expects a unit with an export for tag ~a with signature ~a, which the given unit ~a"
name
tag
sub-name
err-str)]
[else
(format "~a: this usage context expects a unit with an untagged export with signature ~a, which the given unit ~a"
name
sub-name
err-str)])
(current-continuation-marks))))))
(unit-deps unit)))
;; check-no-imports : unit symbol ->
;; ensures that the unit has no imports
(define (check-no-imports unit name)
(check-helper (vector) (unit-import-sigs unit) name #t))
;; check-sigs : unit
;; (vectorof (cons symbol (vectorof (cons symbol symbol)))))
;; (vectorof (cons symbol (vectorof (cons symbol symbol)))))
;; symbol ->
;; ensures that unit has the given signatures
(define (check-sigs unit expected-imports expected-exports name)
(check-helper expected-imports (unit-import-sigs unit) name #t)
(check-helper (unit-export-sigs unit) expected-exports name #f)))
(loop (sub1 i)))))
;; check-deps : (hash-tableof (cons symbol (or symbol #f)) (cons symbol symbol)) unit symbol ->
;; The hash table keys are the tag and runtime signature id
;; The values are the name of the signature and the linkage
(define (check-deps dep-table unit name)
(for-each
(λ (dep)
(let ([r (hash-ref dep-table dep #f)])
(when r
(raise
(make-exn:fail:contract
(if (car dep)
(format "~a: initialization dependent signature ~a with tag ~a is supplied from a later unit with link ~a"
name (car r) (car dep) (cdr r))
(format "~a: untagged initialization dependent signature ~a is supplied from a later unit with link ~a"
name (car r) (cdr r)))
(current-continuation-marks))))))
(unit-deps unit)))
;; check-no-imports : unit symbol ->
;; ensures that the unit has no imports
(define (check-no-imports unit name)
(check-helper (vector) (unit-import-sigs unit) name #t))
;; check-sigs : unit
;; (vectorof (cons symbol (vectorof (cons symbol symbol)))))
;; (vectorof (cons symbol (vectorof (cons symbol symbol)))))
;; symbol ->
;; ensures that unit has the given signatures
(define (check-sigs unit expected-imports expected-exports name)
(check-helper expected-imports (unit-import-sigs unit) name #t)
(check-helper (unit-export-sigs unit) expected-exports name #f))

View File

@ -1,286 +1,284 @@
(module unit-syntax mzscheme
(require syntax/stx)
(require-for-template "unit-keywords.ss")
(provide (all-defined))
(define error-syntax (make-parameter #f))
(define raise-stx-err
(case-lambda
((msg) (raise-syntax-error #f msg (error-syntax)))
((msg stx) (raise-syntax-error #f msg (error-syntax) stx))))
#lang scheme/base
;; check-id: syntax-object -> identifier
(define (check-id id)
(unless (identifier? id)
(raise-stx-err "not an identifier" id))
id)
(require syntax/stx)
(require (for-template "unit-keywords.ss"))
;; checked-syntax->list : syntax-object -> (listof syntax-object)
(define (checked-syntax->list s)
(define l (syntax->list s))
(unless (or (stx-pair? s) (stx-null? s))
(raise-stx-err "bad syntax (not a list)" s))
(unless l
(raise-stx-err "bad syntax (illegal use of `.')" s))
l)
(provide (all-defined-out))
;; check-tagged : (syntax-object -> X) -> syntax-object -> (cons (or symbol #f) X)
(define (check-tagged check)
(λ (o)
(syntax-case o (tag)
((tag . s)
(syntax-case #'s ()
((sym spec)
(begin
(unless (symbol? (syntax-e #'sym))
(raise-stx-err "tag must be a symbol" #'sym))
(cons (syntax-e #'sym) (check #'spec))))
(_ (raise-stx-err "expected (tag <identifier> <syntax>)" #'s))))
(_
(cons #f (check o))))))
(define error-syntax (make-parameter #f))
(define raise-stx-err
(case-lambda
((msg) (raise-syntax-error #f msg (error-syntax)))
((msg stx) (raise-syntax-error #f msg (error-syntax) stx))))
;; check-tagged-:-clause : syntax-object -> (cons identifier identifier)
;; ensures that clause matches (a : b) or (a : (tag t b))
(define (check-tagged-:-clause clause)
(checked-syntax->list clause)
(syntax-case* clause (:) (lambda (x y) (eq? (syntax-e x) (syntax-e y)))
((a : b)
(identifier? #'a)
(let ([p ((check-tagged check-id) #'b)])
(cons (car p) (cons #'a (cdr p)))))
(_ (raise-stx-err
"expected syntax matching (<identifier> : <identifier>) or (<identifier> : (tag <identifier> <identifier>))"
clause))))
(define check-tagged-id (check-tagged check-id))
;; check-id: syntax-object -> identifier
(define (check-id id)
(unless (identifier? id)
(raise-stx-err "not an identifier" id))
id)
;; check-spec-syntax : syntax-object boolean (syntax-object -> boolean) ->
;; ensures that s matches spec.
;; tag-spec ::= spec
;; | (tag symbol spec)
;; spec ::= prim-spec
;; | (prefix identifier spec)
;; | (rename spec (identifier identifier) ...)
;; | (only spec identifier ...) only if import? is true
;; | (except spec identifier ...) only if import? is true
(define (check-tagged-spec-syntax s import? prim-spec?)
((check-tagged (λ (s) (check-spec-syntax s import? prim-spec?))) s))
(define (check-spec-syntax s import? prim-spec?)
(unless (prim-spec? s)
(let ((ie (if import? 'import 'export)))
(unless (stx-pair? s)
(raise-stx-err (format "bad ~a spec" ie) s))
(checked-syntax->list s)
(syntax-case s (prefix rename)
((key . x)
(or (module-identifier=? #'key #'only)
(module-identifier=? #'key #'except))
(begin
(unless import?
(raise-stx-err
"bad export-spec keyword"
#'key))
(syntax-case #'x ()
(()
(raise-stx-err (format "missing ~a-spec argument" ie)
s))
((s y ...)
(begin
(for-each check-id (syntax->list #'(y ...)))
(check-spec-syntax #'s import? prim-spec?))))))
((prefix)
(raise-stx-err (format "missing prefix identifier and ~a spec" ie)
s))
((prefix x)
(begin
(check-id #'x)
(raise-stx-err (format "missing ~a spec" ie) s)))
((prefix x y)
(begin
(check-id #'x)
(check-spec-syntax #'y import? prim-spec?)))
((prefix . _)
(raise-stx-err "too many arguments" s))
((rename)
(raise-stx-err (format "missing ~a spec" ie) s))
((rename sub-s clause ...)
(begin
(for-each
(lambda (c)
(syntax-case c ()
((a b)
(begin
(check-id #'a)
(check-id #'b)))
((a . b)
(begin
(checked-syntax->list c)
(raise-stx-err "bad rename clause" c)))
(_
(raise-stx-err "bad rename clause" c))))
(syntax->list #'(clause ...)))
(check-spec-syntax #'sub-s import? prim-spec?)))
((k . x)
(raise-stx-err (format "bad ~a-spec keyword" ie) #'k))))))
;; check-unit-syntax : syntax-object -> syntax-object
;; ensures that stx matches ((import i ...) (export e ...) b ...)
;; or ((import i ...) (export e ...) (init-depend id ...) b ...)
;; and returns syntax that matches the latter
(define (check-unit-syntax stx)
(syntax-case stx (import export init-depend)
(((import . isig) (export . esig) (init-depend . id) . body)
(begin
(checked-syntax->list (stx-car stx))
(checked-syntax->list (stx-car (stx-cdr stx)))
(checked-syntax->list (stx-car (stx-cdr (stx-cdr stx))))
(checked-syntax->list #'body)
stx))
(((import . isig) (export . esig) . body)
(begin
(checked-syntax->list (stx-car stx))
(checked-syntax->list (stx-car (stx-cdr stx)))
(checked-syntax->list #'body)
(syntax/loc stx
((import . isig) (export . esig) (init-depend) . body))))
(()
(raise-stx-err "missing import and export clauses"))
(((import . isig))
(raise-stx-err "missing export clause"))
(((import . isig) e . rest)
(raise-stx-err "export clause must start with keyword \"export\"" #'e))
((i . rest)
(raise-stx-err "import clause must start with keyword \"import\"" #'i))))
;; check-unit-body-syntax : syntax-object -> syntax-object
;; ensures that stx matches (exp (import i ...) (export e ...))
;; or (exp (import i ...) (export e ...) (init-depend id ...))
;; and returns syntax that matches the latter
(define (check-unit-body-syntax stx)
(checked-syntax->list stx)
(syntax-case stx (import export init-depend)
((exp (import . isig) (export . esig) (init-depend . id))
(begin
(checked-syntax->list (stx-car (stx-cdr stx)))
(checked-syntax->list (stx-car (stx-cdr (stx-cdr stx))))
(checked-syntax->list (stx-car (stx-cdr (stx-cdr (stx-cdr stx)))))
stx))
((exp (import . isig) (export . esig))
(begin
(checked-syntax->list (stx-car (stx-cdr stx)))
(checked-syntax->list (stx-car (stx-cdr (stx-cdr stx))))
(syntax/loc stx
(exp (import . isig) (export . esig) (init-depend)))))
(()
(raise-stx-err "missing expression, import and export clauses"))
((exp)
(raise-stx-err "missing import and export clauses"))
((exp (import . isig))
(raise-stx-err "missing export clause"))
((exp i e id extra . rest)
(raise-stx-err "too many clauses" stx))
((exp (import . isig) (export . esig) id)
(raise-stx-err "init-depend clause must start with keyword \"init-depend\"" #'id))
((exp (import . isig) e . rest)
(raise-stx-err "export clause must start with keyword \"export\"" #'e))
((exp i . rest)
(raise-stx-err "import clause must start with keyword \"import\"" #'i))))
;; check-link-line-syntax : syntax-object ->
;; ensures that l matches ((x ...) u y ...)
(define (check-link-line-syntax l)
(unless (stx-pair? l)
(raise-stx-err "bad linking line" l))
(checked-syntax->list l)
(syntax-case l ()
(((x ...) u y ...) (void))
(((x ...))
(raise-stx-err "missing unit expression" l))
((x . y)
(begin
(unless (stx-pair? #'x)
(raise-stx-err "bad export list" #'x))
(checked-syntax->list #'x)))))
;; check-compound-syntax : syntax-object -> syntax-object
;; ensures that clauses has exactly one clause matching each of
;; (import i ...), (export e ...), and (link i ...), in any order.
;; returns #'((i ...) (e ...) (l ...))
(define (check-compound-syntax c)
(define clauses (checked-syntax->list c))
(define im #f)
(define ex #f)
(define li #f)
(for-each
(lambda (clause)
(syntax-case clause (import export link)
((import i ...)
;; checked-syntax->list : syntax-object -> (listof syntax-object)
(define (checked-syntax->list s)
(define l (syntax->list s))
(unless (or (stx-pair? s) (stx-null? s))
(raise-stx-err "bad syntax (not a list)" s))
(unless l
(raise-stx-err "bad syntax (illegal use of `.')" s))
l)
;; check-tagged : (syntax-object -> X) -> syntax-object -> (cons (or symbol #f) X)
(define (check-tagged check)
(λ (o)
(syntax-case o (tag)
((tag . s)
(syntax-case #'s ()
((sym spec)
(begin
(when im
(raise-stx-err "multiple import clauses" clause))
(set! im (syntax->list #'(i ...)))))
((export e ...)
(begin
(when ex
(raise-stx-err "multiple export clauses" clause))
(set! ex (syntax->list #'(e ...)))))
((link l ...)
(begin
(when li
(raise-stx-err "duplicate link clauses" clause))
(set! li (syntax->list #'(l ...)))))
((x . y)
(begin
(checked-syntax->list clause)
(raise-stx-err "bad compound-unit clause keyword" #'x)))
(_
(raise-stx-err "expected import, export, or link clause" clause))))
clauses)
(unless im
(raise-stx-err "missing import clause"))
(unless ex
(raise-stx-err "missing export clause"))
(unless li
(raise-stx-err "missing link clause" ))
#`(#,im #,ex #,li))
(unless (symbol? (syntax-e #'sym))
(raise-stx-err "tag must be a symbol" #'sym))
(cons (syntax-e #'sym) (check #'spec))))
(_ (raise-stx-err "expected (tag <identifier> <syntax>)" #'s))))
(_
(cons #f (check o))))))
;; check-def-syntax : syntax-object ->
;; d must be a syntax-pair
;; ensures that d matches (_ (x ...) e)
(define (check-def-syntax d)
(unless (syntax->list d)
(raise-syntax-error
#f
"bad syntax (illegal use of `.')"
d))
(syntax-case d ()
((_ params expr)
(let ((l (syntax->list #'params)))
(unless l
(raise-syntax-error
#f
"bad variable list"
d #'params))
(for-each
(lambda (x)
(unless (identifier? x)
(raise-syntax-error
#f
"not an identifier"
d x)))
l)))
(_
(raise-syntax-error
#f
(format "bad syntax (has ~a parts after keyword)"
(sub1 (length (syntax->list d))))
d))))
)
;; check-tagged-:-clause : syntax-object -> (cons identifier identifier)
;; ensures that clause matches (a : b) or (a : (tag t b))
(define (check-tagged-:-clause clause)
(checked-syntax->list clause)
(syntax-case* clause (:) (lambda (x y) (eq? (syntax-e x) (syntax-e y)))
((a : b)
(identifier? #'a)
(let ([p ((check-tagged check-id) #'b)])
(cons (car p) (cons #'a (cdr p)))))
(_ (raise-stx-err
"expected syntax matching (<identifier> : <identifier>) or (<identifier> : (tag <identifier> <identifier>))"
clause))))
;(load "test-unit-syntax.ss")
(define check-tagged-id (check-tagged check-id))
;; check-spec-syntax : syntax-object boolean (syntax-object -> boolean) ->
;; ensures that s matches spec.
;; tag-spec ::= spec
;; | (tag symbol spec)
;; spec ::= prim-spec
;; | (prefix identifier spec)
;; | (rename spec (identifier identifier) ...)
;; | (only spec identifier ...) only if import? is true
;; | (except spec identifier ...) only if import? is true
(define (check-tagged-spec-syntax s import? prim-spec?)
((check-tagged (λ (s) (check-spec-syntax s import? prim-spec?))) s))
(define (check-spec-syntax s import? prim-spec?)
(unless (prim-spec? s)
(let ((ie (if import? 'import 'export)))
(unless (stx-pair? s)
(raise-stx-err (format "bad ~a spec" ie) s))
(checked-syntax->list s)
(syntax-case s (prefix rename)
((key . x)
(or (free-identifier=? #'key #'only)
(free-identifier=? #'key #'except))
(begin
(unless import?
(raise-stx-err
"bad export-spec keyword"
#'key))
(syntax-case #'x ()
(()
(raise-stx-err (format "missing ~a-spec argument" ie)
s))
((s y ...)
(begin
(for-each check-id (syntax->list #'(y ...)))
(check-spec-syntax #'s import? prim-spec?))))))
((prefix)
(raise-stx-err (format "missing prefix identifier and ~a spec" ie)
s))
((prefix x)
(begin
(check-id #'x)
(raise-stx-err (format "missing ~a spec" ie) s)))
((prefix x y)
(begin
(check-id #'x)
(check-spec-syntax #'y import? prim-spec?)))
((prefix . _)
(raise-stx-err "too many arguments" s))
((rename)
(raise-stx-err (format "missing ~a spec" ie) s))
((rename sub-s clause ...)
(begin
(for-each
(lambda (c)
(syntax-case c ()
((a b)
(begin
(check-id #'a)
(check-id #'b)))
((a . b)
(begin
(checked-syntax->list c)
(raise-stx-err "bad rename clause" c)))
(_
(raise-stx-err "bad rename clause" c))))
(syntax->list #'(clause ...)))
(check-spec-syntax #'sub-s import? prim-spec?)))
((k . x)
(raise-stx-err (format "bad ~a-spec keyword" ie) #'k))))))
;; check-unit-syntax : syntax-object -> syntax-object
;; ensures that stx matches ((import i ...) (export e ...) b ...)
;; or ((import i ...) (export e ...) (init-depend id ...) b ...)
;; and returns syntax that matches the latter
(define (check-unit-syntax stx)
(syntax-case stx (import export init-depend)
(((import . isig) (export . esig) (init-depend . id) . body)
(begin
(checked-syntax->list (stx-car stx))
(checked-syntax->list (stx-car (stx-cdr stx)))
(checked-syntax->list (stx-car (stx-cdr (stx-cdr stx))))
(checked-syntax->list #'body)
stx))
(((import . isig) (export . esig) . body)
(begin
(checked-syntax->list (stx-car stx))
(checked-syntax->list (stx-car (stx-cdr stx)))
(checked-syntax->list #'body)
(syntax/loc stx
((import . isig) (export . esig) (init-depend) . body))))
(()
(raise-stx-err "missing import and export clauses"))
(((import . isig))
(raise-stx-err "missing export clause"))
(((import . isig) e . rest)
(raise-stx-err "export clause must start with keyword \"export\"" #'e))
((i . rest)
(raise-stx-err "import clause must start with keyword \"import\"" #'i))))
;; check-unit-body-syntax : syntax-object -> syntax-object
;; ensures that stx matches (exp (import i ...) (export e ...))
;; or (exp (import i ...) (export e ...) (init-depend id ...))
;; and returns syntax that matches the latter
(define (check-unit-body-syntax stx)
(checked-syntax->list stx)
(syntax-case stx (import export init-depend)
((exp (import . isig) (export . esig) (init-depend . id))
(begin
(checked-syntax->list (stx-car (stx-cdr stx)))
(checked-syntax->list (stx-car (stx-cdr (stx-cdr stx))))
(checked-syntax->list (stx-car (stx-cdr (stx-cdr (stx-cdr stx)))))
stx))
((exp (import . isig) (export . esig))
(begin
(checked-syntax->list (stx-car (stx-cdr stx)))
(checked-syntax->list (stx-car (stx-cdr (stx-cdr stx))))
(syntax/loc stx
(exp (import . isig) (export . esig) (init-depend)))))
(()
(raise-stx-err "missing expression, import and export clauses"))
((exp)
(raise-stx-err "missing import and export clauses"))
((exp (import . isig))
(raise-stx-err "missing export clause"))
((exp i e id extra . rest)
(raise-stx-err "too many clauses" stx))
((exp (import . isig) (export . esig) id)
(raise-stx-err "init-depend clause must start with keyword \"init-depend\"" #'id))
((exp (import . isig) e . rest)
(raise-stx-err "export clause must start with keyword \"export\"" #'e))
((exp i . rest)
(raise-stx-err "import clause must start with keyword \"import\"" #'i))))
;; check-link-line-syntax : syntax-object ->
;; ensures that l matches ((x ...) u y ...)
(define (check-link-line-syntax l)
(unless (stx-pair? l)
(raise-stx-err "bad linking line" l))
(checked-syntax->list l)
(syntax-case l ()
(((x ...) u y ...) (void))
(((x ...))
(raise-stx-err "missing unit expression" l))
((x . y)
(begin
(unless (stx-pair? #'x)
(raise-stx-err "bad export list" #'x))
(checked-syntax->list #'x)))))
;; check-compound-syntax : syntax-object -> syntax-object
;; ensures that clauses has exactly one clause matching each of
;; (import i ...), (export e ...), and (link i ...), in any order.
;; returns #'((i ...) (e ...) (l ...))
(define (check-compound-syntax c)
(define clauses (checked-syntax->list c))
(define im #f)
(define ex #f)
(define li #f)
(for-each
(lambda (clause)
(syntax-case clause (import export link)
((import i ...)
(begin
(when im
(raise-stx-err "multiple import clauses" clause))
(set! im (syntax->list #'(i ...)))))
((export e ...)
(begin
(when ex
(raise-stx-err "multiple export clauses" clause))
(set! ex (syntax->list #'(e ...)))))
((link l ...)
(begin
(when li
(raise-stx-err "duplicate link clauses" clause))
(set! li (syntax->list #'(l ...)))))
((x . y)
(begin
(checked-syntax->list clause)
(raise-stx-err "bad compound-unit clause keyword" #'x)))
(_
(raise-stx-err "expected import, export, or link clause" clause))))
clauses)
(unless im
(raise-stx-err "missing import clause"))
(unless ex
(raise-stx-err "missing export clause"))
(unless li
(raise-stx-err "missing link clause" ))
#`(#,im #,ex #,li))
;; check-def-syntax : syntax-object ->
;; d must be a syntax-pair
;; ensures that d matches (_ (x ...) e)
(define (check-def-syntax d)
(unless (syntax->list d)
(raise-syntax-error
#f
"bad syntax (illegal use of `.')"
d))
(syntax-case d ()
((_ params expr)
(let ((l (syntax->list #'params)))
(unless l
(raise-syntax-error
#f
"bad variable list"
d #'params))
(for-each
(lambda (x)
(unless (identifier? x)
(raise-syntax-error
#f
"not an identifier"
d x)))
l)))
(_
(raise-syntax-error
#f
(format "bad syntax (has ~a parts after keyword)"
(sub1 (length (syntax->list d))))
d))))

View File

@ -4,7 +4,7 @@
syntax/boundmap
"unit-compiletime.ss"
"unit-syntax.ss")
mzlib/contract)
scheme/contract/base)
(provide (for-syntax build-key
check-duplicate-sigs

View File

@ -1,36 +1,35 @@
#lang scheme/base
(module unitidmap mzscheme
;; Help Desk binding info:
(define (binding binder bound stx)
stx
;; This 'bound-in-source is no longer needed
#;
(syntax-property
stx
'bound-in-source
(cons binder (syntax-local-introduce bound))))
;; Help Desk binding info:
(define (binding binder bound stx)
stx
;; This 'bound-in-source is no longer needed
#;
(syntax-property
stx
'bound-in-source
(cons binder (syntax-local-introduce bound))))
(define (make-id-mapper unbox-stx the-binder)
(let ([set!-stx (datum->syntax unbox-stx 'set! #f)])
(make-set!-transformer
(lambda (sstx)
(cond
[(identifier? sstx)
(binding the-binder sstx
unbox-stx)]
[(free-identifier=? set!-stx (car (syntax-e sstx)))
(raise-syntax-error
'unit
"cannot set! imported or exported variables"
sstx)]
[else
(binding
the-binder (car (syntax-e sstx))
(datum->syntax
sstx
(cons unbox-stx (cdr (syntax-e sstx)))
sstx))])))))
(define (make-id-mapper unbox-stx the-binder)
(let ([set!-stx (datum->syntax-object unbox-stx 'set! #f)])
(make-set!-transformer
(lambda (sstx)
(cond
[(identifier? sstx)
(binding the-binder sstx
unbox-stx)]
[(module-identifier=? set!-stx (car (syntax-e sstx)))
(raise-syntax-error
'unit
"cannot set! imported or exported variables"
sstx)]
[else
(binding
the-binder (car (syntax-e sstx))
(datum->syntax-object
sstx
(cons unbox-stx (cdr (syntax-e sstx)))
sstx))])))))
(provide make-id-mapper))
(provide make-id-mapper)

View File

@ -1,26 +1,27 @@
(module unit-exptime mzscheme
(require "private/unit-syntax.ss"
"private/unit-compiletime.ss")
#lang scheme/base
(provide unit-static-signatures
signature-members)
(require "private/unit-syntax.ss"
"private/unit-compiletime.ss")
(define (unit-static-signatures name err-stx)
(parameterize ((error-syntax err-stx))
(let ((ui (lookup-def-unit name)))
(values (apply list (unit-info-import-sig-ids ui))
(apply list (unit-info-export-sig-ids ui))))))
(provide unit-static-signatures
signature-members)
(define (signature-members name err-stx)
(parameterize ((error-syntax err-stx))
(let ([s (lookup-signature name)])
(values
;; extends:
(and (pair? (cdr (siginfo-names (signature-siginfo s))))
(cadr (siginfo-names (signature-siginfo s))))
;; vars
(apply list (signature-vars s))
;; defined vars
(apply list (apply append (map car (signature-val-defs s))))
;; defined stxs
(apply list (apply append (map car (signature-stx-defs s)))))))))
(define (unit-static-signatures name err-stx)
(parameterize ((error-syntax err-stx))
(let ((ui (lookup-def-unit name)))
(values (apply list (unit-info-import-sig-ids ui))
(apply list (unit-info-export-sig-ids ui))))))
(define (signature-members name err-stx)
(parameterize ((error-syntax err-stx))
(let ([s (lookup-signature name)])
(values
;; extends:
(and (pair? (cdr (siginfo-names (signature-siginfo s))))
(cadr (siginfo-names (signature-siginfo s))))
;; vars
(apply list (signature-vars s))
;; defined vars
(apply list (apply append (map car (signature-val-defs s))))
;; defined stxs
(apply list (apply append (map car (signature-stx-defs s))))))))

File diff suppressed because it is too large Load Diff