kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit ab2d4c8ad60e56bba34ca8d3b407980ba8d93004
parent 1237b5860034481d9e40836011e4e781f6a47ad4
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Sun, 24 May 2026 05:42:48 -0700

parse: accept compound-literal static initializers; fix bootstrap driver -Ilang

Self-compilation (make bootstrap) choked on the slice rework's CFREE_SLICE_LIT,
which expands to a parenthesized struct compound literal `((CfreeSlice){...})`.

- parse_static_init_at: an aggregate (struct/union/array) object may be
  initialized by a compound literal of its own type, optionally wrapped in
  grouping parens (`static T x = (T){...};` / `((T){...})`). Strip the
  `(type-name)` cast and peel grouping parens by recursing.
- parse_static_const (pointer path): peel grouping parens around any pointer
  initializer (`("str")`, `(&x)`), not just a nested `((`.
- stage2_link.sh: driver build needs -Ilang so cc.c finds "c/c.h", mirroring
  the Makefile's DRIVER_CFLAGS.

Bootstrap now reaches a bitwise-identical stage2/stage3.

Diffstat:
Mlang/c/parse/parse_init.c | 27++++++++++++++++++++++++++-
Mscripts/stage2_link.sh | 3++-
2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/lang/c/parse/parse_init.c b/lang/c/parse/parse_init.c @@ -1239,7 +1239,11 @@ static CStaticConst parse_static_const(Parser* p, const Type* ty, SrcLoc loc) { if (ty && ty->kind == TY_PTR) { if (is_punct(&p->cur, '(')) { Tok n = peek1(p); - if (is_punct(&n, '(')) { + /* Grouping parens around the pointer initializer, e.g. `("str")`, + * `(&x)`, or `((expr))`. A `(type-name)` is a cast or compound literal + * and is handled below, so peel only when the inner token does not start + * a type-name. */ + if (!starts_type_name(p, &n)) { advance(p); r = parse_static_const(p, ty, loc); expect_punct(p, ')', "')' in static pointer initializer"); @@ -1369,6 +1373,27 @@ static void parse_static_aggregate_remainder(Parser* p, u8* buf, u32 buflen, void parse_static_init_at(Parser* p, u8* buf, u32 buflen, u32 offset, const Type* ty) { + /* An aggregate object may be initialized by a (possibly parenthesized) + * compound literal of its own type: `static T x = (T){...};` or, after macro + * expansion, `static T x = ((T){...});`. Strip the `(type-name)` cast so the + * brace body below initializes the object in place; peel grouping parens by + * recursing and matching the closing ')'. Pointer/scalar targets keep their + * own handling (parse_static_const / eval_const), where a compound literal + * can instead yield an address or value. */ + if ((ty->kind == TY_STRUCT || ty->kind == TY_UNION || ty->kind == TY_ARRAY) && + is_punct(&p->cur, '(')) { + Tok n = peek1(p); + if (starts_type_name(p, &n)) { + advance(p); + parse_type_name(p); + expect_punct(p, ')', "')' after compound literal type-name"); + } else if (is_punct(&n, '(')) { + advance(p); + parse_static_init_at(p, buf, buflen, offset, ty); + expect_punct(p, ')', "')' after parenthesized initializer"); + return; + } + } if (ty->kind == TY_ARRAY) { const Type* elem = ty->arr.elem; u32 esz = c_abi_sizeof(p->abi, elem); diff --git a/scripts/stage2_link.sh b/scripts/stage2_link.sh @@ -38,7 +38,8 @@ LANG_CPP_FLAGS="--support-dir $ROOT -Iinclude -Ilang/cpp" LANG_C_FLAGS="--support-dir $ROOT -Iinclude -Ilang/cpp -Ilang/c" LANG_WASM_FLAGS="--support-dir $ROOT -Iinclude -Ilang/wasm" LANG_TOY_FLAGS="--support-dir $ROOT -Iinclude" -DRIVER_FLAGS="--support-dir $ROOT -Iinclude -I." +# `cc` reaches the C frontend header as "c/c.h"; -Ilang mirrors DRIVER_CFLAGS. +DRIVER_FLAGS="--support-dir $ROOT -Iinclude -I. -Ilang" cfree_objs=() fail_src=()