racket/collects/scheme/private/contract-basic-opters.ss
2008-02-24 21:27:36 +00:00

133 lines
4.0 KiB
Scheme

#lang scheme/base
(require "contract-guts.ss"
"contract-opt.ss"
"contract.ss")
(require (for-syntax scheme/base
"contract-opt-guts.ss"))
;;
;; opt/pred helper
;;
(define-for-syntax (opt/pred opt/info pred)
(with-syntax ((pred pred))
(values
(with-syntax ((val (opt/info-val opt/info))
(ctc (opt/info-contract opt/info))
(pos (opt/info-pos opt/info))
(src-info (opt/info-src-info opt/info))
(orig-str (opt/info-orig-str opt/info)))
(syntax (if (pred val)
val
(raise-contract-error
val
src-info
pos
orig-str
"expected <~a>, given: ~e"
((name-get ctc) ctc)
val))))
null
null
null
(syntax (pred val))
#f
null)))
;;
;; built-in predicate opters
;;
(define/opter (null? opt/i opt/info stx)
(syntax-case stx (null?)
[null? (opt/pred opt/info #'null?)]))
(define/opter (boolean? opt/i opt/info stx)
(syntax-case stx (boolean?)
[boolean? (opt/pred opt/info #'boolean?)]))
(define/opter (integer? opt/i opt/info stx)
(syntax-case stx (integer?)
[integer? (opt/pred opt/info #'integer?)]))
(define/opter (char? opt/i opt/info stx)
(syntax-case stx (char?)
[char? (opt/pred opt/info #'char?)]))
(define/opter (number? opt/i opt/info stx)
(syntax-case stx (number?)
[number? (opt/pred opt/info #'number?)]))
(define/opter (pair? opt/i opt/info stx)
(syntax-case stx (pair?)
[pair? (opt/pred opt/info #'pair?)]))
(define/opter (not opt/i opt/info stx)
(syntax-case stx (not)
[not (opt/pred opt/info #'not)]))
;;
;; any/c
;;
(define/opter (any/c opt/i opt/info stx)
(syntax-case stx (any/c)
[any/c (values
(opt/info-val opt/info)
null
null
null
#'#t
#f
null)]))
;;
;; false/c
;;
(define/opter (false/c opt/i opt/info stx)
(syntax-case stx (false/c)
[false/c (opt/pred opt/info #'not)]))
;;
;; flat-contract helper
;;
(define-for-syntax (opt/flat-ctc opt/info pred checker)
(syntax-case pred (null? number? integer? boolean? pair? not)
;; Better way of doing this?
[null? (opt/pred opt/info pred)]
[number? (opt/pred opt/info pred)]
[integer? (opt/pred opt/info pred)]
[boolean? (opt/pred opt/info pred)]
[pair? (opt/pred opt/info pred)]
[pred
(let* ((lift-vars (generate-temporaries (syntax (pred error-check))))
(lift-pred (car lift-vars)))
(with-syntax ((val (opt/info-val opt/info))
(ctc (opt/info-contract opt/info))
(pos (opt/info-pos opt/info))
(src-info (opt/info-src-info opt/info))
(orig-str (opt/info-orig-str opt/info))
(lift-pred lift-pred))
(values
(syntax (if (lift-pred val)
val
(raise-contract-error
val
src-info
pos
orig-str
"expected <~a>, given: ~e"
((name-get ctc) ctc)
val)))
(interleave-lifts
lift-vars
(list #'pred (cond [(eq? checker 'check-flat-contract) #'(check-flat-contract lift-pred)]
[(eq? checker 'check-flat-named-contract) #'(check-flat-named-contract lift-pred)])))
null
null
(syntax (lift-pred val))
#f
null)))]))
;;
;; flat-contract and friends
;;
(define/opter (flat-contract opt/i opt/info stx)
(syntax-case stx (flat-contract)
[(flat-contract pred) (opt/flat-ctc opt/info #'pred 'check-flat-contract)]))
(define/opter (flat-named-contract opt/i opt/info stx)
(syntax-case stx (flat-named-contract)
[(flat-named-contract name pred) (opt/flat-ctc opt/info #'pred 'check-flat-named-contract)]))