pre.rkt (2963B)
1 #lang racket/base 2 3 (require syntax/parse 4 (for-syntax racket/base 5 syntax/parse 6 racket/syntax 7 phc-toolkit/untyped) 8 "parameters.rkt" 9 "no-order.rkt" 10 "nop.rkt") 11 12 (provide ~pre-check 13 ~pre-fail 14 ~named-seq 15 ~maybe/empty) 16 17 (define-eh-mixin-expander ~pre-check 18 (λ (stx) 19 (syntax-case stx () 20 [(_ pat post) 21 (begin (eh-pre-accumulate! '~pre-check #'post) 22 #'pat)] 23 [(_ post) 24 (begin (eh-pre-accumulate! '~pre-check #'post) 25 #'(~nop))]))) 26 27 (define-for-syntax (pre-fail stx) 28 (syntax-case stx () 29 [(_ message #:when condition) 30 (let () 31 (define/with-syntax clause-present (get-new-clause!)) 32 (eh-pre-accumulate! '~pre-fail 33 #`(~fail #:when (and (attribute clause-present) 34 condition) 35 message)) 36 #'(~bind [clause-present #t]))] 37 [(self #:when condition message) 38 (pre-fail #'(self message #:when condition))] 39 [(self message #:unless unless-condition) 40 (pre-fail #'(self message #:when (not unless-condition)))] 41 [(self #:unless unless-condition message) 42 (pre-fail #'(self message #:when (not unless-condition)))])) 43 44 (define-eh-mixin-expander ~pre-fail pre-fail) 45 46 ;; TODO: fixme: should happen before the other pre operations 47 (define-eh-mixin-expander ~named-seq 48 (λ (stx) 49 (syntax-case stx () 50 [(_ id . pats) 51 (identifier? #'id) 52 (let () 53 (define/with-syntax clause-present (get-new-clause!)) 54 (define/with-syntax clause (get-new-clause!)) 55 (eh-first-accumulate! '~named-seq 56 #'(~bind [(id 1) (if (attribute clause-present) 57 (attribute clause) 58 (list))])) 59 #'(~and (~bind [clause-present #t]) 60 (~seq clause (... ...)) 61 (~seq . pats)))]))) 62 63 64 ;; TODO: fixme: should happen before the other pre operations 65 (define-eh-mixin-expander ~maybe/empty 66 (syntax-parser 67 [(_ {~and pat {~not #:name}} … 68 {~optional {~seq #:name name}}) 69 (let () 70 (define/with-syntax clause-present (get-new-clause!)) 71 (define/with-syntax (expanded-pat …) 72 ;; let the ~post, ~global etc. within pat … be recognized 73 (expand-all-eh-mixin-expanders #'(pat …))) 74 (eh-first-accumulate! '~maybe/empty 75 #'(~parse (expanded-pat …) 76 (if (attribute clause) 77 #'(clause (... ...)) 78 #'()))) 79 #`{~optional {~and {~bind [clause-present #t]} 80 {~seq clause (... ...)}} 81 #,@(when-attr name #'(#:name name))})]))