/racket-5-0-2-bin-i386-osx-mac-dmg/collects/typed-scheme/typecheck/tc-let-unit.rkt

http://github.com/smorin/f4f.arc · Racket · 163 lines · 135 code · 11 blank · 17 comment · 26 complexity · 3b854a273aabfa5009eecc06b6c4fdc9 MD5 · raw file

  1. #lang racket/unit
  2. (require (rename-in "../utils/utils.rkt" [infer r:infer])
  3. "signatures.rkt" "tc-metafunctions.rkt" "tc-subst.rkt"
  4. "check-below.rkt"
  5. (types utils convenience)
  6. (private type-annotation parse-type)
  7. (env lexical-env type-alias-env global-env type-env-structs)
  8. (rep type-rep)
  9. syntax/free-vars
  10. ;racket/trace unstable/debug
  11. racket/match (prefix-in c: racket/contract)
  12. (except-in racket/contract -> ->* one-of/c)
  13. syntax/kerncase syntax/parse
  14. unstable/debug
  15. (for-template
  16. racket/base
  17. "internal-forms.rkt"))
  18. (require (only-in srfi/1/list s:member))
  19. (import tc-expr^)
  20. (export tc-let^)
  21. (define (erase-filter tc)
  22. (match tc
  23. [(tc-results: ts _ _)
  24. (ret ts (for/list ([f ts]) (make-NoFilter)) (for/list ([f ts]) (make-NoObject)))]))
  25. (d/c (do-check expr->type namess results form exprs body clauses expected #:abstract [abstract null])
  26. (((syntax? syntax? tc-results? . c:-> . any/c)
  27. (listof (listof identifier?)) (listof tc-results?)
  28. syntax? (listof syntax?) syntax? (listof syntax?) (or/c #f tc-results?))
  29. (#:abstract any/c)
  30. . c:->* .
  31. tc-results?)
  32. (w/c t/p ([types (listof (listof Type/c))]
  33. [props (listof (listof Filter?))])
  34. (define-values (types props)
  35. (for/lists (t p)
  36. ([r (in-list results)]
  37. [names (in-list namess)])
  38. (match r
  39. [(tc-results: ts (FilterSet: fs+ fs-) os)
  40. ;(printf "f+: ~a\n" fs+)
  41. ;(printf "f-: ~a\n" fs-)
  42. (values ts
  43. (apply append
  44. (for/list ([n names]
  45. [f+ fs+]
  46. [f- fs-])
  47. (list (make-ImpFilter (-not-filter (-val #f) n) f+)
  48. (make-ImpFilter (-filter (-val #f) n) f-)))))]
  49. [(tc-results: ts (NoFilter:) _) (values ts null)]))))
  50. ;; extend the lexical environment for checking the body
  51. (with-lexical-env/extend/props
  52. ;; the list of lists of name
  53. namess
  54. ;; the types
  55. types
  56. (w/c append-region
  57. #:result (listof Filter?)
  58. (define-values (p1 p2)
  59. (combine-props (apply append props) (env-props (lexical-env)) (box #t)))
  60. (append p1 p2))
  61. (for-each expr->type
  62. clauses
  63. exprs
  64. results)
  65. (let ([subber (lambda (proc lst)
  66. (for/list ([i (in-list lst)])
  67. (for/fold ([s i])
  68. ([nm (in-list (apply append abstract namess))])
  69. (proc s nm (make-Empty) #t))))])
  70. (define (run res)
  71. (match res
  72. [(tc-results: ts fs os)
  73. (ret (subber subst-type ts) (subber subst-filter-set fs) (subber subst-object os))]
  74. [(tc-results: ts fs os dt db)
  75. (ret (subber subst-type ts) (subber subst-filter-set fs) (subber subst-object os) dt db)]))
  76. (if expected
  77. (check-below
  78. (run (tc-exprs/check (syntax->list body) (erase-filter expected)))
  79. expected)
  80. (run (tc-exprs (syntax->list body)))))))
  81. (define (tc-expr/maybe-expected/t e name)
  82. (define expecteds
  83. (map (lambda (stx) (lookup-type stx (lambda () #f))) name))
  84. (define mk (if (and (pair? expecteds) (null? (cdr expecteds)))
  85. car
  86. -values))
  87. (define tcr
  88. (if
  89. (andmap values expecteds)
  90. (tc-expr/check e (mk expecteds))
  91. (tc-expr e)))
  92. tcr)
  93. (define (tc/letrec-values namess exprs body form [expected #f])
  94. (let* ([names (map syntax->list (syntax->list namess))]
  95. [orig-flat-names (apply append names)]
  96. [exprs (syntax->list exprs)]
  97. ;; the clauses for error reporting
  98. [clauses (syntax-case form () [(lv cl . b) (syntax->list #'cl)])])
  99. (for-each (lambda (names body)
  100. (kernel-syntax-case* body #f (values :-internal define-type-alias-internal)
  101. [(begin (quote-syntax (define-type-alias-internal nm ty)) (#%plain-app values))
  102. (register-resolved-type-alias #'nm (parse-type #'ty))]
  103. [(begin (quote-syntax (:-internal nm ty)) (#%plain-app values))
  104. (register-type-if-undefined #'nm (parse-type #'ty))]
  105. [_ (void)]))
  106. names
  107. exprs)
  108. (let loop ([names names] [exprs exprs] [flat-names orig-flat-names] [clauses clauses])
  109. (cond
  110. ;; after everything, check the body expressions
  111. [(null? names)
  112. (do-check void null null form null body null expected #:abstract orig-flat-names)
  113. #;
  114. (if expected (tc-exprs/check (syntax->list body) expected) (tc-exprs (syntax->list body)))]
  115. ;; if none of the names bound in the letrec are free vars of this rhs
  116. [(not (ormap (lambda (n) (s:member n flat-names bound-identifier=?)) (free-vars (car exprs))))
  117. ;; then check this expression separately
  118. (with-lexical-env/extend
  119. (list (car names))
  120. (list (match (get-type/infer (car names) (car exprs) (lambda (e) (tc-expr/maybe-expected/t e (car names)))
  121. tc-expr/check)
  122. [(tc-results: ts) ts]))
  123. (loop (cdr names) (cdr exprs) (apply append (cdr names)) (cdr clauses)))]
  124. [else
  125. ;(for-each (lambda (vs) (for-each (lambda (v) (printf/log "Letrec Var: ~a\n" (syntax-e v))) vs)) names)
  126. (do-check (lambda (stx e t) (tc-expr/check e t))
  127. names (map (Îť (l) (ret (map get-type l))) names) form exprs body clauses expected)]))))
  128. ;; this is so match can provide us with a syntax property to
  129. ;; say that this binding is only called in tail position
  130. (define ((tc-expr-t/maybe-expected expected) e)
  131. (syntax-parse e #:literals (#%plain-lambda)
  132. [(#%plain-lambda () _)
  133. #:fail-unless (and expected (syntax-property e 'typechecker:called-in-tail-position)) #f
  134. (tc-expr/check e (ret (-> (tc-results->values expected))))]
  135. [_
  136. #:fail-unless (and expected (syntax-property e 'typechecker:called-in-tail-position)) #f
  137. (tc-expr/check e expected)]
  138. [_ (tc-expr e)]))
  139. (define (tc/let-values namess exprs body form [expected #f])
  140. (let* (;; a list of each name clause
  141. [names (map syntax->list (syntax->list namess))]
  142. ;; all the trailing expressions - the ones actually bound to the names
  143. [exprs (syntax->list exprs)]
  144. ;; the types of the exprs
  145. #;[inferred-types (map (tc-expr-t/maybe-expected expected) exprs)]
  146. ;; the annotated types of the name (possibly using the inferred types)
  147. [types (for/list ([name names] [e exprs])
  148. (get-type/infer name e (tc-expr-t/maybe-expected expected)
  149. tc-expr/check))]
  150. ;; the clauses for error reporting
  151. [clauses (syntax-case form () [(lv cl . b) (syntax->list #'cl)])])
  152. (do-check void names types form exprs body clauses expected)))