boot2

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

commit db4d877362e9b952d72f15507e5e5fa481cd7b5d
parent 1609330a4c15372a20e6e3478499d792aaf66f9e
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Sun, 26 Apr 2026 22:39:33 -0700

cc/cg: lock in p->x arrow access via cg fixture (§D.3)

cg-push-deref + cg-push-field already supported the indirect path:
the ptr-rval is push-deref'd to a struct lval (frame-indirect),
then cg-push-field's indirect-frame branch loads the address, adds
the field offset, and stashes it in a new indirect slot. The
fixture composes the existing primitives end-to-end so any
regression in either lands here.

Diffstat:
Atests/cc-cg/38-arrow.expected-exit | 1+
Atests/cc-cg/38-arrow.scm | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/tests/cc-cg/38-arrow.expected-exit b/tests/cc-cg/38-arrow.expected-exit @@ -0,0 +1 @@ +5 diff --git a/tests/cc-cg/38-arrow.scm b/tests/cc-cg/38-arrow.scm @@ -0,0 +1,59 @@ +;; tests/cc-cg/38-arrow.scm — pointer-to-struct field access via cg +;; (§D.3 of docs/CC-PUNCHLIST.md). Models p->a / p->b through: +;; cg-push-sym sym-p ; lval (frame), holds ptr-value +;; cg-load ; rval ptr +;; cg-push-deref ; lval struct (indirect) +;; cg-push-field "a" ; lval int at p+0 +;; +;; struct S { int a; int b; }; struct S s; +;; struct S *p = &s; p->a = 4; p->b = 9; return p->b - p->a; +;; (The cg fixture takes &s into a frame slot directly so we don't +;; depend on parser-only address-of plumbing.) +;; +;; Expected: 9 - 4 == 5. + +(let* ((cg (cg-init)) + (st-ty (%ctype 'struct 8 4 + (list "S" #t + (list (list "a" %t-i32 0) + (list "b" %t-i32 4))))) + (pt-ty (%ctype 'ptr 8 8 st-ty))) + (cg-fn-begin cg "main" '() %t-i32) + (let* ((off-s (cg-alloc-slot cg 8 4)) + (off-p (cg-alloc-slot cg 8 8)) + (sym-s (%sym "s" 'var 'auto st-ty off-s)) + (sym-p (%sym "p" 'var 'auto pt-ty off-p))) + ;; p = &s + (cg-push-sym cg sym-p) + (cg-push-sym cg sym-s) + (cg-take-addr cg) + (cg-assign cg) (cg-pop cg) + ;; p->a = 4 + (cg-push-sym cg sym-p) + (cg-load cg) + (cg-push-deref cg) + (cg-push-field cg "a") + (cg-push-imm cg %t-i32 4) + (cg-assign cg) (cg-pop cg) + ;; p->b = 9 + (cg-push-sym cg sym-p) + (cg-load cg) + (cg-push-deref cg) + (cg-push-field cg "b") + (cg-push-imm cg %t-i32 9) + (cg-assign cg) (cg-pop cg) + ;; return p->b - p->a + (cg-push-sym cg sym-p) + (cg-load cg) + (cg-push-deref cg) + (cg-push-field cg "b") + (cg-load cg) + (cg-push-sym cg sym-p) + (cg-load cg) + (cg-push-deref cg) + (cg-push-field cg "a") + (cg-load cg) + (cg-binop cg 'sub) + (cg-return cg)) + (cg-fn-end cg) + (write-bv-fd 1 (cg-finish cg)))