From ed9af8fdfd86dc10c87bbef4b95dd0eddba215a5 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 10 Jun 2008 15:41:56 -0400 Subject: [PATCH] Add syntax for ... original commit: e29d4eb881b92a7f96ae1bbb248e311f7f8f90bc --- collects/typed-scheme/private/parse-type.ss | 45 +++++++++++++++++-- collects/typed-scheme/private/subtype.ss | 2 +- .../private/type-effect-printer.ss | 2 +- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/collects/typed-scheme/private/parse-type.ss b/collects/typed-scheme/private/parse-type.ss index 72e51cd5..5565a9d9 100644 --- a/collects/typed-scheme/private/parse-type.ss +++ b/collects/typed-scheme/private/parse-type.ss @@ -24,6 +24,10 @@ (define (stx-cadr stx) (stx-car (stx-cdr stx))) +;; t is (make-F v) +(define-struct Dotted (t)) +(define-struct (DottedBoth Dotted) ()) + (define (parse-type stx) (parameterize ([current-orig-stx stx]) @@ -74,11 +78,28 @@ (make-pred-ty (list (parse-type #'dom)) (parse-type #'rng) (parse-type #'pred-ty)))] [(dom ... rest ::: -> rng) (and (eq? (syntax-e #'->) '->) - (or (symbolic-identifier=? #'::: (quote-syntax ..)) - (symbolic-identifier=? #'::: (quote-syntax ...)))) + (symbolic-identifier=? #'::: (quote-syntax *))) (begin (add-type-name-reference #'->) (->* (map parse-type (syntax->list #'(dom ...))) (parse-type #'rest) (parse-type #'rng)))] + [(dom ... rest ::: bound -> rng) + (and (eq? (syntax-e #'->) '->) + (eq? (syntax-e #':::) '...) + (identifier? #'bound)) + (begin + (add-type-name-reference #'->) + (let ([var (lookup (current-tvars) (syntax-e #'bound) (lambda (_) #f))]) + (if (not (Dotted? var)) + (tc-error/stx #'bound "Used a type variable (~a) not bound with ... as a bound on a ..." (syntax-e #'bound)) + (make-Function + (list + (make-arr-dots (map parse-type (syntax->list #'(dom ...))) + (parse-type #'rng) + (parameterize ([current-tvars (extend-env (list (syntax-e #'bound)) + (list (make-DottedBoth (make-F (syntax-e #'bound)))) + (current-tvars))]) + (parse-type #'rest)) + (syntax-e #'bound)))))))] ;; has to be below the previous one [(dom ... -> rng) (eq? (syntax-e #'->) '->) @@ -129,6 +150,17 @@ [(quot t) (eq? (syntax-e #'quot) 'quote) (-val (syntax-e #'t))] + [(All (vars ... v dd) t) + (and (eq? (syntax-e #'All) 'All) + (eq? (syntax-e #'dd) '...) + (andmap identifier? (syntax->list #'(v vars ...)))) + (let* ([vars (map syntax-e (syntax->list #'(vars ...)))] + [tvars (map make-F vars)] + [v (syntax-e #'v)] + [tv (make-Dotted (make-F v))]) + (add-type-name-reference #'All) + (parameterize ([current-tvars (extend-env (cons v vars) (cons tv tvars) (current-tvars))]) + (make-PolyDots (append vars (list v)) (parse-type #'t))))] [(All (vars ...) t) (and (eq? (syntax-e #'All) 'All) (andmap identifier? (syntax->list #'(vars ...)))) @@ -136,7 +168,7 @@ [tvars (map make-F vars)]) (add-type-name-reference #'All) (parameterize ([current-tvars (extend-env vars tvars (current-tvars))]) - (make-Poly vars (parse-type #'t))))] + (make-Poly vars (parse-type #'t))))] [(Opaque p?) (eq? (syntax-e #'Opaque) 'Opaque) (begin @@ -157,7 +189,12 @@ (identifier? #'id) (cond ;; if it's a type variable, we just produce the corresponding reference (which is in the HT) - [(lookup (current-tvars) (syntax-e #'id) (lambda (_) #f))] + [(lookup (current-tvars) (syntax-e #'id) (lambda (_) #f)) + => + (lambda (e) (cond [(DottedBoth? e) (Dotted-t e)] + [(Dotted? e) + (tc-error "Type variable ~a must be used with ..." (syntax-e #'id))] + [else e]))] ;; if it's a type alias, we expand it (the expanded type is stored in the HT) [(lookup-type-alias #'id parse-type (lambda () #f)) => diff --git a/collects/typed-scheme/private/subtype.ss b/collects/typed-scheme/private/subtype.ss index 5ba4a72c..01698ffb 100644 --- a/collects/typed-scheme/private/subtype.ss +++ b/collects/typed-scheme/private/subtype.ss @@ -198,7 +198,7 @@ ;; use unification to see if we can use the polytype here [(list (Poly: vs b) s) (=> unmatch) - (if (unify vs (list b) (list s)) A0 (unmatch))] + (if (unify vs (list b) (list s)) A0 (unmatch))] [(list s (Poly: vs b)) (=> unmatch) (if (null? (fv b)) (subtype* A0 s b) (unmatch))] diff --git a/collects/typed-scheme/private/type-effect-printer.ss b/collects/typed-scheme/private/type-effect-printer.ss index 2a5dac4d..afe034df 100644 --- a/collects/typed-scheme/private/type-effect-printer.ss +++ b/collects/typed-scheme/private/type-effect-printer.ss @@ -103,7 +103,7 @@ [(Box: e) (fp "(Box ~a)" e)] [(Union: elems) (fp "~a" (cons 'U elems))] [(Pair: l r) (fp "(Pair ~a ~a)" l r)] - [(F: nm) (fp "<~a>" nm)] + [(F: nm) (fp "~a" nm)] [(Values: (list v ...)) (fp "~a" (cons 'values v))] [(Param: in out) (if (equal? in out)