cgen: #57 in-cap tuple cursor fill keys on the DECLARED element type — tagged elems from concrete rvalues widen, both stages
The N_TUPLE literal's stamped type is CONSTRUCTED from its elements
(check.c N_TUPLE keeps untyped/concrete element types; assignability
is consumer-side), so the in-cap cursor fill — count
(tuple_lit_gpwords/tuplitgpwords) + push (tuple_lit_push_elem/
tuplitpushelem) — never saw the DECLARED tuple type. A declared-TAGGED
element whose expr is a concrete rvalue (`return (5: size, 9)` into
(un16, size)) counted ONE word and skipped the widen entirely: 2 words
sent against the receiver's declared 3-word walk, every later element
read garbage. Both stages, byte-identical, gate-blind (ken /tmp/ken57
p8/p9: t.1 read entry-junk). The let-literal twin
(`let t: (un16, size) = (5: size, 9)`) and the tagged-SECOND-elem
shift broke identically (probes q1/q2). The over-cap (sret) arm
already walks declared params (#240/#22b) — only the in-cap path was
declared-blind.
Fix threads the declared tuple type into the ONE shared helper pair
and its two loop sites:
- tuple_lit_gpwords/tuplitpushelem take the declared elem type;
declared-TAGGED + concrete rvalue widens into the shared tagged
scratch (cg_tagscr_slot/tagscradd + cg_widen_tagged_store/
cgwidentaggedstore, the cgreturn tagged-@retscr shape) and pushes
the box words; declared-TAGGED gates the SSE row off (a (void|f64)
box rides INTEGER eightbytes). Tagged->tagged subset (eslot
mismatch) louds — the #23/#40 widening-remap family.
- cg_tuple_lit_to_cursor/cgtuplelittocursor grow a decl param;
cgreturn's in-cap N_TUPLE loops thread cg_ret_type/c.fnret.list
(the same pp/pt walk its over-cap arm does); the N_LET in-cap
tuple arm passes the declared type for an N_TUPLE rhs; the bare
cgexpr route passes NULL/nil (emission unchanged).
Ident-elem sources keep the existing slot-load push byte-identically
(t57_ident_no_regress); the CALL-elem tripwire stays loud (#41,
t57_loud_call_elem). RESIDUAL FILED, not folded (rule 11): the
N_MASSIGN destructure-reassign literal rhs routes through the bare
cgexpr path (decl=NULL) and stays silent-wrong — probe q5_massign,
task #64, cited at the massign arm both stages. The annotated
multi-let spelling (`let (a, b): (un, size) = lit`) does not parse
(both stages), so N_MLET has no declared-literal route.
941 rows t57_*: return (named + inline union), let-literal, tagged
second elem, float payload, bare-untyped payload (rides the #33
chooser through the new wire), ident anchor, loud CALL tripwire;
ken's adversarial shapes (tagged-MID elem, two tagged rvalue elems
incl. void, plain-f64 SSE coexisting with a declared-tagged box), the
in-cap/over-cap boundary loud (k57d), and the NEW #57 tag-remap loud
pinned. Pre-fix at e8977a4: p8/p9 rows exit 1, q1_let exit 1,
q2_mixed exit 2.
Task #57.
This commit is contained in:
@@ -1925,6 +1925,201 @@ static const struct row rows[] = {
|
||||
" if (t.1 != 36) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
/* #57: an IN-CAP tuple literal's cursor fill keyed each element on
|
||||
* its STAMPED type (element-constructed, check.c N_TUPLE), so a
|
||||
* declared-TAGGED element from a concrete rvalue (`(5: size, 9)`)
|
||||
* counted ONE word and skipped the widen — 2 words sent against the
|
||||
* receiver's declared 3-word walk; every later element read garbage
|
||||
* (both stages, byte-id, gate-blind; ken /tmp/ken57). Rows: the
|
||||
* return position (named + inline union spelling, t.N + destructure
|
||||
* readback), the let-literal twin, tagged SECOND element (shift
|
||||
* direction), float payload (the SSE-row gate: a (void|f64) box
|
||||
* rides INTEGER eightbytes), bare-untyped payload (rides the #33
|
||||
* chooser through the new widen wire), the ident no-regress anchor,
|
||||
* and the still-loud CALL-elem tripwire (#41). */
|
||||
{ "t57_ret_cast_elem",
|
||||
"package main;\n"
|
||||
"type un16 = (void | size);\n"
|
||||
"fn mk() (un16, size) = {\n"
|
||||
" return (5: size, 9);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let t = mk();\n"
|
||||
" if (t.1 != 9) { return 1; };\n"
|
||||
" let (a, b) = mk();\n"
|
||||
" if (!(a is size)) { return 2; };\n"
|
||||
" if (a as size != 5) { return 3; };\n"
|
||||
" if (b != 9) { return 4; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "t57_ret_inline_union",
|
||||
"package main;\n"
|
||||
"fn mk() ((void | size), size) = {\n"
|
||||
" return (5: size, 9);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let (a, b) = mk();\n"
|
||||
" if (!(a is size)) { return 1; };\n"
|
||||
" if (b != 9) { return 2; };\n"
|
||||
" if (a as size != 5) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "t57_let_literal",
|
||||
"package main;\n"
|
||||
"type un16 = (void | size);\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let t: (un16, size) = (5: size, 9);\n"
|
||||
" if (t.1 != 9) { return 1; };\n"
|
||||
" if (!(t.0 is size)) { return 2; };\n"
|
||||
" if (t.0 as size != 5) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "t57_tagged_second_elem",
|
||||
"package main;\n"
|
||||
"type un16 = (void | size);\n"
|
||||
"fn mk2() (size, un16) = {\n"
|
||||
" return (3, 7: size);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let (a, b) = mk2();\n"
|
||||
" if (a != 3) { return 1; };\n"
|
||||
" if (!(b is size)) { return 2; };\n"
|
||||
" if (b as size != 7) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "t57_float_payload",
|
||||
"package main;\n"
|
||||
"type unf = (void | f64);\n"
|
||||
"fn mkf() (unf, size) = {\n"
|
||||
" return (1.5, 9);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let (a, b) = mkf();\n"
|
||||
" if (b != 9) { return 1; };\n"
|
||||
" if (!(a is f64)) { return 2; };\n"
|
||||
" if (a as f64 != 1.5) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
/* ken's adversarial shapes (k57a/b/c, /tmp/ken57) as rows: the
|
||||
* tagged-MID elem shifts the cursor on BOTH sides of the box; two
|
||||
* tagged rvalue elems (incl. a VOID rvalue) reuse the shared scratch
|
||||
* sequentially; a true SSE elem (plain f64) coexisting with a
|
||||
* declared-tagged box pins the gate splitting the rows. */
|
||||
{ "t57_tagged_mid_elem",
|
||||
"package main;\n"
|
||||
"type un = (void | size);\n"
|
||||
"fn mk3() (size, un, size) = {\n"
|
||||
" return (1, 5: size, 9);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let (a, b, c) = mk3();\n"
|
||||
" if (a != 1) { return 1; };\n"
|
||||
" if (!(b is size)) { return 2; };\n"
|
||||
" if (b as size != 5) { return 3; };\n"
|
||||
" if (c != 9) { return 4; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "t57_two_tagged_void_elem",
|
||||
"package main;\n"
|
||||
"type un = (void | size);\n"
|
||||
"fn mk() (un, un) = {\n"
|
||||
" return (5: size, void);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let t = mk();\n"
|
||||
" if (!(t.0 is size)) { return 1; };\n"
|
||||
" if (t.0 as size != 5) { return 2; };\n"
|
||||
" if (!(t.1 is void)) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "t57_sse_coexist",
|
||||
"package main;\n"
|
||||
"type un = (void | size);\n"
|
||||
"fn mk() (f64, un) = {\n"
|
||||
" return (0.5, 7: size);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let (x, e) = mk();\n"
|
||||
" if (x * 4.0 != 2.0) { return 1; };\n"
|
||||
" if (!(e is size)) { return 2; };\n"
|
||||
" if (e as size != 7) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "t57_bare_untyped_payload",
|
||||
"package main;\n"
|
||||
"type un16 = (void | size);\n"
|
||||
"fn mkb() (un16, size) = {\n"
|
||||
" return (5, 9);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let (a, b) = mkb();\n"
|
||||
" if (!(a is size)) { return 1; };\n"
|
||||
" if (a as size != 5) { return 2; };\n"
|
||||
" if (b != 9) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "t57_ident_no_regress",
|
||||
"package main;\n"
|
||||
"type un16 = (void | size);\n"
|
||||
"fn mk() (un16, size) = {\n"
|
||||
" let e: un16 = 5: size;\n"
|
||||
" return (e, 9);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let t = mk();\n"
|
||||
" if (t.1 != 9) { return 1; };\n"
|
||||
" if (!(t.0 is size)) { return 2; };\n"
|
||||
" if (t.0 as size != 5) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
{ "t57_loud_call_elem",
|
||||
"package main;\n"
|
||||
"type un16 = (void | size);\n"
|
||||
"fn mke() un16 = {\n"
|
||||
" return 5: size;\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let t: (un16, size) = (mke(), 9);\n"
|
||||
" if (t.1 != 9) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0,
|
||||
K_BUILDERR, "tagged tuple element from a non-local source shape unwired" },
|
||||
/* the NEW #57 loud: an in-cap tagged->tagged SUBSET elem (stamped
|
||||
* eslot 16 into declared eslot 24) needs a tag remap on the way into
|
||||
* the slot — pinned loud both stages until the #23/#40 widening
|
||||
* family wires it. (big,size) = 3+1 GP words, in-cap by GPCAP. */
|
||||
{ "t57_loud_remap",
|
||||
"package main;\n"
|
||||
"type st16 = struct { a: size, b: size };\n"
|
||||
"type small = (void | u8);\n"
|
||||
"type big = (void | u8 | st16);\n"
|
||||
"fn mk() (big, size) = {\n"
|
||||
" let s: small = 5u8;\n"
|
||||
" return (s, 9);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let t = mk();\n"
|
||||
" if (t.1 != 9) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0,
|
||||
K_BUILDERR, "widening into a wider declared union slot needs a tag remap" },
|
||||
/* ken k57d: the in-cap/over-cap BOUNDARY — an over-cap
|
||||
* (un,un,size,size) return with concrete rvalue tagged elems must
|
||||
* route to the sret arm's #22b ident-only loud-stop, not slip into
|
||||
* the (now declared-keyed) in-cap path: pins that the declared
|
||||
* count and the over-cap classify (cg_sret_retsize) agree. */
|
||||
{ "t57_loud_overcap_boundary",
|
||||
"package main;\n"
|
||||
"type un = (void | size);\n"
|
||||
"fn mk() (un, un, size, size) = {\n"
|
||||
" return (5: size, void, 8, 9);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let t = mk();\n"
|
||||
" if (t.2 != 8) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0,
|
||||
K_BUILDERR, "tagged element in an over-cap (sret) tuple return" },
|
||||
};
|
||||
|
||||
/* build+run via a driver (ww / ww_ww); returns 0 pass, nonzero fail. */
|
||||
|
||||
Reference in New Issue
Block a user