(module type-annotation mzscheme
(require "type-rep.ss" "parse-type.ss" "tc-utils.ss" "subtype.ss" "utils.ss" "union.ss")
(require (lib "plt-match.ss"))
(provide (all-defined))
(define type-label-symbol 'type-label)
(define type-ascrip-symbol 'type-ascription)
(define (print-size stx)
(syntax-case stx ()
[(a . b) (begin
(printf/log "Annotation Sexp Pair ~n")
(print-size #'a)
(print-size #'b))]
[_ (printf/log "Annotation Sexp ~n" )]))
(define (type-annotation stx)
(define (pt prop)
(print-size prop)
(if (syntax? prop)
(parse-type prop)
(parse-type/id stx prop)))
(cond
[(syntax-property stx type-label-symbol) => pt]
[(syntax-property stx type-ascrip-symbol) => pt]
[else #f]))
(define (log/ann stx ty)
(printf/log "Required Annotated Variable: ~a ~a~n" (syntax-e stx) ty))
(define (log/extra stx ty ty2)
(printf/log "Extra Annotated Variable: ~a ~a ~a~n" (syntax-e stx) ty ty2))
(define (log/noann stx ty)
(printf/log "Unannotated Variable: ~a ~a~n" (syntax-e stx) ty))
(define (get-type stx)
(parameterize
([current-orig-stx stx])
(cond
[(type-annotation stx) => (lambda (x)
(log/ann stx x)
x)]
[(not (syntax-original? stx))
(tc-error "untyped var: ~a" (syntax-e stx))]
[else
(tc-error "no type information on variable ~a" (syntax-e stx))])))
(define (get-type/infer stxs e-type)
(match (list stxs e-type)
[(list '() (Values: '())) (list)]
[(list (list stx) (? (lambda (x) (not (Values? x))) ty))
(cond [(type-annotation stx) => (lambda (ann)
(check-type stx ty ann)
(log/extra stx ty ann)
(list ann))]
[else (log/noann stx ty) (list ty)])]
[(list (list stx ...) (Values: (list ty ...)))
(map (lambda (stx ty)
(cond [(type-annotation stx) => (lambda (ann) (check-type stx ty ann) (log/extra stx ty ann) ann)]
[else (log/noann stx ty) ty]))
stx ty)]
[else (error 'internal-tc-error "Bad")]))
(define (check-type stx e-type ty)
(parameterize ([current-orig-stx stx])
(unless (subtype e-type ty)
(tc-error "Body had type:~n~a~nVariable had type:~n~a~n" e-type ty))))
)