037-struct-store.scm (2093B)
1 ;; tests/cc-cg/37-struct-store.scm — struct member store via cg-push-field. 2 ;; Uses char-typed fields to ensure the width-correct store path from 3 ;; the byte-roundtrip test (15-char-roundtrip) cooperates with field 4 ;; offsets. 5 ;; 6 ;; struct B { unsigned char a; unsigned char b; unsigned char c; }; 7 ;; b.a = 3; b.b = 5; b.c = 7; 8 ;; If field stores ignored offsets (or used 8-byte writes), adjacent 9 ;; bytes would clobber each other. Reading back a*1 + b*10 + c*100 10 ;; isolates each field's contribution: 3 + 50 + 700 = 753. (Truncated 11 ;; to a u8 by the exit-code path: 753 & 255 = 241.) 12 13 (let* ((cg (cg-init)) 14 (st-ty (%ctype 'struct 3 1 15 (list "B" #t 16 (list (list "a" %t-u8 0) 17 (list "b" %t-u8 1) 18 (list "c" %t-u8 2)))))) 19 (cg-fn-begin cg "main" '() %t-i32) 20 (let* ((off-b (cg-alloc-slot cg 3 1)) 21 (sym-b (%sym "b" 'var 'auto st-ty off-b))) 22 ;; b.a = 3 23 (cg-push-sym cg sym-b) 24 (cg-push-field cg "a") 25 (cg-push-imm cg %t-u8 3) 26 (cg-assign cg) (cg-pop cg) 27 ;; b.b = 5 28 (cg-push-sym cg sym-b) 29 (cg-push-field cg "b") 30 (cg-push-imm cg %t-u8 5) 31 (cg-assign cg) (cg-pop cg) 32 ;; b.c = 7 33 (cg-push-sym cg sym-b) 34 (cg-push-field cg "c") 35 (cg-push-imm cg %t-u8 7) 36 (cg-assign cg) (cg-pop cg) 37 ;; return (b.a + b.b*10 + b.c*100) == 753. 38 ;; Cast each u8 load to i32 so cg-binop's narrow-result canon 39 ;; doesn't truncate the products (700 mod 256 = 188). 40 (cg-push-sym cg sym-b) 41 (cg-push-field cg "a") 42 (cg-load cg) (cg-cast cg %t-i32) 43 (cg-push-sym cg sym-b) 44 (cg-push-field cg "b") 45 (cg-load cg) (cg-cast cg %t-i32) 46 (cg-push-imm cg %t-i32 10) 47 (cg-binop cg 'mul) 48 (cg-binop cg 'add) 49 (cg-push-sym cg sym-b) 50 (cg-push-field cg "c") 51 (cg-load cg) (cg-cast cg %t-i32) 52 (cg-push-imm cg %t-i32 100) 53 (cg-binop cg 'mul) 54 (cg-binop cg 'add) 55 (cg-push-imm cg %t-i32 753) 56 (cg-binop cg 'eq) 57 (cg-return cg)) 58 (cg-fn-end cg) 59 (write-bv-fd 1 (cg-finish cg)))