boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

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)))