|
|
|
#lang racket/base
|
|
|
|
(require (for-syntax racket/base))
|
|
|
|
(require racket/contract)
|
|
|
|
|
|
|
|
(provide (all-from-out racket/contract))
|
|
|
|
|
|
|
|
;; get gets of typed source file, recompile it without typing in a submodule,
|
|
|
|
;; then require those identifiers into the current level.
|
|
|
|
(define-syntax (require-via-wormhole stx)
|
|
|
|
(syntax-case stx ()
|
|
|
|
[(_ path-spec)
|
|
|
|
(let ([mod-name (gensym)])
|
|
|
|
;; need to use stx as context to get correct require behavior
|
|
|
|
(datum->syntax stx `(begin
|
|
|
|
(module mod-name typed/racket/base/no-check
|
|
|
|
(require sugar/unstable/include)
|
|
|
|
(include-without-lang-line ,(syntax->datum #'path-spec)))
|
|
|
|
(require (quote mod-name)))))]))
|
|
|
|
|
|
|
|
;; each define macro recursively converts any form of define
|
|
|
|
;; into its lambda form (define name body ...) and then operates on that.
|
|
|
|
|
|
|
|
(define-syntax (make-safe-module stx)
|
|
|
|
(syntax-case stx ()
|
|
|
|
[(_ name contract)
|
|
|
|
#'(module+ safe
|
|
|
|
(require racket/contract)
|
|
|
|
(provide (contract-out [name contract])))]
|
|
|
|
[(_ name)
|
|
|
|
#'(module+ safe
|
|
|
|
(provide name))]))
|
|
|
|
|
|
|
|
(define-syntax (define+provide+safe stx)
|
|
|
|
(syntax-case stx ()
|
|
|
|
[(_ (proc arg ... . rest-arg) contract body ...)
|
|
|
|
#'(define+provide+safe proc contract
|
|
|
|
(λ(arg ... . rest-arg) body ...))]
|
|
|
|
[(_ name contract body ...)
|
|
|
|
#'(begin
|
|
|
|
(define name body ...)
|
|
|
|
(provide name)
|
|
|
|
(make-safe-module name contract))]))
|
|
|
|
|
|
|
|
;; for previously defined identifiers
|
|
|
|
;; takes args like (provide+safe [ident contract]) or just (provide+safe ident)
|
|
|
|
;; any number of args.
|
|
|
|
(define-syntax (provide+safe stx)
|
|
|
|
(syntax-case stx ()
|
|
|
|
[(_ items ...)
|
|
|
|
(datum->syntax stx
|
|
|
|
`(begin
|
|
|
|
,@(for/list ([item (in-list (syntax->datum #'(items ...)))])
|
|
|
|
(define-values (name contract) (if (pair? item)
|
|
|
|
(values (car item) (cadr item))
|
|
|
|
(values item #f)))
|
|
|
|
`(begin
|
|
|
|
(provide ,name)
|
|
|
|
(make-safe-module ,name ,@(if contract (list contract) null))))))]))
|
|
|
|
|
|
|
|
(define-syntax (define+provide/contract stx)
|
|
|
|
(syntax-case stx ()
|
|
|
|
[(_ (proc arg ... . rest-arg) contract body ...)
|
|
|
|
#'(define+provide/contract proc contract
|
|
|
|
(λ(arg ... . rest-arg) body ...))]
|
|
|
|
[(_ name contract body ...)
|
|
|
|
#'(begin
|
|
|
|
(provide (contract-out [name contract]))
|
|
|
|
(define name body ...))]))
|
|
|
|
|
|
|
|
|
|
|
|
(define-syntax (define/contract+provide stx)
|
|
|
|
(syntax-case stx ()
|
|
|
|
[(_ (proc arg ... . rest-arg) contract body ...)
|
|
|
|
#'(define/contract+provide proc contract
|
|
|
|
(λ(arg ... . rest-arg) body ...))]
|
|
|
|
[(_ name contract body ...)
|
|
|
|
#'(begin
|
|
|
|
(provide name)
|
|
|
|
(define/contract name contract body ...))]))
|
|
|
|
|
|
|
|
|
|
|
|
(define-syntax (define+provide stx)
|
|
|
|
(syntax-case stx ()
|
|
|
|
[(_ (proc arg ... . rest-arg) body ...)
|
|
|
|
#'(define+provide proc
|
|
|
|
(λ(arg ... . rest-arg) body ...))]
|
|
|
|
[(_ name body ...)
|
|
|
|
#'(begin
|
|
|
|
(provide name)
|
|
|
|
(define name body ...))]))
|
|
|
|
|
|
|
|
(provide+safe require-via-wormhole
|
|
|
|
make-safe-module
|
|
|
|
define+provide+safe
|
|
|
|
provide+safe
|
|
|
|
define+provide/contract
|
|
|
|
define/contract+provide
|
|
|
|
define+provide)
|