wcc/ww: serialize aggregate exported defs as value-less .wwi prototypes (BUG-2, #70)

The .wwi (separate-compile interface) producer could not serialize an
exported def whose initializer is a struct/array literal (N_STRUCTLIT/
N_ARRLIT) — `export def f64info: floatinfo = floatinfo{...}` aborted with
"unhandled const-expr node kind 15". Such a def is a DATA-global per the
#52 model, so its value lives once in the defining package's .o; the
interface needs only the type+symbol. Emit a value-less prototype
`export def X: T;` for aggregate-initializer defs; scalar fold-eligible
defs keep their value (the importer const-folds those). The parser gains
an optional-init arm so the importer can parse the prototype — value-less
`def X: T;` is now legal in any source, symmetric with the existing
bodyless-fn prototype `fn f();` (USER ruling: unconditional; a value-less
def with no defining .o is a loud undefined-symbol error at link, never
silent). Both stages; producer + parser fold into one commit (the
producer's output is unparseable without the parser arm).

M3-tail commit-6 prerequisite #2 (surfaced by the c6 scout). The
aggregate-def-field const-fold boundary is documented inline (#71). Gate
989_sepstructdef_run proves struct+array exported defs sep-build, link,
and run via external DATA refs, cs==ww, with a value-less .wwi.
This commit is contained in:
2026-06-16 18:04:54 +09:00
parent 2ff54c8bd4
commit 10d005ef58
8 changed files with 346 additions and 17 deletions

View File

@@ -8146,8 +8146,14 @@ fn parsedef(p: *parser, exported: i32) *node = {
n.str = id;
expecttok(p, tkind.TK_COLON, "expected ':' in def");
n.lhs = parsetype(p);
expecttok(p, tkind.TK_ASSIGN, "expected '=' in def");
n.rhs = parseexpr(p);
// A value-LESS `def X: T;` is an interface prototype (an aggregate-
// init `.wwi` def whose DATA lives in the defining package — BUG-2 /
// task #71), mirroring the fn bodyless-prototype arm. rhs stays nil;
// the checker fold pass and cgen emit_defs/emit_lets already guard
// the rhs==nil shape.
if (accepttok(p, tkind.TK_ASSIGN)) {
n.rhs = parseexpr(p);
};
expecttok(p, tkind.TK_SEMI, "expected ';' after def");
n.exported = exported;
return n;