boot2

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

commit 53f1be65ea19367289b852dc6d3f1676d8f3ad35
parent f18b740fb0d49db51a671bf3ab0dac51646bdcac
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Sun, 26 Apr 2026 22:41:57 -0700

cc/cg: array element access at non-zero index (§D.5)

Locks in the array-decay + pointer-arithmetic path that cg-push-field
shipped with in §D.1. The cg fixture pushes the arr-typed lval,
cg-load decays it to a ptr-to-elem rval, cg-binop add scales the
index, cg-push-deref produces an element lval. Three writes (1, 2, 4)
and a 3-term sum read back to 7 isolate every index — a wrong scale
or wrong base shows up as a different sum.

Diffstat:
Atests/cc-cg/40-array-index.expected-exit | 1+
Atests/cc-cg/40-array-index.scm | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/tests/cc-cg/40-array-index.expected-exit b/tests/cc-cg/40-array-index.expected-exit @@ -0,0 +1 @@ +7 diff --git a/tests/cc-cg/40-array-index.scm b/tests/cc-cg/40-array-index.scm @@ -0,0 +1,55 @@ +;; tests/cc-cg/40-array-index.scm — array element access at non-zero +;; index (§D.5 of docs/CC-PUNCHLIST.md). Models: +;; int a[3]; a[0]=1; a[1]=2; a[2]=4; return a[0]+a[1]+a[2]; -> 7 +;; +;; The cg API does the same dance the parser uses for a[i]: +;; cg-push-sym sym-a ; arr-typed lval +;; cg-push-imm i ; index rval +;; cg-binop add ; ptr arithmetic — `cg-load` decays array to +;; ; ptr, then add scales by elem size +;; cg-push-deref ; lval int through the computed pointer +;; +;; Wait — cg-binop pops both ops; for the lhs we need rval-of-arr, +;; not the array lval. We therefore call cg-load BEFORE the index +;; push, so the arr lval decays to a ptr-rval first. + +(let* ((cg (cg-init)) + (arr-ty (%ctype 'arr 12 4 (cons %t-i32 3)))) + (cg-fn-begin cg "main" '() %t-i32) + (let* ((off-a (cg-alloc-slot cg 12 4)) + (sym-a (%sym "a" 'var 'auto arr-ty off-a))) + ;; a[0] = 1 + (cg-push-sym cg sym-a) + (cg-load cg) ; arr lval -> ptr rval (decay) + (cg-push-imm cg %t-i32 0) + (cg-binop cg 'add) ; ptr + 0 + (cg-push-deref cg) + (cg-push-imm cg %t-i32 1) + (cg-assign cg) (cg-pop cg) + ;; a[1] = 2 + (cg-push-sym cg sym-a) (cg-load cg) + (cg-push-imm cg %t-i32 1) (cg-binop cg 'add) + (cg-push-deref cg) + (cg-push-imm cg %t-i32 2) + (cg-assign cg) (cg-pop cg) + ;; a[2] = 4 + (cg-push-sym cg sym-a) (cg-load cg) + (cg-push-imm cg %t-i32 2) (cg-binop cg 'add) + (cg-push-deref cg) + (cg-push-imm cg %t-i32 4) + (cg-assign cg) (cg-pop cg) + ;; return a[0] + a[1] + a[2] + (cg-push-sym cg sym-a) (cg-load cg) + (cg-push-imm cg %t-i32 0) (cg-binop cg 'add) + (cg-push-deref cg) (cg-load cg) + (cg-push-sym cg sym-a) (cg-load cg) + (cg-push-imm cg %t-i32 1) (cg-binop cg 'add) + (cg-push-deref cg) (cg-load cg) + (cg-binop cg 'add) + (cg-push-sym cg sym-a) (cg-load cg) + (cg-push-imm cg %t-i32 2) (cg-binop cg 'add) + (cg-push-deref cg) (cg-load cg) + (cg-binop cg 'add) + (cg-return cg)) + (cg-fn-end cg) + (write-bv-fd 1 (cg-finish cg)))