025-deref-postinc.scm (2633B)
1 ;; tests/cc-cg/25-deref-postinc.scm — *p++ walking an array (§B.5). 2 ;; 3 ;; Models: 4 ;; int a[3]; a[0]=1; a[1]=2; a[2]=4; 5 ;; int *p = &a[0]; 6 ;; int s = 0; 7 ;; s += *p++; // 1, p -> a[1] 8 ;; s += *p++; // 2, p -> a[2] 9 ;; s += *p++; // 4, p -> a[3] 10 ;; return s; // 7 11 ;; 12 ;; Exercises post-inc on a pointer (must scale by sizeof(int)) plus 13 ;; pointer-deref + pointer-arith composition. 14 15 (let ((cg (cg-init))) 16 (cg-fn-begin cg "main" '() %t-i32) 17 (let* ((arr-i32 (%ctype 'arr 12 4 (cons %t-i32 3))) 18 (off-a (cg-alloc-slot cg 12 4)) 19 (sym-a (%sym "a" 'var 'auto arr-i32 off-a)) 20 (off-p (cg-alloc-slot cg 8 8)) 21 (ptr-i32 (%ctype 'ptr 8 8 %t-i32)) 22 (sym-p (%sym "p" 'var 'auto ptr-i32 off-p)) 23 (off-s (cg-alloc-slot cg 4 4)) 24 (sym-s (%sym "s" 'var 'auto %t-i32 off-s))) 25 ;; a[i] = vals[i] — use &a (cast to ptr-i32) + i + push-deref 26 (let store-elem ((i 0) (vals '(1 2 4))) 27 (cond 28 ((null? vals) #t) 29 (else 30 (cg-push-sym cg sym-a) ; lval arr 31 (cg-take-addr cg) ; rval ptr-to-arr 32 (cg-cast cg ptr-i32) ; rval ptr-to-int 33 (cg-push-imm cg %t-i32 i) 34 (cg-binop cg 'add) ; ptr + i (scaled by 4) 35 (cg-push-deref cg) ; lval int 36 (cg-push-imm cg %t-i32 (car vals)) 37 (cg-assign cg) (cg-pop cg) 38 (store-elem (+ i 1) (cdr vals))))) 39 ;; p = &a[0] ; &a (arr) take-addr → ptr-to-arr; cast to ptr-int 40 (cg-push-sym cg sym-p) 41 (cg-push-sym cg sym-a) 42 (cg-take-addr cg) 43 (cg-cast cg ptr-i32) 44 (cg-assign cg) (cg-pop cg) 45 ;; s = 0 46 (cg-push-sym cg sym-s) 47 (cg-push-imm cg %t-i32 0) 48 (cg-assign cg) (cg-pop cg) 49 ;; Three iterations: s += *p++ 50 (let walk ((k 0)) 51 (cond 52 ((= k 3) #t) 53 (else 54 (cg-push-sym cg sym-s) ; lval s 55 (cg-dup cg) (cg-load cg) ; [lval-s, rval-s] 56 ;; compute *p++: push p (lval ptr); cg-postinc → old ptr value; 57 ;; push-deref → lval int. 58 (cg-push-sym cg sym-p) ; lval p (ptr-i32) 59 (cg-postinc cg) ; pushes OLD ptr rval, p slot now bumped 60 (cg-push-deref cg) ; lval int 61 (cg-load cg) ; rval int 62 ;; arith: s + *p_old 63 (cg-binop cg 'add) 64 (cg-assign cg) (cg-pop cg) 65 (walk (+ k 1))))) 66 ;; return s 67 (cg-push-sym cg sym-s) (cg-load cg) 68 (cg-return cg)) 69 (cg-fn-end cg) 70 (write-bv-fd 1 (cg-finish cg)))