(module tc-if-unit (lib "a-unit.ss")
(require "planet-requires.ss"
"signatures.ss"
"type-rep.ss" "type-effect-convenience.ss" "lexical-env.ss" "effect-rep.ss"
"mutated-vars.ss"
"subtype.ss"
"remove-intersect.ss"
"union.ss"
"type-comparison.ss"
(lib "kerncase.ss" "syntax")
(lib "plt-match.ss")
(lib "trace.ss"))
(require-galore)
(require-for-template mzscheme)
(import typechecker^)
(export tc-if^)
(define (tc-expr/eff t/f expr effs)
(let ([flag (box #f)])
(define ((type-op f t) _ old)
(let ([new-t (f old t)])
(when (type-equal? new-t (Un))
(set-box! flag #t))
new-t))
(let loop ([effs effs])
(define-syntax check-rest
(syntax-rules ()
[(check-rest f v)
(with-update-type/lexical f v (loop (cdr effs)))]
[(check-rest f t v) (check-rest (type-op f t) v)]))
(if (null? effs)
(let ([ty (tc-expr expr)])
(if (unbox flag)
(ret (Un))
(begin (printf "returning ~a ~a~n" (syntax-object->datum expr) ty) ty)))
(match (car effs)
[(True-Effect:)
(or t/f (set-box! flag #t))
(loop (cdr effs))]
[(False-Effect:)
(and t/f (set-box! flag #t))
(loop (cdr effs))]
[(Restrict-Effect: t v) (check-rest restrict t v)]
[(Remove-Effect: t v) (check-rest remove t v)]
[(Var-False-Effect: v) (check-rest (lambda (_ old) (-val #f)) v)]
[(Var-True-Effect: v) (check-rest remove (-val #f) v)])))))
(define (tc/if-onearm tst body) (tc/if-twoarm tst body (syntax/loc body (#%app void))))
(define (tc/if-twoarm tst thn els)
(match-let* ([(tc-result: tst-ty tst-thn-eff tst-els-eff) (tc-expr tst)]
[(tc-result: thn-ty thn-thn-eff thn-els-eff) (tc-expr/eff #t thn tst-thn-eff)]
[_ (printf "v is ~a~n" v)]
[c (current-milliseconds)]
[(tc-result: els-ty els-thn-eff els-els-eff) (tc-expr/eff #f els tst-els-eff)])
(printf "v now is ~a~n" (ret els-ty els-thn-eff els-els-eff))
(printf "els-ty ~a ~a~n"
els-ty c)
(match (list thn-thn-eff thn-els-eff els-thn-eff els-els-eff)
[(list (list (True-Effect:)) (list (True-Effect:)) (list (Restrict-Effect: t v)) (list (Remove-Effect: t v*)))
(=> unmatch)
(match (list tst-thn-eff tst-els-eff)
[(list (list (Restrict-Effect: s u)) (list (Remove-Effect: s u*)))
(if (and
(module-identifier=? u u*)
(module-identifier=? v v*)
(module-identifier=? v u))
(ret (Un (-val #t) els-ty)
(list (make-Restrict-Effect (Un s t) v))
(list (make-Remove-Effect (Un s t) v)))
(unmatch))]
[_ (unmatch)])]
[(list _ _ (list (False-Effect:)) (list (False-Effect:)))
(ret (Un (-val #f) thn-ty)
(append (map var->type-eff tst-thn-eff) thn-thn-eff)
(list))]
[_
(printf "els-ty ~a ~a~n"
els-ty c)
(printf "----------------------~nels-ty ~a ~nUn~a~n ~a~n"
els-ty (Un thn-ty els-ty) c)
(ret (Un thn-ty els-ty))])))
)