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