#lang racket/base (require (rename-in "utils/utils.rkt" [infer r:infer]) (private with-types) (for-syntax (except-in syntax/parse id) racket/match unstable/syntax racket/base unstable/match (private type-contract) (optimizer optimizer) (types utils convenience) (typecheck typechecker provide-handling tc-toplevel) (env type-name-env type-alias-env) (r:infer infer) (utils tc-utils) (rep type-rep) (except-in (utils utils) infer) (only-in (r:infer infer-dummy) infer-param) "tc-setup.rkt")) (provide (rename-out [module-begin #%module-begin] [top-interaction #%top-interaction] [#%plain-lambda lambda] [#%app #%app] [require require]) with-type) (define-syntax (module-begin stx) (syntax-parse stx [(mb (~optional (~and #:optimize (~bind [opt? #'#t]))) forms ...) (let ([pmb-form (syntax/loc stx (#%plain-module-begin forms ...))]) (parameterize ([optimize? (or (optimize?) (attribute opt?))]) (tc-setup stx pmb-form 'module-begin new-mod tc-module after-code (with-syntax* (;; pmb = #%plain-module-begin [(pmb . body2) new-mod] ;; add in syntax property on useless expression to draw check-syntax arrows [check-syntax-help (syntax-property #'(void) 'disappeared-use (type-name-references))] ;; perform the provide transformation from [Culpepper 07] [transformed-body (remove-provides #'body2)] ;; add the real definitions of contracts on requires [transformed-body (change-contract-fixups #'transformed-body)] ;; potentially optimize the code based on the type information [(optimized-body ...) ;; do we optimize? (if (optimize?) (begin0 (map optimize-top (syntax->list #'transformed-body)) (do-time "Optimized")) #'transformed-body)]) ;; reconstruct the module with the extra code ;; use the regular %#module-begin from `racket/base' for top-level printing #`(#%module-begin optimized-body ... #,after-code check-syntax-help)))))])) (define-syntax (top-interaction stx) (syntax-parse stx [(_ . ((~datum module) . rest)) #'(module . rest)] [(_ . form) (tc-setup stx #'form 'top-level body2 tc-toplevel-form type (syntax-parse body2 ;; any of these do not produce an expression to be printed [(head:invis-kw . _) body2] [_ (let ([ty-str (match type ;; don't print results of type void [(tc-result1: (== -Void type-equal?)) #f] [(tc-result1: t f o) (format "- : ~a\n" t)] [(tc-results: t) (format "- : ~a\n" (cons 'Values t))] [x (int-err "bad type result: ~a" x)])]) (if ty-str #`(let ([type '#,ty-str]) (begin0 #,body2 (display type))) body2))]))]))