121-record-introspection.scm (2161B)
1 ; Record introspection primitives: record?, record-td, record-ref, 2 ; record-set!, make-record/td, td-nfields, and td-name. 3 ; These operations also back the generic deep-copy walker. 4 5 (define-record-type point 6 (mk-point x y) 7 point? 8 (x point-x) 9 (y point-y point-y-set!)) 10 11 (define-record-type box 12 (mk-box val) 13 box? 14 (val box-val box-val-set!)) 15 16 (define p (mk-point 3 4)) 17 (define b (mk-box 7)) 18 19 ;; ---- record? ---- 20 (if (record? p) 0 (sys-exit 1)) 21 (if (record? b) 0 (sys-exit 2)) 22 (if (not (record? 5)) 0 (sys-exit 3)) 23 (if (not (record? "bv")) 0 (sys-exit 4)) 24 (if (not (record? '())) 0 (sys-exit 5)) 25 (if (not (record? '(a))) 0 (sys-exit 6)) 26 (if (not (record? 'sym)) 0 (sys-exit 7)) 27 (if (not (record? #f)) 0 (sys-exit 8)) 28 29 ;; ---- record-td: identity for instances of the same type ---- 30 (define td-p (record-td p)) 31 (define p2 (mk-point 9 10)) 32 (if (eq? td-p (record-td p2)) 0 (sys-exit 10)) 33 ;; Different types yield different TDs 34 (if (not (eq? td-p (record-td b))) 0 (sys-exit 11)) 35 36 ;; ---- td-nfields ---- 37 (if (= 2 (td-nfields td-p)) 0 (sys-exit 20)) 38 (if (= 1 (td-nfields (record-td b))) 0 (sys-exit 21)) 39 40 ;; ---- td-name ---- 41 (if (eq? 'point (td-name td-p)) 0 (sys-exit 30)) 42 (if (eq? 'box (td-name (record-td b))) 0 (sys-exit 31)) 43 44 ;; ---- record-ref reads slots by index ---- 45 (if (= 3 (record-ref p 0)) 0 (sys-exit 40)) 46 (if (= 4 (record-ref p 1)) 0 (sys-exit 41)) 47 (if (= 7 (record-ref b 0)) 0 (sys-exit 42)) 48 49 ;; ---- record-set! writes slots by index ---- 50 (record-set! p 1 42) 51 (if (= 42 (point-y p)) 0 (sys-exit 50)) 52 (if (= 42 (record-ref p 1)) 0 (sys-exit 51)) 53 (record-set! b 0 'tagged) 54 (if (eq? 'tagged (box-val b)) 0 (sys-exit 52)) 55 56 ;; ---- make-record/td: zero-filled to UNSPEC, then fillable ---- 57 (define p3 (make-record/td td-p)) 58 (if (record? p3) 0 (sys-exit 60)) 59 (if (eq? td-p (record-td p3)) 0 (sys-exit 61)) 60 (if (point? p3) 0 (sys-exit 62)) 61 (record-set! p3 0 100) 62 (record-set! p3 1 200) 63 (if (= 100 (point-x p3)) 0 (sys-exit 63)) 64 (if (= 200 (point-y p3)) 0 (sys-exit 64)) 65 66 (sys-exit 42)