deriv-util.rkt (2988B)
1 #lang racket/base 2 (require (for-syntax racket/base racket/struct-info) 3 racket/match 4 "deriv.rkt") 5 6 (provide make 7 8 Wrap 9 10 ok-node? 11 interrupted-node? 12 13 wderiv-e1 14 wderiv-e2 15 wlderiv-es1 16 wlderiv-es2 17 wbderiv-es1 18 wbderiv-es2 19 20 wderivlist-es2) 21 22 ;; Wrap matcher 23 ;; Matches unwrapped, interrupted wrapped, or error wrapped 24 (define-match-expander Wrap 25 (lambda (stx) 26 (syntax-case stx () 27 [(Wrap S (var ...)) 28 (syntax/loc stx (struct S (var ...)))]))) 29 30 ;; ---- 31 32 (define (check sym pred type x) 33 (unless (pred x) 34 (raise-type-error sym type x))) 35 36 (define (ok-node? x) 37 (check 'ok-node? node? "node" x) 38 (and (node-z2 x) #t)) 39 (define (interrupted-node? x) 40 (check 'interrupted-node? node? "node" x) 41 (not (node-z2 x))) 42 43 44 (define (wderiv-e1 x) 45 (check 'wderiv-e1 deriv? "deriv" x) 46 (node-z1 x)) 47 (define (wderiv-e2 x) 48 (check 'wderiv-e2 deriv? "deriv" x) 49 (node-z2 x)) 50 51 (define (wlderiv-es1 x) 52 (check 'wlderiv-es1 lderiv? "lderiv" x) 53 (node-z1 x)) 54 (define (wlderiv-es2 x) 55 (check 'wlderiv-es2 lderiv? "lderiv" x) 56 (node-z2 x)) 57 58 (define (wbderiv-es1 x) 59 (check 'wbderiv-es1 bderiv? "bderiv" x) 60 (node-z1 x)) 61 (define (wbderiv-es2 x) 62 (check 'wbderiv-es2 bderiv? "bderiv" x)) 63 64 ;; wderivlist-es2 : (list-of WDeriv) -> (list-of Stx)/#f 65 (define (wderivlist-es2 xs) 66 (let ([es2 (map wderiv-e2 xs)]) 67 (and (andmap syntax? es2) es2))) 68 69 ;; get-struct-info : identifier stx -> struct-info-list 70 (define-for-syntax (get-struct-info id ctx) 71 (define (bad-struct-name x) 72 (raise-syntax-error #f "expected struct name" ctx x)) 73 (unless (identifier? id) 74 (bad-struct-name id)) 75 (let ([value (syntax-local-value id (lambda () #f))]) 76 (unless (struct-info? value) 77 (bad-struct-name id)) 78 (extract-struct-info value))) 79 80 ;; (make struct-name field-expr ...) 81 ;; Checks that correct number of fields given. 82 (define-syntax (make stx) 83 (syntax-case stx () 84 [(make S expr ...) 85 (let () 86 (define info (get-struct-info #'S stx)) 87 (define constructor (list-ref info 1)) 88 (define accessors (list-ref info 3)) 89 (unless (identifier? #'constructor) 90 (raise-syntax-error #f "constructor not available for struct" stx #'S)) 91 (unless (andmap identifier? accessors) 92 (raise-syntax-error #f "incomplete info for struct type" stx #'S)) 93 (let ([num-slots (length accessors)] 94 [num-provided (length (syntax->list #'(expr ...)))]) 95 (unless (= num-provided num-slots) 96 (raise-syntax-error 97 #f 98 (format "wrong number of arguments for struct ~s (expected ~s, got ~s)" 99 (syntax-e #'S) 100 num-slots 101 num-provided) 102 stx))) 103 (with-syntax ([constructor constructor]) 104 (syntax-property #'(constructor expr ...) 105 'disappeared-use 106 #'S)))]))