diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index 91947b15..1750efef 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -10767,24 +10767,24 @@ import syntax; import strconv; type checker = struct { - tc: *tctx, - top: *scope, - cur: *scope, + tc: *syntax.tctx, + top: *syntax.scope, + cur: *syntax.scope, nresolved: i32, nunresolved: i32, errs: i32, istest: i32, // #15: `w6c_ww -T` — collect @test fns + // synth the entry; loud-reject a user main. verbose: i32, // when non-zero, log each unresolved name - fnret: *node, // enclosing fn's return type AST (for `?`) + fnret: *syntax.node, // enclosing fn's return type AST (for `?`) curmod: str, // importing-module bareword for the decl // currently being walked; "" for primary // compilation unit. Drives same-module // preference in bare-leaf lookups. - file: *node, // N_FILE root; used by checkmoduleshadow + file: *syntax.node, // N_FILE root; used by checkmoduleshadow // to consult the declaring source's own // `use` directives. - allococtx: *node, // #3/B': the one empty alloc([], n) call node + allococtx: *syntax.node, // #3/B': the one empty alloc([], n) call node // with let-declared slice context this walk; // any other empty alloc has no element hint // and must fail to infer (harec @@ -10813,9 +10813,9 @@ fn cerr(m: str) void = { // and every NAMED-chain chase loop downstream spun forever (the #69 // compiler hang); a struct-value cycle recursed the slot walkers to // stack overflow. -fn circularnamed(c: *checker, t: *tinfo, n: *node) bool = { +fn circularnamed(c: *checker, t: *syntax.tinfo, n: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != tykind.TY_NAMED) { return false; }; + if (t.kind != syntax.tykind.TY_NAMED) { return false; }; if (t.resolving == 0) { return false; }; if (n != nil) { cerr(n.file); cerr(": "); }; cerr("error: circular type dependency: '"); @@ -10835,24 +10835,24 @@ fn circularnamed(c: *checker, t: *tinfo, n: *node) bool = { // seedprimitives — install the built-in type names so `i32`, `str`, // etc. can be looked up like ordinary symbols. fn seedprimitives(c: *checker) void = { - scopedefine(c.top, "void", skind.SK_TYPE, c.tc.tyvoid, nil); - scopedefine(c.top, "bool", skind.SK_TYPE, c.tc.tybool, nil); - scopedefine(c.top, "rune", skind.SK_TYPE, c.tc.tyrune, nil); - scopedefine(c.top, "i8", skind.SK_TYPE, c.tc.tyi8, nil); - scopedefine(c.top, "i16", skind.SK_TYPE, c.tc.tyi16, nil); - scopedefine(c.top, "i32", skind.SK_TYPE, c.tc.tyi32, nil); - scopedefine(c.top, "i64", skind.SK_TYPE, c.tc.tyi64, nil); - scopedefine(c.top, "u8", skind.SK_TYPE, c.tc.tyu8, nil); - scopedefine(c.top, "u16", skind.SK_TYPE, c.tc.tyu16, nil); - scopedefine(c.top, "u32", skind.SK_TYPE, c.tc.tyu32, nil); - scopedefine(c.top, "u64", skind.SK_TYPE, c.tc.tyu64, nil); - scopedefine(c.top, "int", skind.SK_TYPE, c.tc.tyint, nil); - scopedefine(c.top, "uint", skind.SK_TYPE, c.tc.tyuint, nil); - scopedefine(c.top, "uintptr", skind.SK_TYPE, c.tc.tyuintptr, nil); - scopedefine(c.top, "f32", skind.SK_TYPE, c.tc.tyf32, nil); - scopedefine(c.top, "f64", skind.SK_TYPE, c.tc.tyf64, nil); - scopedefine(c.top, "str", skind.SK_TYPE, c.tc.tystr, nil); - scopedefine(c.top, "never", skind.SK_TYPE, c.tc.tynever, nil); + syntax.scopedefine(c.top, "void", syntax.skind.SK_TYPE, c.tc.tyvoid, nil); + syntax.scopedefine(c.top, "bool", syntax.skind.SK_TYPE, c.tc.tybool, nil); + syntax.scopedefine(c.top, "rune", syntax.skind.SK_TYPE, c.tc.tyrune, nil); + syntax.scopedefine(c.top, "i8", syntax.skind.SK_TYPE, c.tc.tyi8, nil); + syntax.scopedefine(c.top, "i16", syntax.skind.SK_TYPE, c.tc.tyi16, nil); + syntax.scopedefine(c.top, "i32", syntax.skind.SK_TYPE, c.tc.tyi32, nil); + syntax.scopedefine(c.top, "i64", syntax.skind.SK_TYPE, c.tc.tyi64, nil); + syntax.scopedefine(c.top, "u8", syntax.skind.SK_TYPE, c.tc.tyu8, nil); + syntax.scopedefine(c.top, "u16", syntax.skind.SK_TYPE, c.tc.tyu16, nil); + syntax.scopedefine(c.top, "u32", syntax.skind.SK_TYPE, c.tc.tyu32, nil); + syntax.scopedefine(c.top, "u64", syntax.skind.SK_TYPE, c.tc.tyu64, nil); + syntax.scopedefine(c.top, "int", syntax.skind.SK_TYPE, c.tc.tyint, nil); + syntax.scopedefine(c.top, "uint", syntax.skind.SK_TYPE, c.tc.tyuint, nil); + syntax.scopedefine(c.top, "uintptr", syntax.skind.SK_TYPE, c.tc.tyuintptr, nil); + syntax.scopedefine(c.top, "f32", syntax.skind.SK_TYPE, c.tc.tyf32, nil); + syntax.scopedefine(c.top, "f64", syntax.skind.SK_TYPE, c.tc.tyf64, nil); + syntax.scopedefine(c.top, "str", syntax.skind.SK_TYPE, c.tc.tystr, nil); + syntax.scopedefine(c.top, "never", syntax.skind.SK_TYPE, c.tc.tynever, nil); // #29: predeclare `type nomem = !void;` so user code needn't // declare it locally. Synthesize an nkind.N_TYPEDECL whose lhs is // nkind.N_TBANG{nkind.N_TNAME("void")} so varianterr and other @@ -10862,34 +10862,34 @@ fn seedprimitives(c: *checker) void = { // separate alias chain — see collectaliases in cgen.ww for the // companion seed. let empty: str; - let tnvoid: *node = newnode(nkind.N_TNAME, empty, 0, 0); + let tnvoid: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, empty, 0, 0); tnvoid.str = "void"; - let bang: *node = newnode(nkind.N_TBANG, empty, 0, 0); + let bang: *syntax.node = syntax.newnode(syntax.nkind.N_TBANG, empty, 0, 0); bang.lhs = tnvoid; - let nomemdecl: *node = newnode(nkind.N_TYPEDECL, empty, 0, 0); + let nomemdecl: *syntax.node = syntax.newnode(syntax.nkind.N_TYPEDECL, empty, 0, 0); nomemdecl.str = "nomem"; nomemdecl.lhs = bang; - scopedefine(c.top, "nomem", skind.SK_TYPE, nil, nomemdecl); + syntax.scopedefine(c.top, "nomem", syntax.skind.SK_TYPE, nil, nomemdecl); // `nil`, `true`, `false` are keywords — handled at the lex/parser // level, no symbol needed. // `len`, `alloc`, `free`, `append`, `delete`, `insert` are // pseudo-builtins; scopedefine them so their use sites resolve. // The actual semantics live in cgen. - scopedefine(c.top, "len", skind.SK_FN, nil, nil); - scopedefine(c.top, "alloc", skind.SK_FN, nil, nil); - scopedefine(c.top, "free", skind.SK_FN, nil, nil); - scopedefine(c.top, "append", skind.SK_FN, nil, nil); - scopedefine(c.top, "delete", skind.SK_FN, nil, nil); - scopedefine(c.top, "insert", skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "len", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "alloc", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "free", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "append", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "delete", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "insert", syntax.skind.SK_FN, nil, nil); // #42: typed builtins folded to integer literals at check time — // `size(T)` / `align(T)` (arg is a type-expression planted by the // parser at lib/ww/parse/expr.ww:254-267) and `offset(e.f)` (arg is // an N_DOT). exprtype intercepts these and rewrites the N_CALL to // N_INTLIT so cgen never sees an unresolved size/align/offset symbol. // Mirrors cmd/wcc/check.c:907-955. - scopedefine(c.top, "size", skind.SK_FN, nil, nil); - scopedefine(c.top, "align", skind.SK_FN, nil, nil); - scopedefine(c.top, "offset", skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "size", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "align", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "offset", syntax.skind.SK_FN, nil, nil); }; // declmod — module-tag stamp for a top-level decl. @@ -10900,19 +10900,19 @@ fn seedprimitives(c: *checker) void = { // directive matches some `use IDENT;` bareword in this compilation // unit. Primary-file decls return "" so they coexist (mod="") with // imported decls of the same leaf name in scopelookupinmodule. -fn declmod(file: *node, d: *node) str = { +fn declmod(file: *syntax.node, d: *syntax.node) str = { let empty: str; if (d == nil) { return empty; }; if (d.nmod.len == 0) { return empty; }; if (file == nil) { return empty; }; - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { // M1 #22: a decl is imported iff some `use` directive's full // dotted import path equals the decl's module (now the path). // Single-level packages have usepath == leaf so this is // unchanged; nested (`encoding.utf8`) match here, not on leaf. - if (u.kind == nkind.N_USE) { - if (streq(u.usepath, d.nmod)) { return d.nmod; }; + if (u.kind == syntax.nkind.N_USE) { + if (syntax.streq(u.usepath, d.nmod)) { return d.nmod; }; }; u = u.next; }; @@ -10924,14 +10924,14 @@ fn declmod(file: *node, d: *node) str = { // module-qualified resolution and codegen hint (M1 #22). Single-level // packages have usepath == alias so the result is unchanged. The // current tree has one occurrence per leaf, so the map is unambiguous. -fn usepathfor(file: *node, alias: str) str = { +fn usepathfor(file: *syntax.node, alias: str) str = { let empty: str; if (file == nil) { return empty; }; if (alias.len == 0) { return empty; }; - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { - if (u.kind == nkind.N_USE) { - if (streq(u.str, alias)) { + if (u.kind == syntax.nkind.N_USE) { + if (syntax.streq(u.str, alias)) { if (u.usepath.len != 0) { return u.usepath; }; return u.str; }; @@ -10953,19 +10953,19 @@ fn modkeyfor(c: *checker, alias: str) str = { // `modtag` carry `use ;`? Mirrors cstage's src_imports — // `modtag.len == 0` means primary, matching declmod's empty-str // return for primary-source decls. -fn srcimports(file: *node, modtag: str, name: str) bool = { +fn srcimports(file: *syntax.node, modtag: str, name: str) bool = { if (file == nil) { return false; }; if (name.len == 0) { return false; }; - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { - if (u.kind == nkind.N_USE) { + if (u.kind == syntax.nkind.N_USE) { // Skip self-imports: lib/fmt/fmttest.ww carries // `use fmt;` while its module tag is also "fmt". // That directive doesn't introduce a foreign // module bareword and lib/fmt's own // `fn bsprintf(fmt: str, ...)` is not a shadow. if (u.nmod.len > 0) { - if (streq(u.nmod, u.usepath)) { + if (syntax.streq(u.nmod, u.usepath)) { u = u.next; continue; }; @@ -10974,9 +10974,9 @@ fn srcimports(file: *node, modtag: str, name: str) bool = { let m: bool = false; if (modtag.len == 0) { if (um.len == 0) { m = true; }; - } else { if (streq(um, modtag)) { m = true; }; }; + } else { if (syntax.streq(um, modtag)) { m = true; }; }; if (m) { - if (streq(u.str, name)) { return true; }; + if (syntax.streq(u.str, name)) { return true; }; }; }; u = u.next; @@ -10995,11 +10995,11 @@ fn checkmoduleshadow(c: *checker, name: str, kindstr: str) void = { if (name.len == 0) { return; }; if (c.cur == c.top) { return; }; let seen: bool = false; - let s: *scope = c.cur; + let s: *syntax.scope = c.cur; for (s != nil) { - let r: *sym = scopelookuplocal(s, name); + let r: *syntax.sym = syntax.scopelookuplocal(s, name); if (r != nil) { - if (r.skind == skind.SK_USE) { + if (r.skind == syntax.skind.SK_USE) { seen = true; s = nil; }; @@ -11043,9 +11043,9 @@ fn checkmoduleshadow(c: *checker, name: str, kindstr: str) void = { // (cmd/wcc/check.c:2852/2911/2932/2955) — see dupdecl below. (Same-scope // LOCAL dup `let a=1; let a=2;` is a different path and stays deferred to // #11; test/wcc/708 + test/wcc/696 are that cstage-only neg-case.) -fn installdecl(c: *checker, file: *node, d: *node) void = { +fn installdecl(c: *checker, file: *syntax.node, d: *syntax.node) void = { if (d == nil) { return; }; - let k: nkind = d.kind; + let k: syntax.nkind = d.kind; let nm: str = d.str; let mod: str = declmod(file, d); // check-(c) self-import: a package may not import itself. Pure @@ -11053,10 +11053,10 @@ fn installdecl(c: *checker, file: *node, d: *node) void = { // unused + (b)/(d) membership DEFERRED to task #8 (filename-keyed // pulls lack import->file->symbol provenance). Message byte-identical // to cstage check.c. - if (k == nkind.N_USE) { + if (k == syntax.nkind.N_USE) { // M1 #22: self-import ⟺ the imported path equals the use's own // (owning) module path. Compares paths, not leaves. - if (mod.len != 0 && streq(d.usepath, mod)) { + if (mod.len != 0 && syntax.streq(d.usepath, mod)) { cerr("self-import: package '"); cerr(mod); cerr("' cannot import itself\n"); c.errs += 1i32; }; @@ -11074,17 +11074,17 @@ fn installdecl(c: *checker, file: *node, d: *node) void = { // (check.c:2823-2834 `if (prev) prev->use_alias = 1`). A pure // duplicate import (prev already SK_USE) keeps the coexisting- // entry path (orthogonal to #30, pre-existing wwstage behavior). - let prev: *sym = scopelookuplocal(c.top, nm); - if (prev != nil) { if (prev.skind != skind.SK_USE) { + let prev: *syntax.sym = syntax.scopelookuplocal(c.top, nm); + if (prev != nil) { if (prev.skind != syntax.skind.SK_USE) { prev.use_alias = 1i32; return; }; }; - scopedefine(c.top, nm, skind.SK_USE, nil, d); return; + syntax.scopedefine(c.top, nm, syntax.skind.SK_USE, nil, d); return; }; - if (k == nkind.N_DEF) { installtop(c, d, nm, mod, skind.SK_DEF, "def"); return; }; - if (k == nkind.N_TYPEDECL) { installtop(c, d, nm, mod, skind.SK_TYPE, "type"); return; }; - if (k == nkind.N_FNDECL) { installtop(c, d, nm, mod, skind.SK_FN, "fn"); return; }; - if (k == nkind.N_LET) { installtop(c, d, nm, mod, skind.SK_VAR, "let"); return; }; + if (k == syntax.nkind.N_DEF) { installtop(c, d, nm, mod, syntax.skind.SK_DEF, "def"); return; }; + if (k == syntax.nkind.N_TYPEDECL) { installtop(c, d, nm, mod, syntax.skind.SK_TYPE, "type"); return; }; + if (k == syntax.nkind.N_FNDECL) { installtop(c, d, nm, mod, syntax.skind.SK_FN, "fn"); return; }; + if (k == syntax.nkind.N_LET) { installtop(c, d, nm, mod, syntax.skind.SK_VAR, "let"); return; }; }; // installtop — install a top-level decl name into c.top, rejecting a @@ -11108,7 +11108,7 @@ fn installdecl(c: *checker, file: *node, d: *node) void = { // carrying no real source decl (primtypes: decl=nil; `nomem`: a // checkinit-synthesized N_TYPEDECL with an empty .file) — user decls // always carry their parsed source file. -fn installtop(c: *checker, d: *node, nm: str, mod: str, k: skind, kind: str) void = { +fn installtop(c: *checker, d: *syntax.node, nm: str, mod: str, k: syntax.skind, kind: str) void = { // #30: a top-level value/type decl whose leaf ALSO names an imported // module PROMOTES that same-leaf SK_USE in place — one correctly-kinded // sym carrying use_alias=1, so bare refs (call/structlit/var) resolve to @@ -11123,16 +11123,16 @@ fn installtop(c: *checker, d: *node, nm: str, mod: str, k: skind, kind: str) voi // (set use_alias on the pre-installed value sym). Both directions reach // the identical single-sym end state, so cstage and wwstage agree on // every source order (#30). - let puse: *sym = scopelookuplocal(c.top, nm); - if (puse != nil) { if (puse.skind == skind.SK_USE) { + let puse: *syntax.sym = syntax.scopelookuplocal(c.top, nm); + if (puse != nil) { if (puse.skind == syntax.skind.SK_USE) { puse.skind = k; puse.decl = d; puse.use_alias = 1i32; if (mod.len > 0) { if (puse.mod.len == 0) { puse.mod = mod; }; }; return; }; }; - if (scopedefineinmodule(c.top, nm, mod, k, nil, d) != nil) { return; }; - let prev: *sym = scopesamekeysym(c.top, nm, mod); + if (syntax.scopedefineinmodule(c.top, nm, mod, k, nil, d) != nil) { return; }; + let prev: *syntax.sym = syntax.scopesamekeysym(c.top, nm, mod); if (prev != nil) { if (prev.decl == nil) { return; }; if (prev.decl.file.len == 0) { return; }; @@ -11164,26 +11164,26 @@ fn installtop(c: *checker, d: *node, nm: str, mod: str, k: skind, kind: str) voi // empty-str N_IDENT with no decl to read a type back from): harec drops // `_` yet still advances the tuple slot, so that slot's element type is // the honest type to stamp — `_` is UNBOUND, not UNTYPED. -fn stamptuplebinds(c: *checker, binds: *node, elems: *node, +fn stamptuplebinds(c: *checker, binds: *syntax.node, elems: *syntax.node, define: bool, what: str) void = { - let b: *node = binds; - let pt: *node = elems; + let b: *syntax.node = binds; + let pt: *syntax.node = elems; for (b != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (pt != nil) { et = pt.lhs; }; if (define) { if (b.lhs == nil) { b.lhs = et; }; let bnm: str = b.str; if (bnm.len > 0) { checkmoduleshadow(c, bnm, what); - scopedefine(c.cur, bnm, skind.SK_VAR, nil, b); + syntax.scopedefine(c.cur, bnm, syntax.skind.SK_VAR, nil, b); }; }; if (b.type_ == nil) { - let src: *node = b.lhs; + let src: *syntax.node = b.lhs; if (src == nil) { src = et; }; if (src != nil) { - let ti: *tinfo = tinfofornode(c, src); + let ti: *syntax.tinfo = tinfofornode(c, src); if (ti != nil) { b.type_ = ti: *void; }; }; }; @@ -11200,27 +11200,27 @@ fn stamptuplebinds(c: *checker, binds: *node, elems: *node, // the C checker's collect-then-resolve flow within a function). // Also runs the typed checks (match exhaustiveness, ? subset) in // the same pass — they need the same scope state. -fn resolvewalk(c: *checker, n: *node) void = { +fn resolvewalk(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; // Typed checks fire on the way down so the scrutinee/operand // is examined before the arm bodies install new bindings. - if (k == nkind.N_MATCH) { checkmatchexhaust(c, n); }; - if (k == nkind.N_TRYPROP) { checktryprop(c, n); }; - if (k == nkind.N_TRYUNW) { checktryprop(c, n); }; - if (k == nkind.N_TYPETEST) { checkisas(c, n); }; - if (k == nkind.N_TYPEASSERT) { checkisas(c, n); }; - if (k == nkind.N_LET) { checkletassign(c, n); }; - if (k == nkind.N_RETURN) { checkretassign(c, n); }; + if (k == syntax.nkind.N_MATCH) { checkmatchexhaust(c, n); }; + if (k == syntax.nkind.N_TRYPROP) { checktryprop(c, n); }; + if (k == syntax.nkind.N_TRYUNW) { checktryprop(c, n); }; + if (k == syntax.nkind.N_TYPETEST) { checkisas(c, n); }; + if (k == syntax.nkind.N_TYPEASSERT) { checkisas(c, n); }; + if (k == syntax.nkind.N_LET) { checkletassign(c, n); }; + if (k == syntax.nkind.N_RETURN) { checkretassign(c, n); }; // `use IDENT;` — name is a module label, not a free ident. - if (k == nkind.N_USE) { return; }; + if (k == syntax.nkind.N_USE) { return; }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { let nm: str = n.str; if (nm.len > 0) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, nm); if (s == nil) { // Unshadowed abort/assert binds no sym BY // DESIGN (the EXPR_ASSERT family has no callee @@ -11241,10 +11241,10 @@ fn resolvewalk(c: *checker, n: *node) void = { }; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = n.str; if (nm.len > 0) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, nm); // `pkg.Type` — strip the last dot prefix and look up // the leaf with a mod filter so same-leaf-name types // from different imports (`bufio.stream` vs @@ -11260,12 +11260,12 @@ fn resolvewalk(c: *checker, n: *node) void = { let head: str; head.ptr = nm.ptr; head.len = dot; - let m: *sym = scopelookup(c.cur, head); + let m: *syntax.sym = syntax.scopelookup(c.cur, head); if (m != nil) { let leaf: str; leaf.ptr = nm.ptr + (dot + 1): u64; leaf.len = nm.len - (dot + 1); - s = scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); + s = syntax.scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); }; }; }; @@ -11292,7 +11292,7 @@ fn resolvewalk(c: *checker, n: *node) void = { // only by wwdump_ww as a diagnostic, so silent-accept here avoids // false-positives on legal cross-block shadow until #11 adds the // scoping infrastructure. - if (k == nkind.N_FORRANGE) { + if (k == syntax.nkind.N_FORRANGE) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; if (n.list != nil) { // Tuple destructure `for (let (a,b) .. xs)`: peel the @@ -11300,13 +11300,13 @@ fn resolvewalk(c: *checker, n: *node) void = { // element types onto the binders, the same lockstep walk // harec runs for the for-each header // (ref/harec/src/check.c:2308-2317 → create_unpack_bindings). - let elems: *node = nil; - let it: *node = exprtype(c, n.lhs, nil); + let elems: *syntax.node = nil; + let it: *syntax.node = exprtype(c, n.lhs, nil); if (it != nil) { - let et: *node = nil; - if (it.kind == nkind.N_TSLICE) { et = it.lhs; }; - if (it.kind == nkind.N_TARRAY) { et = it.lhs; }; - if (et != nil) { if (et.kind == nkind.N_TTUPLE) { + let et: *syntax.node = nil; + if (it.kind == syntax.nkind.N_TSLICE) { et = it.lhs; }; + if (it.kind == syntax.nkind.N_TARRAY) { et = it.lhs; }; + if (et != nil) { if (et.kind == syntax.nkind.N_TTUPLE) { elems = et.list; }; }; }; @@ -11328,8 +11328,8 @@ fn resolvewalk(c: *checker, n: *node) void = { // `b.lhs = et` idiom. A str scrutinee keeps the // old decl: cgen synthesises the u8 elem there // and no dot applies to a u8 binding. - let et: *node = nil; - let it: *node = exprtype(c, n.lhs, nil); + let et: *syntax.node = nil; + let it: *syntax.node = exprtype(c, n.lhs, nil); // #80 (F2a batch-4 c4): an alias-typed iterable // arrives as N_TNAME — without the AST-level // dealias the binder fell to the N_FORRANGE @@ -11338,16 +11338,16 @@ fn resolvewalk(c: *checker, n: *node) void = { // accepts: its scope_define types the elem). if (it != nil) { it = resolvealias(c, unwrapbang(it)); }; if (it != nil) { - if (it.kind == nkind.N_TSLICE) { et = it.lhs; }; - if (it.kind == nkind.N_TARRAY) { et = it.lhs; }; + if (it.kind == syntax.nkind.N_TSLICE) { et = it.lhs; }; + if (it.kind == syntax.nkind.N_TARRAY) { et = it.lhs; }; }; if (et != nil) { - let bn: *node = newnode(nkind.N_LET, n.file, n.line, n.col); + let bn: *syntax.node = syntax.newnode(syntax.nkind.N_LET, n.file, n.line, n.col); bn.str = bnm; bn.lhs = et; - scopedefine(c.cur, bnm, skind.SK_VAR, nil, bn); + syntax.scopedefine(c.cur, bnm, syntax.skind.SK_VAR, nil, bn); } else { - scopedefine(c.cur, bnm, skind.SK_VAR, nil, n); + syntax.scopedefine(c.cur, bnm, syntax.skind.SK_VAR, nil, n); }; }; }; @@ -11362,14 +11362,14 @@ fn resolvewalk(c: *checker, n: *node) void = { // `let e: *T` (scopedefine drops same-scope dupes silently and // would leave references to `e` resolving to the outer type). // Mirrors cmd/wcc/check.c's newscope/saved-restore around cstmt. - if (k == nkind.N_MCASE) { + if (k == syntax.nkind.N_MCASE) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; - let outer: *scope = c.cur; - c.cur = newscope(outer); + let outer: *syntax.scope = c.cur; + c.cur = syntax.newscope(outer); let nm: str = n.str; if (nm.len > 0) { checkmoduleshadow(c, nm, "binding"); - scopedefine(c.cur, nm, skind.SK_VAR, nil, n); + syntax.scopedefine(c.cur, nm, syntax.skind.SK_VAR, nil, n); }; if (n.body != nil) { resolvewalk(c, n.body); }; c.cur = outer; @@ -11385,10 +11385,10 @@ fn resolvewalk(c: *checker, n: *node) void = { // becomes a false-positive on the next driver (`wwdump_ww -r` // flagged the u64→i32 pair in selfhost/cmd/ww/enumeratedir). // Mirrors cstage cstmt N_BLOCK at cmd/wcc/check.c:1559-1566. - if (k == nkind.N_BLOCK) { - let outer: *scope = c.cur; - c.cur = newscope(outer); - let m: *node = n.list; + if (k == syntax.nkind.N_BLOCK) { + let outer: *syntax.scope = c.cur; + c.cur = syntax.newscope(outer); + let m: *syntax.node = n.list; for (m != nil) { resolvewalk(c, m); m = m.next; @@ -11422,9 +11422,9 @@ fn resolvewalk(c: *checker, n: *node) void = { // their own type. Mirrors the N_FORRANGE binding-install shape above; // the bindings would otherwise install (unstamped) via the generic // N_LET walk, so this early return must register them itself. - if (k == nkind.N_MLET) { + if (k == syntax.nkind.N_MLET) { if (n.rhs != nil) { resolvewalk(c, n.rhs); }; - let pt: *node = nil; + let pt: *syntax.node = nil; // #242: consume the rhs's tuple type for ANY rhs, not just an // N_CALL — `let (a,b) = t` over a plain tuple ident (e.g. a // match-bound union payload) must stamp its bindings too, or @@ -11433,8 +11433,8 @@ fn resolvewalk(c: *checker, n: *node) void = { if (n.rhs != nil) { // `rt` would shadow the imported lib/rt module // (checkmoduleshadow errors); `rty` avoids it. - let rty: *node = exprtype(c, n.rhs, nil); - if (rty != nil) { if (rty.kind == nkind.N_TTUPLE) { + let rty: *syntax.node = exprtype(c, n.rhs, nil); + if (rty != nil) { if (rty.kind == syntax.nkind.N_TTUPLE) { pt = rty.list; }; }; }; @@ -11449,13 +11449,13 @@ fn resolvewalk(c: *checker, n: *node) void = { // still-nil slots, which is exactly the discard `_` (no decl, so the // N_IDENT exprtype path leaves it untyped). Distribution mirrors the // N_MLET/N_FORRANGE binders; see stamptuplebinds. - if (k == nkind.N_MASSIGN) { + if (k == syntax.nkind.N_MASSIGN) { if (n.rhs != nil) { resolvewalk(c, n.rhs); }; - let pt: *node = nil; + let pt: *syntax.node = nil; // #242: consume the rhs tuple type for ANY rhs (see N_MLET). if (n.rhs != nil) { - let rty: *node = exprtype(c, n.rhs, nil); - if (rty != nil && rty.kind == nkind.N_TTUPLE) { + let rty: *syntax.node = exprtype(c, n.rhs, nil); + if (rty != nil && rty.kind == syntax.nkind.N_TTUPLE) { pt = rty.list; } else { // #38/F2 (review item 39): the multi-assign rhs must be a @@ -11471,29 +11471,29 @@ fn resolvewalk(c: *checker, n: *node) void = { deffolderr(c, n, "multi-assign rhs is not a tuple"); }; }; - let l: *node = n.list; + let l: *syntax.node = n.list; for (l != nil) { resolvewalk(c, l); l = l.next; }; stamptuplebinds(c, n.list, pt, false, ""); return; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // Walk only the base; the .field name is a member, not a // free identifier. if (n.lhs != nil) { resolvewalk(c, n.lhs); }; // A.6.0: branch returns early; stamp here so the post-walk // dispatch below sees N_DOT covered. exprtype N_DOT arm is // added in A.6.1; for now this is a no-op nil return. - let _t: *node = exprtype(c, n, nil); + let _t: *syntax.node = exprtype(c, n, nil); return; }; - if (k == nkind.N_FIELD) { + if (k == syntax.nkind.N_FIELD) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; return; }; - if (k == nkind.N_TFIELD) { + if (k == syntax.nkind.N_TFIELD) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; return; }; @@ -11506,7 +11506,7 @@ fn resolvewalk(c: *checker, n: *node) void = { if (n.body != nil) { resolvewalk(c, n.body); }; if (n.els != nil) { resolvewalk(c, n.els); }; if (n.list != nil) { - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { resolvewalk(c, m); m = m.next; @@ -11519,19 +11519,19 @@ fn resolvewalk(c: *checker, n: *node) void = { // user-defined aliases). Cgen's slotsize fast-path reads off // n.type_; uncovered shapes fall through to the cstage-mirror // walker until the next sub-commit graduates them. - if (k == nkind.N_TNAME || k == nkind.N_TPTR || - k == nkind.N_TSLICE || k == nkind.N_TCHAN || - k == nkind.N_TBANG || k == nkind.N_TARRAY || - k == nkind.N_TFN || k == nkind.N_TSTRUCT || - k == nkind.N_TTUPLE || k == nkind.N_TTAGGED || - k == nkind.N_TENUM) { + if (k == syntax.nkind.N_TNAME || k == syntax.nkind.N_TPTR || + k == syntax.nkind.N_TSLICE || k == syntax.nkind.N_TCHAN || + k == syntax.nkind.N_TBANG || k == syntax.nkind.N_TARRAY || + k == syntax.nkind.N_TFN || k == syntax.nkind.N_TSTRUCT || + k == syntax.nkind.N_TTUPLE || k == syntax.nkind.N_TTAGGED || + k == syntax.nkind.N_TENUM) { if (n.type_ == nil) { - let ti: *tinfo = tinfofornode(c, n); + let ti: *syntax.tinfo = tinfofornode(c, n); if (ti != nil) { n.type_ = ti: *void; }; }; }; - if (k == nkind.N_TENUM) { stampenumvals(c, n); }; + if (k == syntax.nkind.N_TENUM) { stampenumvals(c, n); }; // #42's size/align/offset fold trigger lived here pre-A.6.0; the // A.6.0 end-of-fn general dispatch (below) now fires exprtype on @@ -11548,17 +11548,17 @@ fn resolvewalk(c: *checker, n: *node) void = { // still silent-accepts here; promoting that to an error stays // queued behind #11 (test/wcc/708 + test/wcc/696 are the cstage- // only neg-case precedent). - if (k == nkind.N_LET) { + if (k == syntax.nkind.N_LET) { let nm: str = n.str; if (nm.len > 0) { checkmoduleshadow(c, nm, "let"); - let s: *sym = scopedefine(c.cur, nm, skind.SK_VAR, nil, n); + let s: *syntax.sym = syntax.scopedefine(c.cur, nm, syntax.skind.SK_VAR, nil, n); // catB-22: flag a `const` binding so checkassign can // reject a later reassignment. The parser stamps // n.op = TK_CONST (parse/stmt.ww). Mirror cstage // cmd/wcc/check.c:2408. if (s != nil) { - if (n.op == tkind.TK_CONST) { s.is_const = 1i32; }; + if (n.op == syntax.tkind.TK_CONST) { s.is_const = 1i32; }; }; }; }; @@ -11571,8 +11571,8 @@ fn resolvewalk(c: *checker, n: *node) void = { // / return only — see coercefloatlit's docstring for the rule-10 scope // (the cstage twin coerces in clet / cstmt N_RETURN). c.fnret is set // by resolvefnbody for the enclosing fn, mirroring checkretassign. - if (k == nkind.N_LET) { coercefloatlit(c, n.rhs, n.lhs); }; - if (k == nkind.N_RETURN) { coercefloatlit(c, n.lhs, c.fnret); }; + if (k == syntax.nkind.N_LET) { coercefloatlit(c, n.rhs, n.lhs); }; + if (k == syntax.nkind.N_RETURN) { coercefloatlit(c, n.lhs, c.fnret); }; // A.6.0: post-order dispatch of exprtype on every expression-yielding // node kind so n.type_ stamps fire universally — not only when reached @@ -11595,24 +11595,24 @@ fn resolvewalk(c: *checker, n: *node) void = { // exprtype below so a regular N_CALL is still an N_CALL (not folded to // an N_INTLIT by the size/align intercept). Mirrors cstage's post- // order cexpr desugar at the call-arg / N_ASSIGN sites. - if (k == nkind.N_CALL) { desugarcallargs(c, n); }; - if (k == nkind.N_ASSIGN) { checkassign(c, n); }; + if (k == syntax.nkind.N_CALL) { desugarcallargs(c, n); }; + if (k == syntax.nkind.N_ASSIGN) { checkassign(c, n); }; - if (k == nkind.N_INTLIT || k == nkind.N_FLOATLIT || - k == nkind.N_STRLIT || k == nkind.N_RUNELIT || - k == nkind.N_TRUE || k == nkind.N_FALSE || - k == nkind.N_NIL || k == nkind.N_VOIDLIT || - k == nkind.N_IDENT || k == nkind.N_BIN || - k == nkind.N_UN || k == nkind.N_CALL || - k == nkind.N_INDEX || k == nkind.N_CAST || - k == nkind.N_STRUCTLIT || k == nkind.N_ARRLIT || - k == nkind.N_RECV || - k == nkind.N_SLICE || k == nkind.N_SPREAD || - k == nkind.N_TUPLE || k == nkind.N_TRYPROP || - k == nkind.N_TRYUNW || k == nkind.N_TYPETEST || - k == nkind.N_TYPEASSERT || k == nkind.N_YIELD || - k == nkind.N_MATCH) { - let _t: *node = exprtype(c, n, nil); + if (k == syntax.nkind.N_INTLIT || k == syntax.nkind.N_FLOATLIT || + k == syntax.nkind.N_STRLIT || k == syntax.nkind.N_RUNELIT || + k == syntax.nkind.N_TRUE || k == syntax.nkind.N_FALSE || + k == syntax.nkind.N_NIL || k == syntax.nkind.N_VOIDLIT || + k == syntax.nkind.N_IDENT || k == syntax.nkind.N_BIN || + k == syntax.nkind.N_UN || k == syntax.nkind.N_CALL || + k == syntax.nkind.N_INDEX || k == syntax.nkind.N_CAST || + k == syntax.nkind.N_STRUCTLIT || k == syntax.nkind.N_ARRLIT || + k == syntax.nkind.N_RECV || + k == syntax.nkind.N_SLICE || k == syntax.nkind.N_SPREAD || + k == syntax.nkind.N_TUPLE || k == syntax.nkind.N_TRYPROP || + k == syntax.nkind.N_TRYUNW || k == syntax.nkind.N_TYPETEST || + k == syntax.nkind.N_TYPEASSERT || k == syntax.nkind.N_YIELD || + k == syntax.nkind.N_MATCH) { + let _t: *syntax.node = exprtype(c, n, nil); }; }; @@ -11625,9 +11625,9 @@ fn resolvewalk(c: *checker, n: *node) void = { // propagation, and !-flag semantics. // unwrapbang — strip an nkind.N_TBANG wrapper; leaves other nodes alone. -fn unwrapbang(n: *node) *node = { +fn unwrapbang(n: *syntax.node) *syntax.node = { if (n == nil) { return nil; }; - if (n.kind == nkind.N_TBANG) { return n.lhs; }; + if (n.kind == syntax.nkind.N_TBANG) { return n.lhs; }; return n; }; @@ -11638,9 +11638,9 @@ fn unwrapbang(n: *node) *node = { // decl sym (nominal identity = sym.type_ ptr-identity) instead of // flattening to the underlying. Mirrors cstage resolve_typename // (cmd/wcc/check.c:60-88), which returns the sym's NAMED, not the base. -fn aliassym(c: *checker, n: *node) *sym = { +fn aliassym(c: *checker, n: *syntax.node) *syntax.sym = { if (n == nil) { return nil; }; - if (n.kind != nkind.N_TNAME) { return nil; }; + if (n.kind != syntax.nkind.N_TNAME) { return nil; }; let nm: str = n.str; // #51: pkg.alias type refs land here as a single TNAME whose // str is the joined form (lib/ww/parse/parse.ww:258-265 in @@ -11655,7 +11655,7 @@ fn aliassym(c: *checker, n: *node) *sym = { if (nm[i] == 46u8) { dotidx = i; }; i += 1; }; - let s: *sym = nil; + let s: *syntax.sym = nil; if (dotidx >= 0) { let head: str; head.ptr = nm.ptr; @@ -11663,7 +11663,7 @@ fn aliassym(c: *checker, n: *node) *sym = { let leaf: str; leaf.ptr = nm.ptr + ((dotidx + 1): u64); leaf.len = nm.len - dotidx - 1; - s = scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); + s = syntax.scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); } else { // #53: same-module preference. Mirrors cstage // cmd/wcc/check.c:66 scope_lookup_prefer. Without this, @@ -11676,7 +11676,7 @@ fn aliassym(c: *checker, n: *node) *sym = { // scopelookupprefer (the #56/#4/#11a wave). The only bare-leaf // type lookups left — varianterr (:1051) + scruttype (:1098) — // stay mod-blind but have no reproducible divergence; #58. - s = scopelookupprefer(c.cur, c.curmod, nm); + s = syntax.scopelookupprefer(c.cur, c.curmod, nm); // #61 A.5: bare TNAME that collides with an imported // module bareword. Two shapes hit this: // - `let l: lex;` where `lex` struct lives in @@ -11692,20 +11692,20 @@ fn aliassym(c: *checker, n: *node) *sym = { // regardless of its declaring package. Mirrors the // bare-vs-qualified pattern from task #57. if (s != nil) { - if (s.skind != skind.SK_TYPE) { + if (s.skind != syntax.skind.SK_TYPE) { // #58/#50: prefer the curmod-matching SK_TYPE. // Two modules exporting the same type leaf (e.g. // utf8.invalid !void vs strconv.invalid !i32) // otherwise resolve install-order-dependent here // when a value binding shadows the leaf; cstage // passes c->cur_mod to scope_lookup_type (sym.c). - let sm: *sym = scopelookuptype(c.cur, c.curmod, nm); + let sm: *syntax.sym = syntax.scopelookuptype(c.cur, c.curmod, nm); if (sm != nil) { s = sm; }; }; }; }; if (s == nil) { return nil; }; - if (s.skind != skind.SK_TYPE) { return nil; }; + if (s.skind != syntax.skind.SK_TYPE) { return nil; }; return s; }; @@ -11713,13 +11713,13 @@ fn aliassym(c: *checker, n: *node) *sym = { // the typedecl's body (possibly recursively). Pass-through for any // other node. The chain stops once we hit a non-nkind.N_TNAME node or a // name we can't resolve. -fn resolvealias(c: *checker, n: *node) *node = { - let cur: *node = n; +fn resolvealias(c: *checker, n: *syntax.node) *syntax.node = { + let cur: *syntax.node = n; for (cur != nil) { - if (cur.kind != nkind.N_TNAME) { return cur; }; - let s: *sym = aliassym(c, cur); + if (cur.kind != syntax.nkind.N_TNAME) { return cur; }; + let s: *syntax.sym = aliassym(c, cur); if (s == nil) { return cur; }; - let body: *node = nil; + let body: *syntax.node = nil; if (s.decl != nil) { body = s.decl.lhs; }; if (body == nil) { return cur; }; cur = unwrapbang(body); @@ -11735,9 +11735,9 @@ fn resolvealias(c: *checker, n: *node) *node = { // bare `oserror` vs qualified `os.oserror` resolve to the SAME // SK_TYPE sym (aliassym maps both via #51/#53), so a cross-module // nominal forward compares equal where the surface streq said false. -fn typeeqast(c: *checker, a: *node, b: *node) bool = { - let aa: *node = unwrapbang(a); - let bb: *node = unwrapbang(b); +fn typeeqast(c: *checker, a: *syntax.node, b: *syntax.node) bool = { + let aa: *syntax.node = unwrapbang(a); + let bb: *syntax.node = unwrapbang(b); if (aa == nil) { return bb == nil; }; if (bb == nil) { return false; }; // Identity fast-path, mirroring cstage type_eq's first line @@ -11749,31 +11749,31 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // cstage accepts via this identity check. if (aa == bb) { return true; }; if (aa.kind != bb.kind) { return false; }; - let k: nkind = aa.kind; - if (k == nkind.N_TNAME) { - if (streq(aa.str, bb.str)) { return true; }; - let sa: *sym = aliassym(c, aa); - let sb: *sym = aliassym(c, bb); + let k: syntax.nkind = aa.kind; + if (k == syntax.nkind.N_TNAME) { + if (syntax.streq(aa.str, bb.str)) { return true; }; + let sa: *syntax.sym = aliassym(c, aa); + let sb: *syntax.sym = aliassym(c, bb); if (sa != nil && sa == sb) { return true; }; return false; }; - if (k == nkind.N_TPTR) { return typeeqast(c, aa.lhs, bb.lhs); }; - if (k == nkind.N_TSLICE){ return typeeqast(c, aa.lhs, bb.lhs); }; - if (k == nkind.N_TCHAN) { return typeeqast(c, aa.lhs, bb.lhs); }; - if (k == nkind.N_TFN) { + if (k == syntax.nkind.N_TPTR) { return typeeqast(c, aa.lhs, bb.lhs); }; + if (k == syntax.nkind.N_TSLICE){ return typeeqast(c, aa.lhs, bb.lhs); }; + if (k == syntax.nkind.N_TCHAN) { return typeeqast(c, aa.lhs, bb.lhs); }; + if (k == syntax.nkind.N_TFN) { // Divergence: cstage type.c:239 compares resolved Type; we // compare AST. See #178. if (!typeeqast(c, aa.lhs, bb.lhs)) { return false; }; - let pa: *node = aa.list; - let pb: *node = bb.list; + let pa: *syntax.node = aa.list; + let pb: *syntax.node = bb.list; for (pa != nil) { if (pb == nil) { return false; }; - let ac: bool = streq(pa.str, "..."); - let bc: bool = streq(pb.str, "..."); + let ac: bool = syntax.streq(pa.str, "..."); + let bc: bool = syntax.streq(pb.str, "..."); if (ac != bc) { return false; }; if (!ac) { - let va: bool = pa.op == tkind.TK_ELLIPSIS; - let vb: bool = pb.op == tkind.TK_ELLIPSIS; + let va: bool = pa.op == syntax.tkind.TK_ELLIPSIS; + let vb: bool = pb.op == syntax.tkind.TK_ELLIPSIS; if (va != vb) { return false; }; if (!typeeqast(c, pa.lhs, pb.lhs)) { return false; }; }; @@ -11789,9 +11789,9 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // would confidently reject a bare-&fn into a structural `*fn(...)` // slot (test 766 fn_tuple_return). Elements are N_TPARAM-wrapped // (parse.ww:302-318), so compare each link's .lhs. - if (k == nkind.N_TTUPLE) { - let pa: *node = aa.list; - let pb: *node = bb.list; + if (k == syntax.nkind.N_TTUPLE) { + let pa: *syntax.node = aa.list; + let pb: *syntax.node = bb.list; for (pa != nil) { if (pb == nil) { return false; }; if (!typeeqast(c, pa.lhs, pb.lhs)) { return false; }; @@ -11810,9 +11810,9 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // Divergence: cstage's nullable-flag check (type.c:293) is a resolved- // Type property with no AST analogue; for case-match both sides share // a spelling so it's moot — no phantom AST nullable check. - if (k == nkind.N_TTAGGED) { - let pa: *node = aa.list; - let pb: *node = bb.list; + if (k == syntax.nkind.N_TTAGGED) { + let pa: *syntax.node = aa.list; + let pb: *syntax.node = bb.list; for (pa != nil) { if (pb == nil) { return false; }; // #115: a `...inner` spread variant stays unflattened at @@ -11823,8 +11823,8 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // match a plain `ab`, accepting a case cstage rejects. // Conservatively loud-reject any spread until the flatten // lands; b1c's (void|size) has none, so byte-id is untouched. - if (pa.op == tkind.TK_ELLIPSIS) { return false; }; - if (pb.op == tkind.TK_ELLIPSIS) { return false; }; + if (pa.op == syntax.tkind.TK_ELLIPSIS) { return false; }; + if (pb.op == syntax.tkind.TK_ELLIPSIS) { return false; }; if (!typeeqast(c, pa, pb)) { return false; }; pa = pa.next; pb = pb.next; @@ -11840,20 +11840,20 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // varianterr — does this variant carry the `!` mark? Either // the variant itself is nkind.N_TBANG or it's an alias whose typedecl // body is `!T`. Mirrors C check.c's iserror-after-NAMED rule. -fn varianterr(c: *checker, v: *node) bool = { +fn varianterr(c: *checker, v: *syntax.node) bool = { if (v == nil) { return false; }; - if (v.kind == nkind.N_TBANG) { return true; }; - if (v.kind == nkind.N_TNAME) { + if (v.kind == syntax.nkind.N_TBANG) { return true; }; + if (v.kind == syntax.nkind.N_TNAME) { // #58: mod-blind by leaf — latent. A same-leaf error-vs-plain // type pair across two modules could in principle flip iserror, // but the union's variants resolve at its declaration before // varianterr runs, so no repro exists. Tracked: #58. - let s: *sym = scopelookup(c.cur, v.str); + let s: *syntax.sym = syntax.scopelookup(c.cur, v.str); if (s != nil) { - if (s.skind == skind.SK_TYPE) { + if (s.skind == syntax.skind.SK_TYPE) { if (s.decl != nil) { if (s.decl.lhs != nil) { - if (s.decl.lhs.kind == nkind.N_TBANG) { + if (s.decl.lhs.kind == syntax.nkind.N_TBANG) { return true; }; }; @@ -11867,8 +11867,8 @@ fn varianterr(c: *checker, v: *node) bool = { // taggedhaserr — true iff any variant of `n` (assumed // nkind.N_TTAGGED) is `!`-marked. Picks the explicit-flag semantics over // the legacy "first variant = success" rule. -fn taggedhaserr(c: *checker, n: *node) bool = { - let v: *node = n.list; +fn taggedhaserr(c: *checker, n: *syntax.node) bool = { + let v: *syntax.node = n.list; for (v != nil) { if (varianterr(c, v)) { return true; }; v = v.next; @@ -11879,7 +11879,7 @@ fn taggedhaserr(c: *checker, n: *node) bool = { // iserrvariant — under flag-aware mode (any !-marked variant), // returns true iff `v` is `!`-marked. Under legacy mode (no flags), // returns true iff `v` is not the first variant of `tagged`. -fn iserrvariant(c: *checker, tagged: *node, v: *node) bool = { +fn iserrvariant(c: *checker, tagged: *syntax.node, v: *syntax.node) bool = { if (taggedhaserr(c, tagged)) { return varianterr(c, v); }; @@ -11892,14 +11892,14 @@ fn iserrvariant(c: *checker, tagged: *node, v: *node) bool = { // scrutinee. Handles nkind.N_IDENT (look up local/param's declared // type) and nkind.N_DOT (module-qualified ref). Returns nil if we // can't statically determine the type. Used by exhaustiveness. -fn scruttype(c: *checker, e: *node) *node = { +fn scruttype(c: *checker, e: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - if (e.kind == nkind.N_IDENT) { + if (e.kind == syntax.nkind.N_IDENT) { // #58: mod-blind by leaf — lenient-only. Feeds match // exhaustiveness; codegen reads the stamped n.type_, so a // mis-resolution cannot drive a wrong binary (no repro). // Tracked: #58. - let s: *sym = scopelookup(c.cur, e.str); + let s: *syntax.sym = syntax.scopelookup(c.cur, e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; // For nkind.N_LET / nkind.N_PARAM: declared type is decl.lhs. @@ -11911,10 +11911,10 @@ fn scruttype(c: *checker, e: *node) *node = { // shape resolvealias' dotted-name branch now consumes. Falls // silently to nil when lhs is a value (struct-field access) — // the rest of the lenient-check contract. - if (e.kind == nkind.N_DOT) { + if (e.kind == syntax.nkind.N_DOT) { if (e.lhs == nil) { return nil; }; - if (e.lhs.kind != nkind.N_IDENT) { return nil; }; - let s: *sym = scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.str), e.str); + if (e.lhs.kind != syntax.nkind.N_IDENT) { return nil; }; + let s: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.str), e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; return s.decl.lhs; @@ -11925,8 +11925,8 @@ fn scruttype(c: *checker, e: *node) *node = { // mktname — fabricate an nkind.N_TNAME node with str = `nm`. Used by // exprtype to return primitive type nodes for literal // expressions. The arena keeps them around as long as the checker. -fn mktname(c: *checker, nm: str) *node = { - let n: *node = newnode(nkind.N_TNAME, "", 0, 0); +fn mktname(c: *checker, nm: str) *syntax.node = { + let n: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, "", 0, 0); n.str = nm; return n; }; @@ -11938,16 +11938,16 @@ fn mktname(c: *checker, nm: str) *node = { // names; callers fall back to alias/struct/enum lookup. Cstage's // equivalent SSoT is cmd/wcc/type.c:46-79 (ty_void/ty_bool/.../ty_str). fn primtypesize(nm: str) i64 = { - if (streq(nm, "void")) { return 0i64; }; - if (streq(nm, "bool")) { return 1i64; }; - if (streq(nm, "i8") || streq(nm, "u8")) { return 1i64; }; - if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; }; - if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; }; - if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64")) { return 8i64; }; - if (streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr") || streq(nm, "size")) { return 8i64; }; + if (syntax.streq(nm, "void")) { return 0i64; }; + if (syntax.streq(nm, "bool")) { return 1i64; }; + if (syntax.streq(nm, "i8") || syntax.streq(nm, "u8")) { return 1i64; }; + if (syntax.streq(nm, "i16") || syntax.streq(nm, "u16")) { return 2i64; }; + if (syntax.streq(nm, "i32") || syntax.streq(nm, "u32") || syntax.streq(nm, "f32") || syntax.streq(nm, "rune")) { return 4i64; }; + if (syntax.streq(nm, "i64") || syntax.streq(nm, "u64") || syntax.streq(nm, "f64")) { return 8i64; }; + if (syntax.streq(nm, "int") || syntax.streq(nm, "uint") || syntax.streq(nm, "uintptr") || syntax.streq(nm, "size")) { return 8i64; }; // str IS []u8: 24B, sourced from the slice header SSoT so str and // []u8 can never drift; no second hardcoded 24 (#1/Phase 3). - if (streq(nm, "str")) { return tyslicesize(); }; + if (syntax.streq(nm, "str")) { return tyslicesize(); }; return -1i64; }; @@ -11962,27 +11962,27 @@ fn tyslicesize() i64 = { return 24i64; }; // sizelint-ok: SSoT for ty_slice head // materialises tinfo for user types so the fold has to walk the AST // directly. Struct layout follows cstage check.c:471-526 (align each // field, max align for the whole record, round size up to alignment). -fn astalign(c: *checker, t: *node) i64 = { +fn astalign(c: *checker, t: *syntax.node) i64 = { if (t == nil) { return 1i64; }; - let k: nkind = t.kind; - if (k == nkind.N_TBANG) { return astalign(c, t.lhs); }; - if (k == nkind.N_TPTR) { return 8i64; }; - if (k == nkind.N_TSLICE) { return 8i64; }; - if (k == nkind.N_TCHAN) { return 8i64; }; - if (k == nkind.N_TFN) { return 8i64; }; - if (k == nkind.N_TARRAY) { return astalign(c, t.lhs); }; - if (k == nkind.N_TTAGGED) { + let k: syntax.nkind = t.kind; + if (k == syntax.nkind.N_TBANG) { return astalign(c, t.lhs); }; + if (k == syntax.nkind.N_TPTR) { return 8i64; }; + if (k == syntax.nkind.N_TSLICE) { return 8i64; }; + if (k == syntax.nkind.N_TCHAN) { return 8i64; }; + if (k == syntax.nkind.N_TFN) { return 8i64; }; + if (k == syntax.nkind.N_TARRAY) { return astalign(c, t.lhs); }; + if (k == syntax.nkind.N_TTAGGED) { // Route through the normalization SSoT: a lone survivor // collapses (align((i32|never))==align(i32)==4, not the tag // word's 8), matching cstage align() reading resolve_type(...) // ->align (cmd/wcc/check.c:1550). Same #1 family as astsize. - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { return ti.align: i64; }; return 8i64; }; - if (k == nkind.N_TTUPLE) { + if (k == syntax.nkind.N_TTUPLE) { let m: i64 = 1i64; - let p: *node = t.list; + let p: *syntax.node = t.list; for (p != nil) { let pa: i64 = astalign(c, p.lhs); if (pa > m) { m = pa; }; @@ -11990,11 +11990,11 @@ fn astalign(c: *checker, t: *node) i64 = { }; return m; }; - if (k == nkind.N_TSTRUCT) { + if (k == syntax.nkind.N_TSTRUCT) { let m: i64 = 1i64; - let f: *node = t.list; + let f: *syntax.node = t.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { let fa: i64 = astalign(c, f.lhs); if (fa > m) { m = fa; }; }; @@ -12002,17 +12002,17 @@ fn astalign(c: *checker, t: *node) i64 = { }; return m; }; - if (k == nkind.N_TENUM) { + if (k == syntax.nkind.N_TENUM) { if (t.lhs != nil) { return astalign(c, t.lhs); }; return 4i64; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; - if (streq(nm, "void") || streq(nm, "bool") || streq(nm, "i8") || streq(nm, "u8")) { return 1i64; }; - if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; }; - if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; }; - if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64") || streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr") || streq(nm, "size") || streq(nm, "str")) { return 8i64; }; - let resolved: *node = resolvealias(c, t); + if (syntax.streq(nm, "void") || syntax.streq(nm, "bool") || syntax.streq(nm, "i8") || syntax.streq(nm, "u8")) { return 1i64; }; + if (syntax.streq(nm, "i16") || syntax.streq(nm, "u16")) { return 2i64; }; + if (syntax.streq(nm, "i32") || syntax.streq(nm, "u32") || syntax.streq(nm, "f32") || syntax.streq(nm, "rune")) { return 4i64; }; + if (syntax.streq(nm, "i64") || syntax.streq(nm, "u64") || syntax.streq(nm, "f64") || syntax.streq(nm, "int") || syntax.streq(nm, "uint") || syntax.streq(nm, "uintptr") || syntax.streq(nm, "size") || syntax.streq(nm, "str")) { return 8i64; }; + let resolved: *syntax.node = resolvealias(c, t); if (resolved != nil && resolved != t) { return astalign(c, resolved); }; @@ -12020,38 +12020,38 @@ fn astalign(c: *checker, t: *node) i64 = { return 1i64; }; -fn astsize(c: *checker, t: *node) i64 = { +fn astsize(c: *checker, t: *syntax.node) i64 = { if (t == nil) { return 0i64; }; - let k: nkind = t.kind; - if (k == nkind.N_TBANG) { return astsize(c, t.lhs); }; - if (k == nkind.N_TPTR) { return 8i64; }; - if (k == nkind.N_TSLICE) { return tyslicesize(); }; - if (k == nkind.N_TCHAN) { return 8i64; }; - if (k == nkind.N_TFN) { return 8i64; }; - if (k == nkind.N_TARRAY) { + let k: syntax.nkind = t.kind; + if (k == syntax.nkind.N_TBANG) { return astsize(c, t.lhs); }; + if (k == syntax.nkind.N_TPTR) { return 8i64; }; + if (k == syntax.nkind.N_TSLICE) { return tyslicesize(); }; + if (k == syntax.nkind.N_TCHAN) { return 8i64; }; + if (k == syntax.nkind.N_TFN) { return 8i64; }; + if (k == syntax.nkind.N_TARRAY) { // #141: a def-dimensioned field array sized to 0 here, so the // struct loop (off += astsize(field)) overlapped the next // field; arrayelen folds the def. let elen: i64 = arrayelen(c, t.rhs): i64; return astsize(c, t.lhs) * elen; }; - if (k == nkind.N_TTUPLE) { + if (k == syntax.nkind.N_TTUPLE) { // Route through the type table, NOT a packed element-sum: // slot layout is the tuple SSoT (C-t0, user-ratified) and // tupleelemslot is its one wwstage answer. The packed walk // this replaces was a C-t0 escape — size((u32,u32)) folded // to 8 here while cstage (check.c N_TTUPLE) and the wwstage // type table both said 16 (task #22 commit 0). - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { return ti.size: i64; }; return 0i64; }; - if (k == nkind.N_TSTRUCT) { + if (k == syntax.nkind.N_TSTRUCT) { let off: i64 = 0i64; let maxal: i64 = 1i64; - let f: *node = t.list; + let f: *syntax.node = t.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { let fa: i64 = astalign(c, f.lhs); if (fa > maxal) { maxal = fa; }; off = (off + fa - 1i64) & ~(fa - 1i64); @@ -12061,7 +12061,7 @@ fn astsize(c: *checker, t: *node) i64 = { }; return (off + maxal - 1i64) & ~(maxal - 1i64); }; - if (k == nkind.N_TTAGGED) { + if (k == syntax.nkind.N_TTAGGED) { // Route through tinfofornode (the tagged-normalization SSoT) // so the size() fold matches cgen's layout AND cstage: the raw // 8+roundup8(max) here ignored never-drop / dedup / single- @@ -12069,19 +12069,19 @@ fn astsize(c: *checker, t: *node) i64 = { // size((i32|never)) 16 not 4 (#1). Mirrors the N_TTUPLE arm // above and cstage size() reading resolve_type(...)->size // (cmd/wcc/check.c:1547-1550). - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { return ti.size: i64; }; return 0i64; }; - if (k == nkind.N_TENUM) { + if (k == syntax.nkind.N_TENUM) { if (t.lhs != nil) { return astsize(c, t.lhs); }; return 4i64; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; let ps: i64 = primtypesize(nm); if (ps >= 0i64) { return ps; }; - let resolved: *node = resolvealias(c, t); + let resolved: *syntax.node = resolvealias(c, t); if (resolved != nil && resolved != t) { return astsize(c, resolved); }; @@ -12103,36 +12103,36 @@ fn astsize(c: *checker, t: *node) i64 = { // require_sized guards that reject unsized aggregates at the type decl // (so the cstage size/align fold only ever sees a leaf opaque); harec // ref/harec/src/check.c:2720, type_store.c:1147 (tuple) / :449 (tagged). -fn astunsized(c: *checker, t: *node) bool = { +fn astunsized(c: *checker, t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return false; }; - let k: nkind = u.kind; - if (k == nkind.N_TNAME) { - if (streq(u.str, "opaque")) { return true; }; + let k: syntax.nkind = u.kind; + if (k == syntax.nkind.N_TNAME) { + if (syntax.streq(u.str, "opaque")) { return true; }; return false; }; - if (k == nkind.N_TARRAY) { return astunsized(c, u.lhs); }; - if (k == nkind.N_TTUPLE) { - let p: *node = u.list; + if (k == syntax.nkind.N_TARRAY) { return astunsized(c, u.lhs); }; + if (k == syntax.nkind.N_TTUPLE) { + let p: *syntax.node = u.list; for (p != nil) { if (astunsized(c, p.lhs)) { return true; }; p = p.next; }; return false; }; - if (k == nkind.N_TSTRUCT) { - let f: *node = u.list; + if (k == syntax.nkind.N_TSTRUCT) { + let f: *syntax.node = u.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { if (astunsized(c, f.lhs)) { return true; }; }; f = f.next; }; return false; }; - if (k == nkind.N_TTAGGED) { - let v: *node = u.list; + if (k == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = u.list; for (v != nil) { if (astunsized(c, v)) { return true; }; v = v.next; @@ -12175,11 +12175,11 @@ fn astunsized(c: *checker, t: *node) bool = { // call use it). The #241 `yield ` fallback (the dominant // match-bind-then-yield idiom, Hare's parseint `case let t => yield t`) // stays, now resolving btype to a tinfo. -fn matchyieldtype(c: *checker, body: *node, bname: str, btype: *node, - nodeout: **node) *tinfo = { +fn matchyieldtype(c: *checker, body: *syntax.node, bname: str, btype: *syntax.node, + nodeout: **syntax.node) *syntax.tinfo = { if (body == nil) { return nil; }; - let k: nkind = body.kind; - if (k == nkind.N_YIELD) { + let k: syntax.nkind = body.kind; + if (k == syntax.nkind.N_YIELD) { if (body.lhs == nil) { return nil; }; if (body.lhs.type_ != nil) { // For the bare-binder idiom `yield `, ALSO surface @@ -12191,40 +12191,40 @@ fn matchyieldtype(c: *checker, body: *node, bname: str, btype: *node, // match idiom in tree, grep-confirmed). btype is the binder's // declared type node, which IS the match's type here; the // cached tinfo returned below equals tinfofornode(btype). - if (body.lhs.kind == nkind.N_IDENT && bname.len > 0 - && streq(body.lhs.str, bname)) { + if (body.lhs.kind == syntax.nkind.N_IDENT && bname.len > 0 + && syntax.streq(body.lhs.str, bname)) { *nodeout = btype; }; - return body.lhs.type_: *tinfo; + return body.lhs.type_: *syntax.tinfo; }; - let t: *node = exprtype(c, body.lhs, nil); + let t: *syntax.node = exprtype(c, body.lhs, nil); if (t != nil) { *nodeout = t; return tinfofornode(c, t); }; - if (body.lhs.kind == nkind.N_IDENT && bname.len > 0 - && streq(body.lhs.str, bname)) { + if (body.lhs.kind == syntax.nkind.N_IDENT && bname.len > 0 + && syntax.streq(body.lhs.str, bname)) { *nodeout = btype; return tinfofornode(c, btype); }; return nil; }; - if (k == nkind.N_MATCH) { return nil; }; - if (k == nkind.N_BLOCK) { - let s: *node = body.list; + if (k == syntax.nkind.N_MATCH) { return nil; }; + if (k == syntax.nkind.N_BLOCK) { + let s: *syntax.node = body.list; for (s != nil) { - let t: *tinfo = matchyieldtype(c, s, bname, btype, nodeout); + let t: *syntax.tinfo = matchyieldtype(c, s, bname, btype, nodeout); if (t != nil) { return t; }; s = s.next; }; return nil; }; - if (k == nkind.N_IF) { - let t: *tinfo = matchyieldtype(c, body.body, bname, btype, nodeout); + if (k == syntax.nkind.N_IF) { + let t: *syntax.tinfo = matchyieldtype(c, body.body, bname, btype, nodeout); if (t != nil) { return t; }; return matchyieldtype(c, body.els, bname, btype, nodeout); }; - if (k == nkind.N_FOR || k == nkind.N_FORRANGE) { + if (k == syntax.nkind.N_FOR || k == syntax.nkind.N_FORRANGE) { return matchyieldtype(c, body.body, bname, btype, nodeout); }; return nil; @@ -12239,13 +12239,13 @@ fn matchyieldtype(c: *checker, body: *node, bname: str, btype: *node, // family mismatch (the catA repro: an int arm vs a str arm) and never an // untyped->concrete promotion (untyped_int vs i32/f64 both land in class 1) // that cstage accepts. The families mirror typeisnum/typeisstr (lib/ww/typ.ww). -fn yieldclass(t: *tinfo) i32 = { - let u: *tinfo = tichase(t); +fn yieldclass(t: *syntax.tinfo) i32 = { + let u: *syntax.tinfo = tichase(t); if (u == nil) { return 0i32; }; - if (typeisnum(u)) { return 1i32; }; - if (typeisstr(u)) { return 2i32; }; - if (u.kind == tykind.TY_BOOL) { return 3i32; }; - if (u.kind == tykind.TY_UNTYPED_BOOL) { return 3i32; }; + if (syntax.typeisnum(u)) { return 1i32; }; + if (syntax.typeisstr(u)) { return 2i32; }; + if (u.kind == syntax.tykind.TY_BOOL) { return 3i32; }; + if (u.kind == syntax.tykind.TY_UNTYPED_BOOL) { return 3i32; }; return 0i32; }; @@ -12254,25 +12254,25 @@ fn yieldclass(t: *tinfo) i32 = { // (for `p.field` where p is *Struct), require N_TSTRUCT, walk fields // honouring per-field alignment, return -1 if the field name is // absent so the caller can flag the error and fold to 0. -fn astoffset(c: *checker, dot: *node) i64 = { +fn astoffset(c: *checker, dot: *syntax.node) i64 = { if (dot == nil) { return -1i64; }; - if (dot.kind != nkind.N_DOT) { return -1i64; }; - let recv: *node = scruttype(c, dot.lhs); + if (dot.kind != syntax.nkind.N_DOT) { return -1i64; }; + let recv: *syntax.node = scruttype(c, dot.lhs); if (recv == nil) { return -1i64; }; - let rtyp: *node = resolvealias(c, unwrapbang(recv)); + let rtyp: *syntax.node = resolvealias(c, unwrapbang(recv)); if (rtyp == nil) { return -1i64; }; - if (rtyp.kind == nkind.N_TPTR) { + if (rtyp.kind == syntax.nkind.N_TPTR) { rtyp = resolvealias(c, unwrapbang(rtyp.lhs)); }; if (rtyp == nil) { return -1i64; }; - if (rtyp.kind != nkind.N_TSTRUCT) { return -1i64; }; + if (rtyp.kind != syntax.nkind.N_TSTRUCT) { return -1i64; }; let off: i64 = 0i64; - let f: *node = rtyp.list; + let f: *syntax.node = rtyp.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { let fa: i64 = astalign(c, f.lhs); off = (off + fa - 1i64) & ~(fa - 1i64); - if (streq(f.str, dot.str)) { return off; }; + if (syntax.streq(f.str, dot.str)) { return off; }; off += astsize(c, f.lhs); }; f = f.next; @@ -12306,8 +12306,8 @@ fn arenau64tos(v: u64) str = { // Used by the #42 size/align/offset intercepts so cgen sees the // folded literal rather than an unresolved call. Mirrors cstage // cmd/wcc/check.c:919-927 / :951-958. -fn foldtointlit(c: *checker, n: *node, v: i64) void = { - n.kind = nkind.N_INTLIT; +fn foldtointlit(c: *checker, n: *syntax.node, v: i64) void = { + n.kind = syntax.nkind.N_INTLIT; n.uval = v: u64; n.str = arenau64tos(v: u64); n.lhs = nil; @@ -12323,23 +12323,23 @@ fn foldtointlit(c: *checker, n: *node, v: i64) void = { // literal — rule 10 lives at the check pass for #88. Returns false on // division by zero or an op outside the constant subset; the caller // maps that to its own diagnostic. -fn foldbinop(op: tkind, a: u64, b: u64, out: *u64) bool = { - if (op == tkind.TK_PLUS) { *out = a + b; return true; }; - if (op == tkind.TK_MINUS) { *out = a - b; return true; }; - if (op == tkind.TK_STAR) { *out = a * b; return true; }; - if (op == tkind.TK_SLASH) { +fn foldbinop(op: syntax.tkind, a: u64, b: u64, out: *u64) bool = { + if (op == syntax.tkind.TK_PLUS) { *out = a + b; return true; }; + if (op == syntax.tkind.TK_MINUS) { *out = a - b; return true; }; + if (op == syntax.tkind.TK_STAR) { *out = a * b; return true; }; + if (op == syntax.tkind.TK_SLASH) { if (b == 0u64) { return false; }; *out = a / b; return true; }; - if (op == tkind.TK_PERCENT) { + if (op == syntax.tkind.TK_PERCENT) { if (b == 0u64) { return false; }; *out = a % b; return true; }; - if (op == tkind.TK_AMP) { *out = a & b; return true; }; - if (op == tkind.TK_PIPE) { *out = a | b; return true; }; - if (op == tkind.TK_CARET) { *out = a ^ b; return true; }; - if (op == tkind.TK_LSHIFT) { *out = a << b; return true; }; - if (op == tkind.TK_RSHIFT) { *out = a >> b; return true; }; + if (op == syntax.tkind.TK_AMP) { *out = a & b; return true; }; + if (op == syntax.tkind.TK_PIPE) { *out = a | b; return true; }; + if (op == syntax.tkind.TK_CARET) { *out = a ^ b; return true; }; + if (op == syntax.tkind.TK_LSHIFT) { *out = a << b; return true; }; + if (op == syntax.tkind.TK_RSHIFT) { *out = a >> b; return true; }; return false; }; @@ -12348,7 +12348,7 @@ fn foldbinop(op: tkind, a: u64, b: u64, out: *u64) bool = { // gates cgen off in main.ww:165, so this fails the build rather than // emitting a missing DATA row silently (rule 7). cstage twin: err() // in cmd/wcc/check.c. -fn deffolderr(c: *checker, n: *node, msg: str) void = { +fn deffolderr(c: *checker, n: *syntax.node, msg: str) void = { cerr(n.file); cerr(": error: "); cerr(msg); @@ -12364,12 +12364,12 @@ fn deffolderr(c: *checker, n: *node, msg: str) void = { // (t.size, rule 13); the 8s are CHAR_BIT and the u64 byte-width, not // type-layout sizes, so they sit outside rule 13's scope. Pure-u64 so // the range check is bit-identical to cstage (rule 10). -fn defcastfits(t: *tinfo, v: u64) bool = { - if (!typeisint(t)) { return true; }; // non-int target: keep value +fn defcastfits(t: *syntax.tinfo, v: u64) bool = { + if (!syntax.typeisint(t)) { return true; }; // non-int target: keep value let w: u64 = t.size; if (w >= 8u64) { return true; }; // 64-bit target: no narrowing let bits: u64 = w * 8u64; - if (typeisunsigned(t)) { return (v >> bits) == 0u64; }; + if (syntax.typeisunsigned(t)) { return (v >> bits) == 0u64; }; // signed: truncate to `bits` then sign-extend; fits iff unchanged let mask: u64 = (1u64 << bits) - 1u64; let sign: u64 = 1u64 << (bits - 1u64); @@ -12396,45 +12396,45 @@ fn defcastfits(t: *tinfo, v: u64) bool = { // `depth` bounds a def->def->def chain; a cycle (def A = B; def B = A, // incl. cross-module) hits the cap and fails loud rather than hanging // (rule 7), mirroring the cgen nsteps>=16 abort precedent. -fn evaldefconst(c: *checker, n: *node, out: *u64, depth: i32) bool = { +fn evaldefconst(c: *checker, n: *syntax.node, out: *u64, depth: i32) bool = { if (n == nil) { return false; }; if (depth >= 16) { deffolderr(c, n, "def value: reference chain too deep (cycle?)"); return false; }; if (foldintliteral(n, out)) { return true; }; - let k: nkind = n.kind; - if (k == nkind.N_BIN) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_BIN) { let a: u64 = 0u64; let b: u64 = 0u64; if (!evaldefconst(c, n.lhs, &a, depth + 1)) { return false; }; if (!evaldefconst(c, n.rhs, &b, depth + 1)) { return false; }; if (foldbinop(n.op, a, b, out)) { return true; }; - if ((n.op == tkind.TK_SLASH || n.op == tkind.TK_PERCENT) && b == 0u64) { + if ((n.op == syntax.tkind.TK_SLASH || n.op == syntax.tkind.TK_PERCENT) && b == 0u64) { deffolderr(c, n, "def value: division by zero"); } else { deffolderr(c, n, "def value: unsupported binary op"); }; return false; }; - if (k == nkind.N_UN) { + if (k == syntax.nkind.N_UN) { // foldintliteral already covers unary-over-leaf; this arm // catches unary over a resolved ref, e.g. `-A`. let v: u64 = 0u64; if (!evaldefconst(c, n.lhs, &v, depth + 1)) { return false; }; - if (n.op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (n.op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (n.op == tkind.TK_PLUS) { *out = v; return true; }; + if (n.op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (n.op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (n.op == syntax.tkind.TK_PLUS) { *out = v; return true; }; deffolderr(c, n, "def value: unsupported unary op"); return false; }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { // n.lhs = value; n.type_ = resolved target (stamped by // exprtype's N_CAST arm during resolvewalk). Strip the cast // keeping the value; a narrowing cast that loses it fails loud. let v: u64 = 0u64; if (!evaldefconst(c, n.lhs, &v, depth + 1)) { return false; }; - let t: *tinfo = (n.type_): *tinfo; + let t: *syntax.tinfo = (n.type_): *syntax.tinfo; if (!defcastfits(t, v)) { deffolderr(c, n, "def value: narrowing cast loses value"); return false; @@ -12442,20 +12442,20 @@ fn evaldefconst(c: *checker, n: *node, out: *u64, depth: i32) bool = { *out = v; return true; }; - if (k == nkind.N_IDENT) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, n.str); + if (k == syntax.nkind.N_IDENT) { + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, n.str); if (s == nil) { return false; }; - if (s.skind != skind.SK_DEF) { return false; }; + if (s.skind != syntax.skind.SK_DEF) { return false; }; if (s.decl == nil) { return false; }; if (s.decl.rhs == nil) { return false; }; return evaldefconst(c, s.decl.rhs, out, depth + 1); }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { if (n.lhs == nil) { return false; }; - if (n.lhs.kind != nkind.N_IDENT) { return false; }; - let s: *sym = scopelookupinmodule(c.cur, modkeyfor(c, n.lhs.str), n.str); + if (n.lhs.kind != syntax.nkind.N_IDENT) { return false; }; + let s: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, n.lhs.str), n.str); if (s == nil) { return false; }; - if (s.skind != skind.SK_DEF) { return false; }; + if (s.skind != syntax.skind.SK_DEF) { return false; }; if (s.decl == nil) { return false; }; if (s.decl.rhs == nil) { return false; }; return evaldefconst(c, s.decl.rhs, out, depth + 1); @@ -12468,10 +12468,10 @@ fn evaldefconst(c: *checker, n: *node, out: *u64, depth: i32) bool = { // width and pass-3 asserttyped see a properly-typed literal leaf. Lets // cgen's existing emitdefconstants lay down the row with no codegen // change (#88). Shape mirrors foldtointlit (the #42 stamp). -fn stampintlit(n: *node, v: u64) void = { - n.kind = nkind.N_INTLIT; +fn stampintlit(n: *syntax.node, v: u64) void = { + n.kind = syntax.nkind.N_INTLIT; n.uval = v; - n.op = tkind.TK_NONE; + n.op = syntax.tkind.TK_NONE; n.str = arenau64tos(v); n.lhs = nil; n.rhs = nil; @@ -12493,9 +12493,9 @@ fn stampintlit(n: *node, v: u64) void = { // SSoT), so every N_TARRAY length reader routes here to fold the dim // identically — astsize (struct layout), tinfofornode (canonical // tinfo), checkarrlitfits (count gate). -fn arrayelen(c: *checker, rhs: *node) u64 = { +fn arrayelen(c: *checker, rhs: *syntax.node) u64 = { if (rhs == nil) { return 0u64; }; - if (rhs.kind == nkind.N_INTLIT) { return rhs.uval; }; + if (rhs.kind == syntax.nkind.N_INTLIT) { return rhs.uval; }; let v: u64 = 0u64; if (evaldefconst(c, rhs, &v, 0)) { return v; }; return 0u64; @@ -12524,33 +12524,33 @@ fn arrayelen(c: *checker, rhs: *node) u64 = { // practice — harec accepts the same shape without memoisation per // resolve_enum_field's wrap_resolver chain // (ref/harec/src/check.c:4438) — so the quadratic is harmless. -fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = { +fn enumvalfold(body: *syntax.node, until: *syntax.node, e: *syntax.node, out: *u64) bool = { if (e == nil) { return false; }; - let k: nkind = e.kind; - if (k == nkind.N_INTLIT) { *out = e.uval; return true; }; - if (k == nkind.N_RUNELIT) { *out = e.uval; return true; }; - if (k == nkind.N_TRUE) { *out = 1u64; return true; }; - if (k == nkind.N_FALSE) { *out = 0u64; return true; }; - if (k == nkind.N_NIL) { *out = 0u64; return true; }; - if (k == nkind.N_UN) { + let k: syntax.nkind = e.kind; + if (k == syntax.nkind.N_INTLIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_RUNELIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_TRUE) { *out = 1u64; return true; }; + if (k == syntax.nkind.N_FALSE) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_NIL) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_UN) { let v: u64 = 0u64; if (!enumvalfold(body, until, e.lhs, &v)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (op == tkind.TK_PLUS) { *out = v; return true; }; + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (op == syntax.tkind.TK_PLUS) { *out = v; return true; }; return false; }; - if (k == nkind.N_BIN) { + if (k == syntax.nkind.N_BIN) { let a: u64 = 0u64; let b: u64 = 0u64; if (!enumvalfold(body, until, e.lhs, &a)) { return false; }; if (!enumvalfold(body, until, e.rhs, &b)) { return false; }; return foldbinop(e.op, a, b, out); }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { let prev: u64 = (-1i64): u64; - let m: *node = body.list; + let m: *syntax.node = body.list; for (m != nil && m != until) { let val: u64 = 0u64; if (m.lhs == nil) { @@ -12559,7 +12559,7 @@ fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = { if (!enumvalfold(body, m, m.lhs, &val)) { return false; }; }; prev = val; - if (streq(m.str, e.str)) { *out = val; return true; }; + if (syntax.streq(m.str, e.str)) { *out = val; return true; }; m = m.next; }; return false; @@ -12580,13 +12580,13 @@ fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = { // mirror that. The value itself is folded to a constant at every use // site (enumvalfold) and at codegen (cgen.ww enumevalmember), so cgen // never reads these node types — this stamp is checker metadata only. -fn stampenumvals(c: *checker, n: *node) void = { - let under: *tinfo = c.tc.tyi32; +fn stampenumvals(c: *checker, n: *syntax.node) void = { + let under: *syntax.tinfo = c.tc.tyi32; if (n.lhs != nil) { - let s: *tinfo = tinfofornode(c, n.lhs); + let s: *syntax.tinfo = tinfofornode(c, n.lhs); if (s != nil) { under = s; }; }; - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { stampnilexpr(m.lhs, under); m = m.next; @@ -12597,7 +12597,7 @@ fn stampenumvals(c: *checker, n: *node) void = { // `ti`. lhs/rhs cover the enum constexpr grammar enumvalfold accepts // (literals, unary, binary, sibling backref); non-nil nodes keep the // type exprtype already derived. -fn stampnilexpr(n: *node, ti: *tinfo) void = { +fn stampnilexpr(n: *syntax.node, ti: *syntax.tinfo) void = { if (n == nil) { return; }; if (n.type_ == nil) { n.type_ = ti: *void; }; stampnilexpr(n.lhs, ti); @@ -12614,36 +12614,36 @@ fn stampnilexpr(n: *node, ti: *tinfo) void = { // 8; void contributes 0 (never appears in tuples emitted by user // code, but kept for SSoT symmetry with cgen's N_TNAME-"void" // fallback arm). -fn tupleelemslot(pt: *tinfo) u64 = { +fn tupleelemslot(pt: *syntax.tinfo) u64 = { if (pt == nil) { return 8u64; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. - let t: *tinfo = pt; + let t: *syntax.tinfo = pt; t = tichase(t); if (t == nil) { return 8u64; }; - let pk: tykind = t.kind; - if (pk == tykind.TY_VOID) { return 0u64; }; - if (pk == tykind.TY_STR) { return t.size; }; - if (pk == tykind.TY_SLICE) { return t.size; }; + let pk: syntax.tykind = t.kind; + if (pk == syntax.tykind.TY_VOID) { return 0u64; }; + if (pk == syntax.tykind.TY_STR) { return t.size; }; + if (pk == syntax.tykind.TY_SLICE) { return t.size; }; // #22 (user-ratified 2026-06-04): slot = roundup8(size(elem)) — 8B // is a FLOOR, not a ceiling. (str,str)=48B predates this; tagged // was the one truncated >8B kind (the #237 fieldslotsize-missing- // TY_TUPLE precedent: fieldslotsize below already carried this // arm). Cstage twin: check.c N_TTUPLE; cgen accessor: tuple_eslot // / tupeslot. - if (pk == tykind.TY_TAGGED) { return (t.size + 7u64) & ~7u64; }; - if (pk == tykind.TY_PTR || pk == tykind.TY_FN || - pk == tykind.TY_CHAN || pk == tykind.TY_I64 || - pk == tykind.TY_U64 || pk == tykind.TY_INT || - pk == tykind.TY_UINT || pk == tykind.TY_UINTPTR || - pk == tykind.TY_SIZE || pk == tykind.TY_F64) { return 8u64; }; - if (pk == tykind.TY_BOOL || pk == tykind.TY_RUNE || - pk == tykind.TY_I8 || pk == tykind.TY_I16 || - pk == tykind.TY_I32 || pk == tykind.TY_U8 || - pk == tykind.TY_U16 || pk == tykind.TY_U32 || - pk == tykind.TY_F32 || pk == tykind.TY_ENUM) { return 8u64; }; + if (pk == syntax.tykind.TY_TAGGED) { return (t.size + 7u64) & ~7u64; }; + if (pk == syntax.tykind.TY_PTR || pk == syntax.tykind.TY_FN || + pk == syntax.tykind.TY_CHAN || pk == syntax.tykind.TY_I64 || + pk == syntax.tykind.TY_U64 || pk == syntax.tykind.TY_INT || + pk == syntax.tykind.TY_UINT || pk == syntax.tykind.TY_UINTPTR || + pk == syntax.tykind.TY_SIZE || pk == syntax.tykind.TY_F64) { return 8u64; }; + if (pk == syntax.tykind.TY_BOOL || pk == syntax.tykind.TY_RUNE || + pk == syntax.tykind.TY_I8 || pk == syntax.tykind.TY_I16 || + pk == syntax.tykind.TY_I32 || pk == syntax.tykind.TY_U8 || + pk == syntax.tykind.TY_U16 || pk == syntax.tykind.TY_U32 || + pk == syntax.tykind.TY_F32 || pk == syntax.tykind.TY_ENUM) { return 8u64; }; // Composite — one 8B eightbyte, NOT t.slotsize: cgen's cursor // transport strides `wide ? size : 8` at every tuple site (both // stages), so a composite element rides one register word today. @@ -12660,44 +12660,44 @@ fn tupleelemslot(pt: *tinfo) u64 = { // slot-padded total (si.totsize equivalent); primitives keep their // natural width (struct interior packing is unaffected by stack-slot // pad-to-8); arrays use their slot-padded element-stride * elen. -fn fieldslotsize(ft: *tinfo) u64 = { +fn fieldslotsize(ft: *syntax.tinfo) u64 = { if (ft == nil) { return 8u64; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. - let t: *tinfo = ft; + let t: *syntax.tinfo = ft; t = tichase(t); if (t == nil) { return 8u64; }; - let fk: tykind = t.kind; - if (fk == tykind.TY_STRUCT) { return t.slotsize; }; - if (fk == tykind.TY_ARRAY) { return t.slotsize; }; - if (fk == tykind.TY_TAGGED) { return t.size; }; + let fk: syntax.tykind = t.kind; + if (fk == syntax.tykind.TY_STRUCT) { return t.slotsize; }; + if (fk == syntax.tykind.TY_ARRAY) { return t.slotsize; }; + if (fk == syntax.tykind.TY_TAGGED) { return t.size; }; // str / slice read t.size so the typ.ww SSoT seed is the single // source for #1 (str→24) / #34 (slice graduation) — no hardcoded // literal here to drift. - if (fk == tykind.TY_SLICE) { return t.size; }; - if (fk == tykind.TY_PTR || fk == tykind.TY_FN || - fk == tykind.TY_CHAN) { return 8u64; }; - if (fk == tykind.TY_STR) { return t.size; }; + if (fk == syntax.tykind.TY_SLICE) { return t.size; }; + if (fk == syntax.tykind.TY_PTR || fk == syntax.tykind.TY_FN || + fk == syntax.tykind.TY_CHAN) { return 8u64; }; + if (fk == syntax.tykind.TY_STR) { return t.size; }; // #237: a tuple-typed struct field carries its own slot total (the // per-element slot sum stamped at the N_TTUPLE arm above — slices at // 24 each). Without this it fell to the 8B default below, undersizing // the enclosing struct's slotsize (size stayed correct), so a `let s:S` // slot was too small — a silent stack-corrupting miscompile. Aligns // with cgenutil.ww fieldsize, which already returns the tuple's size. - if (fk == tykind.TY_TUPLE) { return t.slotsize; }; + if (fk == syntax.tykind.TY_TUPLE) { return t.slotsize; }; // Primitives keep natural width inside structs (matches // cgenutil fieldsize: primsize, not pad-to-8). - if (fk == tykind.TY_BOOL || fk == tykind.TY_RUNE || - fk == tykind.TY_I8 || fk == tykind.TY_I16 || - fk == tykind.TY_I32 || fk == tykind.TY_I64 || - fk == tykind.TY_U8 || fk == tykind.TY_U16 || - fk == tykind.TY_U32 || fk == tykind.TY_U64 || - fk == tykind.TY_INT || fk == tykind.TY_UINT || - fk == tykind.TY_UINTPTR || fk == tykind.TY_SIZE || - fk == tykind.TY_F32 || fk == tykind.TY_F64 || - fk == tykind.TY_ENUM) { return t.size; }; + if (fk == syntax.tykind.TY_BOOL || fk == syntax.tykind.TY_RUNE || + fk == syntax.tykind.TY_I8 || fk == syntax.tykind.TY_I16 || + fk == syntax.tykind.TY_I32 || fk == syntax.tykind.TY_I64 || + fk == syntax.tykind.TY_U8 || fk == syntax.tykind.TY_U16 || + fk == syntax.tykind.TY_U32 || fk == syntax.tykind.TY_U64 || + fk == syntax.tykind.TY_INT || fk == syntax.tykind.TY_UINT || + fk == syntax.tykind.TY_UINTPTR || fk == syntax.tykind.TY_SIZE || + fk == syntax.tykind.TY_F32 || fk == syntax.tykind.TY_F64 || + fk == syntax.tykind.TY_ENUM) { return t.size; }; return 8u64; }; @@ -12722,53 +12722,53 @@ fn fieldslotsize(ft: *tinfo) u64 = { // typeeq's contract (TY_NAMED → only same ptr, else structural; lib/ww/ // typ.ww:581). nil guards match variant_match's `a==NULL||b==NULL → 0` // so two unresolved variants never collapse. -fn variantpresent(head: *tparam, vt: *tinfo) bool = { +fn variantpresent(head: *syntax.tparam, vt: *syntax.tinfo) bool = { if (vt == nil) { return false; }; - let p: *tparam = head; + let p: *syntax.tparam = head; for (p != nil) { if (p.type_ != nil) { - if (typeeq(p.type_, vt)) { return true; }; + if (syntax.typeeq(p.type_, vt)) { return true; }; }; p = p.tnext; }; return false; }; -fn tinfofornode(c: *checker, n: *node) *tinfo = { +fn tinfofornode(c: *checker, n: *syntax.node) *syntax.tinfo = { if (n == nil) { return nil; }; - let cached: *tinfo = tinfocachelookup(c.tc, n); + let cached: *syntax.tinfo = syntax.tinfocachelookup(c.tc, n); if (cached != nil) { return cached; }; - let r: *tinfo = nil; - let k: nkind = n.kind; + let r: *syntax.tinfo = nil; + let k: syntax.nkind = n.kind; switch (k) { - case nkind.N_TNAME: + case syntax.nkind.N_TNAME: let nm: str = n.str; - if (streq(nm, "void")) { r = c.tc.tyvoid; }; - if (streq(nm, "bool")) { r = c.tc.tybool; }; - if (streq(nm, "rune")) { r = c.tc.tyrune; }; - if (streq(nm, "i8")) { r = c.tc.tyi8; }; - if (streq(nm, "i16")) { r = c.tc.tyi16; }; - if (streq(nm, "i32")) { r = c.tc.tyi32; }; - if (streq(nm, "i64")) { r = c.tc.tyi64; }; - if (streq(nm, "u8")) { r = c.tc.tyu8; }; - if (streq(nm, "u16")) { r = c.tc.tyu16; }; - if (streq(nm, "u32")) { r = c.tc.tyu32; }; - if (streq(nm, "u64")) { r = c.tc.tyu64; }; - if (streq(nm, "int")) { r = c.tc.tyint; }; - if (streq(nm, "uint")) { r = c.tc.tyuint; }; - if (streq(nm, "uintptr")) { r = c.tc.tyuintptr; }; - if (streq(nm, "size")) { r = c.tc.tysize; }; // #85 fold-2 - if (streq(nm, "opaque")) { r = c.tc.tyopaque; }; // #108(a) - if (streq(nm, "f32")) { r = c.tc.tyf32; }; - if (streq(nm, "f64")) { r = c.tc.tyf64; }; - if (streq(nm, "str")) { r = c.tc.tystr; }; - if (streq(nm, "never")) { r = c.tc.tynever; }; - if (streq(nm, "untyped_int")) { r = c.tc.tyuntypedint; }; - if (streq(nm, "untyped_float")) { r = c.tc.tyuntypedfloat; }; - if (streq(nm, "untyped_str")) { r = c.tc.tyuntypedstr; }; - if (streq(nm, "untyped_rune")) { r = c.tc.tyuntypedrune; }; - if (streq(nm, "untyped_bool")) { r = c.tc.tyuntypedbool; }; - if (streq(nm, "untyped_nil")) { r = c.tc.tyuntypednil; }; + if (syntax.streq(nm, "void")) { r = c.tc.tyvoid; }; + if (syntax.streq(nm, "bool")) { r = c.tc.tybool; }; + if (syntax.streq(nm, "rune")) { r = c.tc.tyrune; }; + if (syntax.streq(nm, "i8")) { r = c.tc.tyi8; }; + if (syntax.streq(nm, "i16")) { r = c.tc.tyi16; }; + if (syntax.streq(nm, "i32")) { r = c.tc.tyi32; }; + if (syntax.streq(nm, "i64")) { r = c.tc.tyi64; }; + if (syntax.streq(nm, "u8")) { r = c.tc.tyu8; }; + if (syntax.streq(nm, "u16")) { r = c.tc.tyu16; }; + if (syntax.streq(nm, "u32")) { r = c.tc.tyu32; }; + if (syntax.streq(nm, "u64")) { r = c.tc.tyu64; }; + if (syntax.streq(nm, "int")) { r = c.tc.tyint; }; + if (syntax.streq(nm, "uint")) { r = c.tc.tyuint; }; + if (syntax.streq(nm, "uintptr")) { r = c.tc.tyuintptr; }; + if (syntax.streq(nm, "size")) { r = c.tc.tysize; }; // #85 fold-2 + if (syntax.streq(nm, "opaque")) { r = c.tc.tyopaque; }; // #108(a) + if (syntax.streq(nm, "f32")) { r = c.tc.tyf32; }; + if (syntax.streq(nm, "f64")) { r = c.tc.tyf64; }; + if (syntax.streq(nm, "str")) { r = c.tc.tystr; }; + if (syntax.streq(nm, "never")) { r = c.tc.tynever; }; + if (syntax.streq(nm, "untyped_int")) { r = c.tc.tyuntypedint; }; + if (syntax.streq(nm, "untyped_float")) { r = c.tc.tyuntypedfloat; }; + if (syntax.streq(nm, "untyped_str")) { r = c.tc.tyuntypedstr; }; + if (syntax.streq(nm, "untyped_rune")) { r = c.tc.tyuntypedrune; }; + if (syntax.streq(nm, "untyped_bool")) { r = c.tc.tyuntypedbool; }; + if (syntax.streq(nm, "untyped_nil")) { r = c.tc.tyuntypednil; }; if (r == nil) { // #64 Phase-N step 2 (THE FLIP): build a per-decl // TY_NAMED wrapper instead of collapsing the alias to @@ -12782,12 +12782,12 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // (cmd/wcc/check.c:1900-1929): pass1 creates the NAMED, // pass2 patches under/size off resolve_type(d->lhs), // where resolve_typename returns the inner NAMED. - let s: *sym = aliassym(c, n); + let s: *syntax.sym = aliassym(c, n); if (s != nil) { if (s.type_ != nil) { r = s.type_; } else { - let body: *node = nil; + let body: *syntax.node = nil; if (s.decl != nil) { body = unwrapbang(s.decl.lhs); }; @@ -12801,10 +12801,10 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // (check.c:1909/1917) ahead of pass2's // under patch, and A.2's TSTRUCT/TFN/ // TTAGGED tinfocachebind cycle-break. - let named: *tinfo = typenamed(s.name, nil); + let named: *syntax.tinfo = syntax.typenamed(s.name, nil); s.type_ = named; named.resolving = 1; - let under: *tinfo = tinfofornode(c, body); + let under: *syntax.tinfo = tinfofornode(c, body); // #62/#69: alias-root cycle (`type a = b; // type b = a` / `type a = a`) — checked // BEFORE clearing the flag so self-aliases @@ -12831,7 +12831,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { }; }; }; - case nkind.N_TBANG: + case syntax.nkind.N_TBANG: // #61 audit §1.8: `!T` propagates the inner shape; cstage's // resolve_type sets ty->iserror on the wrapper but no wwstage // cgen reader consumes it yet, so A.1 drops the flag and @@ -12839,13 +12839,13 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // unwrapbang pre-walk; graduate alongside the first cgen // site that needs iserror discrimination. r = tinfofornode(c, n.lhs); - case nkind.N_TPTR: - r = typeptr(tinfofornode(c, n.lhs)); - case nkind.N_TSLICE: - r = typeslice(tinfofornode(c, n.lhs)); - case nkind.N_TCHAN: - r = typechan(tinfofornode(c, n.lhs)); - case nkind.N_TARRAY: + case syntax.nkind.N_TPTR: + r = syntax.typeptr(tinfofornode(c, n.lhs)); + case syntax.nkind.N_TSLICE: + r = syntax.typeslice(tinfofornode(c, n.lhs)); + case syntax.nkind.N_TCHAN: + r = syntax.typechan(tinfofornode(c, n.lhs)); + case syntax.nkind.N_TARRAY: // Cstage cmd/wcc/check.c:314-326: length must be an integer // literal (`[_]T` keeps alen=0 as the inferred-length sentinel // patched at letslotsize-time). @@ -12868,7 +12868,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // fold SSoT for astsize's later size() read. let elen: u64 = 0u64; // #141: fold def-dim if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_INTLIT) { + if (n.rhs.kind == syntax.nkind.N_INTLIT) { elen = n.rhs.uval; } else { let v: u64 = 0u64; @@ -12881,36 +12881,36 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { }; }; }; - let sub: *tinfo = tinfofornode(c, n.lhs); + let sub: *syntax.tinfo = tinfofornode(c, n.lhs); // #62/#69: `type a = [2]a` value cycle — loud, cstage twin. if (circularnamed(c, sub, n)) { sub = c.tc.tyerr; }; - r = typearray(sub, elen); - case nkind.N_TFN: + r = syntax.typearray(sub, elen); + case syntax.nkind.N_TFN: // Cstage cmd/wcc/check.c:437-466: function types are 8B / 8B // (call-target pointer shape). Pre-bind before recursing into // the return type so a recursive `type F = fn() F` self-ref // doesn't spin (cycle-break mirror of the TSTRUCT/TTAGGED // pattern below). - r = newtype(tykind.TY_FN); + r = syntax.newtype(syntax.tykind.TY_FN); r.size = 8u64; r.align = 8u64; r.slotsize = 8u64; - tinfocachebind(c.tc, n, r); + syntax.tinfocachebind(c.tc, n, r); r.ret = tinfofornode(c, n.lhs); - case nkind.N_TENUM: + case syntax.nkind.N_TENUM: // Cstage cmd/wcc/check.c:529-542: storage type's size/align // (default i32 = 4B/4B). Cgen's slotsize-TENUM fallback pads // to 8B per its stack-slot contract; tinfo.size carries the // raw storage width so size(EnumT) folds to the correct value. - r = newtype(tykind.TY_ENUM); - let storage: *tinfo = nil; + r = syntax.newtype(syntax.tykind.TY_ENUM); + let storage: *syntax.tinfo = nil; if (n.lhs != nil) { storage = tinfofornode(c, n.lhs); }; if (storage == nil) { storage = c.tc.tyi32; }; r.sub = storage; r.size = storage.size; r.align = storage.align; r.slotsize = storage.size; - case nkind.N_TTUPLE: + case syntax.nkind.N_TTUPLE: // Slot layout is the tuple SSoT (tuple arc C-t0, user-ratified): // ti.size = ti.slotsize = per-element slot sum (tupleelemslot — // a str/slice its header, everything else one 8B eightbyte), @@ -12925,8 +12925,8 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // cgen strode 8B slots — the checker-says-8/cgen-does-16 split // behind the packed-tuple miscompile family (#32/#33/#48). // Pre-bind for cycle protection (recursive tuple shapes). - r = newtype(tykind.TY_TUPLE); - tinfocachebind(c.tc, n, r); + r = syntax.newtype(syntax.tykind.TY_TUPLE); + syntax.tinfocachebind(c.tc, n, r); // #57 A.6.3i-phase-1: populate r.tupleelems as a ttupleelem // linked list (head=positional 0) in lock-step with the // size/align accumulator. Harec analog ref/harec/src/type_ @@ -12940,28 +12940,28 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // A.6.3f-a) for the head/tail append pattern. Offsets are // slot-cumulative (C-t0), distinct from harec's // add_padding(&offset, memb.align) at type_store.c:561. - let teh: *ttupleelem = nil; - let tet: *ttupleelem = nil; + let teh: *syntax.ttupleelem = nil; + let tet: *syntax.ttupleelem = nil; let slottotal: u64 = 0u64; let maxal: u64 = 1u64; - let p: *node = n.list; + let p: *syntax.node = n.list; for (p != nil) { - let pt: *tinfo = tinfofornode(c, p.lhs); + let pt: *syntax.tinfo = tinfofornode(c, p.lhs); // #62/#69: tuple-member value cycle — loud, cstage twin. if (circularnamed(c, pt, p.lhs)) { pt = c.tc.tyerr; }; // #24: a composite element (array/struct/nested tuple // >8B) cannot ride the 8B cursor slot — the #60 layout // drops it on construction and segvs on t.N[i] read. // Reject until #60/DISP-A inlines it; cstage twin. - let cu: *tinfo = tichase(pt); - if (cu != nil && (cu.kind == tykind.TY_ARRAY - || cu.kind == tykind.TY_STRUCT - || cu.kind == tykind.TY_TUPLE)) { + let cu: *syntax.tinfo = tichase(pt); + if (cu != nil && (cu.kind == syntax.tykind.TY_ARRAY + || cu.kind == syntax.tykind.TY_STRUCT + || cu.kind == syntax.tykind.TY_TUPLE)) { cerr("error: tuple element must be a scalar, str, slice, or tagged-union (composite element deferred to task #60)\n"); c.errs += 1; pt = c.tc.tyerr; }; - let te: *ttupleelem = alloc(ttupleelem{type_=pt, offset=slottotal, tnext=nil})!; + let te: *syntax.ttupleelem = alloc(syntax.ttupleelem{type_=pt, offset=slottotal, tnext=nil})!; if (teh == nil) { teh = te; } else { tet.tnext = te; }; tet = te; if (pt != nil) { @@ -12974,7 +12974,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { r.size = slottotal; r.align = maxal; r.slotsize = slottotal; - case nkind.N_TSTRUCT: + case syntax.nkind.N_TSTRUCT: // Cstage cmd/wcc/check.c:468-527: per-field alignment, max // align for the whole record, total rounded up to alignment. // Anonymous-embed promotion is deferred (#13). @@ -12994,8 +12994,8 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // struct; size-derived alignment; final round to 8). That // slot total lands in ti.slotsize so the cgen fast-path can // graduate TY_STRUCT off the AST walker. - r = newtype(tykind.TY_STRUCT); - tinfocachebind(c.tc, n, r); + r = syntax.newtype(syntax.tykind.TY_STRUCT); + syntax.tinfocachebind(c.tc, n, r); // #57 A.6.3i-phase-1: populate r.fields as a tfield linked // list (head=first declared field) in lock-step with the // natural-layout offset accumulator. Mirrors cstage cmd/wcc/ @@ -13006,15 +13006,15 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // ref/harec/src/type_store.c:314-347 struct_init_from_atype. // Anonymous-embed promotion not populated here (#13 per // the cstage cite at check.ww:1263). - let fh: *tfield = nil; - let ft_: *tfield = nil; + let fh: *syntax.tfield = nil; + let ft_: *syntax.tfield = nil; let off: u64 = 0u64; let maxalign: u64 = 1u64; let soff: u64 = 0u64; - let f: *node = n.list; + let f: *syntax.node = n.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { - let ft: *tinfo = tinfofornode(c, f.lhs); + if (f.kind == syntax.nkind.N_TFIELD) { + let ft: *syntax.tinfo = tinfofornode(c, f.lhs); // #62/#69: struct-field value cycle (`type s1 = // struct { x: s2 }; type s2 = struct { x: s1 }`) // — loud; pre-#62 this stack-overflowed the slot @@ -13026,7 +13026,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { off = (off + ft.align - 1u64) & ~(ft.align - 1u64); }; let fldoff: u64 = off; - let tf: *tfield = alloc(tfield{name=f.str, type_=ft, offset=fldoff, tnext=nil})!; + let tf: *syntax.tfield = alloc(syntax.tfield{name=f.str, type_=ft, offset=fldoff, tnext=nil})!; if (fh == nil) { fh = tf; } else { ft_.tnext = tf; }; ft_ = tf; off += ft.size; @@ -13054,7 +13054,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { soff = (soff + 7u64) & ~7u64; }; r.slotsize = soff; - case nkind.N_TTAGGED: + case syntax.nkind.N_TTAGGED: // THE tagged-union normalization SSoT (astsize/astalign delegate // here). Mirrors cstage resolve_type N_TTAGGED (cmd/wcc/check.c: // 801-882): 8B tag + max(variant) rounded up to 8, AFTER type-set @@ -13067,32 +13067,32 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // and (i32|i32|str) numbered str's tag 2 not 1 (cgen reads the // deduped ti.params). Pre-bind for cycle protection (recursive // sum-type shapes through NAMED variants). - r = newtype(tykind.TY_TAGGED); - tinfocachebind(c.tc, n, r); + r = syntax.newtype(syntax.tykind.TY_TAGGED); + syntax.tinfocachebind(c.tc, n, r); // #50 / A.6.3f phase 1: populate ti.params as a tparam linked // list (head=first surviving variant). #61a: flatten `...inner` // tagged spreads into the chain and stamp each variant's iserror. // Same shared Tparam shape ww reuses across struct-fields / // tuple-fields / fn-params / tagged-variants (sea-of-stars per // rule 12). - let head: *tparam = nil; - let tail: *tparam = nil; + let head: *syntax.tparam = nil; + let tail: *syntax.tparam = nil; let maxsz: u64 = 0u64; let al: u64 = 8u64; let nv: i32 = 0; - let v: *node = n.list; + let v: *syntax.node = n.list; for (v != nil) { - let vt: *tinfo = tinfofornode(c, v); + let vt: *syntax.tinfo = tinfofornode(c, v); // #62/#69: union-member value cycle — loud, cstage twin. if (circularnamed(c, vt, v)) { vt = c.tc.tyerr; }; - let isspread: bool = (v.op == tkind.TK_ELLIPSIS); - let vu: *tinfo = vt; + let isspread: bool = (v.op == syntax.tkind.TK_ELLIPSIS); + let vu: *syntax.tinfo = vt; // Full chase (F2a batch-4 c3-B1): the single peel left a // 2-level-alias inner union a SURFACE member — the box // sized off the inner union's own header, not its // spliced variants (cs twin check.c:755 chases). if (isspread) { vu = tichase(vu); }; - if (isspread && vu != nil && vu.kind == tykind.TY_TAGGED) { + if (isspread && vu != nil && vu.kind == syntax.tykind.TY_TAGGED) { // #209: a `...inner` spread's PAYLOAD is its // members, not the whole inner union — size/align // off each surviving spliced member (cstage check.c: @@ -13101,10 +13101,10 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // and desync the `field` slot from cstage's). Spliced // variants carry the inner union's already-stamped // iserror; no re-derivation. - let src: *tparam = vu.params; + let src: *syntax.tparam = vu.params; for (src != nil) { - let st: *tinfo = src.type_; - if (st != nil && st.kind == tykind.TY_NEVER) { + let st: *syntax.tinfo = src.type_; + if (st != nil && st.kind == syntax.tykind.TY_NEVER) { src = src.tnext; continue; }; if (variantpresent(head, st)) { @@ -13114,14 +13114,14 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { if (st.size > maxsz) { maxsz = st.size; }; if (st.align > al) { al = st.align; }; }; - let tp: *tparam = alloc(tparam{name="", type_=src.type_, iserror=src.iserror, tnext=nil})!; + let tp: *syntax.tparam = alloc(syntax.tparam{name="", type_=src.type_, iserror=src.iserror, tnext=nil})!; if (head == nil) { head = tp; } else { tail.tnext = tp; }; tail = tp; nv += 1; src = src.tnext; }; } else { - if (vt != nil && vt.kind == tykind.TY_NEVER) { + if (vt != nil && vt.kind == syntax.tykind.TY_NEVER) { v = v.next; continue; }; if (variantpresent(head, vt)) { @@ -13132,7 +13132,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { if (vt.align > al) { al = vt.align; }; }; let ve: bool = varianterr(c, v); - let tp: *tparam = alloc(tparam{name="", type_=vt, iserror=ve, tnext=nil})!; + let tp: *syntax.tparam = alloc(syntax.tparam{name="", type_=vt, iserror=ve, tnext=nil})!; if (head == nil) { head = tp; } else { tail.tnext = tp; }; tail = tp; nv += 1; @@ -13156,12 +13156,12 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // the tinfo layer; pre-#1 it AST-keyed n.list instead. let isnull: bool = false; if (nv == 2) { - let pa: *tparam = head; - let pb: *tparam = head.tnext; - let aptr: bool = (pa.type_ != nil && pa.type_.kind == tykind.TY_PTR); - let bptr: bool = (pb.type_ != nil && pb.type_.kind == tykind.TY_PTR); - let avoid: bool = (pa.type_ != nil && pa.type_.kind == tykind.TY_VOID && !pa.iserror); - let bvoid: bool = (pb.type_ != nil && pb.type_.kind == tykind.TY_VOID && !pb.iserror); + let pa: *syntax.tparam = head; + let pb: *syntax.tparam = head.tnext; + let aptr: bool = (pa.type_ != nil && pa.type_.kind == syntax.tykind.TY_PTR); + let bptr: bool = (pb.type_ != nil && pb.type_.kind == syntax.tykind.TY_PTR); + let avoid: bool = (pa.type_ != nil && pa.type_.kind == syntax.tykind.TY_VOID && !pa.iserror); + let bvoid: bool = (pb.type_ != nil && pb.type_.kind == syntax.tykind.TY_VOID && !pb.iserror); if (aptr) { if (bvoid) { isnull = true; }; }; if (avoid) { if (bptr) { isnull = true; }; }; }; @@ -13184,7 +13184,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // chan paths which already populate slotsize, plus TBANG which // inherits the inner's tinfo unchanged). if (r.slotsize == 0u64) { r.slotsize = r.size; }; - tinfocachebind(c.tc, n, r); + syntax.tinfocachebind(c.tc, n, r); }; return r; }; @@ -13201,7 +13201,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // with sym.decl == nil; #19 retires these as dedicated AST kinds). // Propagation, not silent gap — asserttyped gates those idents at the // consumer layer, so a nil operand never reaches the loud reject below. -fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { +fn unifyarith(c: *checker, e: *syntax.node, ltn: *syntax.node, rtn: *syntax.node) *syntax.node = { let lu: bool = isuntypedint(ltn) || isuntypedfloat(ltn); let ru: bool = isuntypedint(rtn) || isuntypedfloat(rtn); if (lu && ru) { @@ -13225,8 +13225,8 @@ fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { // above. Mirror cstage here off the operand node so the rune-literal / // integer mix stays valid (35 selfhost+lib sites) under the #26 reject. if (e != nil) { - let lr: bool = e.lhs != nil && e.lhs.kind == nkind.N_RUNELIT; - let rr: bool = e.rhs != nil && e.rhs.kind == nkind.N_RUNELIT; + let lr: bool = e.lhs != nil && e.lhs.kind == syntax.nkind.N_RUNELIT; + let rr: bool = e.rhs != nil && e.rhs.kind == syntax.nkind.N_RUNELIT; if (lr && isinttypeast(rtn)) { return rtn; }; if (rr && isinttypeast(ltn)) { return ltn; }; }; @@ -13241,13 +13241,13 @@ fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { // SK_TYPE too but decl == nil (check.ww:95-112), so aliassym alone // would mis-flag i32 as "named". This decl != nil gate is the wwstage // analog of cstage's `kind == TY_NAMED` (primitives are TY_I32 etc). - let ls: *sym = aliassym(c, unwrapbang(ltn)); - let rs: *sym = aliassym(c, unwrapbang(rtn)); + let ls: *syntax.sym = aliassym(c, unwrapbang(ltn)); + let rs: *syntax.sym = aliassym(c, unwrapbang(rtn)); let la: bool = ls != nil && ls.decl != nil; let ra: bool = rs != nil && rs.decl != nil; if (!(la && ra)) { - let da: *node = resolvealias(c, ltn); - let db: *node = resolvealias(c, rtn); + let da: *syntax.node = resolvealias(c, ltn); + let db: *syntax.node = resolvealias(c, rtn); if (da != nil && db != nil && varianterr(c, ltn) == varianterr(c, rtn) && typeeqast(c, da, db)) { @@ -13278,16 +13278,16 @@ fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { // f32 off the operands' float-kind, not the node stamp, so a stamped literal // inside an arith-binop / behind a unary minus does NOT narrow there — // binop / unary-minus / assign / call-arg / struct-field wait on #120. -fn coercefloatlit(c: *checker, e: *node, target: *node) void = { +fn coercefloatlit(c: *checker, e: *syntax.node, target: *syntax.node) void = { if (e == nil) { return; }; if (target == nil) { return; }; - let tu: *node = resolvealias(c, unwrapbang(target)); + let tu: *syntax.node = resolvealias(c, unwrapbang(target)); if (tu == nil) { return; }; - if (tu.kind != nkind.N_TNAME) { return; }; - if (!streq(tu.str, "f32")) { return; }; - if (e.kind == nkind.N_FLOATLIT) { - if ((e.type_: *tinfo) == c.tc.tyuntypedfloat) { - let f32t: *node = mktname(c, "f32"); + if (tu.kind != syntax.nkind.N_TNAME) { return; }; + if (!syntax.streq(tu.str, "f32")) { return; }; + if (e.kind == syntax.nkind.N_FLOATLIT) { + if ((e.type_: *syntax.tinfo) == c.tc.tyuntypedfloat) { + let f32t: *syntax.node = mktname(c, "f32"); e.type_ = tinfofornode(c, f32t): *void; }; }; @@ -13315,17 +13315,17 @@ fn coercefloatlit(c: *checker, e: *node, target: *node) void = { // keep harec's per-element range gate via checkarrlitfits's foldint / // defcastfits path (:4634). For a tagged-union target (fnmatch pat_next's // (u8 | star | ...)) return the first integer variant. -fn coercerunelit(c: *checker, e: *node, target: *node) *node = { +fn coercerunelit(c: *checker, e: *syntax.node, target: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - if (e.kind != nkind.N_RUNELIT) { return nil; }; + if (e.kind != syntax.nkind.N_RUNELIT) { return nil; }; if (target == nil) { return nil; }; - let tu: *node = resolvealias(c, unwrapbang(target)); + let tu: *syntax.node = resolvealias(c, unwrapbang(target)); if (tu == nil) { return nil; }; if (isinttypeast(tu)) { return tu; }; - if (tu.kind == nkind.N_TTAGGED) { - let v: *node = tu.list; + if (tu.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = tu.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { if (isinttypeast(vu)) { return vu; }; }; @@ -13340,29 +13340,29 @@ fn coercerunelit(c: *checker, e: *node, target: *node) *node = { // returned by exprtype; ptr arithmetic / bitwise / shifts / comparisons / // logicals all reflect cstage's rules. Type-mismatch diagnostics are // elided here (cstage gates the same shape). -fn binoptype(c: *checker, e: *node) *node = { - let op: tkind = e.op; - let ltn: *node = exprtype(c, e.lhs, nil); - let rtn: *node = exprtype(c, e.rhs, nil); +fn binoptype(c: *checker, e: *syntax.node) *syntax.node = { + let op: syntax.tkind = e.op; + let ltn: *syntax.node = exprtype(c, e.lhs, nil); + let rtn: *syntax.node = exprtype(c, e.rhs, nil); // #38/F2: ptr ± int / int + ptr use intkindast (the type_isint mirror, // incl untyped_int / untyped_rune / alias-chased) — NOT isinttypeast, // which misses untyped_int. cstage's ptr-arith arm gates on type_isint // (check.c:1179/1181), so `p + 1` (untyped_int) returns the ptr there // and never reaches the isnum gate; aligning these arms keeps the new // arithmetic gate below from rejecting valid pointer arithmetic. - if (op == tkind.TK_PLUS || op == tkind.TK_MINUS) { - if (ltn != nil && ltn.kind == nkind.N_TPTR && intkindast(c, rtn)) { + if (op == syntax.tkind.TK_PLUS || op == syntax.tkind.TK_MINUS) { + if (ltn != nil && ltn.kind == syntax.nkind.N_TPTR && intkindast(c, rtn)) { return ltn; }; }; - if (op == tkind.TK_PLUS) { - if (intkindast(c, ltn) && rtn != nil && rtn.kind == nkind.N_TPTR) { + if (op == syntax.tkind.TK_PLUS) { + if (intkindast(c, ltn) && rtn != nil && rtn.kind == syntax.nkind.N_TPTR) { return rtn; }; }; - if (op == tkind.TK_MINUS) { + if (op == syntax.tkind.TK_MINUS) { if (ltn != nil && rtn != nil - && ltn.kind == nkind.N_TPTR && rtn.kind == nkind.N_TPTR) { + && ltn.kind == syntax.nkind.N_TPTR && rtn.kind == syntax.nkind.N_TPTR) { return mktname(c, "i64"); }; }; @@ -13372,27 +13372,27 @@ fn binoptype(c: *checker, e: *node) *node = { // `let c: str = a + b;` (str+str) compiled to an integer ADD of the two // header pointers, silent garbage. The ptr-arithmetic special cases // above already returned, so a survivor here is plain value arithmetic. - if (op == tkind.TK_PLUS || op == tkind.TK_MINUS || - op == tkind.TK_STAR || op == tkind.TK_SLASH || - op == tkind.TK_PERCENT) { + if (op == syntax.tkind.TK_PLUS || op == syntax.tkind.TK_MINUS || + op == syntax.tkind.TK_STAR || op == syntax.tkind.TK_SLASH || + op == syntax.tkind.TK_PERCENT) { if ((ltn != nil && !numkindast(c, ltn)) || (rtn != nil && !numkindast(c, rtn))) { deffolderr(c, e, "arithmetic on non-numeric type"); }; return unifyarith(c, e, ltn, rtn); }; - if (op == tkind.TK_AMP || op == tkind.TK_PIPE || - op == tkind.TK_CARET || op == tkind.TK_LSHIFT || - op == tkind.TK_RSHIFT) { + if (op == syntax.tkind.TK_AMP || op == syntax.tkind.TK_PIPE || + op == syntax.tkind.TK_CARET || op == syntax.tkind.TK_LSHIFT || + op == syntax.tkind.TK_RSHIFT) { if ((ltn != nil && !intkindast(c, ltn)) || (rtn != nil && !intkindast(c, rtn))) { deffolderr(c, e, "bitwise on non-integer type"); }; return unifyarith(c, e, ltn, rtn); }; - if (op == tkind.TK_EQ || op == tkind.TK_NEQ || - op == tkind.TK_LT || op == tkind.TK_LE || - op == tkind.TK_GT || op == tkind.TK_GE) { + if (op == syntax.tkind.TK_EQ || op == syntax.tkind.TK_NEQ || + op == syntax.tkind.TK_LT || op == syntax.tkind.TK_LE || + op == syntax.tkind.TK_GT || op == syntax.tkind.TK_GE) { // cstage routes every comparison through unify_arith (check.c:1195/ // 1200 cbinop), which loud-rejects a differing-types pair, e.g. // strconv.invalid != i32. wwstage routes the ORDERED arm through @@ -13411,8 +13411,8 @@ fn binoptype(c: *checker, e: *node) *node = { // cstage's cbinop equality arm (check.c:1194-1196) gates nothing, // so str==str / ptr==ptr remain valid; aligning those down would // over-reject what cstage accepts. - if (op == tkind.TK_LT || op == tkind.TK_LE || - op == tkind.TK_GT || op == tkind.TK_GE) { + if (op == syntax.tkind.TK_LT || op == syntax.tkind.TK_LE || + op == syntax.tkind.TK_GT || op == syntax.tkind.TK_GE) { if ((ltn != nil && !numkindast(c, ltn)) || (rtn != nil && !numkindast(c, rtn))) { deffolderr(c, e, "ordered comparison on non-numeric"); @@ -13431,7 +13431,7 @@ fn binoptype(c: *checker, e: *node) *node = { }; return mktname(c, "bool"); }; - if (op == tkind.TK_AND || op == tkind.TK_OR) { + if (op == syntax.tkind.TK_AND || op == syntax.tkind.TK_OR) { // #38/F2 (review item 5): logical operands must be bool (cstage // check.c:1208-1211 gates each side via type_chase_named). cstage // formats per-side with tokname; ww's piecewise cerr can't splice @@ -13455,16 +13455,16 @@ fn binoptype(c: *checker, e: *node) *node = { // type_promote. The slice/str .len/.cap pseudo-field address-of widening // to *i64 mirrors check.c:672-682 directly — its purpose is documented // at the cstage site. -fn unoptype(c: *checker, e: *node) *node = { - let op: tkind = e.op; - let opt: *node = exprtype(c, e.lhs, nil); +fn unoptype(c: *checker, e: *syntax.node) *syntax.node = { + let op: syntax.tkind = e.op; + let opt: *syntax.node = exprtype(c, e.lhs, nil); // #38/F2 (review item 5): unop operand-kind gates the wwstage checker // elided. Mirror cstage cunop (cmd/wcc/check.c:1224-1238): unary +/- // want a numeric operand, ~ wants an integer, ! wants a bool. A nil // opt is an already-errored / inherent-IDENT bail — not re-rejected. - if (op == tkind.TK_MINUS || op == tkind.TK_PLUS) { + if (op == syntax.tkind.TK_MINUS || op == syntax.tkind.TK_PLUS) { if (opt != nil && !numkindast(c, opt)) { - if (op == tkind.TK_MINUS) { + if (op == syntax.tkind.TK_MINUS) { deffolderr(c, e, "- on non-numeric"); } else { deffolderr(c, e, "+ on non-numeric"); @@ -13472,19 +13472,19 @@ fn unoptype(c: *checker, e: *node) *node = { }; return opt; }; - if (op == tkind.TK_NOT) { + if (op == syntax.tkind.TK_NOT) { if (opt != nil && !boolkindast(c, opt)) { deffolderr(c, e, "! on non-bool"); }; return mktname(c, "bool"); }; - if (op == tkind.TK_TILDE) { + if (op == syntax.tkind.TK_TILDE) { if (opt != nil && !intkindast(c, opt)) { deffolderr(c, e, "~ on non-integer"); }; return opt; }; - if (op == tkind.TK_STAR) { + if (op == syntax.tkind.TK_STAR) { // opt nil here means the operand was an inherent-IDENT bail // (exprtype N_IDENT arm L1596-1599 — SK_USE / pseudo-builtin // sym.decl == nil — or another helper's nil propagation); @@ -13494,17 +13494,17 @@ fn unoptype(c: *checker, e: *node) *node = { // resolvealias passes through non-nil unchanged (L513 // `for (cur != nil)` only exits via `return cur` or `return n`). if (opt == nil) { return nil; }; - let u: *node = resolvealias(c, unwrapbang(opt)); + let u: *syntax.node = resolvealias(c, unwrapbang(opt)); // Invalid input (non-pointer dereference); cstage errors at // cmd/wcc/check.c:660. 5-lite-b #34. - if (u.kind != nkind.N_TPTR) { return nil; }; + if (u.kind != syntax.nkind.N_TPTR) { return nil; }; return u.lhs; }; - if (op == tkind.TK_AMP) { - if (e.lhs != nil && e.lhs.kind == nkind.N_DOT) { + if (op == syntax.tkind.TK_AMP) { + if (e.lhs != nil && e.lhs.kind == syntax.nkind.N_DOT) { let fld: str = e.lhs.str; - if (streq(fld, "len") || streq(fld, "cap")) { - let base: *node = e.lhs.lhs; + if (syntax.streq(fld, "len") || syntax.streq(fld, "cap")) { + let base: *syntax.node = e.lhs.lhs; if (base != nil && base.type_ != nil) { // Full chase per hop (F2a batch-4 c3-B2): // the one-peel-per-hop walk lost 2-level @@ -13514,12 +13514,12 @@ fn unoptype(c: *checker, e: *node) *node = { // stays loud for ALL alias bases (task // #96) — this aligns the stamped type // only; rows graduate with #96. - let bu: *tinfo = tichase(base.type_: *tinfo); - if (bu != nil && bu.kind == tykind.TY_PTR) { bu = bu.sub; }; + let bu: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu != nil && bu.kind == syntax.tykind.TY_PTR) { bu = bu.sub; }; bu = tichase(bu); if (bu != nil) { - if (bu.kind == tykind.TY_SLICE || bu.kind == tykind.TY_STR) { - let pp: *node = newnode(nkind.N_TPTR, "", 0, 0); + if (bu.kind == syntax.tykind.TY_SLICE || bu.kind == syntax.tykind.TY_STR) { + let pp: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pp.lhs = mktname(c, "i64"); return pp; }; @@ -13538,21 +13538,21 @@ fn unoptype(c: *checker, e: *node) *node = { // cstage, where a fn ident already types as TY_FN // (cmd/wcc/check.c:668), so `&fn` is `*fn` natively. if (e.lhs != nil) { - if (e.lhs.kind == nkind.N_IDENT) { + if (e.lhs.kind == syntax.nkind.N_IDENT) { // #4: curmod preference. A bare `&handler` whose leaf // also names a fn in a LATER module otherwise binds // the foreign signature (scopedefineinmodule prepends); // cstage types a fn ident via scope_lookup_prefer with // cur_mod (cmd/wcc/check.c:1305). - let fs: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); + let fs: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.lhs.str); if (fs != nil) { - if (fs.skind == skind.SK_FN) { + if (fs.skind == syntax.skind.SK_FN) { if (fs.decl != nil) { - if (fs.decl.kind == nkind.N_FNDECL) { - let synth: *node = newnode(nkind.N_TFN, "", 0, 0); + if (fs.decl.kind == syntax.nkind.N_FNDECL) { + let synth: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); synth.lhs = fs.decl.lhs; synth.list = fs.decl.list; - let pf: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pf: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pf.lhs = synth; return pf; }; @@ -13568,17 +13568,17 @@ fn unoptype(c: *checker, e: *node) *node = { // typeeq → confident reject; cstage types `&mod.fn` as `*fn` // natively (a dotted fn ref is TY_FN), so this aligns ww UP to // cstage's actual acceptance reason. - if (e.lhs.kind == nkind.N_DOT) { - if (e.lhs.lhs != nil && e.lhs.lhs.kind == nkind.N_IDENT) { - let fs: *sym = scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.lhs.str), e.lhs.str); + if (e.lhs.kind == syntax.nkind.N_DOT) { + if (e.lhs.lhs != nil && e.lhs.lhs.kind == syntax.nkind.N_IDENT) { + let fs: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.lhs.str), e.lhs.str); if (fs != nil) { - if (fs.skind == skind.SK_FN) { + if (fs.skind == syntax.skind.SK_FN) { if (fs.decl != nil) { - if (fs.decl.kind == nkind.N_FNDECL) { - let synth: *node = newnode(nkind.N_TFN, "", 0, 0); + if (fs.decl.kind == syntax.nkind.N_FNDECL) { + let synth: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); synth.lhs = fs.decl.lhs; synth.list = fs.decl.list; - let pf: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pf: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pf.lhs = synth; return pf; }; @@ -13592,7 +13592,7 @@ fn unoptype(c: *checker, e: *node) *node = { // #34). Generic &expr widens to *opt; without opt we can't // synthesize the pointer node. if (opt == nil) { return nil; }; - let pp: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pp: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pp.lhs = opt; return pp; }; @@ -13608,32 +13608,32 @@ fn unoptype(c: *checker, e: *node) *node = { // to T (pointer-to-array); `*[]T` does NOT decay (yields []T via the // generic *U → U fallback — Hare-faithful, a pointer-to-slice is a 1D // array of slices, not of T); generic *T → T. -fn indexresult(c: *checker, e: *node) *node = { - let basetn: *node = exprtype(c, e.lhs, nil); - let _idx: *node = exprtype(c, e.rhs, nil); - let u: *node = resolvealias(c, unwrapbang(basetn)); +fn indexresult(c: *checker, e: *syntax.node) *syntax.node = { + let basetn: *syntax.node = exprtype(c, e.lhs, nil); + let _idx: *syntax.node = exprtype(c, e.rhs, nil); + let u: *syntax.node = resolvealias(c, unwrapbang(basetn)); // basetn nil → propagation from inherent-IDENT bail at exprtype // N_IDENT arm L1596-1599 (5-lite-b #34, A.6.2.1c #24). // unwrapbang(nil)=nil and resolvealias(nil)=nil pass through. if (u == nil) { return nil; }; - if (u.kind == nkind.N_TSLICE) { return u.lhs; }; - if (u.kind == nkind.N_TARRAY) { return u.lhs; }; - if (u.kind == nkind.N_TNAME) { + if (u.kind == syntax.nkind.N_TSLICE) { return u.lhs; }; + if (u.kind == syntax.nkind.N_TARRAY) { return u.lhs; }; + if (u.kind == syntax.nkind.N_TNAME) { // rule-9 divergence-doc (drew .ai/drew-14-ruling.md): `str[i] -> // u8` is a deliberate Go-like direct byte-index, a SANCTIONED ww // divergence from Hare's `strings::toutf8(s)[i]` (the Hare // reference checker rejects str-index, harec check.c:362). // lib/strings is load-bearing on it (compare/dup/join). - if (streq(u.str, "str")) { + if (syntax.streq(u.str, "str")) { // #14: reject INDEX of a bare def-global scalar str — an // inline compile-time constant with no storage to index // (cgen refs an unbacked symbol -> link-fail ww / segfault // cs). let/param/local + string-literal operands stay // valid; only the SK_DEF scalar-str operand is // unindexable. cstage twin: check.c N_INDEX TY_STR arm. - if (e.lhs != nil && e.lhs.kind == nkind.N_IDENT) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); - if (s != nil && s.skind == skind.SK_DEF) { + if (e.lhs != nil && e.lhs.kind == syntax.nkind.N_IDENT) { + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.lhs.str); + if (s != nil && s.skind == syntax.skind.SK_DEF) { cerr("error: cannot index a def-constant str '"); cerr(e.lhs.str); cerr("'; bind it to a `let` (def strings are inline constants, not storage-backed)\n"); @@ -13644,10 +13644,10 @@ fn indexresult(c: *checker, e: *node) *node = { return mktname(c, "u8"); }; }; - if (u.kind == nkind.N_TPTR) { - let inner: *node = u.lhs; - let iu: *node = resolvealias(c, unwrapbang(inner)); - if (iu != nil && iu.kind == nkind.N_TARRAY) { + if (u.kind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = u.lhs; + let iu: *syntax.node = resolvealias(c, unwrapbang(inner)); + if (iu != nil && iu.kind == syntax.nkind.N_TARRAY) { return iu.lhs; }; return inner; @@ -13684,79 +13684,79 @@ fn indexresult(c: *checker, e: *node) *node = { // inherent-IDENT bails (SK_USE, pseudo-builtin sym.decl==nil, // N_DOT-LHS syntactic position, EXPR_ASSERT-family abort/assert) until // #19 retires the bail shape. -fn exprtype(c: *checker, e: *node, hint: *node) *node = { +fn exprtype(c: *checker, e: *syntax.node, hint: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - let k: nkind = e.kind; + let k: syntax.nkind = e.kind; // #61 audit §1.8 — A.2 widens A.1's single N_INTLIT population to // every primitive literal arm + N_IDENT. Cgen size walkers // (slotsize first; elemsize/fieldsize/letemitsize follow) consult // node.type_ as the SSoT; populating literals + idents closes the // loop from the read side. - if (k == nkind.N_INTLIT) { + if (k == syntax.nkind.N_INTLIT) { // Typed-int literal (`7u32`, `0i8`): tsuffix names a builtin // primitive. Mirrors cstage cmd/wcc/check.c:694-701 cexpr's // `lookup_builtin(n->tsuffix)`; falls through to untyped_int // when the suffix doesn't resolve. if (e.tsuffix.len > 0) { - let suf: *node = mktname(c, e.tsuffix); - let ti: *tinfo = tinfofornode(c, suf); + let suf: *syntax.node = mktname(c, e.tsuffix); + let ti: *syntax.tinfo = tinfofornode(c, suf); if (ti != nil) { e.type_ = ti: *void; return suf; }; }; - let tn: *node = mktname(c, "untyped_int"); + let tn: *syntax.node = mktname(c, "untyped_int"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_FLOATLIT) { + if (k == syntax.nkind.N_FLOATLIT) { // Typed-float literal (`1.5f32`, `0.0f64`): tsuffix names a // builtin primitive. Mirrors cstage cmd/wcc/check.c:702-709 // cexpr's `lookup_builtin(n->tsuffix)`; falls through to // untyped_float when the suffix doesn't resolve. if (e.tsuffix.len > 0) { - let suf: *node = mktname(c, e.tsuffix); - let ti: *tinfo = tinfofornode(c, suf); + let suf: *syntax.node = mktname(c, e.tsuffix); + let ti: *syntax.tinfo = tinfofornode(c, suf); if (ti != nil) { e.type_ = ti: *void; return suf; }; }; - let tn: *node = mktname(c, "untyped_float"); + let tn: *syntax.node = mktname(c, "untyped_float"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_STRLIT) { - let tn: *node = mktname(c, "str"); + if (k == syntax.nkind.N_STRLIT) { + let tn: *syntax.node = mktname(c, "str"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_RUNELIT) { - let tn: *node = mktname(c, "rune"); + if (k == syntax.nkind.N_RUNELIT) { + let tn: *syntax.node = mktname(c, "rune"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_TRUE) { - let tn: *node = mktname(c, "bool"); + if (k == syntax.nkind.N_TRUE) { + let tn: *syntax.node = mktname(c, "bool"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_FALSE) { - let tn: *node = mktname(c, "bool"); + if (k == syntax.nkind.N_FALSE) { + let tn: *syntax.node = mktname(c, "bool"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_VOIDLIT) { - let tn: *node = mktname(c, "void"); + if (k == syntax.nkind.N_VOIDLIT) { + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_NIL) { - let tn: *node = mktname(c, "untyped_nil"); + if (k == syntax.nkind.N_NIL) { + let tn: *syntax.node = mktname(c, "untyped_nil"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { // #55: bare-leaf value-ident must prefer curmod. Flat-scope // scopelookup bucket-walks and can bind a same-leaf symbol from // the wrong module under a foreign curmod, dragging its decl's @@ -13764,7 +13764,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // bare `error` then binds strconv.error not io.error). Mirrors // cstage cmd/wcc/check.c:66 scope_lookup_prefer; sibling #56 at // L2439, #53 at L688. Tracked in the cluster note at L685-687. - let s: *sym = scopelookupprefer(c.cur, c.curmod, e.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; // #34: a bare fn-name rvalue types as its FN TYPE, not its return @@ -13779,21 +13779,21 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // root of the #24 fn-family over-rejects (`let p: fn()i32 = g` compared // i32 vs the fn type). cgen lowers a fn rvalue name-keyed via // fnretlookup (cgenexpr.ww:1100), never off this stamp → byte-id-neutral. - if (s.skind == skind.SK_FN) { - let ft: *node = newnode(nkind.N_TFN, "", 0, 0); + if (s.skind == syntax.skind.SK_FN) { + let ft: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); ft.lhs = s.decl.lhs; ft.list = s.decl.list; e.type_ = tinfofornode(c, ft): *void; return ft; }; - let t: *node = s.decl.lhs; + let t: *syntax.node = s.decl.lhs; // Propagate the declared type's tinfo onto the use site so // downstream cgen walkers can read n.type_ off an ident. if (t != nil) { if (t.type_ != nil) { e.type_ = t.type_; } else { - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { e.type_ = ti: *void; t.type_ = ti: *void; @@ -13802,29 +13802,29 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; return t; }; - if (k == nkind.N_BIN) { - let tn: *node = binoptype(c, e); + if (k == syntax.nkind.N_BIN) { + let tn: *syntax.node = binoptype(c, e); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_UN) { - let tn: *node = unoptype(c, e); + if (k == syntax.nkind.N_UN) { + let tn: *syntax.node = unoptype(c, e); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_INDEX) { - let tn: *node = indexresult(c, e); + if (k == syntax.nkind.N_INDEX) { + let tn: *syntax.node = indexresult(c, e); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { // `expr: T` — explicit cast; the type expr is e.rhs. Mirrors // cstage cmd/wcc/check.c:737 `n->type = resolve_type(c, n->rhs)`. e.type_ = tinfofornode(c, e.rhs): *void; return e.rhs; }; - if (k == nkind.N_CALL) { - let callee: *node = e.lhs; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = e.lhs; if (callee == nil) { return nil; }; // #31: synthesize the `alloc(value)` / `alloc([], n)` builtin // return shape so checkletassign sees the same `(*T | nomem)` / @@ -13833,18 +13833,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // silently accepts `let p: *T = alloc(v);` — rule 10 trap. // Same-module gate mirrors cstage's `c->cur_mod && // scope_lookup_in_module(...)` check from task #23. - if (callee.kind == nkind.N_IDENT) { - if (streq(callee.str, "alloc")) { + if (callee.kind == syntax.nkind.N_IDENT) { + if (syntax.streq(callee.str, "alloc")) { let shadowed: bool = false; if (c.curmod.len > 0) { - if (scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { + if (syntax.scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { shadowed = true; }; }; if (!shadowed) { if (e.list != nil) { // Slice form: `alloc([], n)`. - if (e.list.kind == nkind.N_ARRLIT) { + if (e.list.kind == syntax.nkind.N_ARRLIT) { if (e.list.list == nil) { if (e.list.next != nil) { if (e.list.next.next == nil) { @@ -13865,11 +13865,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { deffolderr(c, e, "cannot infer slice element type for alloc([], n) without a type hint; annotate the binding, e.g. let x: []T = alloc([], n)"); return nil; }; - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = mktname(c, "u8"); - let nome: *node = mktname(c, "nomem"); + let nome: *syntax.node = mktname(c, "nomem"); sl.next = nome; - let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTAGGED, "", 0, 0); tt.list = sl; e.type_ = tinfofornode(c, tt): *void; return tt; @@ -13879,12 +13879,12 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; // Value form: `alloc(value)`. if (e.list.next == nil) { - let argt: *node = exprtype(c, e.list, nil); - let ptr: *node = newnode(nkind.N_TPTR, "", 0, 0); + let argt: *syntax.node = exprtype(c, e.list, nil); + let ptr: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); ptr.lhs = argt; - let nome: *node = mktname(c, "nomem"); + let nome: *syntax.node = mktname(c, "nomem"); ptr.next = nome; - let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTAGGED, "", 0, 0); tt.list = ptr; e.type_ = tinfofornode(c, tt): *void; return tt; @@ -13899,11 +13899,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // mirrors the alloc precedent (#23) so a user `fn size(...)` // inside this module suppresses the builtin. Mirrors cstage // cmd/wcc/check.c:907-960. - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { let bname: str = callee.str; - let issize: bool = streq(bname, "size"); - let isalign: bool = streq(bname, "align"); - let isoffset: bool = streq(bname, "offset"); + let issize: bool = syntax.streq(bname, "size"); + let isalign: bool = syntax.streq(bname, "align"); + let isoffset: bool = syntax.streq(bname, "offset"); if (issize || isalign || isoffset) { // #38/F2 (review item 7): UNCONDITIONAL intercept — cstage // gates size/align/offset on NOTHING (cmd/wcc/check.c:1538- @@ -13920,7 +13920,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // otherwise folded the unresolved N_TNAME to 0 silently // (rc=0 wrong binary). offset's arg is a value N_DOT and // keeps its own "no field" diagnostic below. - if ((issize || isalign) && e.list.kind == nkind.N_TNAME + if ((issize || isalign) && e.list.kind == syntax.nkind.N_TNAME && tinfofornode(c, e.list) == nil) { cerr(e.list.file); cerr(": error: unknown type '"); @@ -13934,7 +13934,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // ty_untyped_int after the fold AND returns it // to the caller (the Hare-correct type), so a // `let x: size = size(T)` binding is assignable. - let utn: *node = mktname(c, "untyped_int"); + let utn: *syntax.node = mktname(c, "untyped_int"); if (issize) { // #108(b): rule-10 twin of the cstage // size/align unsized guard. @@ -13959,7 +13959,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // (N_DOT), parsed via parsearglist — not a // type expression. if (isoffset) { - if (e.list.next == nil && e.list.kind == nkind.N_DOT) { + if (e.list.next == nil && e.list.kind == syntax.nkind.N_DOT) { let off: i64 = astoffset(c, e.list); if (off < 0i64) { cerr("offset: no field '"); @@ -13990,7 +13990,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // this task; #19 (Drew's δ — dedicated AST kinds) is the // Hare-faithful path. This is the intercept-shim minimum to // unblock #15 (A.6.2.1e assertion enable). - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { // abort([msg]) / assert(cond[, msg]) — the EXPR_ASSERT // family (harec ref/harec/src/check.c:877,893), lowered // to rt_abort. Builtin only when no user symbol shadows @@ -14000,10 +14000,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // flat-scope root is filed as task #14). // The TY_ERR stamp on the callee is cgen's routing key // (cstage spells it `n->lhs->type = ty_err`). - if (streq(callee.str, "abort") - && scopelookupprefer(c.cur, c.curmod, "abort") == nil) { + if (syntax.streq(callee.str, "abort") + && syntax.scopelookupprefer(c.cur, c.curmod, "abort") == nil) { if (e.list != nil) { - let mt: *node = exprtype(c, e.list, nil); + let mt: *syntax.node = exprtype(c, e.list, nil); let conf: bool = false; if (!isassignable(c, mktname(c, "str"), mt, &conf)) { cerr("abort: message must be str\n"); @@ -14014,14 +14014,14 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { c.errs += 1; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; callee.type_ = c.tc.tyerr: *void; return tn; }; - if (streq(callee.str, "assert") && e.list != nil - && scopelookupprefer(c.cur, c.curmod, "assert") == nil) { - let ct: *node = exprtype(c, e.list, nil); + if (syntax.streq(callee.str, "assert") && e.list != nil + && syntax.scopelookupprefer(c.cur, c.curmod, "assert") == nil) { + let ct: *syntax.node = exprtype(c, e.list, nil); if (ct != nil) { // No alias peel: cstage compares ty_bool by // IDENTITY (cmd/wcc/check.c:1560), so a @@ -14029,11 +14029,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // align down (rule 10). Widening belongs to // the alias-peel choke-point arc (task #5, // #47/#68), both stages together. - let cu: *node = unwrapbang(ct); + let cu: *syntax.node = unwrapbang(ct); let condok: bool = false; - if (cu.kind == nkind.N_TNAME) { - if (streq(cu.str, "bool") - || streq(cu.str, "untyped_bool")) { + if (cu.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(cu.str, "bool") + || syntax.streq(cu.str, "untyped_bool")) { condok = true; }; }; @@ -14043,7 +14043,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; }; if (e.list.next != nil) { - let mt: *node = exprtype(c, e.list.next, nil); + let mt: *syntax.node = exprtype(c, e.list.next, nil); let conf: bool = false; if (!isassignable(c, mktname(c, "str"), mt, &conf)) { cerr("assert: message must be str\n"); @@ -14054,18 +14054,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { c.errs += 1; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; callee.type_ = c.tc.tyerr: *void; return tn; }; - if (streq(callee.str, "len")) { - let tn: *node = mktname(c, "i32"); + if (syntax.streq(callee.str, "len")) { + let tn: *syntax.node = mktname(c, "i32"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (streq(callee.str, "append") || streq(callee.str, "free")) { - let tn: *node = mktname(c, "void"); + if (syntax.streq(callee.str, "append") || syntax.streq(callee.str, "free")) { + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14078,8 +14078,8 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // delete(xs[i..j])); either way the OBJECT must be a // slice. The range form is the fold-5a prereq P2 // (regex.ha:333 delete(jump_idxs[group_level][..])). - if (streq(callee.str, "delete")) { - let d: *node = e.list; + if (syntax.streq(callee.str, "delete")) { + let d: *syntax.node = e.list; if (d == nil || d.next != nil) { cerr("delete: takes exactly one argument\n"); c.errs += 1; @@ -14088,22 +14088,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { exprtype(c, d, nil); // harec check.c:2016's reject; wording // adapted to ww's delete: prefix. - if (d.kind != nkind.N_INDEX && d.kind != nkind.N_SLICE) { + if (d.kind != syntax.nkind.N_INDEX && d.kind != syntax.nkind.N_SLICE) { cerr("delete: operand must be an indexing or slicing expression\n"); c.errs += 1; } else { - let basetn: *node = exprtype(c, d.lhs, nil); - let u: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, d.lhs, nil); + let u: *syntax.node = resolvealias(c, unwrapbang(basetn)); // harec check.c:2024 wording; a // fixed-size [N]T base and a str // base land here. - if (u == nil || u.kind != nkind.N_TSLICE) { + if (u == nil || u.kind != syntax.nkind.N_TSLICE) { cerr("delete must operate on a slice\n"); c.errs += 1; }; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14118,34 +14118,34 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // form (harec :821/:837) stay filed on #35; a range // PLACE is not Hare (harec asserts ACCESS_INDEX at // :784) — rejected, no task cite. - if (streq(callee.str, "insert")) { - let d: *node = e.list; + if (syntax.streq(callee.str, "insert")) { + let d: *syntax.node = e.list; if (d == nil || d.next == nil || d.next.next != nil) { cerr("insert: takes exactly two arguments\n"); c.errs += 1; }; if (d != nil) { exprtype(c, d, nil); - if (d.kind == nkind.N_SLICE) { + if (d.kind == syntax.nkind.N_SLICE) { cerr("insert: range place is invalid; operand must be an indexing expression xs[i]\n"); c.errs += 1; } else { - if (d.kind != nkind.N_INDEX) { + if (d.kind != syntax.nkind.N_INDEX) { cerr("insert: operand must be an indexing expression xs[i]\n"); c.errs += 1; } else { - let basetn: *node = exprtype(c, d.lhs, nil); - let u: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, d.lhs, nil); + let u: *syntax.node = resolvealias(c, unwrapbang(basetn)); // harec check.c:807 wording; a // fixed-size [N]T base lands here. - if (u == nil || u.kind != nkind.N_TSLICE) { + if (u == nil || u.kind != syntax.nkind.N_TSLICE) { cerr("insert must operate on a slice\n"); c.errs += 1; }; }; }; if (d.next != nil) { - if (d.next.kind == nkind.N_SPREAD) { + if (d.next.kind == syntax.nkind.N_SPREAD) { cerr("insert: spread form insert(xs[i], vs...) unimplemented (task #35)\n"); c.errs += 1; } else { @@ -14153,15 +14153,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; }; let nm: str; nm.ptr = nil; nm.len = 0; - if (callee.kind == nkind.N_IDENT) { nm = callee.str; }; - if (callee.kind == nkind.N_DOT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_IDENT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_DOT) { nm = callee.str; }; // #56: bare-leaf N_IDENT calls go through scopelookupprefer so // `foo()` inside module M binds to M.foo rather than another // module's same-leaf foo at the head of the flat scope bucket. @@ -14200,15 +14200,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // cgen post-#180+#185 already lowers the deref-call correctly, // so lifting the asserttyped bail is silent-SIGSEGV-safe. if (nm.len > 0) { - let s: *sym = nil; - if (callee.kind == nkind.N_IDENT) { - s = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = nil; + if (callee.kind == syntax.nkind.N_IDENT) { + s = syntax.scopelookupprefer(c.cur, c.curmod, nm); } else { - let ms: *sym = nil; - if (callee.lhs != nil && callee.lhs.kind == nkind.N_IDENT) { - ms = scopelookupprefer(c.cur, c.curmod, callee.lhs.str); - if (ms != nil && ms.skind != skind.SK_USE) { - let mu: *sym = scopelookupuselocal(ms.scope, callee.lhs.str); + let ms: *syntax.sym = nil; + if (callee.lhs != nil && callee.lhs.kind == syntax.nkind.N_IDENT) { + ms = syntax.scopelookupprefer(c.cur, c.curmod, callee.lhs.str); + if (ms != nil && ms.skind != syntax.skind.SK_USE) { + let mu: *syntax.sym = syntax.scopelookupuselocal(ms.scope, callee.lhs.str); if (mu != nil) { ms = mu; }; }; }; @@ -14227,11 +14227,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // :1378-1433 (call result IS the callee type's ret; no // global-leaf path) and harec check_autodereference // (ref/harec/src/check.c:1566-1581). - if (ms != nil && (ms.skind == skind.SK_USE || ms.use_alias != 0i32)) { - s = scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), nm); + if (ms != nil && (ms.skind == syntax.skind.SK_USE || ms.use_alias != 0i32)) { + s = syntax.scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), nm); }; }; - if (s != nil) { if (s.skind == skind.SK_FN) { if (s.decl != nil) { + if (s != nil) { if (s.skind == syntax.skind.SK_FN) { if (s.decl != nil) { // fn-decl's lhs is the return-type AST node. Mirrors cstage // cmd/wcc/check.c:984+ regular-CALL `n->type = // build_fn_type(c, s->decl)->ret` shape. @@ -14249,18 +14249,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // name path stays primary because a fn-NAME callee node in wwstage // already carries its RETURN type (fn-decl.lhs), not its fn-type — // so a `fn make() fn() void` callee would otherwise mis-yield void. - let ct: *node = resolvealias(c, unwrapbang(exprtype(c, callee, nil))); - for (ct != nil && ct.kind == nkind.N_TPTR) { + let ct: *syntax.node = resolvealias(c, unwrapbang(exprtype(c, callee, nil))); + for (ct != nil && ct.kind == syntax.nkind.N_TPTR) { ct = resolvealias(c, unwrapbang(ct.lhs)); }; - if (ct != nil) { if (ct.kind == nkind.N_TFN) { - let res: *node = ct.lhs; + if (ct != nil) { if (ct.kind == syntax.nkind.N_TFN) { + let res: *syntax.node = ct.lhs; e.type_ = tinfofornode(c, res): *void; return res; }; }; return nil; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // A.6.1.5a — fold cases only. Mirrors cstage cmd/wcc/check.c // :740-832. Struct field + pseudo-field (.len/.cap/.ptr) lands // in A.6.1.5b. SK_USE gates case 1; a #6a-D dot-lhs collision @@ -14273,11 +14273,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // to enumvalfold, matching cstage cmd/wcc/check.c:210-284 and // harec's enum-resolve constexpr set at // ref/harec/src/check.c:4419-4434. - let lhsn: *node = e.lhs; - if (lhsn != nil) { if (lhsn.kind == nkind.N_IDENT) { - let ms: *sym = scopelookupprefer(c.cur, c.curmod, lhsn.str); - if (ms != nil && ms.skind != skind.SK_USE) { - let mu: *sym = scopelookupuselocal(ms.scope, lhsn.str); + let lhsn: *syntax.node = e.lhs; + if (lhsn != nil) { if (lhsn.kind == syntax.nkind.N_IDENT) { + let ms: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, lhsn.str); + if (ms != nil && ms.skind != syntax.skind.SK_USE) { + let mu: *syntax.sym = syntax.scopelookupuselocal(ms.scope, lhsn.str); if (mu != nil) { ms = mu; }; }; if (ms != nil) { @@ -14287,21 +14287,21 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // through to outer case — cgen has its own module- // qualified resolution and the lenient checker policy // keeps the silent miss documented at scruttype L656. - if (ms.skind == skind.SK_USE || ms.use_alias != 0i32) { - let fs: *sym = scopelookupinmodule(c.cur, modkeyfor(c, lhsn.str), e.str); + if (ms.skind == syntax.skind.SK_USE || ms.use_alias != 0i32) { + let fs: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, lhsn.str), e.str); if (fs != nil) { if (fs.decl != nil) { // #34: a module-qualified bare fn rvalue `mod.fn` types as // its FN TYPE (twin of the N_IDENT arm, :2688); decl.lhs is // the RETURN type for an N_FNDECL. Pins 706 (`let p1: fn()i32 // = mod1.ping`). - if (fs.skind == skind.SK_FN) { - let ft: *node = newnode(nkind.N_TFN, "", 0, 0); + if (fs.skind == syntax.skind.SK_FN) { + let ft: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); ft.lhs = fs.decl.lhs; ft.list = fs.decl.list; e.type_ = tinfofornode(c, ft): *void; return ft; }; - let tn: *node = fs.decl.lhs; + let tn: *syntax.node = fs.decl.lhs; if (tn != nil) { e.type_ = tinfofornode(c, tn): *void; return tn; @@ -14311,12 +14311,12 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Fold case 2 inner: bare `EnumT.MEMBER` where EnumT // is an SK_TYPE in the flat scope. Mirror cstage // check.c:780-803. - if (ms.skind == skind.SK_TYPE) { if (ms.decl != nil) { - let body: *node = ms.decl.lhs; - let ub: *node = resolvealias(c, unwrapbang(body)); - if (ub != nil) { if (ub.kind == nkind.N_TENUM) { + if (ms.skind == syntax.skind.SK_TYPE) { if (ms.decl != nil) { + let body: *syntax.node = ms.decl.lhs; + let ub: *syntax.node = resolvealias(c, unwrapbang(body)); + if (ub != nil) { if (ub.kind == syntax.nkind.N_TENUM) { let prev: u64 = (-1i64): u64; - let m: *node = ub.list; + let m: *syntax.node = ub.list; for (m != nil) { let val: u64 = 0u64; if (m.lhs == nil) { @@ -14325,7 +14325,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { if (!enumvalfold(ub, m, m.lhs, &val)) { return nil; }; }; prev = val; - if (streq(m.str, e.str)) { + if (syntax.streq(m.str, e.str)) { foldtointlit(c, e, val: i64); e.type_ = tinfofornode(c, body): *void; return body; @@ -14341,15 +14341,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // via case 1 above to the enum body. Mirror cstage // check.c:805-832. Peel one TPTR for `(*EnumT).MEMBER` (rare // but cstage handles it at L808). - let basetn: *node = exprtype(c, lhsn, nil); + let basetn: *syntax.node = exprtype(c, lhsn, nil); if (basetn != nil) { - let bu: *node = resolvealias(c, unwrapbang(basetn)); - if (bu != nil) { if (bu.kind == nkind.N_TPTR) { + let bu: *syntax.node = resolvealias(c, unwrapbang(basetn)); + if (bu != nil) { if (bu.kind == syntax.nkind.N_TPTR) { bu = resolvealias(c, unwrapbang(bu.lhs)); }; }; - if (bu != nil) { if (bu.kind == nkind.N_TENUM) { + if (bu != nil) { if (bu.kind == syntax.nkind.N_TENUM) { let prev: u64 = (-1i64): u64; - let m: *node = bu.list; + let m: *syntax.node = bu.list; for (m != nil) { let val: u64 = 0u64; if (m.lhs == nil) { @@ -14358,7 +14358,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { if (!enumvalfold(bu, m, m.lhs, &val)) { return nil; }; }; prev = val; - if (streq(m.str, e.str)) { + if (syntax.streq(m.str, e.str)) { foldtointlit(c, e, val: i64); e.type_ = tinfofornode(c, basetn): *void; return basetn; @@ -14374,10 +14374,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // L833-842. `str` lives as N_TNAME("str") in wwstage — no // dedicated N_TSTR kind — so test the trio shape here. if (bu != nil) { - let isstr: bool = (bu.kind == nkind.N_TNAME) && streq(bu.str, "str"); - if (bu.kind == nkind.N_TSLICE || bu.kind == nkind.N_TARRAY || isstr) { - if (streq(e.str, "len")) { - let tn: *node = mktname(c, "i32"); + let isstr: bool = (bu.kind == syntax.nkind.N_TNAME) && syntax.streq(bu.str, "str"); + if (bu.kind == syntax.nkind.N_TSLICE || bu.kind == syntax.nkind.N_TARRAY || isstr) { + if (syntax.streq(e.str, "len")) { + let tn: *syntax.node = mktname(c, "i32"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14385,13 +14385,13 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // invalid (drew ruling). cstage check.c errs // symmetrically. c.errs>0 gates cgen off → build // fails (the #11 inferarraylen idiom). - if (bu.kind == nkind.N_TARRAY && streq(e.str, "cap")) { + if (bu.kind == syntax.nkind.N_TARRAY && syntax.streq(e.str, "cap")) { cerr("error: no field 'cap' on a fixed-size array (arrays have no capacity; use .len)\n"); c.errs += 1; return nil; }; - if (streq(e.str, "cap")) { - let tn: *node = mktname(c, "i32"); + if (syntax.streq(e.str, "cap")) { + let tn: *syntax.node = mktname(c, "i32"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14399,10 +14399,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // &A[0], a sanctioned ww spelling / faithful Hare // desugaring (14 live consumers). KEEP — .ptr valid. // See .ai/drew-gapa-ptr-ruling.md. - if (streq(e.str, "ptr")) { - let elem: *node = bu.lhs; + if (syntax.streq(e.str, "ptr")) { + let elem: *syntax.node = bu.lhs; if (isstr) { elem = mktname(c, "u8"); }; - let pp: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pp: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pp.lhs = elem; e.type_ = tinfofornode(c, pp): *void; return pp; @@ -14410,10 +14410,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; }; // Struct field walk. Cstage L843-849 errors on missing field. - if (bu != nil) { if (bu.kind == nkind.N_TSTRUCT) { - let f: *node = bu.list; + if (bu != nil) { if (bu.kind == syntax.nkind.N_TSTRUCT) { + let f: *syntax.node = bu.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { if (streq(f.str, e.str)) { + if (f.kind == syntax.nkind.N_TFIELD) { if (syntax.streq(f.str, e.str)) { e.type_ = tinfofornode(c, f.lhs): *void; return f.lhs; }; }; @@ -14423,16 +14423,16 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Tuple positional access `t.0`, `t.1`, …. Cstage L850-866 // errors on non-numeric / out-of-range; wwstage falls // through. fldnumidx (cgenutil) returns -1 on non-digit. - if (bu != nil) { if (bu.kind == nkind.N_TTUPLE) { + if (bu != nil) { if (bu.kind == syntax.nkind.N_TTUPLE) { let idx: i32 = fldnumidx(e.str); if (idx >= 0) { - let p: *node = bu.list; + let p: *syntax.node = bu.list; for (idx > 0 && p != nil) { p = p.next; idx -= 1; }; if (p != nil) { - let pt: *node = p.lhs; + let pt: *syntax.node = p.lhs; e.type_ = tinfofornode(c, pt): *void; return pt; }; @@ -14441,7 +14441,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; return nil; }; - if (k == nkind.N_STRUCTLIT) { + if (k == syntax.nkind.N_STRUCTLIT) { // A.6.1.6 — head-only stamp of the struct-lit's overall type. // Mirror cstage cmd/wcc/check.c:1161-1197; field-level walk // (cstage L1178-1194) parked behind #23 / Phase 2 — field @@ -14452,10 +14452,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // TYPE_IDENT in e.lhs; e.lhs == nil would be a future Hare- // style anonymous struct lit we don't yet parse — bail. if (e.lhs == nil) { return nil; }; - if (e.lhs.kind == nkind.N_IDENT) { - let ms: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); - if (ms != nil) { if (ms.skind == skind.SK_TYPE) { if (ms.decl != nil) { - let tn: *node = ms.decl.lhs; + if (e.lhs.kind == syntax.nkind.N_IDENT) { + let ms: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.lhs.str); + if (ms != nil) { if (ms.skind == syntax.skind.SK_TYPE) { if (ms.decl != nil) { + let tn: *syntax.node = ms.decl.lhs; if (tn != nil) { // #66 Phase-N step 3: stamp e.type_ to the NOMINAL // per-decl NAMED, not the flattened body. `overflow{}` @@ -14473,8 +14473,8 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Return the body node tn unchanged: byte-id rides // e.type_ (cgen), while the checker's AST-level // assign/return checks keep their prior input. - let tnm: *node = mktname(c, e.lhs.str); - let nti: *tinfo = tinfofornode(c, tnm); + let tnm: *syntax.node = mktname(c, e.lhs.str); + let nti: *syntax.tinfo = tinfofornode(c, tnm); if (nti != nil) { e.type_ = nti: *void; } else { e.type_ = tinfofornode(c, tn): *void; }; // #251: range-check array-typed field inits @@ -14487,18 +14487,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // and closes the rule-7 silent out-of-range truncate // at this site (cstage check.c:1546 range-checks via // arrlit_init_fits). - let stn: *node = resolvealias(c, tn); - if (stn != nil && stn.kind == nkind.N_TSTRUCT) { - let fi: *node = e.list; + let stn: *syntax.node = resolvealias(c, tn); + if (stn != nil && stn.kind == syntax.nkind.N_TSTRUCT) { + let fi: *syntax.node = e.list; for (fi != nil) { - if (fi.kind == nkind.N_FIELD + if (fi.kind == syntax.nkind.N_FIELD && fi.lhs != nil - && fi.lhs.kind == nkind.N_ARRLIT) { - let ftn: *node = nil; - let tf: *node = stn.list; + && fi.lhs.kind == syntax.nkind.N_ARRLIT) { + let ftn: *syntax.node = nil; + let tf: *syntax.node = stn.list; for (tf != nil) { - if (tf.kind == nkind.N_TFIELD) { - if (streq(tf.str, fi.str)) { ftn = tf.lhs; }; + if (tf.kind == syntax.nkind.N_TFIELD) { + if (syntax.streq(tf.str, fi.str)) { ftn = tf.lhs; }; }; tf = tf.next; }; @@ -14521,7 +14521,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, e.lhs): *void; return e.lhs; }; - if (k == nkind.N_ARRLIT) { + if (k == syntax.nkind.N_ARRLIT) { // A.6.1.7 — head-only stamp of the array-lit's overall type. // Mirror cstage cmd/wcc/check.c:1198-1211: walk elements, // skip the `...` repeat sentinel (parse/expr.ww:101-105), @@ -14538,16 +14538,16 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // precedent at L1509. Consumers default-type via the declared // `let` slot until A.6.3 lands. Mixed-type elements follow // cstage first-element-wins; no unify check (future scope). - let elt: *node = nil; + let elt: *syntax.node = nil; let count: u64 = 0u64; - let it: *node = e.list; + let it: *syntax.node = e.list; for (it != nil) { let skip: bool = false; - if (it.kind == nkind.N_FIELD) { - if (streq(it.str, "...")) { skip = true; }; + if (it.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(it.str, "...")) { skip = true; }; }; if (!skip) { - let t: *node = exprtype(c, it, nil); + let t: *syntax.node = exprtype(c, it, nil); if (elt == nil) { // #19: N_STRUCTLIT exprtype returns the struct BODY // (N_TSTRUCT) per #66, but the array->slice @@ -14559,9 +14559,9 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // is the same N_TNAME shape (typeeqast is already // streq-keyed for TNAME). Non-named elements keep the // existing first-element shape. - if (it.kind == nkind.N_STRUCTLIT + if (it.kind == syntax.nkind.N_STRUCTLIT && it.lhs != nil - && it.lhs.kind == nkind.N_IDENT) { + && it.lhs.kind == syntax.nkind.N_IDENT) { elt = mktname(c, it.lhs.str); } else { elt = t; @@ -14583,23 +14583,23 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Hare-fidelity: harec lower_flexible defaults a flexible iconst // to `int` (ref/harec/src/types.c:835). int = machine word (8B); // the old i32 truncated values >2^31 (#263 trap). - if (elt != nil && elt.kind == nkind.N_TNAME) { - if (streq(elt.str, "untyped_int")) { + if (elt != nil && elt.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(elt.str, "untyped_int")) { elt = mktname(c, "int"); - } else { if (streq(elt.str, "untyped_float")) { + } else { if (syntax.streq(elt.str, "untyped_float")) { elt = mktname(c, "f64"); - } else { if (streq(elt.str, "untyped_str")) { + } else { if (syntax.streq(elt.str, "untyped_str")) { elt = mktname(c, "str"); - } else { if (streq(elt.str, "untyped_rune")) { + } else { if (syntax.streq(elt.str, "untyped_rune")) { elt = mktname(c, "rune"); - } else { if (streq(elt.str, "untyped_bool")) { + } else { if (syntax.streq(elt.str, "untyped_bool")) { elt = mktname(c, "bool"); }; }; }; }; }; }; // Empty inferred arrlit: default to int, symmetric with cstage // check.c:1859 empty-fallback ty_int (#103). Was "i32". if (elt == nil) { elt = mktname(c, "int"); }; - let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0); + let arr: *syntax.node = syntax.newnode(syntax.nkind.N_TARRAY, "", 0, 0); // #6(niche): stamp the SYNTHESIZED element TNAME so the inferred // array's cgen is IDENTICAL to an explicit [N]T's (whose element is // resolvewalk-stamped). For a scalar element (int/u8) cgen's @@ -14611,7 +14611,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // real exprtype result whose type_ is already set. if (elt.type_ == nil) { elt.type_ = tinfofornode(c, elt): *void; }; arr.lhs = elt; - let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let cn: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); cn.uval = count; // #6(niche): stamp the SYNTHESIZED count literal. When this arr is // planted on an inferred array global's n.lhs (the array twin of @@ -14632,7 +14632,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { arr.type_ = e.type_; return arr; }; - if (k == nkind.N_SLICE) { + if (k == syntax.nkind.N_SLICE) { // A.6.2.0a — head-only stamp of the slice expression's overall // type. Mirrors cstage cmd/wcc/check.c:1214-1228 N_SLICE: peel // alias on the base; [N]T → []T, []T → []T (return base), str @@ -14643,22 +14643,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Documented cstage divergence: cstage L1227 errors on a // non-sliceable base; wwstage returns nil (lenient on miss), // matching scruttype L656 / A.6.1.5b N_DOT precedent. - let basetn: *node = exprtype(c, e.lhs, nil); - let bu: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, e.lhs, nil); + let bu: *syntax.node = resolvealias(c, unwrapbang(basetn)); if (bu == nil) { return nil; }; - if (bu.kind == nkind.N_TARRAY) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + if (bu.kind == syntax.nkind.N_TARRAY) { + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = bu.lhs; e.type_ = tinfofornode(c, sl): *void; return sl; }; - if (bu.kind == nkind.N_TSLICE) { + if (bu.kind == syntax.nkind.N_TSLICE) { e.type_ = tinfofornode(c, basetn): *void; return basetn; }; - if (bu.kind == nkind.N_TNAME) { - if (streq(bu.str, "str")) { - let tn: *node = mktname(c, "str"); + if (bu.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(bu.str, "str")) { + let tn: *syntax.node = mktname(c, "str"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14668,15 +14668,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // the index route (idxeffti) and unlike Hare. Loud on the // usual []T annotation; for-range likewise. Team task #18 // (#61-residual A). - if (bu.kind == nkind.N_TPTR && bu.lhs != nil) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + if (bu.kind == syntax.nkind.N_TPTR && bu.lhs != nil) { + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = bu.lhs; e.type_ = tinfofornode(c, sl): *void; return sl; }; return nil; }; - if (k == nkind.N_TUPLE) { + if (k == syntax.nkind.N_TUPLE) { // A.6.2.0b — head-only stamp of the tuple expression's // overall type. Mirrors cstage cmd/wcc/check.c:1437-1451 // N_TUPLE: walk e.list, type each element via exprtype, and @@ -14692,47 +14692,47 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // expression), so empty is unreachable and yields nil here // (matches scruttype L656 / A.6.1.5b N_DOT lenient-on-miss). if (e.list == nil) { return nil; }; - let head: *node = nil; - let tail: *node = nil; - let it: *node = e.list; + let head: *syntax.node = nil; + let tail: *syntax.node = nil; + let it: *syntax.node = e.list; for (it != nil) { - let elemt: *node = exprtype(c, it, nil); - let w: *node = newnode(nkind.N_TPARAM, "", 0, 0); + let elemt: *syntax.node = exprtype(c, it, nil); + let w: *syntax.node = syntax.newnode(syntax.nkind.N_TPARAM, "", 0, 0); w.lhs = elemt; if (head == nil) { head = w; } else { tail.next = w; }; tail = w; it = it.next; }; - let tt: *node = newnode(nkind.N_TTUPLE, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTUPLE, "", 0, 0); tt.list = head; e.type_ = tinfofornode(c, tt): *void; return tt; }; - if (k == nkind.N_RECV) { + if (k == syntax.nkind.N_RECV) { // A.6.2.0d — head-only stamp of the receive expression's // overall type. Mirrors cstage cmd/wcc/check.c:1230-1236 // N_RECV: peel alias on the channel base; chan T → T. // Documented cstage divergence: cstage L1234 errors on a // non-chan base; wwstage returns nil (lenient on miss), // matching scruttype L656 / A.6.1.5b N_DOT precedent. - let basetn: *node = exprtype(c, e.lhs, nil); - let bu: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, e.lhs, nil); + let bu: *syntax.node = resolvealias(c, unwrapbang(basetn)); if (bu == nil) { return nil; }; - if (bu.kind == nkind.N_TCHAN) { + if (bu.kind == syntax.nkind.N_TCHAN) { e.type_ = tinfofornode(c, bu.lhs): *void; return bu.lhs; }; return nil; }; - if (k == nkind.N_SPREAD) { + if (k == syntax.nkind.N_SPREAD) { // A.6.2.0e — pass-through stamp. Mirrors cstage check.c:1212-1213. // The spread expression `xs...` carries the operand's type. - let t: *node = exprtype(c, e.lhs, nil); + let t: *syntax.node = exprtype(c, e.lhs, nil); if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; return t; }; - if (k == nkind.N_MATCH) { + if (k == syntax.nkind.N_MATCH) { // A.6.2.0g — port of cstage cmd/wcc/check.c:1316-1330 match-as- // expression stamp. The match's type is the first arm's yield // operand type; void if no arm yields. Wwstage skips cstage's @@ -14747,15 +14747,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // node (nil on the post-walk cached read) for the assignability // node the consumers (checkletassign/checkretassign) read off this // arm's *node return; see matchyieldtype's docstring + #279. - let yt: *tinfo = nil; - let retn: *node = nil; - let cs: *node = e.list; + let yt: *syntax.tinfo = nil; + let retn: *syntax.node = nil; + let cs: *syntax.node = e.list; for (cs != nil) { // cs.str/cs.lhs = the arm's case-binding name + declared // type (the N_MCASE binder); fed to matchyieldtype's #241 // scope-popped `yield ` fallback. - let armn: *node = nil; - let t: *tinfo = matchyieldtype(c, cs.body, cs.str, cs.lhs, &armn); + let armn: *syntax.node = nil; + let t: *syntax.tinfo = matchyieldtype(c, cs.body, cs.str, cs.lhs, &armn); if (t != nil) { if (yt == nil) { // First yielding arm: it is the match's type; @@ -14782,7 +14782,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // untyped_float) - a precision gap, not a silent // miscompile of the catA repro; closeable only with a // real tinfo type_assignable. - if (!typeeq(yt, t)) { + if (!syntax.typeeq(yt, t)) { let ca: i32 = yieldclass(yt); let cb: i32 = yieldclass(t); if (ca != 0i32 && cb != 0i32 && ca != cb) { @@ -14799,7 +14799,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = yt: *void; return retn; }; - if (k == nkind.N_YIELD) { + if (k == syntax.nkind.N_YIELD) { // A.6.2.0f — pass-through stamp; cstage check.c:1708 does NOT // stamp N_YIELD (statement-shaped). Wwstage's A.6.2 invariant // requires every post-dispatch kind have type_ set. Yield's @@ -14808,25 +14808,25 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // expression with a type). Bare `yield;` (no operand) stamps // void. if (e.lhs == nil) { - let v: *node = mktname(c, "void"); + let v: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, v): *void; return v; }; - let t: *node = exprtype(c, e.lhs, nil); + let t: *syntax.node = exprtype(c, e.lhs, nil); if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; return t; }; - if (k == nkind.N_TRYPROP) { + if (k == syntax.nkind.N_TRYPROP) { // success unwrap: the success-variant type of operand's // tagged union. - let opt: *node = exprtype(c, e.lhs, nil); - let ou: *node = resolvealias(c, unwrapbang(opt)); + let opt: *syntax.node = exprtype(c, e.lhs, nil); + let ou: *syntax.node = resolvealias(c, unwrapbang(opt)); if (ou == nil) { return nil; }; - if (ou.kind != nkind.N_TTAGGED) { return nil; }; + if (ou.kind != syntax.nkind.N_TTAGGED) { return nil; }; // Hare semantics: success = first non-error variant if // any !-flag is present; else first variant. if (taggedhaserr(c, ou)) { - let v: *node = ou.list; + let v: *syntax.node = ou.list; for (v != nil) { if (!iserrvariant(c, ou, v)) { e.type_ = tinfofornode(c, v): *void; @@ -14839,16 +14839,16 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, ou.list): *void; return ou.list; }; - if (k == nkind.N_TRYUNW) { + if (k == syntax.nkind.N_TRYUNW) { // `e!` abort-on-error unwrap; success variant is what the // receiver gets, identical to `?` shape modulo control flow. // #31: required so `let p: *T = alloc(v)!;` resolves to *T. - let opt: *node = exprtype(c, e.lhs, nil); - let ou: *node = resolvealias(c, unwrapbang(opt)); + let opt: *syntax.node = exprtype(c, e.lhs, nil); + let ou: *syntax.node = resolvealias(c, unwrapbang(opt)); if (ou == nil) { return nil; }; - if (ou.kind != nkind.N_TTAGGED) { return nil; }; + if (ou.kind != syntax.nkind.N_TTAGGED) { return nil; }; if (taggedhaserr(c, ou)) { - let v: *node = ou.list; + let v: *syntax.node = ou.list; for (v != nil) { if (!iserrvariant(c, ou, v)) { e.type_ = tinfofornode(c, v): *void; @@ -14861,15 +14861,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, ou.list): *void; return ou.list; }; - if (k == nkind.N_TYPEASSERT) { + if (k == syntax.nkind.N_TYPEASSERT) { // `e as T` → T. Mirrors cstage cmd/wcc/check.c TYPEASSERT // `n->type = resolve_type(c, n->rhs)`. e.type_ = tinfofornode(c, e.rhs): *void; return e.rhs; }; - if (k == nkind.N_TYPETEST) { + if (k == syntax.nkind.N_TYPETEST) { // `e is T` → bool - let tn: *node = mktname(c, "bool"); + let tn: *syntax.node = mktname(c, "bool"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14879,22 +14879,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // isuntypedint / is_str_like / is_bool_like — helpers used // by the assignability check below to allow common AST shapes // through without needing real type inference. -fn isuntypedint(t: *node) bool = { +fn isuntypedint(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "untyped_int"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "untyped_int"); }; -fn isuntypedfloat(t: *node) bool = { +fn isuntypedfloat(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "untyped_float"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "untyped_float"); }; -fn isuntypednil(t: *node) bool = { +fn isuntypednil(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "untyped_nil"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "untyped_nil"); }; // isinttypeast — int-typed AST node. Either a primitive int name @@ -14902,24 +14902,24 @@ fn isuntypednil(t: *node) bool = { // excluded so the enum↔int reinterpret in checkisas (#52) refuses a // surprise `enum as f64` shape. Mirrors cstage's type_isint // (cmd/wcc/type.c) restricted to the kinds reachable from AST. -fn isinttypeast(t: *node) bool = { +fn isinttypeast(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind == nkind.N_TENUM) { return true; }; - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind == syntax.nkind.N_TENUM) { return true; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let s: str = t.str; - if (streq(s, "i8")) { return true; }; - if (streq(s, "i16")) { return true; }; - if (streq(s, "i32")) { return true; }; - if (streq(s, "i64")) { return true; }; - if (streq(s, "u8")) { return true; }; - if (streq(s, "u16")) { return true; }; - if (streq(s, "u32")) { return true; }; - if (streq(s, "u64")) { return true; }; - if (streq(s, "int")) { return true; }; - if (streq(s, "uint")) { return true; }; - if (streq(s, "uintptr")) { return true; }; - if (streq(s, "size")) { return true; }; - if (streq(s, "rune")) { return true; }; + if (syntax.streq(s, "i8")) { return true; }; + if (syntax.streq(s, "i16")) { return true; }; + if (syntax.streq(s, "i32")) { return true; }; + if (syntax.streq(s, "i64")) { return true; }; + if (syntax.streq(s, "u8")) { return true; }; + if (syntax.streq(s, "u16")) { return true; }; + if (syntax.streq(s, "u32")) { return true; }; + if (syntax.streq(s, "u64")) { return true; }; + if (syntax.streq(s, "int")) { return true; }; + if (syntax.streq(s, "uint")) { return true; }; + if (syntax.streq(s, "uintptr")) { return true; }; + if (syntax.streq(s, "size")) { return true; }; + if (syntax.streq(s, "rune")) { return true; }; return false; }; @@ -14933,64 +14933,64 @@ fn isinttypeast(t: *node) bool = { // (chasing) accepts. nil operands are treated as already-errored upstream // (the unifyarith nil-bail shapes) and NOT re-rejected — the cstage twin's // `l == ty_err` escape. -fn intkindast(c: *checker, t: *node) bool = { +fn intkindast(c: *checker, t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (isinttypeast(u)) { return true; }; // int family + enum + rune if (isuntypedint(u)) { return true; }; - if (u != nil && u.kind == nkind.N_TNAME && streq(u.str, "untyped_rune")) { + if (u != nil && u.kind == syntax.nkind.N_TNAME && syntax.streq(u.str, "untyped_rune")) { return true; }; return false; }; -fn numkindast(c: *checker, t: *node) bool = { +fn numkindast(c: *checker, t: *syntax.node) bool = { if (intkindast(c, t)) { return true; }; if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return false; }; - if (u.kind != nkind.N_TNAME) { return false; }; + if (u.kind != syntax.nkind.N_TNAME) { return false; }; let s: str = u.str; - if (streq(s, "f32")) { return true; }; - if (streq(s, "f64")) { return true; }; - if (streq(s, "untyped_float")) { return true; }; + if (syntax.streq(s, "f32")) { return true; }; + if (syntax.streq(s, "f64")) { return true; }; + if (syntax.streq(s, "untyped_float")) { return true; }; return false; }; -fn boolkindast(c: *checker, t: *node) bool = { +fn boolkindast(c: *checker, t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return false; }; - if (u.kind != nkind.N_TNAME) { return false; }; - return streq(u.str, "bool") || streq(u.str, "untyped_bool"); + if (u.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(u.str, "bool") || syntax.streq(u.str, "untyped_bool"); }; -fn isnumerictname(t: *node) bool = { +fn isnumerictname(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let s: str = t.str; - if (streq(s, "i8")) { return true; }; - if (streq(s, "i16")) { return true; }; - if (streq(s, "i32")) { return true; }; - if (streq(s, "i64")) { return true; }; - if (streq(s, "u8")) { return true; }; - if (streq(s, "u16")) { return true; }; - if (streq(s, "u32")) { return true; }; - if (streq(s, "u64")) { return true; }; - if (streq(s, "int")) { return true; }; - if (streq(s, "uint")) { return true; }; - if (streq(s, "uintptr")) { return true; }; - if (streq(s, "size")) { return true; }; - if (streq(s, "rune")) { return true; }; - if (streq(s, "f32")) { return true; }; - if (streq(s, "f64")) { return true; }; + if (syntax.streq(s, "i8")) { return true; }; + if (syntax.streq(s, "i16")) { return true; }; + if (syntax.streq(s, "i32")) { return true; }; + if (syntax.streq(s, "i64")) { return true; }; + if (syntax.streq(s, "u8")) { return true; }; + if (syntax.streq(s, "u16")) { return true; }; + if (syntax.streq(s, "u32")) { return true; }; + if (syntax.streq(s, "u64")) { return true; }; + if (syntax.streq(s, "int")) { return true; }; + if (syntax.streq(s, "uint")) { return true; }; + if (syntax.streq(s, "uintptr")) { return true; }; + if (syntax.streq(s, "size")) { return true; }; + if (syntax.streq(s, "rune")) { return true; }; + if (syntax.streq(s, "f32")) { return true; }; + if (syntax.streq(s, "f64")) { return true; }; return false; }; -fn isstrtname(t: *node) bool = { +fn isstrtname(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "str"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "str"); }; // tagshape — #24/#37: the coarse variant-shape bucket of a (resolved) type @@ -15001,9 +15001,9 @@ fn isstrtname(t: *node) bool = { // aggregate-shape-lenient leg to keep a tagged accept lenient ONLY against a // shape-compatible variant — same classifier cgen boxes with, so the checker // accept and the cgen box agree (rule-12: reuse the in-tree classifier). -fn tagshape(t: *node) i32 = { +fn tagshape(t: *syntax.node) i32 = { if (t == nil) { return 0i32; }; - if (t.kind == nkind.N_TSLICE) { return 2i32; }; + if (t.kind == syntax.nkind.N_TSLICE) { return 2i32; }; if (isstrtname(t)) { return 1i32; }; return 0i32; }; @@ -15014,14 +15014,14 @@ fn tagshape(t: *node) i32 = { // Mirror of cstage addrfn_ptr_matches (cmd/wcc/check.c, project #206); // reuses typeeqast — the same structural-fn comparator cstage uses via // type_eq(TY_FN,TY_FN) — for symmetry. -fn addrfnptrmatches(c: *checker, ptr: *node, synth: *node) bool = { +fn addrfnptrmatches(c: *checker, ptr: *syntax.node, synth: *syntax.node) bool = { if (ptr == nil) { return false; }; - let pu: *node = resolvealias(c, unwrapbang(ptr)); + let pu: *syntax.node = resolvealias(c, unwrapbang(ptr)); if (pu == nil) { return false; }; - if (pu.kind != nkind.N_TPTR) { return false; }; - let ref: *node = resolvealias(c, unwrapbang(pu.lhs)); + if (pu.kind != syntax.nkind.N_TPTR) { return false; }; + let ref: *syntax.node = resolvealias(c, unwrapbang(pu.lhs)); if (ref == nil) { return false; }; - if (ref.kind != nkind.N_TFN) { return false; }; + if (ref.kind != syntax.nkind.N_TFN) { return false; }; return typeeqast(c, synth, ref); }; @@ -15040,35 +15040,35 @@ fn addrfnptrmatches(c: *checker, ptr: *node, synth: *node) bool = { // the rhs node. N_FNDECL and N_TFN share parseparams' param-node shape // (lib/ww/parse/decl.ww + parse.ww), so a synthetic N_TFN over the fn // decl's lhs/list compares correctly under typeeqast. -fn assignableaddrfn(c: *checker, dst: *node, rhs: *node) bool = { +fn assignableaddrfn(c: *checker, dst: *syntax.node, rhs: *syntax.node) bool = { if (dst == nil) { return false; }; if (rhs == nil) { return false; }; - if (rhs.kind != nkind.N_UN) { return false; }; - if (rhs.op != tkind.TK_AMP) { return false; }; - let id: *node = rhs.lhs; + if (rhs.kind != syntax.nkind.N_UN) { return false; }; + if (rhs.op != syntax.tkind.TK_AMP) { return false; }; + let id: *syntax.node = rhs.lhs; if (id == nil) { return false; }; - if (id.kind != nkind.N_IDENT) { return false; }; + if (id.kind != syntax.nkind.N_IDENT) { return false; }; // #4: curmod preference. Without it a `&handler` whose leaf also // names a fn in a later module misbinds the foreign fn's signature // here (scopedefineinmodule prepends → chain-first = last module), // silently admitting a *fn into a foreign-sig slot or rejecting a // valid same-module &fn. cstage uses scope_lookup_prefer with // cur_mod (cmd/wcc/check.c:410, assignable_addrfn). - let s: *sym = scopelookupprefer(c.cur, c.curmod, id.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, id.str); if (s == nil) { return false; }; - if (s.skind != skind.SK_FN) { return false; }; + if (s.skind != syntax.skind.SK_FN) { return false; }; if (s.decl == nil) { return false; }; - let d: *node = s.decl; - if (d.kind != nkind.N_FNDECL) { return false; }; - let synth: *node = newnode(nkind.N_TFN, "", 0, 0); + let d: *syntax.node = s.decl; + if (d.kind != syntax.nkind.N_FNDECL) { return false; }; + let synth: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); synth.lhs = d.lhs; synth.list = d.list; - let du: *node = resolvealias(c, unwrapbang(dst)); + let du: *syntax.node = resolvealias(c, unwrapbang(dst)); if (du == nil) { return false; }; - if (du.kind == nkind.N_TPTR) { return addrfnptrmatches(c, du, synth); }; - if (du.kind == nkind.N_TTAGGED) { + if (du.kind == syntax.nkind.N_TPTR) { return addrfnptrmatches(c, du, synth); }; + if (du.kind == syntax.nkind.N_TTAGGED) { let nmatch: i32 = 0; - let v: *node = du.list; + let v: *syntax.node = du.list; for (v != nil) { if (addrfnptrmatches(c, v, synth)) { nmatch = nmatch + 1; }; v = v.next; @@ -15085,13 +15085,13 @@ fn assignableaddrfn(c: *checker, dst: *node, rhs: *node) bool = { // `confident` lets the caller decide whether to emit an error // when the result is false: if !confident, the caller should not // flag it. -fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { +fn isassignable(c: *checker, dst: *syntax.node, src: *syntax.node, confident: *bool) bool = { *confident = false; if (dst == nil) { return true; }; // no declared target if (src == nil) { return true; }; // unknown src type *confident = true; - let du: *node = resolvealias(c, unwrapbang(dst)); - let su: *node = resolvealias(c, unwrapbang(src)); + let du: *syntax.node = resolvealias(c, unwrapbang(dst)); + let su: *syntax.node = resolvealias(c, unwrapbang(src)); if (du == nil) { *confident = false; return true; }; if (su == nil) { *confident = false; return true; }; if (typeeqast(c, du, su)) { return true; }; @@ -15102,8 +15102,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // reject (mirror cstage type.c type_assignable's #258 arm + fallthrough // to 0). The acceptance sites then desugar the array expr to an // explicit full slice via desugararrayslice; cgen is untouched. - if (du.kind == nkind.N_TSLICE) { - if (su.kind == nkind.N_TARRAY) { + if (du.kind == syntax.nkind.N_TSLICE) { + if (su.kind == syntax.nkind.N_TARRAY) { if (typeeqast(c, du.lhs, su.lhs)) { return true; }; return false; }; @@ -15112,10 +15112,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { if (isuntypedint(su)) { if (isnumerictname(du)) { return true; }; // (T | ...) tagged: only OK if some variant accepts untyped_int. - if (du.kind == nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { if (isnumerictname(vu)) { return true; }; // mirror cstage type_isnum(enum)=true (type.c:201 -> @@ -15123,7 +15123,7 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // accept an untyped int. Without this the #23 fix would // flip an enum-variant union to reject while cstage // accepts = a NEW divergence (A3 trap). - if (vu.kind == nkind.N_TENUM) { return true; }; + if (vu.kind == syntax.nkind.N_TENUM) { return true; }; }; v = v.next; }; @@ -15136,8 +15136,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // general call-arg check made this path reachable). Mirror the // tagged→tagged spread escape (:4117). Spread decl-form flatten // is #199b, deferred. - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { *confident = false; return true; }; @@ -15156,10 +15156,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { return false; }; // Known non-numeric primitive: confidently wrong. - if (du.kind == nkind.N_TNAME) { - if (streq(du.str, "bool")) { return false; }; - if (streq(du.str, "void")) { return false; }; - if (streq(du.str, "str")) { return false; }; + if (du.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(du.str, "bool")) { return false; }; + if (syntax.streq(du.str, "void")) { return false; }; + if (syntax.streq(du.str, "str")) { return false; }; }; // #24: untyped int into a known AGGREGATE (slice/array/ptr/fn/chan/ // tuple/struct) — confident reject. `let xs: []int = 5` read the int @@ -15167,10 +15167,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // left it unconfident → silent accept). cstage type_assignable // rejects untyped_int into a non-numeric aggregate (cmd/wcc/type.c). // The TTAGGED case is handled above; this is the bare aggregate. - if (du.kind == nkind.N_TSLICE || du.kind == nkind.N_TARRAY - || du.kind == nkind.N_TPTR || du.kind == nkind.N_TFN - || du.kind == nkind.N_TCHAN || du.kind == nkind.N_TTUPLE - || du.kind == nkind.N_TSTRUCT) { + if (du.kind == syntax.nkind.N_TSLICE || du.kind == syntax.nkind.N_TARRAY + || du.kind == syntax.nkind.N_TPTR || du.kind == syntax.nkind.N_TFN + || du.kind == syntax.nkind.N_TCHAN || du.kind == syntax.nkind.N_TTUPLE + || du.kind == syntax.nkind.N_TSTRUCT) { return false; }; // Unknown shapes: stay quiet. @@ -15179,10 +15179,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { }; if (isuntypedfloat(su)) { if (isnumerictname(du)) { return true; }; - if (du.kind == nkind.N_TNAME) { - if (streq(du.str, "bool")) { return false; }; - if (streq(du.str, "void")) { return false; }; - if (streq(du.str, "str")) { return false; }; + if (du.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(du.str, "bool")) { return false; }; + if (syntax.streq(du.str, "void")) { return false; }; + if (syntax.streq(du.str, "str")) { return false; }; }; // A4 (#23 float-twin): (T | ...) tagged dst — accept iff a DIRECT // variant is a float type. cstage type_assignable for an @@ -15194,22 +15194,22 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // true (:3777). Without it the catch-all (:3972) over-accepts an // untyped float into ANY tagged (silent tag=0). Faithful // flatten+rebox deferred post-CSP (nominal id, #23/#40). - if (du.kind == nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { - if (vu.kind == nkind.N_TNAME) { - if (streq(vu.str, "f32")) { return true; }; - if (streq(vu.str, "f64")) { return true; }; + if (vu.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(vu.str, "f32")) { return true; }; + if (syntax.streq(vu.str, "f64")) { return true; }; }; }; v = v.next; }; // #24: spread variant keeps the lenient escape (cstage flattens; // wwstage can't) — same rationale as the untyped-int arm above. - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { *confident = false; return true; }; @@ -15218,10 +15218,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { }; // #24: untyped float into a known AGGREGATE — confident reject (twin // of the untyped-int aggregate arm above; `let xs: []f64 = 1.5`). - if (du.kind == nkind.N_TSLICE || du.kind == nkind.N_TARRAY - || du.kind == nkind.N_TPTR || du.kind == nkind.N_TFN - || du.kind == nkind.N_TCHAN || du.kind == nkind.N_TTUPLE - || du.kind == nkind.N_TSTRUCT) { + if (du.kind == syntax.nkind.N_TSLICE || du.kind == syntax.nkind.N_TARRAY + || du.kind == syntax.nkind.N_TPTR || du.kind == syntax.nkind.N_TFN + || du.kind == syntax.nkind.N_TCHAN || du.kind == syntax.nkind.N_TTUPLE + || du.kind == syntax.nkind.N_TSTRUCT) { return false; }; *confident = false; @@ -15229,25 +15229,25 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { }; if (isuntypednil(su)) { // nil → ptr/slice/chan/fn/nullable - if (du.kind == nkind.N_TPTR) { return true; }; - if (du.kind == nkind.N_TSLICE) { return true; }; - if (du.kind == nkind.N_TCHAN) { return true; }; - if (du.kind == nkind.N_TFN) { return true; }; + if (du.kind == syntax.nkind.N_TPTR) { return true; }; + if (du.kind == syntax.nkind.N_TSLICE) { return true; }; + if (du.kind == syntax.nkind.N_TCHAN) { return true; }; + if (du.kind == syntax.nkind.N_TFN) { return true; }; // nullable `(*T | void)` — already accepted by typeeqast // when matched whole; nil is OK there too. - if (du.kind == nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { - if (v.kind == nkind.N_TPTR) { return true; }; - if (v.kind == nkind.N_TSLICE) { return true; }; - if (v.kind == nkind.N_TCHAN) { return true; }; - if (v.kind == nkind.N_TFN) { return true; }; + if (v.kind == syntax.nkind.N_TPTR) { return true; }; + if (v.kind == syntax.nkind.N_TSLICE) { return true; }; + if (v.kind == syntax.nkind.N_TCHAN) { return true; }; + if (v.kind == syntax.nkind.N_TFN) { return true; }; v = v.next; }; // #24: spread variant keeps the lenient escape (cstage flattens; // wwstage can't) — same rationale as the untyped-int arm above. - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { *confident = false; return true; }; @@ -15272,8 +15272,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // harec keeps the drill at types.c:702-739 (#199b deferred port). // Restores SSoT with `is`/`as` non-recursive lookup (#198 sibling). // Callers compose `let inner: Wrapper = sub; let r: parent = inner;`. - if (du.kind == nkind.N_TTAGGED && su.kind != nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED && su.kind != syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { // Spread `...wrapper` keeps the recursive drill: the // wrapper's flat variants are intentionally inlined into @@ -15281,10 +15281,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // expanded yet (cstage flattens at resolve_type; wwstage // stays AST-keyed). Plain wrapper variant gets the // direct-only gate. - let vspread: bool = (v.op == tkind.TK_ELLIPSIS); - let vu: *node = resolvealias(c, unwrapbang(v)); + let vspread: bool = (v.op == syntax.tkind.TK_ELLIPSIS); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); let vtagged: bool = false; - if (vu != nil) { if (vu.kind == nkind.N_TTAGGED) { vtagged = true; }; }; + if (vu != nil) { if (vu.kind == syntax.nkind.N_TTAGGED) { vtagged = true; }; }; if (vtagged && !vspread) { if (typeeqast(c, v, src)) { return true; }; } else { @@ -15341,11 +15341,11 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // qualleaf bridge). Pre-c3 the collision was ALSO accepted (call-arg // ran no check; let/return short-circuited on the scalar variant) — c3 // is NEUTRAL on it. - if (su.kind != nkind.N_TNAME) { + if (su.kind != syntax.nkind.N_TNAME) { let ss: i32 = tagshape(su); - let sp: *node = du.list; + let sp: *syntax.node = du.list; for (sp != nil) { - let svu: *node = resolvealias(c, unwrapbang(sp)); + let svu: *syntax.node = resolvealias(c, unwrapbang(sp)); if (svu != nil) { if (tagshape(svu) == ss) { *confident = false; @@ -15363,7 +15363,7 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // (don't be confident) — common when forwarding a fallible // return through another fn with the same shape but possibly // a different surface spelling. - if (du.kind == nkind.N_TTAGGED && su.kind == nkind.N_TTAGGED) { + if (du.kind == syntax.nkind.N_TTAGGED && su.kind == syntax.nkind.N_TTAGGED) { // #205: NAMED-variant nominal compare BEFORE permissive // fallthrough. Mirror of cstage type.c type_assignable // tagged→tagged arm (#199 α concrete→tagged sibling). @@ -15372,11 +15372,11 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // identity — wrapper's leaves are NOT direct variants of // dst, so a structural subset walk would reject. SSoT // with `is`/`as` variant lookup (#198 family). - let v: *node = du.list; + let v: *syntax.node = du.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { - if (vu.kind == nkind.N_TTAGGED) { + if (vu.kind == syntax.nkind.N_TTAGGED) { if (typeeqast(c, v, src)) { return true; }; }; }; @@ -15390,11 +15390,11 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // spread-widen cstage accepts → new cs≠ww divergence. Spread // decl-form layout is #199b, deferred. let hasspread: bool = false; - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { hasspread = true; }; + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { hasspread = true; }; }; - for (let p: *node = su.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { hasspread = true; }; + for (let p: *syntax.node = su.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { hasspread = true; }; }; if (hasspread) { *confident = false; @@ -15419,15 +15419,15 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // gap. Sound for the bootstrap — no two of its variants share a leaf // (drew); the cross-module same-leaf collision (a.foo vs b.foo) is a // known over-accept deferred to #10 / filed in the #4 census. - for (let sp: *node = su.list; sp != nil; sp = sp.next) { + for (let sp: *syntax.node = su.list; sp != nil; sp = sp.next) { let ok: bool = false; - for (let dp: *node = du.list; dp != nil; dp = dp.next) { + for (let dp: *syntax.node = du.list; dp != nil; dp = dp.next) { if (typeeqast(c, dp, sp)) { ok = true; break; }; - let su2: *node = unwrapbang(sp); - let du2: *node = unwrapbang(dp); + let su2: *syntax.node = unwrapbang(sp); + let du2: *syntax.node = unwrapbang(dp); if (su2 != nil && du2 != nil && - su2.kind == nkind.N_TNAME && du2.kind == nkind.N_TNAME && - streq(qualleaf(su2.str), qualleaf(du2.str))) { + su2.kind == syntax.nkind.N_TNAME && du2.kind == syntax.nkind.N_TNAME && + syntax.streq(qualleaf(su2.str), qualleaf(du2.str))) { ok = true; break; }; }; @@ -15438,18 +15438,18 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // tagged → non-tagged: requires `?` / `!` / match to project a // variant. #31: this is what traps `let p: *T = alloc(v);` // where the builtin returns `(*T | nomem)` and the LHS is bare. - if (su.kind == nkind.N_TTAGGED && du.kind != nkind.N_TTAGGED) { + if (su.kind == syntax.nkind.N_TTAGGED && du.kind != syntax.nkind.N_TTAGGED) { return false; }; // Two known primitives with different names are confidently // incompatible. `i32 ↔ bool`, `str ↔ i32`, etc. - if (du.kind == nkind.N_TNAME && su.kind == nkind.N_TNAME) { + if (du.kind == syntax.nkind.N_TNAME && su.kind == syntax.nkind.N_TNAME) { let known_d: bool = isnumerictname(du) || isstrtname(du); - if (!known_d) { if (streq(du.str, "bool")) { known_d = true; }; }; - if (!known_d) { if (streq(du.str, "void")) { known_d = true; }; }; + if (!known_d) { if (syntax.streq(du.str, "bool")) { known_d = true; }; }; + if (!known_d) { if (syntax.streq(du.str, "void")) { known_d = true; }; }; let known_s: bool = isnumerictname(su) || isstrtname(su); - if (!known_s) { if (streq(su.str, "bool")) { known_s = true; }; }; - if (!known_s) { if (streq(su.str, "void")) { known_s = true; }; }; + if (!known_s) { if (syntax.streq(su.str, "bool")) { known_s = true; }; }; + if (!known_s) { if (syntax.streq(su.str, "void")) { known_s = true; }; }; if (known_d) { if (known_s) { // Both primitives, different names → no. @@ -15467,14 +15467,14 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // handled at the assignment caller sites via assignableaddrfn, NOT // here. Without this the lenient catch-all below silently accepted // the laundering shape. - if (du.kind == nkind.N_TPTR) { - if (su.kind == nkind.N_TPTR) { - let dref: *node = resolvealias(c, unwrapbang(du.lhs)); - let sref: *node = resolvealias(c, unwrapbang(su.lhs)); + if (du.kind == syntax.nkind.N_TPTR) { + if (su.kind == syntax.nkind.N_TPTR) { + let dref: *syntax.node = resolvealias(c, unwrapbang(du.lhs)); + let sref: *syntax.node = resolvealias(c, unwrapbang(su.lhs)); if (dref != nil) { if (sref != nil) { - if (dref.kind == nkind.N_TFN) { - if (sref.kind == nkind.N_TFN) { + if (dref.kind == syntax.nkind.N_TFN) { + if (sref.kind == syntax.nkind.N_TFN) { return false; }; }; @@ -15492,8 +15492,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // The matched-sig case already returned true via typeeqast at the top. // The `&fn` (*fn) vs bare-fn KIND mismatch (du N_TFN, su N_TPTR) is a // different shape, closed by c3's aggregate-kind reject, not here. - if (du.kind == nkind.N_TFN) { - if (su.kind == nkind.N_TFN) { + if (du.kind == syntax.nkind.N_TFN) { + if (su.kind == syntax.nkind.N_TFN) { return false; }; }; @@ -15515,20 +15515,20 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // rejects via structural type_assignable, a filed residual under-reject, // NOT a new over-reject. A NAMED struct/alias dst that does NOT resolve // to a known kind stays N_TNAME-non-prim → neither set → lenient. - let dprim: bool = du.kind == nkind.N_TNAME + let dprim: bool = du.kind == syntax.nkind.N_TNAME && (isnumerictname(du) || isstrtname(du) - || streq(du.str, "bool") || streq(du.str, "void")); - let sprim: bool = su.kind == nkind.N_TNAME + || syntax.streq(du.str, "bool") || syntax.streq(du.str, "void")); + let sprim: bool = su.kind == syntax.nkind.N_TNAME && (isnumerictname(su) || isstrtname(su) - || streq(su.str, "bool") || streq(su.str, "void")); - let daggr: bool = du.kind == nkind.N_TSLICE || du.kind == nkind.N_TARRAY - || du.kind == nkind.N_TPTR || du.kind == nkind.N_TFN - || du.kind == nkind.N_TCHAN || du.kind == nkind.N_TTUPLE - || du.kind == nkind.N_TSTRUCT; - let saggr: bool = su.kind == nkind.N_TSLICE || su.kind == nkind.N_TARRAY - || su.kind == nkind.N_TPTR || su.kind == nkind.N_TFN - || su.kind == nkind.N_TCHAN || su.kind == nkind.N_TTUPLE - || su.kind == nkind.N_TSTRUCT; + || syntax.streq(su.str, "bool") || syntax.streq(su.str, "void")); + let daggr: bool = du.kind == syntax.nkind.N_TSLICE || du.kind == syntax.nkind.N_TARRAY + || du.kind == syntax.nkind.N_TPTR || du.kind == syntax.nkind.N_TFN + || du.kind == syntax.nkind.N_TCHAN || du.kind == syntax.nkind.N_TTUPLE + || du.kind == syntax.nkind.N_TSTRUCT; + let saggr: bool = su.kind == syntax.nkind.N_TSLICE || su.kind == syntax.nkind.N_TARRAY + || su.kind == syntax.nkind.N_TPTR || su.kind == syntax.nkind.N_TFN + || su.kind == syntax.nkind.N_TCHAN || su.kind == syntax.nkind.N_TTUPLE + || su.kind == syntax.nkind.N_TSTRUCT; if (sprim && daggr) { return false; }; if (dprim && saggr) { return false; }; // #24: two aggregates of DIFFERENT kinds → confident reject (array/slice @@ -15542,7 +15542,7 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // principle as the concrete→tagged aggregate-lenient arm above; the // struct-into-ptr genuine mismatch stays a filed #224/#10 under-reject. if (daggr && saggr && du.kind != su.kind - && du.kind != nkind.N_TSTRUCT && su.kind != nkind.N_TSTRUCT) { + && du.kind != syntax.nkind.N_TSTRUCT && su.kind != syntax.nkind.N_TSTRUCT) { return false; }; // Anything else: don't claim confidence. @@ -15602,15 +15602,15 @@ fn qualmod(nm: str, defmod: str) str = { // precise Type-identity form is #10 (tinfo SSoT). typeeqast handles the // exact-string cases first, so this fires only on the qualified-vs-bare // mix. -fn casevariantpairmatch(v: *node, pat: *node, unionmod: str) bool = { - let vv: *node = unwrapbang(v); - let pp: *node = unwrapbang(pat); +fn casevariantpairmatch(v: *syntax.node, pat: *syntax.node, unionmod: str) bool = { + let vv: *syntax.node = unwrapbang(v); + let pp: *syntax.node = unwrapbang(pat); if (vv == nil) { return false; }; if (pp == nil) { return false; }; - if (vv.kind != nkind.N_TNAME) { return false; }; - if (pp.kind != nkind.N_TNAME) { return false; }; - if (!streq(qualleaf(vv.str), qualleaf(pp.str))) { return false; }; - return streq(qualmod(vv.str, unionmod), qualmod(pp.str, unionmod)); + if (vv.kind != syntax.nkind.N_TNAME) { return false; }; + if (pp.kind != syntax.nkind.N_TNAME) { return false; }; + if (!syntax.streq(qualleaf(vv.str), qualleaf(pp.str))) { return false; }; + return syntax.streq(qualmod(vv.str, unionmod), qualmod(pp.str, unionmod)); }; // taggeddefmod — defining module of the typedecl whose body IS the @@ -15618,29 +15618,29 @@ fn casevariantpairmatch(v: *node, pat: *node, unionmod: str) bool = { // Bare variants in that body are defined here: io.error = // !(errors.error | underread | nomem) (module io) -> "io"; errors.error // -> "errors". Falls back to c.curmod when the chain can't resolve. -fn taggeddefmod(c: *checker, st: *node) str = { +fn taggeddefmod(c: *checker, st: *syntax.node) str = { let defmod: str = c.curmod; - let cur: *node = unwrapbang(st); + let cur: *syntax.node = unwrapbang(st); for (cur != nil) { - if (cur.kind != nkind.N_TNAME) { return defmod; }; - let s: *sym = aliassym(c, cur); + if (cur.kind != syntax.nkind.N_TNAME) { return defmod; }; + let s: *syntax.sym = aliassym(c, cur); if (s == nil) { return defmod; }; if (s.decl == nil) { return defmod; }; if (s.decl.nmod.len > 0) { defmod = s.decl.nmod; }; - let body: *node = unwrapbang(s.decl.lhs); + let body: *syntax.node = unwrapbang(s.decl.lhs); if (body == nil) { return defmod; }; - if (body.kind == nkind.N_TTAGGED) { return defmod; }; + if (body.kind == syntax.nkind.N_TTAGGED) { return defmod; }; cur = body; }; return defmod; }; -fn casecovers(c: *checker, cs: *node, want: *node, unionmod: str) bool = { +fn casecovers(c: *checker, cs: *syntax.node, want: *syntax.node, unionmod: str) bool = { if (cs.lhs != nil) { if (typeeqast(c, cs.lhs, want)) { return true; }; if (casevariantpairmatch(want, cs.lhs, unionmod)) { return true; }; }; - let alt: *node = cs.list; + let alt: *syntax.node = cs.list; for (alt != nil) { if (typeeqast(c, alt, want)) { return true; }; if (casevariantpairmatch(want, alt, unionmod)) { return true; }; @@ -15649,10 +15649,10 @@ fn casecovers(c: *checker, cs: *node, want: *node, unionmod: str) bool = { return false; }; -fn errmatchvariant(c: *checker, n: *node, vname: *node) void = { +fn errmatchvariant(c: *checker, n: *syntax.node, vname: *syntax.node) void = { cerr("match: variant not handled"); if (vname != nil) { - if (vname.kind == nkind.N_TNAME) { + if (vname.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(vname.str); cerr(")"); @@ -15673,13 +15673,13 @@ fn errmatchvariant(c: *checker, n: *node, vname: *node) void = { // attributing them the inner union's defining module. Mirrors cstage's // resolve_type flatten (cmd/wcc/check.c:651-674) at the AST layer; the // cgen side already dispatches off the flattened tinfo.params (#61a). -fn casevariantin(c: *checker, tagged: *node, pat: *node, unionmod: str) bool = { - let v: *node = tagged.list; +fn casevariantin(c: *checker, tagged: *syntax.node, pat: *syntax.node, unionmod: str) bool = { + let v: *syntax.node = tagged.list; for (v != nil) { - if (v.op == tkind.TK_ELLIPSIS) { - let inner: *node = resolvealias(c, unwrapbang(v)); + if (v.op == syntax.tkind.TK_ELLIPSIS) { + let inner: *syntax.node = resolvealias(c, unwrapbang(v)); if (inner != nil) { - if (inner.kind == nkind.N_TTAGGED) { + if (inner.kind == syntax.nkind.N_TTAGGED) { if (casevariantin(c, inner, pat, taggeddefmod(c, v))) { return true; @@ -15696,10 +15696,10 @@ fn casevariantin(c: *checker, tagged: *node, pat: *node, unionmod: str) bool = { return false; }; -fn errbadcase(c: *checker, pat: *node) void = { +fn errbadcase(c: *checker, pat: *syntax.node) void = { cerr("case: not a variant of scrutinee"); if (pat != nil) { - if (pat.kind == nkind.N_TNAME) { + if (pat.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(pat.str); cerr(")"); @@ -15709,10 +15709,10 @@ fn errbadcase(c: *checker, pat: *node) void = { c.errs += 1; }; -fn checkmatchexhaust(c: *checker, n: *node) void = { +fn checkmatchexhaust(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { return; }; - let st: *node = scruttype(c, n.lhs); + let st: *syntax.node = scruttype(c, n.lhs); // F9 (task #12): direct `match (expr?)` / `match (expr!)` — cstage // types the try-result as the success variant and rejects when it // is not itself a tagged union (check.c "match on non-tagged- @@ -15723,14 +15723,14 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { // normal exhaustiveness walk, matching cstage's accept. let istry: bool = false; if (st == nil) { - if (n.lhs.kind == nkind.N_TRYPROP || n.lhs.kind == nkind.N_TRYUNW) { + if (n.lhs.kind == syntax.nkind.N_TRYPROP || n.lhs.kind == syntax.nkind.N_TRYUNW) { istry = true; st = exprtype(c, n.lhs, nil); }; }; - let u: *node = resolvealias(c, unwrapbang(st)); + let u: *syntax.node = resolvealias(c, unwrapbang(st)); if (u == nil) { return; }; - if (u.kind != nkind.N_TTAGGED) { + if (u.kind != syntax.nkind.N_TTAGGED) { if (istry) { cerr("match on non-tagged-union try-result\n"); c.errs += 1; @@ -15745,13 +15745,13 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { // Validity: every `case T` pattern (and multi-pattern alts) // must name a variant of u. Catches typos and dead arms that // the dispatch would never reach. - let cs0: *node = n.list; + let cs0: *syntax.node = n.list; for (cs0 != nil) { if (cs0.lhs != nil) { if (!casevariantin(c, u, cs0.lhs, unionmod)) { errbadcase(c, cs0.lhs); }; - let alt: *node = cs0.list; + let alt: *syntax.node = cs0.list; for (alt != nil) { if (!casevariantin(c, u, alt, unionmod)) { errbadcase(c, alt); @@ -15762,13 +15762,13 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { cs0 = cs0.next; }; // Default arm absorbs anything; skip exhaustiveness. - let cs: *node = n.list; + let cs: *syntax.node = n.list; for (cs != nil) { if (cs.lhs == nil) { return; }; // default cs = cs.next; }; // For each variant of u, look for a covering case. - let v: *node = u.list; + let v: *syntax.node = u.list; for (v != nil) { checkvariantcovered(c, n, v, unionmod); v = v.next; @@ -15782,13 +15782,13 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { // members are checked instead. Mirrors the casevariantin spread recursion // + cstage's flattened u->params exhaustiveness walk (cmd/wcc/check.c: // 1648-1669). Leaf variants keep their NODE so errmatchvariant names them. -fn checkvariantcovered(c: *checker, n: *node, v: *node, unionmod: str) void = { - if (v.op == tkind.TK_ELLIPSIS) { - let inner: *node = resolvealias(c, unwrapbang(v)); +fn checkvariantcovered(c: *checker, n: *syntax.node, v: *syntax.node, unionmod: str) void = { + if (v.op == syntax.tkind.TK_ELLIPSIS) { + let inner: *syntax.node = resolvealias(c, unwrapbang(v)); if (inner != nil) { - if (inner.kind == nkind.N_TTAGGED) { + if (inner.kind == syntax.nkind.N_TTAGGED) { let im: str = taggeddefmod(c, v); - let m: *node = inner.list; + let m: *syntax.node = inner.list; for (m != nil) { checkvariantcovered(c, n, m, im); m = m.next; @@ -15798,7 +15798,7 @@ fn checkvariantcovered(c: *checker, n: *node, v: *node, unionmod: str) void = { }; }; let covered: bool = false; - let cs2: *node = n.list; + let cs2: *syntax.node = n.list; for (cs2 != nil) { if (casecovers(c, cs2, v, unionmod)) { covered = true; @@ -15818,16 +15818,16 @@ fn checkvariantcovered(c: *checker, n: *node, v: *node, unionmod: str) void = { // (binary ops, complex exprs we don't infer), we stay quiet — full // type inference lives only on the C side. -fn errnotassign(c: *checker, dst: *node, src: *node, where: str) void = { +fn errnotassign(c: *checker, dst: *syntax.node, src: *syntax.node, where: str) void = { cerr(where); cerr(": not assignable"); if (src != nil) { - if (src.kind == nkind.N_TNAME) { + if (src.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(src.str); cerr(" → "); if (dst != nil) { - if (dst.kind == nkind.N_TNAME) { + if (dst.kind == syntax.nkind.N_TNAME) { cerr(dst.str); }; }; @@ -15849,26 +15849,26 @@ fn errnotassign(c: *checker, dst: *node, src: *node, where: str) void = { // the array-variant box is refused. Mirrors the concrete→tagged variant // select in isassignable (:3859) and cstage tagged_array_variant so the // variant chosen here is the one the box would materialize. -fn taggedarrayvariantctor(c: *checker, dst: *node, src: *node) bool = { +fn taggedarrayvariantctor(c: *checker, dst: *syntax.node, src: *syntax.node) bool = { if (dst == nil) { return false; }; if (src == nil) { return false; }; - let du: *node = resolvealias(c, unwrapbang(dst)); - let su: *node = resolvealias(c, unwrapbang(src)); + let du: *syntax.node = resolvealias(c, unwrapbang(dst)); + let su: *syntax.node = resolvealias(c, unwrapbang(src)); if (du == nil) { return false; }; - if (du.kind != nkind.N_TTAGGED) { return false; }; - if (su != nil) { if (su.kind == nkind.N_TTAGGED) { return false; }; }; - let v: *node = du.list; + if (du.kind != syntax.nkind.N_TTAGGED) { return false; }; + if (su != nil) { if (su.kind == syntax.nkind.N_TTAGGED) { return false; }; }; + let v: *syntax.node = du.list; for (v != nil) { - let vspread: bool = (v.op == tkind.TK_ELLIPSIS); - let vu: *node = resolvealias(c, unwrapbang(v)); + let vspread: bool = (v.op == syntax.tkind.TK_ELLIPSIS); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); let vtagged: bool = false; - if (vu != nil) { if (vu.kind == nkind.N_TTAGGED) { vtagged = true; }; }; + if (vu != nil) { if (vu.kind == syntax.nkind.N_TTAGGED) { vtagged = true; }; }; if (vtagged && !vspread) { if (typeeqast(c, v, src)) { return false; }; } else { let innerconf: bool = false; if (isassignable(c, v, src, &innerconf)) { - if (vu != nil) { if (vu.kind == nkind.N_TARRAY) { return true; }; }; + if (vu != nil) { if (vu.kind == syntax.nkind.N_TARRAY) { return true; }; }; return false; }; }; @@ -15887,7 +15887,7 @@ fn taggedarrayvariantctor(c: *checker, dst: *node, src: *node) bool = { // declared type at cgen, so no element-type restamp is needed — #251 // proved coerce_floatlit's restamp shape does NOT transfer (cgen reads // the declared type's element size, not the literal node's stamp). -fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { +fn checkarrlitfits(c: *checker, arrtn: *syntax.node, rhs: *syntax.node) void = { if (arrtn == nil) { return; }; if (rhs == nil) { return; }; // #106: chase a TY_NAMED alias (`type A=[2]int`) to the underlying @@ -15898,8 +15898,8 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // struct/return/call-arg) alias-aware by construction. arrtn = resolvealias(c, unwrapbang(arrtn)); if (arrtn == nil) { return; }; - if (arrtn.kind != nkind.N_TARRAY) { return; }; - if (rhs.kind != nkind.N_ARRLIT) { return; }; + if (arrtn.kind != syntax.nkind.N_TARRAY) { return; }; + if (rhs.kind != syntax.nkind.N_ARRLIT) { return; }; // #71: more elements than the declared [N] passed every per-element // check below and then smashed the frame at cgen (each element is // stored at its natural offset — the overflow clobbered neighbours @@ -15922,11 +15922,11 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // the wwstage twin of cstage's dropped `alen > 0`. if (arrtn.rhs != nil) { let cnt: u64 = 0u64; - let ce: *node = rhs.list; + let ce: *syntax.node = rhs.list; for (ce != nil) { let cskip: bool = false; - if (ce.kind == nkind.N_FIELD) { - if (streq(ce.str, "...")) { cskip = true; }; + if (ce.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(ce.str, "...")) { cskip = true; }; }; if (!cskip) { cnt += 1u64; }; ce = ce.next; @@ -15941,20 +15941,20 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { return; }; }; - let elemtn: *node = arrtn.lhs; - let at: *tinfo = tinfofornode(c, arrtn); - let et: *tinfo = nil; + let elemtn: *syntax.node = arrtn.lhs; + let at: *syntax.tinfo = tinfofornode(c, arrtn); + let et: *syntax.tinfo = nil; if (at != nil) { et = at.sub; }; et = tichase(et); - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { let skip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { skip = true; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { skip = true; }; }; if (!skip) { - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; // #71: a NESTED array-literal element must run the same // count check against the inner [N] — cstage catches the // nested shape through its typed-literal assignability net @@ -15969,9 +15969,9 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // the segv). resolvealias is transitive, so alias spellings // of any depth take the same recursion; a direct N_TARRAY // passes through unchanged. - let eltr: *node = resolvealias(c, elemtn); - if (eltr != nil && eltr.kind == nkind.N_TARRAY - && ev != nil && ev.kind == nkind.N_ARRLIT) { + let eltr: *syntax.node = resolvealias(c, elemtn); + if (eltr != nil && eltr.kind == syntax.nkind.N_TARRAY + && ev != nil && ev.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, eltr, ev); e = e.next; continue; @@ -15979,7 +15979,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { let v: u64 = 0u64; let folded: bool = false; if (et != nil) { - if (typeisint(et)) { + if (syntax.typeisint(et)) { if (ev != nil) { folded = foldintliteral(ev, &v); }; @@ -15993,7 +15993,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { return; }; } else { - let est: *node = exprtype(c, ev, elemtn); + let est: *syntax.node = exprtype(c, ev, elemtn); let conf2: bool = false; if (est != nil) { if (!isassignable(c, elemtn, est, &conf2)) { @@ -16020,7 +16020,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // N_TUPLE) recurses. Shared by checkletassign (let) and // checkretassign (return). Mirrors cstage's element-wise // type_assignable count-reject; no-ops on scalar elements. -fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { +fn checktuplearrfits(c: *checker, ttn: *syntax.node, tup: *syntax.node) void = { if (ttn == nil) { return; }; if (tup == nil) { return; }; // #38/F2 (review item 10): a tuple literal whose arity differs from the @@ -16034,10 +16034,10 @@ fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { // reject a mismatch before the per-element fits walk. Recursion through // this one choke point gates every nesting depth. let dn: u64 = 0u64; - let dc: *node = ttn.list; + let dc: *syntax.node = ttn.list; for (dc != nil) { dn += 1u64; dc = dc.next; }; let vn: u64 = 0u64; - let vc: *node = tup.list; + let vc: *syntax.node = tup.list; for (vc != nil) { vn += 1u64; vc = vc.next; }; if (dn != vn) { cerr("tuple literal has "); @@ -16048,15 +16048,15 @@ fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { c.errs += 1; return; }; - let dt: *node = ttn.list; - let vt: *node = tup.list; + let dt: *syntax.node = ttn.list; + let vt: *syntax.node = tup.list; for (dt != nil && vt != nil) { - if (vt.kind == nkind.N_ARRLIT) { + if (vt.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, dt.lhs, vt); } else { - if (vt.kind == nkind.N_TUPLE) { - let drt: *node = resolvealias(c, unwrapbang(dt.lhs)); - if (drt != nil && drt.kind == nkind.N_TTUPLE) { + if (vt.kind == syntax.nkind.N_TUPLE) { + let drt: *syntax.node = resolvealias(c, unwrapbang(dt.lhs)); + if (drt != nil && drt.kind == syntax.nkind.N_TTUPLE) { checktuplearrfits(c, drt, vt); }; }; @@ -16087,32 +16087,32 @@ fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { // position there is no addressable backing — loud-reject so the gap is a // compile error, not a dangling-ptr miscompile. Both stages reject here // (rule-10, byte-id-trivial: no asm). Full non-let support is #33. -fn rejectarrlitborrow(c: *checker, dsttn: *node, val: *node) bool = { +fn rejectarrlitborrow(c: *checker, dsttn: *syntax.node, val: *syntax.node) bool = { if (val == nil) { return false; }; - if (val.kind != nkind.N_ARRLIT) { return false; }; - let du: *node = resolvealias(c, unwrapbang(dsttn)); + if (val.kind != syntax.nkind.N_ARRLIT) { return false; }; + let du: *syntax.node = resolvealias(c, unwrapbang(dsttn)); if (du == nil) { return false; }; - if (du.kind != nkind.N_TSLICE) { return false; }; + if (du.kind != syntax.nkind.N_TSLICE) { return false; }; let m: str = "array literal cannot borrow as a slice here; bind it to a `let` first\n"; cerr(m); c.errs += 1; return true; }; -fn desugararrayslice(c: *checker, dsttn: *node, srctn: *node, val: *node) *node = { +fn desugararrayslice(c: *checker, dsttn: *syntax.node, srctn: *syntax.node, val: *syntax.node) *syntax.node = { if (dsttn == nil) { return val; }; if (srctn == nil) { return val; }; if (val == nil) { return val; }; - let du: *node = resolvealias(c, unwrapbang(dsttn)); - let su: *node = resolvealias(c, unwrapbang(srctn)); + let du: *syntax.node = resolvealias(c, unwrapbang(dsttn)); + let su: *syntax.node = resolvealias(c, unwrapbang(srctn)); if (du == nil) { return val; }; if (su == nil) { return val; }; - if (du.kind != nkind.N_TSLICE) { return val; }; - if (su.kind != nkind.N_TARRAY) { return val; }; + if (du.kind != syntax.nkind.N_TSLICE) { return val; }; + if (su.kind != syntax.nkind.N_TARRAY) { return val; }; if (!typeeqast(c, du.lhs, su.lhs)) { return val; }; - let sl: *node = newnode(nkind.N_SLICE, val.file, val.line, val.col); + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_SLICE, val.file, val.line, val.col); sl.lhs = val; // sliced base; lo (.rhs) / hi (.cond) nil → 0 : len(arr) - let slt: *node = newnode(nkind.N_TSLICE, "", 0, 0); + let slt: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); slt.lhs = su.lhs; sl.type_ = tinfofornode(c, slt): *void; sl.next = val.next; @@ -16126,28 +16126,28 @@ fn desugararrayslice(c: *checker, dsttn: *node, srctn: *node, val: *node) *node // module-qualified via the SK_USE receiver). nil for builtins / fn-value // callees — they have no declared param list to drive the #258 desugar, // and the selfhost corpus has no array→slice arg there anyway. -fn calleefndecl(c: *checker, callee: *node) *node = { +fn calleefndecl(c: *checker, callee: *syntax.node) *syntax.node = { if (callee == nil) { return nil; }; - if (callee.kind == nkind.N_IDENT) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, callee.str); + if (callee.kind == syntax.nkind.N_IDENT) { + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, callee.str); if (s != nil) { - if (s.skind == skind.SK_FN) { return s.decl; }; + if (s.skind == syntax.skind.SK_FN) { return s.decl; }; }; return nil; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { - let ms: *sym = scopelookupprefer(c.cur, c.curmod, callee.lhs.str); - if (ms != nil && ms.skind != skind.SK_USE) { - let mu: *sym = scopelookupuselocal(ms.scope, callee.lhs.str); + if (callee.lhs.kind == syntax.nkind.N_IDENT) { + let ms: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, callee.lhs.str); + if (ms != nil && ms.skind != syntax.skind.SK_USE) { + let mu: *syntax.sym = syntax.scopelookupuselocal(ms.scope, callee.lhs.str); if (mu != nil) { ms = mu; }; }; if (ms != nil) { - if (ms.skind == skind.SK_USE || ms.use_alias != 0i32) { - let fs: *sym = scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), callee.str); + if (ms.skind == syntax.skind.SK_USE || ms.use_alias != 0i32) { + let fs: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), callee.str); if (fs != nil) { - if (fs.skind == skind.SK_FN) { return fs.decl; }; + if (fs.skind == syntax.skind.SK_FN) { return fs.decl; }; }; }; }; @@ -16162,7 +16162,7 @@ fn calleefndecl(c: *checker, callee: *node) *node = { // passed where a []T param is expected. Mirrors cstage cmd/wcc/check.c's // non-variadic call-arg arm. Variadic (`T...`) slots are skipped (the // arg flows into the gather as an element, not the slice itself). -fn desugarcallargs(c: *checker, n: *node) void = { +fn desugarcallargs(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; // #24: a 1-arg `free(x)` is the Hare no-op pseudo-builtin (#27), NOT the // rt 2-arg `free(p: *void, n: u64)` that calleefndecl resolves to in the @@ -16174,12 +16174,12 @@ fn desugarcallargs(c: *checker, n: *node) void = { // `free(slice)` (regex finish #27) isn't checked against rt_free's *void // param. `free` is the only builtin name with a colliding real decl // (len/alloc/append/delete/insert keep nil decls → calleefndecl bails). - if (n.lhs != nil) { if (n.lhs.kind == nkind.N_IDENT) { - if (streq(n.lhs.str, "free")) { + if (n.lhs != nil) { if (n.lhs.kind == syntax.nkind.N_IDENT) { + if (syntax.streq(n.lhs.str, "free")) { if (n.list != nil) { if (n.list.next == nil) { return; }; }; }; }; }; - let decl: *node = calleefndecl(c, n.lhs); + let decl: *syntax.node = calleefndecl(c, n.lhs); // task #51: calleefndecl nils every fn-VALUE callee — a deref `(*fp)(...)` // (N_UN), an SK_VAR fn-ptr ident, a struct-field fn call — so this bail // skips the #258 array→slice desugar AND the general arg typecheck for @@ -16188,22 +16188,22 @@ fn desugarcallargs(c: *checker, n: *node) void = { // (cmd/wcc/check.c:1828 type_chase_named(cexpr(callee))). The type-keyed // callee path is MECHANISM (not a checker gate) — filed as task #51. if (decl == nil) { return; }; - let param: *node = decl.list; - let prev: *node = nil; - let a: *node = n.list; + let param: *syntax.node = decl.list; + let prev: *syntax.node = nil; + let a: *syntax.node = n.list; for (a != nil) { - let nexta: *node = a.next; + let nexta: *syntax.node = a.next; if (param != nil) { - if (param.kind == nkind.N_PARAM) { - if (param.op != tkind.TK_ELLIPSIS) { - let atype: *node = exprtype(c, a, nil); + if (param.kind == syntax.nkind.N_PARAM) { + if (param.op != syntax.tkind.TK_ELLIPSIS) { + let atype: *syntax.node = exprtype(c, a, nil); // #29: a rune literal narrowing into an integer param // (`take('b')` where take(b: u8)). Override atype to the // integer target so c3's general isassignable accepts, // mirroring cstage's coarse untyped_rune rule. See // coercerunelit. cgen is byte-id-neutral (narrows by the // param/destination width). - let runet: *node = coercerunelit(c, a, param.lhs); + let runet: *syntax.node = coercerunelit(c, a, param.lhs); if (runet != nil) { atype = runet; }; // #24: GENERAL per-arg assignability — align UP to // cstage check.c:1867-1870, which type_assignables @@ -16229,20 +16229,20 @@ fn desugarcallargs(c: *checker, n: *node) void = { // of falling to cgen #271's late aggregate-arg loud. // param.lhs is the declared param type (alias-aware // via the resolvealias chase in checkarrlitfits). - if (a.kind == nkind.N_ARRLIT) { + if (a.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, param.lhs, a); }; // #31/#33: bare array-literal arg has no backing // — loud-reject (supported only at a `let`). if (!rejectarrlitborrow(c, param.lhs, a)) { - let rep: *node = desugararrayslice(c, param.lhs, atype, a); + let rep: *syntax.node = desugararrayslice(c, param.lhs, atype, a); if (rep != a) { if (prev == nil) { n.list = rep; } else { prev.next = rep; }; a = rep; }; }; }; - if (param.op != tkind.TK_ELLIPSIS) { param = param.next; }; + if (param.op != syntax.tkind.TK_ELLIPSIS) { param = param.next; }; }; }; prev = a; @@ -16255,7 +16255,7 @@ fn desugarcallargs(c: *checker, n: *node) void = { // route an array→slice rhs through the shared desugar so w6c_ww emits // the same borrow as w6c (rule-10). No error diagnostics — cstage gates // the shape. -fn checkassign(c: *checker, n: *node) void = { +fn checkassign(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { return; }; if (n.rhs == nil) { return; }; @@ -16263,9 +16263,9 @@ fn checkassign(c: *checker, n: *node) void = { // is_const bit set at the let-install above). A bare `_` discard // lvalue carries an empty str and is skipped. Mirror cstage // cmd/wcc/check.c:1889-1896. - if (n.lhs.kind == nkind.N_IDENT) { + if (n.lhs.kind == syntax.nkind.N_IDENT) { if (n.lhs.str.len > 0) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, n.lhs.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, n.lhs.str); if (s != nil) { if (s.is_const != 0i32) { cerr("error: cannot assign to const binding\n"); @@ -16274,14 +16274,14 @@ fn checkassign(c: *checker, n: *node) void = { }; }; }; - let ltn: *node = exprtype(c, n.lhs, nil); - let rtn: *node = exprtype(c, n.rhs, nil); + let ltn: *syntax.node = exprtype(c, n.lhs, nil); + let rtn: *syntax.node = exprtype(c, n.rhs, nil); // #29: a rune literal narrowing into an integer assign/index-store // target (`buf[i] = 'F'`). Override rtn to the integer target so a // general assign typecheck accepts, mirroring cstage's coarse // untyped_rune rule. See coercerunelit. cgen narrows by the destination // width (byte-id-neutral). Removes the getopt `'X': u8` index casts. - let runet: *node = coercerunelit(c, n.rhs, ltn); + let runet: *syntax.node = coercerunelit(c, n.rhs, ltn); if (runet != nil) { rtn = runet; }; // #24/#36 (rule-7 deferred-divergence, NEVER silent): the ASSIGN seam // does NOT yet route the general conf-gated UNION (isassignable || @@ -16318,35 +16318,35 @@ fn checkassign(c: *checker, n: *node) void = { // never a silent zero-length array (rule 7). Idempotent (skips once the // length child is set), so the module-level double-call (checkfile's // pre-resolvewalk call + checkletassign here) raises at most one error. -fn inferarraylen(c: *checker, n: *node) void = { +fn inferarraylen(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { return; }; - if (n.lhs.kind != nkind.N_TARRAY) { return; }; + if (n.lhs.kind != syntax.nkind.N_TARRAY) { return; }; if (n.lhs.rhs != nil) { return; }; // explicit [N] or already inferred - if (n.rhs == nil || n.rhs.kind != nkind.N_ARRLIT) { + if (n.rhs == nil || n.rhs.kind != syntax.nkind.N_ARRLIT) { cerr("error: [_]T needs an array-literal initialiser\n"); c.errs += 1; - let z: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let z: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); z.uval = 0u64; n.lhs.rhs = z; // sentinel: idempotent, error already raised return; }; let cnt: u64 = 0u64; - let it: *node = n.rhs.list; + let it: *syntax.node = n.rhs.list; for (it != nil) { let skip: bool = false; - if (it.kind == nkind.N_FIELD) { - if (streq(it.str, "...")) { skip = true; }; + if (it.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(it.str, "...")) { skip = true; }; }; if (!skip) { cnt += 1u64; }; it = it.next; }; - let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let cn: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); cn.uval = cnt; n.lhs.rhs = cn; }; -fn checkletassign(c: *checker, n: *node) void = { +fn checkletassign(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; inferarraylen(c, n); // #7: must run before the n.rhs==nil bail if (n.rhs == nil) { return; }; // no init @@ -16357,34 +16357,34 @@ fn checkletassign(c: *checker, n: *node) void = { // exprtype, so flag the exact call node up front; exprtype errors on // any empty alloc that isn't this one). Peel the same ?/! wrapper #45 // peels so the flagged node matches. - let octx: *node = nil; - if (n.lhs != nil && n.lhs.kind == nkind.N_TSLICE) { - let inner: *node = n.rhs; - if (inner.kind == nkind.N_TRYPROP) { + let octx: *syntax.node = nil; + if (n.lhs != nil && n.lhs.kind == syntax.nkind.N_TSLICE) { + let inner: *syntax.node = n.rhs; + if (inner.kind == syntax.nkind.N_TRYPROP) { inner = inner.lhs; - } else { if (inner.kind == nkind.N_TRYUNW) { + } else { if (inner.kind == syntax.nkind.N_TRYUNW) { inner = inner.lhs; }; }; - if (inner != nil && inner.kind == nkind.N_CALL) { - let callee: *node = inner.lhs; - let a0: *node = inner.list; - let a1: *node = nil; - let a2: *node = nil; + if (inner != nil && inner.kind == syntax.nkind.N_CALL) { + let callee: *syntax.node = inner.lhs; + let a0: *syntax.node = inner.list; + let a1: *syntax.node = nil; + let a2: *syntax.node = nil; if (a0 != nil) { a1 = a0.next; }; if (a1 != nil) { a2 = a1.next; }; if (callee != nil - && callee.kind == nkind.N_IDENT - && streq(callee.str, "alloc") - && a0 != nil && a0.kind == nkind.N_ARRLIT + && callee.kind == syntax.nkind.N_IDENT + && syntax.streq(callee.str, "alloc") + && a0 != nil && a0.kind == syntax.nkind.N_ARRLIT && a0.list == nil && a1 != nil && a2 == nil) { octx = inner; }; }; }; - let savedoctx: *node = c.allococtx; + let savedoctx: *syntax.node = c.allococtx; c.allococtx = octx; - let src: *node = exprtype(c, n.rhs, nil); + let src: *syntax.node = exprtype(c, n.rhs, nil); c.allococtx = savedoctx; // Inferred binding (`let r = expr;`, no type annotation). Mirror // cstage cmd/wcc/check.c:1477 clet `if (t == NULL && initt) t = @@ -16405,10 +16405,10 @@ fn checkletassign(c: *checker, n: *node) void = { // one downstream. cstage needs no twin: check.c:1477 clet carries // Sym.type (tinfo), and its emission is annotation-invariant // (probed identical asm annotated vs not). - if (src != nil && src.kind == nkind.N_TSTRUCT - && n.rhs.kind == nkind.N_STRUCTLIT - && n.rhs.lhs != nil && n.rhs.lhs.kind == nkind.N_IDENT) { - let ltn: *node = mktname(c, n.rhs.lhs.str); + if (src != nil && src.kind == syntax.nkind.N_TSTRUCT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT + && n.rhs.lhs != nil && n.rhs.lhs.kind == syntax.nkind.N_IDENT) { + let ltn: *syntax.node = mktname(c, n.rhs.lhs.str); ltn.type_ = tinfofornode(c, ltn): *void; n.lhs = ltn; return; @@ -16424,44 +16424,44 @@ fn checkletassign(c: *checker, n: *node) void = { // so isassignable sees exact equality. cgenstmt cglet drives the // element size from n.lhs already (cmd/wcc/cgenstmt.ww), so this // stays symmetric with cstage check.c clet's parallel retype. - if (n.lhs.kind == nkind.N_TSLICE) { + if (n.lhs.kind == syntax.nkind.N_TSLICE) { let wrapped: bool = false; - let inner: *node = n.rhs; - if (inner.kind == nkind.N_TRYPROP) { + let inner: *syntax.node = n.rhs; + if (inner.kind == syntax.nkind.N_TRYPROP) { wrapped = true; inner = inner.lhs; - } else { if (inner.kind == nkind.N_TRYUNW) { + } else { if (inner.kind == syntax.nkind.N_TRYUNW) { wrapped = true; inner = inner.lhs; }; }; - if (inner != nil && inner.kind == nkind.N_CALL) { - let callee: *node = inner.lhs; - let a0: *node = inner.list; - let a1: *node = nil; - let a2: *node = nil; + if (inner != nil && inner.kind == syntax.nkind.N_CALL) { + let callee: *syntax.node = inner.lhs; + let a0: *syntax.node = inner.list; + let a1: *syntax.node = nil; + let a2: *syntax.node = nil; if (a0 != nil) { a1 = a0.next; }; if (a1 != nil) { a2 = a1.next; }; if (callee != nil - && callee.kind == nkind.N_IDENT - && streq(callee.str, "alloc") - && a0 != nil && a0.kind == nkind.N_ARRLIT + && callee.kind == syntax.nkind.N_IDENT + && syntax.streq(callee.str, "alloc") + && a0 != nil && a0.kind == syntax.nkind.N_ARRLIT && a0.list == nil && a1 != nil && a2 == nil) { let shadowed: bool = false; if (c.curmod.len > 0) { - if (scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { + if (syntax.scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { shadowed = true; }; }; if (!shadowed) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = n.lhs.lhs; if (wrapped) { src = sl; } else { - let nome: *node = mktname(c, "nomem"); + let nome: *syntax.node = mktname(c, "nomem"); sl.next = nome; - let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTAGGED, "", 0, 0); tt.list = sl; src = tt; }; @@ -16487,8 +16487,8 @@ fn checkletassign(c: *checker, n: *node) void = { // here too so an alias-of-array routes through the same over-fill. A // direct N_TARRAY is unchanged (resolvealias is idempotent), and the // early return matches the direct-array branch's pre-existing return. - let llhs: *node = resolvealias(c, unwrapbang(n.lhs)); - if (llhs != nil && llhs.kind == nkind.N_TARRAY && n.rhs.kind == nkind.N_ARRLIT) { + let llhs: *syntax.node = resolvealias(c, unwrapbang(n.lhs)); + if (llhs != nil && llhs.kind == syntax.nkind.N_TARRAY && n.rhs.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, n.lhs, n.rhs); return; }; @@ -16502,8 +16502,8 @@ fn checkletassign(c: *checker, n: *node) void = { // early return — the rest of checkletassign still runs for the tuple. // N_TTUPLE elements wrap their type on .lhs (N_TPARAM chain, // stamptuplebinds:311); the N_TUPLE rhs values chain directly on .list. - if (llhs != nil && llhs.kind == nkind.N_TTUPLE - && n.rhs.kind == nkind.N_TUPLE) { + if (llhs != nil && llhs.kind == syntax.nkind.N_TTUPLE + && n.rhs.kind == syntax.nkind.N_TUPLE) { checktuplearrfits(c, llhs, n.rhs); }; // #25/#31: an array literal initialising a SLICE local. Re-stamp the @@ -16514,21 +16514,21 @@ fn checkletassign(c: *checker, n: *node) void = { // [count]T), then drive isassignable + the borrow off [count]T. Twin of // cstage arrlit_init_fits' slice arm. Local-only (c.cur != c.top): the // borrow runs at runtime; module-level slice-from-arrlit stays #32. - if (c.cur != c.top && n.lhs.kind == nkind.N_TSLICE - && n.rhs.kind == nkind.N_ARRLIT) { + if (c.cur != c.top && n.lhs.kind == syntax.nkind.N_TSLICE + && n.rhs.kind == syntax.nkind.N_ARRLIT) { let cnt: u64 = 0u64; - let e0: *node = n.rhs.list; + let e0: *syntax.node = n.rhs.list; for (e0 != nil) { let skip: bool = false; - if (e0.kind == nkind.N_FIELD) { - if (streq(e0.str, "...")) { skip = true; }; + if (e0.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e0.str, "...")) { skip = true; }; }; if (!skip) { cnt += 1u64; }; e0 = e0.next; }; - let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let cn: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); cn.uval = cnt; - let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0); + let arr: *syntax.node = syntax.newnode(syntax.nkind.N_TARRAY, "", 0, 0); arr.lhs = n.lhs.lhs; // declared slice element type arr.rhs = cn; checkarrlitfits(c, arr, n.rhs); @@ -16544,7 +16544,7 @@ fn checkletassign(c: *checker, n: *node) void = { // #29: an un-suffixed rune literal narrowing into an integer let target // (`let b: u8 = 'a'`). Override src to the integer target so isassignable // accepts, mirroring cstage's coarse untyped_rune rule. See coercerunelit. - let runet: *node = coercerunelit(c, n.rhs, n.lhs); + let runet: *syntax.node = coercerunelit(c, n.rhs, n.lhs); if (runet != nil) { src = runet; }; let conf: bool = false; let ok: bool = isassignable(c, n.lhs, src, &conf); @@ -16577,7 +16577,7 @@ fn checkletassign(c: *checker, n: *node) void = { }; }; -fn checkretassign(c: *checker, n: *node) void = { +fn checkretassign(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { // bare `return;` — mirror cstage cmd/wcc/check.c:2428-2439: @@ -16588,7 +16588,7 @@ fn checkretassign(c: *checker, n: *node) void = { // reaches the same verdict (void→void typeeqast; void→tagged via // the void variant; void→i32 a confident primitive mismatch). if (c.fnret == nil) { return; }; - let vt: *node = mktname(c, "void"); + let vt: *syntax.node = mktname(c, "void"); let vconf: bool = false; let vok: bool = isassignable(c, c.fnret, vt, &vconf); if (vconf) { if (!vok) { errnotassign(c, c.fnret, vt, "return"); }; }; @@ -16602,7 +16602,7 @@ fn checkretassign(c: *checker, n: *node) void = { // would short-circuit the check (the alias path set conf=true, so neg3 // caught it but the direct neg0 slipped). Alias-aware via the // resolvealias chase at the top of checkarrlitfits. - if (n.lhs.kind == nkind.N_ARRLIT) { + if (n.lhs.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, c.fnret, n.lhs); }; // #25: array-typed element of a TUPLE RETURN with an overlong array @@ -16613,18 +16613,18 @@ fn checkretassign(c: *checker, n: *node) void = { // BEFORE the isassignable/conf guards (a tuple return drives // conf=false → short-circuit), same reason as the #12 array arm // above. Alias/!-aware on the fnret tuple type. - let rrt: *node = resolvealias(c, unwrapbang(c.fnret)); - if (rrt != nil && rrt.kind == nkind.N_TTUPLE - && n.lhs.kind == nkind.N_TUPLE) { + let rrt: *syntax.node = resolvealias(c, unwrapbang(c.fnret)); + if (rrt != nil && rrt.kind == syntax.nkind.N_TTUPLE + && n.lhs.kind == syntax.nkind.N_TUPLE) { checktuplearrfits(c, rrt, n.lhs); }; - let src: *node = exprtype(c, n.lhs, nil); + let src: *syntax.node = exprtype(c, n.lhs, nil); if (src == nil) { return; }; // #29: a rune literal returned into an integer (or integer-variant) // fnret (`return '\\';` into u8 or (u8 | star | ...)). Override src so // isassignable accepts; cgen boxes via the shape fallback. See // coercerunelit. Removes the fnmatch.ww:126 `'\\': u8` workaround cast. - let runet: *node = coercerunelit(c, n.lhs, c.fnret); + let runet: *syntax.node = coercerunelit(c, n.lhs, c.fnret); if (runet != nil) { src = runet; }; let conf: bool = false; let ok: bool = isassignable(c, c.fnret, src, &conf); @@ -16653,10 +16653,10 @@ fn checkretassign(c: *checker, n: *node) void = { // union and that T name one of its variants. Operates on AST type // expressions; falls back silently when we can't determine e's // type (matches the case-variant rule for match). -fn checkisas(c: *checker, n: *node) void = { +fn checkisas(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; // e is in n.lhs (value), T is in n.rhs (type expr). - let st: *node = scruttype(c, n.lhs); + let st: *syntax.node = scruttype(c, n.lhs); // F9 (task #12): direct `expr? is T` / `expr! is T` — cstage cexpr // types the ?/! result as the success variant and the non-tagged // gate below then rejects (check.c "is on non-tagged-union"). @@ -16666,11 +16666,11 @@ fn checkisas(c: *checker, n: *node) void = { // union variant) flows on into the variant checks, matching // cstage's accept. if (st == nil && n.lhs != nil) { - if (n.lhs.kind == nkind.N_TRYPROP || n.lhs.kind == nkind.N_TRYUNW) { + if (n.lhs.kind == syntax.nkind.N_TRYPROP || n.lhs.kind == syntax.nkind.N_TRYUNW) { st = exprtype(c, n.lhs, nil); }; }; - let u: *node = resolvealias(c, unwrapbang(st)); + let u: *syntax.node = resolvealias(c, unwrapbang(st)); if (u == nil) { return; }; // #52: enum ↔ int reinterpret (`enum as intT` / `intT as enum`). // Mirrors cstage cmd/wcc/check.c:1346-1357 — N_TYPEASSERT with an @@ -16680,22 +16680,22 @@ fn checkisas(c: *checker, n: *node) void = { // the lib/os syscall casts stop false-positiving. `is` (TYPETEST) // stays rejected on non-tagged operands — cstage cmd/wcc/check.c // gates the bypass on N_TYPEASSERT only. - if (n.kind == nkind.N_TYPEASSERT) { - let v: *node = resolvealias(c, unwrapbang(n.rhs)); + if (n.kind == syntax.nkind.N_TYPEASSERT) { + let v: *syntax.node = resolvealias(c, unwrapbang(n.rhs)); let lhsenum: bool = false; let rhsenum: bool = false; - if (u != nil) { if (u.kind == nkind.N_TENUM) { lhsenum = true; }; }; - if (v != nil) { if (v.kind == nkind.N_TENUM) { rhsenum = true; }; }; + if (u != nil) { if (u.kind == syntax.nkind.N_TENUM) { lhsenum = true; }; }; + if (v != nil) { if (v.kind == syntax.nkind.N_TENUM) { rhsenum = true; }; }; if (lhsenum || rhsenum) { if (isinttypeast(u)) { if (isinttypeast(v)) { return; }; }; }; }; - if (u.kind != nkind.N_TTAGGED) { + if (u.kind != syntax.nkind.N_TTAGGED) { cerr("is/as: operand is not a tagged union\n"); c.errs += 1; return; }; - let want: *node = n.rhs; + let want: *syntax.node = n.rhs; if (want == nil) { return; }; // #198: route through tinfo.params (the #61a-flattened chain built // at L1789-1845 N_TTAGGED) — the prior AST u.list walk via @@ -16706,8 +16706,8 @@ fn checkisas(c: *checker, n: *node) void = { // keys off at cgenexpr.ww:155). project_tinfo_lossy_nominal: name- // keying was the pre-Phase-N workaround for tinfo lossy on nominal // identity; typeeq inside flatvariantidxt now handles NAMED ptr-id. - let utinfo: *tinfo = tinfofornode(c, u); - let wanttinfo: *tinfo = tinfofornode(c, want); + let utinfo: *syntax.tinfo = tinfofornode(c, u); + let wanttinfo: *syntax.tinfo = tinfofornode(c, want); if (utinfo != nil) { if (wanttinfo != nil) { // exact-only (#95-c3): is/as acceptance is nominal variant // membership; the cgen tag-synthesis chain/structural arms must @@ -16718,7 +16718,7 @@ fn checkisas(c: *checker, n: *node) void = { }; }; if (casevariantin(c, u, want, taggeddefmod(c, st))) { return; }; cerr("is/as: not a variant of operand"); - if (want.kind == nkind.N_TNAME) { + if (want.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(want.str); cerr(")"); @@ -16736,35 +16736,35 @@ fn checkisas(c: *checker, n: *node) void = { // we look at the expr's *declared* type for nkind.N_IDENT/nkind.N_CALL // cases. -fn exprtypeoftry(c: *checker, e: *node) *node = { +fn exprtypeoftry(c: *checker, e: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - if (e.kind == nkind.N_IDENT) { + if (e.kind == syntax.nkind.N_IDENT) { // #11a: curmod preference (the #53/#55 family). A bare ident // whose leaf also names a global in a later module otherwise // binds the foreign decl's type, mis-typing the try operand and // either spuriously rejecting valid `?` code or skipping the F8 // reject. Mirrors exprtype's own N_IDENT arm (scopelookupprefer // at :2897); cstage types the operand via cexpr with cur_mod. - let s: *sym = scopelookupprefer(c.cur, c.curmod, e.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; return s.decl.lhs; }; - if (e.kind == nkind.N_CALL) { + if (e.kind == syntax.nkind.N_CALL) { // callee return type lookup: callee is e.lhs (nkind.N_IDENT or // nkind.N_DOT). We need the fn-decl's lhs (return-type AST). - let callee: *node = e.lhs; + let callee: *syntax.node = e.lhs; if (callee == nil) { return nil; }; let nm: str; nm.ptr = nil; nm.len = 0; - if (callee.kind == nkind.N_IDENT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_IDENT) { nm = callee.str; }; // #11b/task #51: an N_DOT callee `mod.f()?` is looked up by BARE // LEAF here, NOT via the module qualifier (callee.lhs) the way // exprtype's own N_CALL arm does (:3095 scopelookupinmodule) — a // cross-module same-leaf `f` misbinds. The mechanism fix (module- // keyed callee resolution + the deref-callee `(*fp)()?` shape that // returns nil below) rides task #51 with the fn-ptr-callee desugar. - if (callee.kind == nkind.N_DOT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_DOT) { nm = callee.str; }; if (nm.len == 0) { return nil; }; // #11a: curmod preference for the bare-leaf callee. A same-leaf // `op()?` declared in a later module otherwise binds the foreign @@ -16773,9 +16773,9 @@ fn exprtypeoftry(c: *checker, e: *node) *node = { // N_CALL arm (scopelookupprefer at :3336). The N_DOT-callee leaf // (callee.str above) still resolves bare-leaf, not via the module // qualifier callee.lhs.str — that module-keyed fix rides task #51. - let s: *sym = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, nm); if (s == nil) { return nil; }; - if (s.skind != skind.SK_FN) { return nil; }; + if (s.skind != syntax.skind.SK_FN) { return nil; }; if (s.decl == nil) { return nil; }; return s.decl.lhs; }; @@ -16799,12 +16799,12 @@ fn exprtypeoftry(c: *checker, e: *node) *node = { // or a spliced member carries the error, so each flattened member routes // through varianterr, matching cstage's per-param iserror. Mirrors the #209 // spread recursion tinfofornode already runs over vu.params (check.ww:2275). -fn trycountvariants(c: *checker, outer: *node, v: *node, nsuccp: *int, +fn trycountvariants(c: *checker, outer: *syntax.node, v: *syntax.node, nsuccp: *int, haserrp: *bool, depth: i32) void = { for (v != nil) { - if (v.op == tkind.TK_ELLIPSIS && depth < 8i32) { - let inner: *node = resolvealias(c, unwrapbang(v)); - if (inner != nil && inner.kind == nkind.N_TTAGGED) { + if (v.op == syntax.tkind.TK_ELLIPSIS && depth < 8i32) { + let inner: *syntax.node = resolvealias(c, unwrapbang(v)); + if (inner != nil && inner.kind == syntax.nkind.N_TTAGGED) { trycountvariants(c, outer, inner.list, nsuccp, haserrp, depth + 1i32); v = v.next; @@ -16817,12 +16817,12 @@ fn trycountvariants(c: *checker, outer: *node, v: *node, nsuccp: *int, }; }; -fn checktryprop(c: *checker, n: *node) void = { +fn checktryprop(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; - let t: *node = exprtypeoftry(c, n.lhs); - let u: *node = resolvealias(c, unwrapbang(t)); + let t: *syntax.node = exprtypeoftry(c, n.lhs); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return; }; - if (u.kind != nkind.N_TTAGGED) { return; }; + if (u.kind != syntax.nkind.N_TTAGGED) { return; }; // F8 interim gate (task #5): try-propagation assumes ONE success // member end-to-end — exprtype collapses to the first non-error // variant and cgen emits a single tag compare, so any OTHER @@ -16837,33 +16837,33 @@ fn checktryprop(c: *checker, n: *node) void = { // multi-success gate counts the spliced members, not the spread alias. trycountvariants(c, u, u.list, &nsucc, &haserr, 0i32); if (nsucc > 1) { - if (n.kind == nkind.N_TRYPROP) { cerr("?"); } else { cerr("!"); }; + if (n.kind == syntax.nkind.N_TRYPROP) { cerr("?"); } else { cerr("!"); }; cerr(": multi-success union unwired (task #14): bind and match instead\n"); c.errs += 1; return; }; // `!` has no propagation, so no error-subset check (mirrors // cstage's N_TRYPROP-only guard on the subset walk). - if (n.kind != nkind.N_TRYPROP) { return; }; + if (n.kind != syntax.nkind.N_TRYPROP) { return; }; if (!haserr) { return; }; // Enclosing fn must return a tagged union with each operand // error variant present. - let r: *node = resolvealias(c, unwrapbang(c.fnret)); + let r: *syntax.node = resolvealias(c, unwrapbang(c.fnret)); if (r == nil) { cerr("?: enclosing fn has no tagged-union return\n"); c.errs += 1; return; }; - if (r.kind != nkind.N_TTAGGED) { + if (r.kind != syntax.nkind.N_TTAGGED) { cerr("?: enclosing fn return is not tagged\n"); c.errs += 1; return; }; - let ev: *node = u.list; + let ev: *syntax.node = u.list; for (ev != nil) { if (iserrvariant(c, u, ev)) { let found: bool = false; - let rv: *node = r.list; + let rv: *syntax.node = r.list; for (rv != nil) { if (typeeqast(c, rv, ev)) { found = true; @@ -16889,10 +16889,10 @@ fn checktryprop(c: *checker, n: *node) void = { // into w6c_ww so the diagnostic class lands as a single coordinated // step rather than dribbling in. Matches the cstage-only neg-case // precedent at test/wcc/708 + test/wcc/696. -fn installparams(c: *checker, params: *node) void = { - let p: *node = params; +fn installparams(c: *checker, params: *syntax.node) void = { + let p: *syntax.node = params; for (p != nil) { - if (p.kind == nkind.N_PARAM) { + if (p.kind == syntax.nkind.N_PARAM) { // Hare-style variadic `T...`: normalize p.lhs to []T so // downstream consumers (N_IDENT exprtype lookups via // s.decl.lhs, cgen's variadic-slot synthesis) see the @@ -16900,9 +16900,9 @@ fn installparams(c: *checker, params: *node) void = { // `tp->type = type_slice(c->a, pt)` and harec // check_func_type. Surface-fidelity preserved: wwdump // -a runs parser only and never reaches this mutation. - if (p.op == tkind.TK_ELLIPSIS) { - if (p.lhs != nil && p.lhs.kind != nkind.N_TSLICE) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + if (p.op == syntax.tkind.TK_ELLIPSIS) { + if (p.lhs != nil && p.lhs.kind != syntax.nkind.N_TSLICE) { + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = p.lhs; p.lhs = sl; }; @@ -16910,7 +16910,7 @@ fn installparams(c: *checker, params: *node) void = { let nm: str = p.str; if (nm.len > 0) { checkmoduleshadow(c, nm, "param"); - scopedefine(c.cur, nm, skind.SK_PARAM, nil, p); + syntax.scopedefine(c.cur, nm, syntax.skind.SK_PARAM, nil, p); }; }; p = p.next; @@ -16921,22 +16921,22 @@ fn installparams(c: *checker, params: *node) void = { // then walk the body. Local lets installed by walk_stmt (a future // extension); for the current pass we just resolve-walk without // per-statement scopes. -fn resolvefnbody(c: *checker, fnnode: *node) void = { - let outer: *scope = c.cur; - c.cur = newscope(c.cur); +fn resolvefnbody(c: *checker, fnnode: *syntax.node) void = { + let outer: *syntax.scope = c.cur; + c.cur = syntax.newscope(c.cur); installparams(c, fnnode.list); // #61 audit §1.8 — A.2: walk each param's declared type-expr so // tinfofornode stamps n.type_ on it. installparams binds the name // but never recurses into the type; without this, cgen's slotsize // fast-path hits the fallback for every param load/store. - let p: *node = fnnode.list; + let p: *syntax.node = fnnode.list; for (p != nil) { - if (p.kind == nkind.N_PARAM) { + if (p.kind == syntax.nkind.N_PARAM) { if (p.lhs != nil) { resolvewalk(c, p.lhs); }; }; p = p.next; }; - let prevret: *node = c.fnret; + let prevret: *syntax.node = c.fnret; c.fnret = fnnode.lhs; // return type AST, used by `?` check if (fnnode.body != nil) { resolvewalk(c, fnnode.body); @@ -16954,13 +16954,13 @@ fn resolvefnbody(c: *checker, fnnode: *node) void = { // callee carry no type by design. Recognized exactly as the cstage // builtin intercept (cmd/wcc/check.c:1314,1328): the reserved name // with no shadowing user symbol. -fn isassertfam(c: *checker, id: *node) bool = { +fn isassertfam(c: *checker, id: *syntax.node) bool = { if (id == nil) { return false; }; - if (id.kind != nkind.N_IDENT) { return false; }; - if (!streq(id.str, "abort") && !streq(id.str, "assert")) { + if (id.kind != syntax.nkind.N_IDENT) { return false; }; + if (!syntax.streq(id.str, "abort") && !syntax.streq(id.str, "assert")) { return false; }; - return scopelookupprefer(c.cur, c.curmod, id.str) == nil; + return syntax.scopelookupprefer(c.cur, c.curmod, id.str) == nil; }; // asserttyped — post-checker invariant gate (#15, A.6.2.1e). Walks the @@ -16999,43 +16999,43 @@ fn isassertfam(c: *checker, id: *node) bool = { // // `indot` tracks gate 3: true only when the immediate caller is an // N_DOT recursing into its .lhs. -fn asserttyped(c: *checker, n: *node, indot: bool) void = { +fn asserttyped(c: *checker, n: *syntax.node, indot: bool) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; let isexpr: bool = - k == nkind.N_INTLIT || k == nkind.N_FLOATLIT || - k == nkind.N_STRLIT || k == nkind.N_RUNELIT || - k == nkind.N_TRUE || k == nkind.N_FALSE || - k == nkind.N_NIL || k == nkind.N_VOIDLIT || - k == nkind.N_IDENT || k == nkind.N_BIN || - k == nkind.N_UN || k == nkind.N_CALL || - k == nkind.N_INDEX || k == nkind.N_CAST || - k == nkind.N_STRUCTLIT || k == nkind.N_ARRLIT || - k == nkind.N_RECV || k == nkind.N_DOT || - k == nkind.N_SLICE || k == nkind.N_SPREAD || - k == nkind.N_TUPLE || k == nkind.N_TRYPROP || - k == nkind.N_TRYUNW || k == nkind.N_TYPETEST || - k == nkind.N_TYPEASSERT || k == nkind.N_YIELD || - k == nkind.N_MATCH; + k == syntax.nkind.N_INTLIT || k == syntax.nkind.N_FLOATLIT || + k == syntax.nkind.N_STRLIT || k == syntax.nkind.N_RUNELIT || + k == syntax.nkind.N_TRUE || k == syntax.nkind.N_FALSE || + k == syntax.nkind.N_NIL || k == syntax.nkind.N_VOIDLIT || + k == syntax.nkind.N_IDENT || k == syntax.nkind.N_BIN || + k == syntax.nkind.N_UN || k == syntax.nkind.N_CALL || + k == syntax.nkind.N_INDEX || k == syntax.nkind.N_CAST || + k == syntax.nkind.N_STRUCTLIT || k == syntax.nkind.N_ARRLIT || + k == syntax.nkind.N_RECV || k == syntax.nkind.N_DOT || + k == syntax.nkind.N_SLICE || k == syntax.nkind.N_SPREAD || + k == syntax.nkind.N_TUPLE || k == syntax.nkind.N_TRYPROP || + k == syntax.nkind.N_TRYUNW || k == syntax.nkind.N_TYPETEST || + k == syntax.nkind.N_TYPEASSERT || k == syntax.nkind.N_YIELD || + k == syntax.nkind.N_MATCH; let skip: bool = false; - if (isexpr && k == nkind.N_IDENT) { + if (isexpr && k == syntax.nkind.N_IDENT) { if (indot) { skip = true; }; if (!skip) { - let s: *sym = scopelookup(c.cur, n.str); + let s: *syntax.sym = syntax.scopelookup(c.cur, n.str); if (s != nil) { - if (s.skind == skind.SK_USE) { skip = true; }; + if (s.skind == syntax.skind.SK_USE) { skip = true; }; if (s.decl == nil) { skip = true; }; }; }; if (!skip) { if (isassertfam(c, n)) { skip = true; }; }; }; - if (isexpr && k == nkind.N_CALL) { + if (isexpr && k == syntax.nkind.N_CALL) { if (isassertfam(c, n.lhs)) { skip = true; }; }; if (isexpr && !skip) { if (n.type_ == nil) { cerr("asserttyped: "); - let kn: str = nkname(k); + let kn: str = syntax.nkname(k); cerr(kn); cerr(" "); if (n.file.len > 0) { @@ -17053,7 +17053,7 @@ fn asserttyped(c: *checker, n: *node, indot: bool) void = { os.exit(1); }; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { if (n.lhs != nil) { asserttyped(c, n.lhs, true); }; return; }; @@ -17063,16 +17063,16 @@ fn asserttyped(c: *checker, n: *node, indot: bool) void = { if (n.cond != nil) { asserttyped(c, n.cond, false); }; if (n.body != nil) { asserttyped(c, n.body, false); }; if (n.els != nil) { asserttyped(c, n.els, false); }; - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { asserttyped(c, m, false); m = m.next; }; }; -export fn checkinit(c: *checker, tc: *tctx) void = { +export fn checkinit(c: *checker, tc: *syntax.tctx) void = { c.tc = tc; - c.top = newscope(nil); + c.top = syntax.newscope(nil); c.cur = c.top; c.nresolved = 0; c.nunresolved = 0; @@ -17087,13 +17087,13 @@ export fn checkinit(c: *checker, tc: *tctx) void = { seedprimitives(c); }; -export fn checkfile(c: *checker, file: *node) void = { +export fn checkfile(c: *checker, file: *syntax.node) void = { if (file == nil) { return; }; - if (file.kind != nkind.N_FILE) { return; }; + if (file.kind != syntax.nkind.N_FILE) { return; }; c.file = file; // Pass 1: install all top-level names. - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { installdecl(c, file, d); d = d.next; @@ -17106,12 +17106,12 @@ export fn checkfile(c: *checker, file: *node) void = { // collision by construction (#31). Two ROOT entries still collide on // the bare symbol → reject loud (rule 7). Walks USER decls only — runs // before the -T synth main is appended below. Twin of cmd/wcc/check.c. - let firstmain: *node = nil; - let mm: *node = file.list; + let firstmain: *syntax.node = nil; + let mm: *syntax.node = file.list; for (mm != nil) { - let ismain: bool = (mm.kind == nkind.N_FNDECL - || mm.kind == nkind.N_LET || mm.kind == nkind.N_DEF - || mm.kind == nkind.N_TYPEDECL) && streq(mm.str, "main"); + let ismain: bool = (mm.kind == syntax.nkind.N_FNDECL + || mm.kind == syntax.nkind.N_LET || mm.kind == syntax.nkind.N_DEF + || mm.kind == syntax.nkind.N_TYPEDECL) && syntax.streq(mm.str, "main"); if (ismain && mm.imported == 0) { if (firstmain == nil) { firstmain = mm; @@ -17153,10 +17153,10 @@ export fn checkfile(c: *checker, file: *node) void = { let pl: i32 = file.line; let pc: i32 = file.col; // (b) the synth entry OWNS `main` — loud-reject a user one. - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { - if (u.kind == nkind.N_FNDECL && u.body != nil - && streq(u.str, "main")) { + if (u.kind == syntax.nkind.N_FNDECL && u.body != nil + && syntax.streq(u.str, "main")) { cerr(u.file); cerr(": error: test mode: main is synthesized by -T; remove the explicit main\n"); c.errs += 1; @@ -17169,7 +17169,7 @@ export fn checkfile(c: *checker, file: *node) void = { // so the synth `run(__wwtests)` iterates the user's table, not // the collected @tests — reserve the NAME so the collision is // loud regardless of type. Any decl kind (const/let/fn). - if (streq(u.str, "__wwtests")) { + if (syntax.streq(u.str, "__wwtests")) { cerr(u.file); cerr(": error: test mode: __wwtests is reserved by -T; rename the declaration\n"); c.errs += 1; @@ -17178,17 +17178,17 @@ export fn checkfile(c: *checker, file: *node) void = { }; // (c) collect @test fns in file.list order; build one table row // `("", &)` per validated @test fn. - let rhead: *node = nil; - let rtail: *node = nil; + let rhead: *syntax.node = nil; + let rtail: *syntax.node = nil; let ntest: i32 = 0; - let t: *node = file.list; + let t: *syntax.node = file.list; for (t != nil) { - if (t.kind == nkind.N_FNDECL) { + if (t.kind == syntax.nkind.N_FNDECL) { let istest: bool = false; - let at: *node = t.attr; + let at: *syntax.node = t.attr; for (at != nil) { - if (at.kind == nkind.N_ATTR - && streq(at.str, "test")) { + if (at.kind == syntax.nkind.N_ATTR + && syntax.streq(at.str, "test")) { istest = true; }; at = at.next; @@ -17198,8 +17198,8 @@ export fn checkfile(c: *checker, file: *node) void = { // into t.lhs, so void-returning is lhs==nil // OR an N_TNAME "void". let retvoid: bool = t.lhs == nil - || (t.lhs.kind == nkind.N_TNAME - && streq(t.lhs.str, "void")); + || (t.lhs.kind == syntax.nkind.N_TNAME + && syntax.streq(t.lhs.str, "void")); if (t.list != nil || !retvoid) { cerr(t.file); cerr(": error: @test fn '"); @@ -17207,14 +17207,14 @@ export fn checkfile(c: *checker, file: *node) void = { cerr("' must be fn() void\n"); c.errs += 1; } else { - let nm: *node = newnode(nkind.N_STRLIT, pf, pl, pc); + let nm: *syntax.node = syntax.newnode(syntax.nkind.N_STRLIT, pf, pl, pc); nm.str = t.str; - let id: *node = newnode(nkind.N_IDENT, pf, pl, pc); + let id: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc); id.str = t.str; - let amp: *node = newnode(nkind.N_UN, pf, pl, pc); - amp.op = tkind.TK_AMP; + let amp: *syntax.node = syntax.newnode(syntax.nkind.N_UN, pf, pl, pc); + amp.op = syntax.tkind.TK_AMP; amp.lhs = id; - let row: *node = newnode(nkind.N_TUPLE, pf, pl, pc); + let row: *syntax.node = syntax.newnode(syntax.nkind.N_TUPLE, pf, pl, pc); row.list = nm; nm.next = amp; if (rhead == nil) { rhead = row; } @@ -17227,39 +17227,39 @@ export fn checkfile(c: *checker, file: *node) void = { t = t.next; }; - let body: *node = newnode(nkind.N_BLOCK, pf, pl, pc); - let tab: *node = nil; + let body: *syntax.node = syntax.newnode(syntax.nkind.N_BLOCK, pf, pl, pc); + let tab: *syntax.node = nil; if (ntest == 0i32) { // no @test fns in this unit — exit 0, nothing to run. - let ret: *node = newnode(nkind.N_RETURN, pf, pl, pc); - let zero: *node = newnode(nkind.N_INTLIT, pf, pl, pc); + let ret: *syntax.node = syntax.newnode(syntax.nkind.N_RETURN, pf, pl, pc); + let zero: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, pf, pl, pc); zero.uval = 0u64; ret.lhs = zero; body.list = ret; } else { // const __wwtests: [](str, *fn() void) = [rows...]; // wwstage tuple-type elements wrap in N_TPARAM (parse.ww:308). - let e0: *node = newnode(nkind.N_TNAME, pf, pl, pc); + let e0: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, pf, pl, pc); e0.str = "str"; - let p0: *node = newnode(nkind.N_TPARAM, pf, pl, pc); + let p0: *syntax.node = syntax.newnode(syntax.nkind.N_TPARAM, pf, pl, pc); p0.lhs = e0; - let vret: *node = newnode(nkind.N_TNAME, pf, pl, pc); + let vret: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, pf, pl, pc); vret.str = "void"; - let vfn: *node = newnode(nkind.N_TFN, pf, pl, pc); + let vfn: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, pf, pl, pc); vfn.lhs = vret; - let e1: *node = newnode(nkind.N_TPTR, pf, pl, pc); + let e1: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, pf, pl, pc); e1.lhs = vfn; - let p1: *node = newnode(nkind.N_TPARAM, pf, pl, pc); + let p1: *syntax.node = syntax.newnode(syntax.nkind.N_TPARAM, pf, pl, pc); p1.lhs = e1; - let tup: *node = newnode(nkind.N_TTUPLE, pf, pl, pc); + let tup: *syntax.node = syntax.newnode(syntax.nkind.N_TTUPLE, pf, pl, pc); tup.list = p0; p0.next = p1; - let tsl: *node = newnode(nkind.N_TSLICE, pf, pl, pc); + let tsl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, pf, pl, pc); tsl.lhs = tup; - let arr: *node = newnode(nkind.N_ARRLIT, pf, pl, pc); + let arr: *syntax.node = syntax.newnode(syntax.nkind.N_ARRLIT, pf, pl, pc); arr.list = rhead; - tab = newnode(nkind.N_LET, pf, pl, pc); - tab.op = tkind.TK_CONST; + tab = syntax.newnode(syntax.nkind.N_LET, pf, pl, pc); + tab.op = syntax.tkind.TK_CONST; tab.str = "__wwtests"; tab.lhs = tsl; tab.rhs = arr; @@ -17270,23 +17270,23 @@ export fn checkfile(c: *checker, file: *node) void = { // duplicate-decl reject (#23) the same way, so a pathological // user `const __wwtests` stays a downstream type error in // both stages rather than a dup-diagnostic in only one. - scopedefineinmodule(c.top, tab.str, "", skind.SK_VAR, nil, tab); + syntax.scopedefineinmodule(c.top, tab.str, "", syntax.skind.SK_VAR, nil, tab); - let arg: *node = newnode(nkind.N_IDENT, pf, pl, pc); + let arg: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc); arg.str = "__wwtests"; - let call: *node = newnode(nkind.N_CALL, pf, pl, pc); - let cid: *node = newnode(nkind.N_IDENT, pf, pl, pc); + let call: *syntax.node = syntax.newnode(syntax.nkind.N_CALL, pf, pl, pc); + let cid: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc); cid.str = "run"; call.lhs = cid; call.list = arg; - let ret: *node = newnode(nkind.N_RETURN, pf, pl, pc); + let ret: *syntax.node = syntax.newnode(syntax.nkind.N_RETURN, pf, pl, pc); ret.lhs = call; body.list = ret; }; - let m: *node = newnode(nkind.N_FNDECL, pf, pl, pc); + let m: *syntax.node = syntax.newnode(syntax.nkind.N_FNDECL, pf, pl, pc); m.str = "main"; m.exported = 1i32; - let rety: *node = newnode(nkind.N_TNAME, pf, pl, pc); + let rety: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, pf, pl, pc); rety.str = "i32"; m.lhs = rety; m.body = body; @@ -17294,7 +17294,7 @@ export fn checkfile(c: *checker, file: *node) void = { // type_ pre-set on main: installdecl never stamps a fn's type_ on // the ww side — cgfn reads lhs/list on demand. Pass-2 below // resolve-walks the appended bodies. - let tl: *node = file.list; + let tl: *syntax.node = file.list; if (tl == nil) { if (tab != nil) { file.list = tab; tab.next = m; } else { file.list = m; }; @@ -17318,12 +17318,12 @@ export fn checkfile(c: *checker, file: *node) void = { // dispatch. Mirror resolvewalk L405 which descends n.attr on // inner nodes. if (d.attr != nil) { resolvewalk(c, d.attr); }; - let k: nkind = d.kind; + let k: syntax.nkind = d.kind; switch (k) { - case nkind.N_FNDECL: + case syntax.nkind.N_FNDECL: if (d.lhs != nil) { resolvewalk(c, d.lhs); }; // return type resolvefnbody(c, d); - case nkind.N_DEF: + case syntax.nkind.N_DEF: // #11: a module-level `def xs: [_]T = arrlit;` must infer // its length BEFORE resolvewalk stamps d.lhs's tinfo, the // def twin of the N_LET arm below. #7 wired only the let @@ -17356,9 +17356,9 @@ export fn checkfile(c: *checker, file: *node) void = { }; }; }; - case nkind.N_TYPEDECL: + case syntax.nkind.N_TYPEDECL: if (d.lhs != nil) { resolvewalk(c, d.lhs); }; - case nkind.N_LET: + case syntax.nkind.N_LET: // #7: a module-level `let xs: [_]T = arrlit;` must infer // its length BEFORE resolvewalk stamps d.lhs's tinfo — // otherwise the array tinfo caches the alen=0 sentinel and @@ -17417,21 +17417,21 @@ export fn checkfile(c: *checker, file: *node) void = { // untouched: its synth main calls the @test fns, so they must remain. // Twin: cmd/wcc/check.c. if (c.istest == 0) { - let prev: *node = nil; - let e: *node = file.list; + let prev: *syntax.node = nil; + let e: *syntax.node = file.list; for (e != nil) { let istest: bool = false; - if (e.kind == nkind.N_FNDECL) { - let at: *node = e.attr; + if (e.kind == syntax.nkind.N_FNDECL) { + let at: *syntax.node = e.attr; for (at != nil) { - if (at.kind == nkind.N_ATTR - && streq(at.str, "test")) { + if (at.kind == syntax.nkind.N_ATTR + && syntax.streq(at.str, "test")) { istest = true; }; at = at.next; }; }; - let nx: *node = e.next; + let nx: *syntax.node = e.next; if (istest) { if (prev == nil) { file.list = nx; } else { prev.next = nx; }; @@ -18256,8 +18256,8 @@ import strconv; // for the param (callee side) and the call-site slice descriptor // (caller side) both advertise their effective type as []ELEM — // every isslicetype / nodeisslice check then succeeds naturally. -fn slicewrap(c: *cgen, elem: *node) *node = { - let s: *node = newnode(nkind.N_TSLICE, "", 0, 0); +fn slicewrap(c: *cgen, elem: *syntax.node) *syntax.node = { + let s: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); s.lhs = elem; return s; }; @@ -18266,12 +18266,12 @@ fn slicewrap(c: *cgen, elem: *node) *node = { // param node (the one with op == TK_ELLIPSIS) plus the count of // non-variadic params before it. Returns nil/0 when no variadic. // nfixed_out cannot be nil. -fn findvariadicparam(ps: *node, nfixed_out: *i32) *node = { +fn findvariadicparam(ps: *syntax.node, nfixed_out: *i32) *syntax.node = { *nfixed_out = 0; - let p: *node = ps; + let p: *syntax.node = ps; for (p != nil) { - if (p.kind == nkind.N_PARAM) { - if (p.op == tkind.TK_ELLIPSIS) { + if (p.kind == syntax.nkind.N_PARAM) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { return p; }; *nfixed_out += 1; @@ -18293,19 +18293,19 @@ fn findvariadicparam(ps: *node, nfixed_out: *i32) *node = { // strings.contains gained a variadic shape and a caller's // bytes.contains call site picked strings.contains' variadic // params for arg-prep while emitting CALL bytes.contains. -fn callee_variadic_param(c: *cgen, callee: *node, nfixed_out: *i32) *node = { +fn callee_variadic_param(c: *cgen, callee: *syntax.node, nfixed_out: *i32) *syntax.node = { *nfixed_out = 0; if (callee == nil) { return nil; }; - let ps: *node = nil; - if (callee.kind == nkind.N_IDENT) { + let ps: *syntax.node = nil; + if (callee.kind == syntax.nkind.N_IDENT) { if (callee.str.len == 0) { return nil; }; ps = fnparamslookup(c, callee.str); - } else { if (callee.kind == nkind.N_DOT) { + } else { if (callee.kind == syntax.nkind.N_DOT) { if (callee.str.len == 0) { return nil; }; let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; @@ -18347,21 +18347,21 @@ fn callee_variadic_param(c: *cgen, callee: *node, nfixed_out: *i32) *node = { // payload word) or the float-source box was misclassified as a float arg // (#48: MOVSD ate the tag word into X0). Mirrors cstage's precomputed // widen[i]/widen_sz[i] (cmd/w6c/cgen.c cgcall). -fn argtaggedwidensz(c: *cgen, arg0: *node, param: *node) i32 = { +fn argtaggedwidensz(c: *cgen, arg0: *syntax.node, param: *syntax.node) i32 = { if (param == nil) { return 0; }; - if (param.kind != nkind.N_PARAM) { return 0; }; - if (param.op == tkind.TK_ELLIPSIS) { return 0; }; - let ptype: *node = param.lhs; + if (param.kind != syntax.nkind.N_PARAM) { return 0; }; + if (param.op == syntax.tkind.TK_ELLIPSIS) { return 0; }; + let ptype: *syntax.node = param.lhs; if (ptype == nil) { return 0; }; if (!istaggedtype(c, ptype)) { return 0; }; // >48B slot is memory-class: pushargsrev stages it below the register // words and the drain skips it (dmemsz) — never a register widen. - if (taggedmemargsize(ptype.type_: *tinfo) > 0) { return 0; }; - let arg: *node = taggedcastpeel(c, arg0); + if (taggedmemargsize(ptype.type_: *syntax.tinfo) > 0) { return 0; }; + let arg: *syntax.node = taggedcastpeel(c, arg0); let pslot: i32 = slotsize(c, ptype); // Already a matching-slot tagged source → natural push, no widen // (mirrors pushargsrev's aistagged gates: ident/call/index/dot/deref). - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, arg.str); if (lc != nil) { if (istaggedtype(c, lc.tnode)) { @@ -18370,13 +18370,13 @@ fn argtaggedwidensz(c: *cgen, arg0: *node, param: *node) i32 = { }; }; if (taggedcallslot(c, arg) == pslot) { return 0; }; - if (arg.kind == nkind.N_INDEX) { + if (arg.kind == syntax.nkind.N_INDEX) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == pslot) { return 0; }; }; }; - if (arg.kind == nkind.N_DOT) { + if (arg.kind == syntax.nkind.N_DOT) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == pslot) { return 0; }; }; }; - if (arg.kind == nkind.N_UN && arg.op == tkind.TK_STAR) { + if (arg.kind == syntax.nkind.N_UN && arg.op == syntax.tkind.TK_STAR) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == pslot) { return 0; }; }; }; // The 8B nullable fold pushes one pointer word the scalar drain path @@ -18386,9 +18386,9 @@ fn argtaggedwidensz(c: *cgen, arg0: *node, param: *node) i32 = { return pslot; }; -fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { +fn pushargsrev(c: *cgen, arg: *syntax.node, param: *syntax.node, memphase: bool) i32 = { if (arg == nil) { return 0; }; - let nextparam: *node = nil; + let nextparam: *syntax.node = nil; if (param != nil) { nextparam = param.next; }; let rest: i32 = pushargsrev(c, arg.next, nextparam, memphase); // Family C (#35): peel tagged→tagged casts FIRST so every gate @@ -18404,33 +18404,33 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // type (so widening into a >48B slot is caught), else the arg's // own stamped type (fn-ptr callee carries no param nodes). let memsz: i32 = 0; - let memptype: *node = nil; - if (param != nil) { if (param.kind == nkind.N_PARAM) { - if (param.op != tkind.TK_ELLIPSIS) { + let memptype: *syntax.node = nil; + if (param != nil) { if (param.kind == syntax.nkind.N_PARAM) { + if (param.op != syntax.tkind.TK_ELLIPSIS) { memptype = param.lhs; if (memptype != nil) { - memsz = taggedmemargsize(memptype.type_: *tinfo); + memsz = taggedmemargsize(memptype.type_: *syntax.tinfo); }; }; }; }; if (memsz == 0) { - memsz = taggedmemargsize(arg.type_: *tinfo); + memsz = taggedmemargsize(arg.type_: *syntax.tinfo); }; if (memphase != (memsz > 0)) { return rest; }; if (memsz > 0) { // same-type check — mirror cstage's `(pu == au) || // type_eq(p->type, at)` widen detection. let same: bool = false; - let at: *tinfo = arg.type_: *tinfo; + let at: *syntax.tinfo = arg.type_: *syntax.tinfo; if (memptype != nil) { - let pt: *tinfo = memptype.type_: *tinfo; - let pu: *tinfo = pt; + let pt: *syntax.tinfo = memptype.type_: *syntax.tinfo; + let pu: *syntax.tinfo = pt; pu = tichase(pu); - let au: *tinfo = at; + let au: *syntax.tinfo = at; au = tichase(au); if (pu != nil && pu == au) { same = true; }; if (!same && pt != nil && at != nil) { - if (typeeq(pt, at)) { same = true; }; + if (syntax.typeeq(pt, at)) { same = true; }; }; } else { same = true; @@ -18450,7 +18450,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, memptype.type_: *tinfo, arg, + cgwidentaggedstore(c, memptype.type_: *syntax.tinfo, arg, "BP", scroff, memsz); let pp: i32 = memsz - 8; for (pp >= 0) { @@ -18469,12 +18469,12 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // return) — its result is in memory behind a dest pointer, // not a register cursor; receive-then-push is the // #40-family follow-up. - if (arg.kind == nkind.N_CALL) { + if (arg.kind == syntax.nkind.N_CALL) { let mc: str = "#38b: sret-class tagged call result as a >48B by-value arg unwired (#40-family follow-up)\n"; os.write(2, mc.ptr, mc.len: u64); os.exit(1); }; - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, arg.str); if (lc != nil) { let w: i32 = memsz / 8 - 1; @@ -18525,20 +18525,20 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { let widensz: i32 = 0; let widentag: i32 = 0; if (param != nil) { - if (param.kind == nkind.N_PARAM) { + if (param.kind == syntax.nkind.N_PARAM) { // Hare-style variadic `T...`: effective param type is // []T (slice). The arg here is the synthesised slice // descriptor (or a forwarded `xs...` slice), not a // value of T being widened into a tagged slot — skip // the widening detection so the slice-ident fast path // at the bottom of pushargsrev gets the push. - if (param.op == tkind.TK_ELLIPSIS) { + if (param.op == syntax.tkind.TK_ELLIPSIS) { widensz = 0; } else { - let ptype: *node = param.lhs; + let ptype: *syntax.node = param.lhs; if (istaggedtype(c, ptype)) { let aistagged: bool = false; - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, arg.str); if (lc != nil) { // #55: only treat a tagged ident as @@ -18582,7 +18582,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // slotsize read .type_, so feed the N_INDEX node // directly. cstage reads the element via // base->type->sub (cmd/w6c/cgen.c:3518). - if (arg.kind == nkind.N_INDEX) { + if (arg.kind == syntax.nkind.N_INDEX) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == slotsize(c, ptype)) { aistagged = true; @@ -18598,7 +18598,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // twin of the N_INDEX arm above; cstage // needs no kind gate (its widen[i] `same` // check is type-keyed on args[i]->type). - if (arg.kind == nkind.N_DOT) { + if (arg.kind == syntax.nkind.N_DOT) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == slotsize(c, ptype)) { aistagged = true; @@ -18611,7 +18611,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // scalar branch boxed the box. Same // slotsize key as the N_INDEX/N_DOT // stamped-carrier arms above. - if (arg.kind == nkind.N_UN && arg.op == tkind.TK_STAR) { + if (arg.kind == syntax.nkind.N_UN && arg.op == syntax.tkind.TK_STAR) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == slotsize(c, ptype)) { aistagged = true; @@ -18620,7 +18620,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { }; if (!aistagged) { widensz = slotsize(c, ptype); - let tagged: *node = resolvetagged(c, ptype); + let tagged: *syntax.node = resolvetagged(c, ptype); let t: i32 = taggedvariantindex(c, tagged, arg); if (t < 0) { t = 0; }; widentag = t; @@ -18648,7 +18648,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // the scratch store, whose #242/#66 tuple arm handles the // literal/cast forms and loud-stops the rest (#72). Mirrors // cstage cg_widen_tagged_push src_is_tuple. - let argtup: *tinfo = arg.type_: *tinfo; + let argtup: *syntax.tinfo = arg.type_: *syntax.tinfo; argtup = tichase(argtup); let argistuple: bool = false; // #55: a tagged SOURCE widened into a wider/reordered tagged param @@ -18662,16 +18662,16 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // routing (cmd/w6c/cgen.c:2982). let argistagged: bool = false; if (argtup != nil) { - if (argtup.kind == tykind.TY_TUPLE) { + if (argtup.kind == syntax.tykind.TY_TUPLE) { argistuple = true; }; - if (argtup.kind == tykind.TY_TAGGED) { + if (argtup.kind == syntax.tykind.TY_TAGGED) { argistagged = true; }; }; let pname: str = rhsstructpayload(c, arg); if (pname.len > 0 || argistuple || argistagged) { - let ptype: *node = param.lhs; + let ptype: *syntax.node = param.lhs; let scroff: i32 = tagscradd(c, widensz); emitline("\tXORQ\tAX, AX\n"); let zz: i32 = 0; @@ -18681,7 +18681,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, ptype.type_: *tinfo, arg, "BP", scroff, widensz); + cgwidentaggedstore(c, ptype.type_: *syntax.tinfo, arg, "BP", scroff, widensz); let pp: i32 = widensz - 8; for (pp >= 0) { emitline("\tMOVQ\t"); @@ -18757,20 +18757,20 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // nkind.N_SLICE expression as arg: `buf[lo:hi]` builds a slice header // on the stack matching C cgen's sequence — push base, push hi, // compute lo, pop into BX/CX, derive len/ptr, push (cap, len, ptr). - if (arg.kind == nkind.N_SLICE) { - let base: *node = arg.lhs; - let lo: *node = arg.rhs; - let hi: *node = arg.cond; + if (arg.kind == syntax.nkind.N_SLICE) { + let base: *syntax.node = arg.lhs; + let lo: *syntax.node = arg.rhs; + let hi: *syntax.node = arg.cond; let baselocal: *local = nil; - let globaltn: *node = nil; + let globaltn: *syntax.node = nil; let globalname: str; globalname.ptr = nil; globalname.len = 0; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal == nil) { - let gt: *node = letvartnode(c, bn); + let gt: *syntax.node = letvartnode(c, bn); if (gt != nil) { globaltn = gt; globalname = bn; @@ -18783,9 +18783,9 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // checker-stamped element tinfo on base.type_ instead. Cstage // twin reads base->type (cgen.c pushargs N_SLICE esz). Mirror // of the cgslice #252 site. - let dotbu: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_DOT) { - dotbu = base.type_: *tinfo; + let dotbu: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_DOT) { + dotbu = base.type_: *syntax.tinfo; dotbu = tichase(dotbu); };}; // #60 (alias arc #5): alias-NAMED N_IDENT base — the tnode @@ -18794,10 +18794,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // pusharg twin of the cgslice fix (cstage pushargs N_SLICE // reads bu = type_chase_named(base->type) uniformly). let basealias: bool = false; - let bu60: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; - if (bt60 != nil) { if (bt60.kind == tykind.TY_NAMED) { + let bu60: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt60 != nil) { if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; bu60 = tichase(bt60); };}; @@ -18817,18 +18817,18 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { esz = dotbu.sub.size: i32; };};}; if (bu60 != nil) { - let es60: *tinfo = tichase(bu60.sub); + let es60: *syntax.tinfo = tichase(bu60.sub); if (es60 != nil) { esz = es60.size: i32; }; }; // base address → push if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarr60: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { isarr60 = true; }; + if (tn.kind == syntax.nkind.N_TARRAY) { isarr60 = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). - if (bu60 != nil) { isarr60 = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { isarr60 = bu60.kind == syntax.tykind.TY_ARRAY; }; if (isarr60) { emitline("\tLEAQ\t"); emitoff(baselocal.off: i64); @@ -18839,10 +18839,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("(BP), AX\n"); }; } else { if (globaltn != nil) { - let gisarr60: bool = globaltn.kind == nkind.N_TARRAY; + let gisarr60: bool = globaltn.kind == syntax.nkind.N_TARRAY; // #60: alias-NAMED base — chased kind; runtime- // unreachable until #77/#78 global DATA. - if (bu60 != nil) { gisarr60 = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { gisarr60 = bu60.kind == syntax.tykind.TY_ARRAY; }; if (gisarr60) { emitline("\tLEAQ\t"); emitsymname(c, globalname); @@ -18865,11 +18865,11 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { if (hi != nil) { cgexpr(c, hi); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { - let lenn: *node = tn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (tn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = tn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -18880,19 +18880,19 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // N_TNAME); a plain `[MAX]u8` base reaches here // with a non-N_INTLIT dim and dropped the // default-hi entirely. cstage reads bu->alen. - let abt: *tinfo = tichase(tn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(tn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); }; }; - } else { if (tn.kind == nkind.N_TSLICE) { + } else { if (tn.kind == syntax.nkind.N_TSLICE) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); - } else { if (tn.kind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { + } else { if (tn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); @@ -18902,21 +18902,21 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // #60: alias-NAMED base default-hi — chased kind // (see the cgslice twin). if (bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); };}; }; } else { if (globaltn != nil) { - if (globaltn.kind == nkind.N_TARRAY) { - let lenn: *node = globaltn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (globaltn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = globaltn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -18924,20 +18924,20 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // #56: def/const dim on a global array base — // resolve from the stamped array tinfo (rule-13), // twin of the local arg-push arm above. - let abt: *tinfo = tichase(globaltn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(globaltn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); }; }; - } else { if (globaltn.kind == nkind.N_TSLICE) { + } else { if (globaltn.kind == syntax.nkind.N_TSLICE) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); emitline("\tMOVQ\t8(CX), AX\n"); - } else { if (globaltn.kind == nkind.N_TNAME) { - if (streq(globaltn.str, "str")) { + } else { if (globaltn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(globaltn.str, "str")) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -18947,12 +18947,12 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // #60: alias-NAMED global base default-hi — chased // kind; runtime-unreachable until #77/#78 global DATA. if (bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -18998,7 +18998,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // into argregs lands the canonical (ptr/tag, len/v0, cap/v1). // For tagged ident with a >24B slot (slice-payload variant), // push a fourth word from off+24. - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let nm: str = arg.str; let lc: *local = localfindnode(c, nm); if (lc != nil) { @@ -19058,9 +19058,9 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // from dotchainaddr). The slot-word count is the stamped tinfo // size (the type table, byte-id with cstage struct_arg_size). if (lc == nil) { - let gst: *tinfo = arg.type_: *tinfo; + let gst: *syntax.tinfo = arg.type_: *syntax.tinfo; gst = tichase(gst); - if (gst != nil) { if (gst.kind == tykind.TY_STRUCT) { + if (gst != nil) { if (gst.kind == syntax.tykind.TY_STRUCT) { let gsz: i32 = gst.size: i32; if (gsz > 0 && gsz <= 16 && (isletvar(c, nm) || deflookup(c, nm))) { @@ -19097,7 +19097,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // would LEAQ an undefined main.(SB) (w6l fails); a // def must fall through to the const-fold path instead. if (gst != nil && isletvar(c, nm)) { - if (gst.kind == tykind.TY_SLICE) { + if (gst.kind == syntax.tykind.TY_SLICE) { emitline("\tLEAQ\t"); emitsymname(c, nm); emitline("(SB), BX\n"); @@ -19109,7 +19109,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("\tPUSHQ\tAX\n"); return rest + 3; }; - if (gst.kind == tykind.TY_STR) { + if (gst.kind == syntax.tykind.TY_STR) { emitline("\tLEAQ\t"); emitsymname(c, nm); emitline("(SB), CX\n"); @@ -19134,7 +19134,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // >24B sret'd into @aggargscr then pushed from there. Pre-fix every // such source fell to the scalar default (one PUSHQ for a multi-word // aggregate) and stack-imbalanced against the type-based drain. - let aggsz: i32 = aggargsizetn(arg.type_: *tinfo); + let aggsz: i32 = aggargsizetn(arg.type_: *syntax.tinfo); if (aggsz > 0) { // Exclude a ≤16B-struct IDENT — it owns the structparamsize // fast path above (or, when a cross-module same-leaf collision @@ -19145,10 +19145,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // args[i]->type) — a name-keyed gate here re-opens the #211/#13 // name-keyed divergence the cstage type gate doesn't have. let structident: bool = false; - if (arg.kind == nkind.N_IDENT) { - let st: *tinfo = arg.type_: *tinfo; + if (arg.kind == syntax.nkind.N_IDENT) { + let st: *syntax.tinfo = arg.type_: *syntax.tinfo; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { if (st.size: i32 <= 16) { structident = true; }; }; }; }; @@ -19159,7 +19159,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { os.exit(1); }; let nwords: i32 = (aggsz + 7) / 8; - if (arg.kind == nkind.N_CALL) { + if (arg.kind == syntax.nkind.N_CALL) { if (callsretsize(c, arg) > 0) { let scr: i32 = localadd(c, "@aggargscr", aggsz, nil); @@ -19215,9 +19215,9 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // the MOVSS load on the pop side touches only the low 4. let fk: i32 = 0; if (arg != nil) { - let at: *tinfo = arg.type_: *tinfo; - if (typeisf32(at)) { fk = 1; } - else { if (typeisfloat(at)) { fk = 2; }; }; + let at: *syntax.tinfo = arg.type_: *syntax.tinfo; + if (syntax.typeisf32(at)) { fk = 1; } + else { if (syntax.typeisfloat(at)) { fk = 2; }; }; }; if (fk != 0) { cgexpr(c, arg); @@ -19235,14 +19235,14 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // the box cursor; the restage + push then key on the param tuple type // node (declared element widths), not the literal's element- // constructed types. Mirrors cstage cgcall paramtup. - let paramtt: *node = nil; - if (arg.kind == nkind.N_TUPLE) { if (param != nil) { - if (param.kind == nkind.N_PARAM && param.lhs != nil) { - let ptn: *node = param.lhs; - for (ptn != nil && ptn.kind == nkind.N_TNAME) { + let paramtt: *syntax.node = nil; + if (arg.kind == syntax.nkind.N_TUPLE) { if (param != nil) { + if (param.kind == syntax.nkind.N_PARAM && param.lhs != nil) { + let ptn: *syntax.node = param.lhs; + for (ptn != nil && ptn.kind == syntax.nkind.N_TNAME) { ptn = aliaslookup(c, ptn.str); }; - if (ptn != nil) { if (ptn.kind == nkind.N_TTUPLE) { paramtt = ptn; }; }; + if (ptn != nil) { if (ptn.kind == syntax.nkind.N_TTUPLE) { paramtt = ptn; }; }; }; }; }; if (paramtt != nil) { cgtuplelittocursor(c, arg, paramtt); } @@ -19258,17 +19258,17 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // arg-class regs. When the PARAM tuple type is known (#68), walk its // declared element type nodes (p.lhs); else an N_TUPLE literal's // elements are VALUE exprs classified the way cgtuplelittocursor does. - let tuparg: *node = paramtt; + let tuparg: *syntax.node = paramtt; if (tuparg == nil) { tuparg = nodetuplearg(c, arg); }; if (tuparg != nil) { let tuplit: bool = false; - if (paramtt == nil) { if (tuparg.kind == nkind.N_TUPLE) { tuplit = true; }; }; + if (paramtt == nil) { if (tuparg.kind == syntax.nkind.N_TUPLE) { tuplit = true; }; }; let gptot: i32 = 0; let sstot: i32 = 0; let tsz: i32 = 0; - let p: *node = tuparg.list; + let p: *syntax.node = tuparg.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (tuplit) { et = p; }; // C-t2 (ken demand 1, rule 7): a COMPOSITE element // (nested tuple/struct/array/tagged) occupies more @@ -19278,19 +19278,19 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // skewed). The stamped tinfo classifies both type // nodes and literal value exprs. Mirrors the cstage // restage guard. - let eti: *tinfo = et.type_: *tinfo; + let eti: *syntax.tinfo = et.type_: *syntax.tinfo; eti = tichase(eti); if (eti != nil) { - let bad: bool = eti.kind == tykind.TY_TUPLE - || eti.kind == tykind.TY_STRUCT - || eti.kind == tykind.TY_ARRAY; + let bad: bool = eti.kind == syntax.tykind.TY_TUPLE + || eti.kind == syntax.tykind.TY_STRUCT + || eti.kind == syntax.tykind.TY_ARRAY; // #68: a declared-tagged element graduates to a real // widen — the decl-aware send (cgtuplelittocursor over // the param tuple type) left the box words in the // cursor, so tupstore below carries them. A tagged // element with no param decl stays rule-7 loud (the // cursor was filled stamped-keyed). - if (eti.kind == tykind.TY_TAGGED && paramtt == nil) { bad = true; }; + if (eti.kind == syntax.tykind.TY_TAGGED && paramtt == nil) { bad = true; }; if (bad) { let mne: str = "#32: tuple arg element kind unsupported (nested tuple/struct/array/tagged; rule 7)\n"; os.write(2, mne.ptr, mne.len: u64); @@ -19327,7 +19327,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { let eoff: i32 = 0; p = tuparg.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (tuplit) { et = p; }; let eslot: i32 = 8; if (tuplit) { @@ -19358,10 +19358,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // single-PUSHQ default and silently skewed every later arg // register. Mirrors the cstage cgcall guard. { - let ati: *tinfo = arg.type_: *tinfo; + let ati: *syntax.tinfo = arg.type_: *syntax.tinfo; ati = tichase(ati); if (ati != nil) { - if (ati.kind == tykind.TY_TUPLE) { + if (ati.kind == syntax.tykind.TY_TUPLE) { let m32: str = "#32: tuple arg from unsupported source shape (call/ident/literal/unwrap only; rule 7)\n"; os.write(2, m32.ptr, m32.len: u64); os.exit(1); @@ -19416,8 +19416,8 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // keeps the stamped-carrier kind gate (#67 pattern) — the // remaining kinds (deref/cast/unwrap) are word0-only reads today, // filed residual. - if (arg.kind == nkind.N_INDEX || arg.kind == nkind.N_DOT - || (arg.kind == nkind.N_UN && arg.op == tkind.TK_STAR)) { + if (arg.kind == syntax.nkind.N_INDEX || arg.kind == syntax.nkind.N_DOT + || (arg.kind == syntax.nkind.N_UN && arg.op == syntax.tkind.TK_STAR)) { if (istaggedtype(c, arg)) { let isz: i32 = slotsize(c, arg); // #35 (Family C): a mem-based read left the box @@ -19454,21 +19454,21 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // route a tagged-return call result through the AX/DX/CX/R8 high→low // push convention rather than the concrete-variant widening path // (which drops DX/CX/R8). See task #21. -export fn taggedcallslot(c: *cgen, n: *node) i32 = { +export fn taggedcallslot(c: *cgen, n: *syntax.node) i32 = { if (n == nil) { return 0; }; - if (n.kind != nkind.N_CALL) { return 0; }; - let callee: *node = n.lhs; + if (n.kind != syntax.nkind.N_CALL) { return 0; }; + let callee: *syntax.node = n.lhs; if (callee == nil) { return 0; }; - if (callee.kind != nkind.N_IDENT) { return 0; }; - let rtyp: *node = fnretlookup(c, callee.str); + if (callee.kind != syntax.nkind.N_IDENT) { return 0; }; + let rtyp: *syntax.node = fnretlookup(c, callee.str); if (!istaggedtype(c, rtyp)) { return 0; }; return slotsize(c, rtyp); }; -fn nodeisslice(c: *cgen, n: *node) bool = { +fn nodeisslice(c: *cgen, n: *syntax.node) bool = { if (n == nil) { return false; }; - let k: nkind = n.kind; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_IDENT) { let nm: str = n.str; let lc: *local = localfindnode(c, nm); // F7-c1: the local read collapses onto the checker-stamped @@ -19479,7 +19479,7 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // decl localfindnode keys on); the localfindnode gate stays to // keep the global-var-not-def case routing to false (out of F7 // scope), so this is a zero-delta mechanic validation. - if (lc != nil) { return typeisslice(n.type_: *tinfo); }; + if (lc != nil) { return syntax.typeisslice(n.type_: *syntax.tinfo); }; // #21: a module-level `def g: []T` ident is not a frame // slot (localfindnode→nil), so the local arm above misses // it and it would fall to the scalar single-PUSHQ default, @@ -19491,12 +19491,12 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // const-fold, so the push site and cgcall's pop sizer flip // together on this shared recognizer (load-bearing). if (deflookup(c, nm)) { - return typeisslice(n.type_: *tinfo); + return syntax.typeisslice(n.type_: *syntax.tinfo); }; return false; }; - if (k == nkind.N_SLICE) { return true; }; - if (k == nkind.N_CAST) { return isslicetype(c, n.rhs); }; + if (k == syntax.nkind.N_SLICE) { return true; }; + if (k == syntax.nkind.N_CAST) { return isslicetype(c, n.rhs); }; // #24: N_CALL returning a slice — cgexpr leaves (AX=ptr, // BX=len, CX=cap); pushargsrev's slice arm pushes CX/BX/AX // and cgcall pops 3 words. Without this arm the natural-push @@ -19508,22 +19508,22 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // doesn't shadow the explicit `mod.f()` qualifier — surfaced by // strings.slice returning `frombytes(utf8.slice(...))` // where strings.slice itself returns str. - if (k == nkind.N_CALL) { - let callee: *node = n.lhs; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = n.lhs; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { - let rtyp: *node = fnretlookupmod(c, callee.str, c.curmod); + if (callee.kind == syntax.nkind.N_IDENT) { + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, c.curmod); return isslicetype(c, rtyp); }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; - let rtyp: *node = fnretlookupmod(c, callee.str, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, cmod); return isslicetype(c, rtyp); }; }; @@ -19534,8 +19534,8 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // resolve to the right tinfo via check.ww:1947-1978 (pseudo-field // + struct-field stamps). Cstage cgen.c:182-184 node_isslice = // type_isslice(n->type) — same shape. Collapsed per A.6.3h (#56). - if (k == nkind.N_DOT) { - return typeisslice(n.type_: *tinfo); + if (k == syntax.nkind.N_DOT) { + return syntax.typeisslice(n.type_: *syntax.tinfo); }; // #45 (F7-c2): `arr[i]` whose element is a slice. cgindex leaves // (AX=ptr, BX=len, CX=cap) for a 24B element, but with no N_INDEX @@ -19545,8 +19545,8 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // type (exprtype N_INDEX stamps n.type_, check.ww:2777), mirroring // cstage node_isslice = type_isslice(n->type) and the N_INDEX arms of // nodeisstr (below) + nodeisunsigned (:1798). - if (k == nkind.N_INDEX) { - return typeisslice(n.type_: *tinfo); + if (k == syntax.nkind.N_INDEX) { + return syntax.typeisslice(n.type_: *syntax.tinfo); }; return false; }; @@ -19567,11 +19567,11 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // - N_UN(TK_STAR) of `*str` — cgun itself emits only `MOVQ (AX), AX` // and never loads .len into BX; fixing the recognizer alone won't // help. Tracked alongside the broader cgun-load-shape gap. -fn nodeisstr(c: *cgen, n: *node) bool = { +fn nodeisstr(c: *cgen, n: *syntax.node) bool = { if (n == nil) { return false; }; - let k: nkind = n.kind; - if (k == nkind.N_STRLIT) { return true; }; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_STRLIT) { return true; }; + if (k == syntax.nkind.N_IDENT) { let nm: str = n.str; let lc: *local = localfindnode(c, nm); // F7-c1: the local read collapses onto the checker-stamped @@ -19584,7 +19584,7 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // localfindnode keys on). The localfindnode gate stays to keep // the global-var-not-def case routing to false (out of F7 // scope), so this is a zero-delta mechanic validation. - if (lc != nil) { return typeisstr(n.type_: *tinfo); }; + if (lc != nil) { return syntax.typeisstr(n.type_: *syntax.tinfo); }; // #21: a module-level `def s: str` ident is not a frame slot // (localfindnode→nil), so the local arm above misses it and // it would fall to the scalar single-PUSHQ default, dropping @@ -19596,29 +19596,29 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // $len), so the push site and cgcall's pop sizer flip together // on this shared recognizer (load-bearing). if (deflookup(c, nm)) { - return typeisstr(n.type_: *tinfo); + return syntax.typeisstr(n.type_: *syntax.tinfo); }; return false; }; - if (k == nkind.N_CALL) { - let callee: *node = n.lhs; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = n.lhs; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { - let rtyp: *node = fnretlookupmod(c, callee.str, c.curmod); + if (callee.kind == syntax.nkind.N_IDENT) { + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, c.curmod); return isstrtype(c, rtyp); }; // #34: cross-module N_DOT — route through fnretlookupmod // so a same-leaf caller-module fn (different return shape) // doesn't shadow the explicit qualifier. - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; - let rtyp: *node = fnretlookupmod(c, callee.str, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, cmod); return isstrtype(c, rtyp); }; }; @@ -19633,18 +19633,18 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // = type_isstr(n->type) and nodeisunsigned's N_INDEX arm (:1798). The // base-kind whitelist is gone — every base shape routes through the // one stamp read. - if (k == nkind.N_INDEX) { - return typeisstr(n.type_: *tinfo); + if (k == syntax.nkind.N_INDEX) { + return syntax.typeisstr(n.type_: *syntax.tinfo); }; // N_DOT: read the checker-stamped n.type_. Struct field, nested // dot, value-struct hops, and pseudo-fields (.ptr/.len/.cap) all // resolve to the right tinfo via check.ww:1947-1978. Cstage // cgen.c:168-170 node_isstr = type_isstr(n->type) — same shape. // Collapsed per A.6.3h (#56). - if (k == nkind.N_DOT) { - return typeisstr(n.type_: *tinfo); + if (k == syntax.nkind.N_DOT) { + return syntax.typeisstr(n.type_: *syntax.tinfo); }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { return isstrtype(c, n.rhs); }; return false; @@ -19655,9 +19655,9 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // (cstage N_LET sz==8 ladder SSoT). t.type_ is stamped at check.ww // L426-436 for every type-AST kind callers reach. Collapsed onto the // tinfo helper per A.6.3b (#46). -fn typeis8byteprimitive(c: *cgen, t: *node) bool = { +fn typeis8byteprimitive(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeis8byteprim(t.type_: *tinfo); + return syntax.typeis8byteprim(t.type_: *syntax.tinfo); }; // elemissignedc — given an indexable type-AST (`*T`, `[]T`, `[N]T`), @@ -19665,7 +19665,7 @@ fn typeis8byteprimitive(c: *cgen, t: *node) bool = { // MOVSXD vs MOVL at esz=4 (and MOVSBQ/MOVSWQ at esz=1/2). Mirrors // cstage's `signed_elem` (cmd/w6c/cgen.c idx_eff path). Reads through // the stamped tinfo so alias/enum recursion lives in lib/ww/typ.ww. -fn elemissignedc(c: *cgen, t: *node) bool = { +fn elemissignedc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; // #65 Phase-N step-2 cleanup: peel TY_NAMED before the .sub read. // #64 now flows per-decl NAMED wrappers, so a NAMED-of-(`*T`/`[]T`/ @@ -19677,9 +19677,9 @@ fn elemissignedc(c: *cgen, t: *node) bool = { // idxeffti additionally drills `*[N]T` to the pointee array (#61) // so a signed-narrow element behind a pointer-to-array still // sign-extends on load. - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti == nil) { return false; }; - return typeissigned(ti.sub); + return syntax.typeissigned(ti.sub); }; // elemisfloatc — given an indexable type-AST (`*T`, `[]T`, `[N]T`), is @@ -19690,22 +19690,22 @@ fn elemissignedc(c: *cgen, t: *node) bool = { // .sub read exactly as elemissignedc does (#64/#65). Float-ness comes // from the SAME tinfo the esz already reads — never a fresh node-stamp // (the unstamped-base trap that broke the exprfloatkind collapse, #121). -fn elemisfloatc(c: *cgen, t: *node) bool = { +fn elemisfloatc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; // idxeffti = TY_NAMED peel + the `*[N]T` drill (#61). - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti == nil) { return false; }; - return typeisfloat(ti.sub); + return syntax.typeisfloat(ti.sub); }; // elemisf32c — narrower elemisfloatc: true only when the element is f32, // so cgindex picks MOVSS over MOVSD at the #119 element load. -fn elemisf32c(c: *cgen, t: *node) bool = { +fn elemisf32c(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; // idxeffti = TY_NAMED peel + the `*[N]T` drill (#61). - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti == nil) { return false; }; - return typeisf32(ti.sub); + return syntax.typeisf32(ti.sub); }; // elemisarrayc — given an indexable type-AST (`*T` / `[]T` / `[N]T`), is @@ -19717,20 +19717,20 @@ fn elemisf32c(c: *cgen, t: *node) bool = { // elemsizeof (:920-948) so elem-is-array aligns with the esz this same // tnode feeds. cstage twin: idx_eff(bt)->sub unwrapped == TY_ARRAY // (cmd/w6c/cgen.c). `c` kept for signature symmetry with elemisfloatc. -fn elemisarrayc(c: *cgen, t: *node) bool = { +fn elemisarrayc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - let k: nkind = t.kind; - let elem: *node = nil; - if (k == nkind.N_TPTR) { elem = t.lhs; }; - if (k == nkind.N_TSLICE) { elem = t.lhs; }; - if (k == nkind.N_TARRAY) { elem = t.lhs; }; + let k: syntax.nkind = t.kind; + let elem: *syntax.node = nil; + if (k == syntax.nkind.N_TPTR) { elem = t.lhs; }; + if (k == syntax.nkind.N_TSLICE) { elem = t.lhs; }; + if (k == syntax.nkind.N_TARRAY) { elem = t.lhs; }; if (elem == nil) { return false; }; - if (k == nkind.N_TPTR) { - if (elem.kind == nkind.N_TARRAY) { + if (k == syntax.nkind.N_TPTR) { + if (elem.kind == syntax.nkind.N_TARRAY) { if (elem.lhs != nil) { elem = elem.lhs; }; }; }; - return elem.kind == nkind.N_TARRAY; + return elem.kind == syntax.nkind.N_TARRAY; }; // tichase — transitive TY_NAMED peel, nil-passthrough. Exact wwstage @@ -19740,10 +19740,10 @@ fn elemisarrayc(c: *cgen, t: *node) bool = { // scalar shape (#60's esz=1/pointer-base SEGV family). One chased // accessor is the only spelled way to dealias; raw `.under` reads // outside it are the lint target (rob F2 ruling). -fn tichase(t0: *tinfo) *tinfo = { - let t: *tinfo = t0; +fn tichase(t0: *syntax.tinfo) *syntax.tinfo = { + let t: *syntax.tinfo = t0; // peel-ok: chase body - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + for (t != nil && t.kind == syntax.tykind.TY_NAMED) { t = t.under; }; return t; }; @@ -19752,11 +19752,11 @@ fn tichase(t0: *tinfo) *tinfo = { // element type comes from n.type_ (stamped tinfo) not a tnode. Same // role as typeisslice/typeisstr in lib/ww/typ.ww; kept cgen-local to // avoid widening the frontend surface for one #156 read-half check. -fn tinfoisarray(t: *tinfo) bool = { - let u: *tinfo = t; +fn tinfoisarray(t: *syntax.tinfo) bool = { + let u: *syntax.tinfo = t; u = tichase(u); if (u == nil) { return false; }; - return u.kind == tykind.TY_ARRAY; + return u.kind == syntax.tykind.TY_ARRAY; }; // fieldissignedc — does this field/element type-AST need sign- @@ -19764,9 +19764,9 @@ fn tinfoisarray(t: *tinfo) bool = { // cgen.c:240 `fld_issigned` SSoT). t.type_ is stamped at check.ww // L426-436 for every type-AST kind we see here (TNAME / TPTR / // TBANG / TENUM / TARRAY / TSLICE — see resolvewalk). -fn fieldissignedc(c: *cgen, t: *node) bool = { +fn fieldissignedc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeissigned(t.type_: *tinfo); + return syntax.typeissigned(t.type_: *syntax.tinfo); }; // fieldloadop — pick the load instruction for a non-str struct @@ -19801,7 +19801,7 @@ fn fieldstoreop(c: *cgen, f: *fieldinfo) str = { // pointer-target, slice-element, etc.) rather than a struct fieldinfo. // Used at the index / tuple / pointer-deref sites where there's no // fieldinfo entry but the type-node + size are both known. -fn tnodeloadop(c: *cgen, t: *node, sz: i32) str = { +fn tnodeloadop(c: *cgen, t: *syntax.node, sz: i32) str = { let sigd: bool = fieldissignedc(c, t); if (sz == 1) { if (sigd) { return "MOVSBQ"; }; return "MOVZBQ"; }; if (sz == 2) { if (sigd) { return "MOVSWQ"; }; return "MOVZWQ"; }; @@ -19809,7 +19809,7 @@ fn tnodeloadop(c: *cgen, t: *node, sz: i32) str = { return "MOVQ"; }; -fn tnodestoreop(c: *cgen, t: *node, sz: i32) str = { +fn tnodestoreop(c: *cgen, t: *syntax.node, sz: i32) str = { if (sz == 1) { return "MOVB"; }; if (sz == 2) { return "MOVW"; }; if (sz == 4) { return "MOVL"; }; @@ -19841,13 +19841,13 @@ fn loadopsz(sigd: bool, sz: i32) str = { // reports, with TBANG / TENUM / TNAME-alias chains pre-folded by // tinfofornode (check.ww:1102-1153 TNAME, 1154-1161 TBANG, // 1196-1208 TENUM). -export fn localloadop(c: *cgen, tnode: *node) str = { +export fn localloadop(c: *cgen, tnode: *syntax.node) str = { if (tnode == nil) { return "MOVQ"; }; - let ti: *tinfo = tnode.type_: *tinfo; + let ti: *syntax.tinfo = tnode.type_: *syntax.tinfo; if (ti == nil) { return "MOVQ"; }; let sz: i32 = ti.size: i32; if (sz != 1) { if (sz != 2) { if (sz != 4) { return "MOVQ"; }; }; }; - let sigd: bool = typeissigned(ti); + let sigd: bool = syntax.typeissigned(ti); return loadopsz(sigd, sz); }; @@ -19858,13 +19858,13 @@ export fn localloadop(c: *cgen, tnode: *node) str = { // step). One peel choke-point: every tinfo-keyed index-element answer // (elemsizeofc / elemissignedc / elemisfloatc / elemisf32c) routes // through here. Mirrors cstage idx_eff (cmd/w6c/cgen.c:1163). -fn idxeffti(t0: *tinfo) *tinfo = { - let t: *tinfo = t0; +fn idxeffti(t0: *syntax.tinfo) *syntax.tinfo = { + let t: *syntax.tinfo = t0; t = tichase(t); - if (t != nil && t.kind == tykind.TY_PTR) { - let p: *tinfo = t.sub; + if (t != nil && t.kind == syntax.tykind.TY_PTR) { + let p: *syntax.tinfo = t.sub; p = tichase(p); - if (p != nil && p.kind == tykind.TY_ARRAY) { return p; }; + if (p != nil && p.kind == syntax.tykind.TY_ARRAY) { return p; }; }; return t; }; @@ -19878,14 +19878,14 @@ fn idxeffti(t0: *tinfo) *tinfo = { // N*8-byte aggregate copy from an 8B source: caller-frame smash). // nil for non-indexable kinds (str N_TNAME: callers want nil so // tnodestoreop falls to the u8 byte store). -fn idxelemtn(tn: *node) *node = { +fn idxelemtn(tn: *syntax.node) *syntax.node = { if (tn == nil) { return nil; }; - let k: nkind = tn.kind; - if (k != nkind.N_TARRAY && k != nkind.N_TSLICE - && k != nkind.N_TPTR) { return nil; }; - let elem: *node = tn.lhs; - if (k == nkind.N_TPTR && elem != nil - && elem.kind == nkind.N_TARRAY) { + let k: syntax.nkind = tn.kind; + if (k != syntax.nkind.N_TARRAY && k != syntax.nkind.N_TSLICE + && k != syntax.nkind.N_TPTR) { return nil; }; + let elem: *syntax.node = tn.lhs; + if (k == syntax.nkind.N_TPTR && elem != nil + && elem.kind == syntax.nkind.N_TARRAY) { return elem.lhs; }; return elem; @@ -19897,14 +19897,14 @@ fn idxelemtn(tn: *node) *node = { // For aliased element types (e.g. `[N]formattable`), callers that // need the resolved slot size should use elemsizeofc(c, t) which // follows aliases via slotsize. -fn elemsizeof(t: *node) i32 = { +fn elemsizeof(t: *syntax.node) i32 = { if (t == nil) { return 1; }; - let k: nkind = t.kind; - let elem: *node = nil; - if (k == nkind.N_TPTR) { elem = t.lhs; }; - if (k == nkind.N_TSLICE) { elem = t.lhs; }; - if (k == nkind.N_TARRAY) { elem = t.lhs; }; - if (k == nkind.N_TNAME) { + let k: syntax.nkind = t.kind; + let elem: *syntax.node = nil; + if (k == syntax.nkind.N_TPTR) { elem = t.lhs; }; + if (k == syntax.nkind.N_TSLICE) { elem = t.lhs; }; + if (k == syntax.nkind.N_TARRAY) { elem = t.lhs; }; + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; // str's element is u8 (F1: tystr.sub = tyu8), named directly // rather than read off str.sub because elemsizeof gets a raw @@ -19914,7 +19914,7 @@ fn elemsizeof(t: *node) i32 = { // str.sub-equivalent; the structural collapse onto str.sub is // blocked on tinfo-stamping here, not intent (#24). cstage twin // reads eff->sub->size (cmd/w6c/cgen.c N_INDEX). - if (streq(nm, "str")) { return primtypesize("u8"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("u8"): i32; }; // Indexing a primitive name (rare): element size = the prim. // primsize-ok (#101/#109): elemsizeof is the STRUCTURAL (non- // chasing) sizer by design — its alias-resolving twin elemsizeofc @@ -19933,17 +19933,17 @@ fn elemsizeof(t: *node) i32 = { // double-index (cgindex) needs the sub-array stride — call // elemsizeofc, the 2D-correct entry, which recovers slotsize([M]T) // when elemsizeof returns 8. Never call elemsizeof for a 2D stride. - if (elem.kind == nkind.N_TARRAY) { + if (elem.kind == syntax.nkind.N_TARRAY) { if (elem.lhs != nil) { elem = elem.lhs; }; }; // `*[]T`: stride is the slice header (24B). Hare-faithful — a // pointer-to-slice is a 1D array of slices, not of T. Mirrors the // cstage check.c default `*U → U` path for U=[]T (slice element). - if (elem.kind == nkind.N_TSLICE) { return tyslicesize(): i32; }; - if (elem.kind == nkind.N_TNAME) { + if (elem.kind == syntax.nkind.N_TSLICE) { return tyslicesize(): i32; }; + if (elem.kind == syntax.nkind.N_TNAME) { let nm: str = elem.str; // str element is 16B (ptr+len). primsize returns 0 for it. - if (streq(nm, "str")) { return primtypesize("str"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("str"): i32; }; // primsize-ok (#101/#109): structural sizer — the chase lives // in elemsizeofc (:1579), not here. See the :1475 leg. let ps: i32 = primsize(nm); @@ -19956,7 +19956,7 @@ fn elemsizeof(t: *node) i32 = { // (struct / tagged / `type foo = bar;`) via slotsize. Used where // cgindex / cgassign need a correct stride for `[N]Alias` arrays // whose Alias resolves to a tagged union (e.g. `[N]formattable`). -fn elemsizeofc(c: *cgen, t: *node) i32 = { +fn elemsizeofc(c: *cgen, t: *syntax.node) i32 = { if (t == nil) { return 1; }; // #270-2: a NESTED-array element ([N][M]T) — the OUTER index stride // is the WHOLE sub-array [M]T, not the scalar T that elemsizeof @@ -19973,12 +19973,12 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // every index by N*size(T) — the siphash round() corruption. The // `*[N][M]T` outer stride still resolves below via idxeffti // (pointee array's .sub = [M]T, its natural size). - let nk: nkind = t.kind; - let nest: *node = nil; - if (nk == nkind.N_TSLICE) { nest = t.lhs; }; - if (nk == nkind.N_TARRAY) { nest = t.lhs; }; - if (nest != nil && nest.kind == nkind.N_TARRAY) { - let eti: *tinfo = nest.type_: *tinfo; + let nk: syntax.nkind = t.kind; + let nest: *syntax.node = nil; + if (nk == syntax.nkind.N_TSLICE) { nest = t.lhs; }; + if (nk == syntax.nkind.N_TARRAY) { nest = t.lhs; }; + if (nest != nil && nest.kind == syntax.nkind.N_TARRAY) { + let eti: *syntax.tinfo = nest.type_: *syntax.tinfo; eti = tichase(eti); if (eti != nil) { return eti.size: i32; }; }; @@ -19991,12 +19991,12 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // element chased like the #8 leg below. Non-indexable names // (struct/prim/str aliases) fall through to the old paths — // byte-id preserved there. - if (nk == nkind.N_TNAME) { - let eff: *tinfo = idxeffti(t.type_: *tinfo); + if (nk == syntax.nkind.N_TNAME) { + let eff: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (eff != nil) { - if (eff.kind == tykind.TY_ARRAY - || eff.kind == tykind.TY_SLICE) { - let aes: *tinfo = tichase(eff.sub); + if (eff.kind == syntax.tykind.TY_ARRAY + || eff.kind == syntax.tykind.TY_SLICE) { + let aes: *syntax.tinfo = tichase(eff.sub); if (aes != nil) { return aes.size: i32; }; }; }; @@ -20017,15 +20017,15 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // idxeffti folds that peel together with the `*[N]T` TY_PTR→ // TY_ARRAY drill (#61) so .sub is the array's element, never the // whole pointee array. - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti != nil) { - let esub: *tinfo = ti.sub; + let esub: *syntax.tinfo = ti.sub; esub = tichase(esub); if (esub != nil) { return esub.size: i32; }; }; - let elem: *node = idxelemtn(t); + let elem: *syntax.node = idxelemtn(t); if (elem == nil) { return direct; }; - if (elem.kind == nkind.N_TNAME) { + if (elem.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, elem.str); if (ps > 0) { return ps; }; }; @@ -20042,9 +20042,9 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // // Conservative: if we can't tell, return false (signed). The cost of // being wrong here is byte-different asm vs C, not bad runtime. -fn nodeisunsigned(c: *cgen, n: *node) bool = { +fn nodeisunsigned(c: *cgen, n: *syntax.node) bool = { if (n == nil) { return false; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; // #25 (F7-c5): collapse the whole N_IDENT arm onto the checker-stamped // n.type_, dropping the localfindnode special-case. The prior arm read // the local's declared tnode and returned `false` (signed) for a @@ -20056,21 +20056,21 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // the corpus HAS module-global unsigned counters on the divide/shift // path, so the self-compile .s MOVES — every move is toward cstage // (IDIV→DIV where the global's stamp is unsigned) and runtime-correct. - if (k == nkind.N_IDENT) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_IDENT) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; - if (k == nkind.N_DOT) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_DOT) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { if (n.rhs == nil) { return false; }; - return typeisunsigned(n.rhs.type_: *tinfo); + return syntax.typeisunsigned(n.rhs.type_: *syntax.tinfo); }; - if (k == nkind.N_BIN) { + if (k == syntax.nkind.N_BIN) { if (nodeisunsigned(c, n.lhs)) { return true; }; return nodeisunsigned(c, n.rhs); }; - if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); }; + if (k == syntax.nkind.N_UN) { return nodeisunsigned(c, n.lhs); }; // nkind.N_INDEX: `p[i]` is unsigned iff its element type is // unsigned. Read the checker-stamped result type directly, // mirroring the N_DOT arm above and cstage cgen.c:2541 @@ -20081,8 +20081,8 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // `d.digits[nd] >= 5u8` pick signed JGE instead of unsigned JAE. // Embodies the #121 principle (collapse structural onto stamp). // #134. - if (k == nkind.N_INDEX) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_INDEX) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; // nkind.N_CALL: a call returning an unsigned type (e.g. `fn f() u64`) // is unsigned. Read the checker-stamped result type directly — the @@ -20091,8 +20091,8 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // `n->type = u->ret`; without this arm the wwstage fell through to // `return false`, picking signed IDIV/SAR over unsigned DIV/SHR on a // call-result div/mod/shift operand. #168. - if (k == nkind.N_CALL) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_CALL) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; return false; }; @@ -20101,27 +20101,27 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // statically determinable. Mirrors nodeisunsigned's structural walk. // Used by cgun TK_TILDE to clamp narrow unsigned ~ results to type // width (NOTQ inverts the full 64-bit register). -fn nodeprimwidth(c: *cgen, n: *node) i32 = { +fn nodeprimwidth(c: *cgen, n: *syntax.node) i32 = { if (n == nil) { return 0; }; - let k: nkind = n.kind; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; + if (tn.kind == syntax.nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; }; }; return 0; }; - if (k == nkind.N_CAST) { - let tn: *node = n.rhs; + if (k == syntax.nkind.N_CAST) { + let tn: *syntax.node = n.rhs; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; + if (tn.kind == syntax.nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; }; return 0; }; - if (k == nkind.N_UN) { return nodeprimwidth(c, n.lhs); }; + if (k == syntax.nkind.N_UN) { return nodeprimwidth(c, n.lhs); }; return 0; }; @@ -20178,7 +20178,7 @@ fn structabisize(si: *structinfo) i32 = { let end: i32 = fi.foff + fi.fsz; if (end > n) { n = end; }; if (fi.tnode != nil) { - let ti: *tinfo = fi.tnode.type_: *tinfo; + let ti: *syntax.tinfo = fi.tnode.type_: *syntax.tinfo; ti = tichase(ti); if (ti != nil) { let aln: i32 = ti.align: i32; @@ -20211,7 +20211,7 @@ fn structabisize(si: *structinfo) i32 = { // cgdot / cgassign at every "field-walk on a struct-typed local" // site so a transitively-aliased struct name resolves to its // fieldinfo list regardless of chain depth. -export fn structlookupchain(c: *cgen, tn: *node) *structinfo = { +export fn structlookupchain(c: *cgen, tn: *syntax.node) *structinfo = { if (tn == nil) { return nil; }; // #92: a struct LITERAL's type ref parses as N_IDENT (expression // position, lib/ww/parse/expr.ww) where type specs parse N_TNAME @@ -20219,17 +20219,17 @@ export fn structlookupchain(c: *cgen, tn: *node) *structinfo = { // iterations past the first walk aliaslookup results, which are // N_TNAME by the loop's own reassignment gate. Consumer census // (commit body): no existing caller can pass N_IDENT. - if (tn.kind != nkind.N_TNAME && tn.kind != nkind.N_IDENT) { return nil; }; + if (tn.kind != syntax.nkind.N_TNAME && tn.kind != syntax.nkind.N_IDENT) { return nil; }; let si: *structinfo = structlookup(c, tn.str); if (si != nil) { return si; }; - let cur: *node = tn; + let cur: *syntax.node = tn; for (cur != nil - && (cur.kind == nkind.N_TNAME || cur.kind == nkind.N_IDENT) + && (cur.kind == syntax.nkind.N_TNAME || cur.kind == syntax.nkind.N_IDENT) && si == nil) { - let aliased: *node = aliaslookup(c, cur.str); + let aliased: *syntax.node = aliaslookup(c, cur.str); if (aliased == nil) { cur = nil; } else { - if (aliased.kind == nkind.N_TNAME) { + if (aliased.kind == syntax.nkind.N_TNAME) { si = structlookup(c, aliased.str); cur = aliased; } else { cur = nil; }; @@ -20238,10 +20238,10 @@ export fn structlookupchain(c: *cgen, tn: *node) *structinfo = { return si; }; -export fn sretretsize(c: *cgen, t: *node) i32 = { +export fn sretretsize(c: *cgen, t: *syntax.node) i32 = { if (t == nil) { return 0; }; - let r: *node = t; - if (r.kind == nkind.N_TBANG) { + let r: *syntax.node = t; + if (r.kind == syntax.nkind.N_TBANG) { r = r.lhs; if (r == nil) { return 0; }; }; @@ -20257,7 +20257,7 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { if (tsz38 <= TUPLE_GPCAP * 8) { return 0; }; return tsz38; }; - if (r.kind == nkind.N_TTUPLE) { + if (r.kind == syntax.nkind.N_TTUPLE) { // #10: over-cap tuple → sret. Walk the element TYPE nodes // (pt.lhs) over the SAME caps the SEND/receive use; a float = // 1 SSE eightbyte, a slice/str its 3-word header, a scalar 1 @@ -20268,9 +20268,9 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { let ssecap: i32 = TUPLE_SSECAP; let gptotal: i32 = 0; let ssecount: i32 = 0; - let pt: *node = r.list; + let pt: *syntax.node = r.list; for (pt != nil) { - let et: *node = pt.lhs; + let et: *syntax.node = pt.lhs; if (isfloattype(c, et)) { ssecount = ssecount + 1; } else { @@ -20279,7 +20279,7 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { pt = pt.next; }; if (gptotal > TUPLE_GPCAP || ssecount > ssecap) { - let rti: *tinfo = r.type_: *tinfo; + let rti: *syntax.tinfo = r.type_: *syntax.tinfo; if (rti != nil) { return rti.size: i32; }; }; return 0; @@ -20288,24 +20288,24 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { // (sub.size*len, the type table) gates ≤24 reg / >24 sret, mirroring // cstage cg_sret_retsize TY_ARRAY arm. Pure-int element arrays only; // no float-array-return consumer (structfloatclass stays struct-only). - if (r.kind == nkind.N_TARRAY) { - let ati: *tinfo = r.type_: *tinfo; + if (r.kind == syntax.nkind.N_TARRAY) { + let ati: *syntax.tinfo = r.type_: *syntax.tinfo; ati = tichase(ati); if (ati == nil) { return 0; }; let asz: i32 = ati.size: i32; if (asz <= 24) { return 0; }; return asz; }; - if (r.kind != nkind.N_TNAME) { return 0; }; + if (r.kind != syntax.nkind.N_TNAME) { return 0; }; // Primitives / aliased-to-primitives are never sret. if (aliasprimsize(c, r.str) > 0) { return 0; }; - if (streq(r.str, "str")) { return 0; }; + if (syntax.streq(r.str, "str")) { return 0; }; // #129: same-module alias wins over any-module struct hit. Without // this, `type stream = *vtable` (io) loses to memio.stream (56B // struct) via structlookup's any-module fallback → spurious sret. // Mirrors cstage cg_sret_retsize, which sees TY_PTR, not a name. if (c != nil) { - let al: *node = aliassamemod(c, r.str); + let al: *syntax.node = aliassamemod(c, r.str); if (al != nil) { return sretretsize(c, al); }; @@ -20313,7 +20313,7 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { let si: *structinfo = structlookup(c, r.str); if (si == nil) { if (c != nil) { - let aliased: *node = aliaslookup(c, r.str); + let aliased: *syntax.node = aliaslookup(c, r.str); if (aliased != nil) { return sretretsize(c, aliased); }; @@ -20329,29 +20329,29 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { // > 24B, return its natural size; else 0. Wraps sretretsize over the // callee's resolved return type, used by cglet / cgassign receive // sites and cgcall to detect sret at the receive / emit boundaries. -export fn callsretsize(c: *cgen, n: *node) i32 = { +export fn callsretsize(c: *cgen, n: *syntax.node) i32 = { if (n == nil) { return 0; }; - if (n.kind != nkind.N_CALL) { return 0; }; - let callee: *node = n.lhs; + if (n.kind != syntax.nkind.N_CALL) { return 0; }; + let callee: *syntax.node = n.lhs; if (callee == nil) { return 0; }; let cn: str; cn.ptr = nil; cn.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { cn = callee.str; cmod = c.curmod; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { cn = callee.str; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cn.len == 0) { return 0; }; - let rtyp: *node = fnretlookupmod(c, cn, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cn, cmod); // #129: sretretsize must see the CALLEE's module context so // aliassamemod resolves aliases from the callee's module (not the // caller's). Mirrors cstage operating on resolved Type* objects @@ -20372,15 +20372,15 @@ fn structlookup(c: *cgen, name: str) *structinfo = { // wrong totsize / field offsets. let s: *structinfo = c.structs; for (s != nil) { - if (streq(s.sname, name)) { - if (streq(s.smod, c.curmod)) { return s; }; + if (syntax.streq(s.sname, name)) { + if (syntax.streq(s.smod, c.curmod)) { return s; }; }; s = s.sinext; }; s = c.structs; for (s != nil) { let sn: str = s.sname; - if (streq(sn, name)) { return s; }; + if (syntax.streq(sn, name)) { return s; }; s = s.sinext; }; // Module-qualified form embedded in name (`pkg.S`): scope the @@ -20401,8 +20401,8 @@ fn structlookup(c: *cgen, name: str) *structinfo = { let pkgmod: str = usehint(c, pkg); let b: *structinfo = c.structs; for (b != nil) { - if (streq(b.sname, leaf)) { - if (streq(b.smod, pkgmod)) { + if (syntax.streq(b.sname, leaf)) { + if (syntax.streq(b.smod, pkgmod)) { return b; }; }; @@ -20424,8 +20424,8 @@ fn structlookup(c: *cgen, name: str) *structinfo = { fn structsamemod(c: *cgen, name: str) *structinfo = { let s: *structinfo = c.structs; for (s != nil) { - if (streq(s.sname, name)) { - if (streq(s.smod, c.curmod)) { return s; }; + if (syntax.streq(s.sname, name)) { + if (syntax.streq(s.smod, c.curmod)) { return s; }; }; s = s.sinext; }; @@ -20455,23 +20455,23 @@ fn fldnumidx(s: str) i32 = { // IS the SSoT table aliasprimsize wraps; there is nothing below it to // chase. fn primsize(name: str) i32 = { - if (streq(name, "u8")) { return 1; }; - if (streq(name, "i8")) { return 1; }; - if (streq(name, "bool")) { return 1; }; - if (streq(name, "u16")) { return 2; }; - if (streq(name, "i16")) { return 2; }; - if (streq(name, "u32")) { return 4; }; - if (streq(name, "i32")) { return 4; }; - if (streq(name, "f32")) { return 4; }; - if (streq(name, "u64")) { return 8; }; - if (streq(name, "i64")) { return 8; }; - if (streq(name, "uint")) { return 8; }; - if (streq(name, "int")) { return 8; }; - if (streq(name, "uintptr")) { return 8; }; - if (streq(name, "size")) { return 8; }; - if (streq(name, "f64")) { return 8; }; - if (streq(name, "rune")) { return 4; }; - if (streq(name, "void")) { return 0; }; + if (syntax.streq(name, "u8")) { return 1; }; + if (syntax.streq(name, "i8")) { return 1; }; + if (syntax.streq(name, "bool")) { return 1; }; + if (syntax.streq(name, "u16")) { return 2; }; + if (syntax.streq(name, "i16")) { return 2; }; + if (syntax.streq(name, "u32")) { return 4; }; + if (syntax.streq(name, "i32")) { return 4; }; + if (syntax.streq(name, "f32")) { return 4; }; + if (syntax.streq(name, "u64")) { return 8; }; + if (syntax.streq(name, "i64")) { return 8; }; + if (syntax.streq(name, "uint")) { return 8; }; + if (syntax.streq(name, "int")) { return 8; }; + if (syntax.streq(name, "uintptr")) { return 8; }; + if (syntax.streq(name, "size")) { return 8; }; + if (syntax.streq(name, "f64")) { return 8; }; + if (syntax.streq(name, "rune")) { return 4; }; + if (syntax.streq(name, "void")) { return 0; }; return 0; }; @@ -20492,9 +20492,9 @@ fn primsize(name: str) i32 = { fn aliasprimsize(c: *cgen, nm: str) i32 = { let ps: i32 = primsize(nm); if (ps > 0) { return ps; }; - let cur: *node = aliaslookup(c, nm); + let cur: *syntax.node = aliaslookup(c, nm); for (cur != nil) { - if (cur.kind != nkind.N_TNAME) { return 0; }; + if (cur.kind != syntax.nkind.N_TNAME) { return 0; }; let p: i32 = primsize(cur.str); if (p > 0) { return p; }; cur = aliaslookup(c, cur.str); @@ -20509,16 +20509,16 @@ fn aliasprimsize(c: *cgen, nm: str) i32 = { // enum, etc.). Mirrors cstage's `type_isint(t) ? t->size : 0` / // `type_isunsigned` recursion through TY_NAMED and TY_ENUM. Used by // cgcast's identity-width identity-sign clamp-skip predicate (#33). -export fn typenodeprimresolved(c: *cgen, t: *node, +export fn typenodeprimresolved(c: *cgen, t: *syntax.node, sz_out: *i32, unsigned_out: *bool) void = { *sz_out = 0; *unsigned_out = false; - let cur: *node = t; + let cur: *syntax.node = t; for (cur != nil) { - let k: nkind = cur.kind; - if (k == nkind.N_TBANG) { cur = cur.lhs; } - else { if (k == nkind.N_TENUM) { cur = cur.lhs; } - else { if (k == nkind.N_TNAME) { + let k: syntax.nkind = cur.kind; + if (k == syntax.nkind.N_TBANG) { cur = cur.lhs; } + else { if (k == syntax.nkind.N_TENUM) { cur = cur.lhs; } + else { if (k == syntax.nkind.N_TNAME) { let nm: str = cur.str; // bool is excluded from the int-prim contract: cstage's // `type_isint(TY_BOOL)` is false, so its identity check @@ -20529,17 +20529,17 @@ export fn typenodeprimresolved(c: *cgen, t: *node, // primsize("bool")=1, so the exclusion stays local. The // dedicated `is_bool` path in cgcast owns bool→bool's // ANDQ $255 on both stages. - if (streq(nm, "bool")) { return; }; + if (syntax.streq(nm, "bool")) { return; }; // primsize-ok (#101/#109): this fn IS a prim-resolver // chaser (#33) — primsize is the leaf-primitive probe; // aliaslookup below advances the walk on a miss. let ps: i32 = primsize(nm); if (ps > 0) { *sz_out = ps; - *unsigned_out = typeisunsigned(cur.type_: *tinfo); + *unsigned_out = syntax.typeisunsigned(cur.type_: *syntax.tinfo); return; }; - let al: *node = aliaslookup(c, nm); + let al: *syntax.node = aliaslookup(c, nm); if (al == nil) { return; }; cur = al; } @@ -20555,13 +20555,13 @@ export fn typenodeprimresolved(c: *cgen, t: *node, // caller treats sz=0 as "not identity", which conservatively keeps // the clamp. Mirror of cstage's `n->lhs->type` lookup with the same // TY_NAMED / TY_ENUM recursion through type_isint / type_isunsigned. -export fn exprprimresolved(c: *cgen, n: *node, +export fn exprprimresolved(c: *cgen, n: *syntax.node, sz_out: *i32, unsigned_out: *bool) void = { *sz_out = 0; *unsigned_out = false; if (n == nil) { return; }; - let k: nkind = n.kind; - if (k == nkind.N_INTLIT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_INTLIT) { // Typed-int literal: `7u32` has tsuffix = "u32". Mirrors // cstage's `cexpr` which assigns `lookup_builtin(tsuffix)` // as the node's type — without this, wwstage misses the @@ -20576,12 +20576,12 @@ export fn exprprimresolved(c: *cgen, n: *node, let ps: i32 = primsize(s); if (ps > 0) { *sz_out = ps; - *unsigned_out = typeisunsigned(n.type_: *tinfo); + *unsigned_out = syntax.typeisunsigned(n.type_: *syntax.tinfo); }; }; return; }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { typenodeprimresolved(c, lc.tnode, @@ -20589,15 +20589,15 @@ export fn exprprimresolved(c: *cgen, n: *node, }; return; }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { typenodeprimresolved(c, n.rhs, sz_out, unsigned_out); return; }; - if (k == nkind.N_UN) { + if (k == syntax.nkind.N_UN) { exprprimresolved(c, n.lhs, sz_out, unsigned_out); return; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // #59: read the checker-stamped tinfo instead of re-deriving the // field type via dotfieldtnode's structinfo walk. Mirrors cstage // castsrcprim N_DOT (cmd/w6c/cgen.c:323-344): the base must @@ -20618,16 +20618,16 @@ export fn exprprimresolved(c: *cgen, n: *node, // there, sound through type_isint's NAMED recursion + the // NAMED tinfo carrying its underlying's size (probe // b1c_fld2lvl byte-id). - let bu: *tinfo = nil; - if (n.lhs != nil) { bu = n.lhs.type_: *tinfo; }; + let bu: *syntax.tinfo = nil; + if (n.lhs != nil) { bu = n.lhs.type_: *syntax.tinfo; }; bu = tichase(bu); - if (bu != nil && bu.kind == tykind.TY_PTR) { bu = tichase(bu.sub); }; - if (bu != nil && bu.kind == tykind.TY_STRUCT) { - let u: *tinfo = n.type_: *tinfo; + if (bu != nil && bu.kind == syntax.tykind.TY_PTR) { bu = tichase(bu.sub); }; + if (bu != nil && bu.kind == syntax.tykind.TY_STRUCT) { + let u: *syntax.tinfo = n.type_: *syntax.tinfo; u = tichase(u); - if (typeisint(u)) { + if (syntax.typeisint(u)) { *sz_out = u.size: i32; - *unsigned_out = typeisunsigned(u); + *unsigned_out = syntax.typeisunsigned(u); }; }; return; @@ -20642,7 +20642,7 @@ export fn exprprimresolved(c: *cgen, n: *node, // accept exact match plus suffix-after-`.` on either side. Mirrors // the C cgen's type_eq, which goes through resolved Type pointers. fn variantnamematch(vname: str, pname: str) bool = { - if (streq(vname, pname)) { return true; }; + if (syntax.streq(vname, pname)) { return true; }; // `pname` is qualified, `vname` is bare: drop module prefix. let i: i32 = 0; for (i < pname.len) { @@ -20650,7 +20650,7 @@ fn variantnamematch(vname: str, pname: str) bool = { let tail: str; tail.ptr = pname.ptr + i + 1; tail.len = pname.len - i - 1; - if (streq(tail, vname)) { return true; }; + if (syntax.streq(tail, vname)) { return true; }; }; i += 1; }; @@ -20661,7 +20661,7 @@ fn variantnamematch(vname: str, pname: str) bool = { let tail: str; tail.ptr = vname.ptr + j + 1; tail.len = vname.len - j - 1; - if (streq(tail, pname)) { return true; }; + if (syntax.streq(tail, pname)) { return true; }; }; j += 1; }; @@ -20675,42 +20675,42 @@ fn variantnamematch(vname: str, pname: str) bool = { // the SB-symbol fallback (linker reports `undefined reference to // `). We don't infer for plain `let x = f()` yet — // non-tagged returns don't carry their type back the same way. -fn inferletcalltype(c: *cgen, rhs: *node) *node = { +fn inferletcalltype(c: *cgen, rhs: *syntax.node) *syntax.node = { if (rhs == nil) { return nil; }; // `?` (N_TRYPROP) and `!` (N_TRYUNW) both unwrap a tagged // return to its success variant; the rhs we want the type of // is the inner call expression. let unwrap: bool = false; - let call: *node = rhs; - if (rhs.kind == nkind.N_TRYPROP) { call = rhs.lhs; unwrap = true; }; - if (rhs.kind == nkind.N_TRYUNW) { call = rhs.lhs; unwrap = true; }; + let call: *syntax.node = rhs; + if (rhs.kind == syntax.nkind.N_TRYPROP) { call = rhs.lhs; unwrap = true; }; + if (rhs.kind == syntax.nkind.N_TRYUNW) { call = rhs.lhs; unwrap = true; }; if (call == nil) { return nil; }; - if (call.kind != nkind.N_CALL) { return nil; }; - let callee: *node = call.lhs; + if (call.kind != syntax.nkind.N_CALL) { return nil; }; + let callee: *syntax.node = call.lhs; if (callee == nil) { return nil; }; let cname: str; cname.ptr = nil; cname.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { cname = callee.str; cmod = c.curmod; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { cname = callee.str; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cname.len == 0) { return nil; }; - let rtyp: *node = fnretlookupmod(c, cname, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cname, cmod); if (rtyp == nil) { return nil; }; if (unwrap) { // Strip error variants — success type is the first // variant of the tagged return. - if (rtyp.kind != nkind.N_TTAGGED) { return nil; }; + if (rtyp.kind != syntax.nkind.N_TTAGGED) { return nil; }; return rtyp.list; }; // Plain call: declared return type is the local's type. @@ -20728,7 +20728,7 @@ fn inferletcalltype(c: *cgen, rhs: *node) *node = { // not the default 8B. Without this, the AX:DX:CX spill in cglet's // tagged-init branch writes past the local and tramples the next // slot. -export fn letslotsize(c: *cgen, n: *node) i32 = { +export fn letslotsize(c: *cgen, n: *syntax.node) i32 = { // `[_]T = arrlit;` inferred-length arrays no longer need a slot-size // intercept here: the checker (inferarraylen, check.ww) stamps the // real element count onto the array type's length child before cgen @@ -20736,7 +20736,7 @@ export fn letslotsize(c: *cgen, n: *node) i32 = { // Annotation-less init: defer to the call's return type if we can // infer it. Tagged-union returns need 24B; everything else matches // slotsize on the inferred type. - let tn: *node = n.lhs; + let tn: *syntax.node = n.lhs; if (tn == nil) { tn = inferletcalltype(c, n.rhs); }; if (tn == nil) { return 8; }; let s: i32 = slotsize(c, tn); @@ -20748,9 +20748,9 @@ export fn letslotsize(c: *cgen, n: *node) i32 = { // instead, else its zero width collides with the next local. A // genuine empty struct or [0]T array (also slotsize 0) keeps its 0. if (s == 0) { - let ti: *tinfo = tn.type_: *tinfo; + let ti: *syntax.tinfo = tn.type_: *syntax.tinfo; if (ti != nil) { ti = tichase(ti); }; - if (ti != nil && ti.kind == tykind.TY_VOID) { return 8; }; + if (ti != nil && ti.kind == syntax.tykind.TY_VOID) { return 8; }; }; return s; }; @@ -20774,9 +20774,9 @@ export fn letslotsize(c: *cgen, n: *node) i32 = { // // `c: *cgen` retained unused for callsite stability (localloadop // precedent, 68219a1). -fn slotsize(c: *cgen, typn: *node) i32 = { +fn slotsize(c: *cgen, typn: *syntax.node) i32 = { if (typn == nil) { return 8; }; - let ti: *tinfo = typn.type_: *tinfo; + let ti: *syntax.tinfo = typn.type_: *syntax.tinfo; if (ti == nil) { return 8; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel @@ -20784,11 +20784,11 @@ fn slotsize(c: *cgen, typn: *node) i32 = { // NAMED to the alias-invariant underlying this read consumes. ti = tichase(ti); if (ti == nil) { return 8; }; - let kk: tykind = ti.kind; - if (kk == tykind.TY_VOID) { return 0; }; - if (kk == tykind.TY_PTR || kk == tykind.TY_SLICE || - kk == tykind.TY_CHAN || kk == tykind.TY_FN || - kk == tykind.TY_STR || kk == tykind.TY_TAGGED) { + let kk: syntax.tykind = ti.kind; + if (kk == syntax.tykind.TY_VOID) { return 0; }; + if (kk == syntax.tykind.TY_PTR || kk == syntax.tykind.TY_SLICE || + kk == syntax.tykind.TY_CHAN || kk == syntax.tykind.TY_FN || + kk == syntax.tykind.TY_STR || kk == syntax.tykind.TY_TAGGED) { return ti.size: i32; }; // #75: a struct LOCAL's stack slot is the struct's NATURAL size @@ -20800,10 +20800,10 @@ fn slotsize(c: *cgen, typn: *node) i32 = { // dual-SSoT leak as #44 (field-offset) / #55, one notion over. The // TUPLE arm (8B/elem slot, user ruling #60) and ARRAY arm (element // stride, #48 [N]Alias 24B) keep ti.slotsize — deliberate divergences. - if (kk == tykind.TY_STRUCT) { + if (kk == syntax.tykind.TY_STRUCT) { return ((ti.size + 7u64) & ~7u64): i32; }; - if (kk == tykind.TY_TUPLE || kk == tykind.TY_ARRAY) { + if (kk == syntax.tykind.TY_TUPLE || kk == syntax.tykind.TY_ARRAY) { return ti.slotsize: i32; }; return 8; @@ -20823,9 +20823,9 @@ fn slotsize(c: *cgen, typn: *node) i32 = { // // `c: *cgen` retained unused for callsite stability (slotsize / // localloadop precedent, a828c03 / 68219a1). -fn fieldsize(c: *cgen, tnode: *node) i32 = { +fn fieldsize(c: *cgen, tnode: *syntax.node) i32 = { if (tnode == nil) { return 8; }; - let ti: *tinfo = tnode.type_: *tinfo; + let ti: *syntax.tinfo = tnode.type_: *syntax.tinfo; if (ti == nil) { return 8; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel @@ -20833,14 +20833,14 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = { // NAMED to the alias-invariant underlying this read consumes. ti = tichase(ti); if (ti == nil) { return 8; }; - let k: tykind = ti.kind; - if (k == tykind.TY_STRUCT) { return ti.slotsize: i32; }; - if (k == tykind.TY_ARRAY) { return ti.slotsize: i32; }; - if (k == tykind.TY_TAGGED) { return ti.size: i32; }; - if (k == tykind.TY_SLICE) { return ti.size: i32; }; - if (k == tykind.TY_PTR || k == tykind.TY_FN || - k == tykind.TY_CHAN) { return 8; }; - if (k == tykind.TY_STR) { return ti.size: i32; }; + let k: syntax.tykind = ti.kind; + if (k == syntax.tykind.TY_STRUCT) { return ti.slotsize: i32; }; + if (k == syntax.tykind.TY_ARRAY) { return ti.slotsize: i32; }; + if (k == syntax.tykind.TY_TAGGED) { return ti.size: i32; }; + if (k == syntax.tykind.TY_SLICE) { return ti.size: i32; }; + if (k == syntax.tykind.TY_PTR || k == syntax.tykind.TY_FN || + k == syntax.tykind.TY_CHAN) { return 8; }; + if (k == syntax.tykind.TY_STR) { return ti.size: i32; }; // Primitives + TY_ENUM keep natural width inside structs // (cstage parity: cgen.c reads f->type->size directly). TY_TUPLE // flows here too — pre-collapse fallback was 8, the populated @@ -20864,7 +20864,7 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = { // non-TFIELD identically), so they advance in exact step. si.totsize keeps // the slot-padded total (stack-slot allocator's number) from ti.slotsize, // already 8-rounded at check.ww:2259-2261. -fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { +fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *syntax.node) void = { let si: *structinfo = alloc(structinfo{ sname = name, smod = srcmod, @@ -20874,7 +20874,7 @@ fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { os.write(2, msg.ptr, msg.len: u64); os.exit(1); }; - let ti: *tinfo = tichase(tstruct.type_: *tinfo); + let ti: *syntax.tinfo = tichase(tstruct.type_: *syntax.tinfo); if (ti == nil) { let msg: str = "#44/#55: registerstruct: tichase yielded nil tinfo\n"; os.write(2, msg.ptr, msg.len: u64); @@ -20882,10 +20882,10 @@ fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { }; let head: *fieldinfo = nil; let tail: *fieldinfo = nil; - let f: *node = tstruct.list; - let tf: *tfield = ti.fields; + let f: *syntax.node = tstruct.list; + let tf: *syntax.tfield = ti.fields; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { if (tf == nil) { let msg: str = "#44/#55: registerstruct: AST/tfield walk desync (more TFIELDs than tinfo.fields)\n"; os.write(2, msg.ptr, msg.len: u64); @@ -20909,13 +20909,13 @@ fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { c.structs = si; }; -fn collectstructs(c: *cgen, file: *node) void = { +fn collectstructs(c: *cgen, file: *syntax.node) void = { c.structs = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_TYPEDECL) { - let body: *node = d.lhs; + if (d.kind == syntax.nkind.N_TYPEDECL) { + let body: *syntax.node = d.lhs; // #9: an error-struct (`type X = !struct{...}`) carries an // N_TBANG-wrapped body; peel it so X registers like any // struct. cstage is tinfo-based and needs no table, but @@ -20927,11 +20927,11 @@ fn collectstructs(c: *cgen, file: *node) void = { // cutover, which deletes this name-keyed dispatch outright; // until then the table must be complete (errors.opaque_ is // the first such type). #10 tracks retiring the table. - if (body != nil && body.kind == nkind.N_TBANG) { + if (body != nil && body.kind == syntax.nkind.N_TBANG) { body = body.lhs; }; if (body != nil) { - if (body.kind == nkind.N_TSTRUCT) { + if (body.kind == syntax.nkind.N_TSTRUCT) { registerstruct(c, d.str, d.nmod, body); }; }; @@ -20946,14 +20946,14 @@ fn collectstructs(c: *cgen, file: *node) void = { // Collapsed onto typeisstr per A.6.3b (#46); the prior AST walker is // reconstituted by typeisstr's TY_NAMED chase + tinfofornode's // TBANG-unwrap (check.ww:1145). -fn isstrtype(c: *cgen, t: *node) bool = { +fn isstrtype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisstr(t.type_: *tinfo); + return syntax.typeisstr(t.type_: *syntax.tinfo); }; -fn isslicetype(c: *cgen, t: *node) bool = { +fn isslicetype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisslice(t.type_: *tinfo); + return syntax.typeisslice(t.type_: *syntax.tinfo); }; // resolvetagged — return the underlying N_TTAGGED node for `t`, or nil @@ -20963,16 +20963,16 @@ fn isslicetype(c: *cgen, t: *node) bool = { // `(invalid | overflow)` node. Use at sites that read variant lists // or detect nullable folding off a scrutinee — cgmatch, cgtypetest, // cgtypeassert — so aliased `!(A|B)` shapes still dispatch. -export fn resolvetagged(c: *cgen, t: *node) *node = { - let r: *node = resolvetype(c, t); +export fn resolvetagged(c: *cgen, t: *syntax.node) *syntax.node = { + let r: *syntax.node = resolvetype(c, t); if (r == nil) { return nil; }; - if (r.kind == nkind.N_TBANG) { - let inner: *node = r.lhs; + if (r.kind == syntax.nkind.N_TBANG) { + let inner: *syntax.node = r.lhs; if (inner == nil) { return nil; }; r = resolvetype(c, inner); if (r == nil) { return nil; }; }; - if (r.kind == nkind.N_TTAGGED) { return r; }; + if (r.kind == syntax.nkind.N_TTAGGED) { return r; }; return nil; }; @@ -20981,41 +20981,41 @@ export fn resolvetagged(c: *cgen, t: *node) *node = { // @match_spill slot at first use (#15 first-use+fail-loud convergence). // IDENT scrutinees use a different lookup path (read off the local // directly, no spill) so this returns nil for them too. -fn matchscrutt(c: *cgen, scrut: *node) *node = { +fn matchscrutt(c: *cgen, scrut: *syntax.node) *syntax.node = { if (scrut == nil) { return nil; }; - let k: nkind = scrut.kind; - if (k == nkind.N_IDENT) { return nil; }; - if (k == nkind.N_CALL) { - let callee: *node = scrut.lhs; + let k: syntax.nkind = scrut.kind; + if (k == syntax.nkind.N_IDENT) { return nil; }; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = scrut.lhs; if (callee != nil) { let cnm: str; cnm.ptr = nil; cnm.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { cnm = callee.str; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_IDENT) { cnm = callee.str; }; + if (callee.kind == syntax.nkind.N_DOT) { cnm = callee.str; // Same-module-first disambiguation: a leaf collision // on `next` (utf8.next + caller-side next) otherwise // returns the last-declared (caller) rtype and the // 4-arm match collapses arms 2+ to tag 0. Task #31. if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cnm.len > 0) { - let rtyp: *node = fnretlookupmod(c, cnm, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cnm, cmod); if (rtyp != nil) { return resolvetagged(c, rtyp); }; }; }; return nil; }; - if (k == nkind.N_INDEX) { - let ibase: *node = scrut.lhs; + if (k == syntax.nkind.N_INDEX) { + let ibase: *syntax.node = scrut.lhs; if (ibase == nil) { return nil; }; - if (ibase.kind != nkind.N_IDENT) { + if (ibase.kind != syntax.nkind.N_IDENT) { // #48: non-ident index base (s.field[i], call()[i], // nested). Only idents carry a declared tnode to walk, // so resolve from the checker-stamped element tinfo @@ -21028,16 +21028,16 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { return nil; }; let bl: *local = localfindnode(c, ibase.str); - let btn: *node = nil; + let btn: *syntax.node = nil; if (bl != nil) { btn = bl.tnode; } else { btn = letvartnode(c, ibase.str); }; if (btn == nil) { return nil; }; // idxelemtn: `*[N]T` drills to the pointee array's element (#61). - let etn: *node = idxelemtn(btn); + let etn: *syntax.node = idxelemtn(btn); if (etn == nil) { return nil; }; return resolvetagged(c, etn); }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // #67: read the field's stamped tinfo off the N_DOT node // (post-#66 N_DOT carries the field type) instead of the // dotfieldtnode AST walk. cgmatch's gate reads scrutt.type_ @@ -21052,7 +21052,7 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { // non-ident N_INDEX/N_DOT arms (`match (*p)` spill size + variant // indices key off scrut.type_; pre-#46 nil here clamped the // variant to 0 and mis-sized @match_spill). - if (k == nkind.N_UN && scrut.op == tkind.TK_STAR) { + if (k == syntax.nkind.N_UN && scrut.op == syntax.tkind.TK_STAR) { if (!istaggedtype(c, scrut)) { return nil; }; return scrut; }; @@ -21065,7 +21065,7 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { // when the scrutinee type can't be resolved keeps the historical // alloc for non-tagged / unresolved cases. Called by cgmatch at first // use; #15 first-use+fail-loud pins this size per fn. -fn matchspillsz(c: *cgen, scrutt: *node) i32 = { +fn matchspillsz(c: *cgen, scrutt: *syntax.node) i32 = { if (scrutt == nil) { return 16; }; let sz: i32 = slotsize(c, scrutt); if (sz <= 0) { return 16; }; @@ -21081,13 +21081,13 @@ fn matchspillsz(c: *cgen, scrutt: *node) i32 = { // scalar catch-all, the second-half value registers (DX/CX) were // never spilled, and field reads from the under-allocated slot // trailed into the saved-BP word. -fn structparamsize(c: *cgen, t: *node) i32 = { +fn structparamsize(c: *cgen, t: *syntax.node) i32 = { if (c == nil) { return 0; }; - let r: *node = resolvetype(c, t); + let r: *syntax.node = resolvetype(c, t); if (r == nil) { return 0; }; - if (r.kind != nkind.N_TNAME) { return 0; }; + if (r.kind != syntax.nkind.N_TNAME) { return 0; }; let nm: str = r.str; - if (streq(nm, "str")) { return 0; }; + if (syntax.streq(nm, "str")) { return 0; }; if (aliasprimsize(c, nm) > 0) { return 0; }; let si: *structinfo = structlookup(c, nm); if (si == nil) { return 0; }; @@ -21101,12 +21101,12 @@ fn structparamsize(c: *cgen, t: *node) i32 = { // ≤16B-struct structparamsize carve-out doesn't cover: arrays of any // size and structs > 16B. Reads the stamped tinfo size (the type table, // byte-id with cstage Type.size). -fn aggargsizetn(t: *tinfo) i32 = { +fn aggargsizetn(t: *syntax.tinfo) i32 = { if (t == nil) { return 0; }; - let u: *tinfo = t; + let u: *syntax.tinfo = t; u = tichase(u); if (u == nil) { return 0; }; - if (u.kind == tykind.TY_STRUCT || u.kind == tykind.TY_ARRAY) { + if (u.kind == syntax.tykind.TY_STRUCT || u.kind == syntax.tykind.TY_ARRAY) { return u.size: i32; }; return 0; @@ -21119,12 +21119,12 @@ fn aggargsizetn(t: *tinfo) i32 = { // positive BP offsets. Mirror of cstage tagged_memarg_size; ABI shape // per ref/qbe/amd64/sysv.c:80-85 (inmem) / :411-426 (stack blit). The // ≤48B register convention is pinned in-tree (test/926 boundary rows). -fn taggedmemargsize(t: *tinfo) i32 = { +fn taggedmemargsize(t: *syntax.tinfo) i32 = { if (t == nil) { return 0; }; - let u: *tinfo = t; + let u: *syntax.tinfo = t; u = tichase(u); if (u == nil) { return 0; }; - if (u.kind != tykind.TY_TAGGED) { return 0; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return 0; }; if (u.nullable != 0) { return 0; }; // sizelint-ok: 6 SysV int arg regs (DI..R9) x 8B words — the // same register-capacity constant as cstage tagged_arg_size. @@ -21132,9 +21132,9 @@ fn taggedmemargsize(t: *tinfo) i32 = { return u.size: i32; }; -fn nodeisaggarg(n: *node) bool = { +fn nodeisaggarg(n: *syntax.node) bool = { if (n == nil) { return false; }; - return aggargsizetn(n.type_: *tinfo) > 0; + return aggargsizetn(n.type_: *syntax.tinfo) > 0; }; // aggargfloatstop — true iff the arg is a ≤16B struct with any float @@ -21142,16 +21142,16 @@ fn nodeisaggarg(n: *node) bool = { // the SSE eightbyte transport the GP aggregate push/drain can't model; // both stages loud-stop on it. Same predicate as the cstage Tfield // fld_isfloat walk (cmd/w6c/cgen.c #271 push arm). -fn aggargfloatstop(n: *node) bool = { +fn aggargfloatstop(n: *syntax.node) bool = { if (n == nil) { return false; }; - let st: *tinfo = n.type_: *tinfo; + let st: *syntax.tinfo = n.type_: *syntax.tinfo; st = tichase(st); if (st == nil) { return false; }; - if (st.kind != tykind.TY_STRUCT) { return false; }; + if (st.kind != syntax.tykind.TY_STRUCT) { return false; }; if (st.size: i32 > 16) { return false; }; - let f: *tfield = st.fields; + let f: *syntax.tfield = st.fields; for (f != nil) { - if (typeisfloat(f.type_)) { return true; }; + if (syntax.typeisfloat(f.type_)) { return true; }; f = f.tnext; }; return false; @@ -21170,13 +21170,13 @@ fn aggargfloatstop(n: *node) bool = { // eightbyte is pure-INT or a lone f64 AND at least one is f64. f32 / // sub-eightbyte packing deferred (#165b). Mirrors cstage // struct_float_class (cmd/w6c/cgen.c). -fn structfloatclass(c: *cgen, t: *node) i32 = { +fn structfloatclass(c: *cgen, t: *syntax.node) i32 = { if (c == nil) { return 0; }; - let r: *node = resolvetype(c, t); + let r: *syntax.node = resolvetype(c, t); if (r == nil) { return 0; }; - if (r.kind != nkind.N_TNAME) { return 0; }; + if (r.kind != syntax.nkind.N_TNAME) { return 0; }; let nm: str = r.str; - if (streq(nm, "str")) { return 0; }; + if (syntax.streq(nm, "str")) { return 0; }; if (aliasprimsize(c, nm) > 0) { return 0; }; let si: *structinfo = structlookup(c, nm); if (si == nil) { return 0; }; @@ -21211,10 +21211,10 @@ fn structfloatclass(c: *cgen, t: *node) i32 = { // and every tuple field; the fsz>8 guard below also lets a // <=8B one slip, so such a struct would wrongly SSE-route on // this stage but stay GP on cstage (a #165b leak). - let rf: *node = resolvetype(c, fi.tnode); + let rf: *syntax.node = resolvetype(c, fi.tnode); if (rf != nil) { - if (rf.kind == nkind.N_TARRAY) { return 0; }; - if (rf.kind == nkind.N_TTUPLE) { return 0; }; + if (rf.kind == syntax.nkind.N_TARRAY) { return 0; }; + if (rf.kind == syntax.nkind.N_TTUPLE) { return 0; }; }; if (fsz > 8) { return 0; }; if ((foff + fsz - 1) / 8 != e) { return 0; }; @@ -21239,49 +21239,49 @@ fn structfloatclass(c: *cgen, t: *node) i32 = { // resolve to TY_TAGGED — tinfofornode handles the N_TBANG unwrap // (check.ww:1145) so we don't re-walk it here. Cite cstage cgen.c // (`type_chase_named` + TY_TAGGED). Collapsed per A.6.3b (#46). -fn istaggedtype(c: *cgen, t: *node) bool = { +fn istaggedtype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeistagged(t.type_: *tinfo); + return syntax.typeistagged(t.type_: *syntax.tinfo); }; // tnodeisagg — struct/array/tuple kind off the checker-STAMPED tinfo // (the #49 funnel predicate; #209/#211 discipline — never tnode // names). Mirror of cstage's chase-then-kind test at the fill / // assign aggregate arms. -fn tnodeisagg(t: *node) bool = { +fn tnodeisagg(t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *tinfo = t.type_: *tinfo; + let u: *syntax.tinfo = t.type_: *syntax.tinfo; u = tichase(u); if (u == nil) { return false; }; - if (u.kind == tykind.TY_STRUCT) { return true; }; - if (u.kind == tykind.TY_ARRAY) { return true; }; - return u.kind == tykind.TY_TUPLE; + if (u.kind == syntax.tykind.TY_STRUCT) { return true; }; + if (u.kind == syntax.tykind.TY_ARRAY) { return true; }; + return u.kind == syntax.tykind.TY_TUPLE; }; // isfloattype — f32 / f64 / untyped_float (alias-aware). Cite cstage // cgen.c:117 `cg_isfloat`. Dispatches MOVSS/MOVSD-shaped paths across // cglet, cgident, cgassign, cgbin, cgcast, cgcall, cgreturn, fn- // prologue. Collapsed per A.6.3b (#46). -export fn isfloattype(c: *cgen, t: *node) bool = { +export fn isfloattype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisfloat(t.type_: *tinfo); + return syntax.typeisfloat(t.type_: *syntax.tinfo); }; // isf32type — narrower: true only for f32 (after alias chase). Cite // cstage cgen.c:188 `type_isf32`. Picks MOVSS vs MOVSD and the SS- // variant arithmetic / cast opcodes. Collapsed per A.6.3b (#46). -export fn isf32type(c: *cgen, t: *node) bool = { +export fn isf32type(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisf32(t.type_: *tinfo); + return syntax.typeisf32(t.type_: *syntax.tinfo); }; // isnullabletype — `(*T | void)` one-word fold per Hare's // `(*T | null)` semantics. Cite cstage cgen.c:396 `type_isnullable`; // the .nullable flag lands on tinfo at check.ww:1309-1318 when the // two-variant shape matches. Collapsed per A.6.3b (#46). -export fn isnullabletype(t: *node) bool = { +export fn isnullabletype(t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisnullable(t.type_: *tinfo); + return syntax.typeisnullable(t.type_: *syntax.tinfo); }; // nullableptrtag — 0-based index of the *T variant in a nullable @@ -21289,9 +21289,9 @@ export fn isnullabletype(t: *node) bool = { // scan ti.params, strip TY_NAMED on each variant, return idx of first // TY_PTR. Phase 1 (26724fe) populated the chain in tinfofornode's // TTAGGED arm so this walk could retire the AST-keyed predecessor. -export fn nullableptrtag(t: *node) i32 = { +export fn nullableptrtag(t: *syntax.node) i32 = { if (t == nil) { return 0; }; - let ti: *tinfo = t.type_: *tinfo; + let ti: *syntax.tinfo = t.type_: *syntax.tinfo; if (ti == nil) { return 0; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel @@ -21299,19 +21299,19 @@ export fn nullableptrtag(t: *node) i32 = { // NAMED to the alias-invariant underlying this read consumes. ti = tichase(ti); if (ti == nil) { return 0; }; - if (ti.kind != tykind.TY_TAGGED) { return 0; }; - let p: *tparam = ti.params; + if (ti.kind != syntax.tykind.TY_TAGGED) { return 0; }; + let p: *syntax.tparam = ti.params; let i: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; + let vt: *syntax.tinfo = p.type_; if (vt != nil) { // peel-ok: single peel PROBE-CLEARED (batch-2 c3-B2, // 018ef66) — constructible variant params never carry // 2+-level NAMED at this scan; cs twin nullable_ptr_tag // (cmd/w6c/cgen.c:747) keeps the identical single peel. - if (vt.kind == tykind.TY_NAMED) { vt = vt.under; }; + if (vt.kind == syntax.tykind.TY_NAMED) { vt = vt.under; }; if (vt != nil) { - if (vt.kind == tykind.TY_PTR) { return i; }; + if (vt.kind == syntax.tykind.TY_PTR) { return i; }; }; }; p = p.tnext; @@ -21332,18 +21332,18 @@ export fn nullableptrtag(t: *node) i32 = { // Mirrors cstage cg_tag_for_variant(rt, ty_void) (cmd/w6c/cgen.c:900-911): // chase NAMED, scan params, match bare TY_VOID (not `!void`, carried by the // tparam iserror flag). -fn voidvariantindex(tagged: *node) i32 = { +fn voidvariantindex(tagged: *syntax.node) i32 = { if (tagged == nil) { return -1; }; - let ti: *tinfo = tagged.type_: *tinfo; + let ti: *syntax.tinfo = tagged.type_: *syntax.tinfo; if (ti == nil) { return -1; }; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; - let p: *tparam = ti.params; + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; - if (vt != nil && vt.kind == tykind.TY_VOID && !p.iserror) { + let vt: *syntax.tinfo = p.type_; + if (vt != nil && vt.kind == syntax.tykind.TY_VOID && !p.iserror) { return idx; }; p = p.tnext; @@ -21356,9 +21356,9 @@ fn voidvariantindex(tagged: *node) i32 = { // returned value's surface type, find the matching variant's 0-based // index. Compare by exact type name first; if no match, fall back to // "any str-shape variant matches an str-typed value". -fn taggedvariantindex(c: *cgen, tagged: *node, rhs: *node) i32 = { +fn taggedvariantindex(c: *cgen, tagged: *syntax.node, rhs: *syntax.node) i32 = { if (tagged == nil) { return -1; }; - return taggedvariantindext(c, tagged.type_: *tinfo, rhs); + return taggedvariantindext(c, tagged.type_: *syntax.tinfo, rhs); }; // taggedvariantindext — tinfo-keyed core of taggedvariantindex. Given @@ -21373,14 +21373,14 @@ fn taggedvariantindex(c: *cgen, tagged: *node, rhs: *node) i32 = { // pass 1 (cgvariantmatch's tyassignableuntyped arm, the cg_variant_match // :801 mirror); the str/slice shape scan below covers the remaining // LOOSE sources (concrete types that typeeq no variant). -fn taggedvariantindext(c: *cgen, du: *tinfo, rhs: *node) i32 = { +fn taggedvariantindext(c: *cgen, du: *syntax.tinfo, rhs: *syntax.node) i32 = { if (du == nil) { return -1; }; if (rhs == nil) { return -1; }; - let ti: *tinfo = du; + let ti: *syntax.tinfo = du; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; - let r: i32 = flatvariantidxt(ti, rhs.type_: *tinfo, false); + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; + let r: i32 = flatvariantidxt(ti, rhs.type_: *syntax.tinfo, false); if (r >= 0) { return r; }; // Shape fallback: classify rhs as (str, slice, scalar/other) and // pick the first variant of matching shape. Covers LOOSE concrete @@ -21392,12 +21392,12 @@ fn taggedvariantindext(c: *cgen, du: *tinfo, rhs: *node) i32 = { // walk collapses to a flat scan over p.type_. let wantstr: bool = nodeisstr(c, rhs); let wantslice: bool = nodeisslice(c, rhs); - let p: *tparam = ti.params; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; - let visstr: bool = typeisstr(vt); - let visslice: bool = typeisslice(vt); + let vt: *syntax.tinfo = p.type_; + let visstr: bool = syntax.typeisstr(vt); + let visslice: bool = syntax.typeisslice(vt); if (visstr == wantstr && visslice == wantslice) { return idx; }; p = p.tnext; idx += 1; @@ -21419,10 +21419,10 @@ fn taggedvariantindext(c: *cgen, du: *tinfo, rhs: *node) i32 = { // ptr-id (typeeq, typ.ww:514), one-NAMED → kind mismatch → false. ww has // no type_assignable, so the untyped/loose arm (cg_variant_match's first // branch) lives in the caller's str/slice shape fallback, not here. -fn flatvariantidx(c: *cgen, tagged: *node, pat: *node) i32 = { +fn flatvariantidx(c: *cgen, tagged: *syntax.node, pat: *syntax.node) i32 = { if (tagged == nil) { return -1; }; if (pat == nil) { return -1; }; - return flatvariantidxt(tagged.type_: *tinfo, pat.type_: *tinfo, false); + return flatvariantidxt(tagged.type_: *syntax.tinfo, pat.type_: *syntax.tinfo, false); }; // flatvariantidxt — tinfo-keyed core of flatvariantidx: flat 0-based @@ -21442,16 +21442,16 @@ fn flatvariantidx(c: *cgen, tagged: *node, pat: *node) i32 = { // consumers, two modes — not a wrapper. cstage has no twin: its is/as // gate (check.c:2036) never calls cg_tag_for_variant, so cg_tag_for_variant // stays full-only there. -fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { +fn flatvariantidxt(tagged: *syntax.tinfo, want: *syntax.tinfo, exactonly: bool) i32 = { if (want == nil) { return -1; }; - let ti: *tinfo = tagged; + let ti: *syntax.tinfo = tagged; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; // Pass 1: exact match (NAMED-vs-NAMED typeeq, tagged-vs-tagged, bare // typeeq). Exact matches take precedence and need no guard — distinct // variants don't exact-match the same source. - let p: *tparam = ti.params; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { if (cgvariantmatch(p.type_, want)) { return idx; }; @@ -21473,10 +21473,10 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // disambiguated once the nominal-lossy model collapses the chain — // hard-error (drew's ambiguity proviso extended to the chained // set). cs twin cg_tag_for_variant fused in this commit. - if (want.kind == tykind.TY_NAMED) { - let sb: *tinfo = tichase(want); + if (want.kind == syntax.tykind.TY_NAMED) { + let sb: *syntax.tinfo = tichase(want); if (sb == nil) { return -1; }; - let q: *tparam = ti.params; + let q: *syntax.tparam = ti.params; let qi: i32 = 0; let found: i32 = -1; let n: i32 = 0; @@ -21512,7 +21512,7 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { q = ti.params; qi = 0; for (q != nil) { - if (q.type_ != nil && typeeq(tichase(q.type_), sb)) { + if (q.type_ != nil && syntax.typeeq(tichase(q.type_), sb)) { if (found < 0) { found = qi; }; n += 1; }; @@ -21536,8 +21536,8 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // exact `i64`. drew's proviso: guard the structural fallback like the // #218 nested-widen site — a bare source matching >=2 NAMED variants // needs nominal layout to disambiguate, so hard-error. - if (want.kind != tykind.TY_NAMED) { - let q: *tparam = ti.params; + if (want.kind != syntax.tykind.TY_NAMED) { + let q: *syntax.tparam = ti.params; let qi: i32 = 0; let found: i32 = -1; let n: i32 = 0; @@ -21551,9 +21551,9 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // below now guards the CHASED match set. cs twin // cg_tag_for_variant fused in this commit (probe: // both-wrong-identical pre-fix). - let pu: *tinfo = q.type_; - if (pu != nil && pu.kind == tykind.TY_NAMED - && typeeq(tichase(pu), want)) { + let pu: *syntax.tinfo = q.type_; + if (pu != nil && pu.kind == syntax.tykind.TY_NAMED + && syntax.typeeq(tichase(pu), want)) { if (found < 0) { found = qi; }; n += 1; }; @@ -21576,7 +21576,7 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // (type.c:316-324) for a variant that is itself a union. ww's checker // isassignable is node-keyed (AST type exprs), so the tinfo-keyed // widen/match funnel needs this focused mirror (#33). -fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { +fn tyassignableuntyped(dst: *syntax.tinfo, want: *syntax.tinfo) bool = { if (dst == nil) { return false; }; if (want == nil) { return false; }; // c4 (rob RE-RULE 2026-06-05): FULL chase, not the one-level unwrap @@ -21587,8 +21587,8 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // alias variant silently mis-tagged 0 (the str twin was masked by // taggedvariantindext's shape fallback). Aligns ww UP to the cs // twin cmd/wcc/type.c:369-385, harec-shaped since F1 9bd0d8b. - let du: *tinfo = tichase(dst); - if (du != nil && du.kind == tykind.TY_TAGGED) { + let du: *syntax.tinfo = tichase(dst); + if (du != nil && du.kind == syntax.tykind.TY_TAGGED) { // concrete→tagged drill (type.c:316-324): a NESTED tagged // variant compares by type_eq there — never equal to an // untyped source — so only non-tagged variants recurse, on @@ -21596,12 +21596,12 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // detected via the full chase (was one-level: a 2-level // alias-tagged variant slipped INTO the recursion, diverging // from cs's checker-level #199α reject — see the c4 finding). - let p: *tparam = du.params; + let p: *syntax.tparam = du.params; for (p != nil) { - let pu: *tinfo = tichase(p.type_); + let pu: *syntax.tinfo = tichase(p.type_); let nestedtagged: bool = false; if (pu != nil) { - if (pu.kind == tykind.TY_TAGGED) { nestedtagged = true; }; + if (pu.kind == syntax.tykind.TY_TAGGED) { nestedtagged = true; }; }; if (!nestedtagged) { if (tyassignableuntyped(p.type_, want)) { return true; }; @@ -21613,26 +21613,26 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // type.c:369-385 — INT/FLOAT/RUNE run on the UNPEELED dst exactly // like cs (typeisnum/typeisfloat/typeisint self-recurse TY_NAMED); // STR/BOOL/NIL read the chased du like cs reads its chased du. - if (want.kind == tykind.TY_UNTYPED_INT) { return typeisnum(dst); }; - if (want.kind == tykind.TY_UNTYPED_FLOAT) { return typeisfloat(dst); }; - if (want.kind == tykind.TY_UNTYPED_STR) { + if (want.kind == syntax.tykind.TY_UNTYPED_INT) { return syntax.typeisnum(dst); }; + if (want.kind == syntax.tykind.TY_UNTYPED_FLOAT) { return syntax.typeisfloat(dst); }; + if (want.kind == syntax.tykind.TY_UNTYPED_STR) { if (du == nil) { return false; }; - return du.kind == tykind.TY_STR; + return du.kind == syntax.tykind.TY_STR; }; - if (want.kind == tykind.TY_UNTYPED_RUNE) { - if (typeisint(dst)) { return true; }; - return dst.kind == tykind.TY_RUNE; + if (want.kind == syntax.tykind.TY_UNTYPED_RUNE) { + if (syntax.typeisint(dst)) { return true; }; + return dst.kind == syntax.tykind.TY_RUNE; }; - if (want.kind == tykind.TY_UNTYPED_BOOL) { + if (want.kind == syntax.tykind.TY_UNTYPED_BOOL) { if (du == nil) { return false; }; - return du.kind == tykind.TY_BOOL; + return du.kind == syntax.tykind.TY_BOOL; }; - if (want.kind == tykind.TY_UNTYPED_NIL) { + if (want.kind == syntax.tykind.TY_UNTYPED_NIL) { if (du == nil) { return false; }; - if (du.kind == tykind.TY_PTR) { return true; }; - if (du.kind == tykind.TY_SLICE) { return true; }; - if (du.kind == tykind.TY_CHAN) { return true; }; - return du.kind == tykind.TY_FN; + if (du.kind == syntax.tykind.TY_PTR) { return true; }; + if (du.kind == syntax.tykind.TY_SLICE) { return true; }; + if (du.kind == syntax.tykind.TY_CHAN) { return true; }; + return du.kind == syntax.tykind.TY_FN; }; return false; }; @@ -21650,7 +21650,7 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // nominal-lossy; the collision guard in cgwidentaggedstorebp enforces // the invariant for when #199b/B-full lands true nominal layout. // - neither NAMED → structural typeeq -fn cgvariantmatch(vt: *tinfo, want: *tinfo) bool = { +fn cgvariantmatch(vt: *syntax.tinfo, want: *syntax.tinfo) bool = { if (vt == nil) { return false; }; if (want == nil) { return false; }; // #33: pre-fix an untyped scalar fell past the typeeq passes to @@ -21658,23 +21658,23 @@ fn cgvariantmatch(vt: *tinfo, want: *tinfo) bool = { // non-str/slice variant can be `void` — a bare // `let e: (void | size) = 5` stored tag 0 while the is/as side // resolved `size` to 1 (wwstage-only; cstage resolves here). - if (typeisuntyped(want)) { return tyassignableuntyped(vt, want); }; - if (vt.kind == tykind.TY_NAMED && want.kind == tykind.TY_NAMED) { - return typeeq(vt, want); + if (syntax.typeisuntyped(want)) { return tyassignableuntyped(vt, want); }; + if (vt.kind == syntax.tykind.TY_NAMED && want.kind == syntax.tykind.TY_NAMED) { + return syntax.typeeq(vt, want); }; - if (vt.kind == tykind.TY_NAMED || want.kind == tykind.TY_NAMED) { - let vu: *tinfo = vt; + if (vt.kind == syntax.tykind.TY_NAMED || want.kind == syntax.tykind.TY_NAMED) { + let vu: *syntax.tinfo = vt; vu = tichase(vu); - let wu: *tinfo = want; + let wu: *syntax.tinfo = want; wu = tichase(wu); if (vu != nil && wu != nil - && vu.kind == tykind.TY_TAGGED - && wu.kind == tykind.TY_TAGGED) { - return typeeq(vu, wu); + && vu.kind == syntax.tykind.TY_TAGGED + && wu.kind == syntax.tykind.TY_TAGGED) { + return syntax.typeeq(vu, wu); }; return false; }; - return typeeq(vt, want); + return syntax.typeeq(vt, want); }; // cgvariantstructmatch — structural equality ignoring nominal identity @@ -21682,14 +21682,14 @@ fn cgvariantmatch(vt: *tinfo, want: *tinfo) bool = { // variants share the source's *shape*; ≥2 means the structural fallback // could not disambiguate them once nominal identity is lost. Mirrors // cstage cg_variant_struct_match (cmd/w6c/cgen.c). -fn cgvariantstructmatch(vt: *tinfo, want: *tinfo) bool = { - let vu: *tinfo = vt; +fn cgvariantstructmatch(vt: *syntax.tinfo, want: *syntax.tinfo) bool = { + let vu: *syntax.tinfo = vt; vu = tichase(vu); - let wu: *tinfo = want; + let wu: *syntax.tinfo = want; wu = tichase(wu); if (vu == nil) { return false; }; if (wu == nil) { return false; }; - return typeeq(vu, wu); + return syntax.typeeq(vu, wu); }; // flatslicevariantidx — flat 0-based index of a slice-shape variant in @@ -21703,27 +21703,27 @@ fn cgvariantstructmatch(vt: *tinfo, want: *tinfo) bool = { // #66 Phase-N step 3: element compare flips from surface-name to // typeeq(p.type_.sub, elem.type_). Mirrors cstage cg_tag_for_variant // over Type->params. Returns -1 when no slice variant exists. -fn flatslicevariantidx(c: *cgen, tagged: *node, elem: *node) i32 = { +fn flatslicevariantidx(c: *cgen, tagged: *syntax.node, elem: *syntax.node) i32 = { if (tagged == nil) { return -1; }; - let ti: *tinfo = tagged.type_: *tinfo; + let ti: *syntax.tinfo = tagged.type_: *syntax.tinfo; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; - let want: *tinfo = nil; - if (elem != nil) { want = elem.type_: *tinfo; }; + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; + let want: *syntax.tinfo = nil; + if (elem != nil) { want = elem.type_: *syntax.tinfo; }; let fallback: i32 = -1; - let p: *tparam = ti.params; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; + let vt: *syntax.tinfo = p.type_; if (vt != nil) { - if (typeisslice(vt)) { + if (syntax.typeisslice(vt)) { if (fallback < 0) { fallback = idx; }; if (want != nil) { - let su: *tinfo = vt; + let su: *syntax.tinfo = vt; su = tichase(su); if (su != nil) { - if (typeeq(su.sub, want)) { return idx; }; + if (syntax.typeeq(su.sub, want)) { return idx; }; }; }; }; @@ -21742,17 +21742,17 @@ fn flatslicevariantidx(c: *cgen, tagged: *node, elem: *node) i32 = { // TY_NAMED then walk su.params, mapping each source variant to its dst // index by typeeq (flatvariantidxt). Mirrors cg_widen_tag_remap // (cmd/w6c/cgen.c:1177) over su->params + cg_tag_for_variant (:503). -fn cgwidentagremap(c: *cgen, du: *tinfo, su: *tinfo, slot_off: i32) void = { - let dt: *tinfo = du; +fn cgwidentagremap(c: *cgen, du: *syntax.tinfo, su: *syntax.tinfo, slot_off: i32) void = { + let dt: *syntax.tinfo = du; dt = tichase(dt); if (dt == nil) { return; }; - if (dt.kind != tykind.TY_TAGGED) { return; }; - let st: *tinfo = su; + if (dt.kind != syntax.tykind.TY_TAGGED) { return; }; + let st: *syntax.tinfo = su; st = tichase(st); if (st == nil) { return; }; - if (st.kind != tykind.TY_TAGGED) { return; }; + if (st.kind != syntax.tykind.TY_TAGGED) { return; }; let identity: bool = true; - let p: *tparam = st.params; + let p: *syntax.tparam = st.params; let idx: i32 = 0; for (p != nil) { let di: i32 = flatvariantidxt(dt, p.type_, false); @@ -21799,12 +21799,12 @@ fn cgwidentagremap(c: *cgen, du: *tinfo, su: *tinfo, slot_off: i32) void = { // when the name is registered in c.structs — `!void` / `!i32` aliases // share the N_STRUCTLIT / N_TNAME shape but aren't structs, and must // fall through to the scalar/str/tagged-source paths instead. -fn rhsstructpayload(c: *cgen, src: *node) str = { +fn rhsstructpayload(c: *cgen, src: *syntax.node) str = { let empty: str; empty.ptr = nil; empty.len = 0; if (src == nil) { return empty; }; - if (src.kind == nkind.N_STRUCTLIT) { - let trefn: *node = src.lhs; + if (src.kind == syntax.nkind.N_STRUCTLIT) { + let trefn: *syntax.node = src.lhs; if (trefn != nil) { // #92: bare structlookup missed an alias-named literal // — `ali{...}` into a union fell to the scalar widen @@ -21819,12 +21819,12 @@ fn rhsstructpayload(c: *cgen, src: *node) str = { }; return empty; }; - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, src.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { + if (tn.kind == syntax.nkind.N_TNAME) { // #62 Layer-2 (F2 ww half): bare structlookup // missed an alias name (ali->base), so the // struct value fell to the SCALAR widen arm — @@ -21849,12 +21849,12 @@ fn rhsstructpayload(c: *cgen, src: *node) str = { // rhstaggedsource — return the tagged-type node for `src` when src is a // tagged-typed local ident; nil otherwise. The slot-copy path uses this // to walk variants for tag remap. -fn rhstaggedident(c: *cgen, src: *node) *node = { +fn rhstaggedident(c: *cgen, src: *syntax.node) *syntax.node = { if (src == nil) { return nil; }; - if (src.kind != nkind.N_IDENT) { return nil; }; + if (src.kind != syntax.nkind.N_IDENT) { return nil; }; let lc: *local = localfindnode(c, src.str); if (lc == nil) { return nil; }; - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (!istaggedtype(c, tn)) { return nil; }; return resolvetagged(c, tn); }; @@ -21865,9 +21865,9 @@ fn rhstaggedident(c: *cgen, src: *node) *node = { // #28's cgdot fix loads AX/DX/CX/R8 from the field's slot). Used to // decide whether cgexpr/spill works for the tagged-source branch of // cgwidentaggedstore. -fn rhstaggedabicall(c: *cgen, src: *node) bool = { +fn rhstaggedabicall(c: *cgen, src: *syntax.node) bool = { if (src == nil) { return false; }; - if (src.kind == nkind.N_CALL) { + if (src.kind == syntax.nkind.N_CALL) { // #211: a call's result type is the CALLEE's fn-type ret, which // the checker stamps onto this N_CALL node (check.ww N_CALL: both // the SK_FN path and the fn-VALUE/field path set e.type_ = the @@ -21878,10 +21878,10 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // sister reads u->ret off the callee type (cmd/wcc/check.c:1433, // :1490); harec selects by interned type id, not name (ref/harec/ // src/types.c:714). Mirrors the N_DOT branch below. - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; return false; }; - if (src.kind == nkind.N_INDEX) { + if (src.kind == syntax.nkind.N_INDEX) { // The checker stamps every N_INDEX node's type_ to the element // tinfo (check.ww:2334-2337 indexresult) for ANY base shape — // N_IDENT, N_DOT (`x.o[i]`), or chained N_INDEX (`m[i][j]`). Read @@ -21891,7 +21891,7 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // so a tagged element materialized via `x.o[i]` (correct AX/DX // slot from cgindex) was then spilled by the scalar-widen arm, // dropping the tag/payload-high word — silent cs≠ww. - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; return false; }; // N_DOT of a tagged-typed struct field — cgdot loads @@ -21901,19 +21901,19 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // stamp) instead of re-deriving via dotfieldtnode — matches // cstage cg_widen_tagged_store reading src->type directly // (cmd/w6c/cgen.c:1302-1305). typeistagged(nil) is false. - if (src.kind == nkind.N_DOT) { - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (src.kind == syntax.nkind.N_DOT) { + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; }; // Family C (#35/#46): a DEREF source is mem-based (taggedmemread, // any size) — the widen-store's memread arm copies the box from // the address cgexpr leaves in AX. An unwrap (`?`/`!`) source // fills the cursor after the tagged-success payload shift (the // cgtryprop/cgtryunw twin of cstage's kind-blind su-tagged arm). - if (src.kind == nkind.N_UN && src.op == tkind.TK_STAR) { - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (src.kind == syntax.nkind.N_UN && src.op == syntax.tkind.TK_STAR) { + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; }; - if (src.kind == nkind.N_TRYPROP || src.kind == nkind.N_TRYUNW) { - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (src.kind == syntax.nkind.N_TRYPROP || src.kind == syntax.nkind.N_TRYUNW) { + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; }; return false; }; @@ -21930,21 +21930,21 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // (which carried only the tag) and consumers copy from memory. ≤32B // INDEX/DOT keep the cursor byte-for-byte (the #37 no-drift bar); // the nullable one-word fold stays a scalar deref. -fn taggedmemread(c: *cgen, e: *node) bool = { +fn taggedmemread(c: *cgen, e: *syntax.node) bool = { if (e == nil) { return false; }; - if (e.kind == nkind.N_UN && e.op == tkind.TK_STAR) { - let du: *tinfo = e.type_: *tinfo; + if (e.kind == syntax.nkind.N_UN && e.op == syntax.tkind.TK_STAR) { + let du: *syntax.tinfo = e.type_: *syntax.tinfo; du = tichase(du); if (du == nil) { return false; }; - if (du.kind != tykind.TY_TAGGED) { return false; }; + if (du.kind != syntax.tykind.TY_TAGGED) { return false; }; if (du.nullable != 0) { return false; }; return du.size: i32 > 8; }; - if (e.kind != nkind.N_INDEX && e.kind != nkind.N_DOT) { return false; }; - let u: *tinfo = e.type_: *tinfo; + if (e.kind != syntax.nkind.N_INDEX && e.kind != syntax.nkind.N_DOT) { return false; }; + let u: *syntax.tinfo = e.type_: *syntax.tinfo; u = tichase(u); if (u == nil) { return false; }; - if (u.kind != tykind.TY_TAGGED) { return false; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return false; }; return u.size: i32 > TUPLE_GPCAP * 8; }; @@ -21956,17 +21956,17 @@ fn taggedmemread(c: *cgen, e: *node) bool = { // variant casts (`7: size`) keep their node for variant-tag lookup; // the nullable one-word fold never spills a cursor — excluded. // Mirrors cstage cg_tagged_castpeel. -fn taggedcastpeel(c: *cgen, e: *node) *node = { - for (e != nil && e.kind == nkind.N_CAST && e.lhs != nil) { - let cu: *tinfo = e.type_: *tinfo; +fn taggedcastpeel(c: *cgen, e: *syntax.node) *syntax.node = { + for (e != nil && e.kind == syntax.nkind.N_CAST && e.lhs != nil) { + let cu: *syntax.tinfo = e.type_: *syntax.tinfo; cu = tichase(cu); if (cu == nil) { return e; }; - if (cu.kind != tykind.TY_TAGGED) { return e; }; + if (cu.kind != syntax.tykind.TY_TAGGED) { return e; }; if (cu.nullable != 0) { return e; }; - let iu: *tinfo = e.lhs.type_: *tinfo; + let iu: *syntax.tinfo = e.lhs.type_: *syntax.tinfo; iu = tichase(iu); if (iu == nil) { return e; }; - if (iu.kind != tykind.TY_TAGGED) { return e; }; + if (iu.kind != syntax.tykind.TY_TAGGED) { return e; }; if (iu.nullable != 0) { return e; }; e = e.lhs; }; @@ -21979,13 +21979,13 @@ fn taggedcastpeel(c: *cgen, e: *node) *node = { // cast changes the tag numbering and must NOT be peeled — those die // loud at the consumer's cast catch-all instead. Mirrors cstage // cg_tagged_idcastpeel. -fn taggedidcastpeel(c: *cgen, e: *node) *node = { - for (e != nil && e.kind == nkind.N_CAST && e.lhs != nil) { - if (!typeeq(e.type_: *tinfo, e.lhs.type_: *tinfo)) { return e; }; - let cu: *tinfo = e.type_: *tinfo; +fn taggedidcastpeel(c: *cgen, e: *syntax.node) *syntax.node = { + for (e != nil && e.kind == syntax.nkind.N_CAST && e.lhs != nil) { + if (!syntax.typeeq(e.type_: *syntax.tinfo, e.lhs.type_: *syntax.tinfo)) { return e; }; + let cu: *syntax.tinfo = e.type_: *syntax.tinfo; cu = tichase(cu); if (cu == nil) { return e; }; - if (cu.kind != tykind.TY_TAGGED) { return e; }; + if (cu.kind != syntax.tykind.TY_TAGGED) { return e; }; e = e.lhs; }; return e; @@ -22062,9 +22062,9 @@ fn cgloadtaggedfield(c: *cgen, basereg: str, foff: i32, slot_sz: i32) void = { // tag last. // - str src: tag@+0, ptr@+8, len@+16, cap@+24 (str IS []u8, #1/Phase 3). // - scalar src: tag@+0, value@+8. -fn cgwidentaggedstore(c: *cgen, dst: *tinfo, src: *node, +fn cgwidentaggedstore(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, basereg: str, slot_off: i32, slot_sz: i32) void = { - if (streq(basereg, "BP")) { + if (syntax.streq(basereg, "BP")) { cgwidentaggedstorebp(c, dst, src, slot_off, slot_sz); return; }; @@ -22111,16 +22111,16 @@ fn cgwidentaggedstore(c: *cgen, dst: *tinfo, src: *node, // for the natural "BP" case and via the wrapper's scratch path for // pointer-rooted dst. Direct callers exist only in case of future // inlined uses inside this file; new code should call the wrapper. -fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_sz: i32) void = { +fn cgwidentaggedstorebp(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, slot_off: i32, slot_sz: i32) void = { // #68: dst is the tagged tinfo. Peel TY_NAMED → du and gate // TY_TAGGED, mirroring cstage cg_widen_tagged_store's // `du = (dst->kind==TY_NAMED)?dst->under:dst` + TY_TAGGED guard // (cmd/w6c/cgen.c:1273). resolvetagged's N_TBANG unwrap is already // handled upstream by tinfofornode (check.ww:1203-1210). - let dt: *tinfo = dst; + let dt: *syntax.tinfo = dst; dt = tichase(dt); if (dt == nil) { return; }; - if (dt.kind != tykind.TY_TAGGED) { return; }; + if (dt.kind != syntax.tykind.TY_TAGGED) { return; }; // Nullable fold: one 8B word holding the pointer (or 0 for void). if (dt.nullable != 0) { cgexpr(c, src); @@ -22143,11 +22143,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // a concrete variant (`7: i32`) is left intact so the existing // scalar / str / slice branches pick the right variant tag. if (src != nil) { - if (src.kind == nkind.N_CAST) { + if (src.kind == syntax.nkind.N_CAST) { if (src.lhs != nil) { - let inner: *node = src.lhs; + let inner: *syntax.node = src.lhs; let inneristagged: bool = false; - if (inner.kind == nkind.N_IDENT) { + if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { inneristagged = istaggedtype(c, lc.tnode); @@ -22170,16 +22170,16 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // the a==b fast path. let castisdst: bool = false; let castsubset: bool = false; - let castrhs: *node = src.rhs; + let castrhs: *syntax.node = src.rhs; if (castrhs != nil) { - let castt: *tinfo = castrhs.type_: *tinfo; - let castu: *tinfo = castt; + let castt: *syntax.tinfo = castrhs.type_: *syntax.tinfo; + let castu: *syntax.tinfo = castt; castu = tichase(castu); if (castu != nil) { if (castu == dt) { castisdst = true; - } else { if (castu.kind == tykind.TY_TAGGED) { - if (typeeq(castt, dst)) { + } else { if (castu.kind == syntax.tykind.TY_TAGGED) { + if (syntax.typeeq(castt, dst)) { castisdst = true; } else { castsubset = true; @@ -22216,7 +22216,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // chased the same src.type_. Mirrors cstage cg_widen_tagged_store's // `su = type_chase_named(st)` position (c138605). Tag lookups keep // the un-chased src.type_ (nominal identity is the alias). - let su: *tinfo = src.type_: *tinfo; + let su: *syntax.tinfo = src.type_: *syntax.tinfo; su = tichase(su); // #218: is the source itself a single NESTED variant of dt (its // whole tagged type matches one dt variant), rather than a flattened @@ -22232,14 +22232,14 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s || rhstaggedabicall(c, src); // #51 (#263): a module-global tagged ident is also a tagged source // (no local slot — handled by the global branch in the nested copy). - if (!srctagged) { if (src.kind == nkind.N_IDENT) { + if (!srctagged) { if (src.kind == syntax.nkind.N_IDENT) { if (localfindnode(c, src.str) == nil) { - let gtn51: *node = letvartnode(c, src.str); + let gtn51: *syntax.node = letvartnode(c, src.str); if (gtn51 != nil) { if (istaggedtype(c, gtn51)) { srctagged = true; }; }; }; }; }; if (srctagged) { - let nested: i32 = flatvariantidxt(dt, src.type_: *tinfo, false); + let nested: i32 = flatvariantidxt(dt, src.type_: *syntax.tinfo, false); if (nested >= 0) { // drew collision guard: the structural fallback over- // matches if ≥2 nominally-distinct dt variants share the @@ -22248,10 +22248,10 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // layer — hard-error NOW so a future collision STOPS the // compiler instead of silently mis-tagging. let nmatch: i32 = 0; - let gp: *tparam = dt.params; + let gp: *syntax.tparam = dt.params; for (gp != nil) { if (cgvariantstructmatch(gp.type_, - src.type_: *tinfo)) { + src.type_: *syntax.tinfo)) { nmatch += 1; }; gp = gp.tnext; @@ -22270,7 +22270,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s emitline("(BP)\n"); zk += 8; }; - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, src.str); if (lc != nil) { let soff: i32 = lc.off; @@ -22312,7 +22312,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // memory (AX = dest pointer), not the cursor — // the spill below would store the pointer as // the payload. Mem-to-mem widen is #40. - if (src.kind == nkind.N_CALL) { + if (src.kind == syntax.nkind.N_CALL) { if (callsretsize(c, src) > 0) { let m40a: str = "#40: sret-class call result cannot be cursor-widened into a tagged slot (mem-to-mem widen unwired)\n"; os.write(2, m40a.ptr, m40a.len: u64); @@ -22346,7 +22346,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // surviving taggedcastpeel (cast to a THIRD // union) has no cursor — loud, not word0 // garbage. Mirrors cstage. - if (src.kind == nkind.N_CAST) { + if (src.kind == syntax.nkind.N_CAST) { let m35a: str = "#35: tagged cast source shape unwired at the widen nested arm (rule 7)\n"; os.write(2, m35a.ptr, m35a.len: u64); os.exit(1); @@ -22383,7 +22383,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // Tagged source ident: byte-copy slot words then tag-remap. // rhstaggedident gates "src is a tagged-typed local ident"; the // remap reads the source tagged tinfo off the local's tnode (#68). - let st: *node = rhstaggedident(c, src); + let st: *syntax.node = rhstaggedident(c, src); if (st != nil) { let lc: *local = localfindnode(c, src.str); let ssz: i32 = slotsize(c, lc.tnode); @@ -22408,7 +22408,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s p += 8; }; }; - cgwidentagremap(c, dt, lc.tnode.type_: *tinfo, slot_off); + cgwidentagremap(c, dt, lc.tnode.type_: *syntax.tinfo, slot_off); return; }; // Tagged source via AX/DX/CX/R8 register ABI (N_CALL, N_INDEX @@ -22417,7 +22417,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s if (rhstaggedabicall(c, src)) { // #38b: an sret-classified call result is in memory (AX = // dest pointer), not the cursor. #40. - if (src.kind == nkind.N_CALL) { + if (src.kind == syntax.nkind.N_CALL) { if (callsretsize(c, src) > 0) { let m40b: str = "#40: sret-class call result cannot be cursor-widened into a tagged slot (mem-to-mem widen unwired)\n"; os.write(2, m40b.ptr, m40b.len: u64); @@ -22451,7 +22451,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s pp37 += 8; }; }; - cgwidentagremap(c, dt, src.type_: *tinfo, slot_off); + cgwidentagremap(c, dt, src.type_: *syntax.tinfo, slot_off); return; }; // #55: spill the AX/DX/CX/R8 cursor by the SOURCE box width @@ -22495,7 +22495,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s pp += 8; }; }; - cgwidentagremap(c, dt, src.type_: *tinfo, slot_off); + cgwidentagremap(c, dt, src.type_: *syntax.tinfo, slot_off); return; }; // #37 (rule 7): a >32B TAGGED source of a kind the resolver arms @@ -22505,7 +22505,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // cg_widen_tagged_store's generic-else bound. Surfaced by // reviewer-37's `let w = *p` probe on a 56B box: cstage loud, // wwstage silent (rule-10 break). - if (su != nil && su.kind == tykind.TY_TAGGED + if (su != nil && su.kind == syntax.tykind.TY_TAGGED && su.size: i32 > TUPLE_GPCAP * 8) { let m37f: str = "#37: >32B tagged source of a non-mem-based kind unwired (rule 7)\n"; os.write(2, m37f.ptr, m37f.len: u64); @@ -22515,8 +22515,8 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // taggedcastpeel (cast to a THIRD union) would fall to the // scalar arm below and silently truncate — loud. Mirrors // cstage's widen subset-arm cast bound. - if (src.kind == nkind.N_CAST && su != nil - && su.kind == tykind.TY_TAGGED && su.nullable == 0) { + if (src.kind == syntax.nkind.N_CAST && su != nil + && su.kind == syntax.tykind.TY_TAGGED && su.nullable == 0) { let m35b: str = "#35: tagged cast source shape unwired at the widen subset arm (rule 7)\n"; os.write(2, m35b.ptr, m35b.len: u64); os.exit(1); @@ -22535,13 +22535,13 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // slot 1+. Peel to the inner tuple here; src.type_ stays the CAST's // type, which resolves the variant tag by exact named match, so the // #241 untyped-element un-matchability does not arise for this form. - let tupsrc: *node = nil; + let tupsrc: *syntax.node = nil; let tupcast: bool = false; if (src != nil) { - if (src.kind == nkind.N_TUPLE) { tupsrc = src; }; - if (src.kind == nkind.N_CAST) { + if (src.kind == syntax.nkind.N_TUPLE) { tupsrc = src; }; + if (src.kind == syntax.nkind.N_CAST) { if (src.lhs != nil) { - if (src.lhs.kind == nkind.N_TUPLE) { + if (src.lhs.kind == syntax.nkind.N_TUPLE) { tupsrc = src.lhs; tupcast = true; }; @@ -22553,7 +22553,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // Mirrors cstage cg_widen_tagged_store. }; if (tupsrc != nil) { - if (su != nil) { if (su.kind == tykind.TY_TUPLE) { + if (su != nil) { if (su.kind == syntax.tykind.TY_TUPLE) { // #242/#241: mirror cstage's loud-stop CONDITION, not its // -1 mechanism (rule 10, align the RICHER side DOWN). // wwstage types `true`/`false` as bool and a suffix-less `7` @@ -22567,15 +22567,15 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // literal typing -> symmetric accept. BARE form only (#66): // the cast form resolves its tag from the cast's type on // BOTH stages, so bare elements are fine there. - let bl: *node = tupsrc.list; + let bl: *syntax.node = tupsrc.list; for (bl != nil && !tupcast) { let bare: bool = false; - if (bl.kind == nkind.N_TRUE) { bare = true; }; - if (bl.kind == nkind.N_FALSE) { bare = true; }; - if (bl.kind == nkind.N_INTLIT && bl.tsuffix.len == 0) { + if (bl.kind == syntax.nkind.N_TRUE) { bare = true; }; + if (bl.kind == syntax.nkind.N_FALSE) { bare = true; }; + if (bl.kind == syntax.nkind.N_INTLIT && bl.tsuffix.len == 0) { bare = true; }; - if (bl.kind == nkind.N_FLOATLIT && bl.tsuffix.len == 0) { + if (bl.kind == syntax.nkind.N_FLOATLIT && bl.tsuffix.len == 0) { bare = true; }; if (bare) { @@ -22590,7 +22590,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // str/slice shape fallback would silently pick tag 0 for an // unmatched tuple, diverging from cstage cg_tag_for_variant // (which returns -1) and masking the loud-stop below. - let ttag: i32 = flatvariantidxt(dt, src.type_: *tinfo, false); + let ttag: i32 = flatvariantidxt(dt, src.type_: *syntax.tinfo, false); // #242: an untyped/literal tuple element (`(true,7)`) leaves // the src tuple un-matchable, so the variant tag can't // resolve — the supported shape is a tuple of TYPED exprs @@ -22608,7 +22608,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // SysV eightbyte tuple classification is a deferred // follow-up. Symmetric with cstage cg_widen_tagged_store. let ttotal: i32 = 0; - let ce: *node = tupsrc.list; + let ce: *syntax.node = tupsrc.list; for (ce != nil) { // #47 gap-A: a tagged element rides its OWN // box (tag + payload, roundup8) per tuple slot @@ -22616,9 +22616,9 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // N_TTUPLE accumulation (check.ww:1640-1646); // the store loop below boxes it recursively // (two-level widen). Symmetric with cstage. - let ceti: *tinfo = ce.type_: *tinfo; + let ceti: *syntax.tinfo = ce.type_: *syntax.tinfo; ceti = tichase(ceti); - if (ceti != nil && ceti.kind == tykind.TY_TAGGED) { + if (ceti != nil && ceti.kind == syntax.tykind.TY_TAGGED) { ttotal += (ceti.size: i32 + 7) & ~7; } else { if (nodeisstr(c, ce) || nodeisslice(c, ce)) { ttotal += 24; @@ -22639,7 +22639,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s tzk += 8; }; let tfoff: i32 = 0; - let te: *node = tupsrc.list; + let te: *syntax.node = tupsrc.list; for (te != nil) { // #47 gap-A: a tagged element is its own // tag+payload box. Recurse so the inner box @@ -22649,11 +22649,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // (inner boxes here, outer tuple tag stamped // below). slot stride = roundup8(box). Symmetric // with cstage cg_widen_tagged_store. - let teti: *tinfo = te.type_: *tinfo; + let teti: *syntax.tinfo = te.type_: *syntax.tinfo; teti = tichase(teti); - if (teti != nil && teti.kind == tykind.TY_TAGGED) { + if (teti != nil && teti.kind == syntax.tykind.TY_TAGGED) { let ebox: i32 = (teti.size: i32 + 7) & ~7; - cgwidentaggedstore(c, te.type_: *tinfo, te, + cgwidentaggedstore(c, te.type_: *syntax.tinfo, te, "BP", slot_off + 8 + tfoff, ebox); tfoff += ebox; te = te.next; @@ -22662,7 +22662,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s let isflt: bool = isfloattype(c, te); let wide: bool = nodeisstr(c, te) || nodeisslice(c, te); let esz: i32 = 8; - let eti: *tinfo = te.type_: *tinfo; + let eti: *syntax.tinfo = te.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; cgexpr(c, te); if (isflt) { @@ -22715,23 +22715,23 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // A cast wrapping a concrete-variant tuple (`(tbl[i]: ci)`) // survived the widen-cast peel above; its operand is the // addressable expr. Mirror of cstage cg_widen_tagged_store. - if (su != nil) { if (su.kind == tykind.TY_TUPLE) { - let addrsrc: *node = src; - if (addrsrc.kind == nkind.N_CAST) { + if (su != nil) { if (su.kind == syntax.tykind.TY_TUPLE) { + let addrsrc: *syntax.node = src; + if (addrsrc.kind == syntax.nkind.N_CAST) { if (addrsrc.lhs != nil) { addrsrc = addrsrc.lhs; }; }; let okkind: bool = false; - if (addrsrc.kind == nkind.N_IDENT) { okkind = true; }; - if (addrsrc.kind == nkind.N_INDEX) { okkind = true; }; - if (addrsrc.kind == nkind.N_UN) { - if (addrsrc.op == tkind.TK_STAR) { okkind = true; }; + if (addrsrc.kind == syntax.nkind.N_IDENT) { okkind = true; }; + if (addrsrc.kind == syntax.nkind.N_INDEX) { okkind = true; }; + if (addrsrc.kind == syntax.nkind.N_UN) { + if (addrsrc.op == syntax.tkind.TK_STAR) { okkind = true; }; }; if (!okkind) { let mk: str = "cgwidentaggedstore: tuple-typed source shape unwired (only the bare/cast tuple literal and the addressable ident/index/deref trio carry a full payload; see #116)\n"; os.write(2, mk.ptr, mk.len: u64); os.exit(1); }; - let ntag: i32 = flatvariantidxt(dt, src.type_: *tinfo, false); + let ntag: i32 = flatvariantidxt(dt, src.type_: *syntax.tinfo, false); if (ntag < 0) { let mt: str = "cgwidentaggedstore: tuple-in-union variant tag unresolved (untyped/literal tuple element; see #242 / #241)\n"; os.write(2, mt.ptr, mt.len: u64); @@ -22784,10 +22784,10 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // fell to the scalar word0 arm — payload truncated. Land g(SB) in SI and // byte-copy the struct words into slot+8; cstage zero-fills the payload // (cstage half #43). Local/literal sources keep the existing arms (byte-id). - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { if (localfindnode(c, src.str) == nil) { - let gtn: *node = letvartnode(c, src.str); - if (gtn != nil) { if (gtn.kind == nkind.N_TNAME) { + let gtn: *syntax.node = letvartnode(c, src.str); + if (gtn != nil) { if (gtn.kind == syntax.nkind.N_TNAME) { let gsi: *structinfo = structlookupchain(c, gtn); if (gsi != nil) { emitline("\tXORQ\tAX, AX\n"); @@ -22848,7 +22848,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s }; let tag: i32 = taggedvariantindext(c, dt, src); if (tag < 0) { tag = 0; }; - if (src.kind == nkind.N_STRUCTLIT) { + if (src.kind == syntax.nkind.N_STRUCTLIT) { // #23: delegate to the single fill path. The // inline field loop this replaces was a // parallel fill that drifted: it lacked the @@ -22949,9 +22949,9 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // value" is dead and removed. let fkind: i32 = 0; if (src != nil) { - let srct: *tinfo = src.type_: *tinfo; - if (typeisf32(srct)) { fkind = 1; } - else { if (typeisfloat(srct)) { fkind = 2; }; }; + let srct: *syntax.tinfo = src.type_: *syntax.tinfo; + if (syntax.typeisf32(srct)) { fkind = 1; } + else { if (syntax.typeisfloat(srct)) { fkind = 2; }; }; }; if (fkind != 0) { let fmov: str = "MOVSD"; @@ -22983,17 +22983,17 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // like the slice axis, not nominal identity. let wantf32: bool = (fkind == 1); let ftag: i32 = -1; - let fti: *tinfo = dt; + let fti: *syntax.tinfo = dt; fti = tichase(fti); - if (fti != nil) { if (fti.kind == tykind.TY_TAGGED) { - let fp: *tparam = fti.params; + if (fti != nil) { if (fti.kind == syntax.tykind.TY_TAGGED) { + let fp: *syntax.tparam = fti.params; let fidx: i32 = 0; for (fp != nil) { - let fvt: *tinfo = fp.type_; + let fvt: *syntax.tinfo = fp.type_; fvt = tichase(fvt); if (fvt != nil) { - if (typeisfloat(fvt)) { - if (typeisf32(fvt) == wantf32) { ftag = fidx; break; }; + if (syntax.typeisfloat(fvt)) { + if (syntax.typeisf32(fvt) == wantf32) { ftag = fidx; break; }; }; }; fp = fp.tnext; @@ -23068,9 +23068,9 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // offset), so this is offset-preserving. Leaf out-param is the field's // stamped *tinfo (was *fieldinfo); the str/slice pseudo-leaf leaves it // nil and the callers gate on slicedelta>=0 first. -export fn dotchainresolve(c: *cgen, n: *node, +export fn dotchainresolve(c: *cgen, n: *syntax.node, outrootname: *str, outrootoff: *i32, outtotaloff: *i32, - outleaftype: **tinfo, outslicedelta: *i32, + outleaftype: **syntax.tinfo, outslicedelta: *i32, outisglobal: *bool, outptrroot: *bool) bool = { *outrootname = ""; *outrootoff = 0; @@ -23080,12 +23080,12 @@ export fn dotchainresolve(c: *cgen, n: *node, *outleaftype = nil; *outslicedelta = -1; if (n == nil) { return false; }; - if (n.kind != nkind.N_DOT) { return false; }; - let stk: [16]*node; + if (n.kind != syntax.nkind.N_DOT) { return false; }; + let stk: [16]*syntax.node; let nsteps: i32 = 0; - let cur: *node = n; + let cur: *syntax.node = n; for (cur != nil) { - if (cur.kind != nkind.N_DOT) { break; }; + if (cur.kind != syntax.nkind.N_DOT) { break; }; if (nsteps >= 16) { return false; }; stk[nsteps] = cur; nsteps += 1; @@ -23093,13 +23093,13 @@ export fn dotchainresolve(c: *cgen, n: *node, }; if (nsteps < 2) { return false; }; if (cur == nil) { return false; }; - if (cur.kind != nkind.N_IDENT) { return false; }; + if (cur.kind != syntax.nkind.N_IDENT) { return false; }; *outrootname = cur.str; let resolved: bool = false; let lc: *local = localfindnode(c, cur.str); if (lc != nil) { if (lc.tnode != nil) { - if (lc.tnode.kind == nkind.N_TNAME) { + if (lc.tnode.kind == syntax.nkind.N_TNAME) { *outrootoff = lc.off; resolved = true; }; @@ -23107,10 +23107,10 @@ export fn dotchainresolve(c: *cgen, n: *node, // pointee struct supplies the field layout. Callers // that opt in via *outptrroot emit a MOVQ load of the // slot before indexing. - if (lc.tnode.kind == nkind.N_TPTR) { - let pe: *node = lc.tnode.lhs; + if (lc.tnode.kind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = lc.tnode.lhs; if (pe != nil) { - if (pe.kind == nkind.N_TNAME) { + if (pe.kind == syntax.nkind.N_TNAME) { *outrootoff = lc.off; *outptrroot = true; resolved = true; @@ -23130,24 +23130,24 @@ export fn dotchainresolve(c: *cgen, n: *node, // Root struct layout = the stamped root-ident type_, peeled NAMED // (plus one TY_PTR hop for a `*struct` root). tfield.type_ then // supplies each nested struct directly, so no name re-lookup. - let curstruct: *tinfo = cur.type_: *tinfo; + let curstruct: *syntax.tinfo = cur.type_: *syntax.tinfo; curstruct = tichase(curstruct); if (*outptrroot) { if (curstruct == nil) { return false; }; - if (curstruct.kind != tykind.TY_PTR) { return false; }; + if (curstruct.kind != syntax.tykind.TY_PTR) { return false; }; curstruct = curstruct.sub; curstruct = tichase(curstruct); }; let i: i32 = nsteps - 1; for (i >= 0) { if (curstruct == nil) { return false; }; - if (curstruct.kind != tykind.TY_STRUCT) { return false; }; + if (curstruct.kind != syntax.tykind.TY_STRUCT) { return false; }; if (stk[i] == nil) { return false; }; let stepnm: str = stk[i].str; - let tf: *tfield = curstruct.fields; - let found: *tfield = nil; + let tf: *syntax.tfield = curstruct.fields; + let found: *syntax.tfield = nil; for (tf != nil) { - if (streq(tf.name, stepnm)) { found = tf; break; }; + if (syntax.streq(tf.name, stepnm)) { found = tf; break; }; tf = tf.tnext; }; if (found == nil) { return false; }; @@ -23157,37 +23157,37 @@ export fn dotchainresolve(c: *cgen, n: *node, *outleaftype = found.type_; return true; }; - let ft: *tinfo = found.type_; + let ft: *syntax.tinfo = found.type_; ft = tichase(ft); if (ft == nil) { return false; }; - if (ft.kind == tykind.TY_STR) { + if (ft.kind == syntax.tykind.TY_STR) { // str IS []u8: .cap is the third header word, same as // the TY_SLICE leaf below — cstage treats str≡slice for // .ptr/.len/.cap (cmd/w6c/cgen.c:2478) (#1/Phase 3, #11). if (i != 1) { return false; }; let pseudo: str = stk[0].str; let delta: i32 = -1; - if (streq(pseudo, "ptr")) { delta = 0; } - else { if (streq(pseudo, "len")) { delta = 8; } - else { if (streq(pseudo, "cap")) { delta = 16; }; }; }; + if (syntax.streq(pseudo, "ptr")) { delta = 0; } + else { if (syntax.streq(pseudo, "len")) { delta = 8; } + else { if (syntax.streq(pseudo, "cap")) { delta = 16; }; }; }; if (delta < 0) { return false; }; *outtotaloff = *outtotaloff + foff; *outslicedelta = delta; return true; }; - if (ft.kind == tykind.TY_SLICE) { + if (ft.kind == syntax.tykind.TY_SLICE) { if (i != 1) { return false; }; let pseudo: str = stk[0].str; let delta: i32 = -1; - if (streq(pseudo, "ptr")) { delta = 0; } - else { if (streq(pseudo, "len")) { delta = 8; } - else { if (streq(pseudo, "cap")) { delta = 16; }; }; }; + if (syntax.streq(pseudo, "ptr")) { delta = 0; } + else { if (syntax.streq(pseudo, "len")) { delta = 8; } + else { if (syntax.streq(pseudo, "cap")) { delta = 16; }; }; }; if (delta < 0) { return false; }; *outtotaloff = *outtotaloff + foff; *outslicedelta = delta; return true; }; - if (ft.kind != tykind.TY_STRUCT) { return false; }; + if (ft.kind != syntax.tykind.TY_STRUCT) { return false; }; *outtotaloff = *outtotaloff + foff; curstruct = ft; i -= 1; @@ -23253,14 +23253,14 @@ export fn dotchainresolve(c: *cgen, n: *node, // byte-identically — cstage hasn't yet learned MOVW for fsz==2. Once // #13 aligns both stages, the dispatch can switch to fieldstoreop // which already returns MOVW where appropriate. -fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, +fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *syntax.node, mode: i32, srcoff: i32, srcname: str, disp: i32) void = { if (si == nil) { return; }; let basereg: str = "BP"; if (mode != 0) { basereg = "BX"; }; let totsize: i32 = structabisize(si); - if (lit.op == tkind.TK_ELLIPSIS) { + if (lit.op == syntax.tkind.TK_ELLIPSIS) { // `..., ...` autofill — zero the entire slot first so // unmentioned fields read as 0. Sized stores: 8/4/1. For // non-BP modes, reload BX once before the loop (cgexpr-free @@ -23311,14 +23311,14 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, zi += 1; }; }; - let fieldnode: *node = lit.list; + let fieldnode: *syntax.node = lit.list; for (fieldnode != nil) { - if (fieldnode.kind == nkind.N_FIELD) { + if (fieldnode.kind == syntax.nkind.N_FIELD) { let fname: str = fieldnode.str; let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fname)) { + if (syntax.streq(fn_, fname)) { // Tagged-union field: delegate to the shared // widening writer (handles str/scalar/struct // literal/ident payload + tagged-subset tag @@ -23335,7 +23335,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, emitsymname(c, srcname); emitline("(SB), BX\n"); }; - cgwidentaggedstore(c, fi.tnode.type_: *tinfo, + cgwidentaggedstore(c, fi.tnode.type_: *syntax.tinfo, fieldnode.lhs, basereg, disp + fi.foff, fi.fsz); fi = nil; @@ -23347,9 +23347,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // the rest silently stayed zero. let nested: bool = false; if (fieldnode.lhs != nil) { - if (fieldnode.lhs.kind == nkind.N_STRUCTLIT) { + if (fieldnode.lhs.kind == syntax.nkind.N_STRUCTLIT) { if (fi.tnode != nil) { - if (fi.tnode.kind == nkind.N_TNAME) { + if (fi.tnode.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, fi.tnode.str) == 0) { let isi: *structinfo = structlookup(c, fi.tnode.str); if (isi != nil) { @@ -23393,9 +23393,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, let callwhole: bool = false; if (!nested) { if (fieldnode.lhs != nil) { - if (fieldnode.lhs.kind == nkind.N_CALL) { + if (fieldnode.lhs.kind == syntax.nkind.N_CALL) { if (fi.tnode != nil) { - if (fi.tnode.kind == nkind.N_TNAME) { + if (fi.tnode.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, fi.tnode.str) == 0) { let csi: *structinfo = structlookup(c, fi.tnode.str); if (csi != nil) { @@ -23524,9 +23524,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, }; fi = nil; } else if (fi.tnode != nil - && fi.tnode.kind == nkind.N_TARRAY + && fi.tnode.kind == syntax.nkind.N_TARRAY && fieldnode.lhs != nil - && fieldnode.lhs.kind == nkind.N_ARRLIT) { + && fieldnode.lhs.kind == syntax.nkind.N_ARRLIT) { // #249: array field from an N_ARRLIT. Without this // the generic tail below cgexprs the N_ARRLIT (→ AX) // and stores one sized word, silently DROPPING every @@ -23536,7 +23536,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // str/slice/struct/tagged elements are the N_LET // multi-word gap — loud rule-7 error (cstage // cg_structlit_fill twin). - let elemn: *node = fi.tnode.lhs; + let elemn: *syntax.node = fi.tnode.lhs; let isstrel: bool = isstrtype(c, elemn); let istagel: bool = istaggedtype(c, elemn); let issliceel: bool = isslicetype(c, elemn); @@ -23550,9 +23550,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // type_chase_named key (cgen.c:3179, B5-c1). let isstructel: bool = false; if (elemn != nil) { - let eu: *tinfo = tichase(elemn.type_: *tinfo); + let eu: *syntax.tinfo = tichase(elemn.type_: *syntax.tinfo); if (eu != nil) { - if (eu.kind == tykind.TY_STRUCT) { + if (eu.kind == syntax.tykind.TY_STRUCT) { isstructel = true; }; }; @@ -23567,7 +23567,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, }; let esz: i32 = 8; if (elemn != nil) { - if (elemn.kind == nkind.N_TNAME) { + if (elemn.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, elemn.str); if (ps > 0) { esz = ps; }; }; @@ -23578,11 +23578,11 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, if (isf32type(c, elemn)) { fmov = "MOVSS"; }; let idx: i32 = 0; let repeat: bool = false; - let e: *node = fieldnode.lhs.list; + let e: *syntax.node = fieldnode.lhs.list; for (e != nil) { let isellip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; isellip = true; }; @@ -23625,7 +23625,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, if (repeat) { let total: i32 = idx; if (fi.tnode.rhs != nil) { - if (fi.tnode.rhs.kind == nkind.N_INTLIT) { + if (fi.tnode.rhs.kind == syntax.nkind.N_INTLIT) { total = fi.tnode.rhs.uval: i32; }; }; @@ -23706,7 +23706,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, }; let agsz49: i32 = 0; if (fi.tnode != nil) { - let agti49: *tinfo = fi.tnode.type_: *tinfo; + let agti49: *syntax.tinfo = fi.tnode.type_: *syntax.tinfo; agti49 = tichase(agti49); if (agti49 != nil) { agsz49 = agti49.size: i32; }; }; @@ -23777,7 +23777,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // Thin wrapper preserving the BP-rel call shape used by cglet, // cgreturn, cgassign N_IDENT-lhs N_STRUCTLIT, and the C1.25 // @placescr materialise (cg_structlit_fill_bp's named twin). -fn cgstructlitfillbp(c: *cgen, si: *structinfo, lit: *node, bpoff: i32) void = { +fn cgstructlitfillbp(c: *cgen, si: *structinfo, lit: *syntax.node, bpoff: i32) void = { if (si == nil) { return; }; cgstructlitfill(c, si, lit, 0, 0, "", bpoff); }; @@ -23816,12 +23816,12 @@ fn cgfloatbits(c: *cgen, bits: u64) void = { emitline("\tADDQ\t$8, SP\n"); }; -fn cgexpr(c: *cgen, n: *node) void = { +fn cgexpr(c: *cgen, n: *syntax.node) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; switch (k) { - case nkind.N_INTLIT: + case syntax.nkind.N_INTLIT: // A no-decimal `0f64`/`8f64` is an N_INTLIT carrying float // TYPE; it must reach X0 like a true float literal, not the // integer-immediate path (which strands it in AX and an SSE @@ -23849,7 +23849,7 @@ fn cgexpr(c: *cgen, n: *node) void = { emitint(n.uval: i64); emitline(", AX\n"); return; - case nkind.N_FLOATLIT: + case syntax.nkind.N_FLOATLIT: // The bits come from n.uval — the parser populates it from // the lexer's bitcast of t.fval. cgfloatbits(c, n.uval); @@ -23858,41 +23858,41 @@ fn cgexpr(c: *cgen, n: *node) void = { emitline("\tCVTSD2SS\tX0, X0\n"); }; return; - case nkind.N_RUNELIT: + case syntax.nkind.N_RUNELIT: emitline("\tMOVQ\t$"); emitint(n.uval: i64); emitline(", AX\n"); return; - case nkind.N_STRLIT: cgstrlit(c, n); return; - case nkind.N_TRUE: + case syntax.nkind.N_STRLIT: cgstrlit(c, n); return; + case syntax.nkind.N_TRUE: emitline("\tMOVQ\t$1, AX\n"); return; - case nkind.N_FALSE: + case syntax.nkind.N_FALSE: emitline("\tMOVQ\t$0, AX\n"); return; - case nkind.N_NIL: + case syntax.nkind.N_NIL: emitline("\tMOVQ\t$0, AX\n"); return; - case nkind.N_VOIDLIT: + case syntax.nkind.N_VOIDLIT: // void value: zero-size, but the consumer's ABI expects a // deterministic AX. Emit 0 like nil/false do. emitline("\tMOVQ\t$0, AX\n"); return; - case nkind.N_IDENT: cgident(c, n); return; - case nkind.N_INDEX: cgindex(c, n); return; - case nkind.N_SLICE: cgslice(c, n); return; - case nkind.N_MATCH: cgmatch(c, n); return; - case nkind.N_CAST: cgcast(c, n); return; - case nkind.N_DOT: cgdot(c, n); return; - case nkind.N_UN: cgun(c, n); return; - case nkind.N_BIN: cgbin(c, n); return; - case nkind.N_CALL: cgcall(c, n); return; - case nkind.N_ASSIGN: cgassign(c, n); return; - case nkind.N_TRYPROP: cgtryprop(c, n); return; - case nkind.N_TRYUNW: cgtryunw(c, n); return; - case nkind.N_TYPETEST: cgtypetest(c, n); return; - case nkind.N_TYPEASSERT: cgtypeassert(c, n); return; - case nkind.N_TUPLE: + case syntax.nkind.N_IDENT: cgident(c, n); return; + case syntax.nkind.N_INDEX: cgindex(c, n); return; + case syntax.nkind.N_SLICE: cgslice(c, n); return; + case syntax.nkind.N_MATCH: cgmatch(c, n); return; + case syntax.nkind.N_CAST: cgcast(c, n); return; + case syntax.nkind.N_DOT: cgdot(c, n); return; + case syntax.nkind.N_UN: cgun(c, n); return; + case syntax.nkind.N_BIN: cgbin(c, n); return; + case syntax.nkind.N_CALL: cgcall(c, n); return; + case syntax.nkind.N_ASSIGN: cgassign(c, n); return; + case syntax.nkind.N_TRYPROP: cgtryprop(c, n); return; + case syntax.nkind.N_TRYUNW: cgtryunw(c, n); return; + case syntax.nkind.N_TYPETEST: cgtypetest(c, n); return; + case syntax.nkind.N_TYPEASSERT: cgtypeassert(c, n); return; + case syntax.nkind.N_TUPLE: // #241: a literal tuple rvalue `(a, b)` is a value — pack its // elements into the register cursor (mirror cgreturn's N_TUPLE // arm) so a let-bind / destructure consumer reads every element, @@ -23913,10 +23913,10 @@ fn cgexpr(c: *cgen, n: *node) void = { // tagged-union type expression `tagged`. -1 if `tagged` isn't an // nkind.N_TTAGGED or no variant matches. Mirrors the lookup that cgmatch // does inline; pulled out so `is` / `as` can reuse it. -fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { +fn cgtagvariantidx(c: *cgen, tagged: *syntax.node, vt: *syntax.node) i32 = { if (tagged == nil) { return -1; }; if (vt == nil) { return -1; }; - if (tagged.kind != nkind.N_TTAGGED) { + if (tagged.kind != syntax.nkind.N_TTAGGED) { // #22a: a STAMPED-CARRIER scrutinee (the #67 matchscrutt // shape — is/as on a tuple element t.N, a struct field, an // indexed element) is not an N_TTAGGED type-AST node; its @@ -23925,10 +23925,10 @@ fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { // cstage cg_tag_for_variant is type-based for every // scrutinee shape, so the AST-keyed -1 here was a silent // tag-0 clamp on wwstage (cs CMPQ $1 vs ww CMPQ $0). - let sti: *tinfo = tagged.type_: *tinfo; + let sti: *syntax.tinfo = tagged.type_: *syntax.tinfo; sti = tichase(sti); - if (sti != nil && sti.kind == tykind.TY_TAGGED && vt.type_ != nil) { - return flatvariantidxt(sti, vt.type_: *tinfo, false); + if (sti != nil && sti.kind == syntax.tykind.TY_TAGGED && vt.type_ != nil) { + return flatvariantidxt(sti, vt.type_: *syntax.tinfo, false); }; return -1; }; @@ -23936,7 +23936,7 @@ fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { // element-aware helper, which carries the loose first-slice-shape // fallback (cstage type_assignable stand-in) that flatvariantidx's // strict typeeq below doesn't. Task #19; #66 refresh. - if (vt.kind == nkind.N_TSLICE) { + if (vt.kind == syntax.nkind.N_TSLICE) { return flatslicevariantidx(c, tagged, vt.lhs); }; // #66 Phase-N step 3: match by typeeq on vt's stamped tinfo @@ -23949,12 +23949,12 @@ fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { // error (`!T`), the success tag is the first NON-error variant's index; // else 0 (legacy/no-error). Drives the `?`/`!` success-tag CMPQ + the // payload-shift variant lookup (#52/#216 — replaces the hardcoded tag-0). -fn successtag(ou: *tinfo) i64 = { - let u: *tinfo = tichase(ou); +fn successtag(ou: *syntax.tinfo) i64 = { + let u: *syntax.tinfo = tichase(ou); if (u == nil) { return 0i64; }; - if (u.kind != tykind.TY_TAGGED) { return 0i64; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return 0i64; }; let haserr: bool = false; - let p: *tparam = u.params; + let p: *syntax.tparam = u.params; for (p != nil) { if (p.iserror) { haserr = true; }; p = p.tnext; }; if (!haserr) { return 0i64; }; let idx: i64 = 0i64; @@ -23970,13 +23970,13 @@ fn successtag(ou: *tinfo) i64 = { // successvariant — the success variant's type_ (the param at successtag). // Lets the #241 tuple/tagged payload-shift sites inspect the SUCCESS // variant's shape, not the (error-first) first param. -fn successvariant(ou: *tinfo) *tinfo = { - let u: *tinfo = tichase(ou); +fn successvariant(ou: *syntax.tinfo) *syntax.tinfo = { + let u: *syntax.tinfo = tichase(ou); if (u == nil) { return nil; }; - if (u.kind != tykind.TY_TAGGED) { return nil; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return nil; }; let st: i64 = successtag(ou); let idx: i64 = 0i64; - let p: *tparam = u.params; + let p: *syntax.tparam = u.params; for (p != nil) { if (idx == st) { return p.type_; }; idx += 1i64; @@ -23992,17 +23992,17 @@ fn successvariant(ou: *tinfo) *tinfo = { // stamped tagged result tinfo (n.lhs.type_); the success variant is the // param at successtag (dynamic, #52 — not the hardcoded first param), // matching the dynamic CMPQ $successtag success-tag convention. -fn cgtrytupleshift(c: *cgen, n: *node) bool = { +fn cgtrytupleshift(c: *cgen, n: *syntax.node) bool = { if (n.lhs == nil) { return false; }; - let ou: *tinfo = n.lhs.type_: *tinfo; + let ou: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; ou = tichase(ou); if (ou == nil) { return false; }; - if (ou.kind != tykind.TY_TAGGED) { return false; }; + if (ou.kind != syntax.tykind.TY_TAGGED) { return false; }; if (ou.params == nil) { return false; }; - let sv: *tinfo = successvariant(ou); + let sv: *syntax.tinfo = successvariant(ou); sv = tichase(sv); if (sv == nil) { return false; }; - if (sv.kind != tykind.TY_TUPLE) { return false; }; + if (sv.kind != syntax.tykind.TY_TUPLE) { return false; }; cgtaggedtuplepayloadshift(c, sv); return true; }; @@ -24015,17 +24015,17 @@ fn cgtrytupleshift(c: *cgen, n: *node) bool = { // MOVQ DX,AX tail carried only the inner tag and dropped the payload // (ken unw16). Nullable folds to one word and stays on the scalar // move. Twin of cgtrytupleshift; mirrors cstage N_TRYPROP/N_TRYUNW. -fn cgtrytaggedshift(c: *cgen, n: *node) bool = { +fn cgtrytaggedshift(c: *cgen, n: *syntax.node) bool = { if (n.lhs == nil) { return false; }; - let ou: *tinfo = n.lhs.type_: *tinfo; + let ou: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; ou = tichase(ou); if (ou == nil) { return false; }; - if (ou.kind != tykind.TY_TAGGED) { return false; }; + if (ou.kind != syntax.tykind.TY_TAGGED) { return false; }; if (ou.params == nil) { return false; }; - let sv: *tinfo = successvariant(ou); + let sv: *syntax.tinfo = successvariant(ou); sv = tichase(sv); if (sv == nil) { return false; }; - if (sv.kind != tykind.TY_TAGGED) { return false; }; + if (sv.kind != syntax.tykind.TY_TAGGED) { return false; }; if (sv.nullable != 0) { return false; }; emitline("\tMOVQ\tDX, AX\n"); if (sv.size: i32 > 8) { emitline("\tMOVQ\tCX, DX\n"); }; @@ -24048,25 +24048,25 @@ fn cgtrytaggedshift(c: *cgen, n: *node) bool = { // need the lhs in AX and the divisor/count in CX, so swap (rhs AX→CX, // old BX→AX) first. Signed RSHIFTEQ uses SARQ, unsigned SHRQ (#136). // Mirrors cstage cg_dotfield_combine — both stages emit identical asm. -fn cgdotfieldcombine(c: *cgen, op: tkind, unsignd: bool) void = { - if (op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tBX, AX\n"); return; }; - if (op == tkind.TK_MINUSEQ) { +fn cgdotfieldcombine(c: *cgen, op: syntax.tkind, unsignd: bool) void = { + if (op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); emitline("\tMOVQ\tBX, AX\n"); return; }; - if (op == tkind.TK_STAREQ) { emitline("\tIMULQ\tBX, AX\n"); return; }; - if (op == tkind.TK_AMPEQ) { emitline("\tANDQ\tBX, AX\n"); return; }; - if (op == tkind.TK_PIPEEQ) { emitline("\tORQ\tBX, AX\n"); return; }; - if (op == tkind.TK_CARETEQ) { emitline("\tXORQ\tBX, AX\n"); return; }; - if (op == tkind.TK_SLASHEQ) { + if (op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_SLASHEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; return; }; - if (op == tkind.TK_PERCENTEQ) { + if (op == syntax.tkind.TK_PERCENTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } @@ -24074,13 +24074,13 @@ fn cgdotfieldcombine(c: *cgen, op: tkind, unsignd: bool) void = { emitline("\tMOVQ\tDX, AX\n"); return; }; - if (op == tkind.TK_LSHIFTEQ) { + if (op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); emitline("\tSHLQ\tCX, AX\n"); return; }; - if (op == tkind.TK_RSHIFTEQ) { + if (op == syntax.tkind.TK_RSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); if (unsignd) { emitline("\tSHRQ\tCX, AX\n"); } @@ -24096,7 +24096,7 @@ fn cgdotfieldcombine(c: *cgen, op: tkind, unsignd: bool) void = { // non-integer field (float/str/slice/tagged): the combine arm only // speaks integer ABI; pre-#34 these silently became `s.f = rhs`. // Mirrors the cstage cg_dotfield_hardstop gate. (#34/rule-7) -fn cgdotfieldhardstop(c: *cgen, ftn: *node) void = { +fn cgdotfieldhardstop(c: *cgen, ftn: *syntax.node) void = { if (istaggedtype(c, ftn)) { let m: str = "single-dot field compound on tagged field not wired (#34/rule-7)\n"; os.write(2, m.ptr, m.len: u64); @@ -24119,18 +24119,18 @@ fn cgdotfieldhardstop(c: *cgen, ftn: *node) void = { }; }; -fn cgtryunwcursor(c: *cgen, n: *node, opname: str) void = { - let u: *tinfo = nil; - if (n.lhs != nil) { u = n.lhs.type_: *tinfo; }; +fn cgtryunwcursor(c: *cgen, n: *syntax.node, opname: str) void = { + let u: *syntax.tinfo = nil; + if (n.lhs != nil) { u = n.lhs.type_: *syntax.tinfo; }; u = tichase(u); let utag: bool = false; if (u != nil) { - if (u.kind == tykind.TY_TAGGED && u.nullable == 0) { + if (u.kind == syntax.tykind.TY_TAGGED && u.nullable == 0) { utag = true; }; }; if (utag && u.size: i32 > TUPLE_GPCAP * 8 - && n.lhs.kind != nkind.N_CALL) { + && n.lhs.kind != syntax.nkind.N_CALL) { let p37: str = "#37: `"; os.write(2, p37.ptr, p37.len: u64); os.write(2, opname.ptr, opname.len: u64); @@ -24138,7 +24138,7 @@ fn cgtryunwcursor(c: *cgen, n: *node, opname: str) void = { os.write(2, m37t.ptr, m37t.len: u64); os.exit(1); }; - if (utag && n.lhs.kind == nkind.N_IDENT) { + if (utag && n.lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.lhs.str); if (lc == nil) { let p35: str = "#35: `"; @@ -24186,14 +24186,14 @@ fn cgtryunwcursor(c: *cgen, n: *node, opname: str) void = { // cgtryprop — `e?` propagates the error variant up the stack. // Success tag is dynamic via successtag (#52/#216): the first non-error // variant's index (cstage cg_tagged_success_tag parity), 0 when success-first. -fn cgtryprop(c: *cgen, n: *node) void = { +fn cgtryprop(c: *cgen, n: *syntax.node) void = { // #38b residuals (rule 7): the cursor read below cannot see an // sret-classified call result (AX = dest pointer), and the // propagate-RET cannot speak an sret-classified enclosing return // (the caller reads memory, not the cursor). #40-family follow-ups. // Mirrors cstage cgen.c N_TRYPROP gates. if (n.lhs != nil) { - if (n.lhs.kind == nkind.N_CALL) { + if (n.lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, n.lhs) > 0) { let m38p: str = "#38b: `?` on an sret-class call result unwired (mem-based unwrap is a #40-family follow-up)\n"; os.write(2, m38p.ptr, m38p.len: u64); @@ -24231,8 +24231,8 @@ fn cgtryprop(c: *cgen, n: *node) void = { // parity, #52): 0 for success-first, the first non-error index for an // error-first union. let cl: str = mklabel(c, "tryprop_ok"); - let propu: *tinfo = nil; - if (n.lhs != nil) { propu = n.lhs.type_: *tinfo; }; + let propu: *syntax.tinfo = nil; + if (n.lhs != nil) { propu = n.lhs.type_: *syntax.tinfo; }; emitline("\tCMPQ\t$"); emitint(successtag(propu)); emitline(", AX\n"); @@ -24247,17 +24247,17 @@ fn cgtryprop(c: *cgen, n: *node) void = { // Payload words DX/CX/R8 ride the RET untouched; only AX (the // tag) is rewritten. Same-order unions map every error variant to // itself → zero instructions, byte-id with the pre-#173 emit. - let u: *tinfo = nil; - if (n.lhs != nil) { u = n.lhs.type_: *tinfo; }; + let u: *syntax.tinfo = nil; + if (n.lhs != nil) { u = n.lhs.type_: *syntax.tinfo; }; u = tichase(u); - let r: *tinfo = nil; - if (c.fnret != nil) { r = c.fnret.type_: *tinfo; }; + let r: *syntax.tinfo = nil; + if (c.fnret != nil) { r = c.fnret.type_: *syntax.tinfo; }; r = tichase(r); - if (u != nil && r != nil && r.kind == tykind.TY_TAGGED && u.params != nil) { + if (u != nil && r != nil && r.kind == syntax.tykind.TY_TAGGED && u.params != nil) { let propret: str; propret.ptr = nil; propret.len = 0; let haveret: bool = false; - let p: *tparam = u.params; + let p: *syntax.tparam = u.params; let i: i32 = 0; for (p != nil) { if (p.iserror) { @@ -24306,7 +24306,7 @@ fn cgtryprop(c: *cgen, n: *node) void = { // (success_is_str = type_isstr(succ_t at cg_tagged_success_tag)). let succisstr: bool = false; if (n.lhs != nil) { - succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo)); + succisstr = syntax.typeisstr(successvariant(n.lhs.type_: *syntax.tinfo)); }; if (succisstr) { // str IS []u8: success arrives DX=ptr, CX=len, R8=cap @@ -24322,10 +24322,10 @@ fn cgtryprop(c: *cgen, n: *node) void = { // cgtryunw — `e!` aborts on the error variant via exit(1). Success tag // is dynamic via successtag (#52): the first non-error variant's index // (cstage cg_tagged_success_tag parity), 0 when success-first. -fn cgtryunw(c: *cgen, n: *node) void = { +fn cgtryunw(c: *cgen, n: *syntax.node) void = { // #38b residual (rule 7): see the cgtryprop twin. if (n.lhs != nil) { - if (n.lhs.kind == nkind.N_CALL) { + if (n.lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, n.lhs) > 0) { let m38u: str = "#38b: `!` on an sret-class call result unwired (mem-based unwrap is a #40-family follow-up)\n"; os.write(2, m38u.ptr, m38u.len: u64); @@ -24354,8 +24354,8 @@ fn cgtryunw(c: *cgen, n: *node) void = { // Success tag is dynamic (successtag / cstage cg_tagged_success_tag // parity, #52): 0 for success-first, the first non-error index for an // error-first union. - let unwu: *tinfo = nil; - if (n.lhs != nil) { unwu = n.lhs.type_: *tinfo; }; + let unwu: *syntax.tinfo = nil; + if (n.lhs != nil) { unwu = n.lhs.type_: *syntax.tinfo; }; emitline("\tCMPQ\t$"); emitint(successtag(unwu)); emitline(", AX\n"); @@ -24373,7 +24373,7 @@ fn cgtryunw(c: *cgen, n: *node) void = { // cgtryprop; cstage cgen.c:10595-10602). let succisstr: bool = false; if (n.lhs != nil) { - succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo)); + succisstr = syntax.typeisstr(successvariant(n.lhs.type_: *syntax.tinfo)); }; if (succisstr) { // str IS []u8: success arrives DX=ptr, CX=len, R8=cap @@ -24386,7 +24386,7 @@ fn cgtryunw(c: *cgen, n: *node) void = { return; }; -fn cgtypetest(c: *cgen, n: *node) void = { +fn cgtypetest(c: *cgen, n: *syntax.node) void = { // `e is T` — load the lhs's tag, compare against T's variant // index, set AX = (tag == idx). Result type is bool. // @@ -24398,12 +24398,12 @@ fn cgtypetest(c: *cgen, n: *node) void = { // the ident emission carries; a WIDENING tagged cast renumbers // the tag the compare keys on and has no wired source arm — // loud below, not a mis-keyed test. Mirrors cstage N_TYPETEST. - let lhs: *node = taggedidcastpeel(c, n.lhs); + let lhs: *syntax.node = taggedidcastpeel(c, n.lhs); // #38b residual (rule 7): an sret-class call result leaves AX = // dest pointer, not the tag — mem-based test is a #40-family // follow-up. Mirrors cstage cgen.c N_TYPETEST gate. if (lhs != nil) { - if (lhs.kind == nkind.N_CALL) { + if (lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, lhs) > 0) { let m38t: str = "#38b: `is` on an sret-class call result unwired (#40-family follow-up)\n"; os.write(2, m38t.ptr, m38t.len: u64); @@ -24412,11 +24412,11 @@ fn cgtypetest(c: *cgen, n: *node) void = { }; }; let scrutoff: i32 = 0; - let scrutt: *node = nil; + let scrutt: *syntax.node = nil; let nonident: bool = false; let globalident: bool = false; if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, lhs.str); if (lc != nil) { scrutoff = lc.off; @@ -24425,7 +24425,7 @@ fn cgtypetest(c: *cgen, n: *node) void = { // #18 is-half (align-UP): global tagged ident — tag word at // g(SB)+0, no BP slot. cstage N_TYPETEST is uniformly cgexpr // (MOVQ g(SB),AX); pre-fix the !nonident emit read 0(BP)=saved BP. - let gt: *node = letvartnode(c, lhs.str); + let gt: *syntax.node = letvartnode(c, lhs.str); scrutt = resolvetagged(c, gt); globalident = true; }; @@ -24444,10 +24444,10 @@ fn cgtypetest(c: *cgen, n: *node) void = { // Family C catch-all (rule 7): a widening tagged // cast source — loud. Mirrors cstage. { - let icu: *tinfo = lhs.type_: *tinfo; + let icu: *syntax.tinfo = lhs.type_: *syntax.tinfo; icu = tichase(icu); - if (lhs.kind == nkind.N_CAST && icu != nil - && icu.kind == tykind.TY_TAGGED + if (lhs.kind == syntax.nkind.N_CAST && icu != nil + && icu.kind == syntax.tykind.TY_TAGGED && icu.nullable == 0) { let m35i: str = "#35: tagged cast source shape unwired at `is` (rule 7)\n"; os.write(2, m35i.ptr, m35i.len: u64); @@ -24464,7 +24464,7 @@ fn cgtypetest(c: *cgen, n: *node) void = { }; }; let want: i32 = 0; - let nullcarrier: *node = scrutt; + let nullcarrier: *syntax.node = scrutt; if (nonident) { // Variant index from the STAMPED scrutinee type (cstage: // u = n->lhs->type) — matchscrutt's node-shape walk can't @@ -24473,7 +24473,7 @@ fn cgtypetest(c: *cgen, n: *node) void = { // flatslicevariantidx read .type_ off any stamped carrier. nullcarrier = lhs; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_TSLICE) { + if (n.rhs.kind == syntax.nkind.N_TSLICE) { want = flatslicevariantidx(c, lhs, n.rhs.lhs); } else { want = flatvariantidx(c, lhs, n.rhs); @@ -24524,13 +24524,13 @@ fn cgtypetest(c: *cgen, n: *node) void = { return; }; -fn cgtypeassert(c: *cgen, n: *node) void = { +fn cgtypeassert(c: *cgen, n: *syntax.node) void = { // `e as T` — load tag, abort (exit 1) if tag != T's variant // index, otherwise unwrap to T's ABI: scalar/ptr → AX, 16B // str → (AX, BX). Mirrors cgmatch's slot-based value load. // Slot resolution inlined; see cgtypetest comment. // Family C (#35): identity-cast peel — see the cgtypetest twin. - let lhs: *node = taggedidcastpeel(c, n.lhs); + let lhs: *syntax.node = taggedidcastpeel(c, n.lhs); // Enum ↔ integer: reinterpret-only — the value already occupies AX // (or AX:BX for str variants, irrelevant here); no tag/unwrap. Gate // on the stamped operand / result TYPE, not node shape: a constant- @@ -24539,13 +24539,13 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // spurious tagged-assertion + exit(1) (#27b). Mirrors cstage // cmd/w6c/cgen.c N_TYPEASSERT (type_chase_named on operand + result). { - let su: *tinfo = nil; - if (lhs != nil) { su = tichase(lhs.type_: *tinfo); }; - let vu: *tinfo = tichase(n.type_: *tinfo); + let su: *syntax.tinfo = nil; + if (lhs != nil) { su = tichase(lhs.type_: *syntax.tinfo); }; + let vu: *syntax.tinfo = tichase(n.type_: *syntax.tinfo); let lenum: bool = false; let renum: bool = false; - if (su != nil) { if (su.kind == tykind.TY_ENUM) { lenum = true; }; }; - if (vu != nil) { if (vu.kind == tykind.TY_ENUM) { renum = true; }; }; + if (su != nil) { if (su.kind == syntax.tykind.TY_ENUM) { lenum = true; }; }; + if (vu != nil) { if (vu.kind == syntax.tykind.TY_ENUM) { renum = true; }; }; if (lenum || renum) { cgexpr(c, lhs); return; @@ -24555,7 +24555,7 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // an sret-class call result never fills. Mirrors cstage cgen.c // N_TYPEASSERT gate. if (lhs != nil) { - if (lhs.kind == nkind.N_CALL) { + if (lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, lhs) > 0) { let m38a: str = "#38b: `as` on an sret-class call result unwired (#40-family follow-up)\n"; os.write(2, m38a.ptr, m38a.len: u64); @@ -24564,9 +24564,9 @@ fn cgtypeassert(c: *cgen, n: *node) void = { }; }; let scrutoff: i32 = 0; - let scrutt: *node = nil; + let scrutt: *syntax.node = nil; if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, lhs.str); if (lc != nil) { scrutoff = lc.off; @@ -24577,7 +24577,7 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // task #46). No BP slot: copy the box words from g(SB) into a // fresh @asrt_spill so the tag-check + payload load below index // off memory like a local. cs!=ww residual until #46 lands. - let gt: *node = letvartnode(c, lhs.str); + let gt: *syntax.node = letvartnode(c, lhs.str); scrutt = resolvetagged(c, gt); let gsz: i32 = matchspillsz(c, scrutt); scrutoff = localalloc(c, "@asrt_spill", gsz, nil); @@ -24634,10 +24634,10 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // Family C catch-all (rule 7): a widening tagged // cast source — loud. Mirrors cstage. { - let acu: *tinfo = lhs.type_: *tinfo; + let acu: *syntax.tinfo = lhs.type_: *syntax.tinfo; acu = tichase(acu); - if (lhs.kind == nkind.N_CAST && acu != nil - && acu.kind == tykind.TY_TAGGED + if (lhs.kind == syntax.nkind.N_CAST && acu != nil + && acu.kind == syntax.tykind.TY_TAGGED && acu.nullable == 0) { let m35s: str = "#35: tagged cast source shape unwired at `as` (rule 7)\n"; os.write(2, m35s.ptr, m35s.len: u64); @@ -24716,12 +24716,12 @@ fn cgtypeassert(c: *cgen, n: *node) void = { return; }; -fn cgcast(c: *cgen, n: *node) void = { +fn cgcast(c: *cgen, n: *syntax.node) void = { let srcfk: i32 = 0; if (n.lhs != nil) { - let st: *tinfo = n.lhs.type_: *tinfo; - if (typeisf32(st)) { srcfk = 1; } - else { if (typeisfloat(st)) { srcfk = 2; }; }; + let st: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; + if (syntax.typeisf32(st)) { srcfk = 1; } + else { if (syntax.typeisfloat(st)) { srcfk = 2; }; }; }; let dstf64: bool = isfloattype(c, n.rhs); let dstf32: bool = isf32type(c, n.rhs); @@ -24774,18 +24774,18 @@ fn cgcast(c: *cgen, n: *node) void = { // Detect bool dst by walking n.rhs to the leaf TNAME. bool // keeps its dedicated ANDQ $255 contract regardless of // upstream shape; it stays off the identity path. - let leaf_tn: *node = n.rhs; + let leaf_tn: *syntax.node = n.rhs; for (leaf_tn != nil) { - let lk: nkind = leaf_tn.kind; - if (lk == nkind.N_TBANG) { leaf_tn = leaf_tn.lhs; } - else { if (lk == nkind.N_TENUM) { leaf_tn = leaf_tn.lhs; } - else { if (lk == nkind.N_TNAME) { + let lk: syntax.nkind = leaf_tn.kind; + if (lk == syntax.nkind.N_TBANG) { leaf_tn = leaf_tn.lhs; } + else { if (lk == syntax.nkind.N_TENUM) { leaf_tn = leaf_tn.lhs; } + else { if (lk == syntax.nkind.N_TNAME) { let lnm: str = leaf_tn.str; // primsize-ok (#101/#109): this IS an alias chase loop // — primsize is the leaf-primitive break test the loop // wraps (aliaslookup advances the cursor on a miss). if (primsize(lnm) > 0) { break; }; - let lal: *node = aliaslookup(c, lnm); + let lal: *syntax.node = aliaslookup(c, lnm); if (lal == nil) { leaf_tn = nil; } else { leaf_tn = lal; }; } @@ -24793,8 +24793,8 @@ fn cgcast(c: *cgen, n: *node) void = { }; let is_bool: bool = false; if (leaf_tn != nil) { - if (leaf_tn.kind == nkind.N_TNAME) { - is_bool = streq(leaf_tn.str, "bool"); + if (leaf_tn.kind == syntax.nkind.N_TNAME) { + is_bool = syntax.streq(leaf_tn.str, "bool"); }; }; // Symmetric narrow on signed vs unsigned (task #5): @@ -24852,7 +24852,7 @@ fn cgcast(c: *cgen, n: *node) void = { // Same-kind float→float: nothing to emit. }; -fn cgstrlit(c: *cgen, n: *node) void = { +fn cgstrlit(c: *cgen, n: *syntax.node) void = { // str IS []u8: the (ptr, len, cap) triple — ptr in AX, len in BX, // cap in CX. A static literal has no spare storage, so cap = len // (#1/Phase 3). Call sites that expect a str arg pick these up. @@ -24870,7 +24870,7 @@ fn cgstrlit(c: *cgen, n: *node) void = { return; }; -fn cgident(c: *cgen, n: *node) void = { +fn cgident(c: *cgen, n: *syntax.node) void = { let nm: str = n.str; let lc: *local = localfindnode(c, nm); if (lc != nil) { @@ -24878,10 +24878,10 @@ fn cgident(c: *cgen, n: *node) void = { // #241: a tuple ident is a value — leave the whole tuple in the // register cursor (`yield t` / `return t` / `let q = t`), not // just word0 in AX. Mirror of cstage cgexpr N_IDENT tuple arm. - let itu: *tinfo = nil; - if (lc.tnode != nil) { itu = lc.tnode.type_: *tinfo; }; + let itu: *syntax.tinfo = nil; + if (lc.tnode != nil) { itu = lc.tnode.type_: *syntax.tinfo; }; itu = tichase(itu); - if (itu != nil) { if (itu.kind == tykind.TY_TUPLE) { + if (itu != nil) { if (itu.kind == syntax.tykind.TY_TUPLE) { cgtupleslottocursor(c, off, itu); return; }; }; @@ -24938,9 +24938,9 @@ fn cgident(c: *cgen, n: *node) void = { // the (LEAQ ptr, MOVQ $len) pair instead, mirroring cstage // Sdef walk #1 N_IDENT bare-load (cmd/w6c/cgen.c). Filed #12. if (deflookup(c, nm)) { - let drhs: *node = deflookuprhs(c, nm); + let drhs: *syntax.node = deflookuprhs(c, nm); if (drhs != nil) { - if (drhs.kind == nkind.N_STRLIT) { + if (drhs.kind == syntax.nkind.N_STRLIT) { let bytes: str = drhs.str; let lab: str = internstrlit(c, bytes); emitline("\tLEAQ\t"); @@ -24984,7 +24984,7 @@ fn cgident(c: *cgen, n: *node) void = { // in one go, so a body-less FFI binding emits the C symbol // it was declared with via @symbol(), not the ww-side ident. // Bare ident → same-module by ww's resolver, hint with c.curmod. - let rtyp: *node = fnretlookup(c, nm); + let rtyp: *syntax.node = fnretlookup(c, nm); if (rtyp != nil) { emitline("\tLEAQ\t"); emitfnname(c, nm, c.curmod); @@ -25005,12 +25005,12 @@ fn cgident(c: *cgen, n: *node) void = { // receive read a STALE cursor for words 1+. Element reads // (g.N) are the supported surface. Mirrors the cstage cgexpr // non-local ident guard. - let gtt: *node = letvartnode(c, nm); - for (gtt != nil && gtt.kind == nkind.N_TNAME) { + let gtt: *syntax.node = letvartnode(c, nm); + for (gtt != nil && gtt.kind == syntax.nkind.N_TNAME) { gtt = aliaslookup(c, gtt.str); }; if (gtt != nil) { - if (gtt.kind == nkind.N_TTUPLE) { + if (gtt.kind == syntax.nkind.N_TTUPLE) { let mgt: str = "#48: global tuple as a first-class value unwired (element reads only; rule 7)\n"; os.write(2, mgt.ptr, mgt.len: u64); os.exit(1); @@ -25035,10 +25035,10 @@ fn cgident(c: *cgen, n: *node) void = { // MOVSD have no D_EXTERN operand form in w6a. Signed-narrow // scalar globals route through the same LEAQ scratch since // MOVSXD/MOVSWQ/MOVSBQ also have no D_EXTERN form. - let lvtnode: *node = nil; + let lvtnode: *syntax.node = nil; let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, nm)) { + if (syntax.streq(lv.name, nm)) { // #135: an inferred-float global's tnode is the // defaultinferredlets-renamed "f64"/"f32" N_TNAME whose // .type_ is unstamped (cgen can't build tinfo), so the @@ -25048,7 +25048,7 @@ fn cgident(c: *cgen, n: *node) void = { let isf: bool = isfloattype(c, lv.tnode); let is32: bool = isf32type(c, lv.tnode); if (!isf && lv.tnode != nil - && lv.tnode.kind == nkind.N_TNAME) { + && lv.tnode.kind == syntax.nkind.N_TNAME) { let fsz: i32 = letfloatprim(lv.tnode.str); if (fsz > 0) { isf = true; }; if (fsz == 4) { is32 = true; }; @@ -25071,7 +25071,7 @@ fn cgident(c: *cgen, n: *node) void = { }; }; let glop: str = localloadop(c, lvtnode); - if (streq(glop, "MOVQ")) { + if (syntax.streq(glop, "MOVQ")) { emitline("\tMOVQ\t"); emitfnname(c, nm, c.curmod); emitline("(SB), AX\n"); @@ -25096,12 +25096,12 @@ fn cgident(c: *cgen, n: *node) void = { // and, later, the typeassert str-variant leaf (#9). c retained unused // for callsite symmetry with cstage cgslicehdr. fn cgslicehdr(c: *cgen, base: str) void = { - if (!streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; - if (!streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; - if (!streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; - if (streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; - if (streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; - if (streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; + if (!syntax.streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; + if (!syntax.streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; + if (!syntax.streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; + if (syntax.streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; + if (syntax.streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; + if (syntax.streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; }; // dotchainaddr — emit the ADDRESS of a dot/ident lvalue chain into @@ -25113,9 +25113,9 @@ fn cgslicehdr(c: *cgen, base: str) void = { // spill contract as dotbaseaddr. The chained-base arm of dotbaseaddr // (#253) is its sole caller. Cstage twin: cmd/w6c/cgen.c // `cg_dotchain_addr`. -fn dotchainaddr(c: *cgen, n: *node, dstreg: str) bool = { +fn dotchainaddr(c: *cgen, n: *syntax.node, dstreg: str) bool = { if (n == nil) { return false; }; - if (n.kind == nkind.N_IDENT) { + if (n.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -25142,29 +25142,29 @@ fn dotchainaddr(c: *cgen, n: *node, dstreg: str) bool = { }; return false; }; - if (n.kind != nkind.N_DOT) { return false; }; - let x: *node = n.lhs; + if (n.kind != syntax.nkind.N_DOT) { return false; }; + let x: *syntax.node = n.lhs; if (x == nil) { return false; }; - let xu: *tinfo = x.type_: *tinfo; + let xu: *syntax.tinfo = x.type_: *syntax.tinfo; xu = tichase(xu); if (xu == nil) { return false; }; let xviaptr: bool = false; - let st: *tinfo = nil; - if (xu.kind == tykind.TY_PTR) { - let p: *tinfo = xu.sub; + let st: *syntax.tinfo = nil; + if (xu.kind == syntax.tykind.TY_PTR) { + let p: *syntax.tinfo = xu.sub; p = tichase(p); - if (p != nil) { if (p.kind == tykind.TY_STRUCT) { + if (p != nil) { if (p.kind == syntax.tykind.TY_STRUCT) { st = p; xviaptr = true; }; }; - } else { if (xu.kind == tykind.TY_STRUCT) { + } else { if (xu.kind == syntax.tykind.TY_STRUCT) { st = xu; }; }; if (st == nil) { return false; }; - let f: *tfield = st.fields; + let f: *syntax.tfield = st.fields; let foff: i64 = -1; for (f != nil) { - if (streq(f.name, n.str)) { + if (syntax.streq(f.name, n.str)) { foff = f.offset: i64; break; }; @@ -25207,13 +25207,13 @@ fn dotchainaddr(c: *cgen, n: *node, dstreg: str) bool = { // inner when inner is a *struct (viaptr), else the ADDRESS of inner — // then adds the field offset. Closes the array-field-base-address // family across every op (index r/w, addr-of, slice, compound). -fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { +fn dotbaseaddr(c: *cgen, base: *syntax.node, dstreg: str) bool = { if (base == nil) { return false; }; - if (base.kind != nkind.N_DOT) { return false; }; - let inner: *node = base.lhs; + if (base.kind != syntax.nkind.N_DOT) { return false; }; + let inner: *syntax.node = base.lhs; if (inner == nil) { return false; }; - let chained: bool = (inner.kind == nkind.N_DOT); - if (inner.kind != nkind.N_IDENT && !chained) { return false; }; + let chained: bool = (inner.kind == syntax.nkind.N_DOT); + if (inner.kind != syntax.nkind.N_IDENT && !chained) { return false; }; // #128b: module-qualified `mod.arr` where arr is an imported // top-level `let X: [N]T`. The checker leaves SK_USE module- // idents without a localfindnode entry; detect via letvartnode @@ -25232,10 +25232,10 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { // (cgen.c:2109). Without the gate a typed-struct global inner whose // FIELD shares a name with an unrelated global array hijacks it // (gs.fld -> LEAQ fld(SB)) — #20. A typed inner falls to #249 below. - let ibu: *tinfo = tichase(inner.type_: *tinfo); - if (ibu == nil || ibu.kind == tykind.TY_ERR) { - let gt: *node = letvartnode(c, base.str); - if (gt != nil && gt.kind == nkind.N_TARRAY) { + let ibu: *syntax.tinfo = tichase(inner.type_: *syntax.tinfo); + if (ibu == nil || ibu.kind == syntax.tykind.TY_ERR) { + let gt: *syntax.node = letvartnode(c, base.str); + if (gt != nil && gt.kind == syntax.nkind.N_TARRAY) { emitline("\tLEAQ\t"); emitsymname(c, base.str); emitline("(SB), "); @@ -25252,27 +25252,27 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { isglobal = true; }; }; - let bu: *tinfo = inner.type_: *tinfo; + let bu: *syntax.tinfo = inner.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; let viaptr: bool = false; - let structt: *tinfo = nil; - if (bu.kind == tykind.TY_PTR) { - let st: *tinfo = bu.sub; + let structt: *syntax.tinfo = nil; + if (bu.kind == syntax.tykind.TY_PTR) { + let st: *syntax.tinfo = bu.sub; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { structt = st; viaptr = true; }; }; - } else { if (bu.kind == tykind.TY_STRUCT) { + } else { if (bu.kind == syntax.tykind.TY_STRUCT) { structt = bu; }; }; if (structt == nil) { return false; }; - let f: *tfield = structt.fields; + let f: *syntax.tfield = structt.fields; let foff: i64 = -1; - let ft: *tinfo = nil; + let ft: *syntax.tinfo = nil; for (f != nil) { - if (streq(f.name, base.str)) { + if (syntax.streq(f.name, base.str)) { foff = f.offset: i64; ft = f.type_; break; @@ -25286,7 +25286,7 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { // twin gate at cg_dotbase_addr. ft = tichase(ft); if (ft == nil) { return false; }; - if (ft.kind != tykind.TY_ARRAY) { return false; }; + if (ft.kind != syntax.tykind.TY_ARRAY) { return false; }; // #253: chained inner — compute the container base via the dot-chain // spine (pointer VALUE of inner when viaptr, else its ADDRESS), then // add the field offset. dotchainaddr keeps the spill contract. @@ -25356,11 +25356,11 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { // #253), N_INDEX element of an N_IDENT array base (the &base[i] spine, // #252/#270). Returns false for an uncovered source kind (caller loud- // stops, rule 7). The CALL source is handled at the push site. -fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { - if (src.kind == nkind.N_UN) { - if (src.op == tkind.TK_STAR) { +fn aggargsrcaddr(c: *cgen, src: *syntax.node, dst: str) bool = { + if (src.kind == syntax.nkind.N_UN) { + if (src.op == syntax.tkind.TK_STAR) { cgexpr(c, src.lhs); - if (!streq(dst, "AX")) { + if (!syntax.streq(dst, "AX")) { emitline("\tMOVQ\tAX, "); emitline(dst); emitline("\n"); @@ -25368,7 +25368,7 @@ fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { return true; }; }; - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, src.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -25392,18 +25392,18 @@ fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { }; return false; }; - if (src.kind == nkind.N_DOT) { + if (src.kind == syntax.nkind.N_DOT) { return dotchainaddr(c, src, dst); }; - if (src.kind == nkind.N_INDEX) { - let base: *node = src.lhs; - let idx: *node = src.rhs; + if (src.kind == syntax.nkind.N_INDEX) { + let base: *syntax.node = src.lhs; + let idx: *syntax.node = src.rhs; if (base == nil) { return false; }; - if (base.kind != nkind.N_IDENT) { return false; }; - let bu: *tinfo = base.type_: *tinfo; + if (base.kind != syntax.nkind.N_IDENT) { return false; }; + let bu: *syntax.tinfo = base.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; - if (bu.kind != tykind.TY_ARRAY) { return false; }; + if (bu.kind != syntax.tykind.TY_ARRAY) { return false; }; let esz: i32 = 1; if (bu.sub != nil) { esz = bu.sub.size: i32; }; cgexpr(c, idx); @@ -25424,7 +25424,7 @@ fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { emitline("(SB), BX\n"); }; emitline("\tADDQ\tBX, AX\n"); - if (!streq(dst, "AX")) { + if (!syntax.streq(dst, "AX")) { emitline("\tMOVQ\tAX, "); emitline(dst); emitline("\n"); @@ -25494,13 +25494,13 @@ fn aggcopy(c: *cgen, sz: i32) void = { // #44-coupled source). The ragged-tail completeness shared by both stages' // field copies is a separate class, tracked under #73 / the aggcopy // emitter choke-point. -fn copysrcnatsize(c: *cgen, src: *node) i32 = { +fn copysrcnatsize(c: *cgen, src: *syntax.node) i32 = { if (src == nil || src.type_ == nil) { let msg: str = "#71: whole-struct copy source has no stamped tinfo\n"; os.write(2, msg.ptr, msg.len: u64); os.exit(1); }; - let ti: *tinfo = tichase(src.type_: *tinfo); + let ti: *syntax.tinfo = tichase(src.type_: *syntax.tinfo); if (ti == nil) { let msg: str = "#71: whole-struct copy source tinfo chase yielded nil\n"; os.write(2, msg.ptr, msg.len: u64); @@ -25524,9 +25524,9 @@ fn copysrcnatsize(c: *cgen, src: *node) i32 = { // keeps its own load/store/copy emission. Clobbers AX/CX (cgexpr on // index / pointer operands) and balances its own PUSHQ/POPQ; dstreg // must not be AX or CX. -fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { +fn cgplaceaddr(c: *cgen, n: *syntax.node, dstreg: str) bool = { if (n == nil) { return false; }; - if (n.kind == nkind.N_IDENT) { + if (n.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -25541,9 +25541,9 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { if (defvarstructinfo(c, n.str) != nil) { gok = true; }; }; if (!gok) { - let dtn: *node = defvartnode(c, n.str); + let dtn: *syntax.node = defvartnode(c, n.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { gok = true; }; + if (dtn.kind == syntax.nkind.N_TARRAY) { gok = true; }; }; }; if (gok) { @@ -25556,8 +25556,8 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { }; return false; }; - if (n.kind == nkind.N_UN) { - if (n.op != tkind.TK_STAR) { return false; }; + if (n.kind == syntax.nkind.N_UN) { + if (n.op != syntax.tkind.TK_STAR) { return false; }; // &(*e) is e's value — no load. cgexpr(c, n.lhs); emitline("\tMOVQ\tAX, "); @@ -25565,21 +25565,21 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { emitline("\n"); return true; }; - if (n.kind == nkind.N_INDEX) { - let base: *node = n.lhs; - let idx: *node = n.rhs; + if (n.kind == syntax.nkind.N_INDEX) { + let base: *syntax.node = n.lhs; + let idx: *syntax.node = n.rhs; if (base == nil || idx == nil) { return false; }; // C2: any addressable base — recursion decides (deref / // ident / dot / index spine). Ident-rooted shapes with // enumerated arms never reach the resolver (those arms // dispatch first), so their asm is untouched. - let bu: *tinfo = base.type_: *tinfo; + let bu: *syntax.tinfo = base.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; - if (bu.kind != tykind.TY_SLICE && bu.kind != tykind.TY_ARRAY) { + if (bu.kind != syntax.tykind.TY_SLICE && bu.kind != syntax.tykind.TY_ARRAY) { return false; }; - let et: *tinfo = n.type_: *tinfo; + let et: *syntax.tinfo = n.type_: *syntax.tinfo; et = tichase(et); if (et == nil) { return false; }; let esz: i32 = et.size: i32; @@ -25595,7 +25595,7 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { // A slice place holds the {ptr,len,cap} header — the // element base is its .ptr word; an array place IS the // element storage. - if (bu.kind == tykind.TY_SLICE) { + if (bu.kind == syntax.tykind.TY_SLICE) { emitline("\tMOVQ\t("); emitline(dstreg); emitline("), "); @@ -25608,29 +25608,29 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { emitline("\n"); return true; }; - if (n.kind == nkind.N_DOT) { - let base: *node = n.lhs; + if (n.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = n.lhs; if (base == nil) { return false; }; - let bu: *tinfo = base.type_: *tinfo; + let bu: *syntax.tinfo = base.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; let viaptr: bool = false; - let st: *tinfo = nil; - if (bu.kind == tykind.TY_PTR) { - let p: *tinfo = bu.sub; + let st: *syntax.tinfo = nil; + if (bu.kind == syntax.tykind.TY_PTR) { + let p: *syntax.tinfo = bu.sub; p = tichase(p); - if (p != nil) { if (p.kind == tykind.TY_STRUCT) { + if (p != nil) { if (p.kind == syntax.tykind.TY_STRUCT) { st = p; viaptr = true; }; }; - } else { if (bu.kind == tykind.TY_STRUCT) { + } else { if (bu.kind == syntax.tykind.TY_STRUCT) { st = bu; }; }; if (st == nil) { return false; }; - let f: *tfield = st.fields; + let f: *syntax.tfield = st.fields; let foff: i64 = -1; for (f != nil) { - if (streq(f.name, n.str)) { + if (syntax.streq(f.name, n.str)) { foff = f.offset: i64; break; }; @@ -25657,12 +25657,12 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { return false; }; -fn cgindex(c: *cgen, n: *node) void = { +fn cgindex(c: *cgen, n: *syntax.node) void = { // Element-size-aware load: u8 → MOVZBQ, i32 → MOVSXD, u32 → MOVL, // str → (ptr, len) into (AX, BX), everything else → MOVQ. Fast // path when the base is a bare ident (mem.ww shape). - let base: *node = n.lhs; - let idx: *node = n.rhs; + let base: *syntax.node = n.lhs; + let idx: *syntax.node = n.rhs; // Direct non-ident index bases that match none of the typed arms // below (e.g. a cast-expression base) keep this 8B default — // cs!=ww for narrow elements. Team task #19 (#61-residual B). @@ -25707,7 +25707,7 @@ fn cgindex(c: *cgen, n: *node) void = { let globalname: str; globalname.ptr = nil; globalname.len = 0; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal != nil) { @@ -25717,7 +25717,7 @@ fn cgindex(c: *cgen, n: *node) void = { f32_elem = elemisf32c(c, baselocal.tnode); elem_isarray = elemisarrayc(c, baselocal.tnode); } else { - let tn: *node = letvartnode(c, bn); + let tn: *syntax.node = letvartnode(c, bn); // #129 A.3: array-typed defs now have DATA storage; // resolve their base via the same N_TARRAY path as // lets. defvartnode is the def-side sister of @@ -25750,7 +25750,7 @@ fn cgindex(c: *cgen, n: *node) void = { float_elem = elemisfloatc(c, tn); f32_elem = elemisf32c(c, tn); elem_isarray = elemisarrayc(c, tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; @@ -25760,17 +25760,17 @@ fn cgindex(c: *cgen, n: *node) void = { // #60: element facts off the chased checker-stamped // tinfos — cstage reads them via type_chase_named/ // idx_eff uniformly (cmd/w6c/cgen.c N_INDEX). - let bt60: *tinfo = base.type_: *tinfo; + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; if (bt60 != nil) { - if (bt60.kind == tykind.TY_NAMED) { basealias = true; }; + if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; }; }; if (basealias) { - let et60: *tinfo = tichase(n.type_: *tinfo); + let et60: *syntax.tinfo = tichase(n.type_: *syntax.tinfo); if (et60 != nil) { esz = et60.size: i32; - signed_elem = typeissigned(et60); - float_elem = typeisfloat(et60); - f32_elem = typeisf32(et60); + signed_elem = syntax.typeissigned(et60); + float_elem = syntax.typeisfloat(et60); + f32_elem = syntax.typeisf32(et60); }; // global base: array-vs-pointer re-keyed off the // chased BASE kind (cstage isglobal && u->kind == @@ -25778,9 +25778,9 @@ fn cgindex(c: *cgen, n: *node) void = { // alias-typed global DATA emit lands (#77/#78); // kept so the read leg is already cs-aligned. if (isglobalarr || isglobalptr) { - let bu60: *tinfo = tichase(bt60); + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - isglobalarr = bu60.kind == tykind.TY_ARRAY; + isglobalarr = bu60.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; @@ -25791,9 +25791,9 @@ fn cgindex(c: *cgen, n: *node) void = { // element tinfo is the authority (cstage gates on // esubu = type_chase_named(esub) == TY_ARRAY). if (!elem_isarray) { - elem_isarray = tinfoisarray(n.type_: *tinfo); + elem_isarray = tinfoisarray(n.type_: *syntax.tinfo); }; - } else { if (base.kind == nkind.N_INDEX) { + } else { if (base.kind == syntax.nkind.N_INDEX) { // #60: chained `names[i][k]` — n.type_ is the checker- // stamped outer element tinfo (indexresult over the inner // index's value type). cstage reads base->type->sub->size @@ -25809,14 +25809,14 @@ fn cgindex(c: *cgen, n: *node) void = { // reading the SAME stamp the esz read above uses. CLASS-N: // the corpus has no chained str/slice element, so the prior // byte-id is preserved (this only fires on the missed shape). - let et: *tinfo = n.type_: *tinfo; + let et: *syntax.tinfo = n.type_: *syntax.tinfo; if (et != nil) { esz = et.size: i32; - signed_elem = typeissigned(et); - elemisstr = typeisstr(et); - elemisslice = typeisslice(et); - float_elem = typeisfloat(et); - f32_elem = typeisf32(et); + signed_elem = syntax.typeissigned(et); + elemisstr = syntax.typeisstr(et); + elemisslice = syntax.typeisslice(et); + float_elem = syntax.typeisfloat(et); + f32_elem = syntax.typeisf32(et); elem_isarray = tinfoisarray(et); }; } else { @@ -25838,8 +25838,8 @@ fn cgindex(c: *cgen, n: *node) void = { // on (signed,sz); cstage's fldloadop reads it from the element // type — align ww up, #255). The base ADDRESS materialization // below is unchanged; only the stride/load-width was wrong. - let dt: *tinfo = n.type_: *tinfo; - if (dt != nil) { esz = dt.size: i32; signed_elem = typeissigned(dt); elemisstr = typeisstr(dt); elemisslice = typeisslice(dt); float_elem = typeisfloat(dt); f32_elem = typeisf32(dt); }; + let dt: *syntax.tinfo = n.type_: *syntax.tinfo; + if (dt != nil) { esz = dt.size: i32; signed_elem = syntax.typeissigned(dt); elemisstr = syntax.typeisstr(dt); elemisslice = syntax.typeisslice(dt); float_elem = syntax.typeisfloat(dt); f32_elem = syntax.typeisf32(dt); }; elem_isarray = tinfoisarray(dt); };}; }; @@ -25851,9 +25851,9 @@ fn cgindex(c: *cgen, n: *node) void = { let elem_tagged: bool = false; let elem_slot_sz: i32 = esz; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bl: *local = baselocal; - let etn: *node = nil; + let etn: *syntax.node = nil; // idxelemtn drills `*[N]T` to the pointee array's own // element (#61) — an undrilled etn classified the whole // array, missing tagged/str/slice elements behind a @@ -25904,10 +25904,10 @@ fn cgindex(c: *cgen, n: *node) void = { // `MOVQ (AX),AX` (tag only) vs cstage's full 4-word cursor // (cs rc=50 / ww rc=40). Dropping the whitelist for the stamp read // closes the base-kind class by construction. - if (base.kind != nkind.N_IDENT) { - let dt: *tinfo = n.type_: *tinfo; + if (base.kind != syntax.nkind.N_IDENT) { + let dt: *syntax.tinfo = n.type_: *syntax.tinfo; if (dt != nil) { - if (typeistagged(dt)) { + if (syntax.typeistagged(dt)) { elem_tagged = true; elem_slot_sz = dt.size: i32; esz = elem_slot_sz; @@ -25923,11 +25923,11 @@ fn cgindex(c: *cgen, n: *node) void = { let elem_tuple: bool = false; let tuple_nwords: i32 = 0; { - let eti: *tinfo = tichase(n.type_: *tinfo); - if (eti != nil) { if (eti.kind == tykind.TY_TUPLE) { + let eti: *syntax.tinfo = tichase(n.type_: *syntax.tinfo); + if (eti != nil) { if (eti.kind == syntax.tykind.TY_TUPLE) { elem_tuple = true; // ww tuples store elements in .tupleelems, not .params. - let tpw: *ttupleelem = eti.tupleelems; + let tpw: *syntax.ttupleelem = eti.tupleelems; for (tpw != nil) { tuple_nwords += tupeslot(tpw.type_) / 8; tpw = tpw.tnext; @@ -26024,14 +26024,14 @@ fn cgindex(c: *cgen, n: *node) void = { return; }; if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; - if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; }; + if (tn != nil) { if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — LEAQ-vs-MOVQ off the chased stamped // kind (cstage u->kind == TY_ARRAY, cmd/w6c/cgen.c N_INDEX). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarray) { emitline("\tLEAQ\t"); @@ -26204,16 +26204,16 @@ fn cgindex(c: *cgen, n: *node) void = { // a GLOBAL str base (no +16 load here, #73 -- matching the cstage // carve-out keeps both stages byte-identical). cstage twin: // cmd/w6c/cgen.c cg_base_cap. -fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { +fn cgbasecap(c: *cgen, base: *syntax.node, dst: str) bool = { if (base == nil) { return false; }; - if (base.kind != nkind.N_IDENT) { return false; }; + if (base.kind != syntax.nkind.N_IDENT) { return false; }; let baselocal: *local = localfindnode(c, base.str); if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; if (tn == nil) { return false; }; - if (tn.kind == nkind.N_TARRAY) { - let lenn: *node = tn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (tn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = tn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", "); @@ -26225,8 +26225,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { // from the stamped array tinfo (rule-13), the cap twin of the // default-hi fix; pre-fix cgbasecap returned false here and the // caller fell to cap=len (cs computes base_cap-lo from bu->alen). - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", "); @@ -26236,7 +26236,7 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { }; return false; }; - if (tn.kind == nkind.N_TSLICE) { + if (tn.kind == syntax.nkind.N_TSLICE) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 16): i64); emitline("(BP), "); @@ -26244,8 +26244,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { emitline("\n"); return true; }; - if (tn.kind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { + if (tn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 16): i64); emitline("(BP), "); @@ -26256,11 +26256,11 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { }; // #60: alias-NAMED base — chased kind (cstage cg_base_cap // receives bu pre-chased by the N_SLICE arm, cgen.c:1888). - let bt60: *tinfo = base.type_: *tinfo; - if (bt60 != nil) { if (bt60.kind == tykind.TY_NAMED) { - let bu60: *tinfo = tichase(bt60); + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt60 != nil) { if (bt60.kind == syntax.tykind.TY_NAMED) { + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", "); @@ -26268,8 +26268,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { emitline("\n"); return true; }; - if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 16): i64); emitline("(BP), "); @@ -26281,11 +26281,11 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { };}; return false; }; - let gt: *node = letvartnode(c, base.str); + let gt: *syntax.node = letvartnode(c, base.str); if (gt == nil) { return false; }; - if (gt.kind == nkind.N_TARRAY) { - let lenn: *node = gt.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (gt.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = gt.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", "); @@ -26294,8 +26294,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { return true; }; // #21: def/const global array dim cap — twin of the local arm. - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", "); @@ -26305,7 +26305,7 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { }; return false; }; - if (gt.kind == nkind.N_TSLICE) { + if (gt.kind == syntax.nkind.N_TSLICE) { emitline("\tLEAQ\t"); emitsymname(c, base.str); emitline("(SB), "); @@ -26321,11 +26321,11 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { // #60: alias-NAMED global base — chased kind; global STR keeps // the #73 cap=len carve-out (cstage isglobal && TY_STR → 0). // Runtime-unreachable until #77/#78 global DATA. - let gbt60: *tinfo = base.type_: *tinfo; - if (gbt60 != nil) { if (gbt60.kind == tykind.TY_NAMED) { - let gbu60: *tinfo = tichase(gbt60); + let gbt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (gbt60 != nil) { if (gbt60.kind == syntax.tykind.TY_NAMED) { + let gbu60: *syntax.tinfo = tichase(gbt60); if (gbu60 != nil) { - if (gbu60.kind == tykind.TY_ARRAY) { + if (gbu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(gbu60.alen: i64); emitline(", "); @@ -26333,7 +26333,7 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { emitline("\n"); return true; }; - if (gbu60.kind == tykind.TY_SLICE) { + if (gbu60.kind == syntax.tykind.TY_SLICE) { emitline("\tLEAQ\t"); emitsymname(c, base.str); emitline("(SB), "); @@ -26364,45 +26364,45 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { // the COUNT by this same width, so it MUST match cgslice's ptr scaling // byte-for-byte (cgslice supplies the dst ptr). Cstage twin: the N_SLICE-LHS // arm in cgen.c N_ASSIGN reuses the read-path one-liner directly. -fn slicebaseesz(c: *cgen, base: *node) i32 = { +fn slicebaseesz(c: *cgen, base: *syntax.node) i32 = { if (base == nil) { return 1; }; let esz: i32 = 1; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bl: *local = localfindnode(c, base.str); if (bl != nil) { esz = elemsizeofc(c, bl.tnode); } else { - let gt: *node = letvartnode(c, base.str); + let gt: *syntax.node = letvartnode(c, base.str); if (gt != nil) { esz = elemsizeofc(c, gt); }; }; - let bt: *tinfo = base.type_: *tinfo; - if (bt != nil) { if (bt.kind == tykind.TY_NAMED) { - let bu60: *tinfo = tichase(bt); - let es60: *tinfo = tichase(bu60.sub); + let bt: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt != nil) { if (bt.kind == syntax.tykind.TY_NAMED) { + let bu60: *syntax.tinfo = tichase(bt); + let es60: *syntax.tinfo = tichase(bu60.sub); if (es60 != nil) { esz = es60.size: i32; }; };}; - } else { if (base.kind == nkind.N_DOT) { - let db: *tinfo = tichase(base.type_: *tinfo); + } else { if (base.kind == syntax.nkind.N_DOT) { + let db: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); if (db != nil) { if (db.sub != nil) { esz = db.sub.size: i32; }; }; - } else { if (base.kind == nkind.N_ARRLIT) { + } else { if (base.kind == syntax.nkind.N_ARRLIT) { esz = elemsizeofc(c, base.lhs); };};}; return esz; }; -fn cgslice(c: *cgen, n: *node) void = { - let base: *node = n.lhs; - let lo: *node = n.rhs; - let hi: *node = n.cond; +fn cgslice(c: *cgen, n: *syntax.node) void = { + let base: *syntax.node = n.lhs; + let lo: *syntax.node = n.rhs; + let hi: *syntax.node = n.cond; let baselocal: *local = nil; - let globaltn: *node = nil; + let globaltn: *syntax.node = nil; let globalname: str; globalname.ptr = nil; globalname.len = 0; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { baselocal = localfindnode(c, base.str); if (baselocal == nil) { - let gt: *node = letvartnode(c, base.str); + let gt: *syntax.node = letvartnode(c, base.str); if (gt != nil) { globaltn = gt; globalname = base.str; @@ -26414,9 +26414,9 @@ fn cgslice(c: *cgen, n: *node) void = { // tnode — resolve esz / default-hi / base-address from the checker- // stamped element tinfo on base.type_ instead. Cstage twin reads // base->type (cgen.c N_SLICE esz + bu->kind==TY_ARRAY default-hi). - let dotbu: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_DOT) { - dotbu = base.type_: *tinfo; + let dotbu: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_DOT) { + dotbu = base.type_: *syntax.tinfo; dotbu = tichase(dotbu); };}; // #31: an N_ARRLIT base (the desugared one-step `let xs:[]T=[..]` @@ -26426,8 +26426,8 @@ fn cgslice(c: *cgen, n: *node) void = { // count come NODE-wise (elemsizeofc / .rhs intlit), because wwstage // narrow-primitive tinfos are unsized (#8). Cstage twin reads base->type // (its Type IS sized). - let arrlittn: *node = nil; - if (base != nil) { if (base.kind == nkind.N_ARRLIT) { + let arrlittn: *syntax.node = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_ARRLIT) { arrlittn = base.lhs; };}; // #60 (alias arc #5): alias-NAMED N_IDENT base — the tnode reads @@ -26436,10 +26436,10 @@ fn cgslice(c: *cgen, n: *node) void = { // stamped tinfo, mirroring cstage N_SLICE's single // bu = type_chase_named(base->type) source (cmd/w6c/cgen.c). let basealias: bool = false; - let bu60: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; - if (bt60 != nil) { if (bt60.kind == tykind.TY_NAMED) { + let bu60: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt60 != nil) { if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; bu60 = tichase(bt60); };}; @@ -26459,18 +26459,18 @@ fn cgslice(c: *cgen, n: *node) void = { esz = elemsizeofc(c, arrlittn); };};};}; if (bu60 != nil) { - let es60: *tinfo = tichase(bu60.sub); + let es60: *syntax.tinfo = tichase(bu60.sub); if (es60 != nil) { esz = es60.size: i32; }; }; // base address if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { isarray = true; }; + if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; if (isarray) { emitline("\tLEAQ\t"); emitoff(baselocal.off: i64); @@ -26484,10 +26484,10 @@ fn cgslice(c: *cgen, n: *node) void = { // Top-level let: [N]T → LEAQ name(SB); pointer/slice/str // → MOVQ name(SB) (the symbol holds the {ptr,len,cap} or // {ptr,len} or pointer value). - let gisarr: bool = globaltn.kind == nkind.N_TARRAY; + let gisarr: bool = globaltn.kind == syntax.nkind.N_TARRAY; // #60: alias-NAMED base — chased kind; runtime-unreachable // until #77/#78 global DATA (see cgindex twin). - if (bu60 != nil) { gisarr = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { gisarr = bu60.kind == syntax.tykind.TY_ARRAY; }; if (gisarr) { emitline("\tLEAQ\t"); emitsymname(c, globalname); @@ -26497,7 +26497,7 @@ fn cgslice(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), AX\n"); }; - } else { if (base != nil && base.kind == nkind.N_ARRLIT + } else { if (base != nil && base.kind == syntax.nkind.N_ARRLIT && arrlittn != nil) { // #31: materialise the array literal into a FRESH per-borrow // @slicescr stack slot (distinct slot per borrow — a borrow's @@ -26512,7 +26512,7 @@ fn cgslice(c: *cgen, n: *node) void = { // local borrowed past its frame is a footgun, not promoted). let cnt: i32 = 0; if (arrlittn.rhs != nil) { - if (arrlittn.rhs.kind == nkind.N_INTLIT) { + if (arrlittn.rhs.kind == syntax.nkind.N_INTLIT) { cnt = arrlittn.rhs.uval: i32; }; }; @@ -26540,12 +26540,12 @@ fn cgslice(c: *cgen, n: *node) void = { if (hi != nil) { cgexpr(c, hi); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let handled: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { - let lenn: *node = tn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (tn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = tn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -26556,21 +26556,21 @@ fn cgslice(c: *cgen, n: *node) void = { // (MOVQ $0 default-hi -> len 0 / underflow, exit 255). // Read the resolved length from the stamped array // tinfo (rule-13), mirroring cstage's bu->alen. - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); handled = true; }; }; - } else { if (tn.kind == nkind.N_TSLICE) { + } else { if (tn.kind == syntax.nkind.N_TSLICE) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); handled = true; - } else { if (tn.kind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { + } else { if (tn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); @@ -26582,13 +26582,13 @@ fn cgslice(c: *cgen, n: *node) void = { // N_SLICE hi-default reads bu uniformly: TY_ARRAY → $alen, // TY_SLICE/TY_STR → len word at +8). if (!handled && bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); handled = true; - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); @@ -26598,9 +26598,9 @@ fn cgslice(c: *cgen, n: *node) void = { if (!handled) { emitline("\tMOVQ\t$0, AX\n"); }; } else { if (globaltn != nil) { let handled: bool = false; - if (globaltn.kind == nkind.N_TARRAY) { - let lenn: *node = globaltn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (globaltn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = globaltn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -26609,15 +26609,15 @@ fn cgslice(c: *cgen, n: *node) void = { // #21: a def/const global array dim — non-N_INTLIT, read the // resolved length off the stamped array tinfo (rule-13), the // twin of the local arm above (cstage's bu->alen). - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); handled = true; }; }; - } else { if (globaltn.kind == nkind.N_TSLICE) { + } else { if (globaltn.kind == syntax.nkind.N_TSLICE) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -26628,13 +26628,13 @@ fn cgslice(c: *cgen, n: *node) void = { // runtime-unreachable until #77/#78 global DATA (cstage // emits LEAQ+8 for global SLICE/STR alike). if (!handled && bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); handled = true; - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -26643,7 +26643,7 @@ fn cgslice(c: *cgen, n: *node) void = { };}; }; if (!handled) { emitline("\tMOVQ\t$0, AX\n"); }; - } else { if (dotbu != nil && dotbu.kind == tykind.TY_ARRAY) { + } else { if (dotbu != nil && dotbu.kind == syntax.tykind.TY_ARRAY) { // #252: default-hi `s.obuf[lo:]` on a struct array-field → // element count from the field's array tinfo. Cstage twin // cgexpr_int(bu->alen) (cgen.c N_SLICE default-hi). @@ -26655,7 +26655,7 @@ fn cgslice(c: *cgen, n: *node) void = { // stashed [count]T tnode's .rhs intlit). let hc: i64 = 0i64; if (arrlittn.rhs != nil) { - if (arrlittn.rhs.kind == nkind.N_INTLIT) { + if (arrlittn.rhs.kind == syntax.nkind.N_INTLIT) { hc = arrlittn.rhs.uval: i64; }; }; @@ -26689,7 +26689,7 @@ fn cgslice(c: *cgen, n: *node) void = { }; }; -fn cgmatch(c: *cgen, n: *node) void = { +fn cgmatch(c: *cgen, n: *syntax.node) void = { // match (e) { case let v: T => stmt; ... } // // Read the tagged-union slot and dispatch by tag. Slot @@ -26697,11 +26697,11 @@ fn cgmatch(c: *cgen, n: *node) void = { // (`case let v: T =>`) get a fresh local slot loaded from // slot+8 (and slot+16 for str-typed payload). // Family C (#35): identity-cast peel — see the cgtypetest twin. - let scrut: *node = taggedidcastpeel(c, n.lhs); + let scrut: *syntax.node = taggedidcastpeel(c, n.lhs); let scrutoff: i32 = 0; - let scrutt: *node = nil; + let scrutt: *syntax.node = nil; if (scrut != nil) { - if (scrut.kind == nkind.N_IDENT) { + if (scrut.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, scrut.str); if (lc != nil) { scrutoff = lc.off; @@ -26713,7 +26713,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // saved BP as the tag (garbage). The PLAIN-tagged twin // of cstage #78 SB-resolution: LEAQ the address, copy // the box into an @match_spill slot indexed off BP. - let gtt: *node = resolvetagged(c, letvartnode(c, scrut.str)); + let gtt: *syntax.node = resolvetagged(c, letvartnode(c, scrut.str)); if (gtt != nil && !isnullabletype(gtt)) { scrutt = gtt; let gspill: i32 = matchspillsz(c, gtt); @@ -26754,15 +26754,15 @@ fn cgmatch(c: *cgen, n: *node) void = { // spill `else`, which resolves g(SB). align-DOWN to cstage // (rule 10): both stages emit TEXT $32 on the local-field // case and the same g(SB) spill on the global-field case. - let mfld: *tfield = nil; - if (scrut.kind == nkind.N_DOT && scrut.lhs != nil - && scrut.lhs.kind == nkind.N_IDENT + let mfld: *syntax.tfield = nil; + if (scrut.kind == syntax.nkind.N_DOT && scrut.lhs != nil + && scrut.lhs.kind == syntax.nkind.N_IDENT && scrut.lhs.type_ != nil) { - let bu: *tinfo = tichase(scrut.lhs.type_: *tinfo); - if (bu != nil && bu.kind == tykind.TY_STRUCT) { - let fl: *tfield = bu.fields; + let bu: *syntax.tinfo = tichase(scrut.lhs.type_: *syntax.tinfo); + if (bu != nil && bu.kind == syntax.tykind.TY_STRUCT) { + let fl: *syntax.tfield = bu.fields; for (fl != nil) { - if (streq(fl.name, scrut.str)) { + if (syntax.streq(fl.name, scrut.str)) { mfld = fl; break; }; @@ -26799,7 +26799,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // binds already read the slot from memory. Mirrors // cstage cgen.c N_MATCH. let msret: i32 = 0; - if (scrut.kind == nkind.N_CALL) { + if (scrut.kind == syntax.nkind.N_CALL) { msret = callsretsize(c, scrut); }; if (msret > 0) { @@ -26837,9 +26837,9 @@ fn cgmatch(c: *cgen, n: *node) void = { // stamped s->type, so it louds — key on scrut.type_ // to match. Surfaced by reviewer-37's `match (*p)` // probe on a 56B box. - let ms37: *tinfo = scrut.type_: *tinfo; + let ms37: *syntax.tinfo = scrut.type_: *syntax.tinfo; ms37 = tichase(ms37); - if (ms37 != nil && ms37.kind == tykind.TY_TAGGED + if (ms37 != nil && ms37.kind == syntax.tykind.TY_TAGGED && ms37.size: i32 > TUPLE_GPCAP * 8) { let m37n: str = "#37: >32B tagged match scrutinee from a non-mem-based source unwired (rule 7)\n"; os.write(2, m37n.ptr, m37n.len: u64); @@ -26848,8 +26848,8 @@ fn cgmatch(c: *cgen, n: *node) void = { // Family C catch-all (rule 7): a widening tagged // cast scrutinee has no cursor — loud. Mirrors // cstage cgmatch. - if (scrut.kind == nkind.N_CAST && ms37 != nil - && ms37.kind == tykind.TY_TAGGED + if (scrut.kind == syntax.nkind.N_CAST && ms37 != nil + && ms37.kind == syntax.tykind.TY_TAGGED && ms37.nullable == 0) { let m35m: str = "#35: tagged cast source shape unwired at match (rule 7)\n"; os.write(2, m35m.ptr, m35m.len: u64); @@ -26889,10 +26889,10 @@ fn cgmatch(c: *cgen, n: *node) void = { c.yieldbuf[c.yieldtop] = endl; c.yieldtop += 1; }; - let cs: *node = n.list; + let cs: *syntax.node = n.list; for (cs != nil) { let nxt: str = mklabel(c, "match_next"); - let pat: *node = cs.lhs; + let pat: *syntax.node = cs.lhs; let nullable: bool = isnullabletype(scrutt); // Per-arm scope: save c.locals before allocating the bind // and restore after the body runs, so the arm's bind (and @@ -26911,7 +26911,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // void arm: skip if ptr != 0. let ptr_tag: i32 = nullableptrtag(scrutt); let cur_tag: i32 = 0; - if (pat.kind == nkind.N_TPTR) { cur_tag = ptr_tag; } + if (pat.kind == syntax.nkind.N_TPTR) { cur_tag = ptr_tag; } else { if (ptr_tag == 0) { cur_tag = 1; }; }; emitline("\tMOVQ\t"); emitoff(scrutoff: i64); @@ -26933,7 +26933,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // rather than the resolved N_TTAGGED node. if (istaggedtype(c, scrutt)) { let r: i32 = -1; - let pattype: *tinfo = pat.type_: *tinfo; + let pattype: *syntax.tinfo = pat.type_: *syntax.tinfo; if (pattype != nil) { // #179: kind-agnostic dispatch on the resolved // tinfo. Cstage cg_tag_for_variant works on @@ -26943,10 +26943,10 @@ fn cgmatch(c: *cgen, n: *node) void = { // Slice arm still goes through flatslicevariantidx // (task #19 untyped-elem fallback when typeeq // can't match a (scalar | []T) shape). - if (typeisslice(pattype)) { + if (syntax.typeisslice(pattype)) { r = flatslicevariantidx(c, scrutt, pat.lhs); } else { - r = flatvariantidxt(scrutt.type_: *tinfo, pattype, false); + r = flatvariantidxt(scrutt.type_: *syntax.tinfo, pattype, false); }; }; if (r >= 0) { want = r; }; @@ -26971,7 +26971,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // Bind the pointer (or skip for the // void arm, which has zero-size). The // value IS slot+0. - if (pat.kind == nkind.N_TPTR) { + if (pat.kind == syntax.nkind.N_TPTR) { let voff: i32 = localalloc(c, bn, 8, pat); emitline("\tMOVQ\t"); emitoff(scrutoff: i64); @@ -27033,8 +27033,8 @@ fn cgmatch(c: *cgen, n: *node) void = { return; }; -fn cgdot(c: *cgen, n: *node) void = { - let lhs: *node = n.lhs; +fn cgdot(c: *cgen, n: *syntax.node) void = { + let lhs: *syntax.node = n.lhs; let fld: str = n.str; // `(*p).f` read retarget: parser produces n.lhs = N_UN(STAR, // IDENT(p)). Substitute the inner IDENT as dotlhs so the @@ -27044,12 +27044,12 @@ fn cgdot(c: *cgen, n: *node) void = { // (*expr).f follow-up task pending. Enum-leaf lookup above and // chained-N_DOT branches below keep checking raw lhs since // (*p) is neither shape. - let dotlhs: *node = lhs; + let dotlhs: *syntax.node = lhs; if (dotlhs != nil) { - if (dotlhs.kind == nkind.N_UN) { - if (dotlhs.op == tkind.TK_STAR) { + if (dotlhs.kind == syntax.nkind.N_UN) { + if (dotlhs.op == syntax.tkind.TK_STAR) { if (dotlhs.lhs != nil) { - if (dotlhs.lhs.kind == nkind.N_IDENT) { + if (dotlhs.lhs.kind == syntax.nkind.N_IDENT) { dotlhs = dotlhs.lhs; }; }; @@ -27066,12 +27066,12 @@ fn cgdot(c: *cgen, n: *node) void = { let etmod: str; etname.ptr = nil; etname.len = 0; etmod.ptr = nil; etmod.len = 0; - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { etname = lhs.str; }; - if (lhs.kind == nkind.N_DOT) { + if (lhs.kind == syntax.nkind.N_DOT) { if (lhs.lhs != nil) { - if (lhs.lhs.kind == nkind.N_IDENT) { + if (lhs.lhs.kind == syntax.nkind.N_IDENT) { etname = lhs.str; etmod = lhs.lhs.str; }; @@ -27091,11 +27091,11 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (dotlhs != nil) { - if (dotlhs.kind == nkind.N_IDENT) { + if (dotlhs.kind == syntax.nkind.N_IDENT) { let nm: str = dotlhs.str; let lc: *local = localfindnode(c, nm); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; // Receiver is a NAMED alias chain — peel via aliaslookup // until tn exposes a non-N_TNAME kind (or a struct alias). // Without this, `type vs = *vt` leaves lkind == N_TNAME and @@ -27122,9 +27122,9 @@ fn cgdot(c: *cgen, n: *node) void = { // any-module heuristic. The broader cross-module same-leaf // STRUCT name-keying at the direct-struct arm below is // filed separately as #224 (not FLIP-triggered). - for (tn != nil && tn.kind == nkind.N_TNAME) { + for (tn != nil && tn.kind == syntax.nkind.N_TNAME) { if (structsamemod(c, tn.str) != nil) { break; }; - let nx: *node = aliassamemod(c, tn.str); + let nx: *syntax.node = aliassamemod(c, tn.str); if (nx == nil) { if (structlookup(c, tn.str) != nil) { break; }; nx = aliaslookup(c, tn.str); @@ -27133,14 +27133,14 @@ fn cgdot(c: *cgen, n: *node) void = { tn = nx; }; if (tn == nil) { return; }; - let lkind: nkind = tn.kind; + let lkind: syntax.nkind = tn.kind; // Pointer-to-struct: deref then field load. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; let sname: str; sname.ptr = nil; sname.len = 0; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; @@ -27154,7 +27154,7 @@ fn cgdot(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // tagged-union field via *struct: stage // the *struct in BX, then load the four // payload regs via cgloadtaggedfield. @@ -27223,7 +27223,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; // Direct struct local: field load at off+foff. - if (lkind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { // structlookupchain walks the alias chain on // miss so a transitively-aliased struct (`type // b = a; a = struct`) still resolves to the @@ -27233,7 +27233,7 @@ fn cgdot(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // tagged-union field: emit the AX=tag, // DX=word0, CX=word1[, R8=word2] load // sequence so the match / let-init / @@ -27291,17 +27291,17 @@ fn cgdot(c: *cgen, n: *node) void = { // Array pseudo-fields: `.ptr` is the array's // address (LEAQ); `.len` is the static element // count (immediate). - if (lkind == nkind.N_TARRAY) { - if (streq(fld, "ptr")) { + if (lkind == syntax.nkind.N_TARRAY) { + if (syntax.streq(fld, "ptr")) { emitline("\tLEAQ\t"); emitoff(lc.off: i64); emitline("(BP), AX\n"); return; }; - if (streq(fld, "len")) { - let lenn: *node = tn.rhs; + if (syntax.streq(fld, "len")) { + let lenn: *syntax.node = tn.rhs; let alen: i64 = 0i64; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i64; } else { // #56: def/const dim — resolve from the @@ -27310,8 +27310,8 @@ fn cgdot(c: *cgen, n: *node) void = { // node is an N_IDENT(def), not N_INTLIT, so // the literal read above defaults 0; cstage // reads the resolved bu->alen. - let abt: *tinfo = tichase(tn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(tn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i64; }; }; @@ -27330,10 +27330,10 @@ fn cgdot(c: *cgen, n: *node) void = { // sibling here, so the triple is hand-authored; base is // BP (frame, not a target reg) so ptr/len/cap order has // no clobber risk. - if (lkind == nkind.N_TTUPLE) { + if (lkind == syntax.nkind.N_TTUPLE) { let idx: i32 = fldnumidx(fld); if (idx >= 0) { - let tp: *node = tn.list; + let tp: *syntax.node = tn.list; let foff: i32 = 0; let i: i32 = 0; for (i < idx) { @@ -27347,7 +27347,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (tp != nil) { - let tpt: *node = tp.lhs; + let tpt: *syntax.node = tp.lhs; // str IS []u8, and a slice is the same 24B // {ptr,len,cap} header — load all three words // into (AX, BX, CX). #28: pre-fix the gate was @@ -27420,7 +27420,7 @@ fn cgdot(c: *cgen, n: *node) void = { // byte-id twin of cstage's fldloadop // in the N_DOT TY_TUPLE arm. let nsz: i32 = 8; - let tpti: *tinfo = tpt.type_: *tinfo; + let tpti: *syntax.tinfo = tpt.type_: *syntax.tinfo; if (tpti != nil) { nsz = tpti.size: i32; }; let op: str = tnodeloadop(c, tpt, nsz); emitline("\t"); @@ -27435,22 +27435,22 @@ fn cgdot(c: *cgen, n: *node) void = { // str/slice pseudo-fields .ptr/.len/.cap on a // direct local: load at slot+delta. let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { // Pointer to str/slice (`*[]u8`, `*str`): // deref, then load at delta within the // pointed-to header. C cgen does the same. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; - let innerkind: nkind = nkind.N_NONE; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; + let innerkind: syntax.nkind = syntax.nkind.N_NONE; if (inner != nil) { innerkind = inner.kind; }; let innerstr: bool = false; - if (innerkind == nkind.N_TNAME) { - if (streq(inner.str, "str")) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TNAME) { + if (syntax.streq(inner.str, "str")) { innerstr = true; }; }; - if (innerkind == nkind.N_TSLICE) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TSLICE) { innerstr = true; }; if (innerstr) { emitline("\tMOVQ\t"); emitoff(lc.off: i64); @@ -27475,19 +27475,19 @@ fn cgdot(c: *cgen, n: *node) void = { // `MOVQ (SB), AX` (looking up the field name as a // symbol). Mirrors cmd/w6c/cgen.c nkind.N_DOT off==0 / Sdef branch. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - let drhs: *node = deflookuprhs(c, lhs.str); + if (lhs.kind == syntax.nkind.N_IDENT) { + let drhs: *syntax.node = deflookuprhs(c, lhs.str); if (drhs != nil) { - if (drhs.kind == nkind.N_STRLIT) { + if (drhs.kind == syntax.nkind.N_STRLIT) { let bytes: str = drhs.str; - if (streq(fld, "ptr")) { + if (syntax.streq(fld, "ptr")) { let lab: str = internstrlit(c, bytes); emitline("\tLEAQ\t"); emitbytes( lab.ptr, lab.len: u64); emitline("(SB), AX\n"); return; }; - if (streq(fld, "len")) { + if (syntax.streq(fld, "len")) { emitline("\tMOVQ\t$"); emitint(bytes.len: i64); emitline(", AX\n"); @@ -27502,17 +27502,17 @@ fn cgdot(c: *cgen, n: *node) void = { // delta(CX), AX. Without this the module-qualified fallback // below would mis-emit `MOVQ (SB), AX`. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { if (isletvar(c, lhs.str)) { let isstr: bool = letvarisstr(c, lhs.str); let issl: bool = letvarisslice(c, lhs.str); if (isstr || issl) { let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; // str IS []u8: .cap is valid on a str global too, // not slice-only — mirrors cstage (#1/Phase 3, #11). - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); @@ -27534,27 +27534,27 @@ fn cgdot(c: *cgen, n: *node) void = { // reference to len). Mirror of the local-array arm above and cstage // cg_base_cap's `aimm(bu->alen)` immediate (cgen.c:1692). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - let gtn: *node = letvartnode(c, lhs.str); + if (lhs.kind == syntax.nkind.N_IDENT) { + let gtn: *syntax.node = letvartnode(c, lhs.str); if (gtn != nil) { - if (gtn.kind == nkind.N_TARRAY) { - if (streq(fld, "ptr")) { + if (gtn.kind == syntax.nkind.N_TARRAY) { + if (syntax.streq(fld, "ptr")) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), AX\n"); return; }; - if (streq(fld, "len")) { - let lenn: *node = gtn.rhs; + if (syntax.streq(fld, "len")) { + let lenn: *syntax.node = gtn.rhs; let alen: i64 = 0i64; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i64; } else { // #56: def/const dim on a let-global array — // resolve from the stamped array tinfo // (rule-13), twin of the local arm above. - let abt: *tinfo = tichase(gtn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(gtn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i64; }; }; @@ -27579,11 +27579,11 @@ fn cgdot(c: *cgen, n: *node) void = { // so both stages byte-id). `.cap` stays unmirrored — arrays have no // .cap (both checkers reject, task GAP-A.cap). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - if (streq(fld, "ptr")) { - let dtn: *node = defvartnode(c, lhs.str); + if (lhs.kind == syntax.nkind.N_IDENT) { + if (syntax.streq(fld, "ptr")) { + let dtn: *syntax.node = defvartnode(c, lhs.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { + if (dtn.kind == syntax.nkind.N_TARRAY) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), AX\n"); @@ -27591,20 +27591,20 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; }; - if (streq(fld, "len")) { - let dtn: *node = defvartnode(c, lhs.str); + if (syntax.streq(fld, "len")) { + let dtn: *syntax.node = defvartnode(c, lhs.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { - let lenn: *node = dtn.rhs; + if (dtn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = dtn.rhs; let alen: i64 = 0i64; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i64; } else { // #56: def/const dim on a def array — // resolve from the stamped array tinfo // (rule-13), twin of the let-global arm above. - let abt: *tinfo = tichase(dtn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(dtn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i64; }; }; @@ -27625,16 +27625,16 @@ fn cgdot(c: *cgen, n: *node) void = { // DATA) and the module-leaf fallback mis-emitted the field index // as a symbol (`MOVQ 0(SB), AX`). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - let gtt: *node = letvartnode(c, lhs.str); - for (gtt != nil && gtt.kind == nkind.N_TNAME) { + if (lhs.kind == syntax.nkind.N_IDENT) { + let gtt: *syntax.node = letvartnode(c, lhs.str); + for (gtt != nil && gtt.kind == syntax.nkind.N_TNAME) { gtt = aliaslookup(c, gtt.str); }; if (gtt != nil) { - if (gtt.kind == nkind.N_TTUPLE) { + if (gtt.kind == syntax.nkind.N_TTUPLE) { let gidx: i32 = fldnumidx(fld); if (gidx >= 0) { - let gtp: *node = gtt.list; + let gtp: *syntax.node = gtt.list; let gfoff: i32 = 0; let gi: i32 = 0; for (gi < gidx) { @@ -27648,7 +27648,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (gtp != nil) { - let gpt: *node = gtp.lhs; + let gpt: *syntax.node = gtp.lhs; emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), CX\n"); @@ -27677,7 +27677,7 @@ fn cgdot(c: *cgen, n: *node) void = { return; }; let gnsz: i32 = 8; - let gpti: *tinfo = gpt.type_: *tinfo; + let gpti: *syntax.tinfo = gpt.type_: *syntax.tinfo; if (gpti != nil) { gnsz = gpti.size: i32; }; let gop: str = tnodeloadop(c, gpt, gnsz); emitline("\t"); @@ -27702,13 +27702,13 @@ fn cgdot(c: *cgen, n: *node) void = { // fell through to the integer-let MOVQ catch-all (reading garbage // from the wrong offset). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let si: *structinfo = letvarstructinfo(c, lhs.str); if (si == nil) { si = defvarstructinfo(c, lhs.str); }; if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), CX\n"); @@ -27780,41 +27780,41 @@ fn cgdot(c: *cgen, n: *node) void = { // Mirrors cstage cgen.c case N_DOT N_INDEX-lhs arm 1:1; #209/#211 // name-keyed→tinfo-SSoT cluster. if (lhs != nil) { - if (lhs.kind == nkind.N_INDEX) { - let idxbase: *node = lhs.lhs; - if (idxbase != nil) { if (idxbase.kind == nkind.N_IDENT) { - let elemt: *tinfo = lhs.type_: *tinfo; - let elemu: *tinfo = elemt; + if (lhs.kind == syntax.nkind.N_INDEX) { + let idxbase: *syntax.node = lhs.lhs; + if (idxbase != nil) { if (idxbase.kind == syntax.nkind.N_IDENT) { + let elemt: *syntax.tinfo = lhs.type_: *syntax.tinfo; + let elemu: *syntax.tinfo = elemt; elemu = tichase(elemu); - let st: *tinfo = nil; + let st: *syntax.tinfo = nil; let viaptr: bool = false; if (elemu != nil) { - if (elemu.kind == tykind.TY_PTR) { - let pin: *tinfo = elemu.sub; + if (elemu.kind == syntax.tykind.TY_PTR) { + let pin: *syntax.tinfo = elemu.sub; pin = tichase(pin); - if (pin != nil) { if (pin.kind == tykind.TY_STRUCT) { + if (pin != nil) { if (pin.kind == syntax.tykind.TY_STRUCT) { st = pin; viaptr = true; };}; - } else { if (elemu.kind == tykind.TY_STRUCT) { + } else { if (elemu.kind == syntax.tykind.TY_STRUCT) { st = elemu; };}; }; if (st != nil) { - let fnd: *tfield = nil; - let fwalk: *tfield = st.fields; + let fnd: *syntax.tfield = nil; + let fwalk: *syntax.tfield = st.fields; for (fwalk != nil) { - if (streq(fwalk.name, fld)) { fnd = fwalk; break; }; + if (syntax.streq(fwalk.name, fld)) { fnd = fwalk; break; }; fwalk = fwalk.tnext; }; - let bu: *tinfo = idxbase.type_: *tinfo; + let bu: *syntax.tinfo = idxbase.type_: *syntax.tinfo; bu = tichase(bu); let baseisarray: bool = false; let baseok: bool = false; if (bu != nil) { - if (bu.kind == tykind.TY_ARRAY) { baseisarray = true; baseok = true; }; - if (bu.kind == tykind.TY_SLICE) { baseok = true; }; - if (bu.kind == tykind.TY_PTR) { baseok = true; }; + if (bu.kind == syntax.tykind.TY_ARRAY) { baseisarray = true; baseok = true; }; + if (bu.kind == syntax.tykind.TY_SLICE) { baseok = true; }; + if (bu.kind == syntax.tykind.TY_PTR) { baseok = true; }; }; let lc: *local = localfindnode(c, idxbase.str); // #21 (READ twin of #11): a module-GLOBAL base makes @@ -27832,9 +27832,9 @@ fn cgdot(c: *cgen, n: *node) void = { if (isletvar(c, idxbase.str)) { isglobal = true; } else { - let dtn: *node = defvartnode(c, idxbase.str); + let dtn: *syntax.node = defvartnode(c, idxbase.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { isglobal = true; }; + if (dtn.kind == syntax.nkind.N_TARRAY) { isglobal = true; }; }; }; }; @@ -27875,8 +27875,8 @@ fn cgdot(c: *cgen, n: *node) void = { emitline("\tMOVQ\tBX, AX\n"); }; let foff: i64 = fnd.offset: i64; - let ft: *tinfo = fnd.type_; - let fu: *tinfo = ft; + let ft: *syntax.tinfo = fnd.type_; + let fu: *syntax.tinfo = ft; fu = tichase(fu); // #270-1a: an `[N]T`-typed field of an // array element (`a[i].m[j]`) — leave the @@ -27888,7 +27888,7 @@ fn cgdot(c: *cgen, n: *node) void = { // field fell to the scalar load below and loaded // its first 8 bytes as a value → garbage // base → SEGFAULT in the outer index. - if (fu != nil && fu.kind == tykind.TY_ARRAY) { + if (fu != nil && fu.kind == syntax.tykind.TY_ARRAY) { if (foff != 0) { emitline("\tADDQ\t$"); emitint(foff); @@ -27896,8 +27896,8 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - if (fu != nil && (fu.kind == tykind.TY_STR - || fu.kind == tykind.TY_SLICE)) { + if (fu != nil && (fu.kind == syntax.tykind.TY_STR + || fu.kind == syntax.tykind.TY_SLICE)) { // str/slice: the 3-word {ptr,len,cap} // slice header (#1). AX holds the // element base, so load .ptr (which @@ -27915,9 +27915,9 @@ fn cgdot(c: *cgen, n: *node) void = { emitline(", AX\n"); return; }; - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); @@ -27947,7 +27947,7 @@ fn cgdot(c: *cgen, n: *node) void = { // #114 wires it, that commit replaces this with // the LEAQ box-address emission + a >32B value // pin row. Mirrors cstage cgen.c. - if (fu != nil && fu.kind == tykind.TY_TAGGED) { + if (fu != nil && fu.kind == syntax.tykind.TY_TAGGED) { let bsz: i32 = fu.size: i32; if (bsz > TUPLE_GPCAP * 8) { let m58r: str = "#58: >32B tagged-field indexed read unreachable until #114\n"; @@ -27976,7 +27976,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; let fsz: i32 = 8; if (ft != nil) { fsz = ft.size: i32; }; - let lop: str = loadopsz(typeissigned(ft), fsz); + let lop: str = loadopsz(syntax.typeissigned(ft), fsz); emitline("\t"); emitline(lop); emitline("\t"); @@ -27998,16 +27998,16 @@ fn cgdot(c: *cgen, n: *node) void = { // scalar loadopsz. Narrow (rob Q3): tagged / nested-aggregate // fields stay LOUD. Mirrors cstage cgen.c leg-(a) arm 1:1. if (lhs != nil) { - if (lhs.kind == nkind.N_INDEX) { - let eu: *tinfo = tichase(lhs.type_: *tinfo); - if (eu != nil) { if (eu.kind == tykind.TY_TUPLE) { + if (lhs.kind == syntax.nkind.N_INDEX) { + let eu: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); + if (eu != nil) { if (eu.kind == syntax.tykind.TY_TUPLE) { let idx: i32 = fldnumidx(fld); if (idx >= 0) { // ww tuples store elements in .tupleelems // (ttupleelem chain), NOT .params (that is // fn-only). foff via tupeslot accumulation = // cstage tuple_eslot, byte-id. - let tp: *ttupleelem = eu.tupleelems; + let tp: *syntax.ttupleelem = eu.tupleelems; let foff: i32 = 0; let i: i32 = 0; for (i < idx) { @@ -28019,12 +28019,12 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (tp != nil) { - let ft: *tinfo = tp.type_; - let fu: *tinfo = tichase(ft); - if (fu != nil && (fu.kind == tykind.TY_TAGGED - || fu.kind == tykind.TY_STRUCT - || fu.kind == tykind.TY_TUPLE - || fu.kind == tykind.TY_ARRAY)) { + let ft: *syntax.tinfo = tp.type_; + let fu: *syntax.tinfo = tichase(ft); + if (fu != nil && (fu.kind == syntax.tykind.TY_TAGGED + || fu.kind == syntax.tykind.TY_STRUCT + || fu.kind == syntax.tykind.TY_TUPLE + || fu.kind == syntax.tykind.TY_ARRAY)) { let mt: str = "#121: aggregate/tagged tuple-element field read off an indexed base unwired\n"; os.write(2, mt.ptr, mt.len: u64); os.exit(1); @@ -28035,9 +28035,9 @@ fn cgdot(c: *cgen, n: *node) void = { os.exit(1); }; emitline("\tMOVQ\tBX, AX\n"); - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); @@ -28045,8 +28045,8 @@ fn cgdot(c: *cgen, n: *node) void = { emitline(", X0\n"); return; }; - if (fu != nil && (fu.kind == tykind.TY_STR - || fu.kind == tykind.TY_SLICE)) { + if (fu != nil && (fu.kind == syntax.tykind.TY_STR + || fu.kind == syntax.tykind.TY_SLICE)) { emitline("\tMOVQ\t"); emitdispreg((foff + 8): i64, "AX"); emitline(", BX\n"); @@ -28060,7 +28060,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; let fsz: i32 = 8; if (ft != nil) { fsz = ft.size: i32; }; - let lop: str = loadopsz(typeissigned(ft), fsz); + let lop: str = loadopsz(syntax.typeissigned(ft), fsz); emitline("\t"); emitline(lop); emitline("\t"); @@ -28079,7 +28079,7 @@ fn cgdot(c: *cgen, n: *node) void = { // prior narrow deref-store doesn't leave stale upper bytes. Same // fallback the C cgen takes when bt is NULL/tyerr. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { // `let p = mod.fn` — fn rvalue via N_DOT. Mirror of // cstage cgdot's TY_FN branch (mafn with module hint). // Without this the MOVQ leaf(SB) fallback below would @@ -28088,7 +28088,7 @@ fn cgdot(c: *cgen, n: *node) void = { // lhs.str is the explicit module hint so a same-leaf // def in another module (head of c.fnrets) can't shadow // the explicit qualifier (#17 N_DOT-arm omission audit). - let frt: *node = fnretlookupmod(c, fld, usehint(c, lhs.str)); + let frt: *syntax.node = fnretlookupmod(c, fld, usehint(c, lhs.str)); if (frt != nil) { emitline("\tLEAQ\t"); emitfnname(c, fld, usehint(c, lhs.str)); @@ -28103,9 +28103,9 @@ fn cgdot(c: *cgen, n: *node) void = { // the explicit module hint — a 3rd-module qualifier // `alpha.MSG` from gamma needs alpha (not c.curmod) // to beat a head-of-c.defs beta.MSG collision (#11). - let drhs: *node = deflookuprhsmod(c, fld, usehint(c, lhs.str)); + let drhs: *syntax.node = deflookuprhsmod(c, fld, usehint(c, lhs.str)); if (drhs != nil) { - if (drhs.kind == nkind.N_STRLIT) { + if (drhs.kind == syntax.nkind.N_STRLIT) { let bytes: str = drhs.str; let lab: str = internstrlit(c, bytes); emitline("\tLEAQ\t"); @@ -28122,7 +28122,7 @@ fn cgdot(c: *cgen, n: *node) void = { // — the non-preferring emitsymname mis-mangled `aa.v` onto // a same-leaf global. The TY_FN branch above already // threads lhs.str via emitfnname. - if (streq(mqop, "MOVQ")) { + if (syntax.streq(mqop, "MOVQ")) { emitline("\tMOVQ\t"); emitfnname(c, fld, usehint(c, lhs.str)); emitline("(SB), AX\n"); @@ -28148,11 +28148,11 @@ fn cgdot(c: *cgen, n: *node) void = { // (loading only .ptr into AX) and shuffle stale BX into AX. // Placed BEFORE the .ptr/.len fast paths so the chain wins. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { + if (lhs.kind == syntax.nkind.N_DOT) { let rootname: str = ""; let rootoff: i32 = 0; let totaloff: i32 = 0; - let leaftype: *tinfo = nil; + let leaftype: *syntax.tinfo = nil; let slicedelta: i32 = -1; let isglobal: bool = false; let ptrroot: bool = false; @@ -28195,8 +28195,8 @@ fn cgdot(c: *cgen, n: *node) void = { // ONE word (the tag): is-tests passed by tag-luck // while as/match/let consumers read stale payload // registers (ken x5c: o.r.min as size added DX). - if (typeistagged(leaftype)) { - let tlu: *tinfo = leaftype; + if (syntax.typeistagged(leaftype)) { + let tlu: *syntax.tinfo = leaftype; tlu = tichase(tlu); let ttsz: i32 = tlu.size: i32; if (viacx) { @@ -28216,7 +28216,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - if (typeisstr(leaftype) || typeisslice(leaftype)) { + if (syntax.typeisstr(leaftype) || syntax.typeisslice(leaftype)) { // str/slice leaf: load all three header words into // (AX=ptr, BX=len, CX=cap). str IS []u8 — the same 24B // {ptr,len,cap} header. #29: the str leaf used to load @@ -28259,9 +28259,9 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - if (typeisfloat(leaftype)) { + if (syntax.typeisfloat(leaftype)) { let mov: str = "MOVSD"; - if (typeisf32(leaftype)) { mov = "MOVSS"; }; + if (syntax.typeisf32(leaftype)) { mov = "MOVSS"; }; if (viacx) { if (ptrroot) { emitline("\tMOVQ\t"); @@ -28286,7 +28286,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - let lop: str = loadopsz(typeissigned(leaftype), + let lop: str = loadopsz(syntax.typeissigned(leaftype), leaftype.slotsize: i32); if (viacx) { if (ptrroot) { @@ -28326,21 +28326,21 @@ fn cgdot(c: *cgen, n: *node) void = { // NAME behind a non-ident spine took the offset-blind cgexpr path // while cstage (type-gated) routes it to the read-resolver. { - let pbu: *tinfo = nil; - if (lhs != nil) { pbu = lhs.type_: *tinfo; }; + let pbu: *syntax.tinfo = nil; + if (lhs != nil) { pbu = lhs.type_: *syntax.tinfo; }; pbu = tichase(pbu); let pbok: bool = false; if (pbu != nil) { - if (pbu.kind == tykind.TY_SLICE - || pbu.kind == tykind.TY_STR - || pbu.kind == tykind.TY_UNTYPED_STR) { pbok = true; }; + if (pbu.kind == syntax.tykind.TY_SLICE + || pbu.kind == syntax.tykind.TY_STR + || pbu.kind == syntax.tykind.TY_UNTYPED_STR) { pbok = true; }; }; if (lhs != nil) { - if (lhs.kind == nkind.N_STRLIT) { pbok = true; }; + if (lhs.kind == syntax.nkind.N_STRLIT) { pbok = true; }; }; if (pbok) { - if (streq(fld, "ptr")) { cgexpr(c, lhs); return; }; - if (streq(fld, "len")) { + if (syntax.streq(fld, "ptr")) { cgexpr(c, lhs); return; }; + if (syntax.streq(fld, "len")) { cgexpr(c, lhs); emitline("\tMOVQ\tBX, AX\n"); return; @@ -28360,11 +28360,11 @@ fn cgdot(c: *cgen, n: *node) void = { // alone would wrongly fire. The N_STRLIT exclusion keeps // this byte-identical with cstage. #13 read-fix, sibling // of the #20 store. - if (streq(fld, "cap")) { + if (syntax.streq(fld, "cap")) { cgexpr(c, lhs); - if (lhs != nil && lhs.kind != nkind.N_STRLIT) { - if (pbu != nil && (pbu.kind == tykind.TY_SLICE - || pbu.kind == tykind.TY_STR)) { + if (lhs != nil && lhs.kind != syntax.nkind.N_STRLIT) { + if (pbu != nil && (pbu.kind == syntax.tykind.TY_SLICE + || pbu.kind == syntax.tykind.TY_STR)) { emitline("\tMOVQ\tCX, AX\n"); }; }; @@ -28381,7 +28381,7 @@ fn cgdot(c: *cgen, n: *node) void = { // itself, so reads silently get the pointer value instead of // the field. (Showed up porting w6l/pass.ww.) if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { + if (lhs.kind == syntax.nkind.N_DOT) { // #70 (#12): inner-struct layout via the stamped lhs.type_ // (peel *→struct) + tinfo.fields, replacing dotinnerstructptr's // structinfo walk. Gate is strict-equal to the deleted helper: @@ -28393,34 +28393,34 @@ fn cgdot(c: *cgen, n: *node) void = { // wanted, is a future task with its own probe. Global-root // chains stay in their pre-existing shared base-eval breakage // (filed #27), untouched here. - let croot: *node = lhs; + let croot: *syntax.node = lhs; let allptr: bool = true; - for (croot != nil && croot.kind == nkind.N_DOT) { - let ct: *tinfo = croot.type_: *tinfo; + for (croot != nil && croot.kind == syntax.nkind.N_DOT) { + let ct: *syntax.tinfo = croot.type_: *syntax.tinfo; ct = tichase(ct); let okp: bool = false; - if (ct != nil) { if (ct.kind == tykind.TY_PTR) { - let cs: *tinfo = ct.sub; + if (ct != nil) { if (ct.kind == syntax.tykind.TY_PTR) { + let cs: *syntax.tinfo = ct.sub; cs = tichase(cs); - if (cs != nil) { if (cs.kind == tykind.TY_STRUCT) { okp = true; }; }; + if (cs != nil) { if (cs.kind == syntax.tykind.TY_STRUCT) { okp = true; }; }; }; }; if (!okp) { allptr = false; }; croot = croot.lhs; }; - let it: *tinfo = nil; - if (allptr && croot != nil && croot.kind == nkind.N_IDENT && + let it: *syntax.tinfo = nil; + if (allptr && croot != nil && croot.kind == syntax.nkind.N_IDENT && localfindnode(c, croot.str) != nil) { - it = lhs.type_: *tinfo; + it = lhs.type_: *syntax.tinfo; }; it = tichase(it); - if (it != nil) { if (it.kind == tykind.TY_PTR) { - let st: *tinfo = it.sub; + if (it != nil) { if (it.kind == syntax.tykind.TY_PTR) { + let st: *syntax.tinfo = it.sub; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { - let tf: *tfield = st.fields; + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { + let tf: *syntax.tfield = st.fields; for (tf != nil) { - if (streq(tf.name, fld)) { - let ft: *tinfo = tf.type_; + if (syntax.streq(tf.name, fld)) { + let ft: *syntax.tinfo = tf.type_; cgexpr(c, lhs); // AX = ptr to inner struct // tagged leaf (#38a): AX holds the // *struct base and the tagged cursor @@ -28428,8 +28428,8 @@ fn cgdot(c: *cgen, n: *node) void = { // BX, then cgloadtaggedfield (cstage // chained-*struct twin; ken b8: the // scalar tail read stale DX as payload). - if (typeistagged(ft)) { - let plu: *tinfo = ft; + if (syntax.typeistagged(ft)) { + let plu: *syntax.tinfo = ft; plu = tichase(plu); emitline("\tMOVQ\tAX, BX\n"); cgloadtaggedfield(c, "BX", @@ -28444,7 +28444,7 @@ fn cgdot(c: *cgen, n: *node) void = { // AX) LAST. str folds onto the slice // arm (#1/Phase 3 collapse; cite cstage // cgen.c N_DOT chained *struct caseB). - if (typeisstr(ft) || typeisslice(ft)) { + if (syntax.typeisstr(ft) || syntax.typeisslice(ft)) { emitline("\tMOVQ\t"); emitdispreg((tf.offset + 8u64): i64, "AX"); emitline(", BX\n"); @@ -28457,9 +28457,9 @@ fn cgdot(c: *cgen, n: *node) void = { return; }; // f64/f32 chained field: route through X0. - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); @@ -28467,7 +28467,7 @@ fn cgdot(c: *cgen, n: *node) void = { emitline(", X0\n"); return; }; - let lop: str = loadopsz(typeissigned(ft), ft.slotsize: i32); + let lop: str = loadopsz(syntax.typeissigned(ft), ft.slotsize: i32); emitline("\t"); emitline(lop); emitline("\t"); @@ -28489,21 +28489,21 @@ fn cgdot(c: *cgen, n: *node) void = { // earlier in cgdot) to preserve byte-identical output on shapes // it already handles. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let inner: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let inner: *syntax.node = lhs.lhs; let innerfld: str = lhs.str; - if (inner != nil) { if (inner.kind == nkind.N_IDENT) { + if (inner != nil) { if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { if (lc.tnode != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = tn.kind; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = tn.kind; let outname: str; outname.ptr = nil; outname.len = 0; let isptr: bool = false; - if (lkind == nkind.N_TNAME) { outname = tn.str; }; - if (lkind == nkind.N_TPTR) { - let pe: *node = tn.lhs; - if (pe != nil) { if (pe.kind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { outname = tn.str; }; + if (lkind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = tn.lhs; + if (pe != nil) { if (pe.kind == syntax.nkind.N_TNAME) { outname = pe.str; isptr = true; };}; @@ -28513,15 +28513,15 @@ fn cgdot(c: *cgen, n: *node) void = { if (osi != nil) { let ofi: *fieldinfo = osi.fields; for (ofi != nil) { - if (streq(ofi.fname, innerfld)) { - let oft: *node = ofi.tnode; - if (oft != nil) { if (oft.kind == nkind.N_TNAME) { + if (syntax.streq(ofi.fname, innerfld)) { + let oft: *syntax.node = ofi.tnode; + if (oft != nil) { if (oft.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, oft.str) == 0) { let isi: *structinfo = structlookup(c, oft.str); if (isi != nil) { let ffi: *fieldinfo = isi.fields; for (ffi != nil) { - if (streq(ffi.fname, fld)) { + if (syntax.streq(ffi.fname, fld)) { let totoff: i32 = ofi.foff + ffi.foff; if (isstrtype(c, ffi.tnode)) { if (isptr) { @@ -28608,9 +28608,9 @@ fn cgdot(c: *cgen, n: *node) void = { // chain, turning a TYPED depth-2 read behind an index/deref spine // into a silent global read of a colliding leaf symbol. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let sbt: *tinfo = lhs.type_: *tinfo; - if (sbt == nil || sbt.kind == tykind.TY_ERR) { + if (lhs.kind == syntax.nkind.N_DOT) { + let sbt: *syntax.tinfo = lhs.type_: *syntax.tinfo; + if (sbt == nil || sbt.kind == syntax.tykind.TY_ERR) { emitline("\tMOVQ\t"); emitsymname(c, fld); emitline("(SB), AX\n"); @@ -28625,11 +28625,11 @@ fn cgdot(c: *cgen, n: *node) void = { // arm → cs≠ww). Loud; the wwstage alignment is filed as task // #37. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let pgu: *tinfo = lhs.type_: *tinfo; + if (lhs.kind == syntax.nkind.N_DOT) { + let pgu: *syntax.tinfo = lhs.type_: *syntax.tinfo; pgu = tichase(pgu); if (pgu != nil) { - if (pgu.kind == tykind.TY_PTR) { + if (pgu.kind == syntax.tykind.TY_PTR) { let mp: str = "cgdot: ptr-chained field read unwired in wwstage (task #37)\n"; os.write(2, mp.ptr, mp.len: u64); os.exit(1); @@ -28646,11 +28646,11 @@ fn cgdot(c: *cgen, n: *node) void = { // silently emitted NOTHING. Mirror of cstage cgen.c case N_DOT // read-resolver tail. { - let rdt: *tinfo = n.type_: *tinfo; - let rdu: *tinfo = rdt; + let rdt: *syntax.tinfo = n.type_: *syntax.tinfo; + let rdu: *syntax.tinfo = rdt; rdu = tichase(rdu); if (rdu != nil) { - if (rdu.kind == tykind.TY_TAGGED) { + if (rdu.kind == syntax.tykind.TY_TAGGED) { let mt: str = "read-resolver: tagged field read not wired (rule-7)\n"; os.write(2, mt.ptr, mt.len: u64); os.exit(1); @@ -28660,8 +28660,8 @@ fn cgdot(c: *cgen, n: *node) void = { // them; this loud guards the remaining non-let expr // positions (no register convention for a >8B leaf), // symmetric with cstage's read-resolver tail. - if (rdu.kind == tykind.TY_STRUCT - || rdu.kind == tykind.TY_TUPLE) { + if (rdu.kind == syntax.tykind.TY_STRUCT + || rdu.kind == syntax.tykind.TY_TUPLE) { let ma: str = "read-resolver: aggregate field read not wired (rule-7)\n"; os.write(2, ma.ptr, ma.len: u64); os.exit(1); @@ -28672,22 +28672,22 @@ fn cgdot(c: *cgen, n: *node) void = { os.write(2, mu.ptr, mu.len: u64); os.exit(1); }; - if (typeisfloat(rdt)) { + if (syntax.typeisfloat(rdt)) { let mov: str = "MOVSD"; - if (typeisf32(rdt)) { mov = "MOVSS"; }; + if (syntax.typeisf32(rdt)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t(BX), X0\n"); return; }; - if (rdu != nil && rdu.kind == tykind.TY_ARRAY) { + if (rdu != nil && rdu.kind == syntax.tykind.TY_ARRAY) { // `[N]T` leaf: leave the field ADDRESS — a base for // an outer index, never a value (#270-1a semantics). emitline("\tMOVQ\tBX, AX\n"); return; }; - if (rdu != nil && (rdu.kind == tykind.TY_STR - || rdu.kind == tykind.TY_SLICE)) { + if (rdu != nil && (rdu.kind == syntax.tykind.TY_STR + || rdu.kind == syntax.tykind.TY_SLICE)) { // str IS []u8 — 3-word {ptr,len,cap} into (AX, BX, // CX). BX is the place base, so load .len (which // targets BX) LAST. @@ -28698,7 +28698,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; let lop: str = "MOVQ"; if (rdt != nil) { - lop = loadopsz(typeissigned(rdt), rdt.slotsize: i32); + lop = loadopsz(syntax.typeissigned(rdt), rdt.slotsize: i32); }; emitline("\t"); emitline(lop); @@ -28707,18 +28707,18 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; -fn cgun(c: *cgen, n: *node) void = { +fn cgun(c: *cgen, n: *syntax.node) void = { // Match C cgen ordering: evaluate operand first (load into AX), // then apply the unary op. AMP / STAR override AX with the // address / deref. The wasted load before AMP keeps our asm // byte-identical to the C version. let fk: i32 = 0; if (n.lhs != nil) { - let lt: *tinfo = n.lhs.type_: *tinfo; - if (typeisf32(lt)) { fk = 1; } - else { if (typeisfloat(lt)) { fk = 2; }; }; + let lt: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; + if (syntax.typeisf32(lt)) { fk = 1; } + else { if (syntax.typeisfloat(lt)) { fk = 2; }; }; }; - if (n.op == tkind.TK_MINUS && fk != 0) { + if (n.op == syntax.tkind.TK_MINUS && fk != 0) { // Float negate: X0 = 0 - X0. Stash orig, load 0.0, subtract. // Zero bit pattern equals 0.0 for both f32 and f64 so we // reuse the integer-zero materialisation. @@ -28740,10 +28740,10 @@ fn cgun(c: *cgen, n: *node) void = { // Address-of has its own evaluation strategy — we want the address // of the operand, not its value. Special-case here so `&arr[i]` // doesn't compile the value load and then discard it. - if (n.op == tkind.TK_AMP) { - let opnd: *node = n.lhs; + if (n.op == syntax.tkind.TK_AMP) { + let opnd: *syntax.node = n.lhs; if (opnd != nil) { - if (opnd.kind == nkind.N_IDENT) { + if (opnd.kind == syntax.nkind.N_IDENT) { let nm: str = opnd.str; let off: i32 = localfind(c, nm); if (off != 0) { @@ -28809,16 +28809,16 @@ fn cgun(c: *cgen, n: *node) void = { // only; spine walker aborts on the *T base. Load // p into AX, then LEAQ field_off(AX), AX. Mirror // of the read at cgdot 1144. - if (opnd.kind == nkind.N_DOT) { + if (opnd.kind == syntax.nkind.N_DOT) { // Shape 1 chained: depth-≥2 via dotchainresolve. // `opnd.lhs.kind == N_DOT` gates the helper at // nsteps ≥ 2 (matches the read path's gate). if (opnd.lhs != nil) { - if (opnd.lhs.kind == nkind.N_DOT) { + if (opnd.lhs.kind == syntax.nkind.N_DOT) { let rootname: str = ""; let rootoff: i32 = 0; let totaloff: i32 = 0; - let leaftype: *tinfo = nil; + let leaftype: *syntax.tinfo = nil; let slicedelta: i32 = -1; let isglobal: bool = false; let ptrroot: bool = false; @@ -28854,13 +28854,13 @@ fn cgun(c: *cgen, n: *node) void = { // the base's tnode to pick value-struct vs slice/ // str pseudo vs pointer-field. if (opnd.lhs != nil) { - if (opnd.lhs.kind == nkind.N_IDENT) { + if (opnd.lhs.kind == syntax.nkind.N_IDENT) { let basenm: str = opnd.lhs.str; let fld: str = opnd.str; let lc: *local = localfindnode(c, basenm); if (lc != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = nkind.N_NONE; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = syntax.nkind.N_NONE; if (tn != nil) { lkind = tn.kind; }; // Pointer-field: &p.f where p:*T. // #102 (ken B6-c3 re-attribution): an @@ -28873,19 +28873,19 @@ fn cgun(c: *cgen, n: *node) void = { // chain; plain rows short-circuit at its // structlookup head, byte-id by // construction. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; let sname: str; sname.ptr = nil; sname.len = 0; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; if (sname.len > 0) { let si: *structinfo = structlookupchain(c, inner); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tMOVQ\t"); emitoff(lc.off: i64); emitline("(BP), AX\n"); @@ -28905,12 +28905,12 @@ fn cgun(c: *cgen, n: *node) void = { // &p.f gate — an alias-NAMED value // struct fell to the generic route. // Same chase, same construction. - if (lkind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { let si: *structinfo = structlookupchain(c, tn); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tLEAQ\t"); emitoff((lc.off + fi.foff): i64); emitline("(BP), AX\n"); @@ -28924,14 +28924,14 @@ fn cgun(c: *cgen, n: *node) void = { // &s.ptr / &s.len / &s.cap. Delta is // 0/8/16 — matches the spine walker. let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { let isslor: bool = false; - if (lkind == nkind.N_TSLICE) { isslor = true; }; - if (lkind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { isslor = true; }; + if (lkind == syntax.nkind.N_TSLICE) { isslor = true; }; + if (lkind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { isslor = true; }; }; if (isslor) { emitline("\tLEAQ\t"); @@ -28948,7 +28948,7 @@ fn cgun(c: *cgen, n: *node) void = { if (gsi != nil) { let fi: *fieldinfo = gsi.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tLEAQ\t"); emitsymname(c, basenm); emitline("(SB), CX\n"); @@ -28964,11 +28964,11 @@ fn cgun(c: *cgen, n: *node) void = { let issl: bool = letvarisslice(c, basenm); if (isstr || issl) { let gdelta: i32 = -1; - if (streq(fld, "ptr")) { gdelta = 0; }; - if (streq(fld, "len")) { gdelta = 8; }; + if (syntax.streq(fld, "ptr")) { gdelta = 0; }; + if (syntax.streq(fld, "len")) { gdelta = 8; }; // str IS []u8: &str.cap is valid too, not slice-only // — mirrors cstage (#1/Phase 3, #11). - if (streq(fld, "cap")) { gdelta = 16; }; + if (syntax.streq(fld, "cap")) { gdelta = 16; }; if (gdelta >= 0) { emitline("\tLEAQ\t"); emitsymname(c, basenm); @@ -28992,7 +28992,7 @@ fn cgun(c: *cgen, n: *node) void = { // via emitfnname (fn address), mirroring that read // path's TY_FN branch. if (opnd.lhs != nil) { - if (opnd.lhs.kind == nkind.N_IDENT) { + if (opnd.lhs.kind == syntax.nkind.N_IDENT) { let basenm: str = opnd.lhs.str; if (localfindnode(c, basenm) == nil) { // A def base (`&Pdef.field`) is NOT a module @@ -29008,7 +29008,7 @@ fn cgun(c: *cgen, n: *node) void = { // pre-#149 gap (file as #150-family). if (!isletvar(c, basenm) && !deflookup(c, basenm)) { let fld: str = opnd.str; - let frt: *node = fnretlookupmod(c, fld, usehint(c, basenm)); + let frt: *syntax.node = fnretlookupmod(c, fld, usehint(c, basenm)); if (frt != nil) { emitline("\tLEAQ\t"); emitfnname(c, fld, usehint(c, basenm)); @@ -29043,10 +29043,10 @@ fn cgun(c: *cgen, n: *node) void = { os.write(2, mam.ptr, mam.len: u64); os.exit(1); }; - if (opnd.kind == nkind.N_INDEX) { + if (opnd.kind == syntax.nkind.N_INDEX) { // &base[i] = base + i*esz, no dereference. - let base: *node = opnd.lhs; - let idx: *node = opnd.rhs; + let base: *syntax.node = opnd.lhs; + let idx: *syntax.node = opnd.rhs; let esz: i32 = 8; let isglobalarr: bool = false; let isglobalptr: bool = false; @@ -29055,13 +29055,13 @@ fn cgun(c: *cgen, n: *node) void = { let baselocal: *local = nil; let isarr: bool = false; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { baselocal = localfindnode(c, base.str); if (baselocal != nil) { esz = elemsizeofc(c, baselocal.tnode); - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { isarr = true; }; + if (tn.kind == syntax.nkind.N_TARRAY) { isarr = true; }; }; } else { // #11: addr-of twin of the #10 cgindex read @@ -29076,7 +29076,7 @@ fn cgun(c: *cgen, n: *node) void = { // esz=bu->sub->size, base is_arr?LEAQ:MOVQ // name(SB) (a str/slice's .ptr IS the symbol's // first word). Align UP, mirroring cgindex. - let tn: *node = letvartnode(c, base.str); + let tn: *syntax.node = letvartnode(c, base.str); // #94: a def-array base resolves via // defvartnode (the def-side sister), the same // fallback cgindex's read-side already takes @@ -29090,7 +29090,7 @@ fn cgun(c: *cgen, n: *node) void = { if (tn != nil) { globalname = base.str; esz = elemsizeofc(c, tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; @@ -29106,26 +29106,26 @@ fn cgun(c: *cgen, n: *node) void = { // classifies off type_chase_named uniformly // (cmd/w6c/cgen.c:4172-4188). TY_NAMED gate // keeps non-alias rows byte-id by construction. - let bt82: *tinfo = base.type_: *tinfo; + let bt82: *syntax.tinfo = base.type_: *syntax.tinfo; let basealias82: bool = false; if (bt82 != nil) { - if (bt82.kind == tykind.TY_NAMED) { basealias82 = true; }; + if (bt82.kind == syntax.tykind.TY_NAMED) { basealias82 = true; }; }; if (basealias82) { - let bu82: *tinfo = tichase(bt82); + let bu82: *syntax.tinfo = tichase(bt82); if (bu82 != nil) { if (baselocal != nil) { - isarr = bu82.kind == tykind.TY_ARRAY; + isarr = bu82.kind == syntax.tykind.TY_ARRAY; }; if (isglobalarr || isglobalptr) { - isglobalarr = bu82.kind == tykind.TY_ARRAY; + isglobalarr = bu82.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; }; - } else { if (base.kind == nkind.N_DOT - || (base.kind == nkind.N_UN - && base.op == tkind.TK_STAR)) { + } else { if (base.kind == syntax.nkind.N_DOT + || (base.kind == syntax.nkind.N_UN + && base.op == syntax.tkind.TK_STAR)) { // `&p.ptr[i]`: stride is the checker-stamped // element tinfo's natural size, mirroring // cgindex's N_DOT arm so &p.ptr[i] and @@ -29134,7 +29134,7 @@ fn cgun(c: *cgen, n: *node) void = { // N_UN deref base (`&(*p)[i]`, #61 C): same // stamped source; cstage reads base->type // uniformly. - let dt: *tinfo = opnd.type_: *tinfo; + let dt: *syntax.tinfo = opnd.type_: *syntax.tinfo; if (dt != nil) { esz = dt.size: i32; }; };}; }; @@ -29200,8 +29200,8 @@ fn cgun(c: *cgen, n: *node) void = { return; }; cgexpr(c, n.lhs); - if (n.op == tkind.TK_MINUS) { emitline("\tNEGQ\tAX\n"); return; }; - if (n.op == tkind.TK_TILDE) { + if (n.op == syntax.tkind.TK_MINUS) { emitline("\tNEGQ\tAX\n"); return; }; + if (n.op == syntax.tkind.TK_TILDE) { emitline("\tNOTQ\tAX\n"); // NOTQ inverts the whole 64-bit register; clamp narrow // unsigned results to type width so subsequent 64-bit @@ -29216,7 +29216,7 @@ fn cgun(c: *cgen, n: *node) void = { }; return; }; - if (n.op == tkind.TK_STAR) { + if (n.op == syntax.tkind.TK_STAR) { // #185: deref of *fn — the pointer value IS the fn address. // cgexpr(n.lhs) left AX = fn-addr; a generic MOVQ (AX),AX // would load the first instruction word and a subsequent @@ -29227,10 +29227,10 @@ fn cgun(c: *cgen, n: *node) void = { // `*[N]T` leaves AX = p's value. The scalar load below // pulled a[0]'s VALUE and `(*p)[i]` then dereferenced it as // the index base — a wild pointer, SIGSEGV on both stages. - let rti: *tinfo = n.type_: *tinfo; + let rti: *syntax.tinfo = n.type_: *syntax.tinfo; rti = tichase(rti); - if (rti != nil && rti.kind == tykind.TY_FN) { return; }; - if (rti != nil && rti.kind == tykind.TY_ARRAY) { return; }; + if (rti != nil && rti.kind == syntax.tykind.TY_FN) { return; }; + if (rti != nil && rti.kind == syntax.tykind.TY_ARRAY) { return; }; // Family C (#35/#46): a tagged box behind *p joins the // mem-based class at ANY size (taggedmemread) — AX = p's // value IS the box address. The scalar load below pulled @@ -29238,7 +29238,7 @@ fn cgun(c: *cgen, n: *node) void = { // garbage payload words — silent-wrong both stages (ken // f35/D3a/D3b). The nullable one-word fold stays a scalar // deref. Mirrors cstage N_UN TK_STAR. - if (rti != nil && rti.kind == tykind.TY_TAGGED) { + if (rti != nil && rti.kind == syntax.tykind.TY_TAGGED) { if (rti.nullable == 0 && rti.size: i32 > 8) { return; }; }; // f64/f32 result rides X0 (SSE), not AX — an integer MOVQ @@ -29271,7 +29271,7 @@ fn cgun(c: *cgen, n: *node) void = { }; return; }; - if (n.op == tkind.TK_NOT) { + if (n.op == syntax.tkind.TK_NOT) { let t: str = mklabel(c, "tt"); let e: str = mklabel(c, "te"); emitline("\tCMPQ\t$0, AX\n"); @@ -29292,8 +29292,8 @@ fn cgun(c: *cgen, n: *node) void = { // module-global str (#154 let_islet branch) or BP+off for a local; a // non-ident evals via cgexpr (AX=ptr, BX=len) and pushes BX then AX. Push // order is len then ptr so the matching POPQ pops ptr first. -fn cgstreqpush(c: *cgen, op: *node) void = { - if (op.kind == nkind.N_IDENT) { +fn cgstreqpush(c: *cgen, op: *syntax.node) void = { + if (op.kind == syntax.nkind.N_IDENT) { let nm: str = op.str; let lc: *local = localfindnode(c, nm); if (lc == nil && isletvar(c, nm)) { @@ -29323,17 +29323,17 @@ fn cgstreqpush(c: *cgen, op: *node) void = { emitline("\tPUSHQ\tAX\n"); }; -fn cgbin(c: *cgen, n: *node) void = { +fn cgbin(c: *cgen, n: *syntax.node) void = { // Short-circuit `&&` / `||`. Operands are bool (0/1); the type // checker enforces it. Eval LHS into AX, branch over RHS on the // short-circuit polarity, otherwise eval RHS into AX. The // surviving AX is the result. Must precede any eager-eval path // below — `if (p != nil && p.x > 0)` would segfault on a nil // deref otherwise. Byte-identical to cmd/w6c/cgen.c N_BIN. - if (n.op == tkind.TK_AND || n.op == tkind.TK_OR) { + if (n.op == syntax.tkind.TK_AND || n.op == syntax.tkind.TK_OR) { let prefix: str = "andend"; let jshrt: str = "JE"; - if (n.op == tkind.TK_OR) { prefix = "orend"; jshrt = "JNE"; }; + if (n.op == syntax.tkind.TK_OR) { prefix = "orend"; jshrt = "JNE"; }; let end: str = mklabel(c, prefix); cgexpr(c, n.lhs); emitline("\tCMPQ\t$0, AX\n"); @@ -29352,15 +29352,15 @@ fn cgbin(c: *cgen, n: *node) void = { // for !=. The gate reads the checker stamp (typeisstr) exactly like // cstage node_isstr. Byte-identical to cstage cbinop (cmd/w6c/ // cgen.c:4564-4623). cstage was fixed by #154; this is its mirror. - if ((n.op == tkind.TK_EQ || n.op == tkind.TK_NEQ) + if ((n.op == syntax.tkind.TK_EQ || n.op == syntax.tkind.TK_NEQ) && n.lhs != nil && n.rhs != nil - && typeisstr(n.lhs.type_: *tinfo) - && typeisstr(n.rhs.type_: *tinfo)) { + && syntax.typeisstr(n.lhs.type_: *syntax.tinfo) + && syntax.typeisstr(n.rhs.type_: *syntax.tinfo)) { cgstreqpush(c, n.rhs); cgstreqpush(c, n.lhs); emitline("\tPOPQ\tDI\n\tPOPQ\tSI\n\tPOPQ\tDX\n\tPOPQ\tCX\n"); emitline("\tCALL\trt_streq(SB)\n"); - if (n.op == tkind.TK_NEQ) { emitline("\tXORQ\t$1, AX\n"); }; + if (n.op == syntax.tkind.TK_NEQ) { emitline("\tXORQ\t$1, AX\n"); }; return; }; @@ -29380,25 +29380,25 @@ fn cgbin(c: *cgen, n: *node) void = { // are therefore dead and removed. let lfk: i32 = 0; if (n.lhs != nil) { - let llt: *tinfo = n.lhs.type_: *tinfo; - if (typeisf32(llt)) { lfk = 1; } - else { if (typeisfloat(llt)) { lfk = 2; }; }; + let llt: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; + if (syntax.typeisf32(llt)) { lfk = 1; } + else { if (syntax.typeisfloat(llt)) { lfk = 2; }; }; }; let rfk: i32 = 0; if (n.rhs != nil) { - let rrt: *tinfo = n.rhs.type_: *tinfo; - if (typeisf32(rrt)) { rfk = 1; } - else { if (typeisfloat(rrt)) { rfk = 2; }; }; + let rrt: *syntax.tinfo = n.rhs.type_: *syntax.tinfo; + if (syntax.typeisf32(rrt)) { rfk = 1; } + else { if (syntax.typeisfloat(rrt)) { rfk = 2; }; }; }; let fk: i32 = lfk; if (fk == 0) { fk = rfk; }; if (fk != 0) { let mov: str = "MOVSD"; if (fk == 1) { mov = "MOVSS"; }; - if (n.op == tkind.TK_PLUS || - n.op == tkind.TK_MINUS || - n.op == tkind.TK_STAR || - n.op == tkind.TK_SLASH) { + if (n.op == syntax.tkind.TK_PLUS || + n.op == syntax.tkind.TK_MINUS || + n.op == syntax.tkind.TK_STAR || + n.op == syntax.tkind.TK_SLASH) { cgexpr(c, n.rhs); emitline("\tSUBQ\t$8, SP\n"); emitline("\t"); emitline(mov); emitline("\tX0, (SP)\n"); @@ -29406,25 +29406,25 @@ fn cgbin(c: *cgen, n: *node) void = { emitline("\t"); emitline(mov); emitline("\t(SP), X1\n"); emitline("\tADDQ\t$8, SP\n"); let op: str = "ADDSD"; - if (n.op == tkind.TK_MINUS) { op = "SUBSD"; }; - if (n.op == tkind.TK_STAR) { op = "MULSD"; }; - if (n.op == tkind.TK_SLASH) { op = "DIVSD"; }; + if (n.op == syntax.tkind.TK_MINUS) { op = "SUBSD"; }; + if (n.op == syntax.tkind.TK_STAR) { op = "MULSD"; }; + if (n.op == syntax.tkind.TK_SLASH) { op = "DIVSD"; }; if (fk == 1) { - if (n.op == tkind.TK_PLUS) { op = "ADDSS"; }; - if (n.op == tkind.TK_MINUS) { op = "SUBSS"; }; - if (n.op == tkind.TK_STAR) { op = "MULSS"; }; - if (n.op == tkind.TK_SLASH) { op = "DIVSS"; }; + if (n.op == syntax.tkind.TK_PLUS) { op = "ADDSS"; }; + if (n.op == syntax.tkind.TK_MINUS) { op = "SUBSS"; }; + if (n.op == syntax.tkind.TK_STAR) { op = "MULSS"; }; + if (n.op == syntax.tkind.TK_SLASH) { op = "DIVSS"; }; }; emitline("\t"); emitline(op); emitline("\tX1, X0\n"); return; }; let isfcmp: bool = false; - if (n.op == tkind.TK_EQ) { isfcmp = true; }; - if (n.op == tkind.TK_NEQ) { isfcmp = true; }; - if (n.op == tkind.TK_LT) { isfcmp = true; }; - if (n.op == tkind.TK_LE) { isfcmp = true; }; - if (n.op == tkind.TK_GT) { isfcmp = true; }; - if (n.op == tkind.TK_GE) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_EQ) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_NEQ) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_LT) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_LE) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_GT) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_GE) { isfcmp = true; }; if (isfcmp) { cgexpr(c, n.rhs); emitline("\tSUBQ\t$8, SP\n"); @@ -29444,7 +29444,7 @@ fn cgbin(c: *cgen, n: *node) void = { // unordered never gives, so they are ALREADY NaN-correct // and stay byte-identical to the pre-#97 single-template // arm — no redundant PF guard. - if (n.op == tkind.TK_NEQ) { + if (n.op == syntax.tkind.TK_NEQ) { // not-equal OR unordered -> true let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); @@ -29457,12 +29457,12 @@ fn cgbin(c: *cgen, n: *node) void = { emitlabel(e); return; }; - if (n.op == tkind.TK_EQ || n.op == tkind.TK_LT || - n.op == tkind.TK_LE) { + if (n.op == syntax.tkind.TK_EQ || n.op == syntax.tkind.TK_LT || + n.op == syntax.tkind.TK_LE) { // unordered -> false; otherwise the ordered Jcc decides. let jcc: str = "JE"; - if (n.op == tkind.TK_LT) { jcc = "JB"; }; - if (n.op == tkind.TK_LE) { jcc = "JBE"; }; + if (n.op == syntax.tkind.TK_LT) { jcc = "JB"; }; + if (n.op == syntax.tkind.TK_LE) { jcc = "JBE"; }; let fl: str = mklabel(c, "cf"); let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); @@ -29479,7 +29479,7 @@ fn cgbin(c: *cgen, n: *node) void = { // `>`/`>=`: JA/JAE already reject unordered (CF=1), so // keep the pre-#97 single-template shape verbatim. let jcc: str = "JA"; - if (n.op == tkind.TK_GE) { jcc = "JAE"; }; + if (n.op == syntax.tkind.TK_GE) { jcc = "JAE"; }; let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); emitline("\t"); emitline(jcc); emitline("\t"); emitline(t); emitline("\n"); @@ -29497,10 +29497,10 @@ fn cgbin(c: *cgen, n: *node) void = { emitline("\tPUSHQ\tAX\n"); cgexpr(c, n.lhs); emitline("\tPOPQ\tBX\n"); - if (n.op == tkind.TK_PLUS) { emitline("\tADDQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_MINUS) { emitline("\tSUBQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_STAR) { emitline("\tIMULQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_SLASH) { + if (n.op == syntax.tkind.TK_PLUS) { emitline("\tADDQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_MINUS) { emitline("\tSUBQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_STAR) { emitline("\tIMULQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_SLASH) { // Signed IDIV reads dividend from RDX:RAX; CQO sign-extends // RAX. Zero-filling DX would treat a negative RAX as a huge // positive 128-bit value. Unsigned DIV needs RDX zero. @@ -29513,7 +29513,7 @@ fn cgbin(c: *cgen, n: *node) void = { }; return; }; - if (n.op == tkind.TK_PERCENT) { + if (n.op == syntax.tkind.TK_PERCENT) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tBX\n"); @@ -29524,15 +29524,15 @@ fn cgbin(c: *cgen, n: *node) void = { emitline("\tMOVQ\tDX, AX\n"); return; }; - if (n.op == tkind.TK_AMP) { emitline("\tANDQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_PIPE) { emitline("\tORQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_CARET) { emitline("\tXORQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_LSHIFT) { + if (n.op == syntax.tkind.TK_AMP) { emitline("\tANDQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_PIPE) { emitline("\tORQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_CARET) { emitline("\tXORQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_LSHIFT) { emitline("\tMOVQ\tBX, CX\n"); emitline("\tSHLQ\tCX, AX\n"); return; }; - if (n.op == tkind.TK_RSHIFT) { + if (n.op == syntax.tkind.TK_RSHIFT) { // #136: signed RSHIFT → SAR (arithmetic, sign-extends MSB); // unsigned → SHR (logical, zero-fill). `unsignd` derived above // at cgbin head from nodeisunsigned(lhs) || nodeisunsigned(rhs). @@ -29548,12 +29548,12 @@ fn cgbin(c: *cgen, n: *node) void = { // materialise 0/1 in AX. Same shape as the C cgen. let iscmp: bool = false; let jcc: str = ""; - if (n.op == tkind.TK_EQ) { iscmp = true; jcc = "JE"; }; - if (n.op == tkind.TK_NEQ) { iscmp = true; jcc = "JNE"; }; - if (n.op == tkind.TK_LT) { iscmp = true; if (unsignd) { jcc = "JB"; } else { jcc = "JL"; }; }; - if (n.op == tkind.TK_LE) { iscmp = true; if (unsignd) { jcc = "JBE"; } else { jcc = "JLE"; }; }; - if (n.op == tkind.TK_GT) { iscmp = true; if (unsignd) { jcc = "JA"; } else { jcc = "JG"; }; }; - if (n.op == tkind.TK_GE) { iscmp = true; if (unsignd) { jcc = "JAE"; } else { jcc = "JGE"; }; }; + if (n.op == syntax.tkind.TK_EQ) { iscmp = true; jcc = "JE"; }; + if (n.op == syntax.tkind.TK_NEQ) { iscmp = true; jcc = "JNE"; }; + if (n.op == syntax.tkind.TK_LT) { iscmp = true; if (unsignd) { jcc = "JB"; } else { jcc = "JL"; }; }; + if (n.op == syntax.tkind.TK_LE) { iscmp = true; if (unsignd) { jcc = "JBE"; } else { jcc = "JLE"; }; }; + if (n.op == syntax.tkind.TK_GT) { iscmp = true; if (unsignd) { jcc = "JA"; } else { jcc = "JG"; }; }; + if (n.op == syntax.tkind.TK_GE) { iscmp = true; if (unsignd) { jcc = "JAE"; } else { jcc = "JGE"; }; }; if (iscmp) { let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); @@ -29582,11 +29582,11 @@ fn cgbin(c: *cgen, n: *node) void = { // DX=0) or the success variant (tag=0, DX=ptr) after the // value-init stores complete. Callers wrap with `!` / `?` to // consume the union. -fn cgalloc(c: *cgen, n: *node) void = { - let v: *node = n.list; +fn cgalloc(c: *cgen, n: *syntax.node) void = { + let v: *syntax.node = n.list; let sz: i32 = 8; let si: *structinfo = nil; - if (v.kind == nkind.N_STRUCTLIT) { + if (v.kind == syntax.nkind.N_STRUCTLIT) { // #26: chase the alias chain on the literal's type ref so an // alias head (`type pt = point; alloc(pt{...})`) resolves to // the underlying struct's layout — name-keyed structlookup on @@ -29612,16 +29612,16 @@ fn cgalloc(c: *cgen, n: *node) void = { emitline("\tJMP\t"); emitline(donel); emitline("\n"); emitlabel(okl); emitline("\tPUSHQ\tAX\n"); - if (v.kind == nkind.N_STRUCTLIT) { + if (v.kind == syntax.nkind.N_STRUCTLIT) { if (si != nil) { - let f: *node = v.list; + let f: *syntax.node = v.list; for (f != nil) { - if (f.kind == nkind.N_FIELD) { + if (f.kind == syntax.nkind.N_FIELD) { let fname: str = f.str; let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fname)) { + if (syntax.streq(fn_, fname)) { cgexpr(c, f.lhs); // alloc(T{ fval = v }) for f64/f32 field: cgexpr left // the value in X0, not AX — route the store via MOVSD/MOVSS. @@ -29776,8 +29776,8 @@ fn cgappendslot(c: *cgen, direct: bool, off: i32, scr: i32, esz: i32, dst: str) // ; POPQ AX // ; MOV* AX, (BX) ; store (MOVB / MOVQ) // nkind.N_SPREAD wraps the same body in a counted loop over items.len. -fn cgappend(c: *cgen, n: *node) void = { - let sn: *node = n.list; +fn cgappend(c: *cgen, n: *syntax.node) void = { + let sn: *syntax.node = n.list; if (sn == nil) { return; }; // FA1 (#15): the old `sn.kind != N_IDENT → return` and // `snlocal == nil → return` gates were SILENT zero-emission @@ -29788,7 +29788,7 @@ fn cgappend(c: *cgen, n: *node) void = { let sndirect: bool = false; let sn_off: i32 = 0; let snlocal: *local = nil; - if (sn.kind == nkind.N_IDENT) { + if (sn.kind == syntax.nkind.N_IDENT) { snlocal = localfindnode(c, sn.str); if (snlocal != nil) { sndirect = true; @@ -29796,8 +29796,8 @@ fn cgappend(c: *cgen, n: *node) void = { }; }; let esz: i32 = 0; - let etnode: *node = nil; - let sti: *tinfo = nil; + let etnode: *syntax.node = nil; + let sti: *syntax.tinfo = nil; if (sndirect) { // #34: esz off the DECLARED slice local's stamped tnode via // elemsizeofc — bare elemsizeof returns the 8 sentinel for a @@ -29806,18 +29806,18 @@ fn cgappend(c: *cgen, n: *node) void = { // the slot index vs cstage's su->sub->size. esz = elemsizeofc(c, snlocal.tnode); if (snlocal.tnode != nil) { - let stk: nkind = snlocal.tnode.kind; - if (stk == nkind.N_TSLICE) { etnode = snlocal.tnode.lhs; }; - if (stk == nkind.N_TARRAY) { etnode = snlocal.tnode.lhs; }; - if (stk == nkind.N_TPTR) { etnode = snlocal.tnode.lhs; }; - sti = snlocal.tnode.type_: *tinfo; + let stk: syntax.nkind = snlocal.tnode.kind; + if (stk == syntax.nkind.N_TSLICE) { etnode = snlocal.tnode.lhs; }; + if (stk == syntax.nkind.N_TARRAY) { etnode = snlocal.tnode.lhs; }; + if (stk == syntax.nkind.N_TPTR) { etnode = snlocal.tnode.lhs; }; + sti = snlocal.tnode.type_: *syntax.tinfo; }; } else { // FA1: `*p` has no declared tnode — key esz/element kind off // the checker-STAMPED target tinfo (#209/#211 discipline), the // same source cstage reads (sn->type → su->sub->size). - sti = sn.type_: *tinfo; - let fsti: *tinfo = sti; + sti = sn.type_: *syntax.tinfo; + let fsti: *syntax.tinfo = sti; fsti = tichase(fsti); if (fsti != nil && fsti.sub != nil) { esz = fsti.sub.size: i32; }; if (esz <= 0) { @@ -29834,17 +29834,17 @@ fn cgappend(c: *cgen, n: *node) void = { // Mirrors cstage cgen.c's append arm + the #270/#12/#20 // array-literal element dispatch (cgarrlitfillbp). sti = tichase(sti); - let esubti: *tinfo = nil; + let esubti: *syntax.tinfo = nil; if (sti != nil) { esubti = sti.sub; }; // FA1: pre-peel handle — the indirect struct-lit fill keys its // structinfo off the NAMED element tinfo's name (the same leaf // structlookupchain resolves from the declared tnode). - let esubnamed: *tinfo = esubti; + let esubnamed: *syntax.tinfo = esubti; esubti = tichase(esubti); - let elstr: bool = esubti != nil && esubti.kind == tykind.TY_STR; - let elslice: bool = esubti != nil && esubti.kind == tykind.TY_SLICE; - let eltagged: bool = esubti != nil && esubti.kind == tykind.TY_TAGGED; - let elstruct: bool = esubti != nil && esubti.kind == tykind.TY_STRUCT; + let elstr: bool = esubti != nil && esubti.kind == syntax.tykind.TY_STR; + let elslice: bool = esubti != nil && esubti.kind == syntax.tykind.TY_SLICE; + let eltagged: bool = esubti != nil && esubti.kind == syntax.tykind.TY_TAGGED; + let elstruct: bool = esubti != nil && esubti.kind == syntax.tykind.TY_STRUCT; let elwide: bool = elstr || elslice || eltagged || elstruct; if (!elwide && esz > 8) { let m34k: str = "#34: append() element kind unsupported (rule-7)\n"; @@ -29872,31 +29872,31 @@ fn cgappend(c: *cgen, n: *node) void = { emitline("(BP)\n"); }; - let vn: *node = sn.next; + let vn: *syntax.node = sn.next; for (vn != nil) { - if (vn.kind == nkind.N_SPREAD) { + if (vn.kind == syntax.nkind.N_SPREAD) { // #34 review: a non-ident/non-local spread source used // to be silently SKIPPED here while cstage fell past // its spread arm into the single-value stores with the // N_SPREAD node (garbage store) — divergent. - let it: *node = vn.lhs; + let it: *syntax.node = vn.lhs; // #35: only a {ptr,len,cap}-headered source reads as a // header below; a [N]T array place IS its storage — the // ident path used to read its first 16 data bytes as // ptr/len, silently. Loud until wired (task #27); str // shares the slice header layout. - let itu: *tinfo = nil; - if (it != nil) { itu = it.type_: *tinfo; }; + let itu: *syntax.tinfo = nil; + if (it != nil) { itu = it.type_: *syntax.tinfo; }; itu = tichase(itu); - if (itu == nil || (itu.kind != tykind.TY_SLICE - && itu.kind != tykind.TY_STR)) { + if (itu == nil || (itu.kind != syntax.tykind.TY_SLICE + && itu.kind != syntax.tykind.TY_STR)) { let m35p: str = "#35: append() spread source shape unsupported (rule-7)\n"; os.write(2, m35p.ptr, m35p.len: u64); os.exit(1); }; let it_off: i32 = 0; let itscr: i32 = 0; - if (it.kind == nkind.N_IDENT) { + if (it.kind == syntax.nkind.N_IDENT) { let itlocal: *local = localfindnode(c, it.str); if (itlocal != nil) { it_off = itlocal.off; }; }; @@ -29930,7 +29930,7 @@ fn cgappend(c: *cgen, n: *node) void = { // FA1: no etnode behind `*p` — signedness off the // stamped element tinfo, the predicate cstage's // fldloadop applies to su->sub. - load_op = loadopsz(typeissigned(esubti), esz); + load_op = loadopsz(syntax.typeissigned(esubti), esz); }; emitline("\tSUBQ\t$8, SP\n"); emitline("\tMOVQ\t$0, (SP)\n"); @@ -30112,21 +30112,21 @@ fn cgappend(c: *cgen, n: *node) void = { let arootoff: i32 = 0; let asroot: i32 = 0; let asoff: i32 = 0; - let aroot: *node = nil; - let aidx: *node = nil; - if (elstruct && vn.kind != nkind.N_STRUCTLIT && vn.kind != nkind.N_IDENT) { - let ch: *node = vn; + let aroot: *syntax.node = nil; + let aidx: *syntax.node = nil; + if (elstruct && vn.kind != syntax.nkind.N_STRUCTLIT && vn.kind != syntax.nkind.N_IDENT) { + let ch: *syntax.node = vn; let aok: bool = true; - for (aok && ch.kind == nkind.N_DOT) { - let ab: *node = ch.lhs; - let af: *tfield = nil; + for (aok && ch.kind == syntax.nkind.N_DOT) { + let ab: *syntax.node = ch.lhs; + let af: *syntax.tfield = nil; if (ab != nil) { - let abu: *tinfo = ab.type_: *tinfo; + let abu: *syntax.tinfo = ab.type_: *syntax.tinfo; abu = tichase(abu); - if (abu != nil && abu.kind == tykind.TY_STRUCT) { - let fl: *tfield = abu.fields; + if (abu != nil && abu.kind == syntax.tykind.TY_STRUCT) { + let fl: *syntax.tfield = abu.fields; for (fl != nil) { - if (streq(fl.name, ch.str)) { af = fl; break; }; + if (syntax.streq(fl.name, ch.str)) { af = fl; break; }; fl = fl.tnext; }; }; @@ -30135,27 +30135,27 @@ fn cgappend(c: *cgen, n: *node) void = { afld += af.offset: i32; ch = ab; }; - if (aok && ch.kind == nkind.N_INDEX) { - let ab: *node = ch.lhs; - let aet: *tinfo = ch.type_: *tinfo; + if (aok && ch.kind == syntax.nkind.N_INDEX) { + let ab: *syntax.node = ch.lhs; + let aet: *syntax.tinfo = ch.type_: *syntax.tinfo; aet = tichase(aet); - let abu: *tinfo = nil; + let abu: *syntax.tinfo = nil; if (ab != nil) { - abu = ab.type_: *tinfo; + abu = ab.type_: *syntax.tinfo; abu = tichase(abu); }; if (ab == nil || abu == nil || aet == nil - || (abu.kind != tykind.TY_SLICE && abu.kind != tykind.TY_ARRAY)) { + || (abu.kind != syntax.tykind.TY_SLICE && abu.kind != syntax.tykind.TY_ARRAY)) { aok = false; } else { - abaseslice = abu.kind == tykind.TY_SLICE; + abaseslice = abu.kind == syntax.tykind.TY_SLICE; aidxesz = aet.size: i32; aidx = ch.rhs; ch = ab; }; }; if (aok) { - if (ch.kind == nkind.N_IDENT) { + if (ch.kind == syntax.nkind.N_IDENT) { let rl: *local = localfindnode(c, ch.str); if (rl != nil) { arootoff = rl.off; @@ -30165,15 +30165,15 @@ fn cgappend(c: *cgen, n: *node) void = { if (defvarstructinfo(c, ch.str) != nil) { gok = true; }; }; if (!gok) { - let dtn: *node = defvartnode(c, ch.str); + let dtn: *syntax.node = defvartnode(c, ch.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { gok = true; }; + if (dtn.kind == syntax.nkind.N_TARRAY) { gok = true; }; }; }; if (!gok) { aok = false; }; }; } else { - if (ch.kind != nkind.N_UN || ch.op != tkind.TK_STAR) { + if (ch.kind != syntax.nkind.N_UN || ch.op != syntax.tkind.TK_STAR) { aok = false; }; }; @@ -30184,7 +30184,7 @@ fn cgappend(c: *cgen, n: *node) void = { os.exit(1); }; aroot = ch; - if (aroot.kind == nkind.N_UN) { + if (aroot.kind == syntax.nkind.N_UN) { asroot = localadd(c, "@appendsroot", 8, nil); cgexpr(c, aroot.lhs); emitline("\tMOVQ\tAX, "); @@ -30237,7 +30237,7 @@ fn cgappend(c: *cgen, n: *node) void = { vn = vn.next; continue; }; - if (vn.kind == nkind.N_STRUCTLIT) { + if (vn.kind == syntax.nkind.N_STRUCTLIT) { // #59 (#50's eval-order kin): resolve the struct // info, then fill the literal into a fresh // per-SITE scratch (must stay live across @@ -30252,7 +30252,7 @@ fn cgappend(c: *cgen, n: *node) void = { // FA1: no declared tnode to chain through — // the stamped NAMED element tinfo carries the // same leaf structlookupchain would resolve. - if (esubnamed.kind == tykind.TY_NAMED) { + if (esubnamed.kind == syntax.tykind.TY_NAMED) { esi = structlookup(c, esubnamed.name); }; }; @@ -30315,7 +30315,7 @@ fn cgappend(c: *cgen, n: *node) void = { }; cgappendgrow(c, sndirect, sn_off, snscr, esz); cgappendslot(c, sndirect, sn_off, snscr, esz, "BX"); - if (vn.kind == nkind.N_IDENT) { + if (vn.kind == syntax.nkind.N_IDENT) { let sl: *local = localfindnode(c, vn.str); if (sl == nil) { let m34i: str = "#34: append() struct element source ident is not a local (rule-7)\n"; @@ -30371,7 +30371,7 @@ fn cgappend(c: *cgen, n: *node) void = { emitline("\tMOVQ\tBX, "); emitoff(pscroff: i64); emitline("(BP)\n"); - if (aroot.kind == nkind.N_IDENT) { + if (aroot.kind == syntax.nkind.N_IDENT) { if (arootoff != 0) { emitline("\tLEAQ\t"); emitoff(arootoff: i64); @@ -30468,15 +30468,15 @@ fn cgappend(c: *cgen, n: *node) void = { // src (j+1) ahead of dst (j), the safe memmove-down direction. Mirrors // cmd/w6c/cgen.c's N_CALL delete arm instruction-for-instruction // (rule-10 byte-id). -fn cgdelete(c: *cgen, n: *node) void = { - let d: *node = n.list; // N_INDEX, checker-validated - let base: *node = d.lhs; +fn cgdelete(c: *cgen, n: *syntax.node) void = { + let d: *syntax.node = n.list; // N_INDEX, checker-validated + let base: *syntax.node = d.lhs; // esz off the STAMPED base tinfo (#34/#48 discipline — never the // value node). Peel TY_NAMED on indexable AND element, mirroring // cstage's type_chase_named on both (#8 family). - let sti: *tinfo = base.type_: *tinfo; + let sti: *syntax.tinfo = base.type_: *syntax.tinfo; sti = tichase(sti); - let esub: *tinfo = nil; + let esub: *syntax.tinfo = nil; if (sti != nil) { esub = sti.sub; }; esub = tichase(esub); let esz: i32 = 0; @@ -30489,7 +30489,7 @@ fn cgdelete(c: *cgen, n: *node) void = { let hdr_lea: bool = false; let hdr_off: i32 = 0; let hdr_ok: bool = false; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, base.str); if (lc != nil) { hdr_lea = true; @@ -30499,9 +30499,9 @@ fn cgdelete(c: *cgen, n: *node) void = { }; // (*p)[i]: the header lives behind a local ptr-to-slice — the // regex fold-2b delete_thread shape (threads: *[]thread). - if (!hdr_ok && base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR && base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (!hdr_ok && base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR && base.lhs != nil) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let pc: *local = localfindnode(c, base.lhs.str); if (pc != nil) { hdr_off = pc.off; @@ -30600,15 +30600,15 @@ fn cgdelete(c: *cgen, n: *node) void = { // Bounds are implicit (no range check, matching cgdelete and the rest // of cgen). Mirrors cmd/w6c/cgen.c's N_CALL delete range arm // instruction-for-instruction (rule-10 byte-id). -fn cgdeleterange(c: *cgen, n: *node) void = { - let d: *node = n.list; // N_SLICE, checker-validated - let base: *node = d.lhs; +fn cgdeleterange(c: *cgen, n: *syntax.node) void = { + let d: *syntax.node = n.list; // N_SLICE, checker-validated + let base: *syntax.node = d.lhs; // esz off the STAMPED base tinfo (#34/#48 discipline — never the // value node). Peel TY_NAMED on indexable AND element, mirroring // cstage's type_chase_named on both (#8 family). - let sti: *tinfo = base.type_: *tinfo; + let sti: *syntax.tinfo = base.type_: *syntax.tinfo; sti = tichase(sti); - let esub: *tinfo = nil; + let esub: *syntax.tinfo = nil; if (sti != nil) { esub = sti.sub; }; esub = tichase(esub); let esz: i32 = 0; @@ -30623,7 +30623,7 @@ fn cgdeleterange(c: *cgen, n: *node) void = { let hdr_ok: bool = false; let hdr_idx: bool = false; let osz: i32 = 0; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, base.str); if (lc != nil) { hdr_lea = true; @@ -30633,9 +30633,9 @@ fn cgdeleterange(c: *cgen, n: *node) void = { }; // (*p)[lo:hi]: header behind a local ptr-to-slice — cgdelete's // regex_shape twin. - if (!hdr_ok && base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR && base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (!hdr_ok && base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR && base.lhs != nil) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let pc: *local = localfindnode(c, base.lhs.str); if (pc != nil) { hdr_off = pc.off; @@ -30648,9 +30648,9 @@ fn cgdeleterange(c: *cgen, n: *node) void = { // the fold-5a consumer shape (ref/hare/regex/regex.ha:333 // delete(jump_idxs[group_level][..])). Outer stride = the inner // header type's own table size (sti). - if (!hdr_ok && base.kind == nkind.N_INDEX) { + if (!hdr_ok && base.kind == syntax.nkind.N_INDEX) { if (base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let oc: *local = localfindnode(c, base.lhs.str); if (oc != nil) { hdr_idx = true; @@ -30798,16 +30798,16 @@ fn cgdeleterange(c: *cgen, n: *node) void = { // are implicit (no index check, matching delete). Mirrors cmd/w6c/ // cgen.c's N_CALL insert arm instruction-for-instruction (rule-10 // byte-id). -fn cginsert(c: *cgen, n: *node) void = { - let d: *node = n.list; // N_INDEX, checker-validated - let base: *node = d.lhs; - let v: *node = d.next; +fn cginsert(c: *cgen, n: *syntax.node) void = { + let d: *syntax.node = n.list; // N_INDEX, checker-validated + let base: *syntax.node = d.lhs; + let v: *syntax.node = d.next; // esz off the STAMPED base tinfo (#34/#48 discipline — never the // value node). Peel TY_NAMED on indexable AND element, mirroring // cstage's type_chase_named on both (#8 family). - let sti: *tinfo = base.type_: *tinfo; + let sti: *syntax.tinfo = base.type_: *syntax.tinfo; sti = tichase(sti); - let esub: *tinfo = nil; + let esub: *syntax.tinfo = nil; if (sti != nil) { esub = sti.sub; }; esub = tichase(esub); let esz: i32 = 0; @@ -30820,7 +30820,7 @@ fn cginsert(c: *cgen, n: *node) void = { let hdr_lea: bool = false; let hdr_off: i32 = 0; let hdr_ok: bool = false; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, base.str); if (lc != nil) { hdr_lea = true; @@ -30830,9 +30830,9 @@ fn cginsert(c: *cgen, n: *node) void = { }; // (*p)[i]: the header lives behind a local ptr-to-slice — // delete's regex_shape twin. - if (!hdr_ok && base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR && base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (!hdr_ok && base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR && base.lhs != nil) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let pc: *local = localfindnode(c, base.lhs.str); if (pc != nil) { hdr_off = pc.off; @@ -31026,21 +31026,21 @@ fn cginsert(c: *cgen, n: *node) void = { emitline("\tADDQ\t$24, SP\n"); }; -fn cgcall(c: *cgen, n: *node) void = { +fn cgcall(c: *cgen, n: *syntax.node) void = { // Hare-style `append(s, v)` / `append(s, items...)` builtin — // special-cased before pushargsrev so the spread variant can run // a counted loop over the items slice instead of a normal call. - let callee: *node = n.lhs; + let callee: *syntax.node = n.lhs; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { // abort([msg]) / assert(cond[, msg]) — checker-tagged // builtins (callee TY_ERR is the routing key, cstage's // `lhs->type == ty_err` at cmd/w6c/cgen.c:6618,6645); // lower to rt_abort. A user-shadowed abort/assert is // untagged and stays on the regular call path (#58). - let bti: *tinfo = callee.type_: *tinfo; - if (bti != nil && bti.kind == tykind.TY_ERR) { - if (streq(callee.str, "abort")) { + let bti: *syntax.tinfo = callee.type_: *syntax.tinfo; + if (bti != nil && bti.kind == syntax.tykind.TY_ERR) { + if (syntax.streq(callee.str, "abort")) { if (n.list != nil) { cgexpr(c, n.list); emitline("\tMOVQ\tAX, DI\n"); @@ -31052,14 +31052,14 @@ fn cgcall(c: *cgen, n: *node) void = { emitline("\tCALL\trt_abort(SB)\n"); return; }; - if (streq(callee.str, "assert") && n.list != nil) { + if (syntax.streq(callee.str, "assert") && n.list != nil) { cgexpr(c, n.list); let skip: str = mklabel(c, "as"); emitline("\tCMPQ\t$0, AX\n"); emitline("\tJNE\t"); emitline(skip); emitline("\n"); - let msg: *node = n.list.next; + let msg: *syntax.node = n.list.next; if (msg != nil) { cgexpr(c, msg); emitline("\tMOVQ\tAX, DI\n"); @@ -31073,7 +31073,7 @@ fn cgcall(c: *cgen, n: *node) void = { return; }; }; - if (streq(callee.str, "append")) { + if (syntax.streq(callee.str, "append")) { if (n.list != nil) { if (n.list.next != nil) { cgappend(c, n); @@ -31092,7 +31092,7 @@ fn cgcall(c: *cgen, n: *node) void = { // scope_lookup_prefer gating on the `abort` precedent; // without it, the bare same-module call lands in the // typed-builtin path and shadows the user decl. Task #23. - if (streq(callee.str, "alloc")) { + if (syntax.streq(callee.str, "alloc")) { if (n.list != nil) { if (!samemodfn(c, "alloc")) { cgalloc(c, n); @@ -31118,20 +31118,20 @@ fn cgcall(c: *cgen, n: *node) void = { // DATA POINTER as the length. Non-place operands (call // result, slicing expr, string literal — previously the same // silent ptr-garbage) die LOUD per rule 7. - if (streq(callee.str, "len")) { + if (syntax.streq(callee.str, "len")) { if (n.list != nil) { - let a: *node = n.list; - let at: *tinfo = a.type_: *tinfo; - let u: *tinfo = at; + let a: *syntax.node = n.list; + let at: *syntax.tinfo = a.type_: *syntax.tinfo; + let u: *syntax.tinfo = at; u = tichase(u); let hdrish: bool = false; if (u != nil) { - if (u.kind == tykind.TY_SLICE - || u.kind == tykind.TY_STR) { + if (u.kind == syntax.tykind.TY_SLICE + || u.kind == syntax.tykind.TY_STR) { hdrish = true; }; }; - if (hdrish && a.kind == nkind.N_IDENT) { + if (hdrish && a.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.str); if (lc != nil) { emitline("\tMOVQ\t"); @@ -31168,20 +31168,20 @@ fn cgcall(c: *cgen, n: *node) void = { // directly at BP + element_off + 8, mirroring // the N_IDENT slice arm above and the // tuple-field-offset walk (cgenexpr.ww N_TTUPLE). - if (hdrish && a.kind == nkind.N_DOT + if (hdrish && a.kind == syntax.nkind.N_DOT && a.lhs != nil - && a.lhs.kind == nkind.N_IDENT) { + && a.lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.lhs.str); if (lc != nil) { - let tn: *node = lc.tnode; - for (tn != nil && tn.kind == nkind.N_TNAME) { + let tn: *syntax.node = lc.tnode; + for (tn != nil && tn.kind == syntax.nkind.N_TNAME) { tn = aliaslookup(c, tn.str); }; if (tn != nil) { - if (tn.kind == nkind.N_TTUPLE) { + if (tn.kind == syntax.nkind.N_TTUPLE) { let idx: i32 = fldnumidx(a.str); if (idx >= 0) { - let tp: *node = tn.list; + let tp: *syntax.node = tn.list; let foff: i32 = 0; let i: i32 = 0; for (i < idx) { @@ -31211,15 +31211,15 @@ fn cgcall(c: *cgen, n: *node) void = { // hit; twin of the cgdot global-tuple // arm and cstage's #235 global base. if (lc == nil) { - let gtn: *node = letvartnode(c, a.lhs.str); - for (gtn != nil && gtn.kind == nkind.N_TNAME) { + let gtn: *syntax.node = letvartnode(c, a.lhs.str); + for (gtn != nil && gtn.kind == syntax.nkind.N_TNAME) { gtn = aliaslookup(c, gtn.str); }; if (gtn != nil) { - if (gtn.kind == nkind.N_TTUPLE) { + if (gtn.kind == syntax.nkind.N_TTUPLE) { let gidx: i32 = fldnumidx(a.str); if (gidx >= 0) { - let gtp: *node = gtn.list; + let gtp: *syntax.node = gtn.list; let gfoff: i32 = 0; let gi: i32 = 0; for (gi < gidx) { @@ -31257,13 +31257,13 @@ fn cgcall(c: *cgen, n: *node) void = { // the same MOVQ BX,AX shape as the #14 .len // pseudo-field fix. Same family as #18 (shared // cstage==wwstage gap, not rule-10). - if (hdrish && a.kind == nkind.N_INDEX) { + if (hdrish && a.kind == syntax.nkind.N_INDEX) { cgexpr(c, a); emitline("\tMOVQ\tBX, AX\n"); return; }; if (u != nil) { - if (u.kind == tykind.TY_ARRAY) { + if (u.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(u.alen: i64); emitline(", AX\n"); @@ -31294,7 +31294,7 @@ fn cgcall(c: *cgen, n: *node) void = { // so Hare code ports verbatim with its side effects // intact. Pre-#27 wwstage fell through to a generic // CALL free → undefined reference at link. - if (streq(callee.str, "free")) { + if (syntax.streq(callee.str, "free")) { if (n.list != nil) { if (n.list.next == nil) { cgexpr(c, n.list); @@ -31306,10 +31306,10 @@ fn cgcall(c: *cgen, n: *node) void = { // delete-half + fold-5a P2 range form; mirror of // cstage cgen.c's N_CALL delete arm (which branches // on d->kind == N_SLICE internally). - if (streq(callee.str, "delete")) { + if (syntax.streq(callee.str, "delete")) { if (n.list != nil) { if (n.list.next == nil) { - if (n.list.kind == nkind.N_SLICE) { + if (n.list.kind == syntax.nkind.N_SLICE) { cgdeleterange(c, n); return; }; @@ -31320,7 +31320,7 @@ fn cgcall(c: *cgen, n: *node) void = { }; // insert(xs[idx], v) — #35 insert-half; mirror of // cstage cgen.c's N_CALL insert arm. - if (streq(callee.str, "insert")) { + if (syntax.streq(callee.str, "insert")) { if (n.list != nil) { if (n.list.next != nil) { if (n.list.next.next == nil) { @@ -31343,15 +31343,15 @@ fn cgcall(c: *cgen, n: *node) void = { // fast path and dropped the variant tag word on widened slice args. // Cstage finds params via the checker-set `n->lhs->type`, sidestepping // the name-driven registry entirely (cmd/w6c/cgen.c:4161-4165). - let calleeparams: *node = nil; + let calleeparams: *syntax.node = nil; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { calleeparams = fnparamslookup(c, callee.str); - } else { if (callee.kind == nkind.N_DOT) { + } else { if (callee.kind == syntax.nkind.N_DOT) { let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; @@ -31371,37 +31371,37 @@ fn cgcall(c: *cgen, n: *node) void = { // nvar>0, vararg_sl always — keeping later match labels aligned. { let nfixed_v: i32 = 0; - let varp: *node = callee_variadic_param(c, callee, &nfixed_v); + let varp: *syntax.node = callee_variadic_param(c, callee, &nfixed_v); if (varp != nil) { let nargs0: i32 = 0; - let aw: *node = n.list; + let aw: *syntax.node = n.list; for (aw != nil) { nargs0 += 1; aw = aw.next; }; let nvar: i32 = nargs0 - nfixed_v; if (nvar < 0) { nvar = 0; }; let forwarding: bool = false; if (nvar == 1) { - let aaf: *node = n.list; + let aaf: *syntax.node = n.list; let kk: i32 = 0; for (kk < nfixed_v) { aaf = aaf.next; kk += 1; }; if (aaf != nil) { - if (aaf.kind == nkind.N_SPREAD) { + if (aaf.kind == syntax.nkind.N_SPREAD) { forwarding = true; }; }; }; if (forwarding) { - let prev: *node = nil; - let cur2: *node = n.list; + let prev: *syntax.node = nil; + let cur2: *syntax.node = n.list; let kk2: i32 = 0; for (kk2 < nfixed_v) { prev = cur2; cur2 = cur2.next; kk2 += 1; }; - let inner: *node = cur2.lhs; + let inner: *syntax.node = cur2.lhs; if (inner != nil) { inner.next = nil; }; if (prev == nil) { n.list = inner; } else { prev.next = inner; }; @@ -31421,14 +31421,14 @@ fn cgcall(c: *cgen, n: *node) void = { // .lhs; Ken's gate: only deref when the wrap // shape is confirmed N_TSLICE (mirrors cstage // cgen.c:4352 `vsu->kind == TY_SLICE` guard). - let velem: *node = varp.lhs; + let velem: *syntax.node = varp.lhs; if (varp.lhs != nil - && varp.lhs.kind == nkind.N_TSLICE) { + && varp.lhs.kind == syntax.nkind.N_TSLICE) { velem = varp.lhs.lhs; }; let esz: i32 = 8; if (velem != nil) { - if (velem.kind == nkind.N_TNAME) { + if (velem.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, velem.str); if (ps > 0) { esz = ps; } else { esz = slotsize(c, velem); }; @@ -31442,7 +31442,7 @@ fn cgcall(c: *cgen, n: *node) void = { // gather buffer — unwired (rule 7). cstage twin // guards before its v_is_tagged gather. if (velem != nil) { - if (taggedmemargsize(velem.type_: *tinfo) > 0) { + if (taggedmemargsize(velem.type_: *syntax.tinfo) > 0) { let mv: str = "#38b: >48B tagged variadic element unwired\n"; os.write(2, mv.ptr, mv.len: u64); os.exit(1); @@ -31470,14 +31470,14 @@ fn cgcall(c: *cgen, n: *node) void = { let sname: str = mklabel(c, "vararg_sl"); let soff: i32 = localadd(c, sname, tyslicesize(): i32, varp.lhs); - let aa2: *node = n.list; + let aa2: *syntax.node = n.list; let kk3: i32 = 0; for (kk3 < nfixed_v) { aa2 = aa2.next; kk3 += 1; }; let j: i32 = 0; - let prevarg: *node = n.list; + let prevarg: *syntax.node = n.list; if (nfixed_v == 0) { prevarg = nil; } else { let kk4: i32 = 0; @@ -31492,7 +31492,7 @@ fn cgcall(c: *cgen, n: *node) void = { // dst is the per-element tagged type; // pass velem (cstage cgen.c:4382 passes // velem, not the slice wrap vsu). - cgwidentaggedstore(c, velem.type_: *tinfo, + cgwidentaggedstore(c, velem.type_: *syntax.tinfo, aa2, "BP", slot, esz); } else { if (velemstr) { cgexpr(c, aa2); @@ -31544,7 +31544,7 @@ fn cgcall(c: *cgen, n: *node) void = { emitline("\tMOVQ\tAX, "); emitoff((soff + 16): i64); emitline("(BP)\n"); - let sn: *node = newnode(nkind.N_IDENT, + let sn: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, "", 0, 0); sn.str = sname; // Synthesised after the checker has run, so the @@ -31576,7 +31576,7 @@ fn cgcall(c: *cgen, n: *node) void = { let sretcalloff: i32 = 0; // #220: GLOBAL dest — RDI gets `LEAQ name(SB)` below; no @sretscr // slot (the callee writes the struct straight into g's storage). - let sretdestn: *node = nil; + let sretdestn: *syntax.node = nil; if (sretcs > 0) { if (c.sretdestnode != nil) { sretdestn = c.sretdestnode; @@ -31599,8 +31599,8 @@ fn cgcall(c: *cgen, n: *node) void = { let intidx: i32 = 0; if (sretcs > 0) { intidx = 1; }; let fpidx: i32 = 0; - let a: *node = n.list; - let dparam: *node = calleeparams; + let a: *syntax.node = n.list; + let dparam: *syntax.node = calleeparams; let popped: i32 = 0; let stackslots: i32 = 0; for (a != nil) { @@ -31610,15 +31610,15 @@ fn cgcall(c: *cgen, n: *node) void = { // pushargsrev (a widened concrete arg is mem-class only // via its param). let dmemsz: i32 = 0; - if (dparam != nil) { if (dparam.kind == nkind.N_PARAM) { - if (dparam.op != tkind.TK_ELLIPSIS) { + if (dparam != nil) { if (dparam.kind == syntax.nkind.N_PARAM) { + if (dparam.op != syntax.tkind.TK_ELLIPSIS) { if (dparam.lhs != nil) { - dmemsz = taggedmemargsize(dparam.lhs.type_: *tinfo); + dmemsz = taggedmemargsize(dparam.lhs.type_: *syntax.tinfo); }; }; }; }; if (dmemsz == 0) { - dmemsz = taggedmemargsize(a.type_: *tinfo); + dmemsz = taggedmemargsize(a.type_: *syntax.tinfo); }; if (dmemsz > 0) { if (dparam != nil) { dparam = dparam.next; }; @@ -31657,9 +31657,9 @@ fn cgcall(c: *cgen, n: *node) void = { }; let fk: i32 = 0; if (a != nil) { - let at: *tinfo = a.type_: *tinfo; - if (typeisf32(at)) { fk = 1; } - else { if (typeisfloat(at)) { fk = 2; }; }; + let at: *syntax.tinfo = a.type_: *syntax.tinfo; + if (syntax.typeisf32(at)) { fk = 1; } + else { if (syntax.typeisfloat(at)) { fk = 2; }; }; }; if (fk != 0) { let mov: str = "MOVSD"; @@ -31681,17 +31681,17 @@ fn cgcall(c: *cgen, n: *node) void = { // tuple LITERAL arg (the declared-tagged box words pop // together with the i64 that follows), mirroring the // param-aware send; else the source tuple type. - let dptt: *node = nil; - if (a.kind == nkind.N_TUPLE) { if (dparam != nil) { - if (dparam.kind == nkind.N_PARAM && dparam.lhs != nil) { - let dtn2: *node = dparam.lhs; - for (dtn2 != nil && dtn2.kind == nkind.N_TNAME) { + let dptt: *syntax.node = nil; + if (a.kind == syntax.nkind.N_TUPLE) { if (dparam != nil) { + if (dparam.kind == syntax.nkind.N_PARAM && dparam.lhs != nil) { + let dtn2: *syntax.node = dparam.lhs; + for (dtn2 != nil && dtn2.kind == syntax.nkind.N_TNAME) { dtn2 = aliaslookup(c, dtn2.str); }; - if (dtn2 != nil) { if (dtn2.kind == nkind.N_TTUPLE) { dptt = dtn2; }; }; + if (dtn2 != nil) { if (dtn2.kind == syntax.nkind.N_TTUPLE) { dptt = dtn2; }; }; }; }; }; - let tuparg: *node = dptt; + let tuparg: *syntax.node = dptt; if (tuparg == nil) { tuparg = nodetuplearg(c, a); }; if (tuparg != nil) { // #163/#32: drain the tuple's staged words (slot+0 @@ -31707,10 +31707,10 @@ fn cgcall(c: *cgen, n: *node) void = { // them (kind-discriminated twin walk). The param-aware // path (dptt) walks declared element TYPE nodes. let tuplit: bool = false; - if (dptt == nil) { if (tuparg.kind == nkind.N_TUPLE) { tuplit = true; }; }; - let p: *node = tuparg.list; + if (dptt == nil) { if (tuparg.kind == syntax.nkind.N_TUPLE) { tuplit = true; }; }; + let p: *syntax.node = tuparg.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (tuplit) { et = p; }; if (isfloattype(c, et)) { if (fpidx >= 8) { @@ -31759,7 +31759,7 @@ fn cgcall(c: *cgen, n: *node) void = { }; } else { let stfc: i32 = 0; - if (a.kind == nkind.N_IDENT) { + if (a.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.str); if (lc != nil) { stfc = structfloatclass(c, lc.tnode); } else { @@ -31769,7 +31769,7 @@ fn cgcall(c: *cgen, n: *node) void = { // class off the global's declared tnode (letvartnode), the same // SysV classification the local path uses. cstage keys // structfloatclass off the operand TYPE, not a local slot. - let gtn: *node = letvartnode(c, a.str); + let gtn: *syntax.node = letvartnode(c, a.str); if (gtn != nil) { stfc = structfloatclass(c, gtn); }; }; }; @@ -31829,7 +31829,7 @@ fn cgcall(c: *cgen, n: *node) void = { // drain exactly that many so intidx tracks per-arg // (the ≤16B struct IDENT case is the stfc branch // above). Mirror of cstage node_isaggarg drain arm. - let aggsz: i32 = aggargsizetn(a.type_: *tinfo); + let aggsz: i32 = aggargsizetn(a.type_: *syntax.tinfo); if (aggsz > 0) { extra = (aggsz + 7) / 8 - 1; }; let words: i32 = 1 + extra; let w: i32 = 0; @@ -31892,7 +31892,7 @@ fn cgcall(c: *cgen, n: *node) void = { // the linker rightly fails. let isfnptrcall: bool = false; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { let cn: str = callee.str; if (localfindnode(c, cn) != nil) { isfnptrcall = true; @@ -31907,28 +31907,28 @@ fn cgcall(c: *cgen, n: *node) void = { // `CALL (SB)` (empty symbol) for the N_UN-callee shape — the // IDENT/DOT name-emit branches missed and isfnptrcall stayed // false. - if (callee.kind != nkind.N_IDENT - && callee.kind != nkind.N_DOT) { + if (callee.kind != syntax.nkind.N_IDENT + && callee.kind != syntax.nkind.N_DOT) { isfnptrcall = true; }; - if (callee.kind == nkind.N_DOT) { - let base: *node = callee.lhs; + if (callee.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = callee.lhs; let fld: str = callee.str; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; let lc: *local = localfindnode(c, bn); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - let lkind: nkind = tn.kind; + let lkind: syntax.nkind = tn.kind; let sname: str; sname.ptr = nil; sname.len = 0; - if (lkind == nkind.N_TNAME) { sname = tn.str; }; - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TNAME) { sname = tn.str; }; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; }; if (sname.len > 0) { @@ -31937,10 +31937,10 @@ fn cgcall(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { - let ft: *node = fi.tnode; + if (syntax.streq(fn_, fld)) { + let ft: *syntax.node = fi.tnode; if (ft != nil) { - if (ft.kind == nkind.N_TFN) { + if (ft.kind == syntax.nkind.N_TFN) { isfnptrcall = true; }; }; @@ -31995,12 +31995,12 @@ fn cgcall(c: *cgen, n: *node) void = { } else { emitline("\tCALL\t"); if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { // Bare `f()` — same-module by ww's resolver, // so c.curmod is the disambiguation hint. calleename = callee.str; emitfnname(c, calleename, c.curmod); - } else { if (callee.kind == nkind.N_DOT) { + } else { if (callee.kind == syntax.nkind.N_DOT) { // `m.f()` — pass the explicit module bareword // so cross-module same-leaf exports resolve. calleename = callee.str; @@ -32008,7 +32008,7 @@ fn cgcall(c: *cgen, n: *node) void = { hint.ptr = nil; hint.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { hint = usehint(c, callee.lhs.str); }; }; @@ -32031,8 +32031,8 @@ fn cgcall(c: *cgen, n: *node) void = { return; }; -fn cgassign(c: *cgen, n: *node) void = { - let lhs: *node = n.lhs; +fn cgassign(c: *cgen, n: *syntax.node) void = { + let lhs: *syntax.node = n.lhs; // #145 (c1.5a): bulk slice-copy-assign `s.arr[lo:hi] = bs` (LHS is // N_SLICE). No legacy cgassign arm catches N_SLICE — the statement // silently emitted nothing (both stages, byte-id-green, #263-class). @@ -32044,8 +32044,8 @@ fn cgassign(c: *cgen, n: *node) void = { // the length is RUNTIME (w6a has no REP/MOVSB). Only plain `=`. The // Hare len(bs)==hi-lo assert is task #149 (rule-7: documented, not a // c2 blocker — appendlit's lengths are equal by construction). - if (lhs != nil) { if (lhs.kind == nkind.N_SLICE - && n.op == tkind.TK_ASSIGN) { + if (lhs != nil) { if (lhs.kind == syntax.nkind.N_SLICE + && n.op == syntax.tkind.TK_ASSIGN) { let esz: i32 = slicebaseesz(c, lhs.lhs); cgexpr(c, lhs); if (esz > 1) { @@ -32088,20 +32088,20 @@ fn cgassign(c: *cgen, n: *node) void = { let placeslit: bool = false; let placedotidx: bool = false; if (lhs != nil) { - if (lhs.kind == nkind.N_DOT && lhs.lhs != nil) { - if (lhs.lhs.kind == nkind.N_INDEX) { + if (lhs.kind == syntax.nkind.N_DOT && lhs.lhs != nil) { + if (lhs.lhs.kind == syntax.nkind.N_INDEX) { placedotidx = true; }; }; - if ((lhs.kind == nkind.N_INDEX - || (lhs.kind == nkind.N_UN && lhs.op == tkind.TK_STAR) + if ((lhs.kind == syntax.nkind.N_INDEX + || (lhs.kind == syntax.nkind.N_UN && lhs.op == syntax.tkind.TK_STAR) || placedotidx) - && n.op == tkind.TK_ASSIGN && n.rhs != nil) { - if (n.rhs.kind == nkind.N_STRUCTLIT) { - let iet: *tinfo = lhs.type_: *tinfo; + && n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil) { + if (n.rhs.kind == syntax.nkind.N_STRUCTLIT) { + let iet: *syntax.tinfo = lhs.type_: *syntax.tinfo; iet = tichase(iet); if (iet != nil) { - if (iet.kind == tykind.TY_STRUCT) { + if (iet.kind == syntax.tykind.TY_STRUCT) { placeslit = true; }; }; @@ -32116,14 +32116,14 @@ fn cgassign(c: *cgen, n: *node) void = { // (byte-id-pinned). Mirror of cstage deref_agg. let derefagg: bool = false; if (lhs != nil) { - if (lhs.kind == nkind.N_UN && lhs.op == tkind.TK_STAR - && n.op == tkind.TK_ASSIGN) { - let du: *tinfo = lhs.type_: *tinfo; + if (lhs.kind == syntax.nkind.N_UN && lhs.op == syntax.tkind.TK_STAR + && n.op == syntax.tkind.TK_ASSIGN) { + let du: *syntax.tinfo = lhs.type_: *syntax.tinfo; du = tichase(du); if (du != nil) { - if (du.kind == tykind.TY_STRUCT - || du.kind == tykind.TY_ARRAY - || du.kind == tykind.TY_TUPLE) { + if (du.kind == syntax.tykind.TY_STRUCT + || du.kind == syntax.tykind.TY_ARRAY + || du.kind == syntax.tykind.TY_TUPLE) { derefagg = true; }; }; @@ -32133,9 +32133,9 @@ fn cgassign(c: *cgen, n: *node) void = { // write nothing. Detected by lhs being an nkind.N_IDENT with empty str // (planted by parseprimary on the tkind.TK_UNDER token). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { if (lhs.str.len == 0) { - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { cgexpr(c, n.rhs); return; }; @@ -32147,12 +32147,12 @@ fn cgassign(c: *cgen, n: *node) void = { // decl-init fills. Pre-#32 the same scalar tail zeroed one // word silently; die loud until the fill lands. Slice-typed // places are already loud in the checker. - if (n.op == tkind.TK_ASSIGN && lhs != nil && n.rhs != nil) { - if (n.rhs.kind == nkind.N_ARRLIT) { - let alt: *tinfo = lhs.type_: *tinfo; + if (n.op == syntax.tkind.TK_ASSIGN && lhs != nil && n.rhs != nil) { + if (n.rhs.kind == syntax.nkind.N_ARRLIT) { + let alt: *syntax.tinfo = lhs.type_: *syntax.tinfo; alt = tichase(alt); if (alt != nil) { - if (alt.kind == tykind.TY_ARRAY) { + if (alt.kind == syntax.tykind.TY_ARRAY) { let mal: str = "array-literal store at assignment unwired (task #32)\n"; os.write(2, mal.ptr, mal.len: u64); os.exit(1); @@ -32168,10 +32168,10 @@ fn cgassign(c: *cgen, n: *node) void = { // guard. Plain `=` (the tagged-ident reassign arm just below) is // untouched. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT && n.op != tkind.TK_ASSIGN) { - let itu: *tinfo = tichase(lhs.type_: *tinfo); + if (lhs.kind == syntax.nkind.N_IDENT && n.op != syntax.tkind.TK_ASSIGN) { + let itu: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); if (itu != nil) { - if (itu.kind == tykind.TY_TAGGED) { + if (itu.kind == syntax.tykind.TY_TAGGED) { let m21: str = "ident compound on tagged not wired (#21/rule-7)\n"; os.write(2, m21.ptr, m21.len: u64); os.exit(1); @@ -32184,8 +32184,8 @@ fn cgassign(c: *cgen, n: *node) void = { // as cglet's tagged-init). Covers nullable fold, tagged source, // struct payload, str payload, scalar payload, with tag remap. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - if (n.op == tkind.TK_ASSIGN) { + if (lhs.kind == syntax.nkind.N_IDENT) { + if (n.op == syntax.tkind.TK_ASSIGN) { let lc: *local = localfindnode(c, lhs.str); if (lc != nil) { if (istaggedtype(c, lc.tnode)) { @@ -32198,20 +32198,20 @@ fn cgassign(c: *cgen, n: *node) void = { // arm + the generic sret receive. let asret: i32 = 0; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { + if (n.rhs.kind == syntax.nkind.N_CALL) { asret = callsretsize(c, n.rhs); }; }; if (asret > 0) { - let aru: *tinfo = n.rhs.type_: *tinfo; + let aru: *syntax.tinfo = n.rhs.type_: *syntax.tinfo; aru = tichase(aru); - let alu: *tinfo = lc.tnode.type_: *tinfo; + let alu: *syntax.tinfo = lc.tnode.type_: *syntax.tinfo; alu = tichase(alu); let aexact: bool = false; if (aru != nil && aru == alu) { aexact = true; } else { - if (typeeq(n.rhs.type_: *tinfo, - lc.tnode.type_: *tinfo)) { + if (syntax.typeeq(n.rhs.type_: *syntax.tinfo, + lc.tnode.type_: *syntax.tinfo)) { aexact = true; }; }; @@ -32226,7 +32226,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; let lsz: i32 = slotsize(c, lc.tnode); - cgwidentaggedstore(c, lc.tnode.type_: *tinfo, + cgwidentaggedstore(c, lc.tnode.type_: *syntax.tinfo, n.rhs, "BP", lc.off, lsz); return; }; @@ -32234,10 +32234,10 @@ fn cgassign(c: *cgen, n: *node) void = { // #38b: sret receive into a tagged GLOBAL // lvalue unwired (rule 7; cstage twin fatals). if (lc == nil && n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { - let gru: *tinfo = lhs.type_: *tinfo; + if (n.rhs.kind == syntax.nkind.N_CALL) { + let gru: *syntax.tinfo = lhs.type_: *syntax.tinfo; gru = tichase(gru); - if (gru != nil && gru.kind == tykind.TY_TAGGED + if (gru != nil && gru.kind == syntax.tykind.TY_TAGGED && callsretsize(c, n.rhs) > 0) { let m38g: str = "#38b: sret receive into a tagged GLOBAL lvalue unwired\n"; os.write(2, m38g.ptr, m38g.len: u64); @@ -32252,14 +32252,14 @@ fn cgassign(c: *cgen, n: *node) void = { // scalar store below clobbered the tag word. cstage drops the // store entirely — cs!=ww residual until the cstage half (#41). if (lc == nil) { - let gtn: *node = letvartnode(c, lhs.str); + let gtn: *syntax.node = letvartnode(c, lhs.str); if (gtn != nil) { if (istaggedtype(c, gtn)) { let gsz: i32 = slotsize(c, gtn); emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), BX\n"); - cgwidentaggedstore(c, gtn.type_: *tinfo, n.rhs, "BX", 0, gsz); + cgwidentaggedstore(c, gtn.type_: *syntax.tinfo, n.rhs, "BX", 0, gsz); return; }; }; @@ -32276,11 +32276,11 @@ fn cgassign(c: *cgen, n: *node) void = { // truncates to one word here — task #31 A/E/G; struct-lit // diverts at the placeslit gate, array-lit dies loud (#32). if (lhs != nil) { - if (lhs.kind == nkind.N_UN) { - if (lhs.op == tkind.TK_STAR) { - if (n.op == tkind.TK_ASSIGN && !placeslit + if (lhs.kind == syntax.nkind.N_UN) { + if (lhs.op == syntax.tkind.TK_STAR) { + if (n.op == syntax.tkind.TK_ASSIGN && !placeslit && !derefagg) { - let inner: *node = lhs.lhs; + let inner: *syntax.node = lhs.lhs; // #17: tagged-union pointee. The single-store // tail below writes rhs into the tag word only, // dropping the payload and corrupting the union. @@ -32290,8 +32290,8 @@ fn cgassign(c: *cgen, n: *node) void = { // word-copy scratch -> *p. Mirror of the runtime- // index tagged element arm (cgenexpr.ww:8768) and // the cstage twin (cmd/w6c/cgen.c #17 deref arm). - let du: *tinfo = tichase(lhs.type_: *tinfo); - if (du != nil && du.kind == tykind.TY_TAGGED) { + let du: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); + if (du != nil && du.kind == syntax.tykind.TY_TAGGED) { let ssz: i32 = du.size: i32; let scr: i32 = tagscradd(c, ssz); emitline("\tXORQ\tAX, AX\n"); @@ -32322,18 +32322,18 @@ fn cgassign(c: *cgen, n: *node) void = { let elemf32: bool = false; let storeop: str = "MOVQ"; if (inner != nil) { - if (inner.kind == nkind.N_IDENT) { + if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TPTR) { - let pe: *node = tn.lhs; + if (tn.kind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = tn.lhs; if (pe != nil) { - if (pe.kind == nkind.N_TNAME) { - if (streq(pe.str, "str")) { elemstr = true; } - else { if (streq(pe.str, "f64")) { elemfloat = true; } - else { if (streq(pe.str, "f32")) { elemfloat = true; elemf32 = true; } + if (pe.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(pe.str, "str")) { elemstr = true; } + else { if (syntax.streq(pe.str, "f64")) { elemfloat = true; } + else { if (syntax.streq(pe.str, "f32")) { elemfloat = true; elemf32 = true; } else { // primsize-ok (#101/#109): this site OWNS its own ps==0 // typenodeprimresolved chase below — routing through @@ -32366,7 +32366,7 @@ fn cgassign(c: *cgen, n: *node) void = { // deref-store stays 1-word, the SAME divergence // str carries; resolved-vs-syntactic detection // is unified UP in #80, not patched here. - if (pe.kind == nkind.N_TSLICE) { elemstr = true; }; + if (pe.kind == syntax.nkind.N_TSLICE) { elemstr = true; }; }; }; }; @@ -32431,8 +32431,8 @@ fn cgassign(c: *cgen, n: *node) void = { // no-op — exactly the trap that broke fmt.println). Mirror of // cmd/w6c/cgen.c's N_UN/TK_STAR compound branch. if (lhs != nil) { - if (lhs.kind == nkind.N_UN) { - if (lhs.op == tkind.TK_STAR) { + if (lhs.kind == syntax.nkind.N_UN) { + if (lhs.op == syntax.tkind.TK_STAR) { // Size gate (mirror cstage cgen.c handled=sz∈{1,2,4,8}): // a tagged (or any non-scalar) pointee is not a // meaningful compound target — skip this single-word @@ -32441,24 +32441,24 @@ fn cgassign(c: *cgen, n: *node) void = { // (#18). Without it the MOVQ default below clobbers the // tag word and returns: a silent miscompile. let psz: i32 = 8; - let lt: *tinfo = lhs.type_: *tinfo; + let lt: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (lt != nil) { psz = lt.size: i32; }; let scalarpointee: bool = (psz == 1 || psz == 2 || psz == 4 || psz == 8); - if (n.op != tkind.TK_ASSIGN && scalarpointee) { - let inner: *node = lhs.lhs; + if (n.op != syntax.tkind.TK_ASSIGN && scalarpointee) { + let inner: *syntax.node = lhs.lhs; let loadop: str = "MOVQ"; let storeop: str = "MOVQ"; // Pointee node for the lhs-sign side of the /= // and %= dispatch. Mirror of cstage's `vt` at // cmd/w6c/cgen.c's TK_STAR-compound branch. - let pe: *node = nil; + let pe: *syntax.node = nil; if (inner != nil) { - if (inner.kind == nkind.N_IDENT) { + if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TPTR) { + if (tn.kind == syntax.nkind.N_TPTR) { pe = tn.lhs; if (pe != nil) { let ps: i32 = fieldsize(c, pe); @@ -32488,12 +32488,12 @@ fn cgassign(c: *cgen, n: *node) void = { // RSHIFTEQ can route SHRQ vs SARQ on the same key. let unsignd: bool = false; if (pe != nil) { - unsignd = typeisunsigned(pe.type_: *tinfo); + unsignd = syntax.typeisunsigned(pe.type_: *syntax.tinfo); }; if (!unsignd) { unsignd = nodeisunsigned(c, n.rhs); }; - if (n.op == tkind.TK_SLASHEQ || n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ || n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); @@ -32501,7 +32501,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { emitline("\tMOVQ\tDX, AX\n"); }; emitline("\t"); @@ -32510,14 +32510,14 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; let combineop: str = "MOVQ"; - if (n.op == tkind.TK_PLUSEQ) { combineop = "ADDQ"; } - else { if (n.op == tkind.TK_MINUSEQ) { combineop = "SUBQ"; } - else { if (n.op == tkind.TK_STAREQ) { combineop = "IMULQ"; } - else { if (n.op == tkind.TK_AMPEQ) { combineop = "ANDQ"; } - else { if (n.op == tkind.TK_PIPEEQ) { combineop = "ORQ"; } - else { if (n.op == tkind.TK_CARETEQ) { combineop = "XORQ"; } - else { if (n.op == tkind.TK_LSHIFTEQ) { combineop = "SHLQ"; } - else { if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { combineop = "ADDQ"; } + else { if (n.op == syntax.tkind.TK_MINUSEQ) { combineop = "SUBQ"; } + else { if (n.op == syntax.tkind.TK_STAREQ) { combineop = "IMULQ"; } + else { if (n.op == syntax.tkind.TK_AMPEQ) { combineop = "ANDQ"; } + else { if (n.op == syntax.tkind.TK_PIPEEQ) { combineop = "ORQ"; } + else { if (n.op == syntax.tkind.TK_CARETEQ) { combineop = "XORQ"; } + else { if (n.op == syntax.tkind.TK_LSHIFTEQ) { combineop = "SHLQ"; } + else { if (n.op == syntax.tkind.TK_RSHIFTEQ) { // #136: signed RSHIFTEQ → SARQ. if (unsignd) { combineop = "SHRQ"; } else { combineop = "SARQ"; }; @@ -32537,20 +32537,20 @@ fn cgassign(c: *cgen, n: *node) void = { // Array/slice/ptr index store: `arr[i] = v;`. Element size // from base.tnode picks MOVB vs MOVQ. if (lhs != nil) { - if (lhs.kind == nkind.N_INDEX && !placeslit) { - if (n.op == tkind.TK_ASSIGN) { - let base: *node = lhs.lhs; - let idx: *node = lhs.rhs; + if (lhs.kind == syntax.nkind.N_INDEX && !placeslit) { + if (n.op == syntax.tkind.TK_ASSIGN) { + let base: *syntax.node = lhs.lhs; + let idx: *syntax.node = lhs.rhs; let esz: i32 = 8; let baselocal: *local = nil; let isglobalarr: bool = false; let isglobalptr: bool = false; let globalname: str; globalname.ptr = nil; globalname.len = 0; - let elemtn: *node = nil; + let elemtn: *syntax.node = nil; let basealias: bool = false; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal != nil) { @@ -32578,23 +32578,23 @@ fn cgassign(c: *cgen, n: *node) void = { // picks MOVB on the store arm, and the compound // arm's str/slice hard-error still fires on a // []str element). - let tn: *node = letvartnode(c, bn); + let tn: *syntax.node = letvartnode(c, bn); if (tn != nil) { globalname = bn; esz = elemsizeofc(c, tn); // idxelemtn: `*[N]T` drill, see the // local branch above (#61). elemtn = idxelemtn(tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; }; }; }; - } else { if (base.kind == nkind.N_DOT - || (base.kind == nkind.N_UN - && base.op == tkind.TK_STAR)) { + } else { if (base.kind == syntax.nkind.N_DOT + || (base.kind == syntax.nkind.N_UN + && base.op == syntax.tkind.TK_STAR)) { // lhs.type_ is the checker-stamped element tinfo // of the N_INDEX: esz is its natural size and the // tagged-element gate (below) reads the same @@ -32602,9 +32602,9 @@ fn cgassign(c: *cgen, n: *node) void = { // (#60/#72). cstage idx_eff(base->type)->sub->size // (cmd/w6c/cgen.c:3517-18). N_UN deref base // (`(*p)[i] = v`, #61 C): same stamped source. - let dt: *tinfo = lhs.type_: *tinfo; + let dt: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (dt != nil) { esz = dt.size: i32; elemtn = lhs; }; - } else { if (base.kind == nkind.N_INDEX) { + } else { if (base.kind == syntax.nkind.N_INDEX) { // Chained-write write-side parallel of the // cgindex N_INDEX-base arm (#24): `names[i][k] // = v` (names: **u8) — outer element is u8 so @@ -32615,7 +32615,7 @@ fn cgassign(c: *cgen, n: *node) void = { // (#69/#61d, mirror #60). cstage: esz = // idx_eff(base->type)->sub->size // (cmd/w6c/cgen.c:3517-3518). - let et: *tinfo = lhs.type_: *tinfo; + let et: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (et != nil) { esz = et.size: i32; elemtn = lhs; @@ -32630,13 +32630,13 @@ fn cgassign(c: *cgen, n: *node) void = { // cstage N_INDEX store reads idx_eff(base->type)->sub // uniformly (cmd/w6c/cgen.c:3517-3518). if (base != nil) { - if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; + if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; if (bt60 != nil) { - if (bt60.kind == tykind.TY_NAMED) { basealias = true; }; + if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; }; }; if (basealias) { - let et60: *tinfo = tichase(lhs.type_: *tinfo); + let et60: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); if (et60 != nil) { esz = et60.size: i32; elemtn = lhs; @@ -32644,9 +32644,9 @@ fn cgassign(c: *cgen, n: *node) void = { // see cgindex twin: cs-aligned, runtime- // unreachable until #77/#78 global DATA. if (isglobalarr || isglobalptr) { - let bu60: *tinfo = tichase(bt60); + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - isglobalarr = bu60.kind == tykind.TY_ARRAY; + isglobalarr = bu60.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; @@ -32673,7 +32673,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, elemtn.type_: *tinfo, n.rhs, + cgwidentaggedstore(c, elemtn.type_: *syntax.tinfo, n.rhs, "BP", scroff, slot_sz); cgexpr(c, idx); if (slot_sz > 1) { @@ -32691,18 +32691,18 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarr: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isarr = true; }; }; // #60: alias-NAMED base — chased kind // (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarr = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarr = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarr) { emitline("\tLEAQ\t"); @@ -32760,19 +32760,19 @@ fn cgassign(c: *cgen, n: *node) void = { // so the verdict is byte-identical to cstage's cg_sret_retsize. // The base-shape split below then loud-stops every non-local- // array form, base-kind-independent. - if (n.rhs != nil && n.rhs.kind == nkind.N_CALL + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL && callsretsize(c, n.rhs) > 0) { let islocalarr: bool = false; if (baselocal != nil) { - let btn: *node = baselocal.tnode; + let btn: *syntax.node = baselocal.tnode; if (btn != nil) { - if (btn.kind == nkind.N_TARRAY) { islocalarr = true; }; + if (btn.kind == syntax.nkind.N_TARRAY) { islocalarr = true; }; }; }; let constidx: bool = false; let cidx: i32 = 0; if (idx != nil) { - if (idx.kind == nkind.N_INTLIT) { + if (idx.kind == syntax.nkind.N_INTLIT) { constidx = true; cidx = idx.uval: i32; }; @@ -32799,18 +32799,18 @@ fn cgassign(c: *cgen, n: *node) void = { // element N_TTUPLE), in-cap. Mirror of cstage cgen.c #121 // store arm; the materialise + base-resolve are the // cglet / #270-1b byte-id twins. - if (n.rhs.kind == nkind.N_TUPLE && esz > 8 - && base != nil && base.kind == nkind.N_IDENT - && elemtn != nil && elemtn.kind == nkind.N_TTUPLE + if (n.rhs.kind == syntax.nkind.N_TUPLE && esz > 8 + && base != nil && base.kind == syntax.nkind.N_IDENT + && elemtn != nil && elemtn.kind == syntax.nkind.N_TTUPLE && sretretsize(c, elemtn) == 0) { let scr121: i32 = tagscradd(c, esz); cgtuplelittocursor(c, n.rhs, elemtn); let gpc: i32 = 0; let ssc: i32 = 0; let eo: i32 = 0; - let q121: *node = elemtn.list; + let q121: *syntax.node = elemtn.list; for (q121 != nil) { - let qt: *node = q121.lhs; + let qt: *syntax.node = q121.lhs; let isflt: bool = isfloattype(c, qt); let es: i32 = tupeslotn(qt); tupstore(c, gpc, ssc, scr121 + eo, es, qt); @@ -32837,12 +32837,12 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn2: *node = baselocal.tnode; + let tn2: *syntax.node = baselocal.tnode; let isarr2: bool = false; - if (tn2 != nil) { if (tn2.kind == nkind.N_TARRAY) { isarr2 = true; }; }; + if (tn2 != nil) { if (tn2.kind == syntax.nkind.N_TARRAY) { isarr2 = true; }; }; if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarr2 = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarr2 = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarr2) { emitline("\tLEAQ\t"); @@ -32885,10 +32885,10 @@ fn cgassign(c: *cgen, n: *node) void = { // — RAX-only store, task #31-G. esz>8 // non-str/non-slice IS a struct/array/tuple here (the // tagged element already returned above; floats are ≤8). - let aggsrc: bool = (n.rhs.kind == nkind.N_IDENT) - || (n.rhs.kind == nkind.N_DOT) - || (n.rhs.kind == nkind.N_UN - && n.rhs.op == tkind.TK_STAR); + let aggsrc: bool = (n.rhs.kind == syntax.nkind.N_IDENT) + || (n.rhs.kind == syntax.nkind.N_DOT) + || (n.rhs.kind == syntax.nkind.N_UN + && n.rhs.op == syntax.tkind.TK_STAR); if (esz > 8 && !isstrtype(c, elemtn) && !isslicetype(c, elemtn) && aggsrc) { cgexpr(c, idx); // idx → AX @@ -32908,13 +32908,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn2: *node = baselocal.tnode; + let tn2: *syntax.node = baselocal.tnode; let isarr2: bool = false; - if (tn2 != nil) { if (tn2.kind == nkind.N_TARRAY) { isarr2 = true; }; }; + if (tn2 != nil) { if (tn2.kind == syntax.nkind.N_TARRAY) { isarr2 = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarr2 = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarr2 = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarr2) { emitline("\tLEAQ\t"); @@ -32935,11 +32935,11 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tADDQ\tAX, BX\n"); emitline("\tPUSHQ\tBX\n"); // spill dest // rhs source address → SI - if (n.rhs.kind == nkind.N_UN - && n.rhs.op == tkind.TK_STAR) { + if (n.rhs.kind == syntax.nkind.N_UN + && n.rhs.op == syntax.tkind.TK_STAR) { cgexpr(c, n.rhs.lhs); emitline("\tMOVQ\tAX, SI\n"); - } else { if (n.rhs.kind == nkind.N_IDENT) { + } else { if (n.rhs.kind == syntax.nkind.N_IDENT) { let sl: *local = localfindnode(c, n.rhs.str); if (sl != nil) { emitline("\tLEAQ\t"); @@ -33040,13 +33040,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; - if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; }; + if (tn != nil) { if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarray) { emitline("\tLEAQ\t"); @@ -33121,18 +33121,18 @@ fn cgassign(c: *cgen, n: *node) void = { // unwired — cstage's compound template never carried // those payload kinds. Same shape gate as the cstage // branch (cgen.c #133). - if (n.op != tkind.TK_ASSIGN) { - let base: *node = lhs.lhs; - let idx: *node = lhs.rhs; + if (n.op != syntax.tkind.TK_ASSIGN) { + let base: *syntax.node = lhs.lhs; + let idx: *syntax.node = lhs.rhs; let esz: i32 = 8; let baselocal: *local = nil; let isglobalarr: bool = false; let isglobalptr: bool = false; let globalname: str; globalname.ptr = nil; globalname.len = 0; - let elemtn: *node = nil; + let elemtn: *syntax.node = nil; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal != nil) { @@ -33160,29 +33160,29 @@ fn cgassign(c: *cgen, n: *node) void = { // picks MOVB on the store arm, and the compound // arm's str/slice hard-error still fires on a // []str element). - let tn: *node = letvartnode(c, bn); + let tn: *syntax.node = letvartnode(c, bn); if (tn != nil) { globalname = bn; esz = elemsizeofc(c, tn); // idxelemtn: `*[N]T` drill, see the // local branch above (#61). elemtn = idxelemtn(tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; }; }; }; - } else { if (base.kind == nkind.N_DOT - || (base.kind == nkind.N_UN - && base.op == tkind.TK_STAR)) { + } else { if (base.kind == syntax.nkind.N_DOT + || (base.kind == syntax.nkind.N_UN + && base.op == syntax.tkind.TK_STAR)) { // N_UN deref base (`(*p)[i] OP= v`, #61 C): // same stamped source as the store arm. - let dt: *tinfo = lhs.type_: *tinfo; + let dt: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (dt != nil) { esz = dt.size: i32; elemtn = lhs; }; - } else { if (base.kind == nkind.N_INDEX) { - let et: *tinfo = lhs.type_: *tinfo; + } else { if (base.kind == syntax.nkind.N_INDEX) { + let et: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (et != nil) { esz = et.size: i32; elemtn = lhs; @@ -33193,21 +33193,21 @@ fn cgassign(c: *cgen, n: *node) void = { // same stamped-element adoption as the store arm. let basealias: bool = false; if (base != nil) { - if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; + if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; if (bt60 != nil) { - if (bt60.kind == tykind.TY_NAMED) { basealias = true; }; + if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; }; }; if (basealias) { - let et60: *tinfo = tichase(lhs.type_: *tinfo); + let et60: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); if (et60 != nil) { esz = et60.size: i32; elemtn = lhs; }; if (isglobalarr || isglobalptr) { - let bu60: *tinfo = tichase(bt60); + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - isglobalarr = bu60.kind == tykind.TY_ARRAY; + isglobalarr = bu60.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; @@ -33257,13 +33257,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; - if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; }; + if (tn != nil) { if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarray) { emitline("\tLEAQ\t"); @@ -33295,29 +33295,29 @@ fn cgassign(c: *cgen, n: *node) void = { let unsignd_c: bool = false; if (elemtn != nil) { if (elemtn.type_ != nil) { - unsignd_c = typeisunsigned(elemtn.type_: *tinfo); + unsignd_c = syntax.typeisunsigned(elemtn.type_: *syntax.tinfo); }; }; let wired: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd_c) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd_c) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd_c) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired = true; @@ -33345,30 +33345,30 @@ fn cgassign(c: *cgen, n: *node) void = { // N_INDEX-lhs branch above handles bare `arr[i] = v`, not the // field write). if (lhs != nil) { - if (lhs.kind == nkind.N_DOT && lhs.lhs != nil - && lhs.lhs.kind == nkind.N_INDEX && !placeslit) { - let idxbase: *node = lhs.lhs.lhs; - let idx: *node = lhs.lhs.rhs; + if (lhs.kind == syntax.nkind.N_DOT && lhs.lhs != nil + && lhs.lhs.kind == syntax.nkind.N_INDEX && !placeslit) { + let idxbase: *syntax.node = lhs.lhs.lhs; + let idx: *syntax.node = lhs.lhs.rhs; let fld2: str = lhs.str; - if (idxbase != nil) { if (idxbase.kind == nkind.N_IDENT) { + if (idxbase != nil) { if (idxbase.kind == syntax.nkind.N_IDENT) { if (idx != nil) { let lc: *local = localfindnode(c, idxbase.str); if (lc != nil) { if (lc.tnode != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; // idxelemtn: `*[N]T` drills to the pointee // array's element (#61). - let elemt: *node = idxelemtn(tn); - let baseisarray: bool = tn.kind == nkind.N_TARRAY; - let snode: *node = nil; + let elemt: *syntax.node = idxelemtn(tn); + let baseisarray: bool = tn.kind == syntax.nkind.N_TARRAY; + let snode: *syntax.node = nil; let viaptr: bool = false; if (elemt != nil) { - if (elemt.kind == nkind.N_TPTR) { - let inner: *node = elemt.lhs; - if (inner != nil) { if (inner.kind == nkind.N_TNAME) { + if (elemt.kind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = elemt.lhs; + if (inner != nil) { if (inner.kind == syntax.nkind.N_TNAME) { snode = inner; viaptr = true; };}; - } else { if (elemt.kind == nkind.N_TNAME) { + } else { if (elemt.kind == syntax.nkind.N_TNAME) { snode = elemt; };}; }; @@ -33387,12 +33387,12 @@ fn cgassign(c: *cgen, n: *node) void = { if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld2)) { + if (syntax.streq(fi.fname, fld2)) { let esz: i32 = elemsizeofc(c, tn); // f64/f32: rhs in X0. Spill to stack, // compute &arr[i] in BX (deref if *T), // then reload X0 and MOVSD/MOVSS. - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { if (isfloattype(c, fi.tnode)) { let mov: str = "MOVSD"; if (isf32type(c, fi.tnode)) { mov = "MOVSS"; }; @@ -33520,7 +33520,7 @@ fn cgassign(c: *cgen, n: *node) void = { os.write(2, m58m.ptr, m58m.len: u64); os.exit(1); }; - if (typeisfloat(n.rhs.type_: *tinfo)) { + if (syntax.typeisfloat(n.rhs.type_: *syntax.tinfo)) { let m58f: str = "#58: float-payload tagged-field indexed store unreachable until #114\n"; os.write(2, m58f.ptr, m58f.len: u64); os.exit(1); @@ -33546,7 +33546,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tADDQ\tAX, BX\n"); if (viaptr) { emitline("\tMOVQ\t(BX), BX\n"); }; emitline("\tPOPQ\tAX\n"); - let v58tag: i32 = taggedvariantindext(c, fi.tnode.type_: *tinfo, n.rhs); + let v58tag: i32 = taggedvariantindext(c, fi.tnode.type_: *syntax.tinfo, n.rhs); if (v58tag < 0) { v58tag = 0; }; emitline("\tMOVQ\t$"); emitint(v58tag: i64); @@ -33650,29 +33650,29 @@ fn cgassign(c: *cgen, n: *node) void = { let unsignd_x: bool = false; if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { - unsignd_x = typeisunsigned(fi.tnode.type_: *tinfo); + unsignd_x = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; let wired_x: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd_x) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired_x = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd_x) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd_x) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired_x = true; @@ -33706,33 +33706,33 @@ fn cgassign(c: *cgen, n: *node) void = { // by retargeting to the inner IDENT so the via_ptr branch fires // the same as auto-deref `p.f = v`. v1 scope: bare-IDENT inner. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; if (base != nil) { - if (base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR) { + if (base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR) { if (base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { base = base.lhs; }; }; }; }; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; let lc: *local = localfindnode(c, bn); if (lc != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = nkind.N_NONE; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = syntax.nkind.N_NONE; if (tn != nil) { lkind = tn.kind; }; // Pointer-to-struct: deref then store. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; let sname: str; sname.ptr = nil; sname.len = 0; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; if (sname.len > 0) { // structlookupchain (#22) handles the @@ -33743,18 +33743,18 @@ fn cgassign(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // Tagged-union field via *struct base — full slot // rewrite via cgwidentaggedstore basereg="BX". Pre-#26 // fell through to the scalar store and dropped tag // + payload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && istaggedtype(c, fi.tnode)) { let fsz: i32 = slotsize(c, fi.tnode); emitline("\tMOVQ\t"); emitoff(lc.off: i64); emitline("(BP), BX\n"); - cgwidentaggedstore(c, fi.tnode.type_: *tinfo, + cgwidentaggedstore(c, fi.tnode.type_: *syntax.tinfo, n.rhs, "BX", fi.foff, fsz); return; }; @@ -33762,9 +33762,9 @@ fn cgassign(c: *cgen, n: *node) void = { // be a runtime RDI pointer (the BP-relative c.sretdestoff // can't name `p.f`); deferred. HARD-STOP loud, never fall // through to the truncating generic store (rule 7). - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && sretretsize(c, fi.tnode) > 0) { let m234: str = "#234-tail: over-cap tuple sret store to via-ptr field dest unsupported\n"; os.write(2, m234.ptr, m234.len: u64); @@ -33783,11 +33783,11 @@ fn cgassign(c: *cgen, n: *node) void = { // granularity — size via structabisize (cstage // SSoT lu->size, check.c:760; cgen.c:7720 // sz=lu->size at the receive twin). - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -33838,11 +33838,11 @@ fn cgassign(c: *cgen, n: *node) void = { // its trailing bytes. mode=1 (DST_PTR_LOCAL) reloads BX // from lc.off(BP) before zero-fill and before every // field store. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -33851,11 +33851,11 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); let srhs: *local = localfindnode(c, n.rhs.str); @@ -33904,7 +33904,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; };}; }; - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // compound: load current value emitline("\tMOVQ\t"); emitoff(lc.off: i64); @@ -33918,17 +33918,17 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPUSHQ\tBX\n"); }; cgexpr(c, n.rhs); - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { emitline("\tPOPQ\tBX\n"); // PLUSEQ is commutative; MINUSEQ // needs lhs - rhs (BX is old lhs, // AX is rhs). cgdotfieldhardstop(c, fi.tnode); let uns34: bool = false; - if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = typeisunsigned(fi.tnode.type_: *tinfo); }; }; + if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; cgdotfieldcombine(c, n.op, uns34); }; - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { // str/slice field via *struct: str IS []u8, so both // store the full 3-word {ptr,len,cap} from (AX,BX,CX). // CX holds cap, so stage the struct addr in DX and @@ -33981,7 +33981,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; // Direct struct local: store at off+foff. - if (lkind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { // structlookupchain (#22) — same shape // as the cgdot direct-local read site. let si: *structinfo = structlookupchain(c, tn); @@ -33989,15 +33989,15 @@ fn cgassign(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // Tagged-union field in a direct struct local — // full slot rewrite at (lc.off + fi.foff)(BP) // via cgwidentaggedstore basereg="BP". Pre-#26 // fell through and dropped tag + payload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && istaggedtype(c, fi.tnode)) { let fsz: i32 = slotsize(c, fi.tnode); - cgwidentaggedstore(c, fi.tnode.type_: *tinfo, + cgwidentaggedstore(c, fi.tnode.type_: *syntax.tinfo, n.rhs, "BP", lc.off + fi.foff, fsz); return; }; @@ -34009,9 +34009,9 @@ fn cgassign(c: *cgen, n: *node) void = { // (c.sretdestoff = lc.off + fi.foff) so it writes the // WHOLE value there, never the truncating generic store // below. Mirror of cstage cgen.c (#234) field local arm. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && sretretsize(c, fi.tnode) > 0) { c.sretdestoff = lc.off + fi.foff; cgexpr(c, n.rhs); @@ -34027,11 +34027,11 @@ fn cgassign(c: *cgen, n: *node) void = { // N_STRUCTLIT: field-walk; each inner // field stored at +fi.foff+inner_foff(BP). // BP-rel direct, no addr scratch needed. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -34078,11 +34078,11 @@ fn cgassign(c: *cgen, n: *node) void = { // typed structlit value recurses instead of dropping // its trailing bytes. mode=0 (DST_BP) — direct BP-rel, // no BX reload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -34091,11 +34091,11 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); let srhs: *local = localfindnode(c, n.rhs.str); @@ -34141,7 +34141,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; };}; }; - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // Compound on direct struct-local // scalar field: load current → push // → eval rhs → combine → store @@ -34155,13 +34155,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPUSHQ\tBX\n"); }; cgexpr(c, n.rhs); - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { emitline("\tPOPQ\tBX\n"); // PLUSEQ commutes; MINUSEQ needs // lhs-rhs (BX old lhs, AX rhs). cgdotfieldhardstop(c, fi.tnode); let uns34: bool = false; - if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = typeisunsigned(fi.tnode.type_: *tinfo); }; }; + if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; cgdotfieldcombine(c, n.op, uns34); }; // str/slice field direct: str IS []u8, so both store the @@ -34205,21 +34205,21 @@ fn cgassign(c: *cgen, n: *node) void = { }; // str/slice pseudo-field assignment. let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; - let innerkind: nkind = nkind.N_NONE; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; + let innerkind: syntax.nkind = syntax.nkind.N_NONE; if (inner != nil) { innerkind = inner.kind; }; let innerstr: bool = false; - if (innerkind == nkind.N_TNAME) { - if (streq(inner.str, "str")) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TNAME) { + if (syntax.streq(inner.str, "str")) { innerstr = true; }; }; - if (innerkind == nkind.N_TSLICE) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TSLICE) { innerstr = true; }; if (innerstr) { - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // Compound on `(*str|*slice).field`: load // current → push → eval rhs → combine → store. emitline("\tMOVQ\t"); @@ -34252,7 +34252,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // Compound on local `str|slice` pseudo-field: // load current → push → eval rhs → combine → // store (mirror cgen.c:3235 local arm). @@ -34287,25 +34287,25 @@ fn cgassign(c: *cgen, n: *node) void = { // follows the same load → push → eval → combine → store shape // as the via-ptr local path. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; if (localfindnode(c, bn) == nil) { let si: *structinfo = letvarstructinfo(c, bn); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { // #234-tail: GLOBAL (`g.f`) sret field STORE. c.sretdestoff is // BP-relative only and can't name a global slot; the runtime // RDI-pointer dest variant is deferred. HARD-STOP loud, never // the truncating generic store (rule 7). - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && sretretsize(c, fi.tnode) > 0) { let m234: str = "#234-tail: over-cap tuple sret store to global field dest unsupported\n"; os.write(2, m234.ptr, m234.len: u64); @@ -34318,11 +34318,11 @@ fn cgassign(c: *cgen, n: *node) void = { // N_CALL: cgexpr → AX/DX/CX; LEAQ base into BX // after call, sized stores per natural size. // N_STRUCTLIT: field-walk; reload BX per store. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -34373,11 +34373,11 @@ fn cgassign(c: *cgen, n: *node) void = { // its trailing bytes. mode=2 (DST_GLOBAL) reloads BX // via LEAQ bn(SB) before zero-fill and before every // field store. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -34386,11 +34386,11 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); let srhs: *local = localfindnode(c, n.rhs.str); @@ -34445,18 +34445,18 @@ fn cgassign(c: *cgen, n: *node) void = { // is_global arm. Without this the generic TK_ASSIGN // below truncates to 1 word, silently dropping tag // and payload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && istaggedtype(c, fi.tnode)) { let fsz: i32 = slotsize(c, fi.tnode); emitline("\tLEAQ\t"); emitsymname(c, bn); emitline("(SB), BX\n"); cgwidentaggedstore(c, - fi.tnode.type_: *tinfo, + fi.tnode.type_: *syntax.tinfo, n.rhs, "BX", fi.foff, fsz); return; }; - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { cgexpr(c, n.rhs); if (isstrtype(c, fi.tnode) || isslicetype(c, fi.tnode)) { // str OR slice field: str IS []u8, so @@ -34526,7 +34526,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPOPQ\tBX\n"); cgdotfieldhardstop(c, fi.tnode); let uns34: bool = false; - if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = typeisunsigned(fi.tnode.type_: *tinfo); }; }; + if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; cgdotfieldcombine(c, n.op, uns34); let sop: str = fieldstoreop(c, fi); emitline("\tLEAQ\t"); @@ -34556,11 +34556,11 @@ fn cgassign(c: *cgen, n: *node) void = { // store. Only plain `=` is wired here; chained compound on a // pointer-field hasn't surfaced. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; if (base != nil) { - if (base.kind == nkind.N_DOT) { + if (base.kind == syntax.nkind.N_DOT) { // #70 (#12): inner-struct layout via the stamped // base.type_ (peel *→struct) + tinfo.fields, // replacing dotinnerstructptr's structinfo walk. @@ -34572,35 +34572,35 @@ fn cgassign(c: *cgen, n: *node) void = { // exactly avoids an untested widening past cstage. // Global-root chains stay in their pre-existing shared // base-eval breakage (filed #27). - let croot: *node = base; + let croot: *syntax.node = base; let allptr: bool = true; - for (croot != nil && croot.kind == nkind.N_DOT) { - let ct: *tinfo = croot.type_: *tinfo; + for (croot != nil && croot.kind == syntax.nkind.N_DOT) { + let ct: *syntax.tinfo = croot.type_: *syntax.tinfo; ct = tichase(ct); let okp: bool = false; - if (ct != nil) { if (ct.kind == tykind.TY_PTR) { - let cs: *tinfo = ct.sub; + if (ct != nil) { if (ct.kind == syntax.tykind.TY_PTR) { + let cs: *syntax.tinfo = ct.sub; cs = tichase(cs); - if (cs != nil) { if (cs.kind == tykind.TY_STRUCT) { okp = true; }; }; + if (cs != nil) { if (cs.kind == syntax.tykind.TY_STRUCT) { okp = true; }; }; }; }; if (!okp) { allptr = false; }; croot = croot.lhs; }; - let it: *tinfo = nil; - if (allptr && croot != nil && croot.kind == nkind.N_IDENT && + let it: *syntax.tinfo = nil; + if (allptr && croot != nil && croot.kind == syntax.nkind.N_IDENT && localfindnode(c, croot.str) != nil) { - it = base.type_: *tinfo; + it = base.type_: *syntax.tinfo; }; it = tichase(it); - if (it != nil) { if (it.kind == tykind.TY_PTR) { - let st: *tinfo = it.sub; + if (it != nil) { if (it.kind == syntax.tykind.TY_PTR) { + let st: *syntax.tinfo = it.sub; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { - let tf: *tfield = st.fields; + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { + let tf: *syntax.tfield = st.fields; for (tf != nil) { - if (streq(tf.name, fld)) { - let ft: *tinfo = tf.type_; - if (n.op == tkind.TK_ASSIGN) { + if (syntax.streq(tf.name, fld)) { + let ft: *syntax.tinfo = tf.type_; + if (n.op == syntax.tkind.TK_ASSIGN) { // tagged leaf (#38a): eval the *struct // base into BX, then the shared widener // (it spills BX across its internal @@ -34609,8 +34609,8 @@ fn cgassign(c: *cgen, n: *node) void = { // scalar tail below stored ONE sized // word at the field offset: the rhs // landed in the TAG slot (ken b8). - if (typeistagged(ft)) { - let flu: *tinfo = ft; + if (syntax.typeistagged(ft)) { + let flu: *syntax.tinfo = ft; flu = tichase(flu); cgexpr(c, base); emitline("\tMOVQ\tAX, BX\n"); @@ -34619,7 +34619,7 @@ fn cgassign(c: *cgen, n: *node) void = { flu.size: i32); return; }; - if (typeisstr(ft) || typeisslice(ft)) { + if (syntax.typeisstr(ft) || syntax.typeisslice(ft)) { // str/slice: rhs leaves AX=ptr, // BX=len, CX=cap (#1/Phase 3). Spill // all three across the base-expr eval @@ -34651,9 +34651,9 @@ fn cgassign(c: *cgen, n: *node) void = { // f64/f32 chained plain `=`: cgexpr rhs left value in // X0. Spill to stack so cgexpr(base) can use AX, then // reload and MOVSD/MOVSS into the slot. - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; cgexpr(c, n.rhs); emitline("\tSUBQ\t$8, SP\n"); emitline("\t"); @@ -34698,23 +34698,23 @@ fn cgassign(c: *cgen, n: *node) void = { // float/str/slice/tagged field-type // hard-errors LOUD. Signed RSHIFTEQ uses // SARQ (signed) or SHRQ (unsigned) per #136. - if (n.op != tkind.TK_ASSIGN) { - if (typeisstr(ft)) { + if (n.op != syntax.tkind.TK_ASSIGN) { + if (syntax.typeisstr(ft)) { let m: str = "chained-ptr-field compound on str element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (typeisslice(ft)) { + if (syntax.typeisslice(ft)) { let m: str = "chained-ptr-field compound on slice element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let m: str = "chained-ptr-field compound on float element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (typeistagged(ft)) { + if (syntax.typeistagged(ft)) { let m: str = "chained-ptr-field compound on tagged element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -34724,7 +34724,7 @@ fn cgassign(c: *cgen, n: *node) void = { cgexpr(c, base); emitline("\tPUSHQ\tAX\n"); let fsz: i32 = ft.slotsize: i32; - let unsignd_f: bool = typeisunsigned(ft); + let unsignd_f: bool = syntax.typeisunsigned(ft); let lopf: str = loadopsz(!unsignd_f, fsz); emitline("\t"); emitline(lopf); @@ -34734,25 +34734,25 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPOPQ\tBX\n"); emitline("\tPOPQ\tCX\n"); let wired_f: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd_f) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired_f = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd_f) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd_f) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired_f = true; @@ -34786,13 +34786,13 @@ fn cgassign(c: *cgen, n: *node) void = { // the slice/str pseudo-field write through a value-struct chain // silently emit no store. Only plain `=` is wired. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT && lhs.lhs != nil - && lhs.lhs.kind == nkind.N_DOT - && n.op == tkind.TK_ASSIGN) { + if (lhs.kind == syntax.nkind.N_DOT && lhs.lhs != nil + && lhs.lhs.kind == syntax.nkind.N_DOT + && n.op == syntax.tkind.TK_ASSIGN) { let rootname: str = ""; let rootoff: i32 = 0; let totaloff: i32 = 0; - let leaftype: *tinfo = nil; + let leaftype: *syntax.tinfo = nil; let slicedelta: i32 = -1; let isglobal: bool = false; let ptrroot: bool = false; @@ -34834,8 +34834,8 @@ fn cgassign(c: *cgen, n: *node) void = { // kept its old bytes (ken x5d: `o.r.min = 8: size` left // `is size` false). Only plain `=` reaches this walker // (TK_ASSIGN gate above). - if (typeistagged(leaftype)) { - let wlu: *tinfo = leaftype; + if (syntax.typeistagged(leaftype)) { + let wlu: *syntax.tinfo = leaftype; wlu = tichase(wlu); let wtsz: i32 = wlu.size: i32; if (viacx) { @@ -34856,7 +34856,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; return; }; - if (typeisstr(leaftype) || typeisslice(leaftype)) { + if (syntax.typeisstr(leaftype) || syntax.typeisslice(leaftype)) { // str/slice: store ptr/len/cap. cgexpr leaves // CX=cap, so the viacx base goes in DX (not CX) to // avoid clobbering it — same as the single-dot str @@ -34921,17 +34921,17 @@ fn cgassign(c: *cgen, n: *node) void = { let leafstruct: bool = false; let leafname: str = ""; if (leaftype != nil) { - let lp: *tinfo = leaftype; + let lp: *syntax.tinfo = leaftype; lp = tichase(lp); if (lp != nil) { - if (lp.kind == tykind.TY_STRUCT) { leafstruct = true; }; + if (lp.kind == syntax.tykind.TY_STRUCT) { leafstruct = true; }; }; - if (leaftype.kind == tykind.TY_NAMED) { + if (leaftype.kind == syntax.tykind.TY_NAMED) { leafname = leaftype.name; }; }; if (n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && leafstruct) { let lsi: *structinfo = structlookup(c, leafname); if (lsi != nil) { @@ -35015,7 +35015,7 @@ fn cgassign(c: *cgen, n: *node) void = { // LEAQ rootname(SB). // else → mode=0 (DST_BP), direct BP-rel, no reload. if (n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && leafstruct) { let lsi: *structinfo = structlookup(c, leafname); if (lsi != nil) { @@ -35036,7 +35036,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; if (n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && leafstruct) { let ssi: *structinfo = structlookup(c, leafname); let srhs: *local = localfindnode(c, n.rhs.str); @@ -35117,9 +35117,9 @@ fn cgassign(c: *cgen, n: *node) void = { return; };}; }; - if (typeisfloat(leaftype)) { + if (syntax.typeisfloat(leaftype)) { let mov: str = "MOVSD"; - if (typeisf32(leaftype)) { mov = "MOVSS"; }; + if (syntax.typeisf32(leaftype)) { mov = "MOVSS"; }; cgexpr(c, n.rhs); if (viacx) { if (ptrroot) { @@ -35192,24 +35192,24 @@ fn cgassign(c: *cgen, n: *node) void = { // Kept as fallback below the generalized walker for any shape // the walker doesn't recognize. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; - if (base != nil) { if (base.kind == nkind.N_DOT) { - let inner: *node = base.lhs; + if (base != nil) { if (base.kind == syntax.nkind.N_DOT) { + let inner: *syntax.node = base.lhs; let innerfld: str = base.str; - if (inner != nil) { if (inner.kind == nkind.N_IDENT) { + if (inner != nil) { if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { if (lc.tnode != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = tn.kind; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = tn.kind; let outname: str; outname.ptr = nil; outname.len = 0; let isptr: bool = false; - if (lkind == nkind.N_TNAME) { outname = tn.str; }; - if (lkind == nkind.N_TPTR) { - let pe: *node = tn.lhs; - if (pe != nil) { if (pe.kind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { outname = tn.str; }; + if (lkind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = tn.lhs; + if (pe != nil) { if (pe.kind == syntax.nkind.N_TNAME) { outname = pe.str; isptr = true; };}; @@ -35219,16 +35219,16 @@ fn cgassign(c: *cgen, n: *node) void = { if (osi != nil) { let ofi: *fieldinfo = osi.fields; for (ofi != nil) { - if (streq(ofi.fname, innerfld)) { - let oft: *node = ofi.tnode; - if (oft != nil) { if (oft.kind == nkind.N_TNAME) { + if (syntax.streq(ofi.fname, innerfld)) { + let oft: *syntax.node = ofi.tnode; + if (oft != nil) { if (oft.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, oft.str) == 0) { let isi: *structinfo = structlookup(c, oft.str); if (isi != nil) { let ffi: *fieldinfo = isi.fields; for (ffi != nil) { - if (streq(ffi.fname, fld)) { - if (n.op == tkind.TK_ASSIGN) { + if (syntax.streq(ffi.fname, fld)) { + if (n.op == syntax.tkind.TK_ASSIGN) { let totoff: i32 = ofi.foff + ffi.foff; cgexpr(c, n.rhs); if (isstrtype(c, ffi.tnode)) { @@ -35312,7 +35312,7 @@ fn cgassign(c: *cgen, n: *node) void = { // forms (+= -= *= /=); other compounds fall back to // "evaluate rhs, replace". Mirrors C cgen's IDENT-assign path. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let nm: str = lhs.str; let off: i32 = localfind(c, nm); if (off == 0) { @@ -35341,9 +35341,9 @@ fn cgassign(c: *cgen, n: *node) void = { let lvf: *letvar = c.lets; let isfg: bool = false; let isf32g: bool = false; - let lvftn: *node = nil; + let lvftn: *syntax.node = nil; for (lvf != nil) { - if (streq(lvf.name, nm)) { + if (syntax.streq(lvf.name, nm)) { isfg = isfloattype(c, lvf.tnode); isf32g = isf32type(c, lvf.tnode); lvftn = lvf.tnode; @@ -35369,7 +35369,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tLEAQ\t"); emitsymname(c, nm); emitline("(SB), CX\n"); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { emitline("\t"); emitline(mov); emitline("\tX0, (CX)\n"); @@ -35380,10 +35380,10 @@ fn cgassign(c: *cgen, n: *node) void = { // only, so we can't combine direct to memory. let fop: str; fop.ptr = nil; fop.len = 0; - if (n.op == tkind.TK_PLUSEQ) { fop = addf; }; - if (n.op == tkind.TK_MINUSEQ) { fop = subf; }; - if (n.op == tkind.TK_STAREQ) { fop = mulf; }; - if (n.op == tkind.TK_SLASHEQ) { fop = divf; }; + if (n.op == syntax.tkind.TK_PLUSEQ) { fop = addf; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { fop = subf; }; + if (n.op == syntax.tkind.TK_STAREQ) { fop = mulf; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { fop = divf; }; if (fop.len == 0) { // Unsupported (e.g., %= on float): // fall back to plain store of rhs. @@ -35409,15 +35409,15 @@ fn cgassign(c: *cgen, n: *node) void = { // into g's storage. The scalar store below would emit a // truncated `MOVQ AX, g(SB)` and drop the body. Mirror // of the C cgen N_ASSIGN global arm (cmd/w6c/cgen.c). - if (n.op == tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL && lvftn != nil) { + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil + && n.rhs.kind == syntax.nkind.N_CALL && lvftn != nil) { let gsz: i32 = 0; - if (lvftn.kind == nkind.N_TNAME) { + if (lvftn.kind == syntax.nkind.N_TNAME) { let gsi: *structinfo = structlookup(c, lvftn.str); if (gsi != nil) { gsz = structabisize(gsi); }; }; - if (lvftn.kind == nkind.N_TARRAY) { - let gat: *tinfo = lvftn.type_: *tinfo; + if (lvftn.kind == syntax.nkind.N_TARRAY) { + let gat: *syntax.tinfo = lvftn.type_: *syntax.tinfo; gat = tichase(gat); if (gat != nil) { gsz = gat.size: i32; }; }; @@ -35442,11 +35442,11 @@ fn cgassign(c: *cgen, n: *node) void = { // behaviour — no consumer (rule-10 aligned with cstage; // note non-float struct globals also truncate symmetrically // here, byte-id-clean — #276 covers both). - if (n.op == tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL && lvftn != nil - && lvftn.kind == nkind.N_TARRAY) { + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil + && n.rhs.kind == syntax.nkind.N_CALL && lvftn != nil + && lvftn.kind == syntax.nkind.N_TARRAY) { let aggsz: i32 = 0; - let aat: *tinfo = lvftn.type_: *tinfo; + let aat: *syntax.tinfo = lvftn.type_: *syntax.tinfo; aat = tichase(aat); if (aat != nil) { aggsz = aat.size: i32; }; if (aggsz > 0 && aggsz <= 24) { @@ -35488,16 +35488,16 @@ fn cgassign(c: *cgen, n: *node) void = { // addressable rhs → aggargsrcaddr + LEAQ g(SB), BX // + aggcopy. Pre-#49 every shape fell to the scalar // tail below: one MOVQ AX, g(SB). - if (n.op == tkind.TK_ASSIGN && lvftn != nil) { - let gau: *tinfo = lvftn.type_: *tinfo; + if (n.op == syntax.tkind.TK_ASSIGN && lvftn != nil) { + let gau: *syntax.tinfo = lvftn.type_: *syntax.tinfo; gau = tichase(gau); if (gau != nil) { - if (gau.kind == tykind.TY_STRUCT - || gau.kind == tykind.TY_ARRAY - || gau.kind == tykind.TY_TUPLE) { - if (n.rhs != nil && n.rhs.kind == nkind.N_STRUCTLIT) { + if (gau.kind == syntax.tykind.TY_STRUCT + || gau.kind == syntax.tykind.TY_ARRAY + || gau.kind == syntax.tykind.TY_TUPLE) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_STRUCTLIT) { let gsi49: *structinfo = nil; - if (lvftn.kind == nkind.N_TNAME) { + if (lvftn.kind == syntax.nkind.N_TNAME) { gsi49 = structlookup(c, lvftn.str); }; if (gsi49 == nil) { @@ -35510,7 +35510,7 @@ fn cgassign(c: *cgen, n: *node) void = { cgstructlitfill(c, gsi49, n.rhs, 2, 0, nm, 0); return; }; - if (n.rhs != nil && n.rhs.kind == nkind.N_CALL) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL) { let m49e: str = "assign: aggregate call receive shape unwired (task #49/#276/rule-7)\n"; os.write(2, m49e.ptr, m49e.len: u64); os.exit(1); @@ -35529,7 +35529,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; cgexpr(c, n.rhs); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { // str/slice top-level let: str IS []u8, so both store the // full 3-word {ptr,len,cap}. Stash cap in DI before LEAQ // overwrites CX, then store ptr/len/cap via &name(SB) @@ -35554,7 +35554,7 @@ fn cgassign(c: *cgen, n: *node) void = { // a prior `*(&letname): *iN` deref-store doesn't // leave stale upper bytes feeding the combine. let glop: str = localloadop(c, lvftn); - if (streq(glop, "MOVQ")) { + if (syntax.streq(glop, "MOVQ")) { emitline("\tMOVQ\t"); emitsymname(c, nm); emitline("(SB), BX\n"); @@ -35567,22 +35567,22 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\t(CX), BX\n"); }; let didcompound: bool = true; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_LSHIFTEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tSHLQ\tCX, BX\n"); } - else { if (n.op == tkind.TK_RSHIFTEQ) { + else { if (n.op == syntax.tkind.TK_RSHIFTEQ) { // #136: signed RSHIFTEQ → SARQ. let unsignd_r: bool = false; if (lvftn != nil) { if (lvftn.type_ != nil) { - unsignd_r = typeisunsigned(lvftn.type_: *tinfo); + unsignd_r = syntax.typeisunsigned(lvftn.type_: *syntax.tinfo); }; }; if (!unsignd_r) { @@ -35598,10 +35598,10 @@ fn cgassign(c: *cgen, n: *node) void = { // CQO (or zero DX), IDIVQ (or DIVQ) CX, // ferry AX or DX back to BX for the shared // store-BX tail below. - else { if (n.op == tkind.TK_SLASHEQ || n.op == tkind.TK_PERCENTEQ) { + else { if (n.op == syntax.tkind.TK_SLASHEQ || n.op == syntax.tkind.TK_PERCENTEQ) { let unsignd: bool = false; if (lvftn != nil) { - unsignd = typeisunsigned(lvftn.type_: *tinfo); + unsignd = syntax.typeisunsigned(lvftn.type_: *syntax.tinfo); }; if (!unsignd) { unsignd = nodeisunsigned(c, n.rhs); @@ -35615,7 +35615,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ) { emitline("\tMOVQ\tAX, BX\n"); } else { emitline("\tMOVQ\tDX, BX\n"); @@ -35644,9 +35644,9 @@ fn cgassign(c: *cgen, n: *node) void = { // returning call — rettupleof distinguishes it from a // >24B struct, which keeps its own size-aware recv // below. Mirrors the cstage N_ASSIGN-ident over-cap arm. - if (n.op == tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL) { - let rtup: *node = rettupleof(c, n.rhs); + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil + && n.rhs.kind == syntax.nkind.N_CALL) { + let rtup: *syntax.node = rettupleof(c, n.rhs); if (rtup != nil) { let rscs: i32 = callsretsize(c, n.rhs); if (rscs > 0) { @@ -35693,11 +35693,11 @@ fn cgassign(c: *cgen, n: *node) void = { // doesn't emit (tracked separately as the cstage/ // wwstage MOVW divergence task). if (lcn != nil) { - let lctn: *node = lcn.tnode; + let lctn: *syntax.node = lcn.tnode; let lcsname: str; lcsname.ptr = nil; lcsname.len = 0; if (lctn != nil) { - if (lctn.kind == nkind.N_TNAME) { + if (lctn.kind == syntax.nkind.N_TNAME) { lcsname = lctn.str; }; }; @@ -35712,9 +35712,9 @@ fn cgassign(c: *cgen, n: *node) void = { // (natural 12, ABI 16) to MOVQ+MOVL where // cstage writes MOVQ+MOVQ. let lcnsz: i32 = structabisize(lcsi); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { if (n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT) { + && n.rhs.kind == syntax.nkind.N_STRUCTLIT) { // Delegate to the shared BP-relative // structlit fill helper. Handles // TK_ELLIPSIS autofill + per-field @@ -35730,7 +35730,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; if (n.rhs != nil - && n.rhs.kind == nkind.N_CALL) { + && n.rhs.kind == syntax.nkind.N_CALL) { // sret receive (#23): plain // TY_STRUCT > 24B from a CALL. // `s` is the prealloc dest; the @@ -35795,12 +35795,12 @@ fn cgassign(c: *cgen, n: *node) void = { // stores. Array natural size (tinfo.size = sub.size*len) // mirrors cstage lu->size. No structfloatclass (pure-int // element arrays). - if (lcn != nil && n.op == tkind.TK_ASSIGN - && n.rhs != nil && n.rhs.kind == nkind.N_CALL) { - let acati: *tinfo = nil; - if (lcn.tnode != nil) { acati = lcn.tnode.type_: *tinfo; }; + if (lcn != nil && n.op == syntax.tkind.TK_ASSIGN + && n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL) { + let acati: *syntax.tinfo = nil; + if (lcn.tnode != nil) { acati = lcn.tnode.type_: *syntax.tinfo; }; acati = tichase(acati); - if (acati != nil && acati.kind == tykind.TY_ARRAY) { + if (acati != nil && acati.kind == syntax.tykind.TY_ARRAY) { let lcsz: i32 = acati.size: i32; if (lcsz > 24) { let rscs: i32 = callsretsize(c, n.rhs); @@ -35867,7 +35867,7 @@ fn cgassign(c: *cgen, n: *node) void = { mulf = "MULSS"; divf = "DIVSS"; }; - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { emitline("\t"); emitline(mov); emitline("\tX0, "); @@ -35877,10 +35877,10 @@ fn cgassign(c: *cgen, n: *node) void = { }; let fop: str; fop.ptr = nil; fop.len = 0; - if (n.op == tkind.TK_PLUSEQ) { fop = addf; }; - if (n.op == tkind.TK_MINUSEQ) { fop = subf; }; - if (n.op == tkind.TK_STAREQ) { fop = mulf; }; - if (n.op == tkind.TK_SLASHEQ) { fop = divf; }; + if (n.op == syntax.tkind.TK_PLUSEQ) { fop = addf; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { fop = subf; }; + if (n.op == syntax.tkind.TK_STAREQ) { fop = mulf; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { fop = divf; }; if (fop.len == 0) { emitline("\t"); emitline(mov); @@ -35913,19 +35913,19 @@ fn cgassign(c: *cgen, n: *node) void = { // below and word0-copied `b = a` (cstage cgen.c // N_ASSIGN aggregate-ident twin). Kind keys off the // checker-STAMPED tinfo (#209/#211 discipline). - if (n.op == tkind.TK_ASSIGN) { - let agu: *tinfo = nil; + if (n.op == syntax.tkind.TK_ASSIGN) { + let agu: *syntax.tinfo = nil; if (lcn != nil) { if (lcn.tnode != nil) { - agu = lcn.tnode.type_: *tinfo; + agu = lcn.tnode.type_: *syntax.tinfo; }; }; agu = tichase(agu); if (agu != nil) { - if (agu.kind == tykind.TY_STRUCT - || agu.kind == tykind.TY_ARRAY - || agu.kind == tykind.TY_TUPLE) { - if (n.rhs != nil && n.rhs.kind == nkind.N_STRUCTLIT) { + if (agu.kind == syntax.tykind.TY_STRUCT + || agu.kind == syntax.tykind.TY_ARRAY + || agu.kind == syntax.tykind.TY_TUPLE) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_STRUCTLIT) { // wwstage-only bail: the fill is // structinfo-keyed; a literal // reaching past the name-keyed arm @@ -35938,7 +35938,7 @@ fn cgassign(c: *cgen, n: *node) void = { os.write(2, m49a.ptr, m49a.len: u64); os.exit(1); }; - if (n.rhs != nil && n.rhs.kind == nkind.N_CALL) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL) { let m49b: str = "assign: aggregate call receive shape unwired (task #49/#276/rule-7)\n"; os.write(2, m49b.ptr, m49b.len: u64); os.exit(1); @@ -35957,7 +35957,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; cgexpr(c, n.rhs); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { emitline("\tMOVQ\tAX, "); emitoff(off: i64); emitline("(BP)\n"); @@ -35981,14 +35981,14 @@ fn cgassign(c: *cgen, n: *node) void = { // after a 4B deref-store leaves the upper bytes stale. let llop: str = "MOVQ"; if (lcn != nil) { llop = localloadop(c, lcn.tnode); }; - if (streq(llop, "MOVQ")) { - if (n.op == tkind.TK_PLUSEQ) { + if (syntax.streq(llop, "MOVQ")) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, "); emitoff(off: i64); emitline("(BP)\n"); return; }; - if (n.op == tkind.TK_MINUSEQ) { + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, "); emitoff(off: i64); emitline("(BP)\n"); @@ -36001,23 +36001,23 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\t"); emitoff(off: i64); emitline("(BP), BX\n"); - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); }; - if (n.op == tkind.TK_LSHIFTEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tSHLQ\tCX, BX\n"); }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_RSHIFTEQ) { // #136: signed RSHIFTEQ → SARQ. let unsignd_r: bool = false; if (lcn != nil) { if (lcn.tnode != nil) { if (lcn.tnode.type_ != nil) { - unsignd_r = typeisunsigned(lcn.tnode.type_: *tinfo); + unsignd_r = syntax.typeisunsigned(lcn.tnode.type_: *syntax.tinfo); }; }; }; @@ -36035,11 +36035,11 @@ fn cgassign(c: *cgen, n: *node) void = { // shape the global/deref siblings took. Park rhs in // CX, slot value (BX) into AX, CQO/IDIVQ, ferry AX // (quotient) or DX (remainder) back to BX. - if (n.op == tkind.TK_SLASHEQ || n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ || n.op == syntax.tkind.TK_PERCENTEQ) { let unsignd: bool = false; if (lcn != nil) { if (lcn.tnode != nil) { - unsignd = typeisunsigned(lcn.tnode.type_: *tinfo); + unsignd = syntax.typeisunsigned(lcn.tnode.type_: *syntax.tinfo); }; }; if (!unsignd) { @@ -36054,7 +36054,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ) { emitline("\tMOVQ\tAX, BX\n"); } else { emitline("\tMOVQ\tDX, BX\n"); @@ -36078,20 +36078,20 @@ fn cgassign(c: *cgen, n: *node) void = { // indexed/deref shape returned from its legacy arm), and the // C1.25 aggregate branch fills via @placescr. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT || lhs.kind == nkind.N_INDEX - || (lhs.kind == nkind.N_UN && lhs.op == tkind.TK_STAR)) { - let ft: *tinfo = lhs.type_: *tinfo; - let fu: *tinfo = ft; + if (lhs.kind == syntax.nkind.N_DOT || lhs.kind == syntax.nkind.N_INDEX + || (lhs.kind == syntax.nkind.N_UN && lhs.op == syntax.tkind.TK_STAR)) { + let ft: *syntax.tinfo = lhs.type_: *syntax.tinfo; + let fu: *syntax.tinfo = ft; fu = tichase(fu); let fsz: i32 = 8; if (ft != nil) { fsz = ft.size: i32; }; - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mf: str = "assign-resolver: float field not wired (rule-7)\n"; os.write(2, mf.ptr, mf.len: u64); os.exit(1); }; if (fu != nil) { - if (fu.kind == tykind.TY_TAGGED) { + if (fu.kind == syntax.tykind.TY_TAGGED) { let mt: str = "assign-resolver: tagged field not wired (rule-7)\n"; os.write(2, mt.ptr, mt.len: u64); os.exit(1); @@ -36106,16 +36106,16 @@ fn cgassign(c: *cgen, n: *node) void = { // (loud-first, wire-next). Compound on an // aggregate is meaningless and stays loud. // Mirror of the cstage cgen.c C1.25 arm. - if (fu.kind == tykind.TY_STRUCT - || fu.kind == tykind.TY_ARRAY - || fu.kind == tykind.TY_TUPLE) { - if (n.op != tkind.TK_ASSIGN) { + if (fu.kind == syntax.tykind.TY_STRUCT + || fu.kind == syntax.tykind.TY_ARRAY + || fu.kind == syntax.tykind.TY_TUPLE) { + if (n.op != syntax.tkind.TK_ASSIGN) { let mac: str = "assign-resolver: compound on aggregate field not wired (rule-7)\n"; os.write(2, mac.ptr, mac.len: u64); os.exit(1); }; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { + if (n.rhs.kind == syntax.nkind.N_CALL) { // sret-class needs a runtime-RDI dest // (the #234-tail deferral); the ≤24B // reg-return receive is task #24. The @@ -36136,8 +36136,8 @@ fn cgassign(c: *cgen, n: *node) void = { let placed: bool = false; let isslit: bool = false; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_STRUCTLIT - && fu.kind == tykind.TY_STRUCT) { + if (n.rhs.kind == syntax.nkind.N_STRUCTLIT + && fu.kind == syntax.tykind.TY_STRUCT) { isslit = true; }; }; @@ -36155,7 +36155,7 @@ fn cgassign(c: *cgen, n: *node) void = { // below may clobber AX/CX freely. let sname: str; sname.ptr = nil; sname.len = 0; - if (ft.kind == tykind.TY_NAMED) { + if (ft.kind == syntax.tykind.TY_NAMED) { sname = ft.name; }; let si: *structinfo = nil; @@ -36210,13 +36210,13 @@ fn cgassign(c: *cgen, n: *node) void = { }; let fstrsl: bool = false; if (fu != nil) { - if (fu.kind == tykind.TY_STR - || fu.kind == tykind.TY_SLICE) { + if (fu.kind == syntax.tykind.TY_STR + || fu.kind == syntax.tykind.TY_SLICE) { fstrsl = true; }; }; if (fstrsl) { - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { let ms: str = "assign-resolver: compound on str/slice field not wired (rule-7)\n"; os.write(2, ms.ptr, ms.len: u64); os.exit(1); @@ -36238,7 +36238,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tMOVQ\tCX, 16(DX)\n"); return; }; - } else { if (n.op == tkind.TK_ASSIGN) { + } else { if (n.op == syntax.tkind.TK_ASSIGN) { cgexpr(c, n.rhs); emitline("\tPUSHQ\tAX\n"); if (cgplaceaddr(c, lhs, "BX")) { @@ -36259,32 +36259,32 @@ fn cgassign(c: *cgen, n: *node) void = { cgexpr(c, n.rhs); emitline("\tPUSHQ\tAX\n"); if (cgplaceaddr(c, lhs, "BX")) { - let lop: str = loadopsz(typeissigned(ft), fsz); + let lop: str = loadopsz(syntax.typeissigned(ft), fsz); emitline("\t"); emitline(lop); emitline("\t(BX), AX\n"); emitline("\tPOPQ\tCX\n"); - let unsignd: bool = typeisunsigned(ft); + let unsignd: bool = syntax.typeisunsigned(ft); let wired: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired = true; @@ -36338,36 +36338,36 @@ import strconv; // ---- statement cgen -------------------------------------------------- -fn cgstmt(c: *cgen, n: *node) void = { +fn cgstmt(c: *cgen, n: *syntax.node) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; - if (k == nkind.N_BLOCK) { cgblock(c, n); return; }; + if (k == syntax.nkind.N_BLOCK) { cgblock(c, n); return; }; - if (k == nkind.N_RETURN) { cgreturn(c, n); return; }; + if (k == syntax.nkind.N_RETURN) { cgreturn(c, n); return; }; - if (k == nkind.N_EXPRSTMT) { cgexprstmt(c, n); return; }; + if (k == syntax.nkind.N_EXPRSTMT) { cgexprstmt(c, n); return; }; - if (k == nkind.N_LET) { cglet(c, n); return; }; + if (k == syntax.nkind.N_LET) { cglet(c, n); return; }; - if (k == nkind.N_IF) { cgif(c, n); return; }; + if (k == syntax.nkind.N_IF) { cgif(c, n); return; }; - if (k == nkind.N_FOR) { cgfor(c, n); return; }; + if (k == syntax.nkind.N_FOR) { cgfor(c, n); return; }; - if (k == nkind.N_FORRANGE) { cgforrange(c, n); return; }; + if (k == syntax.nkind.N_FORRANGE) { cgforrange(c, n); return; }; - if (k == nkind.N_SWITCH) { cgswitch(c, n); return; }; + if (k == syntax.nkind.N_SWITCH) { cgswitch(c, n); return; }; - if (k == nkind.N_MASSIGN) { cgmassign(c, n); return; }; + if (k == syntax.nkind.N_MASSIGN) { cgmassign(c, n); return; }; - if (k == nkind.N_MLET) { cgmlet(c, n); return; }; + if (k == syntax.nkind.N_MLET) { cgmlet(c, n); return; }; - if (k == nkind.N_BREAK) { cgbreak(c, n); return; }; - if (k == nkind.N_CONTINUE) { cgcontinue(c, n); return; }; + if (k == syntax.nkind.N_BREAK) { cgbreak(c, n); return; }; + if (k == syntax.nkind.N_CONTINUE) { cgcontinue(c, n); return; }; - if (k == nkind.N_YIELD) { cgyield(c, n); return; }; + if (k == syntax.nkind.N_YIELD) { cgyield(c, n); return; }; - if (k == nkind.N_DEFER) { + if (k == syntax.nkind.N_DEFER) { // #40: at the cap, fail loud in BOTH stages rather than // silently drop the deferred call. cstage's DEFER_MAX was 32 // and also dropped silently past it; the runtime-correct target @@ -36385,7 +36385,7 @@ fn cgstmt(c: *cgen, n: *node) void = { c.lastwasreturn = 0; }; -fn cgyield(c: *cgen, n: *node) void = { +fn cgyield(c: *cgen, n: *syntax.node) void = { // Evaluate the value into AX (and BX for str), then JMP to the // enclosing match's end label. Falls through silently if there // is no active match — should be a checker error eventually. @@ -36400,7 +36400,7 @@ fn cgyield(c: *cgen, n: *node) void = { return; }; -fn cgblock(c: *cgen, n: *node) void = { +fn cgblock(c: *cgen, n: *syntax.node) void = { // Save/restore the locals head across the block (post-#27). // Inner-scope `let` bindings prepend to c.locals via localadd; // without this restore, the prepended stubs leak into sibling @@ -36413,7 +36413,7 @@ fn cgblock(c: *cgen, n: *node) void = { // restore at the function's outermost block — defers (and the // implicit-return epilogue) need locals intact. let saved: *local = c.locals; - let s: *node = n.list; + let s: *syntax.node = n.list; for (s != nil) { cgstmt(c, s); s = s.next; @@ -36470,55 +36470,55 @@ fn tupsse(i: i32) str = { // predicates this absorbs were the #22 neighbor-slot/zeros miscompile. // Checker twin: check.ww tupleelemslot / check.c N_TTUPLE; cstage twin: // tuple_eslot (cmd/w6c/cgen.c). -export fn tupeslot(ti: *tinfo) i32 = { - let t: *tinfo = ti; +export fn tupeslot(ti: *syntax.tinfo) i32 = { + let t: *syntax.tinfo = ti; t = tichase(t); if (t == nil) { return 8; }; - if (t.kind == tykind.TY_VOID) { return 0; }; + if (t.kind == syntax.tykind.TY_VOID) { return 0; }; // a literal tuple's stamped element can be untyped_str (size 0) — // it occupies the str header slot (the C-t2 type_isstr lesson). - if (t.kind == tykind.TY_UNTYPED_STR) { return tyslicesize(): i32; }; - if (t.kind == tykind.TY_STR || t.kind == tykind.TY_SLICE || - t.kind == tykind.TY_TAGGED) { + if (t.kind == syntax.tykind.TY_UNTYPED_STR) { return tyslicesize(): i32; }; + if (t.kind == syntax.tykind.TY_STR || t.kind == syntax.tykind.TY_SLICE || + t.kind == syntax.tykind.TY_TAGGED) { return ((t.size + 7u64) & ~7u64): i32; }; return 8; }; -export fn tupeslotn(n: *node) i32 = { +export fn tupeslotn(n: *syntax.node) i32 = { if (n == nil) { return 8; }; - return tupeslot(n.type_: *tinfo); + return tupeslot(n.type_: *syntax.tinfo); }; // rettupleof — the N_TTUPLE return-type node of an N_CALL rhs (else nil). // wwstage has no checker, so the receive sites read each tuple element's // width from the called fn's declared return type. Mirrors the callee // resolution shared by cgmlet/cgmassign. -fn rettupleof(c: *cgen, rhs: *node) *node = { +fn rettupleof(c: *cgen, rhs: *syntax.node) *syntax.node = { if (rhs == nil) { return nil; }; - if (rhs.kind != nkind.N_CALL) { return nil; }; - let callee: *node = rhs.lhs; + if (rhs.kind != syntax.nkind.N_CALL) { return nil; }; + let callee: *syntax.node = rhs.lhs; if (callee == nil) { return nil; }; let cnm: str; cnm.ptr = nil; cnm.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { cnm = callee.str; cmod = c.curmod; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { cnm = callee.str; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cnm.len == 0) { return nil; }; - let rtyp: *node = fnretlookupmod(c, cnm, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cnm, cmod); if (rtyp == nil) { return nil; }; - if (rtyp.kind != nkind.N_TTUPLE) { return nil; }; + if (rtyp.kind != syntax.nkind.N_TTUPLE) { return nil; }; return rtyp; }; @@ -36531,24 +36531,24 @@ fn rettupleof(c: *cgen, rhs: *node) *node = { // nodes). Mirror of cstage node_tuplearg; the cgcall push site // loud-stops any other tuple-typed source shape (rule 7). rettupleof // stays N_CALL-scoped for the destructure/reassign receive sites. -fn nodetuplearg(c: *cgen, a: *node) *node = { +fn nodetuplearg(c: *cgen, a: *syntax.node) *syntax.node = { if (a == nil) { return nil; }; - if (a.kind == nkind.N_TUPLE) { return a; }; - if (a.kind == nkind.N_IDENT) { + if (a.kind == syntax.nkind.N_TUPLE) { return a; }; + if (a.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.str); if (lc == nil) { return nil; }; - let tn: *node = lc.tnode; - for (tn != nil && tn.kind == nkind.N_TNAME) { + let tn: *syntax.node = lc.tnode; + for (tn != nil && tn.kind == syntax.nkind.N_TNAME) { tn = aliaslookup(c, tn.str); }; if (tn != nil) { - if (tn.kind == nkind.N_TTUPLE) { return tn; }; + if (tn.kind == syntax.nkind.N_TTUPLE) { return tn; }; }; return nil; }; - let t: *node = inferletcalltype(c, a); + let t: *syntax.node = inferletcalltype(c, a); if (t != nil) { - if (t.kind == nkind.N_TTUPLE) { return t; }; + if (t.kind == syntax.nkind.N_TTUPLE) { return t; }; }; return nil; }; @@ -36560,7 +36560,7 @@ fn nodetuplearg(c: *cgen, a: *node) *node = { // registers; a float rides the SSE cursor (X0,X1); a scalar stores 1 // INTEGER word. The caller owns the dual cursor (validated + // advanced). Byte-identical to the cstage tuple_store (cmd/w6c/cgen.c). -fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *node) void = { +fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *syntax.node) void = { if (eslot == 0) { return; }; // void element: the checker's 0-slot if (eslot > 8) { let k: i32 = 0; @@ -36602,7 +36602,7 @@ fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *node) os.write(2, ls.ptr, ls.len: u64); os.write(2, " ".ptr, 1u64); }; - let kn: str = nkname(tn.kind); + let kn: str = syntax.nkname(tn.kind); os.write(2, kn.ptr, kn.len: u64); os.write(2, "\n".ptr, 1u64); os.exit(1); @@ -36639,7 +36639,7 @@ fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *node) // declared-TAGGED slot counted ONE word here while the receive walks // the declared eslot — the cursor shifted and every later element // read garbage. Declared-tagged keys the count on the DECLARED box. -fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { +fn tuplitgpwords(c: *cgen, e: *syntax.node, dtn: *syntax.node) i32 = { if (dtn != nil) { if (istaggedtype(c, dtn)) { return tupeslotn(dtn) / 8; }; }; @@ -36647,10 +36647,10 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { if (nodeisstr(c, e) || nodeisslice(c, e)) { return (tyslicesize() / 8i64): i32; }; - let t: *tinfo = e.type_: *tinfo; + let t: *syntax.tinfo = e.type_: *syntax.tinfo; t = tichase(t); - if (t != nil && (t.kind == tykind.TY_TAGGED || - t.kind == tykind.TY_VOID)) { + if (t != nil && (t.kind == syntax.tykind.TY_TAGGED || + t.kind == syntax.tykind.TY_VOID)) { return tupeslotn(e) / 8; }; return 1; @@ -36673,11 +36673,11 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { // tagged-@retscr shape) and pushes the box words. A tagged->tagged // SUBSET element (eslot mismatch) needs a tag remap on the way into // the slot — loud (rule 7, the #23/#40 widening family). -fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { - let t: *tinfo = e.type_: *tinfo; +fn tuplitpushelem(c: *cgen, e: *syntax.node, dtn: *syntax.node) void = { + let t: *syntax.tinfo = e.type_: *syntax.tinfo; t = tichase(t); let etagged: bool = false; - if (t != nil) { if (t.kind == tykind.TY_TAGGED) { etagged = true; }; }; + if (t != nil) { if (t.kind == syntax.tykind.TY_TAGGED) { etagged = true; }; }; if (dtn != nil) { if (istaggedtype(c, dtn) && !etagged) { let eslot: i32 = tupeslotn(dtn); @@ -36690,7 +36690,7 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { emitline("(BP)\n"); z += 8; }; - cgwidentaggedstore(c, dtn.type_: *tinfo, e, + cgwidentaggedstore(c, dtn.type_: *syntax.tinfo, e, "BP", scr, eslot); let pk: i32 = 0; for (pk < eslot / 8) { @@ -36712,7 +36712,7 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { if (etagged) { let eslot: i32 = tupeslotn(e); let eoff: i32 = 0; - if (e.kind == nkind.N_IDENT) { eoff = localfind(c, e.str); }; + if (e.kind == syntax.nkind.N_IDENT) { eoff = localfind(c, e.str); }; if (eoff == 0) { let m22: str = "#22a: tagged tuple element from a non-local source shape unwired (ident locals only; rule 7; call-source is task #41, widening #23, deref/cast #35)\n"; os.write(2, m22.ptr, m22.len: u64); @@ -36729,7 +36729,7 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { return; }; cgexpr(c, e); - if (t != nil && t.kind == tykind.TY_VOID) { return; }; + if (t != nil && t.kind == syntax.tykind.TY_VOID) { return; }; emitline("\tPUSHQ\tAX\n"); if (nodeisstr(c, e) || nodeisslice(c, e)) { emitline("\tPUSHQ\tBX\n"); @@ -36755,18 +36755,18 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { // declared eslot — see tuplitgpwords / tuplitpushelem. Mirrors cstage // cg_tuple_lit_to_cursor's decl walk; decl.list nodes wrap the elem // type in .lhs (the c.fnret.list shape the over-cap arm walks). -fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { - let dp0: *node = nil; +fn cgtuplelittocursor(c: *cgen, tuple: *syntax.node, decl: *syntax.node) void = { + let dp0: *syntax.node = nil; if (decl != nil) { - if (decl.kind == nkind.N_TTUPLE) { dp0 = decl.list; }; + if (decl.kind == syntax.nkind.N_TTUPLE) { dp0 = decl.list; }; }; let ssecap: i32 = TUPLE_SSECAP; let gptotal: i32 = 0; let ssecount: i32 = 0; - let dp: *node = dp0; - let e: *node = tuple.list; + let dp: *syntax.node = dp0; + let e: *syntax.node = tuple.list; for (e != nil) { - let dtn: *node = nil; + let dtn: *syntax.node = nil; if (dp != nil) { dtn = dp.lhs; }; let dtagged: bool = false; if (dtn != nil) { dtagged = istaggedtype(c, dtn); }; @@ -36791,7 +36791,7 @@ fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { dp = dp0; e = tuple.list; for (e != nil) { - let dtn: *node = nil; + let dtn: *syntax.node = nil; if (dp != nil) { dtn = dp.lhs; }; let dtagged: bool = false; if (dtn != nil) { dtagged = istaggedtype(c, dtn); }; @@ -36821,7 +36821,7 @@ fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { dp = dp0; e = tuple.list; for (e != nil) { - let dtn: *node = nil; + let dtn: *syntax.node = nil; if (dp != nil) { dtn = dp.lhs; }; let dtagged: bool = false; if (dtn != nil) { dtagged = istaggedtype(c, dtn); }; @@ -36849,14 +36849,14 @@ fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { // / `return t` / `let q = t` over a tuple ident leave the whole tuple in the // cursor, not just word0 in AX. Over-cap loud-stops (rule 7; #10). Mirror of // cstage cg_tuple_slot_to_cursor. -fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { +fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *syntax.tinfo) void = { let gptotal: i32 = 0; let ssecount: i32 = 0; - let el: *ttupleelem = tu.tupleelems; + let el: *syntax.ttupleelem = tu.tupleelems; for (el != nil) { - let et: *tinfo = el.type_; + let et: *syntax.tinfo = el.type_; et = tichase(et); - if (et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64)) { + if (et != nil && (et.kind == syntax.tykind.TY_F32 || et.kind == syntax.tykind.TY_F64)) { ssecount = ssecount + 1; } else { gptotal = gptotal + tupeslot(el.type_) / 8; @@ -36873,13 +36873,13 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { let foff: i32 = 0; el = tu.tupleelems; for (el != nil) { - let et: *tinfo = el.type_; + let et: *syntax.tinfo = el.type_; et = tichase(et); - let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); + let isflt: bool = et != nil && (et.kind == syntax.tykind.TY_F32 || et.kind == syntax.tykind.TY_F64); let eslot: i32 = tupeslot(el.type_); if (isflt) { let mov: str = "MOVSD"; - if (et.kind == tykind.TY_F32) { mov = "MOVSS"; }; + if (et.kind == syntax.tykind.TY_F32) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); emitoff((srcoff + foff): i64); emitline("(BP), "); @@ -36912,13 +36912,13 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { // elements ride a different SysV class — loud-stop (rule 7; the per- // eightbyte tagged-tuple-payload classification is the #243 follow-up). // Mirror of cstage cg_tagged_tuple_payload_shift. -fn cgtaggedtuplepayloadshift(c: *cgen, tup: *tinfo) void = { +fn cgtaggedtuplepayloadshift(c: *cgen, tup: *syntax.tinfo) void = { let words: i32 = 0; - let el: *ttupleelem = tup.tupleelems; + let el: *syntax.ttupleelem = tup.tupleelems; for (el != nil) { - let et: *tinfo = el.type_; + let et: *syntax.tinfo = el.type_; et = tichase(et); - let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); + let isflt: bool = et != nil && (et.kind == syntax.tykind.TY_F32 || et.kind == syntax.tykind.TY_F64); if (isflt || tupeslot(el.type_) != 8) { let msg: str = "tuple-in-union ? unwrap: float/slice/str/tagged payload element needs SysV per-eightbyte classification (see #243); only integer tuple payloads supported\n"; os.write(2, msg.ptr, msg.len: u64); @@ -36943,9 +36943,9 @@ fn cgtaggedtuplepayloadshift(c: *cgen, tup: *tinfo) void = { }; }; -fn cgreturn(c: *cgen, n: *node) void = { +fn cgreturn(c: *cgen, n: *syntax.node) void = { rundefers(c); - let rhs: *node = n.lhs; + let rhs: *syntax.node = n.lhs; if (rhs != nil) { // #83 / #164 (#107): positional register-return over a SysV // dual class cursor (harec create_unpack_bindings, ref/harec/src/ @@ -36968,7 +36968,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // below, which routes it via cgwidentaggedstore. Without this // guard the bare-tuple arm fired first and dropped the tag, // returning (AX=word0, DX=word1) with no tag word. - if (rhs.kind == nkind.N_TUPLE && !istaggedtype(c, c.fnret)) { + if (rhs.kind == syntax.nkind.N_TUPLE && !istaggedtype(c, c.fnret)) { let ssecap: i32 = TUPLE_SSECAP; // X0,X1 per SysV let gptotal: i32 = 0; let ssecount: i32 = 0; @@ -36980,16 +36980,16 @@ fn cgreturn(c: *cgen, n: *node) void = { // declared eslot (2 words sent for a 3-word shape; // ken /tmp/ken57 p8/p9). Same pt walk the over-cap arm // already does (#240/#22b). Mirrors cstage cgreturn. - let rp0: *node = nil; + let rp0: *syntax.node = nil; if (c.fnret != nil) { - if (c.fnret.kind == nkind.N_TTUPLE) { + if (c.fnret.kind == syntax.nkind.N_TTUPLE) { rp0 = c.fnret.list; }; }; - let rp: *node = rp0; - let e: *node = rhs.list; + let rp: *syntax.node = rp0; + let e: *syntax.node = rhs.list; for (e != nil) { - let rdtn: *node = nil; + let rdtn: *syntax.node = nil; if (rp != nil) { rdtn = rp.lhs; }; let rdtag: bool = false; if (rdtn != nil) { rdtag = istaggedtype(c, rdtn); }; @@ -37031,15 +37031,15 @@ fn cgreturn(c: *cgen, n: *node) void = { // (#10 Fold B). Byte-identical to cstage cgen.c // N_RETURN over-cap tuple arm. let saoff: i32 = localfind(c, "@sretarg"); - let pt: *node = nil; + let pt: *syntax.node = nil; if (c.fnret != nil) { pt = c.fnret.list; }; - let we: *node = rhs.list; + let we: *syntax.node = rhs.list; let foff: i32 = 0; for (we != nil) { - let dt: *tinfo = nil; - if (pt != nil) { dt = pt.lhs.type_: *tinfo; }; + let dt: *syntax.tinfo = nil; + if (pt != nil) { dt = pt.lhs.type_: *syntax.tinfo; }; dt = tichase(dt); - if (dt != nil && dt.kind == tykind.TY_TAGGED) { + if (dt != nil && dt.kind == syntax.tykind.TY_TAGGED) { // #22b (task #28): MEMORY-class tagged // element — the whole box copies through // the sret pointer mem-to-mem from the @@ -37054,11 +37054,11 @@ fn cgreturn(c: *cgen, n: *node) void = { // follow-ups). Mirror of cstage cgen.c // N_RETURN over-cap tagged arm. let eslot: i32 = tupeslotn(pt.lhs); - let eu: *tinfo = we.type_: *tinfo; + let eu: *syntax.tinfo = we.type_: *syntax.tinfo; eu = tichase(eu); let eoff: i32 = 0; - if (we.kind == nkind.N_IDENT && eu != nil) { - if (eu.kind == tykind.TY_TAGGED && tupeslotn(we) == eslot) { + if (we.kind == syntax.nkind.N_IDENT && eu != nil) { + if (eu.kind == syntax.tykind.TY_TAGGED && tupeslotn(we) == eslot) { eoff = localfind(c, we.str); }; }; @@ -37089,7 +37089,7 @@ fn cgreturn(c: *cgen, n: *node) void = { let wide: bool = nodeisstr(c, we) || nodeisslice(c, we); let esz: i32 = 8; if (pt != nil) { - let eti: *tinfo = pt.lhs.type_: *tinfo; + let eti: *syntax.tinfo = pt.lhs.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; }; cgexpr(c, we); @@ -37165,7 +37165,7 @@ fn cgreturn(c: *cgen, n: *node) void = { rp = rp0; e = rhs.list; for (e != nil) { - let rdtn: *node = nil; + let rdtn: *syntax.node = nil; if (rp != nil) { rdtn = rp.lhs; }; let rdtag: bool = false; if (rdtn != nil) { rdtag = istaggedtype(c, rdtn); }; @@ -37200,7 +37200,7 @@ fn cgreturn(c: *cgen, n: *node) void = { rp = rp0; e = rhs.list; for (e != nil) { - let rdtn: *node = nil; + let rdtn: *syntax.node = nil; if (rp != nil) { rdtn = rp.lhs; }; let rdtag: bool = false; if (rdtn != nil) { rdtag = istaggedtype(c, rdtn); }; @@ -37259,17 +37259,17 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_INDEX tagged-element return fell to the scalar-variant // shuffle (MOVQ AX,DX; MOVQ $0,AX), dropping the payload. let forwardtagged: bool = false; - if ((rhs.kind == nkind.N_CALL || rhs.kind == nkind.N_INDEX || rhs.kind == nkind.N_DOT) && rhs.type_ != nil && c.fnret != nil && c.fnret.type_ != nil) { - let ru: *tinfo = rhs.type_: *tinfo; + if ((rhs.kind == syntax.nkind.N_CALL || rhs.kind == syntax.nkind.N_INDEX || rhs.kind == syntax.nkind.N_DOT) && rhs.type_ != nil && c.fnret != nil && c.fnret.type_ != nil) { + let ru: *syntax.tinfo = rhs.type_: *syntax.tinfo; ru = tichase(ru); - let fu: *tinfo = c.fnret.type_: *tinfo; + let fu: *syntax.tinfo = c.fnret.type_: *syntax.tinfo; fu = tichase(fu); - if (ru != nil && fu != nil && ru.kind == tykind.TY_TAGGED && fu.kind == tykind.TY_TAGGED) { + if (ru != nil && fu != nil && ru.kind == syntax.tykind.TY_TAGGED && fu.kind == syntax.tykind.TY_TAGGED) { if (ru == fu) { forwardtagged = true; } else if (ru.nullable == fu.nullable) { - let pa: *tparam = ru.params; - let pb: *tparam = fu.params; + let pa: *syntax.tparam = ru.params; + let pb: *syntax.tparam = fu.params; let same: bool = true; for (pa != nil && pb != nil) { if (pa.type_ != pb.type_) { same = false; }; @@ -37291,7 +37291,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // cgwidentaggedstore's non-BP base. if (sretretsize(c, c.fnret) > 0) { let sa38v: i32 = localfind(c, "@sretarg"); - if (forwardtagged && rhs.kind == nkind.N_CALL) { + if (forwardtagged && rhs.kind == syntax.nkind.N_CALL) { // exact-type N_CALL forward: inner sret's // into outer's dest; an N_INDEX/N_DOT // source routes through the widener's @@ -37307,14 +37307,14 @@ fn cgreturn(c: *cgen, n: *node) void = { c.lastwasreturn = 1; return; }; - let ru38: *tinfo = rhs.type_: *tinfo; + let ru38: *syntax.tinfo = rhs.type_: *syntax.tinfo; ru38 = tichase(ru38); if (ru38 != nil) { // #37 wired the N_INDEX/N_DOT mem-read into // the widener; the remaining >32B kinds stay // loud. - if (ru38.kind == tykind.TY_TAGGED - && rhs.kind != nkind.N_IDENT + if (ru38.kind == syntax.tykind.TY_TAGGED + && rhs.kind != syntax.nkind.N_IDENT && ru38.size: i32 > TUPLE_GPCAP * 8 && !taggedmemread(c, rhs)) { let m38e: str = "#40: widening tagged return-forward of a >32B source needs mem-to-mem tag-remap (unwired)\n"; @@ -37325,7 +37325,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("\tMOVQ\t"); emitoff(sa38v: i64); emitline("(BP), BX\n"); - cgwidentaggedstore(c, c.fnret.type_: *tinfo, rhs, + cgwidentaggedstore(c, c.fnret.type_: *syntax.tinfo, rhs, "BX", 0, slotsize(c, c.fnret)); emitline("\tMOVQ\t"); emitoff(sa38v: i64); @@ -37350,7 +37350,7 @@ fn cgreturn(c: *cgen, n: *node) void = { }; // #242: a tuple variant packs into the union // payload via cgwidentaggedstore's TY_TUPLE arm. - if (rhs.kind == nkind.N_TUPLE) { + if (rhs.kind == syntax.nkind.N_TUPLE) { needswiden = true; }; // Family C (#35/#46): a mem-based tagged @@ -37374,15 +37374,15 @@ fn cgreturn(c: *cgen, n: *node) void = { // EXACT-type tagged casts on cstage's passthrough // (forwardtagged's own ru==fu equality) so byte-id // holds. - let ru1: *tinfo = rhs.type_: *tinfo; + let ru1: *syntax.tinfo = rhs.type_: *syntax.tinfo; ru1 = tichase(ru1); - let fu1: *tinfo = nil; + let fu1: *syntax.tinfo = nil; if (c.fnret != nil) { - fu1 = c.fnret.type_: *tinfo; + fu1 = c.fnret.type_: *syntax.tinfo; fu1 = tichase(fu1); }; if (ru1 != nil && fu1 != nil) { - if (ru1.kind == tykind.TY_TAGGED && ru1 != fu1) { + if (ru1.kind == syntax.tykind.TY_TAGGED && ru1 != fu1) { needswiden = true; }; // S3/#35: a SAME-TYPE tagged CAST (ru1 == fu1, @@ -37400,7 +37400,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // "N_CAST defeats srcreg"; peeling here instead // would reroute a call/dot source to passthrough // and break byte-id. - if (rhs.kind == nkind.N_CAST && ru1.kind == tykind.TY_TAGGED && ru1 == fu1) { + if (rhs.kind == syntax.nkind.N_CAST && ru1.kind == syntax.tykind.TY_TAGGED && ru1 == fu1) { needswiden = true; }; }; @@ -37429,7 +37429,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, c.fnret.type_: *tinfo, rhs, "BP", + cgwidentaggedstore(c, c.fnret.type_: *syntax.tinfo, rhs, "BP", scroff, rsz); // Tagged-return ABI loads at most 4 eightbytes // (AX/DX/CX/R8). A union whose slot exceeds 32B @@ -37494,9 +37494,9 @@ fn cgreturn(c: *cgen, n: *node) void = { // the SSoT cstage reads via node_isfloat / type_isf32. let rfk: i32 = 0; if (rhs != nil) { - let rety: *tinfo = rhs.type_: *tinfo; - if (typeisf32(rety)) { rfk = 1; } - else { if (typeisfloat(rety)) { rfk = 2; }; }; + let rety: *syntax.tinfo = rhs.type_: *syntax.tinfo; + if (syntax.typeisf32(rety)) { rfk = 1; } + else { if (syntax.typeisfloat(rety)) { rfk = 2; }; }; }; if (nodeisslice(c, rhs)) { // cgexpr leaves (AX=ptr, BX=len, CX=cap). @@ -37579,7 +37579,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // @sretarg(BP), AX is redundant after inner's // RET but kept for byte-id symmetry with the // N_IDENT / N_STRUCTLIT arms below. - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { c.sretforward = 1; cgexpr(c, rhs); emitline("\tMOVQ\t"); @@ -37598,15 +37598,15 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_RETURN sret arm. N_ARRLIT >24B has no consumer // (loud-stops in cstage); not wired here. let addrsrc: bool = false; - if (rhs.kind == nkind.N_IDENT) { okrhs = true; }; - if (rhs.kind == nkind.N_STRUCTLIT) { okrhs = true; }; - if (rhs.kind == nkind.N_DOT) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_INDEX) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_IDENT) { okrhs = true; }; + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { okrhs = true; }; + if (rhs.kind == syntax.nkind.N_DOT) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_INDEX) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { okrhs = true; addrsrc = true; }; }; if (okrhs) { - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { // #63: the >24B sret RETURN twin of the :2421 // let-init fix. sretretsize chases the alias for // the size GATE (so this sret arm fires for a >24B @@ -37619,7 +37619,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // (SILENT wrong, runtime-0). structlookupchain chases // to the base struct; cs fills via the resolved // Type*, runtime-correct. - let trefn: *node = rhs.lhs; + let trefn: *syntax.node = rhs.lhs; let sret_si: *structinfo = structlookupchain(c, trefn); if (sret_si != nil) { let emptys: str; @@ -37728,7 +37728,7 @@ fn cgreturn(c: *cgen, n: *node) void = { let rname: str; rname.ptr = nil; rname.len = 0; if (c.fnret != nil) { - if (c.fnret.kind == nkind.N_TNAME) { + if (c.fnret.kind == syntax.nkind.N_TNAME) { rname = c.fnret.str; }; }; @@ -37745,7 +37745,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_DOT/N_INDEX/deref memcpy into @retscr before the // shared structfloatclass tail (mirror cstage cgen.c). let addrsrc: bool = false; - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { okrhs = true; // #41 (#263 ww-runtime-correct): a module-global struct // source has no BP slot — route it through the addrsrc @@ -37756,13 +37756,13 @@ fn cgreturn(c: *cgen, n: *node) void = { addrsrc = true; }; }; - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { okrhs = true; }; - if (rhs.kind == nkind.N_DOT) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_INDEX) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_DOT) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_INDEX) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { okrhs = true; addrsrc = true; }; }; if (okrhs) { let scroff: i32 = localadd(c, @@ -37777,7 +37777,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("\tMOVQ\tAX, "); emitoff((scroff + 16): i64); emitline("(BP)\n"); - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { // Delegate to the shared BP-relative // structlit fill helper. Same store // sequence the inline pre-#17 walk @@ -37937,7 +37937,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // (tinfo.size = sub.size*len) mirrors cstage rt->size. No // structfloatclass (pure-int arrays); N_CALL forward at reg- // class falls to the default cgexpr passthrough below. - if (c.fnret != nil && c.fnret.kind == nkind.N_TARRAY) { + if (c.fnret != nil && c.fnret.kind == syntax.nkind.N_TARRAY) { // #272: array return-by-value source-shape closure. // Beyond the #267 N_IDENT word-copy, route N_ARRLIT // (literal fill), N_DOT/N_INDEX/deref (aggargsrcaddr + @@ -37945,14 +37945,14 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_RETURN ≤24B arm. N_CALL stays on the cgexpr tail (the // callee already left AX/DX/CX). let arrok: bool = false; - if (rhs.kind == nkind.N_IDENT) { arrok = true; }; - if (rhs.kind == nkind.N_ARRLIT) { arrok = true; }; - if (rhs.kind == nkind.N_DOT) { arrok = true; }; - if (rhs.kind == nkind.N_INDEX) { arrok = true; }; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_IDENT) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_ARRLIT) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_DOT) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_INDEX) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { arrok = true; }; }; - let ati: *tinfo = c.fnret.type_: *tinfo; + let ati: *syntax.tinfo = c.fnret.type_: *syntax.tinfo; ati = tichase(ati); if (arrok && ati != nil) { let rsz: i32 = ati.size: i32; @@ -37968,7 +37968,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("\tMOVQ\tAX, "); emitoff((scroff + 16): i64); emitline("(BP)\n"); - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { let rl: *local = localfindnode(c, rhs.str); let roff: i32 = 0; if (rl != nil) { roff = rl.off; }; @@ -38000,28 +38000,28 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("(BP)\n"); k += 1; }; - } else { if (rhs.kind == nkind.N_ARRLIT) { + } else { if (rhs.kind == syntax.nkind.N_ARRLIT) { // scalar/float element fill; non-scalar // elements loud-stop (rule 7, no consumer). - let esubti: *tinfo = nil; + let esubti: *syntax.tinfo = nil; if (ati.sub != nil) { esubti = ati.sub; }; esubti = tichase(esubti); let esz: i32 = 8; if (esubti != nil) { esz = esubti.size: i32; }; let badel: bool = false; if (esubti != nil) { - if (esubti.kind == tykind.TY_STRUCT) { badel = true; }; - if (esubti.kind == tykind.TY_ARRAY) { badel = true; }; - if (esubti.kind == tykind.TY_TUPLE) { badel = true; }; - if (esubti.kind == tykind.TY_SLICE) { badel = true; }; - if (esubti.kind == tykind.TY_STR) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_STRUCT) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_ARRAY) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_TUPLE) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_SLICE) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_STR) { badel = true; }; }; if (badel) { let m2: str = "#272: array-literal return with non-scalar element unsupported (rule 7, no consumer)\n"; os.write(2, m2.ptr, m2.len: u64); os.exit(1); }; - let esub: *node = c.fnret.lhs; + let esub: *syntax.node = c.fnret.lhs; let isfl: bool = isfloattype(c, esub); let fmov: str = "MOVSD"; if (isf32type(c, esub)) { fmov = "MOVSS"; }; @@ -38029,11 +38029,11 @@ fn cgreturn(c: *cgen, n: *node) void = { if (esz == 1) { op = "MOVB"; } else { if (esz == 2) { op = "MOVW"; } else { if (esz == 4) { op = "MOVL"; }; }; }; let idx: i32 = 0; let repeat: bool = false; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { let isellip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; isellip = true; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; isellip = true; }; }; if (isellip) { e = nil; @@ -38157,14 +38157,14 @@ fn cgreturn(c: *cgen, n: *node) void = { // array-literal return (no consumer) also lands here (#276). let aggret: bool = false; if (c.fnret != nil) { - let rti: *tinfo = c.fnret.type_: *tinfo; + let rti: *syntax.tinfo = c.fnret.type_: *syntax.tinfo; rti = tichase(rti); if (rti != nil) { - if (rti.kind == tykind.TY_ARRAY) { aggret = true; }; - if (rti.kind == tykind.TY_STRUCT) { aggret = true; }; + if (rti.kind == syntax.tykind.TY_ARRAY) { aggret = true; }; + if (rti.kind == syntax.tykind.TY_STRUCT) { aggret = true; }; }; }; - if (aggret && rhs.kind != nkind.N_CALL) { + if (aggret && rhs.kind != syntax.nkind.N_CALL) { let m6: str = "#272/#276/#277: aggregate return reaches scalar default — unclosed shape (named-alias aggregate return or >24B array-literal; wwstage tinfo-dispatch deferred #277)\n"; os.write(2, m6.ptr, m6.len: u64); os.exit(1); @@ -38227,7 +38227,7 @@ fn cgreturn(c: *cgen, n: *node) void = { return; }; -fn cgexprstmt(c: *cgen, n: *node) void = { +fn cgexprstmt(c: *cgen, n: *syntax.node) void = { if (n.lhs != nil) { cgexpr(c, n.lhs); }; c.lastwasreturn = 0; return; @@ -38240,8 +38240,8 @@ fn cgexprstmt(c: *cgen, n: *node) void = { // store-op guarantee for rule-10 byte-id (ken). `arrtn` is the [count]T // type NODE (cglet n.lhs; cgslice the re-stamped tnode on arrlit.lhs, // #25); `rhs` the literal. Twin of cstage cg_arrlit_fill_bp. -fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { - let elemn: *node = arrtn.lhs; +fn cgarrlitfillbp(c: *cgen, arrtn: *syntax.node, rhs: *syntax.node, off: i32) void = { + let elemn: *syntax.node = arrtn.lhs; // #79 (#60 rider): alias-NAMED [count]T (`type A = [4]u32; let // a: A = [...]`) — arrtn is the N_TNAME leaf: elemn nil, esz // stayed the 8 sentinel and the per-element store strode MOVQ @@ -38254,12 +38254,12 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // stash alen for the `...` repeat bound (cstage cg_arrlit_fill_bp // receives the pre-chased bu and reads bu->alen). let aliasalen: i32 = -1; - let ati79: *tinfo = arrtn.type_: *tinfo; - if (ati79 != nil) { if (ati79.kind == tykind.TY_NAMED) { - let au79: *tinfo = tichase(ati79); - if (au79 != nil) { if (au79.kind == tykind.TY_ARRAY + let ati79: *syntax.tinfo = arrtn.type_: *syntax.tinfo; + if (ati79 != nil) { if (ati79.kind == syntax.tykind.TY_NAMED) { + let au79: *syntax.tinfo = tichase(ati79); + if (au79 != nil) { if (au79.kind == syntax.tykind.TY_ARRAY && au79.sub != nil) { - let en79: *node = newnode(nkind.N_TNAME, arrtn.file, arrtn.line, arrtn.col); + let en79: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, arrtn.file, arrtn.line, arrtn.col); en79.str = au79.sub.name; en79.type_ = au79.sub: *void; elemn = en79; @@ -38269,8 +38269,8 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { let esz: i32 = 8; let isstrel: bool = false; if (elemn != nil) { - if (elemn.kind == nkind.N_TNAME) { - if (streq(elemn.str, "str")) { + if (elemn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(elemn.str, "str")) { esz = primtypesize("str"): i32; isstrel = true; } else { @@ -38285,13 +38285,13 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // each element slot from its literal (cgstructlitfillbp) // or source ident (word-copy). esz is the element's // natural size (cstage esub->size). - let esubti: *tinfo = nil; - if (elemn != nil) { esubti = elemn.type_: *tinfo; }; + let esubti: *syntax.tinfo = nil; + if (elemn != nil) { esubti = elemn.type_: *syntax.tinfo; }; esubti = tichase(esubti); let isagg: bool = esubti != nil - && (esubti.kind == tykind.TY_STRUCT - || esubti.kind == tykind.TY_ARRAY - || esubti.kind == tykind.TY_TUPLE); + && (esubti.kind == syntax.tykind.TY_STRUCT + || esubti.kind == syntax.tykind.TY_ARRAY + || esubti.kind == syntax.tykind.TY_TUPLE); if (isagg) { esz = esubti.size: i32; }; // #20/#270 str-slice arm: a slice element (N_TSLICE) is // a 24B {ptr,len,cap} header — it matches no prim/str/agg @@ -38300,7 +38300,7 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // store dropped .len/.cap. Size it from the stamped tinfo // and route it through the 3-word header store below. let isslicel: bool = esubti != nil - && esubti.kind == tykind.TY_SLICE; + && esubti.kind == syntax.tykind.TY_SLICE; if (isslicel) { esz = esubti.size: i32; }; // #12: a tagged-union element. NOT folded into isagg — // isagg's body word-copies/fatals and never boxes the @@ -38311,7 +38311,7 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // 1/2/4, so a tagged 16/24B element keeps the wrong 8 // sentinel stride without this. let istaggedel: bool = esubti != nil - && esubti.kind == tykind.TY_TAGGED; + && esubti.kind == syntax.tykind.TY_TAGGED; if (istaggedel) { esz = esubti.size: i32; }; // #8: a named-narrow element (`[N]tk`, tk = enum i32) is // neither a builtin prim (primsize=0 above, so esz stayed @@ -38338,11 +38338,11 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { if (isf32type(c, elemn)) { fmov = "MOVSS"; }; let idx: i32 = 0; let repeat: bool = false; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { let isellip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; isellip = true; }; @@ -38351,10 +38351,10 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { e = nil; } else { if (isagg) { - if (e.kind == nkind.N_STRUCTLIT) { + if (e.kind == syntax.nkind.N_STRUCTLIT) { let esi: *structinfo = structlookupchain(c, elemn); cgstructlitfillbp(c, esi, e, off + idx * esz); - } else { if (e.kind == nkind.N_IDENT) { + } else { if (e.kind == syntax.nkind.N_IDENT) { let sl: *local = localfindnode(c, e.str); let soff: i32 = 0; if (sl != nil) { soff = sl.off; }; @@ -38450,9 +38450,9 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { if (repeat) { let total: i32 = idx; if (arrtn != nil) { - if (arrtn.kind == nkind.N_TARRAY) { + if (arrtn.kind == syntax.nkind.N_TARRAY) { if (arrtn.rhs != nil) { - if (arrtn.rhs.kind == nkind.N_INTLIT) { + if (arrtn.rhs.kind == syntax.nkind.N_INTLIT) { total = arrtn.rhs.uval: i32; }; }; @@ -38496,10 +38496,10 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // c.locals while cgletbody runs (Hare evals the init in the outer scope: // harec check.c clet runs cexpr before scope_define). localreserve bumps // the frame now so off + nested-let offsets stay stable. -fn cglet(c: *cgen, n: *node) void = { +fn cglet(c: *cgen, n: *syntax.node) void = { let nm: str = n.str; let sz: i32 = letslotsize(c, n); - let tn: *node = n.lhs; + let tn: *syntax.node = n.lhs; if (tn == nil) { tn = inferletcalltype(c, n.rhs); }; let letloc: *local = localreserve(c, nm, sz, tn); cgletbody(c, n, letloc.off); @@ -38512,16 +38512,16 @@ fn cglet(c: *cgen, n: *node) void = { // binding into c.locals only AFTER, so a self-shadowing init // (`let x = f(x)`) resolves x in the OUTER scope (Hare evals the init in // the outer scope: harec check.c clet runs cexpr before scope_define). -fn cgletbody(c: *cgen, n: *node, off: i32) void = { +fn cgletbody(c: *cgen, n: *syntax.node, off: i32) void = { let nm: str = n.str; let sz: i32 = letslotsize(c, n); // `let x = f()?` has no annotation but the cgen's struct-field // paths need a tnode to dispatch off. Infer from f's tagged // success variant — see inferletcalltype. - let tn: *node = n.lhs; + let tn: *syntax.node = n.lhs; if (tn == nil) { tn = inferletcalltype(c, n.rhs); }; if (n.rhs != nil) { - let rhs: *node = n.rhs; + let rhs: *syntax.node = n.rhs; // `let s: []T = alloc([], n)!;` / `?` shortcut (#32, #45). // Mirror of cstage cgen.c N_LET arrlit-empty branch: allocate // n*esz bytes via rt_malloc, then build the {ptr, 0, n} slice @@ -38532,19 +38532,19 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // land an 8B region and a junk slice header). `?` propagates // nomem via AX = tag of nomem in c.fnret, then epilogue RET. { - let scall: *node = nil; + let scall: *syntax.node = nil; let viatryunw: bool = false; let viatryprop: bool = false; - if (rhs.kind == nkind.N_TRYUNW) { + if (rhs.kind == syntax.nkind.N_TRYUNW) { if (rhs.lhs != nil) { - if (rhs.lhs.kind == nkind.N_CALL) { + if (rhs.lhs.kind == syntax.nkind.N_CALL) { scall = rhs.lhs; viatryunw = true; }; }; - } else { if (rhs.kind == nkind.N_TRYPROP) { + } else { if (rhs.kind == syntax.nkind.N_TRYPROP) { if (rhs.lhs != nil) { - if (rhs.lhs.kind == nkind.N_CALL) { + if (rhs.lhs.kind == syntax.nkind.N_CALL) { scall = rhs.lhs; viatryprop = true; }; @@ -38557,18 +38557,18 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // silently miss after #1 if check.ww's astsize ever // drifted from this dispatch. if (scall != nil && tn != nil - && tn.kind == nkind.N_TSLICE && sz == tyslicesize(): i32) { - let callee: *node = scall.lhs; - let a0: *node = scall.list; - let a1: *node = nil; - let a2: *node = nil; + && tn.kind == syntax.nkind.N_TSLICE && sz == tyslicesize(): i32) { + let callee: *syntax.node = scall.lhs; + let a0: *syntax.node = scall.list; + let a1: *syntax.node = nil; + let a2: *syntax.node = nil; if (a0 != nil) { a1 = a0.next; }; if (a1 != nil) { a2 = a1.next; }; if (callee != nil && a0 != nil && a1 != nil && a2 == nil) { - if (callee.kind == nkind.N_IDENT - && streq(callee.str, "alloc") - && a0.kind == nkind.N_ARRLIT + if (callee.kind == syntax.nkind.N_IDENT + && syntax.streq(callee.str, "alloc") + && a0.kind == syntax.nkind.N_ARRLIT && a0.list == nil) { shapeok = true; }; @@ -38582,7 +38582,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // cstage path byte-identically. A bare primsize/slotsize // fork would silently land esz=1 on `[]point`. let esz: i32 = elemsizeofc(c, tn); - let count: *node = scall.list.next; + let count: *syntax.node = scall.list.next; cgexpr(c, count); emitline("\tPUSHQ\tAX\n"); if (esz > 1) { @@ -38623,14 +38623,14 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // holds no tinfo singleton, so find the nomem // variant by its NAMED name over tinfo.params. let nidx: i32 = -1; - let nti: *tinfo = nil; - if (c.fnret != nil) { nti = c.fnret.type_: *tinfo; }; + let nti: *syntax.tinfo = nil; + if (c.fnret != nil) { nti = c.fnret.type_: *syntax.tinfo; }; nti = tichase(nti); - if (nti != nil) { if (nti.kind == tykind.TY_TAGGED) { - let np: *tparam = nti.params; + if (nti != nil) { if (nti.kind == syntax.tykind.TY_TAGGED) { + let np: *syntax.tparam = nti.params; let nidx2: i32 = 0; for (np != nil) { - let nvt: *tinfo = np.type_; + let nvt: *syntax.tinfo = np.type_; if (nvt != nil) { if (variantnamematch(nvt.name, "nomem")) { nidx = nidx2; break; }; }; @@ -38671,23 +38671,23 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // Mirrors cstage cgen.c N_LET tagged arm. if (istaggedtype(c, tn)) { let letsret: i32 = 0; - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { letsret = callsretsize(c, rhs); }; if (letsret == 0) { - cgwidentaggedstore(c, tn.type_: *tinfo, rhs, + cgwidentaggedstore(c, tn.type_: *syntax.tinfo, rhs, "BP", off, sz); c.lastwasreturn = 0; return; }; - let lru: *tinfo = rhs.type_: *tinfo; + let lru: *syntax.tinfo = rhs.type_: *syntax.tinfo; lru = tichase(lru); - let llu: *tinfo = tn.type_: *tinfo; + let llu: *syntax.tinfo = tn.type_: *syntax.tinfo; llu = tichase(llu); let exact38: bool = false; if (lru != nil && lru == llu) { exact38 = true; } else { - if (typeeq(rhs.type_: *tinfo, tn.type_: *tinfo)) { + if (syntax.typeeq(rhs.type_: *syntax.tinfo, tn.type_: *syntax.tinfo)) { exact38 = true; }; }; @@ -38721,12 +38721,12 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // keying). Alias-peel mirrors cstage's type_chase_named; the // unannotated `let t = f()` shape rides the inferletcalltype // tn above. - let ttup: *node = tn; - for (ttup != nil && ttup.kind == nkind.N_TNAME) { + let ttup: *syntax.node = tn; + for (ttup != nil && ttup.kind == syntax.nkind.N_TNAME) { ttup = aliaslookup(c, ttup.str); }; if (ttup != nil) { - if (ttup.kind == nkind.N_TTUPLE + if (ttup.kind == syntax.nkind.N_TTUPLE && sretretsize(c, ttup) == 0) { // #57: a tuple LITERAL rhs carries the DECLARED // type into the cursor fill — its stamped type @@ -38736,7 +38736,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // (let-twin of the return-position bug; probe // /tmp/p57/q1_let). Same emission as the cgexpr // route for every declared-tagged-free literal. - if (rhs.kind == nkind.N_TUPLE) { + if (rhs.kind == syntax.nkind.N_TUPLE) { cgtuplelittocursor(c, rhs, ttup); } else { cgexpr(c, rhs); @@ -38744,9 +38744,9 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { let gpcur: i32 = 0; let ssecur: i32 = 0; let eoff: i32 = 0; - let q: *node = ttup.list; + let q: *syntax.node = ttup.list; for (q != nil) { - let qt: *node = q.lhs; + let qt: *syntax.node = q.lhs; let isflt: bool = isfloattype(c, qt); let eslot: i32 = tupeslotn(qt); tupstore(c, gpcur, ssecur, @@ -38772,8 +38772,8 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // payload (or a void literal) slip through in-cap // (probe /tmp/i22b/p7) — the let-twin of the #22b // classify/emit skew. Mirrors cstage cgen.c N_LET net. - if (ttup.kind == nkind.N_TTUPLE - && rhs.kind != nkind.N_CALL + if (ttup.kind == syntax.nkind.N_TTUPLE + && rhs.kind != syntax.nkind.N_CALL && sretretsize(c, ttup) > 0) { cgexpr(c, rhs); let mnet: str = "over-cap tuple initialiser from a non-call source unwired (see #10/#22b)\n"; @@ -38798,7 +38798,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // (primsize's default-to-8-on-zero pattern is brittle for // composites generally. The str/slice element now stores all 3 // words; [N]tagged element arrays still hit the gap, task #12.) - if (rhs.kind == nkind.N_ARRLIT) { + if (rhs.kind == syntax.nkind.N_ARRLIT) { cgarrlitfillbp(c, n.lhs, rhs, off); c.lastwasreturn = 0; return; @@ -38809,7 +38809,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // values recursing into the helper instead of landing only AX // (the #17 silent-zero fix). Mirror of cstage cgen.c N_LET // structlit branch. - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { // #63: an alias-NAMED struct literal (`type rep2 = rep; // let r = rep2{id=6}`) parses its type ref as N_IDENT/N_TNAME // "rep2", but only the base `rep` is registered — bare @@ -38819,7 +38819,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // alias chain to the base struct, the #92/W2 SSoT already // adopted at cgenstmt:1974/:2687. cs chases via // type_chase_named, runtime-correct. - let trefn: *node = rhs.lhs; + let trefn: *syntax.node = rhs.lhs; let si: *structinfo = structlookupchain(c, trefn); if (si != nil) { cgstructlitfillbp(c, si, rhs, off); @@ -38833,7 +38833,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // before the CALL and the callee writes through it. No // AX/DX/CX shuffle; AX returns the dest pointer per SysV // sret discipline (irrelevant here). - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { let scs: i32 = callsretsize(c, rhs); if (scs > 0) { c.sretdestoff = off; @@ -38873,7 +38873,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // #169 sized tail is unreachable here. structfloatclass gates // to qualifying structs; all-int + f32 fall to the GP recv // below (byte-id / #171b). - if (rhs.kind == nkind.N_CALL && tn != nil) { + if (rhs.kind == syntax.nkind.N_CALL && tn != nil) { let sfc: i32 = structfloatclass(c, tn); if (sfc != 0) { cgexpr(c, rhs); @@ -38904,11 +38904,11 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { return; }; }; - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { let sname: str; sname.ptr = nil; sname.len = 0; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { + if (tn.kind == syntax.nkind.N_TNAME) { sname = tn.str; }; }; @@ -38966,9 +38966,9 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // above (callsretsize keyed). Array natural size (tinfo.size // = sub.size*len) mirrors cstage lu->size. No structfloatclass // (pure-int element arrays). - if (rhs.kind == nkind.N_CALL && tn != nil - && tn.kind == nkind.N_TARRAY) { - let ati: *tinfo = tn.type_: *tinfo; + if (rhs.kind == syntax.nkind.N_CALL && tn != nil + && tn.kind == syntax.nkind.N_TARRAY) { + let ati: *syntax.tinfo = tn.type_: *syntax.tinfo; ati = tichase(ati); if (ati != nil) { let lsz: i32 = ati.size: i32; @@ -39020,11 +39020,11 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // only the first qword (and a stale BX for sz==16 lets // via the str-init tail) — silent partial copy. Mirrors // cstage cgen.c N_LET struct-ident branch (Task #32). - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { let sname: str; sname.ptr = nil; sname.len = 0; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { sname = tn.str; }; + if (tn.kind == syntax.nkind.N_TNAME) { sname = tn.str; }; }; if (sname.len > 0) { let lsi: *structinfo = structlookup(c, sname); @@ -39093,25 +39093,25 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { if (aggsi != nil) { aggn = structabisize(aggsi); } else { - let aggti: *tinfo = nil; - if (tn != nil) { aggti = tn.type_: *tinfo; }; + let aggti: *syntax.tinfo = nil; + if (tn != nil) { aggti = tn.type_: *syntax.tinfo; }; aggti = tichase(aggti); if (aggti != nil) { - if (aggti.kind == tykind.TY_ARRAY) { + if (aggti.kind == syntax.tykind.TY_ARRAY) { aggn = aggti.size: i32; }; }; }; if (aggn > 8) { let havesrc: bool = false; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { cgexpr(c, rhs.lhs); emitline("\tMOVQ\tAX, SI\n"); havesrc = true; }; }; - if (!havesrc) { if (rhs.kind == nkind.N_IDENT) { + if (!havesrc) { if (rhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, rhs.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -39127,10 +39127,10 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // over-copies struct-defs on wwstage // only; mirror the defisaddressable // pairing instead. - let aggdtn: *node = defvartnode(c, rhs.str); + let aggdtn: *syntax.node = defvartnode(c, rhs.str); let aggisdef: bool = defvarstructinfo(c, rhs.str) != nil; if (aggdtn != nil) { - if (aggdtn.kind == nkind.N_TARRAY) { aggisdef = true; }; + if (aggdtn.kind == syntax.nkind.N_TARRAY) { aggisdef = true; }; }; if (isletvar(c, rhs.str) || aggisdef) { emitline("\tLEAQ\t"); @@ -39140,19 +39140,19 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { }; }; }; }; - if (!havesrc) { if (rhs.kind == nkind.N_DOT) { + if (!havesrc) { if (rhs.kind == syntax.nkind.N_DOT) { if (dotchainaddr(c, rhs, "SI")) { havesrc = true; }; }; }; - if (!havesrc) { if (rhs.kind == nkind.N_INDEX) { - let base: *node = rhs.lhs; - let idx: *node = rhs.rhs; - let bu: *tinfo = nil; - if (base != nil) { bu = base.type_: *tinfo; }; + if (!havesrc) { if (rhs.kind == syntax.nkind.N_INDEX) { + let base: *syntax.node = rhs.lhs; + let idx: *syntax.node = rhs.rhs; + let bu: *syntax.tinfo = nil; + if (base != nil) { bu = base.type_: *syntax.tinfo; }; bu = tichase(bu); - if (base != nil && base.kind == nkind.N_IDENT - && bu != nil && bu.kind == tykind.TY_ARRAY) { + if (base != nil && base.kind == syntax.nkind.N_IDENT + && bu != nil && bu.kind == syntax.tykind.TY_ARRAY) { let esz: i32 = 1; if (bu.sub != nil) { esz = bu.sub.size: i32; @@ -39188,8 +39188,8 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // address) or the &abase[bidx] spine (nested // N_IDENT-array base), then add. if (!havesrc && base != nil - && (base.kind == nkind.N_DOT - || base.kind == nkind.N_INDEX)) { + && (base.kind == syntax.nkind.N_DOT + || base.kind == syntax.nkind.N_INDEX)) { let esz2: i32 = 1; if (bu != nil && bu.sub != nil) { esz2 = bu.sub.size: i32; @@ -39203,18 +39203,18 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { }; emitline("\tPUSHQ\tAX\n"); let baseok: bool = false; - if (base.kind == nkind.N_DOT) { + if (base.kind == syntax.nkind.N_DOT) { if (dotbaseaddr(c, base, "AX")) { baseok = true; }; } else { - let ab: *node = base.lhs; - let bidx: *node = base.rhs; - let abu: *tinfo = nil; - if (ab != nil) { abu = ab.type_: *tinfo; }; + let ab: *syntax.node = base.lhs; + let bidx: *syntax.node = base.rhs; + let abu: *syntax.tinfo = nil; + if (ab != nil) { abu = ab.type_: *syntax.tinfo; }; abu = tichase(abu); - if (ab != nil && ab.kind == nkind.N_IDENT - && abu != nil && abu.kind == tykind.TY_ARRAY) { + if (ab != nil && ab.kind == syntax.nkind.N_IDENT + && abu != nil && abu.kind == syntax.tykind.TY_ARRAY) { let aesz: i32 = 1; if (abu.sub != nil) { aesz = abu.sub.size: i32; @@ -39307,10 +39307,10 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // cgen.c N_LET; pre-C4 this shape fell through to the // cgtryunw/cgtryprop gates, which the C4 tail below // now pre-empts in let position). - if (rhs.kind == nkind.N_TRYUNW - || rhs.kind == nkind.N_TRYPROP) { + if (rhs.kind == syntax.nkind.N_TRYUNW + || rhs.kind == syntax.nkind.N_TRYPROP) { if (rhs.lhs != nil) { - if (rhs.lhs.kind == nkind.N_CALL) { + if (rhs.lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, rhs.lhs) > 0) { let m38f: str = "#38b: `?`/`!` on an sret-class call result unwired (mem-based unwrap is a #40-family follow-up)\n"; os.write(2, m38f.ptr, m38f.len: u64); @@ -39407,14 +39407,14 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // would over-zero MOVQ-rounded to 24 and diverge from // cstage's exact 20-byte run. Handles direct N_TARRAY and // alias-to-array (N_TNAME chasing through TY_NAMED) alike. - let zti: *tinfo = n.lhs.type_: *tinfo; + let zti: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; zti = tichase(zti); - if (zti != nil && zti.kind == tykind.TY_ARRAY) { + if (zti != nil && zti.kind == syntax.tykind.TY_ARRAY) { zsz = zti.size: i32; - } else { if (n.lhs.kind == nkind.N_TNAME) { + } else { if (n.lhs.kind == syntax.nkind.N_TNAME) { let szi: *structinfo = structlookupchain(c, n.lhs); if (szi != nil) { - let ti: *tinfo = n.lhs.type_: *tinfo; + let ti: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; ti = tichase(ti); if (ti != nil) { zsz = ti.size: i32; }; }; @@ -39472,7 +39472,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { return; }; -fn cgif(c: *cgen, n: *node) void = { +fn cgif(c: *cgen, n: *syntax.node) void = { let els: str = mklabel(c, "else"); let endl: str = mklabel(c, "end"); cgexpr(c, n.cond); @@ -39492,7 +39492,7 @@ fn cgif(c: *cgen, n: *node) void = { return; }; -fn cgfor(c: *cgen, n: *node) void = { +fn cgfor(c: *cgen, n: *syntax.node) void = { // Match C cgen's label scheme: _loop_N for the top, // _endloop_N for the post-body merge. No separate cont // label when there's no post-expression. @@ -39556,7 +39556,7 @@ fn cgfor(c: *cgen, n: *node) void = { // the first lvalue, then pop DX into the second. Mirrors // cmd/w6c/cgen.c:2424-2440. Lvalues beyond two are dropped (same // as C — no fixture uses >2 today). -fn cgmassign(c: *cgen, n: *node) void = { +fn cgmassign(c: *cgen, n: *syntax.node) void = { // #83: positional per-element destructure REASSIGN. Same cursor as // cgmlet (and cgreturn; harec create_unpack_bindings, // ref/harec/src/check.c:1354-1416), but the slots already exist @@ -39569,7 +39569,7 @@ fn cgmassign(c: *cgen, n: *node) void = { // comma `a, s = f()` multi-assign is a retained ww-EXTENSION beyond // Hare (Hare tuple-unpack is binding-only); ww keeps the Go/rob-pike // multi-assign idiom — rule-9 carve-out. Over-capacity loud-stops. - let rettuple: *node = rettupleof(c, n.rhs); + let rettuple: *syntax.node = rettupleof(c, n.rhs); // #10 Fold B: over-cap tuple destructure REASSIGN. Same sret copy-out // as cgmlet but the slots already exist (localfind); a `_` / missing @@ -39578,7 +39578,7 @@ fn cgmassign(c: *cgen, n: *node) void = { // cstage N_MASSIGN over-cap arm. let sretrecv: i32 = 0; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { + if (n.rhs.kind == syntax.nkind.N_CALL) { sretrecv = callsretsize(c, n.rhs); }; }; @@ -39592,16 +39592,16 @@ fn cgmassign(c: *cgen, n: *node) void = { // fill/receive fall back to the rhs literal element's own stamped type // for the cursor stride (harec `_` advance; pinned by the R3 control). let litrhs: bool = false; - if (n.rhs != nil) { if (n.rhs.kind == nkind.N_TUPLE) { litrhs = true; }; }; - let synthdecl: *node = nil; + if (n.rhs != nil) { if (n.rhs.kind == syntax.nkind.N_TUPLE) { litrhs = true; }; }; + let synthdecl: *syntax.node = nil; if (litrhs) { - synthdecl = newnode(nkind.N_TTUPLE, n.rhs.file, n.rhs.line, n.rhs.col); - let dtail: *node = nil; - let lb0: *node = n.list; + synthdecl = syntax.newnode(syntax.nkind.N_TTUPLE, n.rhs.file, n.rhs.line, n.rhs.col); + let dtail: *syntax.node = nil; + let lb0: *syntax.node = n.list; for (lb0 != nil) { - let w: *node = newnode(nkind.N_TUPLE, n.rhs.file, n.rhs.line, n.rhs.col); + let w: *syntax.node = syntax.newnode(syntax.nkind.N_TUPLE, n.rhs.file, n.rhs.line, n.rhs.col); w.lhs = nil; - if (lb0.kind == nkind.N_IDENT) { + if (lb0.kind == syntax.nkind.N_IDENT) { let lc0: *local = localfindnode(c, lb0.str); if (lc0 != nil) { w.lhs = lc0.tnode; }; }; @@ -39617,12 +39617,12 @@ fn cgmassign(c: *cgen, n: *node) void = { if (sretrecv > 0) { let scr: i32 = localfind(c, "@sretscr"); - let pt2: *node = nil; + let pt2: *syntax.node = nil; if (rettuple != nil) { pt2 = rettuple.list; }; let foff: i32 = 0; - let lb: *node = n.list; + let lb: *syntax.node = n.list; for (lb != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (pt2 != nil) { tn = pt2.lhs; }; let isflt: bool = isfloattype(c, tn); // #22b: the >8B copy-out keys on the ACCESSOR's slot @@ -39635,11 +39635,11 @@ fn cgmassign(c: *cgen, n: *node) void = { let eslot: i32 = tupeslotn(tn); let esz: i32 = 8; if (pt2 != nil) { - let eti: *tinfo = pt2.lhs.type_: *tinfo; + let eti: *syntax.tinfo = pt2.lhs.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; }; let off: i32 = 0; - if (lb.kind == nkind.N_IDENT) { off = localfind(c, lb.str); }; + if (lb.kind == syntax.nkind.N_IDENT) { off = localfind(c, lb.str); }; if (off != 0) { if (isflt) { let mov: str = "MOVSD"; @@ -39689,18 +39689,18 @@ fn cgmassign(c: *cgen, n: *node) void = { let ssecap: i32 = TUPLE_SSECAP; // X0,X1 per SysV let gptotal: i32 = 0; let ssetotal: i32 = 0; - let l: *node = n.list; - let pt: *node = nil; + let l: *syntax.node = n.list; + let pt: *syntax.node = nil; if (rettuple != nil) { pt = rettuple.list; }; // #64: a tuple-LITERAL rhs keys element WIDTH on the DECLARED lvalue // type (synthdecl), not the rettuple (nil for a literal); a `_` slot // (declared type nil) falls back to the rhs literal element's own // stamped type for the cursor stride. - let dp: *node = nil; - let re: *node = nil; + let dp: *syntax.node = nil; + let re: *syntax.node = nil; if (litrhs) { dp = synthdecl.list; re = n.rhs.list; }; for (l != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (litrhs) { if (dp != nil && dp.lhs != nil) { tn = dp.lhs; } else { tn = re; }; } else { @@ -39738,7 +39738,7 @@ fn cgmassign(c: *cgen, n: *node) void = { re = nil; if (litrhs) { dp = synthdecl.list; re = n.rhs.list; }; for (l != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (litrhs) { if (dp != nil && dp.lhs != nil) { tn = dp.lhs; } else { tn = re; }; } else { @@ -39747,7 +39747,7 @@ fn cgmassign(c: *cgen, n: *node) void = { let isflt: bool = isfloattype(c, tn); let eslot: i32 = tupeslotn(tn); let off: i32 = 0; - if (l.kind == nkind.N_IDENT) { off = localfind(c, l.str); }; + if (l.kind == syntax.nkind.N_IDENT) { off = localfind(c, l.str); }; // harec `_` (off==0): skip the store but CONSUME the cursor // slot so the next element stays aligned. if (off != 0) { @@ -39778,8 +39778,8 @@ fn cgmassign(c: *cgen, n: *node) void = { // as (.ptr, .len, .cap). Position-agnostic — the // regs are routed by element type, not by AX/DX. // str IS []u8 (24B): cap rides R8 (#1/Phase 3, task #5). -fn cgmlet(c: *cgen, n: *node) void = { - let rhs: *node = n.rhs; +fn cgmlet(c: *cgen, n: *syntax.node) void = { + let rhs: *syntax.node = n.rhs; if (rhs == nil) { return; }; // #83: positional per-element destructure let-binding. Same cursor @@ -39790,7 +39790,7 @@ fn cgmlet(c: *cgen, n: *node) void = { // walked in lockstep. A slice/str rides its 3-word {ptr,len,cap} // header (ref/hare/rt/ensure.ha:4-8) into a header-sized slot; a // scalar rides 1 word into an 8B slot. Over-capacity loud-stops. - let rettuple: *node = rettupleof(c, rhs); + let rettuple: *syntax.node = rettupleof(c, rhs); // #10 Fold B: over-cap tuple destructure RECEIVE. The callee sret'd // the whole tuple into the @sretscr discard slot (cgcall sees @@ -39799,7 +39799,7 @@ fn cgmlet(c: *cgen, n: *node) void = { // element size — the t.0/t.1 layout), each at its NATURAL width // (#169). Byte-identical to the cstage N_MLET over-cap arm. let sretrecv: i32 = 0; - if (rhs.kind == nkind.N_CALL) { sretrecv = callsretsize(c, rhs); }; + if (rhs.kind == syntax.nkind.N_CALL) { sretrecv = callsretsize(c, rhs); }; // #242: rhs is a tuple already materialised in a local slot (a match- // bound union payload, `let (a,b)=t`), NOT a register-returning call. @@ -39809,22 +39809,22 @@ fn cgmlet(c: *cgen, n: *node) void = { // the SAME layout the tagged construct + match payload-bind write. // Mirror of cstage cgen.c N_MLET tuple-ident arm. The binding element // types ride l.lhs (stamped by the checker's stamptuplebinds). - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { let rl: *local = localfindnode(c, rhs.str); if (rl != nil) { - let rti: *tinfo = rl.tnode.type_: *tinfo; + let rti: *syntax.tinfo = rl.tnode.type_: *syntax.tinfo; rti = tichase(rti); - if (rti != nil) { if (rti.kind == tykind.TY_TUPLE) { + if (rti != nil) { if (rti.kind == syntax.tykind.TY_TUPLE) { let srcoff: i32 = rl.off; let foff: i32 = 0; - let lb: *node = n.list; + let lb: *syntax.node = n.list; for (lb != nil) { - let tn: *node = lb.lhs; + let tn: *syntax.node = lb.lhs; let isflt: bool = isfloattype(c, tn); let eslot: i32 = tupeslotn(tn); let esz: i32 = 8; - let eti: *tinfo = nil; - if (tn != nil) { eti = tn.type_: *tinfo; }; + let eti: *syntax.tinfo = nil; + if (tn != nil) { eti = tn.type_: *syntax.tinfo; }; if (eti != nil) { esz = eti.size: i32; }; let bsz: i32 = 8; if (eslot > 8) { bsz = eslot; }; @@ -39870,18 +39870,18 @@ fn cgmlet(c: *cgen, n: *node) void = { if (sretrecv > 0) { let scr: i32 = localfind(c, "@sretscr"); - let pt2: *node = nil; + let pt2: *syntax.node = nil; if (rettuple != nil) { pt2 = rettuple.list; }; let foff: i32 = 0; - let lb: *node = n.list; + let lb: *syntax.node = n.list; for (lb != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (pt2 != nil) { tn = pt2.lhs; }; let isflt: bool = isfloattype(c, tn); let eslot: i32 = tupeslotn(tn); let esz: i32 = 8; if (pt2 != nil) { - let eti: *tinfo = pt2.lhs.type_: *tinfo; + let eti: *syntax.tinfo = pt2.lhs.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; }; let bsz: i32 = 8; @@ -39929,11 +39929,11 @@ fn cgmlet(c: *cgen, n: *node) void = { let ssecap: i32 = TUPLE_SSECAP; // X0,X1 per SysV let gptotal: i32 = 0; let ssetotal: i32 = 0; - let l: *node = n.list; - let pt: *node = nil; + let l: *syntax.node = n.list; + let pt: *syntax.node = nil; if (rettuple != nil) { pt = rettuple.list; }; for (l != nil) { - let tn: *node = l.lhs; + let tn: *syntax.node = l.lhs; if (tn == nil) { if (pt != nil) { tn = pt.lhs; }; }; @@ -39964,7 +39964,7 @@ fn cgmlet(c: *cgen, n: *node) void = { pt = nil; if (rettuple != nil) { pt = rettuple.list; }; for (l != nil) { - let tn: *node = l.lhs; + let tn: *syntax.node = l.lhs; if (tn == nil) { if (pt != nil) { tn = pt.lhs; }; }; @@ -39990,19 +39990,19 @@ fn cgmlet(c: *cgen, n: *node) void = { // `tp->type->size` read in C cgen N_FORRANGE: 1 for i8/u8/bool, 4 for // i32/u32, 8 for i64/u64/*T/fn, 24 for str/slice (str IS []u8, the slice // header SSoT), tuple → sum of its 8B-floored element slots, default 8. -fn paramfieldsize(t: *node) i32 = { +fn paramfieldsize(t: *syntax.node) i32 = { if (t == nil) { return 8; }; - let k: nkind = t.kind; - if (k == nkind.N_TPTR) { return 8; }; - if (k == nkind.N_TFN) { return 8; }; - if (k == nkind.N_TCHAN) { return 8; }; + let k: syntax.nkind = t.kind; + if (k == syntax.nkind.N_TPTR) { return 8; }; + if (k == syntax.nkind.N_TFN) { return 8; }; + if (k == syntax.nkind.N_TCHAN) { return 8; }; // #43 (F7-c4): a slice tuple-field carries the 24B header (ptr+len+ // cap), not the 8B scalar default. Without this arm the for-range // destructure over `[N]([]T, U)` strode the tuple at 8 not 24 and // read field-2 at the wrong offset (cs=42/ww=8, the cat-A repro). // tyslicesize() is the slice-header SSoT (rule-13); cstage reads the // same width via tp->type->size (cmd/w6c/cgen.c N_FORRANGE). - if (k == nkind.N_TSLICE) { return tyslicesize(): i32; }; + if (k == syntax.nkind.N_TSLICE) { return tyslicesize(): i32; }; // #53: a tagged-union tuple-field carries its full box (tag + widest // payload, slot-padded), NOT the 8B scalar default — a for-range // destructure binding sized 8 loaded only the tag word (cs=56/ww=9, the @@ -40012,10 +40012,10 @@ fn paramfieldsize(t: *node) i32 = { // covers an N_TNAME field naming a tagged union (paramfieldsize's no-`c` // structural contract can't aliaslookup-chase the node). Mirrors the // N_TSLICE arm's type-table SSoT. - let tgi: *tinfo = t.type_: *tinfo; + let tgi: *syntax.tinfo = t.type_: *syntax.tinfo; if (tgi != nil) { tgi = tichase(tgi); - if (tgi != nil && tgi.kind == tykind.TY_TAGGED) { + if (tgi != nil && tgi.kind == syntax.tykind.TY_TAGGED) { return tgi.size: i32; }; }; @@ -40024,9 +40024,9 @@ fn paramfieldsize(t: *node) i32 = { // their 24B header), per the tuple-slot ruling and tupeslot's // roundup8. Recurse structurally so a tuple-of-tuple lands the same // stride cstage's tp->type->size computes. - if (k == nkind.N_TTUPLE) { + if (k == syntax.nkind.N_TTUPLE) { let total: i32 = 0; - let dp: *node = t.list; + let dp: *syntax.node = t.list; for (dp != nil) { let esz: i32 = paramfieldsize(dp.lhs); total = total + (esz + 7) / 8 * 8; @@ -40034,9 +40034,9 @@ fn paramfieldsize(t: *node) i32 = { }; return total; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; - if (streq(nm, "str")) { return primtypesize("str"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("str"): i32; }; // primsize-ok (#101/#109): paramfieldsize is a STRUCTURAL // (no-`c`, no-chase) sizer by design — it takes a *node, not a // *cgen, so it cannot run aliasprimsize's aliaslookup chase @@ -40062,7 +40062,7 @@ fn paramfieldsize(t: *node) i32 = { // paramissigned — does this type need sign-extending on a sub-word // (1/2/4B) load? Mirrors cstage's signed_field check via // fieldissignedc (resolves TBANG / TENUM / alias chains). -fn paramissigned(c: *cgen, t: *node) bool = { +fn paramissigned(c: *cgen, t: *syntax.node) bool = { return fieldissignedc(c, t); }; @@ -40073,22 +40073,22 @@ fn paramissigned(c: *cgen, t: *node) bool = { // either loads the whole element into the named local or pulls each // tuple field into its own local. Mirrors cmd/w6c/cgen.c N_FORRANGE // byte-for-byte (label names + labelseq consumption order). -fn cgforrange(c: *cgen, n: *node) void = { - let slc: *node = n.lhs; +fn cgforrange(c: *cgen, n: *syntax.node) void = { + let slc: *syntax.node = n.lhs; let slclocal: *local = nil; - let slctn: *node = nil; + let slctn: *syntax.node = nil; if (slc != nil) { - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { slclocal = localfindnode(c, slc.str); if (slclocal != nil) { slctn = slclocal.tnode; }; }; }; // Element type — peek through TSLICE/TARRAY for the tuple param walk. - let elemt: *node = nil; + let elemt: *syntax.node = nil; if (slctn != nil) { - let sk: nkind = slctn.kind; - if (sk == nkind.N_TSLICE) { elemt = slctn.lhs; }; - if (sk == nkind.N_TARRAY) { elemt = slctn.lhs; }; + let sk: syntax.nkind = slctn.kind; + if (sk == syntax.nkind.N_TSLICE) { elemt = slctn.lhs; }; + if (sk == syntax.nkind.N_TARRAY) { elemt = slctn.lhs; }; // str IS []u8 (F1: tystr.sub = tyu8). []u8 hands cgen a real // u8 element node (slctn.lhs); a str scrutinee has none, so the // loop var would register tnode=nil and read back as a wide @@ -40097,12 +40097,12 @@ fn cgforrange(c: *cgen, n: *node) void = { // read-back to MOVZBQ on its own — aligning wwstage up to // cstage, whose checker stamps the binding u8. Kind-gated so // str's own type stays nominal. - if (sk == nkind.N_TNAME) { - if (streq(slctn.str, "str")) { - let sti: *tinfo = slctn.type_: *tinfo; + if (sk == syntax.nkind.N_TNAME) { + if (syntax.streq(slctn.str, "str")) { + let sti: *syntax.tinfo = slctn.type_: *syntax.tinfo; if (sti != nil) { if (sti.sub != nil) { - let u8n: *node = newnode(nkind.N_TNAME, slctn.file, slctn.line, slctn.col); + let u8n: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, slctn.file, slctn.line, slctn.col); u8n.str = "u8"; u8n.type_ = sti.sub: *void; elemt = u8n; @@ -40119,18 +40119,18 @@ fn cgforrange(c: *cgen, n: *node) void = { // (slc->type) feeds esz/alen/base classify uniformly) and // synthesise the element node off .sub — the FC0 non-ident // precedent below. - let rti60: *tinfo = nil; + let rti60: *syntax.tinfo = nil; if (slctn != nil) { - if (slctn.kind == nkind.N_TNAME) { - let st60: *tinfo = slctn.type_: *tinfo; + if (slctn.kind == syntax.nkind.N_TNAME) { + let st60: *syntax.tinfo = slctn.type_: *syntax.tinfo; if (st60 != nil) { - if (st60.kind == tykind.TY_NAMED) { rti60 = tichase(st60); }; + if (st60.kind == syntax.tykind.TY_NAMED) { rti60 = tichase(st60); }; }; }; }; if (rti60 != nil && elemt == nil) { if (rti60.sub != nil) { - let en60: *node = newnode(nkind.N_TNAME, slctn.file, slctn.line, slctn.col); + let en60: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, slctn.file, slctn.line, slctn.col); en60.str = rti60.sub.name; en60.type_ = rti60.sub: *void; elemt = en60; @@ -40150,13 +40150,13 @@ fn cgforrange(c: *cgen, n: *node) void = { // #60: alias-NAMED scrutinee — stride off the chased stamped // element (cstage esz = u->sub->size). if (rti60 != nil) { - let es60: *tinfo = tichase(rti60.sub); + let es60: *syntax.tinfo = tichase(rti60.sub); if (es60 != nil) { esz = es60.size: i32; }; }; if (elemt != nil) { - if (elemt.kind == nkind.N_TTUPLE) { + if (elemt.kind == syntax.nkind.N_TTUPLE) { let total: i32 = 0; - let p: *node = elemt.list; + let p: *syntax.node = elemt.list; for (p != nil) { total += paramfieldsize(p.lhs); p = p.next; @@ -40173,15 +40173,15 @@ fn cgforrange(c: *cgen, n: *node) void = { // str/slice/float keys read it like a declared local (the str→u8 // synthesis precedent above). if (slctn == nil && slc != nil) { - let sti2: *tinfo = slc.type_: *tinfo; + let sti2: *syntax.tinfo = slc.type_: *syntax.tinfo; sti2 = tichase(sti2); if (sti2 != nil) { - if (sti2.kind == tykind.TY_SLICE - || sti2.kind == tykind.TY_STR - || sti2.kind == tykind.TY_ARRAY) { + if (sti2.kind == syntax.tykind.TY_SLICE + || sti2.kind == syntax.tykind.TY_STR + || sti2.kind == syntax.tykind.TY_ARRAY) { if (sti2.sub != nil) { esz = sti2.sub.size: i32; - let en: *node = newnode(nkind.N_TNAME, slc.file, slc.line, slc.col); + let en: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, slc.file, slc.line, slc.col); en.str = sti2.sub.name; en.type_ = sti2.sub: *void; elemt = en; @@ -40208,12 +40208,12 @@ fn cgforrange(c: *cgen, n: *node) void = { let loff: i32 = localalloc(c, lname, 8, nil); let baseoff: i32 = 0; if (slc != nil) { - if (slc.kind != nkind.N_IDENT) { - let stu70: *tinfo = slc.type_: *tinfo; + if (slc.kind != syntax.nkind.N_IDENT) { + let stu70: *syntax.tinfo = slc.type_: *syntax.tinfo; stu70 = tichase(stu70); let arr70: bool = false; if (stu70 != nil) { - if (stu70.kind == tykind.TY_ARRAY) { + if (stu70.kind == syntax.tykind.TY_ARRAY) { arr70 = true; }; }; @@ -40226,8 +40226,8 @@ fn cgforrange(c: *cgen, n: *node) void = { // the AX/BX/CX header convention the spill assumes // (the deref-spine load family) — keep it LOUD until // #11 wires the deref load. - if (slc.kind == nkind.N_UN) { - if (slc.op == tkind.TK_STAR) { + if (slc.kind == syntax.nkind.N_UN) { + if (slc.op == syntax.tkind.TK_STAR) { let m11: str = "for-range over a deref base unwired (#11)\n"; os.write(2, m11.ptr, m11.len: u64); os.exit(1); @@ -40246,13 +40246,13 @@ fn cgforrange(c: *cgen, n: *node) void = { // into the for-range spine) is a DISTINCT mechanism — filed as a #121 // sibling, off fold-6's path. if (slc != nil) { - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { if (localfindnode(c, slc.str) == nil) { let isglob: bool = isletvar(c, slc.str); if (!isglob) { - let gdtn: *node = defvartnode(c, slc.str); + let gdtn: *syntax.node = defvartnode(c, slc.str); if (gdtn != nil) { - if (gdtn.kind == nkind.N_TARRAY) { isglob = true; }; + if (gdtn.kind == syntax.nkind.N_TARRAY) { isglob = true; }; }; }; if (isglob) { @@ -40273,12 +40273,12 @@ fn cgforrange(c: *cgen, n: *node) void = { let nbinds: i32 = 0; if (destruct) { - let tp: *node = nil; + let tp: *syntax.node = nil; if (elemt != nil) { - if (elemt.kind == nkind.N_TTUPLE) { tp = elemt.list; }; + if (elemt.kind == syntax.nkind.N_TTUPLE) { tp = elemt.list; }; }; let field_off: i32 = 0; - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { if (nbinds >= 8) { m = nil; } else { @@ -40286,7 +40286,7 @@ fn cgforrange(c: *cgen, n: *node) void = { let signf: bool = false; // tp walks the N_TPARAM wrapper chain; tpt is the // actual element type AST. - let tpt: *node = nil; + let tpt: *syntax.node = nil; if (tp != nil) { tpt = tp.lhs; }; if (tpt != nil) { fsz = paramfieldsize(tpt); @@ -40340,22 +40340,22 @@ fn cgforrange(c: *cgen, n: *node) void = { let isarr: bool = false; let isslicestr: bool = false; if (slctn != nil) { - let tk: nkind = slctn.kind; - if (tk == nkind.N_TSLICE) { isslicestr = true; }; - if (tk == nkind.N_TARRAY) { isarr = true; }; - if (tk == nkind.N_TNAME) { - if (streq(slctn.str, "str")) { isslicestr = true; }; + let tk: syntax.nkind = slctn.kind; + if (tk == syntax.nkind.N_TSLICE) { isslicestr = true; }; + if (tk == syntax.nkind.N_TARRAY) { isarr = true; }; + if (tk == syntax.nkind.N_TNAME) { + if (syntax.streq(slctn.str, "str")) { isslicestr = true; }; }; }; // #60: alias-NAMED scrutinee — classify off the chased stamped // kind (cstage gates on u->kind TY_SLICE/TY_STR vs TY_ARRAY). if (rti60 != nil) { - if (rti60.kind == tykind.TY_ARRAY) { isarr = true; }; - if (rti60.kind == tykind.TY_SLICE) { isslicestr = true; }; - if (rti60.kind == tykind.TY_STR) { isslicestr = true; }; + if (rti60.kind == syntax.tykind.TY_ARRAY) { isarr = true; }; + if (rti60.kind == syntax.tykind.TY_SLICE) { isslicestr = true; }; + if (rti60.kind == syntax.tykind.TY_STR) { isslicestr = true; }; }; if (isslicestr) { - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { if (slclocal != nil) { emitline("\tMOVQ\t"); emitoff((slclocal.off + 8): i64); @@ -40368,7 +40368,7 @@ fn cgforrange(c: *cgen, n: *node) void = { } else { if (isarr) { let alen: i64 = 0i64; if (slctn.rhs != nil) { - if (slctn.rhs.kind == nkind.N_INTLIT) { alen = slctn.rhs.uval: i64; }; + if (slctn.rhs.kind == syntax.nkind.N_INTLIT) { alen = slctn.rhs.uval: i64; }; }; // #60: alias-NAMED scrutinee has no length tnode — bound off // the chased tinfo (cstage aimm(u->alen)). @@ -40437,7 +40437,7 @@ fn cgforrange(c: *cgen, n: *node) void = { emitline(", CX\n"); emitline("\tIMULQ\tCX, AX\n"); }; - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { if (slclocal != nil) { if (isarr) { emitline("\tLEAQ\t"); @@ -40594,7 +40594,7 @@ fn cgforrange(c: *cgen, n: *node) void = { // default and runs after all named arms fail. Mirrors cmd/w6c/cgen.c // N_SWITCH: same labelseq consumption order so labels match byte-for- // byte. -fn cgswitch(c: *cgen, n: *node) void = { +fn cgswitch(c: *cgen, n: *syntax.node) void = { let swname: str = mkscratchname(c, "sw"); let sloff: i32 = localalloc(c, swname, 8, nil); @@ -40604,9 +40604,9 @@ fn cgswitch(c: *cgen, n: *node) void = { emitline("(BP)\n"); let endl: str = mklabel(c, "swend"); - let defcase: *node = nil; + let defcase: *syntax.node = nil; - let cs: *node = n.list; + let cs: *syntax.node = n.list; for (cs != nil) { if (cs.list == nil) { defcase = cs; @@ -40615,7 +40615,7 @@ fn cgswitch(c: *cgen, n: *node) void = { }; let body: str = mklabel(c, "swcase"); let nxt: str = mklabel(c, "swnext"); - let e: *node = cs.list; + let e: *syntax.node = cs.list; for (e != nil) { cgexpr(c, e); emitline("\tMOVQ\t"); @@ -40646,7 +40646,7 @@ fn cgswitch(c: *cgen, n: *node) void = { return; }; -fn cgbreak(c: *cgen, n: *node) void = { +fn cgbreak(c: *cgen, n: *syntax.node) void = { if (c.looptop > 0) { let lbl: str = c.loopendbuf[c.looptop - 1]; emitline("\tJMP\t"); emitline(lbl); emitline("\n"); @@ -40655,7 +40655,7 @@ fn cgbreak(c: *cgen, n: *node) void = { return; }; -fn cgcontinue(c: *cgen, n: *node) void = { +fn cgcontinue(c: *cgen, n: *syntax.node) void = { if (c.looptop > 0) { let lbl: str = c.loopcontbuf[c.looptop - 1]; emitline("\tJMP\t"); emitline(lbl); emitline("\n"); @@ -40688,8 +40688,8 @@ import strconv; // ---- function-level cgen --------------------------------------------- -fn cgfnparams(c: *cgen, params: *node) void = { - let p: *node = params; +fn cgfnparams(c: *cgen, params: *syntax.node) void = { + let p: *syntax.node = params; // sret (#23): RDI is consumed by the hidden dest pointer // (already spilled to @sretarg by cgfn); the first user param // lands in SI. @@ -40705,7 +40705,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { // post-walk consistency check against stkcursor. let memwords: i32 = 0; for (p != nil) { - if (p.kind == nkind.N_PARAM) { + if (p.kind == syntax.nkind.N_PARAM) { let nm: str = p.str; // Hare-style variadic `T...`: callee receives a []T // slice (3 register words / 24B). p.lhs is already @@ -40713,8 +40713,8 @@ fn cgfnparams(c: *cgen, params: *node) void = { // (mirrors cstage check.c:455 tp->type promotion), so // we consume it directly — re-wrapping via slicewrap // would yield [][]T. - if (p.op == tkind.TK_ELLIPSIS) { - let tn: *node = p.lhs; + if (p.op == syntax.tkind.TK_ELLIPSIS) { + let tn: *syntax.node = p.lhs; if (idx + 3 <= 6) { let off: i32 = localadd(c, nm, tyslicesize(): i32, tn); emitline("\tMOVQ\t"); @@ -40777,14 +40777,14 @@ fn cgfnparams(c: *cgen, params: *node) void = { // path → 1 slot, SI dropped, t.1 garbage. Slot size + element // walk source the RESOLVED node; localadd keeps the declared // p.lhs so field reads chase identically to cstage (byte-id). - let tt99: *node = nil; + let tt99: *syntax.node = nil; if (p.lhs != nil) { tt99 = p.lhs; - for (tt99 != nil && tt99.kind == nkind.N_TNAME) { + for (tt99 != nil && tt99.kind == syntax.nkind.N_TNAME) { tt99 = aliaslookup(c, tt99.str); }; }; - if (p.lhs != nil) { if (tt99 != nil && tt99.kind == nkind.N_TTUPLE) { + if (p.lhs != nil) { if (tt99 != nil && tt99.kind == syntax.nkind.N_TTUPLE) { // #163: tuple PARAM receive (param twin of #164's // return). Walk the tuple's elements over the SysV // arg cursor — a float reads its XMM (X0..X7), @@ -40796,9 +40796,9 @@ fn cgfnparams(c: *cgen, params: *node) void = { // partial-spill stitch is out of scope (twin of #164). let off: i32 = localadd(c, nm, slotsize(c, p.lhs), p.lhs); let eoff: i32 = 0; - let te: *node = tt99.list; + let te: *syntax.node = tt99.list; for (te != nil) { - let et: *node = te.lhs; + let et: *syntax.node = te.lhs; if (isfloattype(c, et)) { if (fidx >= 8) { let msg: str = "tuple param float element overflows SSE arg regs (X0..X7); stitch out of scope, see #163\n"; @@ -40920,7 +40920,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { // greedy stitch arm below while cstage received // one scalar word (cs≠ww, silent). // ref/qbe/amd64/sysv.c:80-85 / :411-426. - if (taggedmemargsize(p.lhs.type_: *tinfo) > 0) { + if (taggedmemargsize(p.lhs.type_: *syntax.tinfo) > 0) { localaddstack(c, nm, p.lhs, 16 + stkcursor*8); stkcursor += nw; memwords += nw; @@ -41119,7 +41119,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { localaddstack(c, nm, p.lhs, 16 + stkcursor*8); stkcursor += nw; };}; - } else { let aggsz2: i32 = aggargsizetn(p.lhs.type_: *tinfo); + } else { let aggsz2: i32 = aggargsizetn(p.lhs.type_: *syntax.tinfo); if (aggsz2 > 0) { // #271: array / >16B-struct by-value param — // received as ceil(sz/8) GP eightbytes, the @@ -41198,7 +41198,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { }; }; -fn cgfn(c: *cgen, fn_: *node) void = { +fn cgfn(c: *cgen, fn_: *syntax.node) void = { cgeninit(c); c.fnname = fn_.str; c.curmod = fn_.nmod; @@ -41237,8 +41237,8 @@ fn cgfn(c: *cgen, fn_: *node) void = { // resolve identifiers via localfind, so the body's locals must // still be in c.locals when we get there. if (fn_.body != nil) { - if (fn_.body.kind == nkind.N_BLOCK) { - let s: *node = fn_.body.list; + if (fn_.body.kind == syntax.nkind.N_BLOCK) { + let s: *syntax.node = fn_.body.list; for (s != nil) { cgstmt(c, s); s = s.next; @@ -41274,7 +41274,7 @@ fn cgfn(c: *cgen, fn_: *node) void = { // fn_.nmod hint would fall through modlookupforfn's first-leaf match // onto an IMPORTED package's now-registered `pkg.main`. emitline("TEXT "); - if (streq(fn_.str, "main") && fn_.imported == 0) { + if (syntax.streq(fn_.str, "main") && fn_.imported == 0) { emitbytes(fn_.str.ptr, fn_.str.len: u64); } else { emitfnname(c, fn_.str, fn_.nmod); @@ -41294,7 +41294,7 @@ fn cgfn(c: *cgen, fn_: *node) void = { // ---- file-level entry ------------------------------------------------ -export fn cgfile(c: *cgen, file: *node) void = { +export fn cgfile(c: *cgen, file: *syntax.node) void = { if (file == nil) { return; }; c.strlits = nil; c.strlitseq = 0; @@ -41310,9 +41310,9 @@ export fn cgfile(c: *cgen, file: *node) void = { collectmods(c, file); defaultinferredlets(c, file); collectlets(c, file); - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_FNDECL) { + if (d.kind == syntax.nkind.N_FNDECL) { // #22 M3: emit code ONLY for this package's own decls. A // `.wwi` dep fn is a body-less prototype that already skips // (the body != nil gate); the explicit imported gate also @@ -41383,11 +41383,11 @@ import cgendecl; type aliasent = struct { aname: str, amod: str, // originating module (`// MODULE: foo`), or empty - target: *node, // the rhs type expr + target: *syntax.node, // the rhs type expr aanext: *aliasent, }; -fn collectaliases(c: *cgen, file: *node) void = { +fn collectaliases(c: *cgen, file: *syntax.node) void = { c.aliases = nil; // #29: seed `type nomem = !void;` here AS WELL AS in check.ww's // seedprimitives. The two seeds aren't redundant: wwstage's check @@ -41400,18 +41400,18 @@ fn collectaliases(c: *cgen, file: *node) void = { // same-module / any-match passes in aliaslookup then let a local // `type nomem = !void;` shadow this fallback within its module. let empty: str; - let tnvoid: *node = newnode(nkind.N_TNAME, empty, 0, 0); + let tnvoid: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, empty, 0, 0); tnvoid.str = "void"; - let bang: *node = newnode(nkind.N_TBANG, empty, 0, 0); + let bang: *syntax.node = syntax.newnode(syntax.nkind.N_TBANG, empty, 0, 0); bang.lhs = tnvoid; let nomemal: *aliasent = alloc(aliasent{aname="nomem", amod=empty, target=bang, aanext=nil})!; c.aliases = nomemal; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_TYPEDECL) { - let body: *node = d.lhs; + if (d.kind == syntax.nkind.N_TYPEDECL) { + let body: *syntax.node = d.lhs; if (body != nil) { - if (body.kind != nkind.N_TSTRUCT) { + if (body.kind != syntax.nkind.N_TSTRUCT) { let a: *aliasent = alloc(aliasent{aname=d.str, amod=d.nmod, target=body, aanext=c.aliases})!; c.aliases = a; }; @@ -41421,7 +41421,7 @@ fn collectaliases(c: *cgen, file: *node) void = { }; }; -fn aliaslookup(c: *cgen, name: str) *node = { +fn aliaslookup(c: *cgen, name: str) *syntax.node = { // Same-module first, then any. Mirrors cstage's scope_lookup_prefer // (cmd/wcc/check.c:65); without the prefer pass a bare `invalid` // in module M with `type invalid = !void;` can collapse onto a @@ -41431,14 +41431,14 @@ fn aliaslookup(c: *cgen, name: str) *node = { // (task #27 silent-correct-by-zero-init). let a: *aliasent = c.aliases; for (a != nil) { - if (streq(a.aname, name)) { - if (streq(a.amod, c.curmod)) { return a.target; }; + if (syntax.streq(a.aname, name)) { + if (syntax.streq(a.amod, c.curmod)) { return a.target; }; }; a = a.aanext; }; a = c.aliases; for (a != nil) { - if (streq(a.aname, name)) { return a.target; }; + if (syntax.streq(a.aname, name)) { return a.target; }; a = a.aanext; }; // Module-qualified form: `pkg.alias` → match the leaf name @@ -41460,8 +41460,8 @@ fn aliaslookup(c: *cgen, name: str) *node = { let pkgmod: str = usehint(c, pkg); let b: *aliasent = c.aliases; for (b != nil) { - if (streq(b.aname, leaf)) { - if (streq(b.amod, pkgmod)) { + if (syntax.streq(b.aname, leaf)) { + if (syntax.streq(b.amod, pkgmod)) { return b.target; }; }; @@ -41480,11 +41480,11 @@ fn aliaslookup(c: *cgen, name: str) *node = { // cgdot needs to know whether THIS module defines the name as an alias // (so the peel continues) without that cross-module fallback. Returns // the alias target only when an alias of `name` lives in c.curmod. -fn aliassamemod(c: *cgen, name: str) *node = { +fn aliassamemod(c: *cgen, name: str) *syntax.node = { let a: *aliasent = c.aliases; for (a != nil) { - if (streq(a.aname, name)) { - if (streq(a.amod, c.curmod)) { return a.target; }; + if (syntax.streq(a.aname, name)) { + if (syntax.streq(a.amod, c.curmod)) { return a.target; }; }; a = a.aanext; }; @@ -41507,34 +41507,34 @@ fn aliassamemod(c: *cgen, name: str) *node = { // Whitelist kept tight on purpose: anything richer (sibling refs, // arithmetic) belongs in enumevalmember, which calls this for its // literal leaves and handles the rest itself. -fn foldintliteral(e: *node, out: *u64) bool = { +fn foldintliteral(e: *syntax.node, out: *u64) bool = { if (e == nil) { return false; }; - let k: nkind = e.kind; - if (k == nkind.N_INTLIT) { *out = e.uval; return true; }; - if (k == nkind.N_RUNELIT) { *out = e.uval; return true; }; - if (k == nkind.N_TRUE) { *out = 1u64; return true; }; - if (k == nkind.N_FALSE) { *out = 0u64; return true; }; - if (k == nkind.N_NIL) { *out = 0u64; return true; }; - if (k == nkind.N_UN) { + let k: syntax.nkind = e.kind; + if (k == syntax.nkind.N_INTLIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_RUNELIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_TRUE) { *out = 1u64; return true; }; + if (k == syntax.nkind.N_FALSE) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_NIL) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_UN) { let v: u64; if (!foldintliteral(e.lhs, &v)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (op == tkind.TK_PLUS) { *out = v; return true; }; + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (op == syntax.tkind.TK_PLUS) { *out = v; return true; }; return false; }; return false; }; -fn enumevalmember(prev: *enummember, e: *node, out: *u64) bool = { +fn enumevalmember(prev: *enummember, e: *syntax.node, out: *u64) bool = { if (e == nil) { return false; }; if (foldintliteral(e, out)) { return true; }; - let k: nkind = e.kind; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = e.kind; + if (k == syntax.nkind.N_IDENT) { let m: *enummember = prev; for (m != nil) { - if (streq(m.mname, e.str)) { + if (syntax.streq(m.mname, e.str)) { *out = m.mval; return true; }; @@ -41542,55 +41542,55 @@ fn enumevalmember(prev: *enummember, e: *node, out: *u64) bool = { }; return false; }; - if (k == nkind.N_BIN) { + if (k == syntax.nkind.N_BIN) { let a: u64; let b: u64; if (!enumevalmember(prev, e.lhs, &a)) { return false; }; if (!enumevalmember(prev, e.rhs, &b)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_PLUS) { *out = a + b; return true; }; - if (op == tkind.TK_MINUS) { *out = a - b; return true; }; - if (op == tkind.TK_STAR) { *out = a * b; return true; }; - if (op == tkind.TK_SLASH) { + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_PLUS) { *out = a + b; return true; }; + if (op == syntax.tkind.TK_MINUS) { *out = a - b; return true; }; + if (op == syntax.tkind.TK_STAR) { *out = a * b; return true; }; + if (op == syntax.tkind.TK_SLASH) { if (b == 0u64) { return false; }; *out = a / b; return true; }; - if (op == tkind.TK_PERCENT) { + if (op == syntax.tkind.TK_PERCENT) { if (b == 0u64) { return false; }; *out = a % b; return true; }; - if (op == tkind.TK_AMP) { *out = a & b; return true; }; - if (op == tkind.TK_PIPE) { *out = a | b; return true; }; - if (op == tkind.TK_CARET) { *out = a ^ b; return true; }; - if (op == tkind.TK_LSHIFT) { *out = a << b; return true; }; - if (op == tkind.TK_RSHIFT) { *out = a >> b; return true; }; + if (op == syntax.tkind.TK_AMP) { *out = a & b; return true; }; + if (op == syntax.tkind.TK_PIPE) { *out = a | b; return true; }; + if (op == syntax.tkind.TK_CARET) { *out = a ^ b; return true; }; + if (op == syntax.tkind.TK_LSHIFT) { *out = a << b; return true; }; + if (op == syntax.tkind.TK_RSHIFT) { *out = a >> b; return true; }; return false; }; - if (k == nkind.N_UN) { + if (k == syntax.nkind.N_UN) { let v: u64; if (!enumevalmember(prev, e.lhs, &v)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (op == tkind.TK_PLUS) { *out = v; return true; }; + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (op == syntax.tkind.TK_PLUS) { *out = v; return true; }; return false; }; return false; }; -fn collectenums(c: *cgen, file: *node) void = { +fn collectenums(c: *cgen, file: *syntax.node) void = { c.enums = nil; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_TYPEDECL) { - let body: *node = d.lhs; + if (d.kind == syntax.nkind.N_TYPEDECL) { + let body: *syntax.node = d.lhs; if (body != nil) { - if (body.kind == nkind.N_TENUM) { + if (body.kind == syntax.nkind.N_TENUM) { let et: *enumtype = alloc(enumtype{ename=d.str, emod=d.nmod, storage=body.lhs, members=nil, etnext=nil})!; let prev: u64 = (-1i64): u64; let mhead: *enummember = nil; let mtail: *enummember = nil; - let m: *node = body.list; + let m: *syntax.node = body.list; for (m != nil) { let val: u64; if (m.lhs == nil) { @@ -41624,14 +41624,14 @@ fn enumlookup(c: *cgen, name: str) *enumtype = { // c.enums, silently folding `Foo.MEMBER` to the wrong constant. let e: *enumtype = c.enums; for (e != nil) { - if (streq(e.ename, name)) { - if (streq(e.emod, c.curmod)) { return e; }; + if (syntax.streq(e.ename, name)) { + if (syntax.streq(e.emod, c.curmod)) { return e; }; }; e = e.etnext; }; e = c.enums; for (e != nil) { - if (streq(e.ename, name)) { return e; }; + if (syntax.streq(e.ename, name)) { return e; }; e = e.etnext; }; // Module-qualified form embedded in name (`pkg.enum`): scope the @@ -41651,8 +41651,8 @@ fn enumlookup(c: *cgen, name: str) *enumtype = { let pkgmod: str = usehint(c, pkg); let b: *enumtype = c.enums; for (b != nil) { - if (streq(b.ename, leaf)) { - if (streq(b.emod, pkgmod)) { + if (syntax.streq(b.ename, leaf)) { + if (syntax.streq(b.emod, pkgmod)) { return b; }; }; @@ -41673,8 +41673,8 @@ fn enumlookupmod(c: *cgen, name: str, mod: str) *enumtype = { if (mod.len > 0) { let e: *enumtype = c.enums; for (e != nil) { - if (streq(e.ename, name)) { - if (streq(e.emod, mod)) { return e; }; + if (syntax.streq(e.ename, name)) { + if (syntax.streq(e.emod, mod)) { return e; }; }; e = e.etnext; }; @@ -41685,7 +41685,7 @@ fn enumlookupmod(c: *cgen, name: str, mod: str) *enumtype = { fn enummemberval(en: *enumtype, mname: str, out: *u64) bool = { let m: *enummember = en.members; for (m != nil) { - if (streq(m.mname, mname)) { + if (syntax.streq(m.mname, mname)) { *out = m.mval; return true; }; @@ -41696,14 +41696,14 @@ fn enummemberval(en: *enumtype, mname: str, out: *u64) bool = { // resolvetype — follow typedef alias chains to a "canonical" type // expr (str/slice/array/struct/...). Stops on cycles via depth limit. -fn resolvetype(c: *cgen, t: *node) *node = { - let cur: *node = t; +fn resolvetype(c: *cgen, t: *syntax.node) *syntax.node = { + let cur: *syntax.node = t; let depth: i32 = 0; for (depth < 16) { if (cur == nil) { return nil; }; - if (cur.kind != nkind.N_TNAME) { return cur; }; + if (cur.kind != syntax.nkind.N_TNAME) { return cur; }; let nm: str = cur.str; - let next: *node = aliaslookup(c, nm); + let next: *syntax.node = aliaslookup(c, nm); if (next == nil) { return cur; }; cur = next; depth += 1; @@ -41722,7 +41722,7 @@ type fieldinfo = struct { fname: str, foff: i32, fsz: i32, - tnode: *node, // the field type expr, for nested struct lookups + tnode: *syntax.node, // the field type expr, for nested struct lookups finext: *fieldinfo, }; @@ -41746,7 +41746,7 @@ type local = struct { // scanlocals pre-pass, so @tagscr/@retscr/@sretscr/ // @tagbase are sized at first-use; subsequent uses // must fit. - tnode: *node, // declared type expr (nkind.N_TNAME / nkind.N_TPTR / ...) or nil + tnode: *syntax.node, // declared type expr (nkind.N_TNAME / nkind.N_TPTR / ...) or nil lnext: *local, }; @@ -41780,7 +41780,7 @@ type enummember = struct { type enumtype = struct { ename: str, emod: str, // originating module (`// MODULE: foo`), or empty - storage: *node, // AST type expr for the storage type (i32 by default) + storage: *syntax.node, // AST type expr for the storage type (i32 by default) members: *enummember, etnext: *enumtype, }; @@ -41834,14 +41834,14 @@ type cgen = struct { // inside lib/foo binds to `foo.frob` even when // other modules also export `frob`. Set in cgfn // before walking the body. - fnret: *node, // declared return type of current fn (or nil) + fnret: *syntax.node, // declared return type of current fn (or nil) looptop: i32, loopendbuf: []str, // stack of end labels for break loopcontbuf: []str, // stack of cont labels for continue yieldtop: i32, yieldbuf: []str, // stack of match end labels for yield defertop: i32, - deferbuf: []*node, // stack of deferred exprs (LIFO at return) + deferbuf: []*syntax.node, // stack of deferred exprs (LIFO at return) // System V AMD64 sret discipline (#23). Plain TY_STRUCT returns // with size > 24B are passed via a hidden first-arg pointer // (RDI) to a caller-prealloc dest; the callee writes through @@ -41869,7 +41869,7 @@ type cgen = struct { // (sretdestoff) can't name a top-level let, so the lhs IDENT node // is carried and emitted as `LEAQ name(SB), DI`. nil means no // global receiver wired; mutually exclusive with sretdestoff. - sretdestnode: *node, + sretdestnode: *syntax.node, sretforward: i32, // #22 M3 `-c`: separate-compile / primary-only codegen. Emit code+ // DATA ONLY for this package's own (imported==0) decls; treat every @@ -41889,7 +41889,7 @@ type cgen = struct { // when picking the load/store sequence. type letvar = struct { name: str, - tnode: *node, + tnode: *syntax.node, lvnext: *letvar, }; @@ -41914,7 +41914,7 @@ fn cgeninit(c: *cgen) void = { let yieldbuf: []str = alloc([], LOOP_MAX: u64)!; c.yieldbuf = yieldbuf; c.defertop = 0; - let deferbuf: []*node = alloc([], DEFER_MAX: u64)!; + let deferbuf: []*syntax.node = alloc([], DEFER_MAX: u64)!; c.deferbuf = deferbuf; }; @@ -41922,7 +41922,7 @@ fn cgeninit(c: *cgen) void = { // match-arm bindings, which cstage allocates via cgexpr's by-value // `locals` list — so two separate matches each get fresh slots even // when their bind names collide. -fn localalloc(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { +fn localalloc(c: *cgen, name: str, sz: i32, tnode: *syntax.node) i32 = { let asz: i32 = sz; if (asz < 8) { asz = 8; }; if ((asz & 7) != 0) { asz = (asz + 7) & ~7; }; @@ -41938,7 +41938,7 @@ fn localalloc(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { // the binding into c.locals only AFTER, so a self-shadowing init // (`let x = f(x)`) resolves x in the OUTER scope (Hare evals the init in // the outer scope: harec check.c clet runs cexpr before scope_define). -fn localreserve(c: *cgen, name: str, sz: i32, tnode: *node) *local = { +fn localreserve(c: *cgen, name: str, sz: i32, tnode: *syntax.node) *local = { // #15: mirror cstage localslot (cmd/w6c/cgen.c:1900) — // `frame = (frame + size + 7) & ~7`, NO sub-8 floor. Identical to // the old `max(8, round8(sz))` accumulation for every sz>0 (frame @@ -41958,12 +41958,12 @@ fn localreserve(c: *cgen, name: str, sz: i32, tnode: *node) *local = { // pushes them in reverse, so each spilled arg lives at 16(BP), 24(BP), // etc. (after the saved RIP+BP). No spill instruction is emitted; the // slot IS the caller's stack slot. -fn localaddstack(c: *cgen, name: str, tnode: *node, off: i32) void = { +fn localaddstack(c: *cgen, name: str, tnode: *syntax.node, off: i32) void = { let l: *local = alloc(local{name=name, off=off, sz=0, tnode=tnode, lnext=c.locals})!; c.locals = l; }; -fn localadd(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { +fn localadd(c: *cgen, name: str, sz: i32, tnode: *syntax.node) i32 = { // User-let path (post-#27): always allocate a fresh slot per // binding. Pre-fix this deduped by name to share one slot // across same-name lets in disjoint scopes — inherited from @@ -41991,7 +41991,7 @@ fn localadd(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { let cur: *local = c.atlocals; for (cur != nil) { let cn: str = cur.name; - if (streq(cn, name)) { + if (syntax.streq(cn, name)) { if (asz > cur.sz) { // rule-7 surface, post-#15: pinned slot // offset can't grow in place. @@ -42054,7 +42054,7 @@ fn localfindnode(c: *cgen, name: str) *local = { let l: *local = c.locals; for (l != nil) { let ln: str = l.name; - if (streq(ln, name)) { return l; }; + if (syntax.streq(ln, name)) { return l; }; l = l.lnext; }; // @-prefix scratch slots survive cgblock save/restore via @@ -42064,7 +42064,7 @@ fn localfindnode(c: *cgen, name: str) *local = { if (name[0] == 64u8) { let a: *local = c.atlocals; for (a != nil) { - if (streq(a.name, name)) { return a; }; + if (syntax.streq(a.name, name)) { return a; }; a = a.lnext; }; }; @@ -42083,7 +42083,7 @@ fn localfind(c: *cgen, name: str) i32 = { if (name[0] == 64u8) { let a: *local = c.atlocals; for (a != nil) { - if (streq(a.name, name)) { return a.off; }; + if (syntax.streq(a.name, name)) { return a.off; }; a = a.lnext; }; }; @@ -42279,7 +42279,7 @@ fn internstrlit(c: *cgen, bytes: str) str = { let s: *strlit = c.strlits; for (s != nil) { let bs: str = s.bytes; - if (streq(bs, bytes)) { + if (syntax.streq(bs, bytes)) { return s.label; }; s = s.slnext; @@ -42318,28 +42318,28 @@ fn internstrlit(c: *cgen, bytes: str) str = { // types are handled separately by letfloatprim — they need MOVSS/MOVSD // and use 4-byte (f32) or 8-byte (f64) slots. fn letscalarprim(nm: str) bool = { - if (streq(nm, "bool")) { return true; }; - if (streq(nm, "rune")) { return true; }; - if (streq(nm, "i8")) { return true; }; - if (streq(nm, "i16")) { return true; }; - if (streq(nm, "i32")) { return true; }; - if (streq(nm, "i64")) { return true; }; - if (streq(nm, "u8")) { return true; }; - if (streq(nm, "u16")) { return true; }; - if (streq(nm, "u32")) { return true; }; - if (streq(nm, "u64")) { return true; }; - if (streq(nm, "int")) { return true; }; - if (streq(nm, "uint")) { return true; }; - if (streq(nm, "uintptr")) { return true; }; - if (streq(nm, "size")) { return true; }; + if (syntax.streq(nm, "bool")) { return true; }; + if (syntax.streq(nm, "rune")) { return true; }; + if (syntax.streq(nm, "i8")) { return true; }; + if (syntax.streq(nm, "i16")) { return true; }; + if (syntax.streq(nm, "i32")) { return true; }; + if (syntax.streq(nm, "i64")) { return true; }; + if (syntax.streq(nm, "u8")) { return true; }; + if (syntax.streq(nm, "u16")) { return true; }; + if (syntax.streq(nm, "u32")) { return true; }; + if (syntax.streq(nm, "u64")) { return true; }; + if (syntax.streq(nm, "int")) { return true; }; + if (syntax.streq(nm, "uint")) { return true; }; + if (syntax.streq(nm, "uintptr")) { return true; }; + if (syntax.streq(nm, "size")) { return true; }; return false; }; // letfloatprim — float type-name keywords. f32 → 4B slot, f64 → 8B. // Returns the slot size or 0 if not a float type. fn letfloatprim(nm: str) i32 = { - if (streq(nm, "f32")) { return 4; }; - if (streq(nm, "f64")) { return 8; }; + if (syntax.streq(nm, "f32")) { return 4; }; + if (syntax.streq(nm, "f64")) { return 8; }; return 0; }; @@ -42351,31 +42351,31 @@ fn letfloatprim(nm: str) i32 = { // 16 → str (only zero-init / nil / "" supported) // 24 → slice (only zero-init supported) // varies → struct (zero-init only; field reads/scalar-field writes) -fn letemitsize(c: *cgen, d: *node) i32 = { +fn letemitsize(c: *cgen, d: *syntax.node) i32 = { if (d == nil) { return 0; }; - let t: *node = d.lhs; + let t: *syntax.node = d.lhs; for (t != nil) { - if (t.kind == nkind.N_TPTR) { return 8; }; - if (t.kind == nkind.N_TSLICE) { return tyslicesize(): i32; }; - if (t.kind == nkind.N_TARRAY) { - let lenn: *node = t.rhs; - let elemn: *node = t.lhs; + if (t.kind == syntax.nkind.N_TPTR) { return 8; }; + if (t.kind == syntax.nkind.N_TSLICE) { return tyslicesize(): i32; }; + if (t.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = t.rhs; + let elemn: *syntax.node = t.lhs; let alen: i32 = 1; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i32; } else { // #56: def/const dim — resolve from the stamped array // tinfo (rule-13), the letemitsize twin of the cgdot // .len fix. Pre-fix a non-N_INTLIT dim defaulted alen=1 // → array global mis-sized (one element's worth). - let abt: *tinfo = tichase(t.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(t.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i32; }; }; let esz: i32 = 8; if (elemn != nil) { - if (elemn.kind == nkind.N_TNAME) { + if (elemn.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, elemn.str); if (ps > 0) { esz = ps; }; }; @@ -42389,11 +42389,11 @@ fn letemitsize(c: *cgen, d: *node) i32 = { // globals out of collectlets entirely — no DATA emitted, and // the module-leaf fallback mis-emitted the field index as a // symbol (`MOVQ 0(SB), AX`). - if (t.kind == nkind.N_TTUPLE) { + if (t.kind == syntax.nkind.N_TTUPLE) { let tsum: i32 = 0; - let p: *node = t.list; + let p: *syntax.node = t.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (isstrtype(c, et) || isslicetype(c, et)) { tsum += (tyslicesize(): i32); } else { @@ -42406,7 +42406,7 @@ fn letemitsize(c: *cgen, d: *node) i32 = { // #87: non-nullable tagged-union global — box size (tag word + // max payload, mirror of the runtime local). Mirrors cstage // let_emit_size TY_TAGGED. - if (t.kind == nkind.N_TTAGGED) { + if (t.kind == syntax.nkind.N_TTAGGED) { // #45 (silent→loud bridge, task #15): a nullable (*T|void) // GLOBAL has no storage path. Returning 0 here made // letcollect + emitletdataw silently skip the decl (no DATA, @@ -42422,15 +42422,15 @@ fn letemitsize(c: *cgen, d: *node) i32 = { }; return slotsize(c, t); }; - if (t.kind != nkind.N_TNAME) { return 0; }; + if (t.kind != syntax.nkind.N_TNAME) { return 0; }; let nm: str = t.str; if (letscalarprim(nm)) { return 8; }; let fsz: i32 = letfloatprim(nm); if (fsz > 0) { return fsz; }; - if (streq(nm, "str")) { return primtypesize("str"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("str"): i32; }; let si: *structinfo = structlookup(c, nm); if (si != nil) { return si.totsize; }; - let next: *node = aliaslookup(c, nm); + let next: *syntax.node = aliaslookup(c, nm); if (next == nil) { return 0; }; t = next; }; @@ -42464,23 +42464,23 @@ fn letemitsize(c: *cgen, d: *node) i32 = { // cs≠ww divergence (rule-10) — it ships only WITH the cstage float-use-site fix. // Runs before collectlets in cgfile so the mutated d.lhs is visible to // letpreintern + emitletdataw too. -fn defaultinferredlets(c: *cgen, file: *node) void = { +fn defaultinferredlets(c: *cgen, file: *syntax.node) void = { if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { if (d.lhs != nil && d.rhs != nil - && d.lhs.kind == nkind.N_TNAME - && streq(d.lhs.str, "untyped_int")) { - let opnd: *node = d.rhs; - if (opnd.kind == nkind.N_UN - && (opnd.op == tkind.TK_PLUS - || opnd.op == tkind.TK_MINUS - || opnd.op == tkind.TK_TILDE)) { + && d.lhs.kind == syntax.nkind.N_TNAME + && syntax.streq(d.lhs.str, "untyped_int")) { + let opnd: *syntax.node = d.rhs; + if (opnd.kind == syntax.nkind.N_UN + && (opnd.op == syntax.tkind.TK_PLUS + || opnd.op == syntax.tkind.TK_MINUS + || opnd.op == syntax.tkind.TK_TILDE)) { opnd = opnd.lhs; }; if (opnd != nil - && opnd.kind == nkind.N_INTLIT) { + && opnd.kind == syntax.nkind.N_INTLIT) { d.lhs.str = "int"; }; }; @@ -42495,16 +42495,16 @@ fn defaultinferredlets(c: *cgen, file: *node) void = { // return (X0 untouched). Mirror cstage check.c clet // type_default. if (d.lhs != nil && d.rhs != nil - && d.lhs.kind == nkind.N_TNAME - && streq(d.lhs.str, "untyped_float")) { - let opnd: *node = d.rhs; - if (opnd.kind == nkind.N_UN - && (opnd.op == tkind.TK_PLUS - || opnd.op == tkind.TK_MINUS)) { + && d.lhs.kind == syntax.nkind.N_TNAME + && syntax.streq(d.lhs.str, "untyped_float")) { + let opnd: *syntax.node = d.rhs; + if (opnd.kind == syntax.nkind.N_UN + && (opnd.op == syntax.tkind.TK_PLUS + || opnd.op == syntax.tkind.TK_MINUS)) { opnd = opnd.lhs; }; if (opnd != nil - && opnd.kind == nkind.N_FLOATLIT) { + && opnd.kind == syntax.nkind.N_FLOATLIT) { d.lhs.str = "f64"; }; }; @@ -42513,12 +42513,12 @@ fn defaultinferredlets(c: *cgen, file: *node) void = { }; }; -fn collectlets(c: *cgen, file: *node) void = { +fn collectlets(c: *cgen, file: *syntax.node) void = { c.lets = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { let nm: str = d.str; if (nm.len > 0) { if (letemitsize(c, d) > 0) { @@ -42534,7 +42534,7 @@ fn collectlets(c: *cgen, file: *node) void = { fn isletvar(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { return true; }; + if (syntax.streq(lv.name, name)) { return true; }; lv = lv.lvnext; }; return false; @@ -42548,10 +42548,10 @@ fn isletvar(c: *cgen, name: str) bool = { // cgindex / cgassign to detect global `[N]T` arrays and `*T` // pointers, where the addressing path needs LEAQ name(SB) (array) // or MOVQ name(SB) (pointer) and the element size from T. -fn letvartnode(c: *cgen, name: str) *node = { +fn letvartnode(c: *cgen, name: str) *syntax.node = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { return lv.tnode; }; + if (syntax.streq(lv.name, name)) { return lv.tnode; }; lv = lv.lvnext; }; return nil; @@ -42560,13 +42560,13 @@ fn letvartnode(c: *cgen, name: str) *node = { fn letvarisstr(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let nm: str = t.str; - if (streq(nm, "str")) { return true; }; - let nx: *node = aliaslookup(c, nm); + if (syntax.streq(nm, "str")) { return true; }; + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return false; }; t = nx; }; @@ -42590,12 +42590,12 @@ fn letvarisstr(c: *cgen, name: str) bool = { fn letvarisslice(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind == nkind.N_TSLICE) { return true; }; - if (t.kind != nkind.N_TNAME) { return false; }; - let nx: *node = aliaslookup(c, t.str); + if (t.kind == syntax.nkind.N_TSLICE) { return true; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + let nx: *syntax.node = aliaslookup(c, t.str); if (nx == nil) { return false; }; t = nx; }; @@ -42612,13 +42612,13 @@ fn letvarisslice(c: *cgen, name: str) bool = { fn letvarisfloat(c: *cgen, name: str) i32 = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return 0; }; + if (t.kind != syntax.nkind.N_TNAME) { return 0; }; let fsz: i32 = letfloatprim(t.str); if (fsz > 0) { return fsz; }; - let nx: *node = aliaslookup(c, t.str); + let nx: *syntax.node = aliaslookup(c, t.str); if (nx == nil) { return 0; }; t = nx; }; @@ -42636,13 +42636,13 @@ fn letvarisfloat(c: *cgen, name: str) i32 = { fn letvarisstruct(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let nm: str = t.str; if (structlookup(c, nm) != nil) { return true; }; - let nx: *node = aliaslookup(c, nm); + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return false; }; t = nx; }; @@ -42659,14 +42659,14 @@ fn letvarisstruct(c: *cgen, name: str) bool = { fn letvarstructinfo(c: *cgen, name: str) *structinfo = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return nil; }; + if (t.kind != syntax.nkind.N_TNAME) { return nil; }; let nm: str = t.str; let si: *structinfo = structlookup(c, nm); if (si != nil) { return si; }; - let nx: *node = aliaslookup(c, nm); + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return nil; }; t = nx; }; @@ -42689,14 +42689,14 @@ fn letvarstructinfo(c: *cgen, name: str) *structinfo = { fn defvarstructinfo(c: *cgen, name: str) *structinfo = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - let t: *node = e.dtnode; + if (syntax.streq(e.dname, name)) { + let t: *syntax.node = e.dtnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return nil; }; + if (t.kind != syntax.nkind.N_TNAME) { return nil; }; let nm: str = t.str; let si: *structinfo = structlookup(c, nm); if (si != nil) { return si; }; - let nx: *node = aliaslookup(c, nm); + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return nil; }; t = nx; }; @@ -42713,10 +42713,10 @@ fn defvarstructinfo(c: *cgen, name: str) *structinfo = { // resolves through the same N_TARRAY-detect → LEAQ name(SB) shape as // a let array. Parallel to defvarstructinfo (#129 A.2) at the LOAD // side widening. -fn defvartnode(c: *cgen, name: str) *node = { +fn defvartnode(c: *cgen, name: str) *syntax.node = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { return e.dtnode; }; + if (syntax.streq(e.dname, name)) { return e.dtnode; }; e = e.dnext; }; return nil; @@ -42762,25 +42762,25 @@ fn emitdatawbyte(b: u8) void = { // order emitstrarraydata references them by — a divergent order would // mis-pair the DATAR rows with their _S_ rodata. au is the chased // TY_ARRAY tinfo, r the N_ARRLIT rhs; caller verified the element is str. -fn preinternstrarray(c: *cgen, au: *tinfo, r: *node) void = { +fn preinternstrarray(c: *cgen, au: *syntax.tinfo, r: *syntax.node) void = { let alen: i32 = au.alen: i32; let cnt: i32 = 0; - let last_ev: *node = nil; + let last_ev: *syntax.node = nil; let repeat: bool = false; - let e: *node = r.list; + let e: *syntax.node = r.list; for (e != nil && cnt < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { break; }; - if (ev.kind != nkind.N_STRLIT) { break; }; + if (ev.kind != syntax.nkind.N_STRLIT) { break; }; if (ev.str.len > 0) { internstrlit(c, ev.str); }; @@ -42804,7 +42804,7 @@ fn preinternstrarray(c: *cgen, au: *tinfo, r: *node) void = { // emitdatasection emits the DATA row in the same .s file. Running // emitletdataw after emitdatasection would flip the (DATA strlits, // DATAW lets) section order and break byte-identity. -export fn letpreintern(c: *cgen, file: *node) void = { +export fn letpreintern(c: *cgen, file: *syntax.node) void = { if (file == nil) { return; }; // #49: strlit labels allocated here (static-data initialisers) take // the OWNING decl's module prefix, not the stale last-fn curmod. @@ -42812,7 +42812,7 @@ export fn letpreintern(c: *cgen, file: *node) void = { // fn-ptr relocs — see the same value they did before; letpreintern // itself only interns, so driving curmod here has no other effect. let savedmod: str = c.curmod; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { c.curmod = d.nmod; // #22 M3: skip imported deps so the strlit table (and its _S_ @@ -42830,26 +42830,26 @@ export fn letpreintern(c: *cgen, file: *node) void = { // allocated too late (emitdefconstants pass) → dangling _S_. // Str-array ONLY — def tuple/slice/tagged/scalar-str stay out // of scope (#10/#270 / inline-Sdef). - if (d.kind == nkind.N_DEF) { - let dr: *node = d.rhs; - for (dr != nil && dr.kind == nkind.N_CAST) { + if (d.kind == syntax.nkind.N_DEF) { + let dr: *syntax.node = d.rhs; + for (dr != nil && dr.kind == syntax.nkind.N_CAST) { dr = dr.lhs; }; if (d.lhs != nil && dr != nil - && dr.kind == nkind.N_ARRLIT) { - let dau: *tinfo = tichase(d.lhs.type_: *tinfo); - if (dau != nil && dau.kind == tykind.TY_ARRAY) { - let deu: *tinfo = tichase(dau.sub); - if (deu != nil && deu.kind == tykind.TY_STR) { + && dr.kind == syntax.nkind.N_ARRLIT) { + let dau: *syntax.tinfo = tichase(d.lhs.type_: *syntax.tinfo); + if (dau != nil && dau.kind == syntax.tykind.TY_ARRAY) { + let deu: *syntax.tinfo = tichase(dau.sub); + if (deu != nil && deu.kind == syntax.tykind.TY_STR) { preinternstrarray(c, dau, dr); }; }; }; }; - if (d.kind == nkind.N_LET) { - let r: *node = d.rhs; + if (d.kind == syntax.nkind.N_LET) { + let r: *syntax.node = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // #18: `let xs: [N]str = […];` — pre-intern each @@ -42862,11 +42862,11 @@ export fn letpreintern(c: *cgen, file: *node) void = { // globals, desyncing label order vs cstage. let handled: bool = false; if (d.lhs != nil && r != nil) { - let au: *tinfo = tichase(d.lhs.type_: *tinfo); - if (au != nil && au.kind == tykind.TY_ARRAY - && r.kind == nkind.N_ARRLIT) { - let eu: *tinfo = tichase(au.sub); - if (eu != nil && eu.kind == tykind.TY_STR) { + let au: *syntax.tinfo = tichase(d.lhs.type_: *syntax.tinfo); + if (au != nil && au.kind == syntax.tykind.TY_ARRAY + && r.kind == syntax.nkind.N_ARRLIT) { + let eu: *syntax.tinfo = tichase(au.sub); + if (eu != nil && eu.kind == syntax.tykind.TY_STR) { handled = true; preinternstrarray(c, au, r); }; @@ -42877,24 +42877,24 @@ export fn letpreintern(c: *cgen, file: *node) void = { // arm's DATAR rows find their _S_ rodata rows (the // #18 array-arm pattern; cstage let_pre_intern twin). if (!handled && r != nil && d.lhs != nil) { - if (r.kind == nkind.N_TUPLE) { - let tlt: *node = d.lhs; - for (tlt != nil && tlt.kind == nkind.N_TNAME) { + if (r.kind == syntax.nkind.N_TUPLE) { + let tlt: *syntax.node = d.lhs; + for (tlt != nil && tlt.kind == syntax.nkind.N_TNAME) { tlt = aliaslookup(c, tlt.str); }; if (tlt != nil) { - if (tlt.kind == nkind.N_TTUPLE) { + if (tlt.kind == syntax.nkind.N_TTUPLE) { handled = true; - let tp: *node = tlt.list; - let e: *node = r.list; + let tp: *syntax.node = tlt.list; + let e: *syntax.node = r.list; for (e != nil && tp != nil) { - let et: *node = tp.lhs; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { + let et: *syntax.node = tp.lhs; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev != nil) { - if (ev.kind == nkind.N_STRLIT + if (ev.kind == syntax.nkind.N_STRLIT && (isstrtype(c, et) || isslicetype(c, et))) { if (ev.str.len > 0) { internstrlit(c, ev.str); @@ -42917,28 +42917,28 @@ export fn letpreintern(c: *cgen, file: *node) void = { // rodata rows (cstage letpreintern twin). Bounded to // inline N_TTUPLE element types. if (!handled && r != nil && d.lhs != nil) { - if (r.kind == nkind.N_ARRLIT - && d.lhs.kind == nkind.N_TSLICE) { - let tupnode: *node = d.lhs.lhs; - if (tupnode != nil && tupnode.kind == nkind.N_TTUPLE) { + if (r.kind == syntax.nkind.N_ARRLIT + && d.lhs.kind == syntax.nkind.N_TSLICE) { + let tupnode: *syntax.node = d.lhs.lhs; + if (tupnode != nil && tupnode.kind == syntax.nkind.N_TTUPLE) { handled = true; - let row: *node = r.list; + let row: *syntax.node = r.list; for (row != nil) { - let rw: *node = row; - for (rw != nil && rw.kind == nkind.N_CAST) { + let rw: *syntax.node = row; + for (rw != nil && rw.kind == syntax.nkind.N_CAST) { rw = rw.lhs; }; - if (rw != nil && rw.kind == nkind.N_TUPLE) { - let tp: *node = tupnode.list; - let e: *node = rw.list; + if (rw != nil && rw.kind == syntax.nkind.N_TUPLE) { + let tp: *syntax.node = tupnode.list; + let e: *syntax.node = rw.list; for (e != nil && tp != nil) { - let et: *node = tp.lhs; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { + let et: *syntax.node = tp.lhs; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev != nil) { - if (ev.kind == nkind.N_STRLIT + if (ev.kind == syntax.nkind.N_STRLIT && (isstrtype(c, et) || isslicetype(c, et))) { if (ev.str.len > 0) { internstrlit(c, ev.str); @@ -42955,13 +42955,13 @@ export fn letpreintern(c: *cgen, file: *node) void = { }; }; if (!handled && r != nil && d.lhs != nil) { - let tlt: *node = d.lhs; - for (tlt != nil && tlt.kind == nkind.N_TNAME) { + let tlt: *syntax.node = d.lhs; + for (tlt != nil && tlt.kind == syntax.nkind.N_TNAME) { tlt = aliaslookup(c, tlt.str); }; if (tlt != nil) { - if (tlt.kind == nkind.N_TTAGGED && !isnullabletype(tlt)) { - if (r.kind == nkind.N_STRLIT && r.str.len > 0 + if (tlt.kind == syntax.nkind.N_TTAGGED && !isnullabletype(tlt)) { + if (r.kind == syntax.nkind.N_STRLIT && r.str.len > 0 && (nodeisstr(c, r) || nodeisslice(c, r))) { handled = true; internstrlit(c, r.str); @@ -42976,7 +42976,7 @@ export fn letpreintern(c: *cgen, file: *node) void = { // `sz == primtypesize("str"): i32` strlit-init branch. if (sz == primtypesize("str"): i32) { if (r != nil) { - if (r.kind == nkind.N_STRLIT) { + if (r.kind == syntax.nkind.N_STRLIT) { if (r.str.len > 0) { internstrlit(c, r.str); }; @@ -43009,36 +43009,36 @@ export fn letpreintern(c: *cgen, file: *node) void = { // f64/f32 bitcast helpers into cgen. Returns true on emit, false if // rhs doesn't reduce to a foldable float literal. fn emitfloatlitdata(c: *cgen, directive: str, name: str, module: str, - sz: i32, rhs: *node) bool = { + sz: i32, rhs: *syntax.node) bool = { let isf32: bool = (sz == 4); let bits: u64 = 0u64; let neg: bool = false; if (rhs != nil) { - let r: *node = rhs; + let r: *syntax.node = rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; if (r != nil) { - if (r.kind == nkind.N_UN) { - if (r.op == tkind.TK_MINUS) { + if (r.kind == syntax.nkind.N_UN) { + if (r.op == syntax.tkind.TK_MINUS) { neg = true; r = r.lhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; - } else { if (r.op == tkind.TK_PLUS) { + } else { if (r.op == syntax.tkind.TK_PLUS) { r = r.lhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; };}; }; }; if (r == nil) { return false; }; - if (r.kind != nkind.N_FLOATLIT) { return false; }; + if (r.kind != syntax.nkind.N_FLOATLIT) { return false; }; // r.uval holds f64 bits regardless of literal suffix (lexer // stores the pre-narrow bits). f32 needs an explicit // (double→float) narrowing at emit time — mirrors cstage's @@ -43090,25 +43090,25 @@ fn emitfloatlitdata(c: *cgen, directive: str, name: str, module: str, // emit_struct_lit_bytes. `base` offsets the field-start computation // so the recursive call walks an inner struct's fields within its // outer parent's byte stream. -fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, +fn emitstructlitbytes(c: *cgen, structt: *syntax.tinfo, rhs: *syntax.node, base: u64) bool = { - let su: *tinfo = structt; + let su: *syntax.tinfo = structt; su = tichase(su); if (su == nil) { return false; }; - if (su.kind != tykind.TY_STRUCT) { return false; }; + if (su.kind != syntax.tykind.TY_STRUCT) { return false; }; let pos: u64 = base; - let f: *tfield = su.fields; + let f: *syntax.tfield = su.fields; for (f != nil) { let fstart: u64 = base + f.offset; for (pos < fstart) { emitdatawbyte(0u8); pos = pos + 1u64; }; - let v: *node = nil; + let v: *syntax.node = nil; if (rhs != nil) { - let fnod: *node = rhs.list; + let fnod: *syntax.node = rhs.list; for (fnod != nil) { - if (streq(fnod.str, f.name)) { + if (syntax.streq(fnod.str, f.name)) { v = fnod.lhs; break; }; @@ -43126,16 +43126,16 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, f = f.tnext; continue; }; - let vr: *node = v; - for (vr != nil && vr.kind == nkind.N_CAST) { vr = vr.lhs; }; - let fu: *tinfo = f.type_; + let vr: *syntax.node = v; + for (vr != nil && vr.kind == syntax.nkind.N_CAST) { vr = vr.lhs; }; + let fu: *syntax.tinfo = f.type_; fu = tichase(fu); // #19 option A: a non-nullable tagged-union field rides the shared // (tag,payload) core at the field slot size, mirroring the scalar // tagged global — NOT the int emitter. Wide/struct/non-foldable // payload loud-rejects (task #30 sub-item, rule 7). v is non-nil // here (the absent-field zero-fill is handled above). - if (fu != nil && fu.kind == tykind.TY_TAGGED && !typeisnullable(fu)) { + if (fu != nil && fu.kind == syntax.tykind.TY_TAGGED && !syntax.typeisnullable(fu)) { if (!emittaggedbytes(c, f.type_, v, fsz, 1)) { let m: str = "emitstructlitbytes: tagged-union struct-field static-init needs a zero/int payload; wide (str/slice) or struct payload is deferred (task #30, rule 7)\n"; os.write(2, m.ptr, m.len: u64); @@ -43145,13 +43145,13 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, f = f.tnext; continue; }; - if (fu != nil && fu.kind == tykind.TY_STRUCT) { + if (fu != nil && fu.kind == syntax.tykind.TY_STRUCT) { if (vr == nil) { let m: str = "emitstructlitbytes: nested struct field rhs nil (#129 A.2)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (vr.kind != nkind.N_STRUCTLIT) { + if (vr.kind != syntax.nkind.N_STRUCTLIT) { let m: str = "emitstructlitbytes: nested struct rhs not N_STRUCTLIT (#129 A.2)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -43165,13 +43165,13 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, // parked in A.2). Recurses through emitarraylitbytes for // element-kind dispatch. Rule-7 stops loudly if rhs shape // doesn't match. - if (fu != nil && fu.kind == tykind.TY_ARRAY) { + if (fu != nil && fu.kind == syntax.tykind.TY_ARRAY) { if (vr == nil) { let m: str = "emitstructlitbytes: array field rhs nil (#129 A.3)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (vr.kind != nkind.N_ARRLIT) { + if (vr.kind != syntax.nkind.N_ARRLIT) { let m: str = "emitstructlitbytes: array field rhs not N_ARRLIT (#129 A.3)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -43185,18 +43185,18 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, f = f.tnext; continue; }; - if (typeisfloat(f.type_)) { + if (syntax.typeisfloat(f.type_)) { let isf32: bool = (fsz == 4); let neg: bool = false; - let fr: *node = vr; - if (fr != nil) { if (fr.kind == nkind.N_UN) { - if (fr.op == tkind.TK_MINUS) { + let fr: *syntax.node = vr; + if (fr != nil) { if (fr.kind == syntax.nkind.N_UN) { + if (fr.op == syntax.tkind.TK_MINUS) { neg = true; fr = fr.lhs; - for (fr != nil && fr.kind == nkind.N_CAST) { fr = fr.lhs; }; - } else { if (fr.op == tkind.TK_PLUS) { + for (fr != nil && fr.kind == syntax.nkind.N_CAST) { fr = fr.lhs; }; + } else { if (fr.op == syntax.tkind.TK_PLUS) { fr = fr.lhs; - for (fr != nil && fr.kind == nkind.N_CAST) { fr = fr.lhs; }; + for (fr != nil && fr.kind == syntax.nkind.N_CAST) { fr = fr.lhs; }; };}; };}; if (fr == nil) { @@ -43204,7 +43204,7 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (fr.kind != nkind.N_FLOATLIT) { + if (fr.kind != syntax.nkind.N_FLOATLIT) { let m: str = "emitstructlitbytes: float field rhs not FLOATLIT (#129 A.2)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -43259,11 +43259,11 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, // then delegates to emitstructlitbytes. Shared between emitletdataw // struct arm and emitdefconstants struct arm (#129 A.2). fn emitstructdata(c: *cgen, directive: str, name: str, module: str, - structt: *tinfo, rhs: *node) bool = { - let su: *tinfo = structt; + structt: *syntax.tinfo, rhs: *syntax.node) bool = { + let su: *syntax.tinfo = structt; su = tichase(su); if (su == nil) { return false; }; - if (su.kind != tykind.TY_STRUCT) { return false; }; + if (su.kind != syntax.tykind.TY_STRUCT) { return false; }; emitline(directive); emitline(" "); emitfnname(c, name, module); @@ -43291,15 +43291,15 @@ fn emitstructdata(c: *cgen, directive: str, name: str, module: str, // Two-pass validate-then-emit (`emit_phase=0` validate-only, `=1` // actually emit) keeps emit-on-failure from emitting partial bytes // into an open DATA literal. -fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, +fn emitarraylitbytes(c: *cgen, arrt: *syntax.tinfo, rhs: *syntax.node, emit_phase: i32) bool = { - let au: *tinfo = arrt; + let au: *syntax.tinfo = arrt; au = tichase(au); if (au == nil) { return false; }; - if (au.kind != tykind.TY_ARRAY) { return false; }; + if (au.kind != syntax.tykind.TY_ARRAY) { return false; }; let esz: i32 = au.sub.size: i32; let alen: i32 = au.alen: i32; - let eu: *tinfo = au.sub; + let eu: *syntax.tinfo = au.sub; eu = tichase(eu); // #19 option A: a non-nullable tagged-union element rides the shared @@ -43309,13 +43309,13 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // payload element loud-rejects (task #30 sub-item, rule 7). A nullable // `(*T|void)` element is a 1-word fold, not a tag box — left to the // existing int path (task #15). - if (eu != nil && eu.kind == tykind.TY_TAGGED && !typeisnullable(eu)) { + if (eu != nil && eu.kind == syntax.tykind.TY_TAGGED && !syntax.typeisnullable(eu)) { let idx: i32 = 0; - let last_ev: *node = nil; - let e: *node = rhs.list; + let last_ev: *syntax.node = nil; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; if (!emittaggedbytes(c, au.sub, e, esz, 0)) { let m: str = "emitarraylitbytes: tagged-union array element static-init needs a zero/int payload; wide (str/slice) or struct payload is deferred (task #30, rule 7)\n"; @@ -43331,8 +43331,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, let repeat: bool = false; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; emittaggedbytes(c, au.sub, e, esz, 1); idx += 1; @@ -43350,19 +43350,19 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, return true; }; - if (eu != nil && eu.kind == tykind.TY_STRUCT) { + if (eu != nil && eu.kind == syntax.tykind.TY_STRUCT) { // Validate: every element must be N_STRUCTLIT (after N_CAST). let idx: i32 = 0; - let last_ev: *node = nil; - let e: *node = rhs.list; + let last_ev: *syntax.node = nil; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_STRUCTLIT) { return false; }; + if (ev.kind != syntax.nkind.N_STRUCTLIT) { return false; }; last_ev = ev; idx += 1; e = e.next; @@ -43372,11 +43372,11 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, let repeat: bool = false; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; emitstructlitbytes(c, au.sub, ev, 0u64); idx += 1; e = e.next; @@ -43401,21 +43401,21 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // element stride (rule 13). The `...` repeat marker with nested- // array elements is rejected loud (rule 7): no consumer needs it // (powers_of_ten is fully enumerated). - if (eu != nil && eu.kind == tykind.TY_ARRAY) { + if (eu != nil && eu.kind == syntax.tykind.TY_ARRAY) { let idx: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { let m: str = "emitarraylitbytes: '...' repeat with nested-array elements unsupported (#129 A.3, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_ARRLIT) { return false; }; + if (ev.kind != syntax.nkind.N_ARRLIT) { return false; }; if (!emitarraylitbytes(c, au.sub, ev, 0)) { return false; }; idx += 1; e = e.next; @@ -43424,8 +43424,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, idx = 0; e = rhs.list; for (e != nil && idx < alen) { - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; emitarraylitbytes(c, au.sub, ev, 1); idx += 1; e = e.next; @@ -43438,28 +43438,28 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, return true; }; - if (typeisfloat(au.sub)) { - let isf32: bool = typeisf32(au.sub); + if (syntax.typeisfloat(au.sub)) { + let isf32: bool = syntax.typeisf32(au.sub); // Validate. let idx: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; - if (ev != nil) { if (ev.kind == nkind.N_UN) { - if (ev.op == tkind.TK_MINUS) { + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; + if (ev != nil) { if (ev.kind == syntax.nkind.N_UN) { + if (ev.op == syntax.tkind.TK_MINUS) { ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; - } else { if (ev.op == tkind.TK_PLUS) { + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; + } else { if (ev.op == syntax.tkind.TK_PLUS) { ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; };}; };}; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_FLOATLIT) { return false; }; + if (ev.kind != syntax.nkind.N_FLOATLIT) { return false; }; idx += 1; e = e.next; }; @@ -43470,20 +43470,20 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, let repeat: bool = false; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let neg: bool = false; - if (ev != nil) { if (ev.kind == nkind.N_UN) { - if (ev.op == tkind.TK_MINUS) { + if (ev != nil) { if (ev.kind == syntax.nkind.N_UN) { + if (ev.op == syntax.tkind.TK_MINUS) { neg = true; ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; - } else { if (ev.op == tkind.TK_PLUS) { + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; + } else { if (ev.op == syntax.tkind.TK_PLUS) { ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; };}; };}; let bits: u64 = ev.uval; @@ -43535,16 +43535,16 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // emitletdataw in-place arm so bootstrap consumers (u8/i8/u16 // arrays) don't shift. let idx: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; let last: u64 = 0u64; let repeat: bool = false; // Validate first. for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; if (!foldintliteral(ev, &last)) { return false; }; idx += 1; @@ -43568,8 +43568,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, if (inrepeat) { v = last; } else { if (e != nil) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { inrepeat = true; v = last; } else { @@ -43577,8 +43577,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, v = last; }; } else { - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (!foldintliteral(ev, &v)) { v = 0u64; }; last = v; e = e.next; @@ -43609,15 +43609,15 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // holder constraint, not a mutability grant (def immutability stays // checker-enforced). Returns false when the element type isn't str. fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, - arrt: *tinfo, rhs: *node) bool = { - let au: *tinfo = arrt; + arrt: *syntax.tinfo, rhs: *syntax.node) bool = { + let au: *syntax.tinfo = arrt; au = tichase(au); if (au == nil) { return false; }; - if (au.kind != tykind.TY_ARRAY) { return false; }; - let eu: *tinfo = au.sub; + if (au.kind != syntax.tykind.TY_ARRAY) { return false; }; + let eu: *syntax.tinfo = au.sub; eu = tichase(eu); if (eu == nil) { return false; }; - if (eu.kind != tykind.TY_STR) { return false; }; + if (eu.kind != syntax.tykind.TY_STR) { return false; }; // #8/GAP-B: a str-element array's backing ALWAYS lives in DATAW // (writable section), regardless of the caller's let/def directive — // each element carries an A_DATAR ptr-reloc to its _S_ rodata row, and @@ -43632,18 +43632,18 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, let esz: i32 = au.sub.size: i32; let alen: i32 = au.alen: i32; - let last_ev: *node = nil; + let last_ev: *syntax.node = nil; let repeat: bool = false; let cnt: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil && cnt < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_STRLIT) { return false; }; + if (ev.kind != syntax.nkind.N_STRLIT) { return false; }; last_ev = ev; cnt += 1; e = e.next; @@ -43655,11 +43655,11 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, let idx: i32 = 0; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let i: i32 = 0; for (i < 8) { emitdatawbyte(0u8); i += 1; }; let v: u64 = ev.str.len: u64; @@ -43694,11 +43694,11 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, idx = 0; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev.str.len > 0) { let lab: str = internstrlit(c, ev.str); emitline("DATAR "); @@ -43737,11 +43737,11 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, // refactor would have skipped emit entirely without this branch, // causing `undefined reference to strconv.f64tos_buf` at link. fn emitarraydata(c: *cgen, directive: str, name: str, module: str, - arrt: *tinfo, rhs: *node) bool = { - let au: *tinfo = arrt; + arrt: *syntax.tinfo, rhs: *syntax.node) bool = { + let au: *syntax.tinfo = arrt; au = tichase(au); if (au == nil) { return false; }; - if (au.kind != tykind.TY_ARRAY) { return false; }; + if (au.kind != syntax.tykind.TY_ARRAY) { return false; }; if (rhs == nil) { let total: u64 = arrt.size; emitline(directive); @@ -43780,25 +43780,25 @@ fn emitarraydata(c: *cgen, directive: str, name: str, module: str, // (w6a asm.c:362); read-only `def`, `...` repeat (no target length), // and slice-of-{str,slice,tagged} elements (per-element relocs / #17) // all loud-stop (rule 7, #10 follow-ups). -fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, - sltnode: *node, rhs: *node) void = { - let su: *tinfo = slt; +fn emitslicedata(c: *cgen, name: str, module: str, slt: *syntax.tinfo, + sltnode: *syntax.node, rhs: *syntax.node) void = { + let su: *syntax.tinfo = slt; su = tichase(su); // Defensive, mirrors cstage emit_slice_data's // `if (u == NULL || u->kind != TY_SLICE) return 0` (rule-10): the // letvarisslice gate already guarantees a slice, so this is // unreachable — it guards the su.sub deref below if the contract // is ever violated rather than nil-derefing. - if (su == nil || su.kind != tykind.TY_SLICE) { return; }; - let etype: *tinfo = su.sub; - let eu: *tinfo = etype; + if (su == nil || su.kind != syntax.tykind.TY_SLICE) { return; }; + let etype: *syntax.tinfo = su.sub; + let eu: *syntax.tinfo = etype; eu = tichase(eu); // Count elements; reject `...` (a slice literal has no target N). let k: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { let m: str = "emitslicedata: '...' repeat has no target length in a slice literal (#10, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -43812,23 +43812,23 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, // drives the per-element slot classification the node-based // emittuplerow helpers expect; cstage drives the same off the tuple // tinfo's params. Bounded to inline N_TTUPLE element types. - let tupnode: *node = nil; + let tupnode: *syntax.node = nil; if (sltnode != nil) { tupnode = sltnode.lhs; }; let istuprow: bool = false; - if (eu != nil && eu.kind == tykind.TY_TUPLE && tupnode != nil) { - if (tupnode.kind == nkind.N_TTUPLE) { istuprow = true; }; + if (eu != nil && eu.kind == syntax.tykind.TY_TUPLE && tupnode != nil) { + if (tupnode.kind == syntax.nkind.N_TTUPLE) { istuprow = true; }; }; if (istuprow) { let stride: i32 = etype.size: i32; // Validate every row before any bytes (two-pass, partial-row // safe). - let e2: *node = rhs.list; + let e2: *syntax.node = rhs.list; for (e2 != nil) { - let row: *node = e2; - for (row != nil && row.kind == nkind.N_CAST) { row = row.lhs; }; + let row: *syntax.node = e2; + for (row != nil && row.kind == syntax.nkind.N_CAST) { row = row.lhs; }; let bad: bool = false; if (row == nil) { bad = true; } - else if (row.kind != nkind.N_TUPLE) { bad = true; } + else if (row.kind != syntax.nkind.N_TUPLE) { bad = true; } else if (!tuplerowfoldable(c, tupnode, row)) { bad = true; }; if (bad) { let m: str = "emitslicedata: tuple-row element not a foldable constant ((str,*fn) rows only; #117, rule 7)\n"; @@ -43843,8 +43843,8 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, emitline(".d(SB),\""); e2 = rhs.list; for (e2 != nil) { - let row: *node = e2; - for (row != nil && row.kind == nkind.N_CAST) { row = row.lhs; }; + let row: *syntax.node = e2; + for (row != nil && row.kind == syntax.nkind.N_CAST) { row = row.lhs; }; emittuplerowbytes(c, tupnode, row); e2 = e2.next; }; @@ -43852,16 +43852,16 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, let rowoff: i32 = 0; e2 = rhs.list; for (e2 != nil) { - let row: *node = e2; - for (row != nil && row.kind == nkind.N_CAST) { row = row.lhs; }; + let row: *syntax.node = e2; + for (row != nil && row.kind == syntax.nkind.N_CAST) { row = row.lhs; }; emittuplerowrelocs(c, name, module, true, rowoff, tupnode, row); rowoff += stride; e2 = e2.next; }; } else { if (eu != nil) { - if (eu.kind == tykind.TY_STR || eu.kind == tykind.TY_SLICE - || eu.kind == tykind.TY_TAGGED) { + if (eu.kind == syntax.tykind.TY_STR || eu.kind == syntax.tykind.TY_SLICE + || eu.kind == syntax.tykind.TY_TAGGED) { let m: str = "emitslicedata: slice-of-{str,slice,tagged} literal static-init unsupported (#10 follow-up, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -43869,7 +43869,7 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, }; let esz: i32 = etype.size: i32; // Synthesize [k]T to ride the emitarraylitbytes choke-point. - let arrt: *tinfo = newtype(tykind.TY_ARRAY); + let arrt: *syntax.tinfo = syntax.newtype(syntax.tykind.TY_ARRAY); arrt.sub = etype; arrt.alen = k: u64; arrt.size = (k * esz): u64; @@ -43932,7 +43932,7 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, // share this raw core so a nested tagged member rides the SAME // (tag,payload) SSoT as a scalar tagged global. Mirror of cstage // emit_tagged_bytes. -fn emittaggedbytes(c: *cgen, tti: *tinfo, rhs: *node, sz: i32, emit_phase: i32) bool = { +fn emittaggedbytes(c: *cgen, tti: *syntax.tinfo, rhs: *syntax.node, sz: i32, emit_phase: i32) bool = { if (tti == nil) { return false; }; if (rhs == nil) { if (emit_phase == 1) { @@ -43941,10 +43941,10 @@ fn emittaggedbytes(c: *cgen, tti: *tinfo, rhs: *node, sz: i32, emit_phase: i32) }; return true; }; - let r: *node = rhs; - for (r != nil && r.kind == nkind.N_CAST) { r = r.lhs; }; + let r: *syntax.node = rhs; + for (r != nil && r.kind == syntax.nkind.N_CAST) { r = r.lhs; }; if (r == nil) { return false; }; - let tag: i32 = flatvariantidxt(tti, r.type_: *tinfo, false); + let tag: i32 = flatvariantidxt(tti, r.type_: *syntax.tinfo, false); if (tag < 0) { return false; }; if (nodeisstr(c, r) || nodeisslice(c, r)) { return false; }; let v: u64 = 0u64; @@ -43972,18 +43972,18 @@ fn emittaggedbytes(c: *cgen, tti: *tinfo, rhs: *node, sz: i32, emit_phase: i32) // other variant payload returns false and the caller loud-stops (rule 7) — // never the pre-#87 silent no-DATA + garbage read. Mirror of cstage // emit_tagged_data. -fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i32) bool = { +fn emittaggeddata(c: *cgen, name: str, module: str, tt: *syntax.node, rhs: *syntax.node, sz: i32) bool = { if (tt == nil) { return false; }; if (rhs == nil) { emitline("DATAW "); emitfnname(c, name, module); emitline("(SB),\""); - emittaggedbytes(c, tt.type_: *tinfo, rhs, sz, 1); + emittaggedbytes(c, tt.type_: *syntax.tinfo, rhs, sz, 1); emitline("\"\n"); return true; }; - let r: *node = rhs; - for (r != nil && r.kind == nkind.N_CAST) { r = r.lhs; }; + let r: *syntax.node = rhs; + for (r != nil && r.kind == syntax.nkind.N_CAST) { r = r.lhs; }; if (r == nil) { return false; }; // E8/#35: select the variant via flatvariantidx — the EXACT twin of // cstage emit_tagged_data's cg_tag_for_variant (cmd/w6c/cgen.c:15472). @@ -44006,7 +44006,7 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i let i: i32 = 0; let acc: u64 = 0u64; if (wide) { - if (r.kind != nkind.N_STRLIT) { return false; }; + if (r.kind != syntax.nkind.N_STRLIT) { return false; }; let lv: u64 = r.str.len: u64; emitline("DATAW "); emitfnname(c, name, module); @@ -44043,11 +44043,11 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i // int/zero payload via the shared raw core; validate (phase 0) BEFORE // opening the directive so a non-foldable rhs returns false without // leaving a half-written DATAW. - if (!emittaggedbytes(c, tt.type_: *tinfo, rhs, sz, 0)) { return false; }; + if (!emittaggedbytes(c, tt.type_: *syntax.tinfo, rhs, sz, 0)) { return false; }; emitline("DATAW "); emitfnname(c, name, module); emitline("(SB),\""); - emittaggedbytes(c, tt.type_: *tinfo, rhs, sz, 1); + emittaggedbytes(c, tt.type_: *syntax.tinfo, rhs, sz, 1); emitline("\"\n"); return true; }; @@ -44058,11 +44058,11 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i // address-of-fn codegen arm (fnretlookup at the N_UN TK_AMP ident, // cgenexpr.ww). The reloc target symbol is emitted via emitfnname at the // call site (cstage node_fnptr_sym returns the mangled string directly). -fn nodefnptr(c: *cgen, ev: *node) bool = { +fn nodefnptr(c: *cgen, ev: *syntax.node) bool = { if (ev == nil) { return false; }; - if (ev.kind != nkind.N_UN) { return false; }; - if (ev.op != tkind.TK_AMP) { return false; }; - let opnd: *node = ev.lhs; + if (ev.kind != syntax.nkind.N_UN) { return false; }; + if (ev.op != syntax.tkind.TK_AMP) { return false; }; + let opnd: *syntax.node = ev.lhs; if (opnd == nil) { return false; }; // #124: a cross-module `&mod.fn` — opnd is an N_DOT whose base is an // SK_USE module qualifier (not a local / let / def), and whose leaf @@ -44070,9 +44070,9 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { // curmod) at the emit sites so the reloc targets the same TEXT symbol // the runtime `&mod.fn` emits (cgenexpr.ww N_DOT addr-of arm). The // N_DOT arm of the #117/#119 reloc helper. - if (opnd.kind == nkind.N_DOT) { + if (opnd.kind == syntax.nkind.N_DOT) { if (opnd.lhs == nil) { return false; }; - if (opnd.lhs.kind != nkind.N_IDENT) { return false; }; + if (opnd.lhs.kind != syntax.nkind.N_IDENT) { return false; }; let basenm: str = opnd.lhs.str; if (localfindnode(c, basenm) != nil) { return false; }; if (isletvar(c, basenm)) { return false; }; @@ -44080,7 +44080,7 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { if (fnretlookupmod(c, opnd.str, basenm) == nil) { return false; }; return true; }; - if (opnd.kind != nkind.N_IDENT) { return false; }; + if (opnd.kind != syntax.nkind.N_IDENT) { return false; }; // #14 (F7-c7): type-keyed, mirroring cstage node_fnptr_sym // (type_chase_named(opnd->type)->kind == TY_FN, cmd/w6c/cgen.c:15542- // 15543). The prior name-keyed `fnretlookup(opnd.str)` matched a fn @@ -44092,9 +44092,9 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { // #34 fn-rvalue stamp) from a value ident, closing the leaf-name // collision by construction. (F12 name-keyed overlap noted in the F7 // spec — same predicate-to-stamp shape; fixed once here.) - let ou: *tinfo = tichase(opnd.type_: *tinfo); + let ou: *syntax.tinfo = tichase(opnd.type_: *syntax.tinfo); if (ou == nil) { return false; }; - return ou.kind == tykind.TY_FN; + return ou.kind == syntax.tykind.TY_FN; }; // tuplerowfoldable — validate every cast-peeled element of `rhs` (an @@ -44107,26 +44107,26 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { // out of the output (emitarraydata precedent). Factored from emittupledata // so the slice-of-tuple backing (#117) shares it. Mirror of cstage // tuple_row_foldable. -fn tuplerowfoldable(c: *cgen, tt: *node, rhs: *node) bool = { - let tp: *node = tt.list; - let e: *node = rhs.list; +fn tuplerowfoldable(c: *cgen, tt: *syntax.node, rhs: *syntax.node) bool = { + let tp: *syntax.node = tt.list; + let e: *syntax.node = rhs.list; for (e != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (tp != nil) { et = tp.lhs; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; { - let eti: *tinfo = nil; - if (et != nil) { eti = et.type_: *tinfo; }; + let eti: *syntax.tinfo = nil; + if (et != nil) { eti = et.type_: *syntax.tinfo; }; eti = tichase(eti); - if (eti != nil && eti.kind == tykind.TY_TAGGED) { + if (eti != nil && eti.kind == syntax.tykind.TY_TAGGED) { return false; }; }; let wide: bool = isstrtype(c, et) || isslicetype(c, et); if (wide) { - if (ev.kind != nkind.N_STRLIT) { return false; }; + if (ev.kind != syntax.nkind.N_STRLIT) { return false; }; } else if (nodefnptr(c, ev)) { // #117: a `&fn` element folds to an 8B reloc slot. } else { @@ -44145,14 +44145,14 @@ fn tuplerowfoldable(c: *cgen, tt: *node, rhs: *node) bool = { // its 24B header slot (8 zero ptr placeholder + LE len + 8 zero cap). // Caller has already proven the row foldable. Mirror of cstage // emit_tuple_row_bytes. -fn emittuplerowbytes(c: *cgen, tt: *node, rhs: *node) void = { - let tp: *node = tt.list; - let e: *node = rhs.list; +fn emittuplerowbytes(c: *cgen, tt: *syntax.node, rhs: *syntax.node) void = { + let tp: *syntax.node = tt.list; + let e: *syntax.node = rhs.list; for (e != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (tp != nil) { et = tp.lhs; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let wide: bool = isstrtype(c, et) || isslicetype(c, et); if (wide) { let i: i32 = 0; @@ -44195,15 +44195,15 @@ fn emittuplerowbytes(c: *cgen, tt: *node, rhs: *node) void = { // backing place k rows contiguously (#117), emittupledata passes 0 (foff // matches the absolute element offset — byte-neutral). Mirror of cstage // emit_tuple_row_relocs. -fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i32, tt: *node, rhs: *node) void = { +fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i32, tt: *syntax.node, rhs: *syntax.node) void = { let foff: i32 = rowoff; - let tp: *node = tt.list; - let e: *node = rhs.list; + let tp: *syntax.node = tt.list; + let e: *syntax.node = rhs.list; for (e != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (tp != nil) { et = tp.lhs; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let wide: bool = isstrtype(c, et) || isslicetype(c, et); if (wide) { if (ev.str.len > 0) { @@ -44232,7 +44232,7 @@ fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i // #124: a cross-module `&mod.fn` operand mangles // the leaf with the MODULE ident; same-module `&fn` // stays on curmod. - if (ev.lhs.kind == nkind.N_DOT) { + if (ev.lhs.kind == syntax.nkind.N_DOT) { emitfnname(c, ev.lhs.str, usehint(c, ev.lhs.lhs.str)); } else { emitfnname(c, ev.lhs.str, c.curmod); @@ -44255,13 +44255,13 @@ fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i // zero-inits. Unsupported element inits return false and the caller // loud-stops (rule 7 — pre-C-t3 the whole definition was SILENTLY skipped // and reads saw garbage). Mirror of cstage emit_tuple_data. -fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = { +fn emittupledata(c: *cgen, name: str, module: str, tt: *syntax.node, rhs: *syntax.node) bool = { if (tt == nil) { return false; }; if (rhs == nil) { // #22: slot-sum via the accessor so the zero-fill matches // the checker size (cstage zero-emits u->size). let zsz: i32 = 0; - let p0: *node = tt.list; + let p0: *syntax.node = tt.list; for (p0 != nil) { zsz += tupeslotn(p0.lhs); p0 = p0.next; @@ -44274,7 +44274,7 @@ fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = emitline("\"\n"); return true; }; - if (rhs.kind != nkind.N_TUPLE) { return false; }; + if (rhs.kind != syntax.nkind.N_TUPLE) { return false; }; if (!tuplerowfoldable(c, tt, rhs)) { return false; }; emitline("DATAW "); emitfnname(c, name, module); @@ -44285,8 +44285,8 @@ fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = return true; }; -fn emitletdataw(c: *cgen, file: *node) void = { - let d: *node = file.list; +fn emitletdataw(c: *cgen, file: *syntax.node) void = { + let d: *syntax.node = file.list; for (d != nil) { // #22 M3 THE ONE REAL GUARD: a `.wwi` dep value-global is // initializer-less; emitting a DATAW for it would DUPLICATE the @@ -44295,7 +44295,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // init-less let must still zero-init). Symmetric with M2's // producer imported==0 filter — same predicate both ways. if (c.sepmode != 0 && d.imported != 0) { d = d.next; continue; }; - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { let nm: str = d.str; if (nm.len > 0) { let sz: i32 = letemitsize(c, d); @@ -44308,8 +44308,8 @@ fn emitletdataw(c: *cgen, file: *node) void = { // undefined reference at link. The str/float/ // struct/slice/tuple gates already alias-walk // (letvaris* / the tlt tnode walk) and stay put. - let dti: *tinfo = nil; - if (d.lhs != nil) { dti = tichase(d.lhs.type_: *tinfo); }; + let dti: *syntax.tinfo = nil; + if (d.lhs != nil) { dti = tichase(d.lhs.type_: *syntax.tinfo); }; // C-t3 (#48): tuple global — slot-laid DATAW // row (+ DATAR ptr patches for str elements) // via emittupledata. Unsupported element @@ -44318,20 +44318,20 @@ fn emitletdataw(c: *cgen, file: *node) void = { // and reads saw garbage. The istup gate also // keeps a tuple out of the sz==8 / str-size // arms below (a 24B tuple == str size). - let tlt: *node = d.lhs; - for (tlt != nil && tlt.kind == nkind.N_TNAME) { + let tlt: *syntax.node = d.lhs; + for (tlt != nil && tlt.kind == syntax.nkind.N_TNAME) { tlt = aliaslookup(c, tlt.str); }; let istup: bool = false; if (tlt != nil) { - if (tlt.kind == nkind.N_TTUPLE) { + if (tlt.kind == syntax.nkind.N_TTUPLE) { istup = true; }; }; if (istup) { - let tr: *node = d.rhs; + let tr: *syntax.node = d.rhs; for (tr != nil) { - if (tr.kind != nkind.N_CAST) { break; }; + if (tr.kind != syntax.nkind.N_CAST) { break; }; tr = tr.lhs; }; if (!emittupledata(c, nm, d.nmod, tlt, tr)) { @@ -44347,7 +44347,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // a tagged box (size can equal str/slice size) out of those. let istagged: bool = false; if (tlt != nil) { - if (tlt.kind == nkind.N_TTAGGED) { + if (tlt.kind == syntax.nkind.N_TTAGGED) { if (!isnullabletype(tlt)) { istagged = true; }; }; }; @@ -44374,10 +44374,10 @@ fn emitletdataw(c: *cgen, file: *node) void = { // declaration fell out of the .data section and // the link surfaced an undefined-symbol error. if (issg) { - let r: *node = d.rhs; + let r: *syntax.node = d.rhs; if (r != nil) { - if (r.kind == nkind.N_STRUCTLIT) { - let st: *tinfo = d.lhs.type_: *tinfo; + if (r.kind == syntax.nkind.N_STRUCTLIT) { + let st: *syntax.tinfo = d.lhs.type_: *syntax.tinfo; emitstructdata(c, "DATAW", nm, d.nmod, st, r); }; @@ -44390,17 +44390,17 @@ fn emitletdataw(c: *cgen, file: *node) void = { // otherwise differ across stages on user code. let isarr8: bool = false; if (dti != nil) { - if (dti.kind == tykind.TY_ARRAY) { isarr8 = true; }; + if (dti.kind == syntax.tykind.TY_ARRAY) { isarr8 = true; }; }; if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup && !istagged) { let v: u64 = 0u64; let ok: bool = true; let fnp: bool = false; - let r: *node = nil; + let r: *syntax.node = nil; if (d.rhs != nil) { r = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // Same helper as emitdefconstants (#24) @@ -44426,7 +44426,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // #124: cross-module `&mod.fn` mangles the // leaf with the MODULE ident; same-module `&fn` // stays on curmod. - if (r.lhs.kind == nkind.N_DOT) { + if (r.lhs.kind == syntax.nkind.N_DOT) { emitfnname(c, r.lhs.str, usehint(c, r.lhs.lhs.str)); } else { emitfnname(c, r.lhs.str, c.curmod); @@ -44455,9 +44455,9 @@ fn emitletdataw(c: *cgen, file: *node) void = { // emitarraydata path owns them — mirroring the existing // isarr8 guard on the sz==8 scalar arm. if (sz == primtypesize("str"): i32 && !issg && !istup && !istagged && !isarr8 && !letvarisslice(c, nm)) { - let r: *node = d.rhs; + let r: *syntax.node = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // str-literal init (non-empty): emit @@ -44467,7 +44467,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // the strlit's runtime VA. let strlitinit: bool = false; if (r != nil) { - if (r.kind == nkind.N_STRLIT) { + if (r.kind == syntax.nkind.N_STRLIT) { if (r.str.len > 0) { strlitinit = true; }; }; }; @@ -44499,8 +44499,8 @@ fn emitletdataw(c: *cgen, file: *node) void = { if (d.rhs != nil) { ok = false; if (r != nil) { - if (r.kind == nkind.N_NIL) { ok = true; }; - if (r.kind == nkind.N_STRLIT) { + if (r.kind == syntax.nkind.N_NIL) { ok = true; }; + if (r.kind == syntax.nkind.N_STRLIT) { if (r.str.len == 0) { ok = true; }; }; }; @@ -44520,9 +44520,9 @@ fn emitletdataw(c: *cgen, file: *node) void = { }; }; if (sz == tyslicesize(): i32 && !issg && !istagged && letvarisslice(c, nm)) { - let r: *node = d.rhs; + let r: *syntax.node = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // #10 part a: slice-literal static init @@ -44530,9 +44530,9 @@ fn emitletdataw(c: *cgen, file: *node) void = { // writable backing + DATAR). Loud-stops on // the deferred element kinds and the read- // only/`...` shapes (rule 7). - if (r != nil && r.kind == nkind.N_ARRLIT) { + if (r != nil && r.kind == syntax.nkind.N_ARRLIT) { emitslicedata(c, nm, d.nmod, - d.lhs.type_: *tinfo, d.lhs, r); + d.lhs.type_: *syntax.tinfo, d.lhs, r); } else { // zero-init: accept no rhs or nil. // Any other rhs is skipped → @@ -44541,7 +44541,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { if (d.rhs != nil) { ok = false; if (r != nil) { - if (r.kind == nkind.N_NIL) { ok = true; }; + if (r.kind == syntax.nkind.N_NIL) { ok = true; }; }; }; if (ok) { @@ -44596,12 +44596,12 @@ fn emitletdataw(c: *cgen, file: *node) void = { // No-rhs arrays (e.g. `let buf: [N]u8;`) go through // the same helper with rhs=nil → zero-fill branch. if (dti != nil) { - if (dti.kind == tykind.TY_ARRAY) { - let rh: *node = d.rhs; + if (dti.kind == syntax.tykind.TY_ARRAY) { + let rh: *syntax.node = d.rhs; let route: bool = false; if (rh == nil) { route = true; }; if (rh != nil) { - if (rh.kind == nkind.N_ARRLIT) { + if (rh.kind == syntax.nkind.N_ARRLIT) { route = true; }; }; @@ -44630,8 +44630,8 @@ fn emitletdataw(c: *cgen, file: *node) void = { // unary +/-/~ over the same. `def NEG: i32 = -100;` arrives as // N_UN(TK_MINUS, N_INTLIT) — the unary peel is exactly what the // gate is for. -fn emitdefconstants(c: *cgen, file: *node) void = { - let d: *node = file.list; +fn emitdefconstants(c: *cgen, file: *syntax.node) void = { + let d: *syntax.node = file.list; for (d != nil) { // #22 M3: a `.wwi` dep def with DATA storage (int-fold / float / // struct / array) must NOT re-emit — the dep's own .o owns the @@ -44639,8 +44639,8 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // they need no gate; the def registry stays populated for imported // decls so the target's LOAD paths still resolve the extern. if (c.sepmode != 0 && d.imported != 0) { d = d.next; continue; }; - if (d.kind == nkind.N_DEF) { - let r: *node = d.rhs; + if (d.kind == syntax.nkind.N_DEF) { + let r: *syntax.node = d.rhs; let v: u64 = 0u64; let ok: bool = false; if (r != nil) { @@ -44653,12 +44653,12 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // through to no-emit + undef-ref at link. Type-size // walk mirrors letvarisfloat (#129 Phase A.1). let dfsz: i32 = 0; - let dt: *node = d.lhs; + let dt: *syntax.node = d.lhs; for (dt != nil) { - if (dt.kind != nkind.N_TNAME) { dfsz = 0; break; }; + if (dt.kind != syntax.nkind.N_TNAME) { dfsz = 0; break; }; let fsz: i32 = letfloatprim(dt.str); if (fsz > 0) { dfsz = fsz; break; }; - let nx: *node = aliaslookup(c, dt.str); + let nx: *syntax.node = aliaslookup(c, dt.str); if (nx == nil) { dfsz = 0; break; }; dt = nx; }; @@ -44671,12 +44671,12 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // struct's tinfo; helper peels TY_NAMED. Parallel // to emitletdataw struct arm; uses DATA (read- // only) directive. - if (r != nil) { if (r.kind == nkind.N_STRUCTLIT) { - let st: *tinfo = d.lhs.type_: *tinfo; - let su: *tinfo = st; + if (r != nil) { if (r.kind == syntax.nkind.N_STRUCTLIT) { + let st: *syntax.tinfo = d.lhs.type_: *syntax.tinfo; + let su: *syntax.tinfo = st; su = tichase(su); if (su != nil) { - if (su.kind == tykind.TY_STRUCT) { + if (su.kind == syntax.tykind.TY_STRUCT) { emitstructdata(c, "DATA", d.str, d.nmod, st, r); }; @@ -44684,12 +44684,12 @@ fn emitdefconstants(c: *cgen, file: *node) void = { };}; // #129 A.3: array-typed def with N_ARRLIT rhs. // Parallel to emitletdataw array arm; uses DATA. - if (r != nil) { if (r.kind == nkind.N_ARRLIT) { - let at: *tinfo = d.lhs.type_: *tinfo; - let au: *tinfo = at; + if (r != nil) { if (r.kind == syntax.nkind.N_ARRLIT) { + let at: *syntax.tinfo = d.lhs.type_: *syntax.tinfo; + let au: *syntax.tinfo = at; au = tichase(au); if (au != nil) { - if (au.kind == tykind.TY_ARRAY) { + if (au.kind == syntax.tykind.TY_ARRAY) { emitarraydata(c, "DATA", d.str, d.nmod, at, r); }; @@ -44698,7 +44698,7 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // emitslicedata needs (DATAR holder must be // DATAW, w6a asm.c:362). Loud-stop, never // silent no-emit. - if (au.kind == tykind.TY_SLICE) { + if (au.kind == syntax.tykind.TY_SLICE) { let m: str = "emitdefconstants: module-level slice-literal init needs a writable `let` (DATAR holder must be DATAW, w6a asm.c:362); read-only `def` unsupported (#10, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -44830,16 +44830,16 @@ fn emitdatasection(c: *cgen) void = { type fnret = struct { fname: str, fmod: str, - rtype: *node, - params: *node, + rtype: *syntax.node, + params: *syntax.node, frnext: *fnret, }; -fn collectfnrets(c: *cgen, file: *node) void = { +fn collectfnrets(c: *cgen, file: *syntax.node) void = { c.fnrets = nil; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_FNDECL) { + if (d.kind == syntax.nkind.N_FNDECL) { let f: *fnret = alloc(fnret{fname=d.str, fmod=d.nmod, rtype=d.lhs, params=d.list, frnext=c.fnrets})!; c.fnrets = f; }; @@ -44878,17 +44878,17 @@ fn collectfnrets(c: *cgen, file: *node) void = { // the fix. Masked until #208 landed (the checker rejected the shape // before cgen ran). test/wcc/782 pins the cstage-correct runtime // (cstage-only) and graduates to STAGE_WW on #211 close. -fn fnretlookup(c: *cgen, name: str) *node = { +fn fnretlookup(c: *cgen, name: str) *syntax.node = { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, c.curmod)) { return f.rtype; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, c.curmod)) { return f.rtype; }; }; f = f.frnext; }; f = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { return f.rtype; }; + if (syntax.streq(f.fname, name)) { return f.rtype; }; f = f.frnext; }; return nil; @@ -44903,7 +44903,7 @@ fn fnretlookup(c: *cgen, name: str) *node = { // `match (utf8.next(d))` inside a `fn next() (rune | done)` resolves // the scrutinee tagged type to `(rune | done)` — flatvariantidx then // can't see arms 2/3 and collapses them onto tag 0 (task #31). -fn fnretlookupmod(c: *cgen, name: str, mod: str) *node = { +fn fnretlookupmod(c: *cgen, name: str, mod: str) *syntax.node = { // M1 #22 (#199b): the qualifier may be the import ALIAS the user // wrote (`utf8`); fn decls register f.fmod under the dotted import // PATH (`encoding.utf8`). Map alias->path so a nested-package callee @@ -44920,8 +44920,8 @@ fn fnretlookupmod(c: *cgen, name: str, mod: str) *node = { if (mk.len > 0) { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, mk)) { return f.rtype; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, mk)) { return f.rtype; }; }; f = f.frnext; }; @@ -44939,17 +44939,17 @@ fn fnretlookupmod(c: *cgen, name: str, mod: str) *node = { // detection fires (or doesn't) against the wrong param-type — `foo(7)` // against a same-leaf `(i32 | void)` param re-layouts 7 into a 2-word // tagged slot vs the same-module `i32` param's single push. -fn fnparamslookup(c: *cgen, name: str) *node = { +fn fnparamslookup(c: *cgen, name: str) *syntax.node = { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, c.curmod)) { return f.params; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, c.curmod)) { return f.params; }; }; f = f.frnext; }; f = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { return f.params; }; + if (syntax.streq(f.fname, name)) { return f.params; }; f = f.frnext; }; return nil; @@ -44966,8 +44966,8 @@ fn fnparamslookup(c: *cgen, name: str) *node = { fn samemodfn(c: *cgen, name: str) bool = { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, c.curmod)) { return true; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, c.curmod)) { return true; }; }; f = f.frnext; }; @@ -44980,7 +44980,7 @@ fn samemodfn(c: *cgen, name: str) bool = { // to the explicit module. Falls back to the first leaf match if no // matching module is registered — mirrors aliaslookup's two-pass shape // (cgen.ww:75, fixed in #27). -fn fnparamslookupmod(c: *cgen, name: str, mod: str) *node = { +fn fnparamslookupmod(c: *cgen, name: str, mod: str) *syntax.node = { // M1 #22 (#199b): map import alias -> dotted path, identical to // fnretlookupmod (the param-side twin). usehint is idempotent on a // path / c.curmod so existing callers are unaffected. @@ -44988,8 +44988,8 @@ fn fnparamslookupmod(c: *cgen, name: str, mod: str) *node = { if (mk.len > 0) { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, mk)) { return f.params; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, mk)) { return f.params; }; }; f = f.frnext; }; @@ -45006,18 +45006,18 @@ fn fnparamslookupmod(c: *cgen, name: str, mod: str) *node = { type defent = struct { dname: str, dmod: str, // originating module (`// MODULE: foo`), or empty - drhs: *node, - dtnode: *node, // #129 A.2: type-spec node (d.lhs); needed for + drhs: *syntax.node, + dtnode: *syntax.node, // #129 A.2: type-spec node (d.lhs); needed for // struct-def structinfo lookup at the cgdot // LOAD-side widening site. dnext: *defent, }; -fn collectdefs(c: *cgen, file: *node) void = { +fn collectdefs(c: *cgen, file: *syntax.node) void = { c.defs = nil; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_DEF) { + if (d.kind == syntax.nkind.N_DEF) { let e: *defent = alloc(defent{dname=d.str, dmod=d.nmod, drhs=d.rhs, dtnode=d.lhs, dnext=c.defs})!; c.defs = e; }; @@ -45032,14 +45032,14 @@ fn collectdefs(c: *cgen, file: *node) void = { fn deflookup(c: *cgen, name: str) bool = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - if (streq(e.dmod, c.curmod)) { return true; }; + if (syntax.streq(e.dname, name)) { + if (syntax.streq(e.dmod, c.curmod)) { return true; }; }; e = e.dnext; }; e = c.defs; for (e != nil) { - if (streq(e.dname, name)) { return true; }; + if (syntax.streq(e.dname, name)) { return true; }; e = e.dnext; }; return false; @@ -45051,17 +45051,17 @@ fn deflookup(c: *cgen, name: str) bool = { // same-leaf `def MSG: str = ...` sitting at the head of c.defs and // inline the wrong strlit. Used by cgdot to inline `.ptr`/`.len` on // `def NAME: str = "..."` — those aren't laid out in memory. -fn deflookuprhs(c: *cgen, name: str) *node = { +fn deflookuprhs(c: *cgen, name: str) *syntax.node = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - if (streq(e.dmod, c.curmod)) { return e.drhs; }; + if (syntax.streq(e.dname, name)) { + if (syntax.streq(e.dmod, c.curmod)) { return e.drhs; }; }; e = e.dnext; }; e = c.defs; for (e != nil) { - if (streq(e.dname, name)) { return e.drhs; }; + if (syntax.streq(e.dname, name)) { return e.drhs; }; e = e.dnext; }; return nil; @@ -45077,12 +45077,12 @@ fn deflookuprhs(c: *cgen, name: str) *node = { // str-def value-load routes here so a cross-module N_DOT collision // resolves to the explicit module. Falls back to deflookuprhs's bare- // leaf two-pass when no module matches. -fn deflookuprhsmod(c: *cgen, name: str, mod: str) *node = { +fn deflookuprhsmod(c: *cgen, name: str, mod: str) *syntax.node = { if (mod.len > 0) { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - if (streq(e.dmod, mod)) { return e.drhs; }; + if (syntax.streq(e.dname, name)) { + if (syntax.streq(e.dmod, mod)) { return e.drhs; }; }; e = e.dnext; }; @@ -45095,25 +45095,25 @@ fn deflookuprhsmod(c: *cgen, name: str, mod: str) *node = { // float address-of gate must equal that emission set, or `&def` LEAQs a // symbol the data pass never wrote. Keep in sync with emitfloatlitdata's // peel. -fn floatlitleaf(rhs: *node) bool = { - let r: *node = rhs; +fn floatlitleaf(rhs: *syntax.node) bool = { + let r: *syntax.node = rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; if (r != nil) { - if (r.kind == nkind.N_UN) { - if (r.op == tkind.TK_MINUS) { + if (r.kind == syntax.nkind.N_UN) { + if (r.op == syntax.tkind.TK_MINUS) { r = r.lhs; - for (r != nil) { if (r.kind != nkind.N_CAST) { break; }; r = r.lhs; }; - } else { if (r.op == tkind.TK_PLUS) { + for (r != nil) { if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; + } else { if (r.op == syntax.tkind.TK_PLUS) { r = r.lhs; - for (r != nil) { if (r.kind != nkind.N_CAST) { break; }; r = r.lhs; }; + for (r != nil) { if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; }; }; }; }; if (r == nil) { return false; }; - return r.kind == nkind.N_FLOATLIT; + return r.kind == syntax.nkind.N_FLOATLIT; }; // #149/#147: a top-level def is addressable for `&def` iff emitdefs emits @@ -45125,7 +45125,7 @@ fn floatlitleaf(rhs: *node) bool = { // loud error, never a LEAQ of a missing symbol. `opnd` is the `&`-operand // N_IDENT; its checker-stamped type_ carries the def's type (same as the // cgident float-def read at cgenexpr.ww). -fn defisaddressable(c: *cgen, opnd: *node) bool = { +fn defisaddressable(c: *cgen, opnd: *syntax.node) bool = { let nm: str = opnd.str; if (defvarstructinfo(c, nm) != nil) { return true; }; // #88: the emission side (emitdefconstants' array arm) peels @@ -45133,12 +45133,12 @@ fn defisaddressable(c: *cgen, opnd: *node) bool = { // array HAS a DATA symbol — keying this gate on the unchased // dtnode kind (N_TARRAY) lied it back to the loud error. Chase // the same stamped tinfo so gate == emission set stays exact. - let dtn: *node = defvartnode(c, nm); + let dtn: *syntax.node = defvartnode(c, nm); if (dtn != nil) { - let du88: *tinfo = tichase(dtn.type_: *tinfo); - if (du88 != nil) { if (du88.kind == tykind.TY_ARRAY) { return true; }; }; + let du88: *syntax.tinfo = tichase(dtn.type_: *syntax.tinfo); + if (du88 != nil) { if (du88.kind == syntax.tykind.TY_ARRAY) { return true; }; }; }; - let drhs: *node = deflookuprhs(c, nm); + let drhs: *syntax.node = deflookuprhs(c, nm); if (drhs == nil) { return false; }; let v: u64 = 0u64; if (foldintliteral(drhs, &v)) { return true; }; @@ -45168,14 +45168,14 @@ type modent = struct { mnext: *modent, }; -fn collectmods(c: *cgen, file: *node) void = { +fn collectmods(c: *cgen, file: *syntax.node) void = { c.mods = nil; c.uses = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { // M1 #22: record alias→path for the qualified-ref hint. - if (d.kind == nkind.N_USE) { + if (d.kind == syntax.nkind.N_USE) { if (d.usepath.len > 0) { let um: *modent = alloc(modent{mname=d.str, nmod=d.usepath, omod=d.nmod, mnext=c.uses})!; c.uses = um; @@ -45184,23 +45184,23 @@ fn collectmods(c: *cgen, file: *node) void = { // Mirror collectfnrets' shape exactly (plain prepend in one // branch). Earlier nested-if/early-return variants tickled a // wwstage cgen bug that dropped most prepends. - if (d.kind == nkind.N_FNDECL) { + if (d.kind == syntax.nkind.N_FNDECL) { // Fns mangle regardless of export status — covers // lib/os.read vs lib/io.read collision. if (d.nmod.len > 0) { let isffi: bool = false; - let a: *node = d.attr; + let a: *syntax.node = d.attr; for (a != nil) { - if (a.kind == nkind.N_ATTR) { + if (a.kind == syntax.nkind.N_ATTR) { let an: str = a.str; - if (streq(an, "symbol")) { isffi = true; }; + if (syntax.streq(an, "symbol")) { isffi = true; }; }; a = a.next; }; if (!isffi) { // M1 #32: the ROOT main (imported==0) stays bare; // an IMPORTED `fn main` mangles on its path. - if (!streq(d.str, "main") || d.imported != 0) { + if (!syntax.streq(d.str, "main") || d.imported != 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; }; @@ -45211,19 +45211,19 @@ fn collectmods(c: *cgen, file: *node) void = { // like fns — `export def MAX` becomes `.MAX`, not a bare // `MAX` two packages could clash on under sep-compile. No export // guard: every decl with a module mangles identically. - if (d.kind == nkind.N_DEF) { + if (d.kind == syntax.nkind.N_DEF) { if (d.nmod.len > 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; }; }; - if (d.kind == nkind.N_TYPEDECL) { + if (d.kind == syntax.nkind.N_TYPEDECL) { if (d.nmod.len > 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; }; }; - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { if (d.nmod.len > 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; @@ -45236,7 +45236,7 @@ fn collectmods(c: *cgen, file: *node) void = { fn modlookup(c: *cgen, name: str) str = { let m: *modent = c.mods; for (m != nil) { - if (streq(m.mname, name)) { return m.nmod; }; + if (syntax.streq(m.mname, name)) { return m.nmod; }; m = m.mnext; }; let empty: str; @@ -45263,8 +45263,8 @@ fn usehint(c: *cgen, alias: str) str = { any.ptr = nil; any.len = 0; for (m != nil) { - if (streq(m.mname, alias)) { - if (streq(m.omod, c.curmod)) { return m.nmod; }; + if (syntax.streq(m.mname, alias)) { + if (syntax.streq(m.omod, c.curmod)) { return m.nmod; }; if (any.ptr == nil && any.len == 0) { any = m.nmod; }; }; m = m.mnext; @@ -45285,9 +45285,9 @@ fn modlookupforfn(c: *cgen, name: str, hint: str) str = { first.ptr = nil; first.len = 0; for (m != nil) { - if (streq(m.mname, name)) { + if (syntax.streq(m.mname, name)) { if (hint.len > 0 && m.nmod.len > 0 - && streq(m.nmod, hint)) { + && syntax.streq(m.nmod, hint)) { return m.nmod; }; if (first.len == 0 && first.ptr == nil) { @@ -45341,20 +45341,20 @@ fn emitfnname(c: *cgen, ident: str, hint: str) void = { // ---- FFI map --------------------------------------------------------- -fn fficollect(c: *cgen, file: *node) void = { +fn fficollect(c: *cgen, file: *syntax.node) void = { c.ffis = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_FNDECL) { - let a: *node = d.attr; + if (d.kind == syntax.nkind.N_FNDECL) { + let a: *syntax.node = d.attr; for (a != nil) { - if (a.kind == nkind.N_ATTR) { + if (a.kind == syntax.nkind.N_ATTR) { let aname: str = a.str; - if (streq(aname, "symbol")) { - let symnode: *node = a.list; + if (syntax.streq(aname, "symbol")) { + let symnode: *syntax.node = a.list; if (symnode != nil) { - if (symnode.kind == nkind.N_STRLIT) { + if (symnode.kind == syntax.nkind.N_STRLIT) { let f: *ffi = alloc(ffi{ident=d.str, symbol=symnode.str, fnext=c.ffis})!; c.ffis = f; }; @@ -45372,7 +45372,7 @@ fn ffiresolve(c: *cgen, ident: str) str = { let f: *ffi = c.ffis; for (f != nil) { let id: str = f.ident; - if (streq(id, ident)) { return f.symbol; }; + if (syntax.streq(id, ident)) { return f.symbol; }; f = f.fnext; }; return ident; @@ -45486,9 +45486,9 @@ fn wquote(fd: i32, s: str) void = { // primitive/keyword resolves to no SK_TYPE → leaf. By producer time // checkfile has finished and c.cur == c.top. -fn wwitypesym(c: *checker, nm: str) *sym = { +fn wwitypesym(c: *checker, nm: str) *syntax.sym = { let empty: str; - let s: *sym = scopelookuptype(c.cur, empty, nm); + let s: *syntax.sym = syntax.scopelookuptype(c.cur, empty, nm); if (s == nil) { let dotidx: i32 = -1; let i: i32 = 0; @@ -45500,15 +45500,15 @@ fn wwitypesym(c: *checker, nm: str) *sym = { let leaf: str; leaf.ptr = nm.ptr + ((dotidx + 1): u64); leaf.len = nm.len - dotidx - 1; - s = scopelookuptype(c.cur, empty, leaf); + s = syntax.scopelookuptype(c.cur, empty, leaf); }; }; if (s == nil) { return nil; }; - if (s.skind != skind.SK_TYPE) { return nil; }; + if (s.skind != syntax.skind.SK_TYPE) { return nil; }; return s; }; -fn wwireject(d: *node, nm: str) void = { +fn wwireject(d: *syntax.node, nm: str) void = { wputs(2, d.file); wputs(2, ":"); wputs(2, strconv.u64tos(d.line: u64, strconv.base.DEC)); @@ -45520,20 +45520,20 @@ fn wwireject(d: *node, nm: str) void = { }; // Returns 1 if a non-exported nominal was named (loud), else 0. -fn wwichecktype(c: *checker, d: *node, t: *node) i32 = { +fn wwichecktype(c: *checker, d: *syntax.node, t: *syntax.node) i32 = { if (t == nil) { return 0; }; // rule-10: the wwstage checker wraps N_TTUPLE.list elements in // N_TPARAM (ast.ww:101); cstage keeps the type-AST pristine. Unwrap // transparently so the recursion sees the same shape cstage walks. - if (t.kind == nkind.N_TPARAM) { return wwichecktype(c, d, t.lhs); }; + if (t.kind == syntax.nkind.N_TPARAM) { return wwichecktype(c, d, t.lhs); }; let bad: i32 = 0; - if (t.kind == nkind.N_TNAME) { - let s: *sym = wwitypesym(c, t.str); + if (t.kind == syntax.nkind.N_TNAME) { + let s: *syntax.sym = wwitypesym(c, t.str); // sym.exported is vestigial (never set); the nominal's export // status lives on its decl node, parser-set. if (s != nil) { if (s.decl != nil) { - if (s.decl.kind == nkind.N_TYPEDECL) { + if (s.decl.kind == syntax.nkind.N_TYPEDECL) { // file.len == 0 ⇒ a checkinit-synthesized // predeclared builtin (the ONLY empty-source // decls: nomemdecl check.ww:126, the `void` @@ -45551,35 +45551,35 @@ fn wwichecktype(c: *checker, d: *node, t: *node) i32 = { }; }; } else { if ( - t.kind == nkind.N_TPTR || - t.kind == nkind.N_TSLICE || - t.kind == nkind.N_TBANG || - t.kind == nkind.N_TCHAN + t.kind == syntax.nkind.N_TPTR || + t.kind == syntax.nkind.N_TSLICE || + t.kind == syntax.nkind.N_TBANG || + t.kind == syntax.nkind.N_TCHAN ) { bad = bad | wwichecktype(c, d, t.lhs); - } else { if (t.kind == nkind.N_TARRAY) { + } else { if (t.kind == syntax.nkind.N_TARRAY) { // element only; the length is a const-expr, not a type. bad = bad | wwichecktype(c, d, t.lhs); - } else { if (t.kind == nkind.N_TFN) { - let p: *node = t.list; + } else { if (t.kind == syntax.nkind.N_TFN) { + let p: *syntax.node = t.list; for (p != nil) { bad = bad | wwichecktype(c, d, p.lhs); p = p.next; }; bad = bad | wwichecktype(c, d, t.lhs); - } else { if (t.kind == nkind.N_TSTRUCT) { - let f: *node = t.list; + } else { if (t.kind == syntax.nkind.N_TSTRUCT) { + let f: *syntax.node = t.list; for (f != nil) { bad = bad | wwichecktype(c, d, f.lhs); f = f.next; }; - } else { if (t.kind == nkind.N_TTAGGED || t.kind == nkind.N_TTUPLE) { - let e: *node = t.list; + } else { if (t.kind == syntax.nkind.N_TTAGGED || t.kind == syntax.nkind.N_TTUPLE) { + let e: *syntax.node = t.list; for (e != nil) { bad = bad | wwichecktype(c, d, e); e = e.next; }; - } else { if (t.kind == nkind.N_TENUM) { + } else { if (t.kind == syntax.nkind.N_TENUM) { // the inline enum body is the definition, not a reference; // recurse only its storage type (members are values). bad = bad | wwichecktype(c, d, t.lhs); @@ -45587,21 +45587,21 @@ fn wwichecktype(c: *checker, d: *node, t: *node) i32 = { return bad; }; -fn wwicheckdecl(c: *checker, d: *node) i32 = { +fn wwicheckdecl(c: *checker, d: *syntax.node) i32 = { let bad: i32 = 0; - if (d.kind == nkind.N_FNDECL) { - let p: *node = d.list; + if (d.kind == syntax.nkind.N_FNDECL) { + let p: *syntax.node = d.list; for (p != nil) { bad = bad | wwichecktype(c, d, p.lhs); p = p.next; }; bad = bad | wwichecktype(c, d, d.lhs); // ret - } else { if (d.kind == nkind.N_TYPEDECL) { + } else { if (d.kind == syntax.nkind.N_TYPEDECL) { bad = bad | wwichecktype(c, d, d.lhs); - } else { if (d.kind == nkind.N_DEF) { + } else { if (d.kind == syntax.nkind.N_DEF) { // the declared type; the rhs const value is not a type. bad = bad | wwichecktype(c, d, d.lhs); - } else { if (d.kind == nkind.N_LET) { + } else { if (d.kind == syntax.nkind.N_LET) { bad = bad | wwichecktype(c, d, d.lhs); };};};}; return bad; @@ -45647,39 +45647,39 @@ fn wwirune(fd: i32, cp: u64) void = { wputb(fd, '\''); }; -fn wwiexpr(fd: i32, e: *node) void = { +fn wwiexpr(fd: i32, e: *syntax.node) void = { if (e == nil) { return; }; - if (e.kind == nkind.N_INTLIT) { + if (e.kind == syntax.nkind.N_INTLIT) { wputs(fd, strconv.u64tos(e.uval, strconv.base.DEC)); if (e.tsuffix.len > 0) { wputs(fd, e.tsuffix); }; - } else { if (e.kind == nkind.N_IDENT || e.kind == nkind.N_TNAME) { + } else { if (e.kind == syntax.nkind.N_IDENT || e.kind == syntax.nkind.N_TNAME) { wputs(fd, e.str); - } else { if (e.kind == nkind.N_DOT) { + } else { if (e.kind == syntax.nkind.N_DOT) { wwiexpr(fd, e.lhs); wputb(fd, '.'); wputs(fd, e.str); - } else { if (e.kind == nkind.N_TRUE) { + } else { if (e.kind == syntax.nkind.N_TRUE) { wputs(fd, "true"); - } else { if (e.kind == nkind.N_FALSE) { + } else { if (e.kind == syntax.nkind.N_FALSE) { wputs(fd, "false"); - } else { if (e.kind == nkind.N_NIL) { + } else { if (e.kind == syntax.nkind.N_NIL) { wputs(fd, "nil"); - } else { if (e.kind == nkind.N_STRLIT) { + } else { if (e.kind == syntax.nkind.N_STRLIT) { wquote(fd, e.str); - } else { if (e.kind == nkind.N_RUNELIT) { + } else { if (e.kind == syntax.nkind.N_RUNELIT) { // A bare rune literal in a const-expr (types.RUNE_MIN = '\0'); // casts never reach here — the checker folds a const cast to an // integer literal before the producer runs (RUNE_MAX // `0x10ffff: rune` emits as the plain int 1114111). wwirune(fd, e.uval); - } else { if (e.kind == nkind.N_BIN) { + } else { if (e.kind == syntax.nkind.N_BIN) { wwiexpr(fd, e.lhs); wputb(fd, 32u8); - wputs(fd, tokname(e.op)); + wputs(fd, syntax.tokname(e.op)); wputb(fd, 32u8); wwiexpr(fd, e.rhs); - } else { if (e.kind == nkind.N_UN) { - wputs(fd, tokname(e.op)); + } else { if (e.kind == syntax.nkind.N_UN) { + wputs(fd, syntax.tokname(e.op)); wwiexpr(fd, e.lhs); } else { wputs(2, "wwi: unhandled const-expr node kind\n"); @@ -45687,8 +45687,8 @@ fn wwiexpr(fd: i32, e: *node) void = { };};};};};};};};};}; }; -fn wwiparam(fd: i32, p: *node) void = { - if (streq(p.str, "...")) { // C-style FFI `...` +fn wwiparam(fd: i32, p: *syntax.node) void = { + if (syntax.streq(p.str, "...")) { // C-style FFI `...` wputs(fd, "..."); return; }; @@ -45699,46 +45699,46 @@ fn wwiparam(fd: i32, p: *node) void = { // rule-10: the wwstage checker desugars a Hare variadic `T...` param // in place to `[]T` (lhs becomes N_TSLICE); cstage leaves lhs == T. // Peel the inserted slice so both stages emit the surface `T...`. - if (p.op == tkind.TK_ELLIPSIS && p.lhs != nil && p.lhs.kind == nkind.N_TSLICE) { + if (p.op == syntax.tkind.TK_ELLIPSIS && p.lhs != nil && p.lhs.kind == syntax.nkind.N_TSLICE) { wwitype(fd, p.lhs.lhs); } else { wwitype(fd, p.lhs); }; - if (p.op == tkind.TK_ELLIPSIS) { // Hare `T...` variadic + if (p.op == syntax.tkind.TK_ELLIPSIS) { // Hare `T...` variadic wputs(fd, "..."); }; }; -fn wwitype(fd: i32, t: *node) void = { +fn wwitype(fd: i32, t: *syntax.node) void = { if (t == nil) { // absent return type spells void wputs(fd, "void"); return; }; // rule-10: unwrap the wwstage-only N_TPARAM tuple-element wrapper // (ast.ww:101) so the unparse matches cstage's pristine type-AST. - if (t.kind == nkind.N_TPARAM) { wwitype(fd, t.lhs); return; }; - if (t.kind == nkind.N_TNAME) { + if (t.kind == syntax.nkind.N_TPARAM) { wwitype(fd, t.lhs); return; }; + if (t.kind == syntax.nkind.N_TNAME) { if (t.str.len > 0) { wputs(fd, t.str); } else { wputs(fd, "void"); }; - } else { if (t.kind == nkind.N_TPTR) { + } else { if (t.kind == syntax.nkind.N_TPTR) { wputb(fd, '*'); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TSLICE) { + } else { if (t.kind == syntax.nkind.N_TSLICE) { wputs(fd, "[]"); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TARRAY) { + } else { if (t.kind == syntax.nkind.N_TARRAY) { wputb(fd, '['); if (t.rhs != nil) { wwiexpr(fd, t.rhs); } else { wputb(fd, '_'); }; wputb(fd, ']'); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TBANG) { + } else { if (t.kind == syntax.nkind.N_TBANG) { wputb(fd, '!'); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TCHAN) { + } else { if (t.kind == syntax.nkind.N_TCHAN) { wputs(fd, "chan "); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TFN) { + } else { if (t.kind == syntax.nkind.N_TFN) { wputs(fd, "fn("); - let p: *node = t.list; + let p: *syntax.node = t.list; for (p != nil) { if (p != t.list) { wputs(fd, ", "); }; wwiparam(fd, p); @@ -45746,9 +45746,9 @@ fn wwitype(fd: i32, t: *node) void = { }; wputs(fd, ") "); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TSTRUCT) { + } else { if (t.kind == syntax.nkind.N_TSTRUCT) { wputs(fd, "struct { "); - let f: *node = t.list; + let f: *syntax.node = t.list; for (f != nil) { if (f != t.list) { wputs(fd, ", "); }; if (f.str.len > 0) { @@ -45759,32 +45759,32 @@ fn wwitype(fd: i32, t: *node) void = { f = f.next; }; wputs(fd, " }"); - } else { if (t.kind == nkind.N_TTUPLE) { + } else { if (t.kind == syntax.nkind.N_TTUPLE) { wputb(fd, '('); - let e: *node = t.list; + let e: *syntax.node = t.list; for (e != nil) { if (e != t.list) { wputs(fd, ", "); }; wwitype(fd, e); e = e.next; }; wputb(fd, ')'); - } else { if (t.kind == nkind.N_TTAGGED) { + } else { if (t.kind == syntax.nkind.N_TTAGGED) { wputb(fd, '('); - let e: *node = t.list; + let e: *syntax.node = t.list; for (e != nil) { if (e != t.list) { wputs(fd, " | "); }; wwitype(fd, e); e = e.next; }; wputb(fd, ')'); - } else { if (t.kind == nkind.N_TENUM) { + } else { if (t.kind == syntax.nkind.N_TENUM) { wputs(fd, "enum "); if (t.lhs != nil) { wwitype(fd, t.lhs); wputb(fd, 32u8); }; wputs(fd, "{ "); - let m: *node = t.list; + let m: *syntax.node = t.list; for (m != nil) { if (m != t.list) { wputs(fd, ", "); }; wputs(fd, m.str); @@ -45809,18 +45809,18 @@ fn wwitype(fd: i32, t: *node) void = { // today (task #47 report). @test never reaches a `.wwi` (test fns are not // export-marked), so it needs no exclusion arm. fn wwiattrrelevant(nm: str) bool = { - return streq(nm, "symbol"); + return syntax.streq(nm, "symbol"); }; -fn wwiattrs(fd: i32, d: *node) void = { - let a: *node = d.attr; +fn wwiattrs(fd: i32, d: *syntax.node) void = { + let a: *syntax.node = d.attr; for (a != nil) { - if (a.kind == nkind.N_ATTR && wwiattrrelevant(a.str)) { + if (a.kind == syntax.nkind.N_ATTR && wwiattrrelevant(a.str)) { wputb(fd, '@'); wputs(fd, a.str); if (a.list != nil) { wputb(fd, '('); - let arg: *node = a.list; + let arg: *syntax.node = a.list; for (arg != nil) { if (arg != a.list) { wputs(fd, ", "); }; wwiexpr(fd, arg); @@ -45834,13 +45834,13 @@ fn wwiattrs(fd: i32, d: *node) void = { }; }; -fn wwidecl(fd: i32, d: *node) void = { - if (d.kind == nkind.N_FNDECL) { +fn wwidecl(fd: i32, d: *syntax.node) void = { + if (d.kind == syntax.nkind.N_FNDECL) { wwiattrs(fd, d); wputs(fd, "export fn "); wputs(fd, d.str); wputb(fd, '('); - let p: *node = d.list; + let p: *syntax.node = d.list; for (p != nil) { if (p != d.list) { wputs(fd, ", "); }; wwiparam(fd, p); @@ -45849,13 +45849,13 @@ fn wwidecl(fd: i32, d: *node) void = { wputs(fd, ") "); wwitype(fd, d.lhs); wputs(fd, ";\n"); - } else { if (d.kind == nkind.N_TYPEDECL) { + } else { if (d.kind == syntax.nkind.N_TYPEDECL) { wputs(fd, "export type "); wputs(fd, d.str); wputs(fd, " = "); wwitype(fd, d.lhs); wputs(fd, ";\n"); - } else { if (d.kind == nkind.N_DEF) { + } else { if (d.kind == syntax.nkind.N_DEF) { wputs(fd, "export def "); wputs(fd, d.str); wputs(fd, ": "); @@ -45869,15 +45869,15 @@ fn wwidecl(fd: i32, d: *node) void = { // side const-fold of an aggregate def's FIELDS — a no-op, ww // never folds struct-literal field access, and an aggregate-def // field demanded in a const-fold context stays a LOUD error (#71). - if (d.rhs != nil && (d.rhs.kind == nkind.N_STRUCTLIT || - d.rhs.kind == nkind.N_ARRLIT)) { + if (d.rhs != nil && (d.rhs.kind == syntax.nkind.N_STRUCTLIT || + d.rhs.kind == syntax.nkind.N_ARRLIT)) { wputs(fd, ";\n"); } else { wputs(fd, " = "); wwiexpr(fd, d.rhs); wputs(fd, ";\n"); }; - } else { if (d.kind == nkind.N_LET) { + } else { if (d.kind == syntax.nkind.N_LET) { wputs(fd, "export let "); wputs(fd, d.str); wputs(fd, ": "); @@ -45892,16 +45892,16 @@ fn wwidecl(fd: i32, d: *node) void = { // --- deterministic ordering (rob §3) ---------------------------------- -fn wwiprimary(n: *node) bool = { +fn wwiprimary(n: *syntax.node) bool = { // imported==1 marks a decl reached through a `//ww:module ` // boundary (an imported module's concatenated section). if (n == nil) { return false; }; return n.imported == 0; }; -fn wwiisdecl(d: *node) bool = { - return d.kind == nkind.N_FNDECL || d.kind == nkind.N_TYPEDECL || - d.kind == nkind.N_DEF || d.kind == nkind.N_LET; +fn wwiisdecl(d: *syntax.node) bool = { + return d.kind == syntax.nkind.N_FNDECL || d.kind == syntax.nkind.N_TYPEDECL || + d.kind == syntax.nkind.N_DEF || d.kind == syntax.nkind.N_LET; }; // strcmp — byte lexicographic, mirror C strcmp sign (<0/0/>0). Both @@ -45921,7 +45921,7 @@ fn wwistrcmp(a: str, b: str) i32 = { // the symbol name; ties broken by original index — so the result is // stable regardless of any same-name collision, matching cstage's qsort // + idx tiebreak. -fn wwisortdecls(keys: []str, nodes: []*node, n: i32) void = { +fn wwisortdecls(keys: []str, nodes: []*syntax.node, n: i32) void = { let i: i32 = 0; for (i < n) { let best: i32 = i; @@ -45933,17 +45933,17 @@ fn wwisortdecls(keys: []str, nodes: []*node, n: i32) void = { }; if (best != i) { let tk: str = keys[i]; keys[i] = keys[best]; keys[best] = tk; - let tn: *node = nodes[i]; nodes[i] = nodes[best]; nodes[best] = tn; + let tn: *syntax.node = nodes[i]; nodes[i] = nodes[best]; nodes[best] = tn; }; i += 1; }; }; -export fn wwiemit(c: *checker, file: *node, path: str) i32 = { +export fn wwiemit(c: *checker, file: *syntax.node, path: str) i32 = { // §5: check_exported_type FIRST, before any byte — a producer // without it can emit a dangling `.wwi`. let bad: i32 = 0; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { if (wwiprimary(d) && d.exported != 0 && wwiisdecl(d)) { bad = bad | wwicheckdecl(c, d); @@ -45963,7 +45963,7 @@ export fn wwiemit(c: *checker, file: *node, path: str) i32 = { // package line: leaf of the first primary decl's module tag. let pkg: str = "main"; - let pd: *node = file.list; + let pd: *syntax.node = file.list; for (pd != nil) { if (wwiprimary(pd) && pd.nmod.len > 0) { let dotidx: i32 = -1; @@ -45991,20 +45991,20 @@ export fn wwiemit(c: *checker, file: *node, path: str) i32 = { // imports — primary N_USE, byte-sorted by import path. let nuse: i32 = 0; - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { - if (u.kind == nkind.N_USE && wwiprimary(u)) { nuse += 1; }; + if (u.kind == syntax.nkind.N_USE && wwiprimary(u)) { nuse += 1; }; u = u.next; }; if (nuse > 0) { let upaths: []str = alloc([], nuse: u64)!; upaths.len = nuse; - let unodes: []*node = alloc([], nuse: u64)!; + let unodes: []*syntax.node = alloc([], nuse: u64)!; unodes.len = nuse; let k: i32 = 0; u = file.list; for (u != nil) { - if (u.kind == nkind.N_USE && wwiprimary(u)) { + if (u.kind == syntax.nkind.N_USE && wwiprimary(u)) { if (u.usepath.len > 0) { upaths[k] = u.usepath; } else { upaths[k] = u.str; }; unodes[k] = u; k += 1; @@ -46031,7 +46031,7 @@ export fn wwiemit(c: *checker, file: *node, path: str) i32 = { if (ndecl > 0) { let dkeys: []str = alloc([], ndecl: u64)!; dkeys.len = ndecl; - let dnodes: []*node = alloc([], ndecl: u64)!; + let dnodes: []*syntax.node = alloc([], ndecl: u64)!; dnodes.len = ndecl; let k: i32 = 0; d = file.list; diff --git a/selfhost/cmd/wcc/cgen.ww b/selfhost/cmd/wcc/cgen.ww index d31b0762..32123fce 100644 --- a/selfhost/cmd/wcc/cgen.ww +++ b/selfhost/cmd/wcc/cgen.ww @@ -48,11 +48,11 @@ import cgendecl; type aliasent = struct { aname: str, amod: str, // originating module (`// MODULE: foo`), or empty - target: *node, // the rhs type expr + target: *syntax.node, // the rhs type expr aanext: *aliasent, }; -fn collectaliases(c: *cgen, file: *node) void = { +fn collectaliases(c: *cgen, file: *syntax.node) void = { c.aliases = nil; // #29: seed `type nomem = !void;` here AS WELL AS in check.ww's // seedprimitives. The two seeds aren't redundant: wwstage's check @@ -65,18 +65,18 @@ fn collectaliases(c: *cgen, file: *node) void = { // same-module / any-match passes in aliaslookup then let a local // `type nomem = !void;` shadow this fallback within its module. let empty: str; - let tnvoid: *node = newnode(nkind.N_TNAME, empty, 0, 0); + let tnvoid: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, empty, 0, 0); tnvoid.str = "void"; - let bang: *node = newnode(nkind.N_TBANG, empty, 0, 0); + let bang: *syntax.node = syntax.newnode(syntax.nkind.N_TBANG, empty, 0, 0); bang.lhs = tnvoid; let nomemal: *aliasent = alloc(aliasent{aname="nomem", amod=empty, target=bang, aanext=nil})!; c.aliases = nomemal; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_TYPEDECL) { - let body: *node = d.lhs; + if (d.kind == syntax.nkind.N_TYPEDECL) { + let body: *syntax.node = d.lhs; if (body != nil) { - if (body.kind != nkind.N_TSTRUCT) { + if (body.kind != syntax.nkind.N_TSTRUCT) { let a: *aliasent = alloc(aliasent{aname=d.str, amod=d.nmod, target=body, aanext=c.aliases})!; c.aliases = a; }; @@ -86,7 +86,7 @@ fn collectaliases(c: *cgen, file: *node) void = { }; }; -fn aliaslookup(c: *cgen, name: str) *node = { +fn aliaslookup(c: *cgen, name: str) *syntax.node = { // Same-module first, then any. Mirrors cstage's scope_lookup_prefer // (cmd/wcc/check.c:65); without the prefer pass a bare `invalid` // in module M with `type invalid = !void;` can collapse onto a @@ -96,14 +96,14 @@ fn aliaslookup(c: *cgen, name: str) *node = { // (task #27 silent-correct-by-zero-init). let a: *aliasent = c.aliases; for (a != nil) { - if (streq(a.aname, name)) { - if (streq(a.amod, c.curmod)) { return a.target; }; + if (syntax.streq(a.aname, name)) { + if (syntax.streq(a.amod, c.curmod)) { return a.target; }; }; a = a.aanext; }; a = c.aliases; for (a != nil) { - if (streq(a.aname, name)) { return a.target; }; + if (syntax.streq(a.aname, name)) { return a.target; }; a = a.aanext; }; // Module-qualified form: `pkg.alias` → match the leaf name @@ -125,8 +125,8 @@ fn aliaslookup(c: *cgen, name: str) *node = { let pkgmod: str = usehint(c, pkg); let b: *aliasent = c.aliases; for (b != nil) { - if (streq(b.aname, leaf)) { - if (streq(b.amod, pkgmod)) { + if (syntax.streq(b.aname, leaf)) { + if (syntax.streq(b.amod, pkgmod)) { return b.target; }; }; @@ -145,11 +145,11 @@ fn aliaslookup(c: *cgen, name: str) *node = { // cgdot needs to know whether THIS module defines the name as an alias // (so the peel continues) without that cross-module fallback. Returns // the alias target only when an alias of `name` lives in c.curmod. -fn aliassamemod(c: *cgen, name: str) *node = { +fn aliassamemod(c: *cgen, name: str) *syntax.node = { let a: *aliasent = c.aliases; for (a != nil) { - if (streq(a.aname, name)) { - if (streq(a.amod, c.curmod)) { return a.target; }; + if (syntax.streq(a.aname, name)) { + if (syntax.streq(a.amod, c.curmod)) { return a.target; }; }; a = a.aanext; }; @@ -172,34 +172,34 @@ fn aliassamemod(c: *cgen, name: str) *node = { // Whitelist kept tight on purpose: anything richer (sibling refs, // arithmetic) belongs in enumevalmember, which calls this for its // literal leaves and handles the rest itself. -fn foldintliteral(e: *node, out: *u64) bool = { +fn foldintliteral(e: *syntax.node, out: *u64) bool = { if (e == nil) { return false; }; - let k: nkind = e.kind; - if (k == nkind.N_INTLIT) { *out = e.uval; return true; }; - if (k == nkind.N_RUNELIT) { *out = e.uval; return true; }; - if (k == nkind.N_TRUE) { *out = 1u64; return true; }; - if (k == nkind.N_FALSE) { *out = 0u64; return true; }; - if (k == nkind.N_NIL) { *out = 0u64; return true; }; - if (k == nkind.N_UN) { + let k: syntax.nkind = e.kind; + if (k == syntax.nkind.N_INTLIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_RUNELIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_TRUE) { *out = 1u64; return true; }; + if (k == syntax.nkind.N_FALSE) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_NIL) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_UN) { let v: u64; if (!foldintliteral(e.lhs, &v)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (op == tkind.TK_PLUS) { *out = v; return true; }; + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (op == syntax.tkind.TK_PLUS) { *out = v; return true; }; return false; }; return false; }; -fn enumevalmember(prev: *enummember, e: *node, out: *u64) bool = { +fn enumevalmember(prev: *enummember, e: *syntax.node, out: *u64) bool = { if (e == nil) { return false; }; if (foldintliteral(e, out)) { return true; }; - let k: nkind = e.kind; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = e.kind; + if (k == syntax.nkind.N_IDENT) { let m: *enummember = prev; for (m != nil) { - if (streq(m.mname, e.str)) { + if (syntax.streq(m.mname, e.str)) { *out = m.mval; return true; }; @@ -207,55 +207,55 @@ fn enumevalmember(prev: *enummember, e: *node, out: *u64) bool = { }; return false; }; - if (k == nkind.N_BIN) { + if (k == syntax.nkind.N_BIN) { let a: u64; let b: u64; if (!enumevalmember(prev, e.lhs, &a)) { return false; }; if (!enumevalmember(prev, e.rhs, &b)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_PLUS) { *out = a + b; return true; }; - if (op == tkind.TK_MINUS) { *out = a - b; return true; }; - if (op == tkind.TK_STAR) { *out = a * b; return true; }; - if (op == tkind.TK_SLASH) { + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_PLUS) { *out = a + b; return true; }; + if (op == syntax.tkind.TK_MINUS) { *out = a - b; return true; }; + if (op == syntax.tkind.TK_STAR) { *out = a * b; return true; }; + if (op == syntax.tkind.TK_SLASH) { if (b == 0u64) { return false; }; *out = a / b; return true; }; - if (op == tkind.TK_PERCENT) { + if (op == syntax.tkind.TK_PERCENT) { if (b == 0u64) { return false; }; *out = a % b; return true; }; - if (op == tkind.TK_AMP) { *out = a & b; return true; }; - if (op == tkind.TK_PIPE) { *out = a | b; return true; }; - if (op == tkind.TK_CARET) { *out = a ^ b; return true; }; - if (op == tkind.TK_LSHIFT) { *out = a << b; return true; }; - if (op == tkind.TK_RSHIFT) { *out = a >> b; return true; }; + if (op == syntax.tkind.TK_AMP) { *out = a & b; return true; }; + if (op == syntax.tkind.TK_PIPE) { *out = a | b; return true; }; + if (op == syntax.tkind.TK_CARET) { *out = a ^ b; return true; }; + if (op == syntax.tkind.TK_LSHIFT) { *out = a << b; return true; }; + if (op == syntax.tkind.TK_RSHIFT) { *out = a >> b; return true; }; return false; }; - if (k == nkind.N_UN) { + if (k == syntax.nkind.N_UN) { let v: u64; if (!enumevalmember(prev, e.lhs, &v)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (op == tkind.TK_PLUS) { *out = v; return true; }; + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (op == syntax.tkind.TK_PLUS) { *out = v; return true; }; return false; }; return false; }; -fn collectenums(c: *cgen, file: *node) void = { +fn collectenums(c: *cgen, file: *syntax.node) void = { c.enums = nil; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_TYPEDECL) { - let body: *node = d.lhs; + if (d.kind == syntax.nkind.N_TYPEDECL) { + let body: *syntax.node = d.lhs; if (body != nil) { - if (body.kind == nkind.N_TENUM) { + if (body.kind == syntax.nkind.N_TENUM) { let et: *enumtype = alloc(enumtype{ename=d.str, emod=d.nmod, storage=body.lhs, members=nil, etnext=nil})!; let prev: u64 = (-1i64): u64; let mhead: *enummember = nil; let mtail: *enummember = nil; - let m: *node = body.list; + let m: *syntax.node = body.list; for (m != nil) { let val: u64; if (m.lhs == nil) { @@ -289,14 +289,14 @@ fn enumlookup(c: *cgen, name: str) *enumtype = { // c.enums, silently folding `Foo.MEMBER` to the wrong constant. let e: *enumtype = c.enums; for (e != nil) { - if (streq(e.ename, name)) { - if (streq(e.emod, c.curmod)) { return e; }; + if (syntax.streq(e.ename, name)) { + if (syntax.streq(e.emod, c.curmod)) { return e; }; }; e = e.etnext; }; e = c.enums; for (e != nil) { - if (streq(e.ename, name)) { return e; }; + if (syntax.streq(e.ename, name)) { return e; }; e = e.etnext; }; // Module-qualified form embedded in name (`pkg.enum`): scope the @@ -316,8 +316,8 @@ fn enumlookup(c: *cgen, name: str) *enumtype = { let pkgmod: str = usehint(c, pkg); let b: *enumtype = c.enums; for (b != nil) { - if (streq(b.ename, leaf)) { - if (streq(b.emod, pkgmod)) { + if (syntax.streq(b.ename, leaf)) { + if (syntax.streq(b.emod, pkgmod)) { return b; }; }; @@ -338,8 +338,8 @@ fn enumlookupmod(c: *cgen, name: str, mod: str) *enumtype = { if (mod.len > 0) { let e: *enumtype = c.enums; for (e != nil) { - if (streq(e.ename, name)) { - if (streq(e.emod, mod)) { return e; }; + if (syntax.streq(e.ename, name)) { + if (syntax.streq(e.emod, mod)) { return e; }; }; e = e.etnext; }; @@ -350,7 +350,7 @@ fn enumlookupmod(c: *cgen, name: str, mod: str) *enumtype = { fn enummemberval(en: *enumtype, mname: str, out: *u64) bool = { let m: *enummember = en.members; for (m != nil) { - if (streq(m.mname, mname)) { + if (syntax.streq(m.mname, mname)) { *out = m.mval; return true; }; @@ -361,14 +361,14 @@ fn enummemberval(en: *enumtype, mname: str, out: *u64) bool = { // resolvetype — follow typedef alias chains to a "canonical" type // expr (str/slice/array/struct/...). Stops on cycles via depth limit. -fn resolvetype(c: *cgen, t: *node) *node = { - let cur: *node = t; +fn resolvetype(c: *cgen, t: *syntax.node) *syntax.node = { + let cur: *syntax.node = t; let depth: i32 = 0; for (depth < 16) { if (cur == nil) { return nil; }; - if (cur.kind != nkind.N_TNAME) { return cur; }; + if (cur.kind != syntax.nkind.N_TNAME) { return cur; }; let nm: str = cur.str; - let next: *node = aliaslookup(c, nm); + let next: *syntax.node = aliaslookup(c, nm); if (next == nil) { return cur; }; cur = next; depth += 1; @@ -387,7 +387,7 @@ type fieldinfo = struct { fname: str, foff: i32, fsz: i32, - tnode: *node, // the field type expr, for nested struct lookups + tnode: *syntax.node, // the field type expr, for nested struct lookups finext: *fieldinfo, }; @@ -411,7 +411,7 @@ type local = struct { // scanlocals pre-pass, so @tagscr/@retscr/@sretscr/ // @tagbase are sized at first-use; subsequent uses // must fit. - tnode: *node, // declared type expr (nkind.N_TNAME / nkind.N_TPTR / ...) or nil + tnode: *syntax.node, // declared type expr (nkind.N_TNAME / nkind.N_TPTR / ...) or nil lnext: *local, }; @@ -445,7 +445,7 @@ type enummember = struct { type enumtype = struct { ename: str, emod: str, // originating module (`// MODULE: foo`), or empty - storage: *node, // AST type expr for the storage type (i32 by default) + storage: *syntax.node, // AST type expr for the storage type (i32 by default) members: *enummember, etnext: *enumtype, }; @@ -499,14 +499,14 @@ type cgen = struct { // inside lib/foo binds to `foo.frob` even when // other modules also export `frob`. Set in cgfn // before walking the body. - fnret: *node, // declared return type of current fn (or nil) + fnret: *syntax.node, // declared return type of current fn (or nil) looptop: i32, loopendbuf: []str, // stack of end labels for break loopcontbuf: []str, // stack of cont labels for continue yieldtop: i32, yieldbuf: []str, // stack of match end labels for yield defertop: i32, - deferbuf: []*node, // stack of deferred exprs (LIFO at return) + deferbuf: []*syntax.node, // stack of deferred exprs (LIFO at return) // System V AMD64 sret discipline (#23). Plain TY_STRUCT returns // with size > 24B are passed via a hidden first-arg pointer // (RDI) to a caller-prealloc dest; the callee writes through @@ -534,7 +534,7 @@ type cgen = struct { // (sretdestoff) can't name a top-level let, so the lhs IDENT node // is carried and emitted as `LEAQ name(SB), DI`. nil means no // global receiver wired; mutually exclusive with sretdestoff. - sretdestnode: *node, + sretdestnode: *syntax.node, sretforward: i32, // #22 M3 `-c`: separate-compile / primary-only codegen. Emit code+ // DATA ONLY for this package's own (imported==0) decls; treat every @@ -554,7 +554,7 @@ type cgen = struct { // when picking the load/store sequence. type letvar = struct { name: str, - tnode: *node, + tnode: *syntax.node, lvnext: *letvar, }; @@ -579,7 +579,7 @@ fn cgeninit(c: *cgen) void = { let yieldbuf: []str = alloc([], LOOP_MAX: u64)!; c.yieldbuf = yieldbuf; c.defertop = 0; - let deferbuf: []*node = alloc([], DEFER_MAX: u64)!; + let deferbuf: []*syntax.node = alloc([], DEFER_MAX: u64)!; c.deferbuf = deferbuf; }; @@ -587,7 +587,7 @@ fn cgeninit(c: *cgen) void = { // match-arm bindings, which cstage allocates via cgexpr's by-value // `locals` list — so two separate matches each get fresh slots even // when their bind names collide. -fn localalloc(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { +fn localalloc(c: *cgen, name: str, sz: i32, tnode: *syntax.node) i32 = { let asz: i32 = sz; if (asz < 8) { asz = 8; }; if ((asz & 7) != 0) { asz = (asz + 7) & ~7; }; @@ -603,7 +603,7 @@ fn localalloc(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { // the binding into c.locals only AFTER, so a self-shadowing init // (`let x = f(x)`) resolves x in the OUTER scope (Hare evals the init in // the outer scope: harec check.c clet runs cexpr before scope_define). -fn localreserve(c: *cgen, name: str, sz: i32, tnode: *node) *local = { +fn localreserve(c: *cgen, name: str, sz: i32, tnode: *syntax.node) *local = { // #15: mirror cstage localslot (cmd/w6c/cgen.c:1900) — // `frame = (frame + size + 7) & ~7`, NO sub-8 floor. Identical to // the old `max(8, round8(sz))` accumulation for every sz>0 (frame @@ -623,12 +623,12 @@ fn localreserve(c: *cgen, name: str, sz: i32, tnode: *node) *local = { // pushes them in reverse, so each spilled arg lives at 16(BP), 24(BP), // etc. (after the saved RIP+BP). No spill instruction is emitted; the // slot IS the caller's stack slot. -fn localaddstack(c: *cgen, name: str, tnode: *node, off: i32) void = { +fn localaddstack(c: *cgen, name: str, tnode: *syntax.node, off: i32) void = { let l: *local = alloc(local{name=name, off=off, sz=0, tnode=tnode, lnext=c.locals})!; c.locals = l; }; -fn localadd(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { +fn localadd(c: *cgen, name: str, sz: i32, tnode: *syntax.node) i32 = { // User-let path (post-#27): always allocate a fresh slot per // binding. Pre-fix this deduped by name to share one slot // across same-name lets in disjoint scopes — inherited from @@ -656,7 +656,7 @@ fn localadd(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { let cur: *local = c.atlocals; for (cur != nil) { let cn: str = cur.name; - if (streq(cn, name)) { + if (syntax.streq(cn, name)) { if (asz > cur.sz) { // rule-7 surface, post-#15: pinned slot // offset can't grow in place. @@ -719,7 +719,7 @@ fn localfindnode(c: *cgen, name: str) *local = { let l: *local = c.locals; for (l != nil) { let ln: str = l.name; - if (streq(ln, name)) { return l; }; + if (syntax.streq(ln, name)) { return l; }; l = l.lnext; }; // @-prefix scratch slots survive cgblock save/restore via @@ -729,7 +729,7 @@ fn localfindnode(c: *cgen, name: str) *local = { if (name[0] == 64u8) { let a: *local = c.atlocals; for (a != nil) { - if (streq(a.name, name)) { return a; }; + if (syntax.streq(a.name, name)) { return a; }; a = a.lnext; }; }; @@ -748,7 +748,7 @@ fn localfind(c: *cgen, name: str) i32 = { if (name[0] == 64u8) { let a: *local = c.atlocals; for (a != nil) { - if (streq(a.name, name)) { return a.off; }; + if (syntax.streq(a.name, name)) { return a.off; }; a = a.lnext; }; }; @@ -944,7 +944,7 @@ fn internstrlit(c: *cgen, bytes: str) str = { let s: *strlit = c.strlits; for (s != nil) { let bs: str = s.bytes; - if (streq(bs, bytes)) { + if (syntax.streq(bs, bytes)) { return s.label; }; s = s.slnext; @@ -983,28 +983,28 @@ fn internstrlit(c: *cgen, bytes: str) str = { // types are handled separately by letfloatprim — they need MOVSS/MOVSD // and use 4-byte (f32) or 8-byte (f64) slots. fn letscalarprim(nm: str) bool = { - if (streq(nm, "bool")) { return true; }; - if (streq(nm, "rune")) { return true; }; - if (streq(nm, "i8")) { return true; }; - if (streq(nm, "i16")) { return true; }; - if (streq(nm, "i32")) { return true; }; - if (streq(nm, "i64")) { return true; }; - if (streq(nm, "u8")) { return true; }; - if (streq(nm, "u16")) { return true; }; - if (streq(nm, "u32")) { return true; }; - if (streq(nm, "u64")) { return true; }; - if (streq(nm, "int")) { return true; }; - if (streq(nm, "uint")) { return true; }; - if (streq(nm, "uintptr")) { return true; }; - if (streq(nm, "size")) { return true; }; + if (syntax.streq(nm, "bool")) { return true; }; + if (syntax.streq(nm, "rune")) { return true; }; + if (syntax.streq(nm, "i8")) { return true; }; + if (syntax.streq(nm, "i16")) { return true; }; + if (syntax.streq(nm, "i32")) { return true; }; + if (syntax.streq(nm, "i64")) { return true; }; + if (syntax.streq(nm, "u8")) { return true; }; + if (syntax.streq(nm, "u16")) { return true; }; + if (syntax.streq(nm, "u32")) { return true; }; + if (syntax.streq(nm, "u64")) { return true; }; + if (syntax.streq(nm, "int")) { return true; }; + if (syntax.streq(nm, "uint")) { return true; }; + if (syntax.streq(nm, "uintptr")) { return true; }; + if (syntax.streq(nm, "size")) { return true; }; return false; }; // letfloatprim — float type-name keywords. f32 → 4B slot, f64 → 8B. // Returns the slot size or 0 if not a float type. fn letfloatprim(nm: str) i32 = { - if (streq(nm, "f32")) { return 4; }; - if (streq(nm, "f64")) { return 8; }; + if (syntax.streq(nm, "f32")) { return 4; }; + if (syntax.streq(nm, "f64")) { return 8; }; return 0; }; @@ -1016,31 +1016,31 @@ fn letfloatprim(nm: str) i32 = { // 16 → str (only zero-init / nil / "" supported) // 24 → slice (only zero-init supported) // varies → struct (zero-init only; field reads/scalar-field writes) -fn letemitsize(c: *cgen, d: *node) i32 = { +fn letemitsize(c: *cgen, d: *syntax.node) i32 = { if (d == nil) { return 0; }; - let t: *node = d.lhs; + let t: *syntax.node = d.lhs; for (t != nil) { - if (t.kind == nkind.N_TPTR) { return 8; }; - if (t.kind == nkind.N_TSLICE) { return tyslicesize(): i32; }; - if (t.kind == nkind.N_TARRAY) { - let lenn: *node = t.rhs; - let elemn: *node = t.lhs; + if (t.kind == syntax.nkind.N_TPTR) { return 8; }; + if (t.kind == syntax.nkind.N_TSLICE) { return tyslicesize(): i32; }; + if (t.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = t.rhs; + let elemn: *syntax.node = t.lhs; let alen: i32 = 1; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i32; } else { // #56: def/const dim — resolve from the stamped array // tinfo (rule-13), the letemitsize twin of the cgdot // .len fix. Pre-fix a non-N_INTLIT dim defaulted alen=1 // → array global mis-sized (one element's worth). - let abt: *tinfo = tichase(t.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(t.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i32; }; }; let esz: i32 = 8; if (elemn != nil) { - if (elemn.kind == nkind.N_TNAME) { + if (elemn.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, elemn.str); if (ps > 0) { esz = ps; }; }; @@ -1054,11 +1054,11 @@ fn letemitsize(c: *cgen, d: *node) i32 = { // globals out of collectlets entirely — no DATA emitted, and // the module-leaf fallback mis-emitted the field index as a // symbol (`MOVQ 0(SB), AX`). - if (t.kind == nkind.N_TTUPLE) { + if (t.kind == syntax.nkind.N_TTUPLE) { let tsum: i32 = 0; - let p: *node = t.list; + let p: *syntax.node = t.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (isstrtype(c, et) || isslicetype(c, et)) { tsum += (tyslicesize(): i32); } else { @@ -1071,7 +1071,7 @@ fn letemitsize(c: *cgen, d: *node) i32 = { // #87: non-nullable tagged-union global — box size (tag word + // max payload, mirror of the runtime local). Mirrors cstage // let_emit_size TY_TAGGED. - if (t.kind == nkind.N_TTAGGED) { + if (t.kind == syntax.nkind.N_TTAGGED) { // #45 (silent→loud bridge, task #15): a nullable (*T|void) // GLOBAL has no storage path. Returning 0 here made // letcollect + emitletdataw silently skip the decl (no DATA, @@ -1087,15 +1087,15 @@ fn letemitsize(c: *cgen, d: *node) i32 = { }; return slotsize(c, t); }; - if (t.kind != nkind.N_TNAME) { return 0; }; + if (t.kind != syntax.nkind.N_TNAME) { return 0; }; let nm: str = t.str; if (letscalarprim(nm)) { return 8; }; let fsz: i32 = letfloatprim(nm); if (fsz > 0) { return fsz; }; - if (streq(nm, "str")) { return primtypesize("str"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("str"): i32; }; let si: *structinfo = structlookup(c, nm); if (si != nil) { return si.totsize; }; - let next: *node = aliaslookup(c, nm); + let next: *syntax.node = aliaslookup(c, nm); if (next == nil) { return 0; }; t = next; }; @@ -1129,23 +1129,23 @@ fn letemitsize(c: *cgen, d: *node) i32 = { // cs≠ww divergence (rule-10) — it ships only WITH the cstage float-use-site fix. // Runs before collectlets in cgfile so the mutated d.lhs is visible to // letpreintern + emitletdataw too. -fn defaultinferredlets(c: *cgen, file: *node) void = { +fn defaultinferredlets(c: *cgen, file: *syntax.node) void = { if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { if (d.lhs != nil && d.rhs != nil - && d.lhs.kind == nkind.N_TNAME - && streq(d.lhs.str, "untyped_int")) { - let opnd: *node = d.rhs; - if (opnd.kind == nkind.N_UN - && (opnd.op == tkind.TK_PLUS - || opnd.op == tkind.TK_MINUS - || opnd.op == tkind.TK_TILDE)) { + && d.lhs.kind == syntax.nkind.N_TNAME + && syntax.streq(d.lhs.str, "untyped_int")) { + let opnd: *syntax.node = d.rhs; + if (opnd.kind == syntax.nkind.N_UN + && (opnd.op == syntax.tkind.TK_PLUS + || opnd.op == syntax.tkind.TK_MINUS + || opnd.op == syntax.tkind.TK_TILDE)) { opnd = opnd.lhs; }; if (opnd != nil - && opnd.kind == nkind.N_INTLIT) { + && opnd.kind == syntax.nkind.N_INTLIT) { d.lhs.str = "int"; }; }; @@ -1160,16 +1160,16 @@ fn defaultinferredlets(c: *cgen, file: *node) void = { // return (X0 untouched). Mirror cstage check.c clet // type_default. if (d.lhs != nil && d.rhs != nil - && d.lhs.kind == nkind.N_TNAME - && streq(d.lhs.str, "untyped_float")) { - let opnd: *node = d.rhs; - if (opnd.kind == nkind.N_UN - && (opnd.op == tkind.TK_PLUS - || opnd.op == tkind.TK_MINUS)) { + && d.lhs.kind == syntax.nkind.N_TNAME + && syntax.streq(d.lhs.str, "untyped_float")) { + let opnd: *syntax.node = d.rhs; + if (opnd.kind == syntax.nkind.N_UN + && (opnd.op == syntax.tkind.TK_PLUS + || opnd.op == syntax.tkind.TK_MINUS)) { opnd = opnd.lhs; }; if (opnd != nil - && opnd.kind == nkind.N_FLOATLIT) { + && opnd.kind == syntax.nkind.N_FLOATLIT) { d.lhs.str = "f64"; }; }; @@ -1178,12 +1178,12 @@ fn defaultinferredlets(c: *cgen, file: *node) void = { }; }; -fn collectlets(c: *cgen, file: *node) void = { +fn collectlets(c: *cgen, file: *syntax.node) void = { c.lets = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { let nm: str = d.str; if (nm.len > 0) { if (letemitsize(c, d) > 0) { @@ -1199,7 +1199,7 @@ fn collectlets(c: *cgen, file: *node) void = { fn isletvar(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { return true; }; + if (syntax.streq(lv.name, name)) { return true; }; lv = lv.lvnext; }; return false; @@ -1213,10 +1213,10 @@ fn isletvar(c: *cgen, name: str) bool = { // cgindex / cgassign to detect global `[N]T` arrays and `*T` // pointers, where the addressing path needs LEAQ name(SB) (array) // or MOVQ name(SB) (pointer) and the element size from T. -fn letvartnode(c: *cgen, name: str) *node = { +fn letvartnode(c: *cgen, name: str) *syntax.node = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { return lv.tnode; }; + if (syntax.streq(lv.name, name)) { return lv.tnode; }; lv = lv.lvnext; }; return nil; @@ -1225,13 +1225,13 @@ fn letvartnode(c: *cgen, name: str) *node = { fn letvarisstr(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let nm: str = t.str; - if (streq(nm, "str")) { return true; }; - let nx: *node = aliaslookup(c, nm); + if (syntax.streq(nm, "str")) { return true; }; + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return false; }; t = nx; }; @@ -1255,12 +1255,12 @@ fn letvarisstr(c: *cgen, name: str) bool = { fn letvarisslice(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind == nkind.N_TSLICE) { return true; }; - if (t.kind != nkind.N_TNAME) { return false; }; - let nx: *node = aliaslookup(c, t.str); + if (t.kind == syntax.nkind.N_TSLICE) { return true; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + let nx: *syntax.node = aliaslookup(c, t.str); if (nx == nil) { return false; }; t = nx; }; @@ -1277,13 +1277,13 @@ fn letvarisslice(c: *cgen, name: str) bool = { fn letvarisfloat(c: *cgen, name: str) i32 = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return 0; }; + if (t.kind != syntax.nkind.N_TNAME) { return 0; }; let fsz: i32 = letfloatprim(t.str); if (fsz > 0) { return fsz; }; - let nx: *node = aliaslookup(c, t.str); + let nx: *syntax.node = aliaslookup(c, t.str); if (nx == nil) { return 0; }; t = nx; }; @@ -1301,13 +1301,13 @@ fn letvarisfloat(c: *cgen, name: str) i32 = { fn letvarisstruct(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let nm: str = t.str; if (structlookup(c, nm) != nil) { return true; }; - let nx: *node = aliaslookup(c, nm); + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return false; }; t = nx; }; @@ -1324,14 +1324,14 @@ fn letvarisstruct(c: *cgen, name: str) bool = { fn letvarstructinfo(c: *cgen, name: str) *structinfo = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return nil; }; + if (t.kind != syntax.nkind.N_TNAME) { return nil; }; let nm: str = t.str; let si: *structinfo = structlookup(c, nm); if (si != nil) { return si; }; - let nx: *node = aliaslookup(c, nm); + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return nil; }; t = nx; }; @@ -1354,14 +1354,14 @@ fn letvarstructinfo(c: *cgen, name: str) *structinfo = { fn defvarstructinfo(c: *cgen, name: str) *structinfo = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - let t: *node = e.dtnode; + if (syntax.streq(e.dname, name)) { + let t: *syntax.node = e.dtnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return nil; }; + if (t.kind != syntax.nkind.N_TNAME) { return nil; }; let nm: str = t.str; let si: *structinfo = structlookup(c, nm); if (si != nil) { return si; }; - let nx: *node = aliaslookup(c, nm); + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return nil; }; t = nx; }; @@ -1378,10 +1378,10 @@ fn defvarstructinfo(c: *cgen, name: str) *structinfo = { // resolves through the same N_TARRAY-detect → LEAQ name(SB) shape as // a let array. Parallel to defvarstructinfo (#129 A.2) at the LOAD // side widening. -fn defvartnode(c: *cgen, name: str) *node = { +fn defvartnode(c: *cgen, name: str) *syntax.node = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { return e.dtnode; }; + if (syntax.streq(e.dname, name)) { return e.dtnode; }; e = e.dnext; }; return nil; @@ -1427,25 +1427,25 @@ fn emitdatawbyte(b: u8) void = { // order emitstrarraydata references them by — a divergent order would // mis-pair the DATAR rows with their _S_ rodata. au is the chased // TY_ARRAY tinfo, r the N_ARRLIT rhs; caller verified the element is str. -fn preinternstrarray(c: *cgen, au: *tinfo, r: *node) void = { +fn preinternstrarray(c: *cgen, au: *syntax.tinfo, r: *syntax.node) void = { let alen: i32 = au.alen: i32; let cnt: i32 = 0; - let last_ev: *node = nil; + let last_ev: *syntax.node = nil; let repeat: bool = false; - let e: *node = r.list; + let e: *syntax.node = r.list; for (e != nil && cnt < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { break; }; - if (ev.kind != nkind.N_STRLIT) { break; }; + if (ev.kind != syntax.nkind.N_STRLIT) { break; }; if (ev.str.len > 0) { internstrlit(c, ev.str); }; @@ -1469,7 +1469,7 @@ fn preinternstrarray(c: *cgen, au: *tinfo, r: *node) void = { // emitdatasection emits the DATA row in the same .s file. Running // emitletdataw after emitdatasection would flip the (DATA strlits, // DATAW lets) section order and break byte-identity. -export fn letpreintern(c: *cgen, file: *node) void = { +export fn letpreintern(c: *cgen, file: *syntax.node) void = { if (file == nil) { return; }; // #49: strlit labels allocated here (static-data initialisers) take // the OWNING decl's module prefix, not the stale last-fn curmod. @@ -1477,7 +1477,7 @@ export fn letpreintern(c: *cgen, file: *node) void = { // fn-ptr relocs — see the same value they did before; letpreintern // itself only interns, so driving curmod here has no other effect. let savedmod: str = c.curmod; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { c.curmod = d.nmod; // #22 M3: skip imported deps so the strlit table (and its _S_ @@ -1495,26 +1495,26 @@ export fn letpreintern(c: *cgen, file: *node) void = { // allocated too late (emitdefconstants pass) → dangling _S_. // Str-array ONLY — def tuple/slice/tagged/scalar-str stay out // of scope (#10/#270 / inline-Sdef). - if (d.kind == nkind.N_DEF) { - let dr: *node = d.rhs; - for (dr != nil && dr.kind == nkind.N_CAST) { + if (d.kind == syntax.nkind.N_DEF) { + let dr: *syntax.node = d.rhs; + for (dr != nil && dr.kind == syntax.nkind.N_CAST) { dr = dr.lhs; }; if (d.lhs != nil && dr != nil - && dr.kind == nkind.N_ARRLIT) { - let dau: *tinfo = tichase(d.lhs.type_: *tinfo); - if (dau != nil && dau.kind == tykind.TY_ARRAY) { - let deu: *tinfo = tichase(dau.sub); - if (deu != nil && deu.kind == tykind.TY_STR) { + && dr.kind == syntax.nkind.N_ARRLIT) { + let dau: *syntax.tinfo = tichase(d.lhs.type_: *syntax.tinfo); + if (dau != nil && dau.kind == syntax.tykind.TY_ARRAY) { + let deu: *syntax.tinfo = tichase(dau.sub); + if (deu != nil && deu.kind == syntax.tykind.TY_STR) { preinternstrarray(c, dau, dr); }; }; }; }; - if (d.kind == nkind.N_LET) { - let r: *node = d.rhs; + if (d.kind == syntax.nkind.N_LET) { + let r: *syntax.node = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // #18: `let xs: [N]str = […];` — pre-intern each @@ -1527,11 +1527,11 @@ export fn letpreintern(c: *cgen, file: *node) void = { // globals, desyncing label order vs cstage. let handled: bool = false; if (d.lhs != nil && r != nil) { - let au: *tinfo = tichase(d.lhs.type_: *tinfo); - if (au != nil && au.kind == tykind.TY_ARRAY - && r.kind == nkind.N_ARRLIT) { - let eu: *tinfo = tichase(au.sub); - if (eu != nil && eu.kind == tykind.TY_STR) { + let au: *syntax.tinfo = tichase(d.lhs.type_: *syntax.tinfo); + if (au != nil && au.kind == syntax.tykind.TY_ARRAY + && r.kind == syntax.nkind.N_ARRLIT) { + let eu: *syntax.tinfo = tichase(au.sub); + if (eu != nil && eu.kind == syntax.tykind.TY_STR) { handled = true; preinternstrarray(c, au, r); }; @@ -1542,24 +1542,24 @@ export fn letpreintern(c: *cgen, file: *node) void = { // arm's DATAR rows find their _S_ rodata rows (the // #18 array-arm pattern; cstage let_pre_intern twin). if (!handled && r != nil && d.lhs != nil) { - if (r.kind == nkind.N_TUPLE) { - let tlt: *node = d.lhs; - for (tlt != nil && tlt.kind == nkind.N_TNAME) { + if (r.kind == syntax.nkind.N_TUPLE) { + let tlt: *syntax.node = d.lhs; + for (tlt != nil && tlt.kind == syntax.nkind.N_TNAME) { tlt = aliaslookup(c, tlt.str); }; if (tlt != nil) { - if (tlt.kind == nkind.N_TTUPLE) { + if (tlt.kind == syntax.nkind.N_TTUPLE) { handled = true; - let tp: *node = tlt.list; - let e: *node = r.list; + let tp: *syntax.node = tlt.list; + let e: *syntax.node = r.list; for (e != nil && tp != nil) { - let et: *node = tp.lhs; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { + let et: *syntax.node = tp.lhs; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev != nil) { - if (ev.kind == nkind.N_STRLIT + if (ev.kind == syntax.nkind.N_STRLIT && (isstrtype(c, et) || isslicetype(c, et))) { if (ev.str.len > 0) { internstrlit(c, ev.str); @@ -1582,28 +1582,28 @@ export fn letpreintern(c: *cgen, file: *node) void = { // rodata rows (cstage letpreintern twin). Bounded to // inline N_TTUPLE element types. if (!handled && r != nil && d.lhs != nil) { - if (r.kind == nkind.N_ARRLIT - && d.lhs.kind == nkind.N_TSLICE) { - let tupnode: *node = d.lhs.lhs; - if (tupnode != nil && tupnode.kind == nkind.N_TTUPLE) { + if (r.kind == syntax.nkind.N_ARRLIT + && d.lhs.kind == syntax.nkind.N_TSLICE) { + let tupnode: *syntax.node = d.lhs.lhs; + if (tupnode != nil && tupnode.kind == syntax.nkind.N_TTUPLE) { handled = true; - let row: *node = r.list; + let row: *syntax.node = r.list; for (row != nil) { - let rw: *node = row; - for (rw != nil && rw.kind == nkind.N_CAST) { + let rw: *syntax.node = row; + for (rw != nil && rw.kind == syntax.nkind.N_CAST) { rw = rw.lhs; }; - if (rw != nil && rw.kind == nkind.N_TUPLE) { - let tp: *node = tupnode.list; - let e: *node = rw.list; + if (rw != nil && rw.kind == syntax.nkind.N_TUPLE) { + let tp: *syntax.node = tupnode.list; + let e: *syntax.node = rw.list; for (e != nil && tp != nil) { - let et: *node = tp.lhs; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { + let et: *syntax.node = tp.lhs; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev != nil) { - if (ev.kind == nkind.N_STRLIT + if (ev.kind == syntax.nkind.N_STRLIT && (isstrtype(c, et) || isslicetype(c, et))) { if (ev.str.len > 0) { internstrlit(c, ev.str); @@ -1620,13 +1620,13 @@ export fn letpreintern(c: *cgen, file: *node) void = { }; }; if (!handled && r != nil && d.lhs != nil) { - let tlt: *node = d.lhs; - for (tlt != nil && tlt.kind == nkind.N_TNAME) { + let tlt: *syntax.node = d.lhs; + for (tlt != nil && tlt.kind == syntax.nkind.N_TNAME) { tlt = aliaslookup(c, tlt.str); }; if (tlt != nil) { - if (tlt.kind == nkind.N_TTAGGED && !isnullabletype(tlt)) { - if (r.kind == nkind.N_STRLIT && r.str.len > 0 + if (tlt.kind == syntax.nkind.N_TTAGGED && !isnullabletype(tlt)) { + if (r.kind == syntax.nkind.N_STRLIT && r.str.len > 0 && (nodeisstr(c, r) || nodeisslice(c, r))) { handled = true; internstrlit(c, r.str); @@ -1641,7 +1641,7 @@ export fn letpreintern(c: *cgen, file: *node) void = { // `sz == primtypesize("str"): i32` strlit-init branch. if (sz == primtypesize("str"): i32) { if (r != nil) { - if (r.kind == nkind.N_STRLIT) { + if (r.kind == syntax.nkind.N_STRLIT) { if (r.str.len > 0) { internstrlit(c, r.str); }; @@ -1674,36 +1674,36 @@ export fn letpreintern(c: *cgen, file: *node) void = { // f64/f32 bitcast helpers into cgen. Returns true on emit, false if // rhs doesn't reduce to a foldable float literal. fn emitfloatlitdata(c: *cgen, directive: str, name: str, module: str, - sz: i32, rhs: *node) bool = { + sz: i32, rhs: *syntax.node) bool = { let isf32: bool = (sz == 4); let bits: u64 = 0u64; let neg: bool = false; if (rhs != nil) { - let r: *node = rhs; + let r: *syntax.node = rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; if (r != nil) { - if (r.kind == nkind.N_UN) { - if (r.op == tkind.TK_MINUS) { + if (r.kind == syntax.nkind.N_UN) { + if (r.op == syntax.tkind.TK_MINUS) { neg = true; r = r.lhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; - } else { if (r.op == tkind.TK_PLUS) { + } else { if (r.op == syntax.tkind.TK_PLUS) { r = r.lhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; };}; }; }; if (r == nil) { return false; }; - if (r.kind != nkind.N_FLOATLIT) { return false; }; + if (r.kind != syntax.nkind.N_FLOATLIT) { return false; }; // r.uval holds f64 bits regardless of literal suffix (lexer // stores the pre-narrow bits). f32 needs an explicit // (double→float) narrowing at emit time — mirrors cstage's @@ -1755,25 +1755,25 @@ fn emitfloatlitdata(c: *cgen, directive: str, name: str, module: str, // emit_struct_lit_bytes. `base` offsets the field-start computation // so the recursive call walks an inner struct's fields within its // outer parent's byte stream. -fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, +fn emitstructlitbytes(c: *cgen, structt: *syntax.tinfo, rhs: *syntax.node, base: u64) bool = { - let su: *tinfo = structt; + let su: *syntax.tinfo = structt; su = tichase(su); if (su == nil) { return false; }; - if (su.kind != tykind.TY_STRUCT) { return false; }; + if (su.kind != syntax.tykind.TY_STRUCT) { return false; }; let pos: u64 = base; - let f: *tfield = su.fields; + let f: *syntax.tfield = su.fields; for (f != nil) { let fstart: u64 = base + f.offset; for (pos < fstart) { emitdatawbyte(0u8); pos = pos + 1u64; }; - let v: *node = nil; + let v: *syntax.node = nil; if (rhs != nil) { - let fnod: *node = rhs.list; + let fnod: *syntax.node = rhs.list; for (fnod != nil) { - if (streq(fnod.str, f.name)) { + if (syntax.streq(fnod.str, f.name)) { v = fnod.lhs; break; }; @@ -1791,16 +1791,16 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, f = f.tnext; continue; }; - let vr: *node = v; - for (vr != nil && vr.kind == nkind.N_CAST) { vr = vr.lhs; }; - let fu: *tinfo = f.type_; + let vr: *syntax.node = v; + for (vr != nil && vr.kind == syntax.nkind.N_CAST) { vr = vr.lhs; }; + let fu: *syntax.tinfo = f.type_; fu = tichase(fu); // #19 option A: a non-nullable tagged-union field rides the shared // (tag,payload) core at the field slot size, mirroring the scalar // tagged global — NOT the int emitter. Wide/struct/non-foldable // payload loud-rejects (task #30 sub-item, rule 7). v is non-nil // here (the absent-field zero-fill is handled above). - if (fu != nil && fu.kind == tykind.TY_TAGGED && !typeisnullable(fu)) { + if (fu != nil && fu.kind == syntax.tykind.TY_TAGGED && !syntax.typeisnullable(fu)) { if (!emittaggedbytes(c, f.type_, v, fsz, 1)) { let m: str = "emitstructlitbytes: tagged-union struct-field static-init needs a zero/int payload; wide (str/slice) or struct payload is deferred (task #30, rule 7)\n"; os.write(2, m.ptr, m.len: u64); @@ -1810,13 +1810,13 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, f = f.tnext; continue; }; - if (fu != nil && fu.kind == tykind.TY_STRUCT) { + if (fu != nil && fu.kind == syntax.tykind.TY_STRUCT) { if (vr == nil) { let m: str = "emitstructlitbytes: nested struct field rhs nil (#129 A.2)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (vr.kind != nkind.N_STRUCTLIT) { + if (vr.kind != syntax.nkind.N_STRUCTLIT) { let m: str = "emitstructlitbytes: nested struct rhs not N_STRUCTLIT (#129 A.2)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -1830,13 +1830,13 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, // parked in A.2). Recurses through emitarraylitbytes for // element-kind dispatch. Rule-7 stops loudly if rhs shape // doesn't match. - if (fu != nil && fu.kind == tykind.TY_ARRAY) { + if (fu != nil && fu.kind == syntax.tykind.TY_ARRAY) { if (vr == nil) { let m: str = "emitstructlitbytes: array field rhs nil (#129 A.3)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (vr.kind != nkind.N_ARRLIT) { + if (vr.kind != syntax.nkind.N_ARRLIT) { let m: str = "emitstructlitbytes: array field rhs not N_ARRLIT (#129 A.3)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -1850,18 +1850,18 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, f = f.tnext; continue; }; - if (typeisfloat(f.type_)) { + if (syntax.typeisfloat(f.type_)) { let isf32: bool = (fsz == 4); let neg: bool = false; - let fr: *node = vr; - if (fr != nil) { if (fr.kind == nkind.N_UN) { - if (fr.op == tkind.TK_MINUS) { + let fr: *syntax.node = vr; + if (fr != nil) { if (fr.kind == syntax.nkind.N_UN) { + if (fr.op == syntax.tkind.TK_MINUS) { neg = true; fr = fr.lhs; - for (fr != nil && fr.kind == nkind.N_CAST) { fr = fr.lhs; }; - } else { if (fr.op == tkind.TK_PLUS) { + for (fr != nil && fr.kind == syntax.nkind.N_CAST) { fr = fr.lhs; }; + } else { if (fr.op == syntax.tkind.TK_PLUS) { fr = fr.lhs; - for (fr != nil && fr.kind == nkind.N_CAST) { fr = fr.lhs; }; + for (fr != nil && fr.kind == syntax.nkind.N_CAST) { fr = fr.lhs; }; };}; };}; if (fr == nil) { @@ -1869,7 +1869,7 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (fr.kind != nkind.N_FLOATLIT) { + if (fr.kind != syntax.nkind.N_FLOATLIT) { let m: str = "emitstructlitbytes: float field rhs not FLOATLIT (#129 A.2)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -1924,11 +1924,11 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, // then delegates to emitstructlitbytes. Shared between emitletdataw // struct arm and emitdefconstants struct arm (#129 A.2). fn emitstructdata(c: *cgen, directive: str, name: str, module: str, - structt: *tinfo, rhs: *node) bool = { - let su: *tinfo = structt; + structt: *syntax.tinfo, rhs: *syntax.node) bool = { + let su: *syntax.tinfo = structt; su = tichase(su); if (su == nil) { return false; }; - if (su.kind != tykind.TY_STRUCT) { return false; }; + if (su.kind != syntax.tykind.TY_STRUCT) { return false; }; emitline(directive); emitline(" "); emitfnname(c, name, module); @@ -1956,15 +1956,15 @@ fn emitstructdata(c: *cgen, directive: str, name: str, module: str, // Two-pass validate-then-emit (`emit_phase=0` validate-only, `=1` // actually emit) keeps emit-on-failure from emitting partial bytes // into an open DATA literal. -fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, +fn emitarraylitbytes(c: *cgen, arrt: *syntax.tinfo, rhs: *syntax.node, emit_phase: i32) bool = { - let au: *tinfo = arrt; + let au: *syntax.tinfo = arrt; au = tichase(au); if (au == nil) { return false; }; - if (au.kind != tykind.TY_ARRAY) { return false; }; + if (au.kind != syntax.tykind.TY_ARRAY) { return false; }; let esz: i32 = au.sub.size: i32; let alen: i32 = au.alen: i32; - let eu: *tinfo = au.sub; + let eu: *syntax.tinfo = au.sub; eu = tichase(eu); // #19 option A: a non-nullable tagged-union element rides the shared @@ -1974,13 +1974,13 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // payload element loud-rejects (task #30 sub-item, rule 7). A nullable // `(*T|void)` element is a 1-word fold, not a tag box — left to the // existing int path (task #15). - if (eu != nil && eu.kind == tykind.TY_TAGGED && !typeisnullable(eu)) { + if (eu != nil && eu.kind == syntax.tykind.TY_TAGGED && !syntax.typeisnullable(eu)) { let idx: i32 = 0; - let last_ev: *node = nil; - let e: *node = rhs.list; + let last_ev: *syntax.node = nil; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; if (!emittaggedbytes(c, au.sub, e, esz, 0)) { let m: str = "emitarraylitbytes: tagged-union array element static-init needs a zero/int payload; wide (str/slice) or struct payload is deferred (task #30, rule 7)\n"; @@ -1996,8 +1996,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, let repeat: bool = false; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; emittaggedbytes(c, au.sub, e, esz, 1); idx += 1; @@ -2015,19 +2015,19 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, return true; }; - if (eu != nil && eu.kind == tykind.TY_STRUCT) { + if (eu != nil && eu.kind == syntax.tykind.TY_STRUCT) { // Validate: every element must be N_STRUCTLIT (after N_CAST). let idx: i32 = 0; - let last_ev: *node = nil; - let e: *node = rhs.list; + let last_ev: *syntax.node = nil; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_STRUCTLIT) { return false; }; + if (ev.kind != syntax.nkind.N_STRUCTLIT) { return false; }; last_ev = ev; idx += 1; e = e.next; @@ -2037,11 +2037,11 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, let repeat: bool = false; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; emitstructlitbytes(c, au.sub, ev, 0u64); idx += 1; e = e.next; @@ -2066,21 +2066,21 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // element stride (rule 13). The `...` repeat marker with nested- // array elements is rejected loud (rule 7): no consumer needs it // (powers_of_ten is fully enumerated). - if (eu != nil && eu.kind == tykind.TY_ARRAY) { + if (eu != nil && eu.kind == syntax.tykind.TY_ARRAY) { let idx: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { let m: str = "emitarraylitbytes: '...' repeat with nested-array elements unsupported (#129 A.3, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_ARRLIT) { return false; }; + if (ev.kind != syntax.nkind.N_ARRLIT) { return false; }; if (!emitarraylitbytes(c, au.sub, ev, 0)) { return false; }; idx += 1; e = e.next; @@ -2089,8 +2089,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, idx = 0; e = rhs.list; for (e != nil && idx < alen) { - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; emitarraylitbytes(c, au.sub, ev, 1); idx += 1; e = e.next; @@ -2103,28 +2103,28 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, return true; }; - if (typeisfloat(au.sub)) { - let isf32: bool = typeisf32(au.sub); + if (syntax.typeisfloat(au.sub)) { + let isf32: bool = syntax.typeisf32(au.sub); // Validate. let idx: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; - if (ev != nil) { if (ev.kind == nkind.N_UN) { - if (ev.op == tkind.TK_MINUS) { + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; + if (ev != nil) { if (ev.kind == syntax.nkind.N_UN) { + if (ev.op == syntax.tkind.TK_MINUS) { ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; - } else { if (ev.op == tkind.TK_PLUS) { + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; + } else { if (ev.op == syntax.tkind.TK_PLUS) { ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; };}; };}; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_FLOATLIT) { return false; }; + if (ev.kind != syntax.nkind.N_FLOATLIT) { return false; }; idx += 1; e = e.next; }; @@ -2135,20 +2135,20 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, let repeat: bool = false; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let neg: bool = false; - if (ev != nil) { if (ev.kind == nkind.N_UN) { - if (ev.op == tkind.TK_MINUS) { + if (ev != nil) { if (ev.kind == syntax.nkind.N_UN) { + if (ev.op == syntax.tkind.TK_MINUS) { neg = true; ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; - } else { if (ev.op == tkind.TK_PLUS) { + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; + } else { if (ev.op == syntax.tkind.TK_PLUS) { ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; };}; };}; let bits: u64 = ev.uval; @@ -2200,16 +2200,16 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // emitletdataw in-place arm so bootstrap consumers (u8/i8/u16 // arrays) don't shift. let idx: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; let last: u64 = 0u64; let repeat: bool = false; // Validate first. for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; if (!foldintliteral(ev, &last)) { return false; }; idx += 1; @@ -2233,8 +2233,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, if (inrepeat) { v = last; } else { if (e != nil) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { inrepeat = true; v = last; } else { @@ -2242,8 +2242,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, v = last; }; } else { - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (!foldintliteral(ev, &v)) { v = 0u64; }; last = v; e = e.next; @@ -2274,15 +2274,15 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // holder constraint, not a mutability grant (def immutability stays // checker-enforced). Returns false when the element type isn't str. fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, - arrt: *tinfo, rhs: *node) bool = { - let au: *tinfo = arrt; + arrt: *syntax.tinfo, rhs: *syntax.node) bool = { + let au: *syntax.tinfo = arrt; au = tichase(au); if (au == nil) { return false; }; - if (au.kind != tykind.TY_ARRAY) { return false; }; - let eu: *tinfo = au.sub; + if (au.kind != syntax.tykind.TY_ARRAY) { return false; }; + let eu: *syntax.tinfo = au.sub; eu = tichase(eu); if (eu == nil) { return false; }; - if (eu.kind != tykind.TY_STR) { return false; }; + if (eu.kind != syntax.tykind.TY_STR) { return false; }; // #8/GAP-B: a str-element array's backing ALWAYS lives in DATAW // (writable section), regardless of the caller's let/def directive — // each element carries an A_DATAR ptr-reloc to its _S_ rodata row, and @@ -2297,18 +2297,18 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, let esz: i32 = au.sub.size: i32; let alen: i32 = au.alen: i32; - let last_ev: *node = nil; + let last_ev: *syntax.node = nil; let repeat: bool = false; let cnt: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil && cnt < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_STRLIT) { return false; }; + if (ev.kind != syntax.nkind.N_STRLIT) { return false; }; last_ev = ev; cnt += 1; e = e.next; @@ -2320,11 +2320,11 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, let idx: i32 = 0; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let i: i32 = 0; for (i < 8) { emitdatawbyte(0u8); i += 1; }; let v: u64 = ev.str.len: u64; @@ -2359,11 +2359,11 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, idx = 0; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev.str.len > 0) { let lab: str = internstrlit(c, ev.str); emitline("DATAR "); @@ -2402,11 +2402,11 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, // refactor would have skipped emit entirely without this branch, // causing `undefined reference to strconv.f64tos_buf` at link. fn emitarraydata(c: *cgen, directive: str, name: str, module: str, - arrt: *tinfo, rhs: *node) bool = { - let au: *tinfo = arrt; + arrt: *syntax.tinfo, rhs: *syntax.node) bool = { + let au: *syntax.tinfo = arrt; au = tichase(au); if (au == nil) { return false; }; - if (au.kind != tykind.TY_ARRAY) { return false; }; + if (au.kind != syntax.tykind.TY_ARRAY) { return false; }; if (rhs == nil) { let total: u64 = arrt.size; emitline(directive); @@ -2445,25 +2445,25 @@ fn emitarraydata(c: *cgen, directive: str, name: str, module: str, // (w6a asm.c:362); read-only `def`, `...` repeat (no target length), // and slice-of-{str,slice,tagged} elements (per-element relocs / #17) // all loud-stop (rule 7, #10 follow-ups). -fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, - sltnode: *node, rhs: *node) void = { - let su: *tinfo = slt; +fn emitslicedata(c: *cgen, name: str, module: str, slt: *syntax.tinfo, + sltnode: *syntax.node, rhs: *syntax.node) void = { + let su: *syntax.tinfo = slt; su = tichase(su); // Defensive, mirrors cstage emit_slice_data's // `if (u == NULL || u->kind != TY_SLICE) return 0` (rule-10): the // letvarisslice gate already guarantees a slice, so this is // unreachable — it guards the su.sub deref below if the contract // is ever violated rather than nil-derefing. - if (su == nil || su.kind != tykind.TY_SLICE) { return; }; - let etype: *tinfo = su.sub; - let eu: *tinfo = etype; + if (su == nil || su.kind != syntax.tykind.TY_SLICE) { return; }; + let etype: *syntax.tinfo = su.sub; + let eu: *syntax.tinfo = etype; eu = tichase(eu); // Count elements; reject `...` (a slice literal has no target N). let k: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { let m: str = "emitslicedata: '...' repeat has no target length in a slice literal (#10, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -2477,23 +2477,23 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, // drives the per-element slot classification the node-based // emittuplerow helpers expect; cstage drives the same off the tuple // tinfo's params. Bounded to inline N_TTUPLE element types. - let tupnode: *node = nil; + let tupnode: *syntax.node = nil; if (sltnode != nil) { tupnode = sltnode.lhs; }; let istuprow: bool = false; - if (eu != nil && eu.kind == tykind.TY_TUPLE && tupnode != nil) { - if (tupnode.kind == nkind.N_TTUPLE) { istuprow = true; }; + if (eu != nil && eu.kind == syntax.tykind.TY_TUPLE && tupnode != nil) { + if (tupnode.kind == syntax.nkind.N_TTUPLE) { istuprow = true; }; }; if (istuprow) { let stride: i32 = etype.size: i32; // Validate every row before any bytes (two-pass, partial-row // safe). - let e2: *node = rhs.list; + let e2: *syntax.node = rhs.list; for (e2 != nil) { - let row: *node = e2; - for (row != nil && row.kind == nkind.N_CAST) { row = row.lhs; }; + let row: *syntax.node = e2; + for (row != nil && row.kind == syntax.nkind.N_CAST) { row = row.lhs; }; let bad: bool = false; if (row == nil) { bad = true; } - else if (row.kind != nkind.N_TUPLE) { bad = true; } + else if (row.kind != syntax.nkind.N_TUPLE) { bad = true; } else if (!tuplerowfoldable(c, tupnode, row)) { bad = true; }; if (bad) { let m: str = "emitslicedata: tuple-row element not a foldable constant ((str,*fn) rows only; #117, rule 7)\n"; @@ -2508,8 +2508,8 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, emitline(".d(SB),\""); e2 = rhs.list; for (e2 != nil) { - let row: *node = e2; - for (row != nil && row.kind == nkind.N_CAST) { row = row.lhs; }; + let row: *syntax.node = e2; + for (row != nil && row.kind == syntax.nkind.N_CAST) { row = row.lhs; }; emittuplerowbytes(c, tupnode, row); e2 = e2.next; }; @@ -2517,16 +2517,16 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, let rowoff: i32 = 0; e2 = rhs.list; for (e2 != nil) { - let row: *node = e2; - for (row != nil && row.kind == nkind.N_CAST) { row = row.lhs; }; + let row: *syntax.node = e2; + for (row != nil && row.kind == syntax.nkind.N_CAST) { row = row.lhs; }; emittuplerowrelocs(c, name, module, true, rowoff, tupnode, row); rowoff += stride; e2 = e2.next; }; } else { if (eu != nil) { - if (eu.kind == tykind.TY_STR || eu.kind == tykind.TY_SLICE - || eu.kind == tykind.TY_TAGGED) { + if (eu.kind == syntax.tykind.TY_STR || eu.kind == syntax.tykind.TY_SLICE + || eu.kind == syntax.tykind.TY_TAGGED) { let m: str = "emitslicedata: slice-of-{str,slice,tagged} literal static-init unsupported (#10 follow-up, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -2534,7 +2534,7 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, }; let esz: i32 = etype.size: i32; // Synthesize [k]T to ride the emitarraylitbytes choke-point. - let arrt: *tinfo = newtype(tykind.TY_ARRAY); + let arrt: *syntax.tinfo = syntax.newtype(syntax.tykind.TY_ARRAY); arrt.sub = etype; arrt.alen = k: u64; arrt.size = (k * esz): u64; @@ -2597,7 +2597,7 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, // share this raw core so a nested tagged member rides the SAME // (tag,payload) SSoT as a scalar tagged global. Mirror of cstage // emit_tagged_bytes. -fn emittaggedbytes(c: *cgen, tti: *tinfo, rhs: *node, sz: i32, emit_phase: i32) bool = { +fn emittaggedbytes(c: *cgen, tti: *syntax.tinfo, rhs: *syntax.node, sz: i32, emit_phase: i32) bool = { if (tti == nil) { return false; }; if (rhs == nil) { if (emit_phase == 1) { @@ -2606,10 +2606,10 @@ fn emittaggedbytes(c: *cgen, tti: *tinfo, rhs: *node, sz: i32, emit_phase: i32) }; return true; }; - let r: *node = rhs; - for (r != nil && r.kind == nkind.N_CAST) { r = r.lhs; }; + let r: *syntax.node = rhs; + for (r != nil && r.kind == syntax.nkind.N_CAST) { r = r.lhs; }; if (r == nil) { return false; }; - let tag: i32 = flatvariantidxt(tti, r.type_: *tinfo, false); + let tag: i32 = flatvariantidxt(tti, r.type_: *syntax.tinfo, false); if (tag < 0) { return false; }; if (nodeisstr(c, r) || nodeisslice(c, r)) { return false; }; let v: u64 = 0u64; @@ -2637,18 +2637,18 @@ fn emittaggedbytes(c: *cgen, tti: *tinfo, rhs: *node, sz: i32, emit_phase: i32) // other variant payload returns false and the caller loud-stops (rule 7) — // never the pre-#87 silent no-DATA + garbage read. Mirror of cstage // emit_tagged_data. -fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i32) bool = { +fn emittaggeddata(c: *cgen, name: str, module: str, tt: *syntax.node, rhs: *syntax.node, sz: i32) bool = { if (tt == nil) { return false; }; if (rhs == nil) { emitline("DATAW "); emitfnname(c, name, module); emitline("(SB),\""); - emittaggedbytes(c, tt.type_: *tinfo, rhs, sz, 1); + emittaggedbytes(c, tt.type_: *syntax.tinfo, rhs, sz, 1); emitline("\"\n"); return true; }; - let r: *node = rhs; - for (r != nil && r.kind == nkind.N_CAST) { r = r.lhs; }; + let r: *syntax.node = rhs; + for (r != nil && r.kind == syntax.nkind.N_CAST) { r = r.lhs; }; if (r == nil) { return false; }; // E8/#35: select the variant via flatvariantidx — the EXACT twin of // cstage emit_tagged_data's cg_tag_for_variant (cmd/w6c/cgen.c:15472). @@ -2671,7 +2671,7 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i let i: i32 = 0; let acc: u64 = 0u64; if (wide) { - if (r.kind != nkind.N_STRLIT) { return false; }; + if (r.kind != syntax.nkind.N_STRLIT) { return false; }; let lv: u64 = r.str.len: u64; emitline("DATAW "); emitfnname(c, name, module); @@ -2708,11 +2708,11 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i // int/zero payload via the shared raw core; validate (phase 0) BEFORE // opening the directive so a non-foldable rhs returns false without // leaving a half-written DATAW. - if (!emittaggedbytes(c, tt.type_: *tinfo, rhs, sz, 0)) { return false; }; + if (!emittaggedbytes(c, tt.type_: *syntax.tinfo, rhs, sz, 0)) { return false; }; emitline("DATAW "); emitfnname(c, name, module); emitline("(SB),\""); - emittaggedbytes(c, tt.type_: *tinfo, rhs, sz, 1); + emittaggedbytes(c, tt.type_: *syntax.tinfo, rhs, sz, 1); emitline("\"\n"); return true; }; @@ -2723,11 +2723,11 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i // address-of-fn codegen arm (fnretlookup at the N_UN TK_AMP ident, // cgenexpr.ww). The reloc target symbol is emitted via emitfnname at the // call site (cstage node_fnptr_sym returns the mangled string directly). -fn nodefnptr(c: *cgen, ev: *node) bool = { +fn nodefnptr(c: *cgen, ev: *syntax.node) bool = { if (ev == nil) { return false; }; - if (ev.kind != nkind.N_UN) { return false; }; - if (ev.op != tkind.TK_AMP) { return false; }; - let opnd: *node = ev.lhs; + if (ev.kind != syntax.nkind.N_UN) { return false; }; + if (ev.op != syntax.tkind.TK_AMP) { return false; }; + let opnd: *syntax.node = ev.lhs; if (opnd == nil) { return false; }; // #124: a cross-module `&mod.fn` — opnd is an N_DOT whose base is an // SK_USE module qualifier (not a local / let / def), and whose leaf @@ -2735,9 +2735,9 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { // curmod) at the emit sites so the reloc targets the same TEXT symbol // the runtime `&mod.fn` emits (cgenexpr.ww N_DOT addr-of arm). The // N_DOT arm of the #117/#119 reloc helper. - if (opnd.kind == nkind.N_DOT) { + if (opnd.kind == syntax.nkind.N_DOT) { if (opnd.lhs == nil) { return false; }; - if (opnd.lhs.kind != nkind.N_IDENT) { return false; }; + if (opnd.lhs.kind != syntax.nkind.N_IDENT) { return false; }; let basenm: str = opnd.lhs.str; if (localfindnode(c, basenm) != nil) { return false; }; if (isletvar(c, basenm)) { return false; }; @@ -2745,7 +2745,7 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { if (fnretlookupmod(c, opnd.str, basenm) == nil) { return false; }; return true; }; - if (opnd.kind != nkind.N_IDENT) { return false; }; + if (opnd.kind != syntax.nkind.N_IDENT) { return false; }; // #14 (F7-c7): type-keyed, mirroring cstage node_fnptr_sym // (type_chase_named(opnd->type)->kind == TY_FN, cmd/w6c/cgen.c:15542- // 15543). The prior name-keyed `fnretlookup(opnd.str)` matched a fn @@ -2757,9 +2757,9 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { // #34 fn-rvalue stamp) from a value ident, closing the leaf-name // collision by construction. (F12 name-keyed overlap noted in the F7 // spec — same predicate-to-stamp shape; fixed once here.) - let ou: *tinfo = tichase(opnd.type_: *tinfo); + let ou: *syntax.tinfo = tichase(opnd.type_: *syntax.tinfo); if (ou == nil) { return false; }; - return ou.kind == tykind.TY_FN; + return ou.kind == syntax.tykind.TY_FN; }; // tuplerowfoldable — validate every cast-peeled element of `rhs` (an @@ -2772,26 +2772,26 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { // out of the output (emitarraydata precedent). Factored from emittupledata // so the slice-of-tuple backing (#117) shares it. Mirror of cstage // tuple_row_foldable. -fn tuplerowfoldable(c: *cgen, tt: *node, rhs: *node) bool = { - let tp: *node = tt.list; - let e: *node = rhs.list; +fn tuplerowfoldable(c: *cgen, tt: *syntax.node, rhs: *syntax.node) bool = { + let tp: *syntax.node = tt.list; + let e: *syntax.node = rhs.list; for (e != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (tp != nil) { et = tp.lhs; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; { - let eti: *tinfo = nil; - if (et != nil) { eti = et.type_: *tinfo; }; + let eti: *syntax.tinfo = nil; + if (et != nil) { eti = et.type_: *syntax.tinfo; }; eti = tichase(eti); - if (eti != nil && eti.kind == tykind.TY_TAGGED) { + if (eti != nil && eti.kind == syntax.tykind.TY_TAGGED) { return false; }; }; let wide: bool = isstrtype(c, et) || isslicetype(c, et); if (wide) { - if (ev.kind != nkind.N_STRLIT) { return false; }; + if (ev.kind != syntax.nkind.N_STRLIT) { return false; }; } else if (nodefnptr(c, ev)) { // #117: a `&fn` element folds to an 8B reloc slot. } else { @@ -2810,14 +2810,14 @@ fn tuplerowfoldable(c: *cgen, tt: *node, rhs: *node) bool = { // its 24B header slot (8 zero ptr placeholder + LE len + 8 zero cap). // Caller has already proven the row foldable. Mirror of cstage // emit_tuple_row_bytes. -fn emittuplerowbytes(c: *cgen, tt: *node, rhs: *node) void = { - let tp: *node = tt.list; - let e: *node = rhs.list; +fn emittuplerowbytes(c: *cgen, tt: *syntax.node, rhs: *syntax.node) void = { + let tp: *syntax.node = tt.list; + let e: *syntax.node = rhs.list; for (e != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (tp != nil) { et = tp.lhs; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let wide: bool = isstrtype(c, et) || isslicetype(c, et); if (wide) { let i: i32 = 0; @@ -2860,15 +2860,15 @@ fn emittuplerowbytes(c: *cgen, tt: *node, rhs: *node) void = { // backing place k rows contiguously (#117), emittupledata passes 0 (foff // matches the absolute element offset — byte-neutral). Mirror of cstage // emit_tuple_row_relocs. -fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i32, tt: *node, rhs: *node) void = { +fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i32, tt: *syntax.node, rhs: *syntax.node) void = { let foff: i32 = rowoff; - let tp: *node = tt.list; - let e: *node = rhs.list; + let tp: *syntax.node = tt.list; + let e: *syntax.node = rhs.list; for (e != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (tp != nil) { et = tp.lhs; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let wide: bool = isstrtype(c, et) || isslicetype(c, et); if (wide) { if (ev.str.len > 0) { @@ -2897,7 +2897,7 @@ fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i // #124: a cross-module `&mod.fn` operand mangles // the leaf with the MODULE ident; same-module `&fn` // stays on curmod. - if (ev.lhs.kind == nkind.N_DOT) { + if (ev.lhs.kind == syntax.nkind.N_DOT) { emitfnname(c, ev.lhs.str, usehint(c, ev.lhs.lhs.str)); } else { emitfnname(c, ev.lhs.str, c.curmod); @@ -2920,13 +2920,13 @@ fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i // zero-inits. Unsupported element inits return false and the caller // loud-stops (rule 7 — pre-C-t3 the whole definition was SILENTLY skipped // and reads saw garbage). Mirror of cstage emit_tuple_data. -fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = { +fn emittupledata(c: *cgen, name: str, module: str, tt: *syntax.node, rhs: *syntax.node) bool = { if (tt == nil) { return false; }; if (rhs == nil) { // #22: slot-sum via the accessor so the zero-fill matches // the checker size (cstage zero-emits u->size). let zsz: i32 = 0; - let p0: *node = tt.list; + let p0: *syntax.node = tt.list; for (p0 != nil) { zsz += tupeslotn(p0.lhs); p0 = p0.next; @@ -2939,7 +2939,7 @@ fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = emitline("\"\n"); return true; }; - if (rhs.kind != nkind.N_TUPLE) { return false; }; + if (rhs.kind != syntax.nkind.N_TUPLE) { return false; }; if (!tuplerowfoldable(c, tt, rhs)) { return false; }; emitline("DATAW "); emitfnname(c, name, module); @@ -2950,8 +2950,8 @@ fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = return true; }; -fn emitletdataw(c: *cgen, file: *node) void = { - let d: *node = file.list; +fn emitletdataw(c: *cgen, file: *syntax.node) void = { + let d: *syntax.node = file.list; for (d != nil) { // #22 M3 THE ONE REAL GUARD: a `.wwi` dep value-global is // initializer-less; emitting a DATAW for it would DUPLICATE the @@ -2960,7 +2960,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // init-less let must still zero-init). Symmetric with M2's // producer imported==0 filter — same predicate both ways. if (c.sepmode != 0 && d.imported != 0) { d = d.next; continue; }; - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { let nm: str = d.str; if (nm.len > 0) { let sz: i32 = letemitsize(c, d); @@ -2973,8 +2973,8 @@ fn emitletdataw(c: *cgen, file: *node) void = { // undefined reference at link. The str/float/ // struct/slice/tuple gates already alias-walk // (letvaris* / the tlt tnode walk) and stay put. - let dti: *tinfo = nil; - if (d.lhs != nil) { dti = tichase(d.lhs.type_: *tinfo); }; + let dti: *syntax.tinfo = nil; + if (d.lhs != nil) { dti = tichase(d.lhs.type_: *syntax.tinfo); }; // C-t3 (#48): tuple global — slot-laid DATAW // row (+ DATAR ptr patches for str elements) // via emittupledata. Unsupported element @@ -2983,20 +2983,20 @@ fn emitletdataw(c: *cgen, file: *node) void = { // and reads saw garbage. The istup gate also // keeps a tuple out of the sz==8 / str-size // arms below (a 24B tuple == str size). - let tlt: *node = d.lhs; - for (tlt != nil && tlt.kind == nkind.N_TNAME) { + let tlt: *syntax.node = d.lhs; + for (tlt != nil && tlt.kind == syntax.nkind.N_TNAME) { tlt = aliaslookup(c, tlt.str); }; let istup: bool = false; if (tlt != nil) { - if (tlt.kind == nkind.N_TTUPLE) { + if (tlt.kind == syntax.nkind.N_TTUPLE) { istup = true; }; }; if (istup) { - let tr: *node = d.rhs; + let tr: *syntax.node = d.rhs; for (tr != nil) { - if (tr.kind != nkind.N_CAST) { break; }; + if (tr.kind != syntax.nkind.N_CAST) { break; }; tr = tr.lhs; }; if (!emittupledata(c, nm, d.nmod, tlt, tr)) { @@ -3012,7 +3012,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // a tagged box (size can equal str/slice size) out of those. let istagged: bool = false; if (tlt != nil) { - if (tlt.kind == nkind.N_TTAGGED) { + if (tlt.kind == syntax.nkind.N_TTAGGED) { if (!isnullabletype(tlt)) { istagged = true; }; }; }; @@ -3039,10 +3039,10 @@ fn emitletdataw(c: *cgen, file: *node) void = { // declaration fell out of the .data section and // the link surfaced an undefined-symbol error. if (issg) { - let r: *node = d.rhs; + let r: *syntax.node = d.rhs; if (r != nil) { - if (r.kind == nkind.N_STRUCTLIT) { - let st: *tinfo = d.lhs.type_: *tinfo; + if (r.kind == syntax.nkind.N_STRUCTLIT) { + let st: *syntax.tinfo = d.lhs.type_: *syntax.tinfo; emitstructdata(c, "DATAW", nm, d.nmod, st, r); }; @@ -3055,17 +3055,17 @@ fn emitletdataw(c: *cgen, file: *node) void = { // otherwise differ across stages on user code. let isarr8: bool = false; if (dti != nil) { - if (dti.kind == tykind.TY_ARRAY) { isarr8 = true; }; + if (dti.kind == syntax.tykind.TY_ARRAY) { isarr8 = true; }; }; if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup && !istagged) { let v: u64 = 0u64; let ok: bool = true; let fnp: bool = false; - let r: *node = nil; + let r: *syntax.node = nil; if (d.rhs != nil) { r = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // Same helper as emitdefconstants (#24) @@ -3091,7 +3091,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // #124: cross-module `&mod.fn` mangles the // leaf with the MODULE ident; same-module `&fn` // stays on curmod. - if (r.lhs.kind == nkind.N_DOT) { + if (r.lhs.kind == syntax.nkind.N_DOT) { emitfnname(c, r.lhs.str, usehint(c, r.lhs.lhs.str)); } else { emitfnname(c, r.lhs.str, c.curmod); @@ -3120,9 +3120,9 @@ fn emitletdataw(c: *cgen, file: *node) void = { // emitarraydata path owns them — mirroring the existing // isarr8 guard on the sz==8 scalar arm. if (sz == primtypesize("str"): i32 && !issg && !istup && !istagged && !isarr8 && !letvarisslice(c, nm)) { - let r: *node = d.rhs; + let r: *syntax.node = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // str-literal init (non-empty): emit @@ -3132,7 +3132,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // the strlit's runtime VA. let strlitinit: bool = false; if (r != nil) { - if (r.kind == nkind.N_STRLIT) { + if (r.kind == syntax.nkind.N_STRLIT) { if (r.str.len > 0) { strlitinit = true; }; }; }; @@ -3164,8 +3164,8 @@ fn emitletdataw(c: *cgen, file: *node) void = { if (d.rhs != nil) { ok = false; if (r != nil) { - if (r.kind == nkind.N_NIL) { ok = true; }; - if (r.kind == nkind.N_STRLIT) { + if (r.kind == syntax.nkind.N_NIL) { ok = true; }; + if (r.kind == syntax.nkind.N_STRLIT) { if (r.str.len == 0) { ok = true; }; }; }; @@ -3185,9 +3185,9 @@ fn emitletdataw(c: *cgen, file: *node) void = { }; }; if (sz == tyslicesize(): i32 && !issg && !istagged && letvarisslice(c, nm)) { - let r: *node = d.rhs; + let r: *syntax.node = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // #10 part a: slice-literal static init @@ -3195,9 +3195,9 @@ fn emitletdataw(c: *cgen, file: *node) void = { // writable backing + DATAR). Loud-stops on // the deferred element kinds and the read- // only/`...` shapes (rule 7). - if (r != nil && r.kind == nkind.N_ARRLIT) { + if (r != nil && r.kind == syntax.nkind.N_ARRLIT) { emitslicedata(c, nm, d.nmod, - d.lhs.type_: *tinfo, d.lhs, r); + d.lhs.type_: *syntax.tinfo, d.lhs, r); } else { // zero-init: accept no rhs or nil. // Any other rhs is skipped → @@ -3206,7 +3206,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { if (d.rhs != nil) { ok = false; if (r != nil) { - if (r.kind == nkind.N_NIL) { ok = true; }; + if (r.kind == syntax.nkind.N_NIL) { ok = true; }; }; }; if (ok) { @@ -3261,12 +3261,12 @@ fn emitletdataw(c: *cgen, file: *node) void = { // No-rhs arrays (e.g. `let buf: [N]u8;`) go through // the same helper with rhs=nil → zero-fill branch. if (dti != nil) { - if (dti.kind == tykind.TY_ARRAY) { - let rh: *node = d.rhs; + if (dti.kind == syntax.tykind.TY_ARRAY) { + let rh: *syntax.node = d.rhs; let route: bool = false; if (rh == nil) { route = true; }; if (rh != nil) { - if (rh.kind == nkind.N_ARRLIT) { + if (rh.kind == syntax.nkind.N_ARRLIT) { route = true; }; }; @@ -3295,8 +3295,8 @@ fn emitletdataw(c: *cgen, file: *node) void = { // unary +/-/~ over the same. `def NEG: i32 = -100;` arrives as // N_UN(TK_MINUS, N_INTLIT) — the unary peel is exactly what the // gate is for. -fn emitdefconstants(c: *cgen, file: *node) void = { - let d: *node = file.list; +fn emitdefconstants(c: *cgen, file: *syntax.node) void = { + let d: *syntax.node = file.list; for (d != nil) { // #22 M3: a `.wwi` dep def with DATA storage (int-fold / float / // struct / array) must NOT re-emit — the dep's own .o owns the @@ -3304,8 +3304,8 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // they need no gate; the def registry stays populated for imported // decls so the target's LOAD paths still resolve the extern. if (c.sepmode != 0 && d.imported != 0) { d = d.next; continue; }; - if (d.kind == nkind.N_DEF) { - let r: *node = d.rhs; + if (d.kind == syntax.nkind.N_DEF) { + let r: *syntax.node = d.rhs; let v: u64 = 0u64; let ok: bool = false; if (r != nil) { @@ -3318,12 +3318,12 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // through to no-emit + undef-ref at link. Type-size // walk mirrors letvarisfloat (#129 Phase A.1). let dfsz: i32 = 0; - let dt: *node = d.lhs; + let dt: *syntax.node = d.lhs; for (dt != nil) { - if (dt.kind != nkind.N_TNAME) { dfsz = 0; break; }; + if (dt.kind != syntax.nkind.N_TNAME) { dfsz = 0; break; }; let fsz: i32 = letfloatprim(dt.str); if (fsz > 0) { dfsz = fsz; break; }; - let nx: *node = aliaslookup(c, dt.str); + let nx: *syntax.node = aliaslookup(c, dt.str); if (nx == nil) { dfsz = 0; break; }; dt = nx; }; @@ -3336,12 +3336,12 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // struct's tinfo; helper peels TY_NAMED. Parallel // to emitletdataw struct arm; uses DATA (read- // only) directive. - if (r != nil) { if (r.kind == nkind.N_STRUCTLIT) { - let st: *tinfo = d.lhs.type_: *tinfo; - let su: *tinfo = st; + if (r != nil) { if (r.kind == syntax.nkind.N_STRUCTLIT) { + let st: *syntax.tinfo = d.lhs.type_: *syntax.tinfo; + let su: *syntax.tinfo = st; su = tichase(su); if (su != nil) { - if (su.kind == tykind.TY_STRUCT) { + if (su.kind == syntax.tykind.TY_STRUCT) { emitstructdata(c, "DATA", d.str, d.nmod, st, r); }; @@ -3349,12 +3349,12 @@ fn emitdefconstants(c: *cgen, file: *node) void = { };}; // #129 A.3: array-typed def with N_ARRLIT rhs. // Parallel to emitletdataw array arm; uses DATA. - if (r != nil) { if (r.kind == nkind.N_ARRLIT) { - let at: *tinfo = d.lhs.type_: *tinfo; - let au: *tinfo = at; + if (r != nil) { if (r.kind == syntax.nkind.N_ARRLIT) { + let at: *syntax.tinfo = d.lhs.type_: *syntax.tinfo; + let au: *syntax.tinfo = at; au = tichase(au); if (au != nil) { - if (au.kind == tykind.TY_ARRAY) { + if (au.kind == syntax.tykind.TY_ARRAY) { emitarraydata(c, "DATA", d.str, d.nmod, at, r); }; @@ -3363,7 +3363,7 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // emitslicedata needs (DATAR holder must be // DATAW, w6a asm.c:362). Loud-stop, never // silent no-emit. - if (au.kind == tykind.TY_SLICE) { + if (au.kind == syntax.tykind.TY_SLICE) { let m: str = "emitdefconstants: module-level slice-literal init needs a writable `let` (DATAR holder must be DATAW, w6a asm.c:362); read-only `def` unsupported (#10, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -3495,16 +3495,16 @@ fn emitdatasection(c: *cgen) void = { type fnret = struct { fname: str, fmod: str, - rtype: *node, - params: *node, + rtype: *syntax.node, + params: *syntax.node, frnext: *fnret, }; -fn collectfnrets(c: *cgen, file: *node) void = { +fn collectfnrets(c: *cgen, file: *syntax.node) void = { c.fnrets = nil; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_FNDECL) { + if (d.kind == syntax.nkind.N_FNDECL) { let f: *fnret = alloc(fnret{fname=d.str, fmod=d.nmod, rtype=d.lhs, params=d.list, frnext=c.fnrets})!; c.fnrets = f; }; @@ -3543,17 +3543,17 @@ fn collectfnrets(c: *cgen, file: *node) void = { // the fix. Masked until #208 landed (the checker rejected the shape // before cgen ran). test/wcc/782 pins the cstage-correct runtime // (cstage-only) and graduates to STAGE_WW on #211 close. -fn fnretlookup(c: *cgen, name: str) *node = { +fn fnretlookup(c: *cgen, name: str) *syntax.node = { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, c.curmod)) { return f.rtype; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, c.curmod)) { return f.rtype; }; }; f = f.frnext; }; f = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { return f.rtype; }; + if (syntax.streq(f.fname, name)) { return f.rtype; }; f = f.frnext; }; return nil; @@ -3568,7 +3568,7 @@ fn fnretlookup(c: *cgen, name: str) *node = { // `match (utf8.next(d))` inside a `fn next() (rune | done)` resolves // the scrutinee tagged type to `(rune | done)` — flatvariantidx then // can't see arms 2/3 and collapses them onto tag 0 (task #31). -fn fnretlookupmod(c: *cgen, name: str, mod: str) *node = { +fn fnretlookupmod(c: *cgen, name: str, mod: str) *syntax.node = { // M1 #22 (#199b): the qualifier may be the import ALIAS the user // wrote (`utf8`); fn decls register f.fmod under the dotted import // PATH (`encoding.utf8`). Map alias->path so a nested-package callee @@ -3585,8 +3585,8 @@ fn fnretlookupmod(c: *cgen, name: str, mod: str) *node = { if (mk.len > 0) { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, mk)) { return f.rtype; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, mk)) { return f.rtype; }; }; f = f.frnext; }; @@ -3604,17 +3604,17 @@ fn fnretlookupmod(c: *cgen, name: str, mod: str) *node = { // detection fires (or doesn't) against the wrong param-type — `foo(7)` // against a same-leaf `(i32 | void)` param re-layouts 7 into a 2-word // tagged slot vs the same-module `i32` param's single push. -fn fnparamslookup(c: *cgen, name: str) *node = { +fn fnparamslookup(c: *cgen, name: str) *syntax.node = { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, c.curmod)) { return f.params; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, c.curmod)) { return f.params; }; }; f = f.frnext; }; f = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { return f.params; }; + if (syntax.streq(f.fname, name)) { return f.params; }; f = f.frnext; }; return nil; @@ -3631,8 +3631,8 @@ fn fnparamslookup(c: *cgen, name: str) *node = { fn samemodfn(c: *cgen, name: str) bool = { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, c.curmod)) { return true; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, c.curmod)) { return true; }; }; f = f.frnext; }; @@ -3645,7 +3645,7 @@ fn samemodfn(c: *cgen, name: str) bool = { // to the explicit module. Falls back to the first leaf match if no // matching module is registered — mirrors aliaslookup's two-pass shape // (cgen.ww:75, fixed in #27). -fn fnparamslookupmod(c: *cgen, name: str, mod: str) *node = { +fn fnparamslookupmod(c: *cgen, name: str, mod: str) *syntax.node = { // M1 #22 (#199b): map import alias -> dotted path, identical to // fnretlookupmod (the param-side twin). usehint is idempotent on a // path / c.curmod so existing callers are unaffected. @@ -3653,8 +3653,8 @@ fn fnparamslookupmod(c: *cgen, name: str, mod: str) *node = { if (mk.len > 0) { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, mk)) { return f.params; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, mk)) { return f.params; }; }; f = f.frnext; }; @@ -3671,18 +3671,18 @@ fn fnparamslookupmod(c: *cgen, name: str, mod: str) *node = { type defent = struct { dname: str, dmod: str, // originating module (`// MODULE: foo`), or empty - drhs: *node, - dtnode: *node, // #129 A.2: type-spec node (d.lhs); needed for + drhs: *syntax.node, + dtnode: *syntax.node, // #129 A.2: type-spec node (d.lhs); needed for // struct-def structinfo lookup at the cgdot // LOAD-side widening site. dnext: *defent, }; -fn collectdefs(c: *cgen, file: *node) void = { +fn collectdefs(c: *cgen, file: *syntax.node) void = { c.defs = nil; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_DEF) { + if (d.kind == syntax.nkind.N_DEF) { let e: *defent = alloc(defent{dname=d.str, dmod=d.nmod, drhs=d.rhs, dtnode=d.lhs, dnext=c.defs})!; c.defs = e; }; @@ -3697,14 +3697,14 @@ fn collectdefs(c: *cgen, file: *node) void = { fn deflookup(c: *cgen, name: str) bool = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - if (streq(e.dmod, c.curmod)) { return true; }; + if (syntax.streq(e.dname, name)) { + if (syntax.streq(e.dmod, c.curmod)) { return true; }; }; e = e.dnext; }; e = c.defs; for (e != nil) { - if (streq(e.dname, name)) { return true; }; + if (syntax.streq(e.dname, name)) { return true; }; e = e.dnext; }; return false; @@ -3716,17 +3716,17 @@ fn deflookup(c: *cgen, name: str) bool = { // same-leaf `def MSG: str = ...` sitting at the head of c.defs and // inline the wrong strlit. Used by cgdot to inline `.ptr`/`.len` on // `def NAME: str = "..."` — those aren't laid out in memory. -fn deflookuprhs(c: *cgen, name: str) *node = { +fn deflookuprhs(c: *cgen, name: str) *syntax.node = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - if (streq(e.dmod, c.curmod)) { return e.drhs; }; + if (syntax.streq(e.dname, name)) { + if (syntax.streq(e.dmod, c.curmod)) { return e.drhs; }; }; e = e.dnext; }; e = c.defs; for (e != nil) { - if (streq(e.dname, name)) { return e.drhs; }; + if (syntax.streq(e.dname, name)) { return e.drhs; }; e = e.dnext; }; return nil; @@ -3742,12 +3742,12 @@ fn deflookuprhs(c: *cgen, name: str) *node = { // str-def value-load routes here so a cross-module N_DOT collision // resolves to the explicit module. Falls back to deflookuprhs's bare- // leaf two-pass when no module matches. -fn deflookuprhsmod(c: *cgen, name: str, mod: str) *node = { +fn deflookuprhsmod(c: *cgen, name: str, mod: str) *syntax.node = { if (mod.len > 0) { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - if (streq(e.dmod, mod)) { return e.drhs; }; + if (syntax.streq(e.dname, name)) { + if (syntax.streq(e.dmod, mod)) { return e.drhs; }; }; e = e.dnext; }; @@ -3760,25 +3760,25 @@ fn deflookuprhsmod(c: *cgen, name: str, mod: str) *node = { // float address-of gate must equal that emission set, or `&def` LEAQs a // symbol the data pass never wrote. Keep in sync with emitfloatlitdata's // peel. -fn floatlitleaf(rhs: *node) bool = { - let r: *node = rhs; +fn floatlitleaf(rhs: *syntax.node) bool = { + let r: *syntax.node = rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; if (r != nil) { - if (r.kind == nkind.N_UN) { - if (r.op == tkind.TK_MINUS) { + if (r.kind == syntax.nkind.N_UN) { + if (r.op == syntax.tkind.TK_MINUS) { r = r.lhs; - for (r != nil) { if (r.kind != nkind.N_CAST) { break; }; r = r.lhs; }; - } else { if (r.op == tkind.TK_PLUS) { + for (r != nil) { if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; + } else { if (r.op == syntax.tkind.TK_PLUS) { r = r.lhs; - for (r != nil) { if (r.kind != nkind.N_CAST) { break; }; r = r.lhs; }; + for (r != nil) { if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; }; }; }; }; if (r == nil) { return false; }; - return r.kind == nkind.N_FLOATLIT; + return r.kind == syntax.nkind.N_FLOATLIT; }; // #149/#147: a top-level def is addressable for `&def` iff emitdefs emits @@ -3790,7 +3790,7 @@ fn floatlitleaf(rhs: *node) bool = { // loud error, never a LEAQ of a missing symbol. `opnd` is the `&`-operand // N_IDENT; its checker-stamped type_ carries the def's type (same as the // cgident float-def read at cgenexpr.ww). -fn defisaddressable(c: *cgen, opnd: *node) bool = { +fn defisaddressable(c: *cgen, opnd: *syntax.node) bool = { let nm: str = opnd.str; if (defvarstructinfo(c, nm) != nil) { return true; }; // #88: the emission side (emitdefconstants' array arm) peels @@ -3798,12 +3798,12 @@ fn defisaddressable(c: *cgen, opnd: *node) bool = { // array HAS a DATA symbol — keying this gate on the unchased // dtnode kind (N_TARRAY) lied it back to the loud error. Chase // the same stamped tinfo so gate == emission set stays exact. - let dtn: *node = defvartnode(c, nm); + let dtn: *syntax.node = defvartnode(c, nm); if (dtn != nil) { - let du88: *tinfo = tichase(dtn.type_: *tinfo); - if (du88 != nil) { if (du88.kind == tykind.TY_ARRAY) { return true; }; }; + let du88: *syntax.tinfo = tichase(dtn.type_: *syntax.tinfo); + if (du88 != nil) { if (du88.kind == syntax.tykind.TY_ARRAY) { return true; }; }; }; - let drhs: *node = deflookuprhs(c, nm); + let drhs: *syntax.node = deflookuprhs(c, nm); if (drhs == nil) { return false; }; let v: u64 = 0u64; if (foldintliteral(drhs, &v)) { return true; }; @@ -3833,14 +3833,14 @@ type modent = struct { mnext: *modent, }; -fn collectmods(c: *cgen, file: *node) void = { +fn collectmods(c: *cgen, file: *syntax.node) void = { c.mods = nil; c.uses = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { // M1 #22: record alias→path for the qualified-ref hint. - if (d.kind == nkind.N_USE) { + if (d.kind == syntax.nkind.N_USE) { if (d.usepath.len > 0) { let um: *modent = alloc(modent{mname=d.str, nmod=d.usepath, omod=d.nmod, mnext=c.uses})!; c.uses = um; @@ -3849,23 +3849,23 @@ fn collectmods(c: *cgen, file: *node) void = { // Mirror collectfnrets' shape exactly (plain prepend in one // branch). Earlier nested-if/early-return variants tickled a // wwstage cgen bug that dropped most prepends. - if (d.kind == nkind.N_FNDECL) { + if (d.kind == syntax.nkind.N_FNDECL) { // Fns mangle regardless of export status — covers // lib/os.read vs lib/io.read collision. if (d.nmod.len > 0) { let isffi: bool = false; - let a: *node = d.attr; + let a: *syntax.node = d.attr; for (a != nil) { - if (a.kind == nkind.N_ATTR) { + if (a.kind == syntax.nkind.N_ATTR) { let an: str = a.str; - if (streq(an, "symbol")) { isffi = true; }; + if (syntax.streq(an, "symbol")) { isffi = true; }; }; a = a.next; }; if (!isffi) { // M1 #32: the ROOT main (imported==0) stays bare; // an IMPORTED `fn main` mangles on its path. - if (!streq(d.str, "main") || d.imported != 0) { + if (!syntax.streq(d.str, "main") || d.imported != 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; }; @@ -3876,19 +3876,19 @@ fn collectmods(c: *cgen, file: *node) void = { // like fns — `export def MAX` becomes `.MAX`, not a bare // `MAX` two packages could clash on under sep-compile. No export // guard: every decl with a module mangles identically. - if (d.kind == nkind.N_DEF) { + if (d.kind == syntax.nkind.N_DEF) { if (d.nmod.len > 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; }; }; - if (d.kind == nkind.N_TYPEDECL) { + if (d.kind == syntax.nkind.N_TYPEDECL) { if (d.nmod.len > 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; }; }; - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { if (d.nmod.len > 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; @@ -3901,7 +3901,7 @@ fn collectmods(c: *cgen, file: *node) void = { fn modlookup(c: *cgen, name: str) str = { let m: *modent = c.mods; for (m != nil) { - if (streq(m.mname, name)) { return m.nmod; }; + if (syntax.streq(m.mname, name)) { return m.nmod; }; m = m.mnext; }; let empty: str; @@ -3928,8 +3928,8 @@ fn usehint(c: *cgen, alias: str) str = { any.ptr = nil; any.len = 0; for (m != nil) { - if (streq(m.mname, alias)) { - if (streq(m.omod, c.curmod)) { return m.nmod; }; + if (syntax.streq(m.mname, alias)) { + if (syntax.streq(m.omod, c.curmod)) { return m.nmod; }; if (any.ptr == nil && any.len == 0) { any = m.nmod; }; }; m = m.mnext; @@ -3950,9 +3950,9 @@ fn modlookupforfn(c: *cgen, name: str, hint: str) str = { first.ptr = nil; first.len = 0; for (m != nil) { - if (streq(m.mname, name)) { + if (syntax.streq(m.mname, name)) { if (hint.len > 0 && m.nmod.len > 0 - && streq(m.nmod, hint)) { + && syntax.streq(m.nmod, hint)) { return m.nmod; }; if (first.len == 0 && first.ptr == nil) { @@ -4006,20 +4006,20 @@ fn emitfnname(c: *cgen, ident: str, hint: str) void = { // ---- FFI map --------------------------------------------------------- -fn fficollect(c: *cgen, file: *node) void = { +fn fficollect(c: *cgen, file: *syntax.node) void = { c.ffis = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_FNDECL) { - let a: *node = d.attr; + if (d.kind == syntax.nkind.N_FNDECL) { + let a: *syntax.node = d.attr; for (a != nil) { - if (a.kind == nkind.N_ATTR) { + if (a.kind == syntax.nkind.N_ATTR) { let aname: str = a.str; - if (streq(aname, "symbol")) { - let symnode: *node = a.list; + if (syntax.streq(aname, "symbol")) { + let symnode: *syntax.node = a.list; if (symnode != nil) { - if (symnode.kind == nkind.N_STRLIT) { + if (symnode.kind == syntax.nkind.N_STRLIT) { let f: *ffi = alloc(ffi{ident=d.str, symbol=symnode.str, fnext=c.ffis})!; c.ffis = f; }; @@ -4037,7 +4037,7 @@ fn ffiresolve(c: *cgen, ident: str) str = { let f: *ffi = c.ffis; for (f != nil) { let id: str = f.ident; - if (streq(id, ident)) { return f.symbol; }; + if (syntax.streq(id, ident)) { return f.symbol; }; f = f.fnext; }; return ident; diff --git a/selfhost/cmd/wcc/cgendecl.ww b/selfhost/cmd/wcc/cgendecl.ww index bfbac4c9..387ef01f 100644 --- a/selfhost/cmd/wcc/cgendecl.ww +++ b/selfhost/cmd/wcc/cgendecl.ww @@ -19,8 +19,8 @@ import strconv; // ---- function-level cgen --------------------------------------------- -fn cgfnparams(c: *cgen, params: *node) void = { - let p: *node = params; +fn cgfnparams(c: *cgen, params: *syntax.node) void = { + let p: *syntax.node = params; // sret (#23): RDI is consumed by the hidden dest pointer // (already spilled to @sretarg by cgfn); the first user param // lands in SI. @@ -36,7 +36,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { // post-walk consistency check against stkcursor. let memwords: i32 = 0; for (p != nil) { - if (p.kind == nkind.N_PARAM) { + if (p.kind == syntax.nkind.N_PARAM) { let nm: str = p.str; // Hare-style variadic `T...`: callee receives a []T // slice (3 register words / 24B). p.lhs is already @@ -44,8 +44,8 @@ fn cgfnparams(c: *cgen, params: *node) void = { // (mirrors cstage check.c:455 tp->type promotion), so // we consume it directly — re-wrapping via slicewrap // would yield [][]T. - if (p.op == tkind.TK_ELLIPSIS) { - let tn: *node = p.lhs; + if (p.op == syntax.tkind.TK_ELLIPSIS) { + let tn: *syntax.node = p.lhs; if (idx + 3 <= 6) { let off: i32 = localadd(c, nm, tyslicesize(): i32, tn); emitline("\tMOVQ\t"); @@ -108,14 +108,14 @@ fn cgfnparams(c: *cgen, params: *node) void = { // path → 1 slot, SI dropped, t.1 garbage. Slot size + element // walk source the RESOLVED node; localadd keeps the declared // p.lhs so field reads chase identically to cstage (byte-id). - let tt99: *node = nil; + let tt99: *syntax.node = nil; if (p.lhs != nil) { tt99 = p.lhs; - for (tt99 != nil && tt99.kind == nkind.N_TNAME) { + for (tt99 != nil && tt99.kind == syntax.nkind.N_TNAME) { tt99 = aliaslookup(c, tt99.str); }; }; - if (p.lhs != nil) { if (tt99 != nil && tt99.kind == nkind.N_TTUPLE) { + if (p.lhs != nil) { if (tt99 != nil && tt99.kind == syntax.nkind.N_TTUPLE) { // #163: tuple PARAM receive (param twin of #164's // return). Walk the tuple's elements over the SysV // arg cursor — a float reads its XMM (X0..X7), @@ -127,9 +127,9 @@ fn cgfnparams(c: *cgen, params: *node) void = { // partial-spill stitch is out of scope (twin of #164). let off: i32 = localadd(c, nm, slotsize(c, p.lhs), p.lhs); let eoff: i32 = 0; - let te: *node = tt99.list; + let te: *syntax.node = tt99.list; for (te != nil) { - let et: *node = te.lhs; + let et: *syntax.node = te.lhs; if (isfloattype(c, et)) { if (fidx >= 8) { let msg: str = "tuple param float element overflows SSE arg regs (X0..X7); stitch out of scope, see #163\n"; @@ -251,7 +251,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { // greedy stitch arm below while cstage received // one scalar word (cs≠ww, silent). // ref/qbe/amd64/sysv.c:80-85 / :411-426. - if (taggedmemargsize(p.lhs.type_: *tinfo) > 0) { + if (taggedmemargsize(p.lhs.type_: *syntax.tinfo) > 0) { localaddstack(c, nm, p.lhs, 16 + stkcursor*8); stkcursor += nw; memwords += nw; @@ -450,7 +450,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { localaddstack(c, nm, p.lhs, 16 + stkcursor*8); stkcursor += nw; };}; - } else { let aggsz2: i32 = aggargsizetn(p.lhs.type_: *tinfo); + } else { let aggsz2: i32 = aggargsizetn(p.lhs.type_: *syntax.tinfo); if (aggsz2 > 0) { // #271: array / >16B-struct by-value param — // received as ceil(sz/8) GP eightbytes, the @@ -529,7 +529,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { }; }; -fn cgfn(c: *cgen, fn_: *node) void = { +fn cgfn(c: *cgen, fn_: *syntax.node) void = { cgeninit(c); c.fnname = fn_.str; c.curmod = fn_.nmod; @@ -568,8 +568,8 @@ fn cgfn(c: *cgen, fn_: *node) void = { // resolve identifiers via localfind, so the body's locals must // still be in c.locals when we get there. if (fn_.body != nil) { - if (fn_.body.kind == nkind.N_BLOCK) { - let s: *node = fn_.body.list; + if (fn_.body.kind == syntax.nkind.N_BLOCK) { + let s: *syntax.node = fn_.body.list; for (s != nil) { cgstmt(c, s); s = s.next; @@ -605,7 +605,7 @@ fn cgfn(c: *cgen, fn_: *node) void = { // fn_.nmod hint would fall through modlookupforfn's first-leaf match // onto an IMPORTED package's now-registered `pkg.main`. emitline("TEXT "); - if (streq(fn_.str, "main") && fn_.imported == 0) { + if (syntax.streq(fn_.str, "main") && fn_.imported == 0) { emitbytes(fn_.str.ptr, fn_.str.len: u64); } else { emitfnname(c, fn_.str, fn_.nmod); @@ -625,7 +625,7 @@ fn cgfn(c: *cgen, fn_: *node) void = { // ---- file-level entry ------------------------------------------------ -export fn cgfile(c: *cgen, file: *node) void = { +export fn cgfile(c: *cgen, file: *syntax.node) void = { if (file == nil) { return; }; c.strlits = nil; c.strlitseq = 0; @@ -641,9 +641,9 @@ export fn cgfile(c: *cgen, file: *node) void = { collectmods(c, file); defaultinferredlets(c, file); collectlets(c, file); - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_FNDECL) { + if (d.kind == syntax.nkind.N_FNDECL) { // #22 M3: emit code ONLY for this package's own decls. A // `.wwi` dep fn is a body-less prototype that already skips // (the body != nil gate); the explicit imported gate also diff --git a/selfhost/cmd/wcc/cgenexpr.ww b/selfhost/cmd/wcc/cgenexpr.ww index 3afc88c3..051e9b8d 100644 --- a/selfhost/cmd/wcc/cgenexpr.ww +++ b/selfhost/cmd/wcc/cgenexpr.ww @@ -31,12 +31,12 @@ fn cgfloatbits(c: *cgen, bits: u64) void = { emitline("\tADDQ\t$8, SP\n"); }; -fn cgexpr(c: *cgen, n: *node) void = { +fn cgexpr(c: *cgen, n: *syntax.node) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; switch (k) { - case nkind.N_INTLIT: + case syntax.nkind.N_INTLIT: // A no-decimal `0f64`/`8f64` is an N_INTLIT carrying float // TYPE; it must reach X0 like a true float literal, not the // integer-immediate path (which strands it in AX and an SSE @@ -64,7 +64,7 @@ fn cgexpr(c: *cgen, n: *node) void = { emitint(n.uval: i64); emitline(", AX\n"); return; - case nkind.N_FLOATLIT: + case syntax.nkind.N_FLOATLIT: // The bits come from n.uval — the parser populates it from // the lexer's bitcast of t.fval. cgfloatbits(c, n.uval); @@ -73,41 +73,41 @@ fn cgexpr(c: *cgen, n: *node) void = { emitline("\tCVTSD2SS\tX0, X0\n"); }; return; - case nkind.N_RUNELIT: + case syntax.nkind.N_RUNELIT: emitline("\tMOVQ\t$"); emitint(n.uval: i64); emitline(", AX\n"); return; - case nkind.N_STRLIT: cgstrlit(c, n); return; - case nkind.N_TRUE: + case syntax.nkind.N_STRLIT: cgstrlit(c, n); return; + case syntax.nkind.N_TRUE: emitline("\tMOVQ\t$1, AX\n"); return; - case nkind.N_FALSE: + case syntax.nkind.N_FALSE: emitline("\tMOVQ\t$0, AX\n"); return; - case nkind.N_NIL: + case syntax.nkind.N_NIL: emitline("\tMOVQ\t$0, AX\n"); return; - case nkind.N_VOIDLIT: + case syntax.nkind.N_VOIDLIT: // void value: zero-size, but the consumer's ABI expects a // deterministic AX. Emit 0 like nil/false do. emitline("\tMOVQ\t$0, AX\n"); return; - case nkind.N_IDENT: cgident(c, n); return; - case nkind.N_INDEX: cgindex(c, n); return; - case nkind.N_SLICE: cgslice(c, n); return; - case nkind.N_MATCH: cgmatch(c, n); return; - case nkind.N_CAST: cgcast(c, n); return; - case nkind.N_DOT: cgdot(c, n); return; - case nkind.N_UN: cgun(c, n); return; - case nkind.N_BIN: cgbin(c, n); return; - case nkind.N_CALL: cgcall(c, n); return; - case nkind.N_ASSIGN: cgassign(c, n); return; - case nkind.N_TRYPROP: cgtryprop(c, n); return; - case nkind.N_TRYUNW: cgtryunw(c, n); return; - case nkind.N_TYPETEST: cgtypetest(c, n); return; - case nkind.N_TYPEASSERT: cgtypeassert(c, n); return; - case nkind.N_TUPLE: + case syntax.nkind.N_IDENT: cgident(c, n); return; + case syntax.nkind.N_INDEX: cgindex(c, n); return; + case syntax.nkind.N_SLICE: cgslice(c, n); return; + case syntax.nkind.N_MATCH: cgmatch(c, n); return; + case syntax.nkind.N_CAST: cgcast(c, n); return; + case syntax.nkind.N_DOT: cgdot(c, n); return; + case syntax.nkind.N_UN: cgun(c, n); return; + case syntax.nkind.N_BIN: cgbin(c, n); return; + case syntax.nkind.N_CALL: cgcall(c, n); return; + case syntax.nkind.N_ASSIGN: cgassign(c, n); return; + case syntax.nkind.N_TRYPROP: cgtryprop(c, n); return; + case syntax.nkind.N_TRYUNW: cgtryunw(c, n); return; + case syntax.nkind.N_TYPETEST: cgtypetest(c, n); return; + case syntax.nkind.N_TYPEASSERT: cgtypeassert(c, n); return; + case syntax.nkind.N_TUPLE: // #241: a literal tuple rvalue `(a, b)` is a value — pack its // elements into the register cursor (mirror cgreturn's N_TUPLE // arm) so a let-bind / destructure consumer reads every element, @@ -128,10 +128,10 @@ fn cgexpr(c: *cgen, n: *node) void = { // tagged-union type expression `tagged`. -1 if `tagged` isn't an // nkind.N_TTAGGED or no variant matches. Mirrors the lookup that cgmatch // does inline; pulled out so `is` / `as` can reuse it. -fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { +fn cgtagvariantidx(c: *cgen, tagged: *syntax.node, vt: *syntax.node) i32 = { if (tagged == nil) { return -1; }; if (vt == nil) { return -1; }; - if (tagged.kind != nkind.N_TTAGGED) { + if (tagged.kind != syntax.nkind.N_TTAGGED) { // #22a: a STAMPED-CARRIER scrutinee (the #67 matchscrutt // shape — is/as on a tuple element t.N, a struct field, an // indexed element) is not an N_TTAGGED type-AST node; its @@ -140,10 +140,10 @@ fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { // cstage cg_tag_for_variant is type-based for every // scrutinee shape, so the AST-keyed -1 here was a silent // tag-0 clamp on wwstage (cs CMPQ $1 vs ww CMPQ $0). - let sti: *tinfo = tagged.type_: *tinfo; + let sti: *syntax.tinfo = tagged.type_: *syntax.tinfo; sti = tichase(sti); - if (sti != nil && sti.kind == tykind.TY_TAGGED && vt.type_ != nil) { - return flatvariantidxt(sti, vt.type_: *tinfo, false); + if (sti != nil && sti.kind == syntax.tykind.TY_TAGGED && vt.type_ != nil) { + return flatvariantidxt(sti, vt.type_: *syntax.tinfo, false); }; return -1; }; @@ -151,7 +151,7 @@ fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { // element-aware helper, which carries the loose first-slice-shape // fallback (cstage type_assignable stand-in) that flatvariantidx's // strict typeeq below doesn't. Task #19; #66 refresh. - if (vt.kind == nkind.N_TSLICE) { + if (vt.kind == syntax.nkind.N_TSLICE) { return flatslicevariantidx(c, tagged, vt.lhs); }; // #66 Phase-N step 3: match by typeeq on vt's stamped tinfo @@ -164,12 +164,12 @@ fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { // error (`!T`), the success tag is the first NON-error variant's index; // else 0 (legacy/no-error). Drives the `?`/`!` success-tag CMPQ + the // payload-shift variant lookup (#52/#216 — replaces the hardcoded tag-0). -fn successtag(ou: *tinfo) i64 = { - let u: *tinfo = tichase(ou); +fn successtag(ou: *syntax.tinfo) i64 = { + let u: *syntax.tinfo = tichase(ou); if (u == nil) { return 0i64; }; - if (u.kind != tykind.TY_TAGGED) { return 0i64; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return 0i64; }; let haserr: bool = false; - let p: *tparam = u.params; + let p: *syntax.tparam = u.params; for (p != nil) { if (p.iserror) { haserr = true; }; p = p.tnext; }; if (!haserr) { return 0i64; }; let idx: i64 = 0i64; @@ -185,13 +185,13 @@ fn successtag(ou: *tinfo) i64 = { // successvariant — the success variant's type_ (the param at successtag). // Lets the #241 tuple/tagged payload-shift sites inspect the SUCCESS // variant's shape, not the (error-first) first param. -fn successvariant(ou: *tinfo) *tinfo = { - let u: *tinfo = tichase(ou); +fn successvariant(ou: *syntax.tinfo) *syntax.tinfo = { + let u: *syntax.tinfo = tichase(ou); if (u == nil) { return nil; }; - if (u.kind != tykind.TY_TAGGED) { return nil; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return nil; }; let st: i64 = successtag(ou); let idx: i64 = 0i64; - let p: *tparam = u.params; + let p: *syntax.tparam = u.params; for (p != nil) { if (idx == st) { return p.type_; }; idx += 1i64; @@ -207,17 +207,17 @@ fn successvariant(ou: *tinfo) *tinfo = { // stamped tagged result tinfo (n.lhs.type_); the success variant is the // param at successtag (dynamic, #52 — not the hardcoded first param), // matching the dynamic CMPQ $successtag success-tag convention. -fn cgtrytupleshift(c: *cgen, n: *node) bool = { +fn cgtrytupleshift(c: *cgen, n: *syntax.node) bool = { if (n.lhs == nil) { return false; }; - let ou: *tinfo = n.lhs.type_: *tinfo; + let ou: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; ou = tichase(ou); if (ou == nil) { return false; }; - if (ou.kind != tykind.TY_TAGGED) { return false; }; + if (ou.kind != syntax.tykind.TY_TAGGED) { return false; }; if (ou.params == nil) { return false; }; - let sv: *tinfo = successvariant(ou); + let sv: *syntax.tinfo = successvariant(ou); sv = tichase(sv); if (sv == nil) { return false; }; - if (sv.kind != tykind.TY_TUPLE) { return false; }; + if (sv.kind != syntax.tykind.TY_TUPLE) { return false; }; cgtaggedtuplepayloadshift(c, sv); return true; }; @@ -230,17 +230,17 @@ fn cgtrytupleshift(c: *cgen, n: *node) bool = { // MOVQ DX,AX tail carried only the inner tag and dropped the payload // (ken unw16). Nullable folds to one word and stays on the scalar // move. Twin of cgtrytupleshift; mirrors cstage N_TRYPROP/N_TRYUNW. -fn cgtrytaggedshift(c: *cgen, n: *node) bool = { +fn cgtrytaggedshift(c: *cgen, n: *syntax.node) bool = { if (n.lhs == nil) { return false; }; - let ou: *tinfo = n.lhs.type_: *tinfo; + let ou: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; ou = tichase(ou); if (ou == nil) { return false; }; - if (ou.kind != tykind.TY_TAGGED) { return false; }; + if (ou.kind != syntax.tykind.TY_TAGGED) { return false; }; if (ou.params == nil) { return false; }; - let sv: *tinfo = successvariant(ou); + let sv: *syntax.tinfo = successvariant(ou); sv = tichase(sv); if (sv == nil) { return false; }; - if (sv.kind != tykind.TY_TAGGED) { return false; }; + if (sv.kind != syntax.tykind.TY_TAGGED) { return false; }; if (sv.nullable != 0) { return false; }; emitline("\tMOVQ\tDX, AX\n"); if (sv.size: i32 > 8) { emitline("\tMOVQ\tCX, DX\n"); }; @@ -263,25 +263,25 @@ fn cgtrytaggedshift(c: *cgen, n: *node) bool = { // need the lhs in AX and the divisor/count in CX, so swap (rhs AX→CX, // old BX→AX) first. Signed RSHIFTEQ uses SARQ, unsigned SHRQ (#136). // Mirrors cstage cg_dotfield_combine — both stages emit identical asm. -fn cgdotfieldcombine(c: *cgen, op: tkind, unsignd: bool) void = { - if (op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tBX, AX\n"); return; }; - if (op == tkind.TK_MINUSEQ) { +fn cgdotfieldcombine(c: *cgen, op: syntax.tkind, unsignd: bool) void = { + if (op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); emitline("\tMOVQ\tBX, AX\n"); return; }; - if (op == tkind.TK_STAREQ) { emitline("\tIMULQ\tBX, AX\n"); return; }; - if (op == tkind.TK_AMPEQ) { emitline("\tANDQ\tBX, AX\n"); return; }; - if (op == tkind.TK_PIPEEQ) { emitline("\tORQ\tBX, AX\n"); return; }; - if (op == tkind.TK_CARETEQ) { emitline("\tXORQ\tBX, AX\n"); return; }; - if (op == tkind.TK_SLASHEQ) { + if (op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_SLASHEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; return; }; - if (op == tkind.TK_PERCENTEQ) { + if (op == syntax.tkind.TK_PERCENTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } @@ -289,13 +289,13 @@ fn cgdotfieldcombine(c: *cgen, op: tkind, unsignd: bool) void = { emitline("\tMOVQ\tDX, AX\n"); return; }; - if (op == tkind.TK_LSHIFTEQ) { + if (op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); emitline("\tSHLQ\tCX, AX\n"); return; }; - if (op == tkind.TK_RSHIFTEQ) { + if (op == syntax.tkind.TK_RSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); if (unsignd) { emitline("\tSHRQ\tCX, AX\n"); } @@ -311,7 +311,7 @@ fn cgdotfieldcombine(c: *cgen, op: tkind, unsignd: bool) void = { // non-integer field (float/str/slice/tagged): the combine arm only // speaks integer ABI; pre-#34 these silently became `s.f = rhs`. // Mirrors the cstage cg_dotfield_hardstop gate. (#34/rule-7) -fn cgdotfieldhardstop(c: *cgen, ftn: *node) void = { +fn cgdotfieldhardstop(c: *cgen, ftn: *syntax.node) void = { if (istaggedtype(c, ftn)) { let m: str = "single-dot field compound on tagged field not wired (#34/rule-7)\n"; os.write(2, m.ptr, m.len: u64); @@ -334,18 +334,18 @@ fn cgdotfieldhardstop(c: *cgen, ftn: *node) void = { }; }; -fn cgtryunwcursor(c: *cgen, n: *node, opname: str) void = { - let u: *tinfo = nil; - if (n.lhs != nil) { u = n.lhs.type_: *tinfo; }; +fn cgtryunwcursor(c: *cgen, n: *syntax.node, opname: str) void = { + let u: *syntax.tinfo = nil; + if (n.lhs != nil) { u = n.lhs.type_: *syntax.tinfo; }; u = tichase(u); let utag: bool = false; if (u != nil) { - if (u.kind == tykind.TY_TAGGED && u.nullable == 0) { + if (u.kind == syntax.tykind.TY_TAGGED && u.nullable == 0) { utag = true; }; }; if (utag && u.size: i32 > TUPLE_GPCAP * 8 - && n.lhs.kind != nkind.N_CALL) { + && n.lhs.kind != syntax.nkind.N_CALL) { let p37: str = "#37: `"; os.write(2, p37.ptr, p37.len: u64); os.write(2, opname.ptr, opname.len: u64); @@ -353,7 +353,7 @@ fn cgtryunwcursor(c: *cgen, n: *node, opname: str) void = { os.write(2, m37t.ptr, m37t.len: u64); os.exit(1); }; - if (utag && n.lhs.kind == nkind.N_IDENT) { + if (utag && n.lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.lhs.str); if (lc == nil) { let p35: str = "#35: `"; @@ -401,14 +401,14 @@ fn cgtryunwcursor(c: *cgen, n: *node, opname: str) void = { // cgtryprop — `e?` propagates the error variant up the stack. // Success tag is dynamic via successtag (#52/#216): the first non-error // variant's index (cstage cg_tagged_success_tag parity), 0 when success-first. -fn cgtryprop(c: *cgen, n: *node) void = { +fn cgtryprop(c: *cgen, n: *syntax.node) void = { // #38b residuals (rule 7): the cursor read below cannot see an // sret-classified call result (AX = dest pointer), and the // propagate-RET cannot speak an sret-classified enclosing return // (the caller reads memory, not the cursor). #40-family follow-ups. // Mirrors cstage cgen.c N_TRYPROP gates. if (n.lhs != nil) { - if (n.lhs.kind == nkind.N_CALL) { + if (n.lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, n.lhs) > 0) { let m38p: str = "#38b: `?` on an sret-class call result unwired (mem-based unwrap is a #40-family follow-up)\n"; os.write(2, m38p.ptr, m38p.len: u64); @@ -446,8 +446,8 @@ fn cgtryprop(c: *cgen, n: *node) void = { // parity, #52): 0 for success-first, the first non-error index for an // error-first union. let cl: str = mklabel(c, "tryprop_ok"); - let propu: *tinfo = nil; - if (n.lhs != nil) { propu = n.lhs.type_: *tinfo; }; + let propu: *syntax.tinfo = nil; + if (n.lhs != nil) { propu = n.lhs.type_: *syntax.tinfo; }; emitline("\tCMPQ\t$"); emitint(successtag(propu)); emitline(", AX\n"); @@ -462,17 +462,17 @@ fn cgtryprop(c: *cgen, n: *node) void = { // Payload words DX/CX/R8 ride the RET untouched; only AX (the // tag) is rewritten. Same-order unions map every error variant to // itself → zero instructions, byte-id with the pre-#173 emit. - let u: *tinfo = nil; - if (n.lhs != nil) { u = n.lhs.type_: *tinfo; }; + let u: *syntax.tinfo = nil; + if (n.lhs != nil) { u = n.lhs.type_: *syntax.tinfo; }; u = tichase(u); - let r: *tinfo = nil; - if (c.fnret != nil) { r = c.fnret.type_: *tinfo; }; + let r: *syntax.tinfo = nil; + if (c.fnret != nil) { r = c.fnret.type_: *syntax.tinfo; }; r = tichase(r); - if (u != nil && r != nil && r.kind == tykind.TY_TAGGED && u.params != nil) { + if (u != nil && r != nil && r.kind == syntax.tykind.TY_TAGGED && u.params != nil) { let propret: str; propret.ptr = nil; propret.len = 0; let haveret: bool = false; - let p: *tparam = u.params; + let p: *syntax.tparam = u.params; let i: i32 = 0; for (p != nil) { if (p.iserror) { @@ -521,7 +521,7 @@ fn cgtryprop(c: *cgen, n: *node) void = { // (success_is_str = type_isstr(succ_t at cg_tagged_success_tag)). let succisstr: bool = false; if (n.lhs != nil) { - succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo)); + succisstr = syntax.typeisstr(successvariant(n.lhs.type_: *syntax.tinfo)); }; if (succisstr) { // str IS []u8: success arrives DX=ptr, CX=len, R8=cap @@ -537,10 +537,10 @@ fn cgtryprop(c: *cgen, n: *node) void = { // cgtryunw — `e!` aborts on the error variant via exit(1). Success tag // is dynamic via successtag (#52): the first non-error variant's index // (cstage cg_tagged_success_tag parity), 0 when success-first. -fn cgtryunw(c: *cgen, n: *node) void = { +fn cgtryunw(c: *cgen, n: *syntax.node) void = { // #38b residual (rule 7): see the cgtryprop twin. if (n.lhs != nil) { - if (n.lhs.kind == nkind.N_CALL) { + if (n.lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, n.lhs) > 0) { let m38u: str = "#38b: `!` on an sret-class call result unwired (mem-based unwrap is a #40-family follow-up)\n"; os.write(2, m38u.ptr, m38u.len: u64); @@ -569,8 +569,8 @@ fn cgtryunw(c: *cgen, n: *node) void = { // Success tag is dynamic (successtag / cstage cg_tagged_success_tag // parity, #52): 0 for success-first, the first non-error index for an // error-first union. - let unwu: *tinfo = nil; - if (n.lhs != nil) { unwu = n.lhs.type_: *tinfo; }; + let unwu: *syntax.tinfo = nil; + if (n.lhs != nil) { unwu = n.lhs.type_: *syntax.tinfo; }; emitline("\tCMPQ\t$"); emitint(successtag(unwu)); emitline(", AX\n"); @@ -588,7 +588,7 @@ fn cgtryunw(c: *cgen, n: *node) void = { // cgtryprop; cstage cgen.c:10595-10602). let succisstr: bool = false; if (n.lhs != nil) { - succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo)); + succisstr = syntax.typeisstr(successvariant(n.lhs.type_: *syntax.tinfo)); }; if (succisstr) { // str IS []u8: success arrives DX=ptr, CX=len, R8=cap @@ -601,7 +601,7 @@ fn cgtryunw(c: *cgen, n: *node) void = { return; }; -fn cgtypetest(c: *cgen, n: *node) void = { +fn cgtypetest(c: *cgen, n: *syntax.node) void = { // `e is T` — load the lhs's tag, compare against T's variant // index, set AX = (tag == idx). Result type is bool. // @@ -613,12 +613,12 @@ fn cgtypetest(c: *cgen, n: *node) void = { // the ident emission carries; a WIDENING tagged cast renumbers // the tag the compare keys on and has no wired source arm — // loud below, not a mis-keyed test. Mirrors cstage N_TYPETEST. - let lhs: *node = taggedidcastpeel(c, n.lhs); + let lhs: *syntax.node = taggedidcastpeel(c, n.lhs); // #38b residual (rule 7): an sret-class call result leaves AX = // dest pointer, not the tag — mem-based test is a #40-family // follow-up. Mirrors cstage cgen.c N_TYPETEST gate. if (lhs != nil) { - if (lhs.kind == nkind.N_CALL) { + if (lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, lhs) > 0) { let m38t: str = "#38b: `is` on an sret-class call result unwired (#40-family follow-up)\n"; os.write(2, m38t.ptr, m38t.len: u64); @@ -627,11 +627,11 @@ fn cgtypetest(c: *cgen, n: *node) void = { }; }; let scrutoff: i32 = 0; - let scrutt: *node = nil; + let scrutt: *syntax.node = nil; let nonident: bool = false; let globalident: bool = false; if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, lhs.str); if (lc != nil) { scrutoff = lc.off; @@ -640,7 +640,7 @@ fn cgtypetest(c: *cgen, n: *node) void = { // #18 is-half (align-UP): global tagged ident — tag word at // g(SB)+0, no BP slot. cstage N_TYPETEST is uniformly cgexpr // (MOVQ g(SB),AX); pre-fix the !nonident emit read 0(BP)=saved BP. - let gt: *node = letvartnode(c, lhs.str); + let gt: *syntax.node = letvartnode(c, lhs.str); scrutt = resolvetagged(c, gt); globalident = true; }; @@ -659,10 +659,10 @@ fn cgtypetest(c: *cgen, n: *node) void = { // Family C catch-all (rule 7): a widening tagged // cast source — loud. Mirrors cstage. { - let icu: *tinfo = lhs.type_: *tinfo; + let icu: *syntax.tinfo = lhs.type_: *syntax.tinfo; icu = tichase(icu); - if (lhs.kind == nkind.N_CAST && icu != nil - && icu.kind == tykind.TY_TAGGED + if (lhs.kind == syntax.nkind.N_CAST && icu != nil + && icu.kind == syntax.tykind.TY_TAGGED && icu.nullable == 0) { let m35i: str = "#35: tagged cast source shape unwired at `is` (rule 7)\n"; os.write(2, m35i.ptr, m35i.len: u64); @@ -679,7 +679,7 @@ fn cgtypetest(c: *cgen, n: *node) void = { }; }; let want: i32 = 0; - let nullcarrier: *node = scrutt; + let nullcarrier: *syntax.node = scrutt; if (nonident) { // Variant index from the STAMPED scrutinee type (cstage: // u = n->lhs->type) — matchscrutt's node-shape walk can't @@ -688,7 +688,7 @@ fn cgtypetest(c: *cgen, n: *node) void = { // flatslicevariantidx read .type_ off any stamped carrier. nullcarrier = lhs; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_TSLICE) { + if (n.rhs.kind == syntax.nkind.N_TSLICE) { want = flatslicevariantidx(c, lhs, n.rhs.lhs); } else { want = flatvariantidx(c, lhs, n.rhs); @@ -739,13 +739,13 @@ fn cgtypetest(c: *cgen, n: *node) void = { return; }; -fn cgtypeassert(c: *cgen, n: *node) void = { +fn cgtypeassert(c: *cgen, n: *syntax.node) void = { // `e as T` — load tag, abort (exit 1) if tag != T's variant // index, otherwise unwrap to T's ABI: scalar/ptr → AX, 16B // str → (AX, BX). Mirrors cgmatch's slot-based value load. // Slot resolution inlined; see cgtypetest comment. // Family C (#35): identity-cast peel — see the cgtypetest twin. - let lhs: *node = taggedidcastpeel(c, n.lhs); + let lhs: *syntax.node = taggedidcastpeel(c, n.lhs); // Enum ↔ integer: reinterpret-only — the value already occupies AX // (or AX:BX for str variants, irrelevant here); no tag/unwrap. Gate // on the stamped operand / result TYPE, not node shape: a constant- @@ -754,13 +754,13 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // spurious tagged-assertion + exit(1) (#27b). Mirrors cstage // cmd/w6c/cgen.c N_TYPEASSERT (type_chase_named on operand + result). { - let su: *tinfo = nil; - if (lhs != nil) { su = tichase(lhs.type_: *tinfo); }; - let vu: *tinfo = tichase(n.type_: *tinfo); + let su: *syntax.tinfo = nil; + if (lhs != nil) { su = tichase(lhs.type_: *syntax.tinfo); }; + let vu: *syntax.tinfo = tichase(n.type_: *syntax.tinfo); let lenum: bool = false; let renum: bool = false; - if (su != nil) { if (su.kind == tykind.TY_ENUM) { lenum = true; }; }; - if (vu != nil) { if (vu.kind == tykind.TY_ENUM) { renum = true; }; }; + if (su != nil) { if (su.kind == syntax.tykind.TY_ENUM) { lenum = true; }; }; + if (vu != nil) { if (vu.kind == syntax.tykind.TY_ENUM) { renum = true; }; }; if (lenum || renum) { cgexpr(c, lhs); return; @@ -770,7 +770,7 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // an sret-class call result never fills. Mirrors cstage cgen.c // N_TYPEASSERT gate. if (lhs != nil) { - if (lhs.kind == nkind.N_CALL) { + if (lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, lhs) > 0) { let m38a: str = "#38b: `as` on an sret-class call result unwired (#40-family follow-up)\n"; os.write(2, m38a.ptr, m38a.len: u64); @@ -779,9 +779,9 @@ fn cgtypeassert(c: *cgen, n: *node) void = { }; }; let scrutoff: i32 = 0; - let scrutt: *node = nil; + let scrutt: *syntax.node = nil; if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, lhs.str); if (lc != nil) { scrutoff = lc.off; @@ -792,7 +792,7 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // task #46). No BP slot: copy the box words from g(SB) into a // fresh @asrt_spill so the tag-check + payload load below index // off memory like a local. cs!=ww residual until #46 lands. - let gt: *node = letvartnode(c, lhs.str); + let gt: *syntax.node = letvartnode(c, lhs.str); scrutt = resolvetagged(c, gt); let gsz: i32 = matchspillsz(c, scrutt); scrutoff = localalloc(c, "@asrt_spill", gsz, nil); @@ -849,10 +849,10 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // Family C catch-all (rule 7): a widening tagged // cast source — loud. Mirrors cstage. { - let acu: *tinfo = lhs.type_: *tinfo; + let acu: *syntax.tinfo = lhs.type_: *syntax.tinfo; acu = tichase(acu); - if (lhs.kind == nkind.N_CAST && acu != nil - && acu.kind == tykind.TY_TAGGED + if (lhs.kind == syntax.nkind.N_CAST && acu != nil + && acu.kind == syntax.tykind.TY_TAGGED && acu.nullable == 0) { let m35s: str = "#35: tagged cast source shape unwired at `as` (rule 7)\n"; os.write(2, m35s.ptr, m35s.len: u64); @@ -931,12 +931,12 @@ fn cgtypeassert(c: *cgen, n: *node) void = { return; }; -fn cgcast(c: *cgen, n: *node) void = { +fn cgcast(c: *cgen, n: *syntax.node) void = { let srcfk: i32 = 0; if (n.lhs != nil) { - let st: *tinfo = n.lhs.type_: *tinfo; - if (typeisf32(st)) { srcfk = 1; } - else { if (typeisfloat(st)) { srcfk = 2; }; }; + let st: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; + if (syntax.typeisf32(st)) { srcfk = 1; } + else { if (syntax.typeisfloat(st)) { srcfk = 2; }; }; }; let dstf64: bool = isfloattype(c, n.rhs); let dstf32: bool = isf32type(c, n.rhs); @@ -989,18 +989,18 @@ fn cgcast(c: *cgen, n: *node) void = { // Detect bool dst by walking n.rhs to the leaf TNAME. bool // keeps its dedicated ANDQ $255 contract regardless of // upstream shape; it stays off the identity path. - let leaf_tn: *node = n.rhs; + let leaf_tn: *syntax.node = n.rhs; for (leaf_tn != nil) { - let lk: nkind = leaf_tn.kind; - if (lk == nkind.N_TBANG) { leaf_tn = leaf_tn.lhs; } - else { if (lk == nkind.N_TENUM) { leaf_tn = leaf_tn.lhs; } - else { if (lk == nkind.N_TNAME) { + let lk: syntax.nkind = leaf_tn.kind; + if (lk == syntax.nkind.N_TBANG) { leaf_tn = leaf_tn.lhs; } + else { if (lk == syntax.nkind.N_TENUM) { leaf_tn = leaf_tn.lhs; } + else { if (lk == syntax.nkind.N_TNAME) { let lnm: str = leaf_tn.str; // primsize-ok (#101/#109): this IS an alias chase loop // — primsize is the leaf-primitive break test the loop // wraps (aliaslookup advances the cursor on a miss). if (primsize(lnm) > 0) { break; }; - let lal: *node = aliaslookup(c, lnm); + let lal: *syntax.node = aliaslookup(c, lnm); if (lal == nil) { leaf_tn = nil; } else { leaf_tn = lal; }; } @@ -1008,8 +1008,8 @@ fn cgcast(c: *cgen, n: *node) void = { }; let is_bool: bool = false; if (leaf_tn != nil) { - if (leaf_tn.kind == nkind.N_TNAME) { - is_bool = streq(leaf_tn.str, "bool"); + if (leaf_tn.kind == syntax.nkind.N_TNAME) { + is_bool = syntax.streq(leaf_tn.str, "bool"); }; }; // Symmetric narrow on signed vs unsigned (task #5): @@ -1067,7 +1067,7 @@ fn cgcast(c: *cgen, n: *node) void = { // Same-kind float→float: nothing to emit. }; -fn cgstrlit(c: *cgen, n: *node) void = { +fn cgstrlit(c: *cgen, n: *syntax.node) void = { // str IS []u8: the (ptr, len, cap) triple — ptr in AX, len in BX, // cap in CX. A static literal has no spare storage, so cap = len // (#1/Phase 3). Call sites that expect a str arg pick these up. @@ -1085,7 +1085,7 @@ fn cgstrlit(c: *cgen, n: *node) void = { return; }; -fn cgident(c: *cgen, n: *node) void = { +fn cgident(c: *cgen, n: *syntax.node) void = { let nm: str = n.str; let lc: *local = localfindnode(c, nm); if (lc != nil) { @@ -1093,10 +1093,10 @@ fn cgident(c: *cgen, n: *node) void = { // #241: a tuple ident is a value — leave the whole tuple in the // register cursor (`yield t` / `return t` / `let q = t`), not // just word0 in AX. Mirror of cstage cgexpr N_IDENT tuple arm. - let itu: *tinfo = nil; - if (lc.tnode != nil) { itu = lc.tnode.type_: *tinfo; }; + let itu: *syntax.tinfo = nil; + if (lc.tnode != nil) { itu = lc.tnode.type_: *syntax.tinfo; }; itu = tichase(itu); - if (itu != nil) { if (itu.kind == tykind.TY_TUPLE) { + if (itu != nil) { if (itu.kind == syntax.tykind.TY_TUPLE) { cgtupleslottocursor(c, off, itu); return; }; }; @@ -1153,9 +1153,9 @@ fn cgident(c: *cgen, n: *node) void = { // the (LEAQ ptr, MOVQ $len) pair instead, mirroring cstage // Sdef walk #1 N_IDENT bare-load (cmd/w6c/cgen.c). Filed #12. if (deflookup(c, nm)) { - let drhs: *node = deflookuprhs(c, nm); + let drhs: *syntax.node = deflookuprhs(c, nm); if (drhs != nil) { - if (drhs.kind == nkind.N_STRLIT) { + if (drhs.kind == syntax.nkind.N_STRLIT) { let bytes: str = drhs.str; let lab: str = internstrlit(c, bytes); emitline("\tLEAQ\t"); @@ -1199,7 +1199,7 @@ fn cgident(c: *cgen, n: *node) void = { // in one go, so a body-less FFI binding emits the C symbol // it was declared with via @symbol(), not the ww-side ident. // Bare ident → same-module by ww's resolver, hint with c.curmod. - let rtyp: *node = fnretlookup(c, nm); + let rtyp: *syntax.node = fnretlookup(c, nm); if (rtyp != nil) { emitline("\tLEAQ\t"); emitfnname(c, nm, c.curmod); @@ -1220,12 +1220,12 @@ fn cgident(c: *cgen, n: *node) void = { // receive read a STALE cursor for words 1+. Element reads // (g.N) are the supported surface. Mirrors the cstage cgexpr // non-local ident guard. - let gtt: *node = letvartnode(c, nm); - for (gtt != nil && gtt.kind == nkind.N_TNAME) { + let gtt: *syntax.node = letvartnode(c, nm); + for (gtt != nil && gtt.kind == syntax.nkind.N_TNAME) { gtt = aliaslookup(c, gtt.str); }; if (gtt != nil) { - if (gtt.kind == nkind.N_TTUPLE) { + if (gtt.kind == syntax.nkind.N_TTUPLE) { let mgt: str = "#48: global tuple as a first-class value unwired (element reads only; rule 7)\n"; os.write(2, mgt.ptr, mgt.len: u64); os.exit(1); @@ -1250,10 +1250,10 @@ fn cgident(c: *cgen, n: *node) void = { // MOVSD have no D_EXTERN operand form in w6a. Signed-narrow // scalar globals route through the same LEAQ scratch since // MOVSXD/MOVSWQ/MOVSBQ also have no D_EXTERN form. - let lvtnode: *node = nil; + let lvtnode: *syntax.node = nil; let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, nm)) { + if (syntax.streq(lv.name, nm)) { // #135: an inferred-float global's tnode is the // defaultinferredlets-renamed "f64"/"f32" N_TNAME whose // .type_ is unstamped (cgen can't build tinfo), so the @@ -1263,7 +1263,7 @@ fn cgident(c: *cgen, n: *node) void = { let isf: bool = isfloattype(c, lv.tnode); let is32: bool = isf32type(c, lv.tnode); if (!isf && lv.tnode != nil - && lv.tnode.kind == nkind.N_TNAME) { + && lv.tnode.kind == syntax.nkind.N_TNAME) { let fsz: i32 = letfloatprim(lv.tnode.str); if (fsz > 0) { isf = true; }; if (fsz == 4) { is32 = true; }; @@ -1286,7 +1286,7 @@ fn cgident(c: *cgen, n: *node) void = { }; }; let glop: str = localloadop(c, lvtnode); - if (streq(glop, "MOVQ")) { + if (syntax.streq(glop, "MOVQ")) { emitline("\tMOVQ\t"); emitfnname(c, nm, c.curmod); emitline("(SB), AX\n"); @@ -1311,12 +1311,12 @@ fn cgident(c: *cgen, n: *node) void = { // and, later, the typeassert str-variant leaf (#9). c retained unused // for callsite symmetry with cstage cgslicehdr. fn cgslicehdr(c: *cgen, base: str) void = { - if (!streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; - if (!streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; - if (!streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; - if (streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; - if (streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; - if (streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; + if (!syntax.streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; + if (!syntax.streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; + if (!syntax.streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; + if (syntax.streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; + if (syntax.streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; + if (syntax.streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; }; // dotchainaddr — emit the ADDRESS of a dot/ident lvalue chain into @@ -1328,9 +1328,9 @@ fn cgslicehdr(c: *cgen, base: str) void = { // spill contract as dotbaseaddr. The chained-base arm of dotbaseaddr // (#253) is its sole caller. Cstage twin: cmd/w6c/cgen.c // `cg_dotchain_addr`. -fn dotchainaddr(c: *cgen, n: *node, dstreg: str) bool = { +fn dotchainaddr(c: *cgen, n: *syntax.node, dstreg: str) bool = { if (n == nil) { return false; }; - if (n.kind == nkind.N_IDENT) { + if (n.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -1357,29 +1357,29 @@ fn dotchainaddr(c: *cgen, n: *node, dstreg: str) bool = { }; return false; }; - if (n.kind != nkind.N_DOT) { return false; }; - let x: *node = n.lhs; + if (n.kind != syntax.nkind.N_DOT) { return false; }; + let x: *syntax.node = n.lhs; if (x == nil) { return false; }; - let xu: *tinfo = x.type_: *tinfo; + let xu: *syntax.tinfo = x.type_: *syntax.tinfo; xu = tichase(xu); if (xu == nil) { return false; }; let xviaptr: bool = false; - let st: *tinfo = nil; - if (xu.kind == tykind.TY_PTR) { - let p: *tinfo = xu.sub; + let st: *syntax.tinfo = nil; + if (xu.kind == syntax.tykind.TY_PTR) { + let p: *syntax.tinfo = xu.sub; p = tichase(p); - if (p != nil) { if (p.kind == tykind.TY_STRUCT) { + if (p != nil) { if (p.kind == syntax.tykind.TY_STRUCT) { st = p; xviaptr = true; }; }; - } else { if (xu.kind == tykind.TY_STRUCT) { + } else { if (xu.kind == syntax.tykind.TY_STRUCT) { st = xu; }; }; if (st == nil) { return false; }; - let f: *tfield = st.fields; + let f: *syntax.tfield = st.fields; let foff: i64 = -1; for (f != nil) { - if (streq(f.name, n.str)) { + if (syntax.streq(f.name, n.str)) { foff = f.offset: i64; break; }; @@ -1422,13 +1422,13 @@ fn dotchainaddr(c: *cgen, n: *node, dstreg: str) bool = { // inner when inner is a *struct (viaptr), else the ADDRESS of inner — // then adds the field offset. Closes the array-field-base-address // family across every op (index r/w, addr-of, slice, compound). -fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { +fn dotbaseaddr(c: *cgen, base: *syntax.node, dstreg: str) bool = { if (base == nil) { return false; }; - if (base.kind != nkind.N_DOT) { return false; }; - let inner: *node = base.lhs; + if (base.kind != syntax.nkind.N_DOT) { return false; }; + let inner: *syntax.node = base.lhs; if (inner == nil) { return false; }; - let chained: bool = (inner.kind == nkind.N_DOT); - if (inner.kind != nkind.N_IDENT && !chained) { return false; }; + let chained: bool = (inner.kind == syntax.nkind.N_DOT); + if (inner.kind != syntax.nkind.N_IDENT && !chained) { return false; }; // #128b: module-qualified `mod.arr` where arr is an imported // top-level `let X: [N]T`. The checker leaves SK_USE module- // idents without a localfindnode entry; detect via letvartnode @@ -1447,10 +1447,10 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { // (cgen.c:2109). Without the gate a typed-struct global inner whose // FIELD shares a name with an unrelated global array hijacks it // (gs.fld -> LEAQ fld(SB)) — #20. A typed inner falls to #249 below. - let ibu: *tinfo = tichase(inner.type_: *tinfo); - if (ibu == nil || ibu.kind == tykind.TY_ERR) { - let gt: *node = letvartnode(c, base.str); - if (gt != nil && gt.kind == nkind.N_TARRAY) { + let ibu: *syntax.tinfo = tichase(inner.type_: *syntax.tinfo); + if (ibu == nil || ibu.kind == syntax.tykind.TY_ERR) { + let gt: *syntax.node = letvartnode(c, base.str); + if (gt != nil && gt.kind == syntax.nkind.N_TARRAY) { emitline("\tLEAQ\t"); emitsymname(c, base.str); emitline("(SB), "); @@ -1467,27 +1467,27 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { isglobal = true; }; }; - let bu: *tinfo = inner.type_: *tinfo; + let bu: *syntax.tinfo = inner.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; let viaptr: bool = false; - let structt: *tinfo = nil; - if (bu.kind == tykind.TY_PTR) { - let st: *tinfo = bu.sub; + let structt: *syntax.tinfo = nil; + if (bu.kind == syntax.tykind.TY_PTR) { + let st: *syntax.tinfo = bu.sub; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { structt = st; viaptr = true; }; }; - } else { if (bu.kind == tykind.TY_STRUCT) { + } else { if (bu.kind == syntax.tykind.TY_STRUCT) { structt = bu; }; }; if (structt == nil) { return false; }; - let f: *tfield = structt.fields; + let f: *syntax.tfield = structt.fields; let foff: i64 = -1; - let ft: *tinfo = nil; + let ft: *syntax.tinfo = nil; for (f != nil) { - if (streq(f.name, base.str)) { + if (syntax.streq(f.name, base.str)) { foff = f.offset: i64; ft = f.type_; break; @@ -1501,7 +1501,7 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { // twin gate at cg_dotbase_addr. ft = tichase(ft); if (ft == nil) { return false; }; - if (ft.kind != tykind.TY_ARRAY) { return false; }; + if (ft.kind != syntax.tykind.TY_ARRAY) { return false; }; // #253: chained inner — compute the container base via the dot-chain // spine (pointer VALUE of inner when viaptr, else its ADDRESS), then // add the field offset. dotchainaddr keeps the spill contract. @@ -1571,11 +1571,11 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { // #253), N_INDEX element of an N_IDENT array base (the &base[i] spine, // #252/#270). Returns false for an uncovered source kind (caller loud- // stops, rule 7). The CALL source is handled at the push site. -fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { - if (src.kind == nkind.N_UN) { - if (src.op == tkind.TK_STAR) { +fn aggargsrcaddr(c: *cgen, src: *syntax.node, dst: str) bool = { + if (src.kind == syntax.nkind.N_UN) { + if (src.op == syntax.tkind.TK_STAR) { cgexpr(c, src.lhs); - if (!streq(dst, "AX")) { + if (!syntax.streq(dst, "AX")) { emitline("\tMOVQ\tAX, "); emitline(dst); emitline("\n"); @@ -1583,7 +1583,7 @@ fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { return true; }; }; - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, src.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -1607,18 +1607,18 @@ fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { }; return false; }; - if (src.kind == nkind.N_DOT) { + if (src.kind == syntax.nkind.N_DOT) { return dotchainaddr(c, src, dst); }; - if (src.kind == nkind.N_INDEX) { - let base: *node = src.lhs; - let idx: *node = src.rhs; + if (src.kind == syntax.nkind.N_INDEX) { + let base: *syntax.node = src.lhs; + let idx: *syntax.node = src.rhs; if (base == nil) { return false; }; - if (base.kind != nkind.N_IDENT) { return false; }; - let bu: *tinfo = base.type_: *tinfo; + if (base.kind != syntax.nkind.N_IDENT) { return false; }; + let bu: *syntax.tinfo = base.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; - if (bu.kind != tykind.TY_ARRAY) { return false; }; + if (bu.kind != syntax.tykind.TY_ARRAY) { return false; }; let esz: i32 = 1; if (bu.sub != nil) { esz = bu.sub.size: i32; }; cgexpr(c, idx); @@ -1639,7 +1639,7 @@ fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { emitline("(SB), BX\n"); }; emitline("\tADDQ\tBX, AX\n"); - if (!streq(dst, "AX")) { + if (!syntax.streq(dst, "AX")) { emitline("\tMOVQ\tAX, "); emitline(dst); emitline("\n"); @@ -1709,13 +1709,13 @@ fn aggcopy(c: *cgen, sz: i32) void = { // #44-coupled source). The ragged-tail completeness shared by both stages' // field copies is a separate class, tracked under #73 / the aggcopy // emitter choke-point. -fn copysrcnatsize(c: *cgen, src: *node) i32 = { +fn copysrcnatsize(c: *cgen, src: *syntax.node) i32 = { if (src == nil || src.type_ == nil) { let msg: str = "#71: whole-struct copy source has no stamped tinfo\n"; os.write(2, msg.ptr, msg.len: u64); os.exit(1); }; - let ti: *tinfo = tichase(src.type_: *tinfo); + let ti: *syntax.tinfo = tichase(src.type_: *syntax.tinfo); if (ti == nil) { let msg: str = "#71: whole-struct copy source tinfo chase yielded nil\n"; os.write(2, msg.ptr, msg.len: u64); @@ -1739,9 +1739,9 @@ fn copysrcnatsize(c: *cgen, src: *node) i32 = { // keeps its own load/store/copy emission. Clobbers AX/CX (cgexpr on // index / pointer operands) and balances its own PUSHQ/POPQ; dstreg // must not be AX or CX. -fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { +fn cgplaceaddr(c: *cgen, n: *syntax.node, dstreg: str) bool = { if (n == nil) { return false; }; - if (n.kind == nkind.N_IDENT) { + if (n.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -1756,9 +1756,9 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { if (defvarstructinfo(c, n.str) != nil) { gok = true; }; }; if (!gok) { - let dtn: *node = defvartnode(c, n.str); + let dtn: *syntax.node = defvartnode(c, n.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { gok = true; }; + if (dtn.kind == syntax.nkind.N_TARRAY) { gok = true; }; }; }; if (gok) { @@ -1771,8 +1771,8 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { }; return false; }; - if (n.kind == nkind.N_UN) { - if (n.op != tkind.TK_STAR) { return false; }; + if (n.kind == syntax.nkind.N_UN) { + if (n.op != syntax.tkind.TK_STAR) { return false; }; // &(*e) is e's value — no load. cgexpr(c, n.lhs); emitline("\tMOVQ\tAX, "); @@ -1780,21 +1780,21 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { emitline("\n"); return true; }; - if (n.kind == nkind.N_INDEX) { - let base: *node = n.lhs; - let idx: *node = n.rhs; + if (n.kind == syntax.nkind.N_INDEX) { + let base: *syntax.node = n.lhs; + let idx: *syntax.node = n.rhs; if (base == nil || idx == nil) { return false; }; // C2: any addressable base — recursion decides (deref / // ident / dot / index spine). Ident-rooted shapes with // enumerated arms never reach the resolver (those arms // dispatch first), so their asm is untouched. - let bu: *tinfo = base.type_: *tinfo; + let bu: *syntax.tinfo = base.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; - if (bu.kind != tykind.TY_SLICE && bu.kind != tykind.TY_ARRAY) { + if (bu.kind != syntax.tykind.TY_SLICE && bu.kind != syntax.tykind.TY_ARRAY) { return false; }; - let et: *tinfo = n.type_: *tinfo; + let et: *syntax.tinfo = n.type_: *syntax.tinfo; et = tichase(et); if (et == nil) { return false; }; let esz: i32 = et.size: i32; @@ -1810,7 +1810,7 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { // A slice place holds the {ptr,len,cap} header — the // element base is its .ptr word; an array place IS the // element storage. - if (bu.kind == tykind.TY_SLICE) { + if (bu.kind == syntax.tykind.TY_SLICE) { emitline("\tMOVQ\t("); emitline(dstreg); emitline("), "); @@ -1823,29 +1823,29 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { emitline("\n"); return true; }; - if (n.kind == nkind.N_DOT) { - let base: *node = n.lhs; + if (n.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = n.lhs; if (base == nil) { return false; }; - let bu: *tinfo = base.type_: *tinfo; + let bu: *syntax.tinfo = base.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; let viaptr: bool = false; - let st: *tinfo = nil; - if (bu.kind == tykind.TY_PTR) { - let p: *tinfo = bu.sub; + let st: *syntax.tinfo = nil; + if (bu.kind == syntax.tykind.TY_PTR) { + let p: *syntax.tinfo = bu.sub; p = tichase(p); - if (p != nil) { if (p.kind == tykind.TY_STRUCT) { + if (p != nil) { if (p.kind == syntax.tykind.TY_STRUCT) { st = p; viaptr = true; }; }; - } else { if (bu.kind == tykind.TY_STRUCT) { + } else { if (bu.kind == syntax.tykind.TY_STRUCT) { st = bu; }; }; if (st == nil) { return false; }; - let f: *tfield = st.fields; + let f: *syntax.tfield = st.fields; let foff: i64 = -1; for (f != nil) { - if (streq(f.name, n.str)) { + if (syntax.streq(f.name, n.str)) { foff = f.offset: i64; break; }; @@ -1872,12 +1872,12 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { return false; }; -fn cgindex(c: *cgen, n: *node) void = { +fn cgindex(c: *cgen, n: *syntax.node) void = { // Element-size-aware load: u8 → MOVZBQ, i32 → MOVSXD, u32 → MOVL, // str → (ptr, len) into (AX, BX), everything else → MOVQ. Fast // path when the base is a bare ident (mem.ww shape). - let base: *node = n.lhs; - let idx: *node = n.rhs; + let base: *syntax.node = n.lhs; + let idx: *syntax.node = n.rhs; // Direct non-ident index bases that match none of the typed arms // below (e.g. a cast-expression base) keep this 8B default — // cs!=ww for narrow elements. Team task #19 (#61-residual B). @@ -1922,7 +1922,7 @@ fn cgindex(c: *cgen, n: *node) void = { let globalname: str; globalname.ptr = nil; globalname.len = 0; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal != nil) { @@ -1932,7 +1932,7 @@ fn cgindex(c: *cgen, n: *node) void = { f32_elem = elemisf32c(c, baselocal.tnode); elem_isarray = elemisarrayc(c, baselocal.tnode); } else { - let tn: *node = letvartnode(c, bn); + let tn: *syntax.node = letvartnode(c, bn); // #129 A.3: array-typed defs now have DATA storage; // resolve their base via the same N_TARRAY path as // lets. defvartnode is the def-side sister of @@ -1965,7 +1965,7 @@ fn cgindex(c: *cgen, n: *node) void = { float_elem = elemisfloatc(c, tn); f32_elem = elemisf32c(c, tn); elem_isarray = elemisarrayc(c, tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; @@ -1975,17 +1975,17 @@ fn cgindex(c: *cgen, n: *node) void = { // #60: element facts off the chased checker-stamped // tinfos — cstage reads them via type_chase_named/ // idx_eff uniformly (cmd/w6c/cgen.c N_INDEX). - let bt60: *tinfo = base.type_: *tinfo; + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; if (bt60 != nil) { - if (bt60.kind == tykind.TY_NAMED) { basealias = true; }; + if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; }; }; if (basealias) { - let et60: *tinfo = tichase(n.type_: *tinfo); + let et60: *syntax.tinfo = tichase(n.type_: *syntax.tinfo); if (et60 != nil) { esz = et60.size: i32; - signed_elem = typeissigned(et60); - float_elem = typeisfloat(et60); - f32_elem = typeisf32(et60); + signed_elem = syntax.typeissigned(et60); + float_elem = syntax.typeisfloat(et60); + f32_elem = syntax.typeisf32(et60); }; // global base: array-vs-pointer re-keyed off the // chased BASE kind (cstage isglobal && u->kind == @@ -1993,9 +1993,9 @@ fn cgindex(c: *cgen, n: *node) void = { // alias-typed global DATA emit lands (#77/#78); // kept so the read leg is already cs-aligned. if (isglobalarr || isglobalptr) { - let bu60: *tinfo = tichase(bt60); + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - isglobalarr = bu60.kind == tykind.TY_ARRAY; + isglobalarr = bu60.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; @@ -2006,9 +2006,9 @@ fn cgindex(c: *cgen, n: *node) void = { // element tinfo is the authority (cstage gates on // esubu = type_chase_named(esub) == TY_ARRAY). if (!elem_isarray) { - elem_isarray = tinfoisarray(n.type_: *tinfo); + elem_isarray = tinfoisarray(n.type_: *syntax.tinfo); }; - } else { if (base.kind == nkind.N_INDEX) { + } else { if (base.kind == syntax.nkind.N_INDEX) { // #60: chained `names[i][k]` — n.type_ is the checker- // stamped outer element tinfo (indexresult over the inner // index's value type). cstage reads base->type->sub->size @@ -2024,14 +2024,14 @@ fn cgindex(c: *cgen, n: *node) void = { // reading the SAME stamp the esz read above uses. CLASS-N: // the corpus has no chained str/slice element, so the prior // byte-id is preserved (this only fires on the missed shape). - let et: *tinfo = n.type_: *tinfo; + let et: *syntax.tinfo = n.type_: *syntax.tinfo; if (et != nil) { esz = et.size: i32; - signed_elem = typeissigned(et); - elemisstr = typeisstr(et); - elemisslice = typeisslice(et); - float_elem = typeisfloat(et); - f32_elem = typeisf32(et); + signed_elem = syntax.typeissigned(et); + elemisstr = syntax.typeisstr(et); + elemisslice = syntax.typeisslice(et); + float_elem = syntax.typeisfloat(et); + f32_elem = syntax.typeisf32(et); elem_isarray = tinfoisarray(et); }; } else { @@ -2053,8 +2053,8 @@ fn cgindex(c: *cgen, n: *node) void = { // on (signed,sz); cstage's fldloadop reads it from the element // type — align ww up, #255). The base ADDRESS materialization // below is unchanged; only the stride/load-width was wrong. - let dt: *tinfo = n.type_: *tinfo; - if (dt != nil) { esz = dt.size: i32; signed_elem = typeissigned(dt); elemisstr = typeisstr(dt); elemisslice = typeisslice(dt); float_elem = typeisfloat(dt); f32_elem = typeisf32(dt); }; + let dt: *syntax.tinfo = n.type_: *syntax.tinfo; + if (dt != nil) { esz = dt.size: i32; signed_elem = syntax.typeissigned(dt); elemisstr = syntax.typeisstr(dt); elemisslice = syntax.typeisslice(dt); float_elem = syntax.typeisfloat(dt); f32_elem = syntax.typeisf32(dt); }; elem_isarray = tinfoisarray(dt); };}; }; @@ -2066,9 +2066,9 @@ fn cgindex(c: *cgen, n: *node) void = { let elem_tagged: bool = false; let elem_slot_sz: i32 = esz; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bl: *local = baselocal; - let etn: *node = nil; + let etn: *syntax.node = nil; // idxelemtn drills `*[N]T` to the pointee array's own // element (#61) — an undrilled etn classified the whole // array, missing tagged/str/slice elements behind a @@ -2119,10 +2119,10 @@ fn cgindex(c: *cgen, n: *node) void = { // `MOVQ (AX),AX` (tag only) vs cstage's full 4-word cursor // (cs rc=50 / ww rc=40). Dropping the whitelist for the stamp read // closes the base-kind class by construction. - if (base.kind != nkind.N_IDENT) { - let dt: *tinfo = n.type_: *tinfo; + if (base.kind != syntax.nkind.N_IDENT) { + let dt: *syntax.tinfo = n.type_: *syntax.tinfo; if (dt != nil) { - if (typeistagged(dt)) { + if (syntax.typeistagged(dt)) { elem_tagged = true; elem_slot_sz = dt.size: i32; esz = elem_slot_sz; @@ -2138,11 +2138,11 @@ fn cgindex(c: *cgen, n: *node) void = { let elem_tuple: bool = false; let tuple_nwords: i32 = 0; { - let eti: *tinfo = tichase(n.type_: *tinfo); - if (eti != nil) { if (eti.kind == tykind.TY_TUPLE) { + let eti: *syntax.tinfo = tichase(n.type_: *syntax.tinfo); + if (eti != nil) { if (eti.kind == syntax.tykind.TY_TUPLE) { elem_tuple = true; // ww tuples store elements in .tupleelems, not .params. - let tpw: *ttupleelem = eti.tupleelems; + let tpw: *syntax.ttupleelem = eti.tupleelems; for (tpw != nil) { tuple_nwords += tupeslot(tpw.type_) / 8; tpw = tpw.tnext; @@ -2239,14 +2239,14 @@ fn cgindex(c: *cgen, n: *node) void = { return; }; if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; - if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; }; + if (tn != nil) { if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — LEAQ-vs-MOVQ off the chased stamped // kind (cstage u->kind == TY_ARRAY, cmd/w6c/cgen.c N_INDEX). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarray) { emitline("\tLEAQ\t"); @@ -2419,16 +2419,16 @@ fn cgindex(c: *cgen, n: *node) void = { // a GLOBAL str base (no +16 load here, #73 -- matching the cstage // carve-out keeps both stages byte-identical). cstage twin: // cmd/w6c/cgen.c cg_base_cap. -fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { +fn cgbasecap(c: *cgen, base: *syntax.node, dst: str) bool = { if (base == nil) { return false; }; - if (base.kind != nkind.N_IDENT) { return false; }; + if (base.kind != syntax.nkind.N_IDENT) { return false; }; let baselocal: *local = localfindnode(c, base.str); if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; if (tn == nil) { return false; }; - if (tn.kind == nkind.N_TARRAY) { - let lenn: *node = tn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (tn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = tn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", "); @@ -2440,8 +2440,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { // from the stamped array tinfo (rule-13), the cap twin of the // default-hi fix; pre-fix cgbasecap returned false here and the // caller fell to cap=len (cs computes base_cap-lo from bu->alen). - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", "); @@ -2451,7 +2451,7 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { }; return false; }; - if (tn.kind == nkind.N_TSLICE) { + if (tn.kind == syntax.nkind.N_TSLICE) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 16): i64); emitline("(BP), "); @@ -2459,8 +2459,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { emitline("\n"); return true; }; - if (tn.kind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { + if (tn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 16): i64); emitline("(BP), "); @@ -2471,11 +2471,11 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { }; // #60: alias-NAMED base — chased kind (cstage cg_base_cap // receives bu pre-chased by the N_SLICE arm, cgen.c:1888). - let bt60: *tinfo = base.type_: *tinfo; - if (bt60 != nil) { if (bt60.kind == tykind.TY_NAMED) { - let bu60: *tinfo = tichase(bt60); + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt60 != nil) { if (bt60.kind == syntax.tykind.TY_NAMED) { + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", "); @@ -2483,8 +2483,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { emitline("\n"); return true; }; - if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 16): i64); emitline("(BP), "); @@ -2496,11 +2496,11 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { };}; return false; }; - let gt: *node = letvartnode(c, base.str); + let gt: *syntax.node = letvartnode(c, base.str); if (gt == nil) { return false; }; - if (gt.kind == nkind.N_TARRAY) { - let lenn: *node = gt.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (gt.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = gt.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", "); @@ -2509,8 +2509,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { return true; }; // #21: def/const global array dim cap — twin of the local arm. - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", "); @@ -2520,7 +2520,7 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { }; return false; }; - if (gt.kind == nkind.N_TSLICE) { + if (gt.kind == syntax.nkind.N_TSLICE) { emitline("\tLEAQ\t"); emitsymname(c, base.str); emitline("(SB), "); @@ -2536,11 +2536,11 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { // #60: alias-NAMED global base — chased kind; global STR keeps // the #73 cap=len carve-out (cstage isglobal && TY_STR → 0). // Runtime-unreachable until #77/#78 global DATA. - let gbt60: *tinfo = base.type_: *tinfo; - if (gbt60 != nil) { if (gbt60.kind == tykind.TY_NAMED) { - let gbu60: *tinfo = tichase(gbt60); + let gbt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (gbt60 != nil) { if (gbt60.kind == syntax.tykind.TY_NAMED) { + let gbu60: *syntax.tinfo = tichase(gbt60); if (gbu60 != nil) { - if (gbu60.kind == tykind.TY_ARRAY) { + if (gbu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(gbu60.alen: i64); emitline(", "); @@ -2548,7 +2548,7 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { emitline("\n"); return true; }; - if (gbu60.kind == tykind.TY_SLICE) { + if (gbu60.kind == syntax.tykind.TY_SLICE) { emitline("\tLEAQ\t"); emitsymname(c, base.str); emitline("(SB), "); @@ -2579,45 +2579,45 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { // the COUNT by this same width, so it MUST match cgslice's ptr scaling // byte-for-byte (cgslice supplies the dst ptr). Cstage twin: the N_SLICE-LHS // arm in cgen.c N_ASSIGN reuses the read-path one-liner directly. -fn slicebaseesz(c: *cgen, base: *node) i32 = { +fn slicebaseesz(c: *cgen, base: *syntax.node) i32 = { if (base == nil) { return 1; }; let esz: i32 = 1; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bl: *local = localfindnode(c, base.str); if (bl != nil) { esz = elemsizeofc(c, bl.tnode); } else { - let gt: *node = letvartnode(c, base.str); + let gt: *syntax.node = letvartnode(c, base.str); if (gt != nil) { esz = elemsizeofc(c, gt); }; }; - let bt: *tinfo = base.type_: *tinfo; - if (bt != nil) { if (bt.kind == tykind.TY_NAMED) { - let bu60: *tinfo = tichase(bt); - let es60: *tinfo = tichase(bu60.sub); + let bt: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt != nil) { if (bt.kind == syntax.tykind.TY_NAMED) { + let bu60: *syntax.tinfo = tichase(bt); + let es60: *syntax.tinfo = tichase(bu60.sub); if (es60 != nil) { esz = es60.size: i32; }; };}; - } else { if (base.kind == nkind.N_DOT) { - let db: *tinfo = tichase(base.type_: *tinfo); + } else { if (base.kind == syntax.nkind.N_DOT) { + let db: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); if (db != nil) { if (db.sub != nil) { esz = db.sub.size: i32; }; }; - } else { if (base.kind == nkind.N_ARRLIT) { + } else { if (base.kind == syntax.nkind.N_ARRLIT) { esz = elemsizeofc(c, base.lhs); };};}; return esz; }; -fn cgslice(c: *cgen, n: *node) void = { - let base: *node = n.lhs; - let lo: *node = n.rhs; - let hi: *node = n.cond; +fn cgslice(c: *cgen, n: *syntax.node) void = { + let base: *syntax.node = n.lhs; + let lo: *syntax.node = n.rhs; + let hi: *syntax.node = n.cond; let baselocal: *local = nil; - let globaltn: *node = nil; + let globaltn: *syntax.node = nil; let globalname: str; globalname.ptr = nil; globalname.len = 0; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { baselocal = localfindnode(c, base.str); if (baselocal == nil) { - let gt: *node = letvartnode(c, base.str); + let gt: *syntax.node = letvartnode(c, base.str); if (gt != nil) { globaltn = gt; globalname = base.str; @@ -2629,9 +2629,9 @@ fn cgslice(c: *cgen, n: *node) void = { // tnode — resolve esz / default-hi / base-address from the checker- // stamped element tinfo on base.type_ instead. Cstage twin reads // base->type (cgen.c N_SLICE esz + bu->kind==TY_ARRAY default-hi). - let dotbu: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_DOT) { - dotbu = base.type_: *tinfo; + let dotbu: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_DOT) { + dotbu = base.type_: *syntax.tinfo; dotbu = tichase(dotbu); };}; // #31: an N_ARRLIT base (the desugared one-step `let xs:[]T=[..]` @@ -2641,8 +2641,8 @@ fn cgslice(c: *cgen, n: *node) void = { // count come NODE-wise (elemsizeofc / .rhs intlit), because wwstage // narrow-primitive tinfos are unsized (#8). Cstage twin reads base->type // (its Type IS sized). - let arrlittn: *node = nil; - if (base != nil) { if (base.kind == nkind.N_ARRLIT) { + let arrlittn: *syntax.node = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_ARRLIT) { arrlittn = base.lhs; };}; // #60 (alias arc #5): alias-NAMED N_IDENT base — the tnode reads @@ -2651,10 +2651,10 @@ fn cgslice(c: *cgen, n: *node) void = { // stamped tinfo, mirroring cstage N_SLICE's single // bu = type_chase_named(base->type) source (cmd/w6c/cgen.c). let basealias: bool = false; - let bu60: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; - if (bt60 != nil) { if (bt60.kind == tykind.TY_NAMED) { + let bu60: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt60 != nil) { if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; bu60 = tichase(bt60); };}; @@ -2674,18 +2674,18 @@ fn cgslice(c: *cgen, n: *node) void = { esz = elemsizeofc(c, arrlittn); };};};}; if (bu60 != nil) { - let es60: *tinfo = tichase(bu60.sub); + let es60: *syntax.tinfo = tichase(bu60.sub); if (es60 != nil) { esz = es60.size: i32; }; }; // base address if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { isarray = true; }; + if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; if (isarray) { emitline("\tLEAQ\t"); emitoff(baselocal.off: i64); @@ -2699,10 +2699,10 @@ fn cgslice(c: *cgen, n: *node) void = { // Top-level let: [N]T → LEAQ name(SB); pointer/slice/str // → MOVQ name(SB) (the symbol holds the {ptr,len,cap} or // {ptr,len} or pointer value). - let gisarr: bool = globaltn.kind == nkind.N_TARRAY; + let gisarr: bool = globaltn.kind == syntax.nkind.N_TARRAY; // #60: alias-NAMED base — chased kind; runtime-unreachable // until #77/#78 global DATA (see cgindex twin). - if (bu60 != nil) { gisarr = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { gisarr = bu60.kind == syntax.tykind.TY_ARRAY; }; if (gisarr) { emitline("\tLEAQ\t"); emitsymname(c, globalname); @@ -2712,7 +2712,7 @@ fn cgslice(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), AX\n"); }; - } else { if (base != nil && base.kind == nkind.N_ARRLIT + } else { if (base != nil && base.kind == syntax.nkind.N_ARRLIT && arrlittn != nil) { // #31: materialise the array literal into a FRESH per-borrow // @slicescr stack slot (distinct slot per borrow — a borrow's @@ -2727,7 +2727,7 @@ fn cgslice(c: *cgen, n: *node) void = { // local borrowed past its frame is a footgun, not promoted). let cnt: i32 = 0; if (arrlittn.rhs != nil) { - if (arrlittn.rhs.kind == nkind.N_INTLIT) { + if (arrlittn.rhs.kind == syntax.nkind.N_INTLIT) { cnt = arrlittn.rhs.uval: i32; }; }; @@ -2755,12 +2755,12 @@ fn cgslice(c: *cgen, n: *node) void = { if (hi != nil) { cgexpr(c, hi); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let handled: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { - let lenn: *node = tn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (tn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = tn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -2771,21 +2771,21 @@ fn cgslice(c: *cgen, n: *node) void = { // (MOVQ $0 default-hi -> len 0 / underflow, exit 255). // Read the resolved length from the stamped array // tinfo (rule-13), mirroring cstage's bu->alen. - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); handled = true; }; }; - } else { if (tn.kind == nkind.N_TSLICE) { + } else { if (tn.kind == syntax.nkind.N_TSLICE) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); handled = true; - } else { if (tn.kind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { + } else { if (tn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); @@ -2797,13 +2797,13 @@ fn cgslice(c: *cgen, n: *node) void = { // N_SLICE hi-default reads bu uniformly: TY_ARRAY → $alen, // TY_SLICE/TY_STR → len word at +8). if (!handled && bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); handled = true; - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); @@ -2813,9 +2813,9 @@ fn cgslice(c: *cgen, n: *node) void = { if (!handled) { emitline("\tMOVQ\t$0, AX\n"); }; } else { if (globaltn != nil) { let handled: bool = false; - if (globaltn.kind == nkind.N_TARRAY) { - let lenn: *node = globaltn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (globaltn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = globaltn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -2824,15 +2824,15 @@ fn cgslice(c: *cgen, n: *node) void = { // #21: a def/const global array dim — non-N_INTLIT, read the // resolved length off the stamped array tinfo (rule-13), the // twin of the local arm above (cstage's bu->alen). - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); handled = true; }; }; - } else { if (globaltn.kind == nkind.N_TSLICE) { + } else { if (globaltn.kind == syntax.nkind.N_TSLICE) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -2843,13 +2843,13 @@ fn cgslice(c: *cgen, n: *node) void = { // runtime-unreachable until #77/#78 global DATA (cstage // emits LEAQ+8 for global SLICE/STR alike). if (!handled && bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); handled = true; - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -2858,7 +2858,7 @@ fn cgslice(c: *cgen, n: *node) void = { };}; }; if (!handled) { emitline("\tMOVQ\t$0, AX\n"); }; - } else { if (dotbu != nil && dotbu.kind == tykind.TY_ARRAY) { + } else { if (dotbu != nil && dotbu.kind == syntax.tykind.TY_ARRAY) { // #252: default-hi `s.obuf[lo:]` on a struct array-field → // element count from the field's array tinfo. Cstage twin // cgexpr_int(bu->alen) (cgen.c N_SLICE default-hi). @@ -2870,7 +2870,7 @@ fn cgslice(c: *cgen, n: *node) void = { // stashed [count]T tnode's .rhs intlit). let hc: i64 = 0i64; if (arrlittn.rhs != nil) { - if (arrlittn.rhs.kind == nkind.N_INTLIT) { + if (arrlittn.rhs.kind == syntax.nkind.N_INTLIT) { hc = arrlittn.rhs.uval: i64; }; }; @@ -2904,7 +2904,7 @@ fn cgslice(c: *cgen, n: *node) void = { }; }; -fn cgmatch(c: *cgen, n: *node) void = { +fn cgmatch(c: *cgen, n: *syntax.node) void = { // match (e) { case let v: T => stmt; ... } // // Read the tagged-union slot and dispatch by tag. Slot @@ -2912,11 +2912,11 @@ fn cgmatch(c: *cgen, n: *node) void = { // (`case let v: T =>`) get a fresh local slot loaded from // slot+8 (and slot+16 for str-typed payload). // Family C (#35): identity-cast peel — see the cgtypetest twin. - let scrut: *node = taggedidcastpeel(c, n.lhs); + let scrut: *syntax.node = taggedidcastpeel(c, n.lhs); let scrutoff: i32 = 0; - let scrutt: *node = nil; + let scrutt: *syntax.node = nil; if (scrut != nil) { - if (scrut.kind == nkind.N_IDENT) { + if (scrut.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, scrut.str); if (lc != nil) { scrutoff = lc.off; @@ -2928,7 +2928,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // saved BP as the tag (garbage). The PLAIN-tagged twin // of cstage #78 SB-resolution: LEAQ the address, copy // the box into an @match_spill slot indexed off BP. - let gtt: *node = resolvetagged(c, letvartnode(c, scrut.str)); + let gtt: *syntax.node = resolvetagged(c, letvartnode(c, scrut.str)); if (gtt != nil && !isnullabletype(gtt)) { scrutt = gtt; let gspill: i32 = matchspillsz(c, gtt); @@ -2969,15 +2969,15 @@ fn cgmatch(c: *cgen, n: *node) void = { // spill `else`, which resolves g(SB). align-DOWN to cstage // (rule 10): both stages emit TEXT $32 on the local-field // case and the same g(SB) spill on the global-field case. - let mfld: *tfield = nil; - if (scrut.kind == nkind.N_DOT && scrut.lhs != nil - && scrut.lhs.kind == nkind.N_IDENT + let mfld: *syntax.tfield = nil; + if (scrut.kind == syntax.nkind.N_DOT && scrut.lhs != nil + && scrut.lhs.kind == syntax.nkind.N_IDENT && scrut.lhs.type_ != nil) { - let bu: *tinfo = tichase(scrut.lhs.type_: *tinfo); - if (bu != nil && bu.kind == tykind.TY_STRUCT) { - let fl: *tfield = bu.fields; + let bu: *syntax.tinfo = tichase(scrut.lhs.type_: *syntax.tinfo); + if (bu != nil && bu.kind == syntax.tykind.TY_STRUCT) { + let fl: *syntax.tfield = bu.fields; for (fl != nil) { - if (streq(fl.name, scrut.str)) { + if (syntax.streq(fl.name, scrut.str)) { mfld = fl; break; }; @@ -3014,7 +3014,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // binds already read the slot from memory. Mirrors // cstage cgen.c N_MATCH. let msret: i32 = 0; - if (scrut.kind == nkind.N_CALL) { + if (scrut.kind == syntax.nkind.N_CALL) { msret = callsretsize(c, scrut); }; if (msret > 0) { @@ -3052,9 +3052,9 @@ fn cgmatch(c: *cgen, n: *node) void = { // stamped s->type, so it louds — key on scrut.type_ // to match. Surfaced by reviewer-37's `match (*p)` // probe on a 56B box. - let ms37: *tinfo = scrut.type_: *tinfo; + let ms37: *syntax.tinfo = scrut.type_: *syntax.tinfo; ms37 = tichase(ms37); - if (ms37 != nil && ms37.kind == tykind.TY_TAGGED + if (ms37 != nil && ms37.kind == syntax.tykind.TY_TAGGED && ms37.size: i32 > TUPLE_GPCAP * 8) { let m37n: str = "#37: >32B tagged match scrutinee from a non-mem-based source unwired (rule 7)\n"; os.write(2, m37n.ptr, m37n.len: u64); @@ -3063,8 +3063,8 @@ fn cgmatch(c: *cgen, n: *node) void = { // Family C catch-all (rule 7): a widening tagged // cast scrutinee has no cursor — loud. Mirrors // cstage cgmatch. - if (scrut.kind == nkind.N_CAST && ms37 != nil - && ms37.kind == tykind.TY_TAGGED + if (scrut.kind == syntax.nkind.N_CAST && ms37 != nil + && ms37.kind == syntax.tykind.TY_TAGGED && ms37.nullable == 0) { let m35m: str = "#35: tagged cast source shape unwired at match (rule 7)\n"; os.write(2, m35m.ptr, m35m.len: u64); @@ -3104,10 +3104,10 @@ fn cgmatch(c: *cgen, n: *node) void = { c.yieldbuf[c.yieldtop] = endl; c.yieldtop += 1; }; - let cs: *node = n.list; + let cs: *syntax.node = n.list; for (cs != nil) { let nxt: str = mklabel(c, "match_next"); - let pat: *node = cs.lhs; + let pat: *syntax.node = cs.lhs; let nullable: bool = isnullabletype(scrutt); // Per-arm scope: save c.locals before allocating the bind // and restore after the body runs, so the arm's bind (and @@ -3126,7 +3126,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // void arm: skip if ptr != 0. let ptr_tag: i32 = nullableptrtag(scrutt); let cur_tag: i32 = 0; - if (pat.kind == nkind.N_TPTR) { cur_tag = ptr_tag; } + if (pat.kind == syntax.nkind.N_TPTR) { cur_tag = ptr_tag; } else { if (ptr_tag == 0) { cur_tag = 1; }; }; emitline("\tMOVQ\t"); emitoff(scrutoff: i64); @@ -3148,7 +3148,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // rather than the resolved N_TTAGGED node. if (istaggedtype(c, scrutt)) { let r: i32 = -1; - let pattype: *tinfo = pat.type_: *tinfo; + let pattype: *syntax.tinfo = pat.type_: *syntax.tinfo; if (pattype != nil) { // #179: kind-agnostic dispatch on the resolved // tinfo. Cstage cg_tag_for_variant works on @@ -3158,10 +3158,10 @@ fn cgmatch(c: *cgen, n: *node) void = { // Slice arm still goes through flatslicevariantidx // (task #19 untyped-elem fallback when typeeq // can't match a (scalar | []T) shape). - if (typeisslice(pattype)) { + if (syntax.typeisslice(pattype)) { r = flatslicevariantidx(c, scrutt, pat.lhs); } else { - r = flatvariantidxt(scrutt.type_: *tinfo, pattype, false); + r = flatvariantidxt(scrutt.type_: *syntax.tinfo, pattype, false); }; }; if (r >= 0) { want = r; }; @@ -3186,7 +3186,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // Bind the pointer (or skip for the // void arm, which has zero-size). The // value IS slot+0. - if (pat.kind == nkind.N_TPTR) { + if (pat.kind == syntax.nkind.N_TPTR) { let voff: i32 = localalloc(c, bn, 8, pat); emitline("\tMOVQ\t"); emitoff(scrutoff: i64); @@ -3248,8 +3248,8 @@ fn cgmatch(c: *cgen, n: *node) void = { return; }; -fn cgdot(c: *cgen, n: *node) void = { - let lhs: *node = n.lhs; +fn cgdot(c: *cgen, n: *syntax.node) void = { + let lhs: *syntax.node = n.lhs; let fld: str = n.str; // `(*p).f` read retarget: parser produces n.lhs = N_UN(STAR, // IDENT(p)). Substitute the inner IDENT as dotlhs so the @@ -3259,12 +3259,12 @@ fn cgdot(c: *cgen, n: *node) void = { // (*expr).f follow-up task pending. Enum-leaf lookup above and // chained-N_DOT branches below keep checking raw lhs since // (*p) is neither shape. - let dotlhs: *node = lhs; + let dotlhs: *syntax.node = lhs; if (dotlhs != nil) { - if (dotlhs.kind == nkind.N_UN) { - if (dotlhs.op == tkind.TK_STAR) { + if (dotlhs.kind == syntax.nkind.N_UN) { + if (dotlhs.op == syntax.tkind.TK_STAR) { if (dotlhs.lhs != nil) { - if (dotlhs.lhs.kind == nkind.N_IDENT) { + if (dotlhs.lhs.kind == syntax.nkind.N_IDENT) { dotlhs = dotlhs.lhs; }; }; @@ -3281,12 +3281,12 @@ fn cgdot(c: *cgen, n: *node) void = { let etmod: str; etname.ptr = nil; etname.len = 0; etmod.ptr = nil; etmod.len = 0; - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { etname = lhs.str; }; - if (lhs.kind == nkind.N_DOT) { + if (lhs.kind == syntax.nkind.N_DOT) { if (lhs.lhs != nil) { - if (lhs.lhs.kind == nkind.N_IDENT) { + if (lhs.lhs.kind == syntax.nkind.N_IDENT) { etname = lhs.str; etmod = lhs.lhs.str; }; @@ -3306,11 +3306,11 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (dotlhs != nil) { - if (dotlhs.kind == nkind.N_IDENT) { + if (dotlhs.kind == syntax.nkind.N_IDENT) { let nm: str = dotlhs.str; let lc: *local = localfindnode(c, nm); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; // Receiver is a NAMED alias chain — peel via aliaslookup // until tn exposes a non-N_TNAME kind (or a struct alias). // Without this, `type vs = *vt` leaves lkind == N_TNAME and @@ -3337,9 +3337,9 @@ fn cgdot(c: *cgen, n: *node) void = { // any-module heuristic. The broader cross-module same-leaf // STRUCT name-keying at the direct-struct arm below is // filed separately as #224 (not FLIP-triggered). - for (tn != nil && tn.kind == nkind.N_TNAME) { + for (tn != nil && tn.kind == syntax.nkind.N_TNAME) { if (structsamemod(c, tn.str) != nil) { break; }; - let nx: *node = aliassamemod(c, tn.str); + let nx: *syntax.node = aliassamemod(c, tn.str); if (nx == nil) { if (structlookup(c, tn.str) != nil) { break; }; nx = aliaslookup(c, tn.str); @@ -3348,14 +3348,14 @@ fn cgdot(c: *cgen, n: *node) void = { tn = nx; }; if (tn == nil) { return; }; - let lkind: nkind = tn.kind; + let lkind: syntax.nkind = tn.kind; // Pointer-to-struct: deref then field load. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; let sname: str; sname.ptr = nil; sname.len = 0; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; @@ -3369,7 +3369,7 @@ fn cgdot(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // tagged-union field via *struct: stage // the *struct in BX, then load the four // payload regs via cgloadtaggedfield. @@ -3438,7 +3438,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; // Direct struct local: field load at off+foff. - if (lkind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { // structlookupchain walks the alias chain on // miss so a transitively-aliased struct (`type // b = a; a = struct`) still resolves to the @@ -3448,7 +3448,7 @@ fn cgdot(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // tagged-union field: emit the AX=tag, // DX=word0, CX=word1[, R8=word2] load // sequence so the match / let-init / @@ -3506,17 +3506,17 @@ fn cgdot(c: *cgen, n: *node) void = { // Array pseudo-fields: `.ptr` is the array's // address (LEAQ); `.len` is the static element // count (immediate). - if (lkind == nkind.N_TARRAY) { - if (streq(fld, "ptr")) { + if (lkind == syntax.nkind.N_TARRAY) { + if (syntax.streq(fld, "ptr")) { emitline("\tLEAQ\t"); emitoff(lc.off: i64); emitline("(BP), AX\n"); return; }; - if (streq(fld, "len")) { - let lenn: *node = tn.rhs; + if (syntax.streq(fld, "len")) { + let lenn: *syntax.node = tn.rhs; let alen: i64 = 0i64; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i64; } else { // #56: def/const dim — resolve from the @@ -3525,8 +3525,8 @@ fn cgdot(c: *cgen, n: *node) void = { // node is an N_IDENT(def), not N_INTLIT, so // the literal read above defaults 0; cstage // reads the resolved bu->alen. - let abt: *tinfo = tichase(tn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(tn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i64; }; }; @@ -3545,10 +3545,10 @@ fn cgdot(c: *cgen, n: *node) void = { // sibling here, so the triple is hand-authored; base is // BP (frame, not a target reg) so ptr/len/cap order has // no clobber risk. - if (lkind == nkind.N_TTUPLE) { + if (lkind == syntax.nkind.N_TTUPLE) { let idx: i32 = fldnumidx(fld); if (idx >= 0) { - let tp: *node = tn.list; + let tp: *syntax.node = tn.list; let foff: i32 = 0; let i: i32 = 0; for (i < idx) { @@ -3562,7 +3562,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (tp != nil) { - let tpt: *node = tp.lhs; + let tpt: *syntax.node = tp.lhs; // str IS []u8, and a slice is the same 24B // {ptr,len,cap} header — load all three words // into (AX, BX, CX). #28: pre-fix the gate was @@ -3635,7 +3635,7 @@ fn cgdot(c: *cgen, n: *node) void = { // byte-id twin of cstage's fldloadop // in the N_DOT TY_TUPLE arm. let nsz: i32 = 8; - let tpti: *tinfo = tpt.type_: *tinfo; + let tpti: *syntax.tinfo = tpt.type_: *syntax.tinfo; if (tpti != nil) { nsz = tpti.size: i32; }; let op: str = tnodeloadop(c, tpt, nsz); emitline("\t"); @@ -3650,22 +3650,22 @@ fn cgdot(c: *cgen, n: *node) void = { // str/slice pseudo-fields .ptr/.len/.cap on a // direct local: load at slot+delta. let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { // Pointer to str/slice (`*[]u8`, `*str`): // deref, then load at delta within the // pointed-to header. C cgen does the same. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; - let innerkind: nkind = nkind.N_NONE; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; + let innerkind: syntax.nkind = syntax.nkind.N_NONE; if (inner != nil) { innerkind = inner.kind; }; let innerstr: bool = false; - if (innerkind == nkind.N_TNAME) { - if (streq(inner.str, "str")) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TNAME) { + if (syntax.streq(inner.str, "str")) { innerstr = true; }; }; - if (innerkind == nkind.N_TSLICE) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TSLICE) { innerstr = true; }; if (innerstr) { emitline("\tMOVQ\t"); emitoff(lc.off: i64); @@ -3690,19 +3690,19 @@ fn cgdot(c: *cgen, n: *node) void = { // `MOVQ (SB), AX` (looking up the field name as a // symbol). Mirrors cmd/w6c/cgen.c nkind.N_DOT off==0 / Sdef branch. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - let drhs: *node = deflookuprhs(c, lhs.str); + if (lhs.kind == syntax.nkind.N_IDENT) { + let drhs: *syntax.node = deflookuprhs(c, lhs.str); if (drhs != nil) { - if (drhs.kind == nkind.N_STRLIT) { + if (drhs.kind == syntax.nkind.N_STRLIT) { let bytes: str = drhs.str; - if (streq(fld, "ptr")) { + if (syntax.streq(fld, "ptr")) { let lab: str = internstrlit(c, bytes); emitline("\tLEAQ\t"); emitbytes( lab.ptr, lab.len: u64); emitline("(SB), AX\n"); return; }; - if (streq(fld, "len")) { + if (syntax.streq(fld, "len")) { emitline("\tMOVQ\t$"); emitint(bytes.len: i64); emitline(", AX\n"); @@ -3717,17 +3717,17 @@ fn cgdot(c: *cgen, n: *node) void = { // delta(CX), AX. Without this the module-qualified fallback // below would mis-emit `MOVQ (SB), AX`. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { if (isletvar(c, lhs.str)) { let isstr: bool = letvarisstr(c, lhs.str); let issl: bool = letvarisslice(c, lhs.str); if (isstr || issl) { let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; // str IS []u8: .cap is valid on a str global too, // not slice-only — mirrors cstage (#1/Phase 3, #11). - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); @@ -3749,27 +3749,27 @@ fn cgdot(c: *cgen, n: *node) void = { // reference to len). Mirror of the local-array arm above and cstage // cg_base_cap's `aimm(bu->alen)` immediate (cgen.c:1692). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - let gtn: *node = letvartnode(c, lhs.str); + if (lhs.kind == syntax.nkind.N_IDENT) { + let gtn: *syntax.node = letvartnode(c, lhs.str); if (gtn != nil) { - if (gtn.kind == nkind.N_TARRAY) { - if (streq(fld, "ptr")) { + if (gtn.kind == syntax.nkind.N_TARRAY) { + if (syntax.streq(fld, "ptr")) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), AX\n"); return; }; - if (streq(fld, "len")) { - let lenn: *node = gtn.rhs; + if (syntax.streq(fld, "len")) { + let lenn: *syntax.node = gtn.rhs; let alen: i64 = 0i64; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i64; } else { // #56: def/const dim on a let-global array — // resolve from the stamped array tinfo // (rule-13), twin of the local arm above. - let abt: *tinfo = tichase(gtn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(gtn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i64; }; }; @@ -3794,11 +3794,11 @@ fn cgdot(c: *cgen, n: *node) void = { // so both stages byte-id). `.cap` stays unmirrored — arrays have no // .cap (both checkers reject, task GAP-A.cap). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - if (streq(fld, "ptr")) { - let dtn: *node = defvartnode(c, lhs.str); + if (lhs.kind == syntax.nkind.N_IDENT) { + if (syntax.streq(fld, "ptr")) { + let dtn: *syntax.node = defvartnode(c, lhs.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { + if (dtn.kind == syntax.nkind.N_TARRAY) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), AX\n"); @@ -3806,20 +3806,20 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; }; - if (streq(fld, "len")) { - let dtn: *node = defvartnode(c, lhs.str); + if (syntax.streq(fld, "len")) { + let dtn: *syntax.node = defvartnode(c, lhs.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { - let lenn: *node = dtn.rhs; + if (dtn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = dtn.rhs; let alen: i64 = 0i64; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i64; } else { // #56: def/const dim on a def array — // resolve from the stamped array tinfo // (rule-13), twin of the let-global arm above. - let abt: *tinfo = tichase(dtn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(dtn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i64; }; }; @@ -3840,16 +3840,16 @@ fn cgdot(c: *cgen, n: *node) void = { // DATA) and the module-leaf fallback mis-emitted the field index // as a symbol (`MOVQ 0(SB), AX`). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - let gtt: *node = letvartnode(c, lhs.str); - for (gtt != nil && gtt.kind == nkind.N_TNAME) { + if (lhs.kind == syntax.nkind.N_IDENT) { + let gtt: *syntax.node = letvartnode(c, lhs.str); + for (gtt != nil && gtt.kind == syntax.nkind.N_TNAME) { gtt = aliaslookup(c, gtt.str); }; if (gtt != nil) { - if (gtt.kind == nkind.N_TTUPLE) { + if (gtt.kind == syntax.nkind.N_TTUPLE) { let gidx: i32 = fldnumidx(fld); if (gidx >= 0) { - let gtp: *node = gtt.list; + let gtp: *syntax.node = gtt.list; let gfoff: i32 = 0; let gi: i32 = 0; for (gi < gidx) { @@ -3863,7 +3863,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (gtp != nil) { - let gpt: *node = gtp.lhs; + let gpt: *syntax.node = gtp.lhs; emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), CX\n"); @@ -3892,7 +3892,7 @@ fn cgdot(c: *cgen, n: *node) void = { return; }; let gnsz: i32 = 8; - let gpti: *tinfo = gpt.type_: *tinfo; + let gpti: *syntax.tinfo = gpt.type_: *syntax.tinfo; if (gpti != nil) { gnsz = gpti.size: i32; }; let gop: str = tnodeloadop(c, gpt, gnsz); emitline("\t"); @@ -3917,13 +3917,13 @@ fn cgdot(c: *cgen, n: *node) void = { // fell through to the integer-let MOVQ catch-all (reading garbage // from the wrong offset). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let si: *structinfo = letvarstructinfo(c, lhs.str); if (si == nil) { si = defvarstructinfo(c, lhs.str); }; if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), CX\n"); @@ -3995,41 +3995,41 @@ fn cgdot(c: *cgen, n: *node) void = { // Mirrors cstage cgen.c case N_DOT N_INDEX-lhs arm 1:1; #209/#211 // name-keyed→tinfo-SSoT cluster. if (lhs != nil) { - if (lhs.kind == nkind.N_INDEX) { - let idxbase: *node = lhs.lhs; - if (idxbase != nil) { if (idxbase.kind == nkind.N_IDENT) { - let elemt: *tinfo = lhs.type_: *tinfo; - let elemu: *tinfo = elemt; + if (lhs.kind == syntax.nkind.N_INDEX) { + let idxbase: *syntax.node = lhs.lhs; + if (idxbase != nil) { if (idxbase.kind == syntax.nkind.N_IDENT) { + let elemt: *syntax.tinfo = lhs.type_: *syntax.tinfo; + let elemu: *syntax.tinfo = elemt; elemu = tichase(elemu); - let st: *tinfo = nil; + let st: *syntax.tinfo = nil; let viaptr: bool = false; if (elemu != nil) { - if (elemu.kind == tykind.TY_PTR) { - let pin: *tinfo = elemu.sub; + if (elemu.kind == syntax.tykind.TY_PTR) { + let pin: *syntax.tinfo = elemu.sub; pin = tichase(pin); - if (pin != nil) { if (pin.kind == tykind.TY_STRUCT) { + if (pin != nil) { if (pin.kind == syntax.tykind.TY_STRUCT) { st = pin; viaptr = true; };}; - } else { if (elemu.kind == tykind.TY_STRUCT) { + } else { if (elemu.kind == syntax.tykind.TY_STRUCT) { st = elemu; };}; }; if (st != nil) { - let fnd: *tfield = nil; - let fwalk: *tfield = st.fields; + let fnd: *syntax.tfield = nil; + let fwalk: *syntax.tfield = st.fields; for (fwalk != nil) { - if (streq(fwalk.name, fld)) { fnd = fwalk; break; }; + if (syntax.streq(fwalk.name, fld)) { fnd = fwalk; break; }; fwalk = fwalk.tnext; }; - let bu: *tinfo = idxbase.type_: *tinfo; + let bu: *syntax.tinfo = idxbase.type_: *syntax.tinfo; bu = tichase(bu); let baseisarray: bool = false; let baseok: bool = false; if (bu != nil) { - if (bu.kind == tykind.TY_ARRAY) { baseisarray = true; baseok = true; }; - if (bu.kind == tykind.TY_SLICE) { baseok = true; }; - if (bu.kind == tykind.TY_PTR) { baseok = true; }; + if (bu.kind == syntax.tykind.TY_ARRAY) { baseisarray = true; baseok = true; }; + if (bu.kind == syntax.tykind.TY_SLICE) { baseok = true; }; + if (bu.kind == syntax.tykind.TY_PTR) { baseok = true; }; }; let lc: *local = localfindnode(c, idxbase.str); // #21 (READ twin of #11): a module-GLOBAL base makes @@ -4047,9 +4047,9 @@ fn cgdot(c: *cgen, n: *node) void = { if (isletvar(c, idxbase.str)) { isglobal = true; } else { - let dtn: *node = defvartnode(c, idxbase.str); + let dtn: *syntax.node = defvartnode(c, idxbase.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { isglobal = true; }; + if (dtn.kind == syntax.nkind.N_TARRAY) { isglobal = true; }; }; }; }; @@ -4090,8 +4090,8 @@ fn cgdot(c: *cgen, n: *node) void = { emitline("\tMOVQ\tBX, AX\n"); }; let foff: i64 = fnd.offset: i64; - let ft: *tinfo = fnd.type_; - let fu: *tinfo = ft; + let ft: *syntax.tinfo = fnd.type_; + let fu: *syntax.tinfo = ft; fu = tichase(fu); // #270-1a: an `[N]T`-typed field of an // array element (`a[i].m[j]`) — leave the @@ -4103,7 +4103,7 @@ fn cgdot(c: *cgen, n: *node) void = { // field fell to the scalar load below and loaded // its first 8 bytes as a value → garbage // base → SEGFAULT in the outer index. - if (fu != nil && fu.kind == tykind.TY_ARRAY) { + if (fu != nil && fu.kind == syntax.tykind.TY_ARRAY) { if (foff != 0) { emitline("\tADDQ\t$"); emitint(foff); @@ -4111,8 +4111,8 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - if (fu != nil && (fu.kind == tykind.TY_STR - || fu.kind == tykind.TY_SLICE)) { + if (fu != nil && (fu.kind == syntax.tykind.TY_STR + || fu.kind == syntax.tykind.TY_SLICE)) { // str/slice: the 3-word {ptr,len,cap} // slice header (#1). AX holds the // element base, so load .ptr (which @@ -4130,9 +4130,9 @@ fn cgdot(c: *cgen, n: *node) void = { emitline(", AX\n"); return; }; - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); @@ -4162,7 +4162,7 @@ fn cgdot(c: *cgen, n: *node) void = { // #114 wires it, that commit replaces this with // the LEAQ box-address emission + a >32B value // pin row. Mirrors cstage cgen.c. - if (fu != nil && fu.kind == tykind.TY_TAGGED) { + if (fu != nil && fu.kind == syntax.tykind.TY_TAGGED) { let bsz: i32 = fu.size: i32; if (bsz > TUPLE_GPCAP * 8) { let m58r: str = "#58: >32B tagged-field indexed read unreachable until #114\n"; @@ -4191,7 +4191,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; let fsz: i32 = 8; if (ft != nil) { fsz = ft.size: i32; }; - let lop: str = loadopsz(typeissigned(ft), fsz); + let lop: str = loadopsz(syntax.typeissigned(ft), fsz); emitline("\t"); emitline(lop); emitline("\t"); @@ -4213,16 +4213,16 @@ fn cgdot(c: *cgen, n: *node) void = { // scalar loadopsz. Narrow (rob Q3): tagged / nested-aggregate // fields stay LOUD. Mirrors cstage cgen.c leg-(a) arm 1:1. if (lhs != nil) { - if (lhs.kind == nkind.N_INDEX) { - let eu: *tinfo = tichase(lhs.type_: *tinfo); - if (eu != nil) { if (eu.kind == tykind.TY_TUPLE) { + if (lhs.kind == syntax.nkind.N_INDEX) { + let eu: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); + if (eu != nil) { if (eu.kind == syntax.tykind.TY_TUPLE) { let idx: i32 = fldnumidx(fld); if (idx >= 0) { // ww tuples store elements in .tupleelems // (ttupleelem chain), NOT .params (that is // fn-only). foff via tupeslot accumulation = // cstage tuple_eslot, byte-id. - let tp: *ttupleelem = eu.tupleelems; + let tp: *syntax.ttupleelem = eu.tupleelems; let foff: i32 = 0; let i: i32 = 0; for (i < idx) { @@ -4234,12 +4234,12 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (tp != nil) { - let ft: *tinfo = tp.type_; - let fu: *tinfo = tichase(ft); - if (fu != nil && (fu.kind == tykind.TY_TAGGED - || fu.kind == tykind.TY_STRUCT - || fu.kind == tykind.TY_TUPLE - || fu.kind == tykind.TY_ARRAY)) { + let ft: *syntax.tinfo = tp.type_; + let fu: *syntax.tinfo = tichase(ft); + if (fu != nil && (fu.kind == syntax.tykind.TY_TAGGED + || fu.kind == syntax.tykind.TY_STRUCT + || fu.kind == syntax.tykind.TY_TUPLE + || fu.kind == syntax.tykind.TY_ARRAY)) { let mt: str = "#121: aggregate/tagged tuple-element field read off an indexed base unwired\n"; os.write(2, mt.ptr, mt.len: u64); os.exit(1); @@ -4250,9 +4250,9 @@ fn cgdot(c: *cgen, n: *node) void = { os.exit(1); }; emitline("\tMOVQ\tBX, AX\n"); - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); @@ -4260,8 +4260,8 @@ fn cgdot(c: *cgen, n: *node) void = { emitline(", X0\n"); return; }; - if (fu != nil && (fu.kind == tykind.TY_STR - || fu.kind == tykind.TY_SLICE)) { + if (fu != nil && (fu.kind == syntax.tykind.TY_STR + || fu.kind == syntax.tykind.TY_SLICE)) { emitline("\tMOVQ\t"); emitdispreg((foff + 8): i64, "AX"); emitline(", BX\n"); @@ -4275,7 +4275,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; let fsz: i32 = 8; if (ft != nil) { fsz = ft.size: i32; }; - let lop: str = loadopsz(typeissigned(ft), fsz); + let lop: str = loadopsz(syntax.typeissigned(ft), fsz); emitline("\t"); emitline(lop); emitline("\t"); @@ -4294,7 +4294,7 @@ fn cgdot(c: *cgen, n: *node) void = { // prior narrow deref-store doesn't leave stale upper bytes. Same // fallback the C cgen takes when bt is NULL/tyerr. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { // `let p = mod.fn` — fn rvalue via N_DOT. Mirror of // cstage cgdot's TY_FN branch (mafn with module hint). // Without this the MOVQ leaf(SB) fallback below would @@ -4303,7 +4303,7 @@ fn cgdot(c: *cgen, n: *node) void = { // lhs.str is the explicit module hint so a same-leaf // def in another module (head of c.fnrets) can't shadow // the explicit qualifier (#17 N_DOT-arm omission audit). - let frt: *node = fnretlookupmod(c, fld, usehint(c, lhs.str)); + let frt: *syntax.node = fnretlookupmod(c, fld, usehint(c, lhs.str)); if (frt != nil) { emitline("\tLEAQ\t"); emitfnname(c, fld, usehint(c, lhs.str)); @@ -4318,9 +4318,9 @@ fn cgdot(c: *cgen, n: *node) void = { // the explicit module hint — a 3rd-module qualifier // `alpha.MSG` from gamma needs alpha (not c.curmod) // to beat a head-of-c.defs beta.MSG collision (#11). - let drhs: *node = deflookuprhsmod(c, fld, usehint(c, lhs.str)); + let drhs: *syntax.node = deflookuprhsmod(c, fld, usehint(c, lhs.str)); if (drhs != nil) { - if (drhs.kind == nkind.N_STRLIT) { + if (drhs.kind == syntax.nkind.N_STRLIT) { let bytes: str = drhs.str; let lab: str = internstrlit(c, bytes); emitline("\tLEAQ\t"); @@ -4337,7 +4337,7 @@ fn cgdot(c: *cgen, n: *node) void = { // — the non-preferring emitsymname mis-mangled `aa.v` onto // a same-leaf global. The TY_FN branch above already // threads lhs.str via emitfnname. - if (streq(mqop, "MOVQ")) { + if (syntax.streq(mqop, "MOVQ")) { emitline("\tMOVQ\t"); emitfnname(c, fld, usehint(c, lhs.str)); emitline("(SB), AX\n"); @@ -4363,11 +4363,11 @@ fn cgdot(c: *cgen, n: *node) void = { // (loading only .ptr into AX) and shuffle stale BX into AX. // Placed BEFORE the .ptr/.len fast paths so the chain wins. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { + if (lhs.kind == syntax.nkind.N_DOT) { let rootname: str = ""; let rootoff: i32 = 0; let totaloff: i32 = 0; - let leaftype: *tinfo = nil; + let leaftype: *syntax.tinfo = nil; let slicedelta: i32 = -1; let isglobal: bool = false; let ptrroot: bool = false; @@ -4410,8 +4410,8 @@ fn cgdot(c: *cgen, n: *node) void = { // ONE word (the tag): is-tests passed by tag-luck // while as/match/let consumers read stale payload // registers (ken x5c: o.r.min as size added DX). - if (typeistagged(leaftype)) { - let tlu: *tinfo = leaftype; + if (syntax.typeistagged(leaftype)) { + let tlu: *syntax.tinfo = leaftype; tlu = tichase(tlu); let ttsz: i32 = tlu.size: i32; if (viacx) { @@ -4431,7 +4431,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - if (typeisstr(leaftype) || typeisslice(leaftype)) { + if (syntax.typeisstr(leaftype) || syntax.typeisslice(leaftype)) { // str/slice leaf: load all three header words into // (AX=ptr, BX=len, CX=cap). str IS []u8 — the same 24B // {ptr,len,cap} header. #29: the str leaf used to load @@ -4474,9 +4474,9 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - if (typeisfloat(leaftype)) { + if (syntax.typeisfloat(leaftype)) { let mov: str = "MOVSD"; - if (typeisf32(leaftype)) { mov = "MOVSS"; }; + if (syntax.typeisf32(leaftype)) { mov = "MOVSS"; }; if (viacx) { if (ptrroot) { emitline("\tMOVQ\t"); @@ -4501,7 +4501,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - let lop: str = loadopsz(typeissigned(leaftype), + let lop: str = loadopsz(syntax.typeissigned(leaftype), leaftype.slotsize: i32); if (viacx) { if (ptrroot) { @@ -4541,21 +4541,21 @@ fn cgdot(c: *cgen, n: *node) void = { // NAME behind a non-ident spine took the offset-blind cgexpr path // while cstage (type-gated) routes it to the read-resolver. { - let pbu: *tinfo = nil; - if (lhs != nil) { pbu = lhs.type_: *tinfo; }; + let pbu: *syntax.tinfo = nil; + if (lhs != nil) { pbu = lhs.type_: *syntax.tinfo; }; pbu = tichase(pbu); let pbok: bool = false; if (pbu != nil) { - if (pbu.kind == tykind.TY_SLICE - || pbu.kind == tykind.TY_STR - || pbu.kind == tykind.TY_UNTYPED_STR) { pbok = true; }; + if (pbu.kind == syntax.tykind.TY_SLICE + || pbu.kind == syntax.tykind.TY_STR + || pbu.kind == syntax.tykind.TY_UNTYPED_STR) { pbok = true; }; }; if (lhs != nil) { - if (lhs.kind == nkind.N_STRLIT) { pbok = true; }; + if (lhs.kind == syntax.nkind.N_STRLIT) { pbok = true; }; }; if (pbok) { - if (streq(fld, "ptr")) { cgexpr(c, lhs); return; }; - if (streq(fld, "len")) { + if (syntax.streq(fld, "ptr")) { cgexpr(c, lhs); return; }; + if (syntax.streq(fld, "len")) { cgexpr(c, lhs); emitline("\tMOVQ\tBX, AX\n"); return; @@ -4575,11 +4575,11 @@ fn cgdot(c: *cgen, n: *node) void = { // alone would wrongly fire. The N_STRLIT exclusion keeps // this byte-identical with cstage. #13 read-fix, sibling // of the #20 store. - if (streq(fld, "cap")) { + if (syntax.streq(fld, "cap")) { cgexpr(c, lhs); - if (lhs != nil && lhs.kind != nkind.N_STRLIT) { - if (pbu != nil && (pbu.kind == tykind.TY_SLICE - || pbu.kind == tykind.TY_STR)) { + if (lhs != nil && lhs.kind != syntax.nkind.N_STRLIT) { + if (pbu != nil && (pbu.kind == syntax.tykind.TY_SLICE + || pbu.kind == syntax.tykind.TY_STR)) { emitline("\tMOVQ\tCX, AX\n"); }; }; @@ -4596,7 +4596,7 @@ fn cgdot(c: *cgen, n: *node) void = { // itself, so reads silently get the pointer value instead of // the field. (Showed up porting w6l/pass.ww.) if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { + if (lhs.kind == syntax.nkind.N_DOT) { // #70 (#12): inner-struct layout via the stamped lhs.type_ // (peel *→struct) + tinfo.fields, replacing dotinnerstructptr's // structinfo walk. Gate is strict-equal to the deleted helper: @@ -4608,34 +4608,34 @@ fn cgdot(c: *cgen, n: *node) void = { // wanted, is a future task with its own probe. Global-root // chains stay in their pre-existing shared base-eval breakage // (filed #27), untouched here. - let croot: *node = lhs; + let croot: *syntax.node = lhs; let allptr: bool = true; - for (croot != nil && croot.kind == nkind.N_DOT) { - let ct: *tinfo = croot.type_: *tinfo; + for (croot != nil && croot.kind == syntax.nkind.N_DOT) { + let ct: *syntax.tinfo = croot.type_: *syntax.tinfo; ct = tichase(ct); let okp: bool = false; - if (ct != nil) { if (ct.kind == tykind.TY_PTR) { - let cs: *tinfo = ct.sub; + if (ct != nil) { if (ct.kind == syntax.tykind.TY_PTR) { + let cs: *syntax.tinfo = ct.sub; cs = tichase(cs); - if (cs != nil) { if (cs.kind == tykind.TY_STRUCT) { okp = true; }; }; + if (cs != nil) { if (cs.kind == syntax.tykind.TY_STRUCT) { okp = true; }; }; }; }; if (!okp) { allptr = false; }; croot = croot.lhs; }; - let it: *tinfo = nil; - if (allptr && croot != nil && croot.kind == nkind.N_IDENT && + let it: *syntax.tinfo = nil; + if (allptr && croot != nil && croot.kind == syntax.nkind.N_IDENT && localfindnode(c, croot.str) != nil) { - it = lhs.type_: *tinfo; + it = lhs.type_: *syntax.tinfo; }; it = tichase(it); - if (it != nil) { if (it.kind == tykind.TY_PTR) { - let st: *tinfo = it.sub; + if (it != nil) { if (it.kind == syntax.tykind.TY_PTR) { + let st: *syntax.tinfo = it.sub; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { - let tf: *tfield = st.fields; + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { + let tf: *syntax.tfield = st.fields; for (tf != nil) { - if (streq(tf.name, fld)) { - let ft: *tinfo = tf.type_; + if (syntax.streq(tf.name, fld)) { + let ft: *syntax.tinfo = tf.type_; cgexpr(c, lhs); // AX = ptr to inner struct // tagged leaf (#38a): AX holds the // *struct base and the tagged cursor @@ -4643,8 +4643,8 @@ fn cgdot(c: *cgen, n: *node) void = { // BX, then cgloadtaggedfield (cstage // chained-*struct twin; ken b8: the // scalar tail read stale DX as payload). - if (typeistagged(ft)) { - let plu: *tinfo = ft; + if (syntax.typeistagged(ft)) { + let plu: *syntax.tinfo = ft; plu = tichase(plu); emitline("\tMOVQ\tAX, BX\n"); cgloadtaggedfield(c, "BX", @@ -4659,7 +4659,7 @@ fn cgdot(c: *cgen, n: *node) void = { // AX) LAST. str folds onto the slice // arm (#1/Phase 3 collapse; cite cstage // cgen.c N_DOT chained *struct caseB). - if (typeisstr(ft) || typeisslice(ft)) { + if (syntax.typeisstr(ft) || syntax.typeisslice(ft)) { emitline("\tMOVQ\t"); emitdispreg((tf.offset + 8u64): i64, "AX"); emitline(", BX\n"); @@ -4672,9 +4672,9 @@ fn cgdot(c: *cgen, n: *node) void = { return; }; // f64/f32 chained field: route through X0. - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); @@ -4682,7 +4682,7 @@ fn cgdot(c: *cgen, n: *node) void = { emitline(", X0\n"); return; }; - let lop: str = loadopsz(typeissigned(ft), ft.slotsize: i32); + let lop: str = loadopsz(syntax.typeissigned(ft), ft.slotsize: i32); emitline("\t"); emitline(lop); emitline("\t"); @@ -4704,21 +4704,21 @@ fn cgdot(c: *cgen, n: *node) void = { // earlier in cgdot) to preserve byte-identical output on shapes // it already handles. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let inner: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let inner: *syntax.node = lhs.lhs; let innerfld: str = lhs.str; - if (inner != nil) { if (inner.kind == nkind.N_IDENT) { + if (inner != nil) { if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { if (lc.tnode != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = tn.kind; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = tn.kind; let outname: str; outname.ptr = nil; outname.len = 0; let isptr: bool = false; - if (lkind == nkind.N_TNAME) { outname = tn.str; }; - if (lkind == nkind.N_TPTR) { - let pe: *node = tn.lhs; - if (pe != nil) { if (pe.kind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { outname = tn.str; }; + if (lkind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = tn.lhs; + if (pe != nil) { if (pe.kind == syntax.nkind.N_TNAME) { outname = pe.str; isptr = true; };}; @@ -4728,15 +4728,15 @@ fn cgdot(c: *cgen, n: *node) void = { if (osi != nil) { let ofi: *fieldinfo = osi.fields; for (ofi != nil) { - if (streq(ofi.fname, innerfld)) { - let oft: *node = ofi.tnode; - if (oft != nil) { if (oft.kind == nkind.N_TNAME) { + if (syntax.streq(ofi.fname, innerfld)) { + let oft: *syntax.node = ofi.tnode; + if (oft != nil) { if (oft.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, oft.str) == 0) { let isi: *structinfo = structlookup(c, oft.str); if (isi != nil) { let ffi: *fieldinfo = isi.fields; for (ffi != nil) { - if (streq(ffi.fname, fld)) { + if (syntax.streq(ffi.fname, fld)) { let totoff: i32 = ofi.foff + ffi.foff; if (isstrtype(c, ffi.tnode)) { if (isptr) { @@ -4823,9 +4823,9 @@ fn cgdot(c: *cgen, n: *node) void = { // chain, turning a TYPED depth-2 read behind an index/deref spine // into a silent global read of a colliding leaf symbol. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let sbt: *tinfo = lhs.type_: *tinfo; - if (sbt == nil || sbt.kind == tykind.TY_ERR) { + if (lhs.kind == syntax.nkind.N_DOT) { + let sbt: *syntax.tinfo = lhs.type_: *syntax.tinfo; + if (sbt == nil || sbt.kind == syntax.tykind.TY_ERR) { emitline("\tMOVQ\t"); emitsymname(c, fld); emitline("(SB), AX\n"); @@ -4840,11 +4840,11 @@ fn cgdot(c: *cgen, n: *node) void = { // arm → cs≠ww). Loud; the wwstage alignment is filed as task // #37. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let pgu: *tinfo = lhs.type_: *tinfo; + if (lhs.kind == syntax.nkind.N_DOT) { + let pgu: *syntax.tinfo = lhs.type_: *syntax.tinfo; pgu = tichase(pgu); if (pgu != nil) { - if (pgu.kind == tykind.TY_PTR) { + if (pgu.kind == syntax.tykind.TY_PTR) { let mp: str = "cgdot: ptr-chained field read unwired in wwstage (task #37)\n"; os.write(2, mp.ptr, mp.len: u64); os.exit(1); @@ -4861,11 +4861,11 @@ fn cgdot(c: *cgen, n: *node) void = { // silently emitted NOTHING. Mirror of cstage cgen.c case N_DOT // read-resolver tail. { - let rdt: *tinfo = n.type_: *tinfo; - let rdu: *tinfo = rdt; + let rdt: *syntax.tinfo = n.type_: *syntax.tinfo; + let rdu: *syntax.tinfo = rdt; rdu = tichase(rdu); if (rdu != nil) { - if (rdu.kind == tykind.TY_TAGGED) { + if (rdu.kind == syntax.tykind.TY_TAGGED) { let mt: str = "read-resolver: tagged field read not wired (rule-7)\n"; os.write(2, mt.ptr, mt.len: u64); os.exit(1); @@ -4875,8 +4875,8 @@ fn cgdot(c: *cgen, n: *node) void = { // them; this loud guards the remaining non-let expr // positions (no register convention for a >8B leaf), // symmetric with cstage's read-resolver tail. - if (rdu.kind == tykind.TY_STRUCT - || rdu.kind == tykind.TY_TUPLE) { + if (rdu.kind == syntax.tykind.TY_STRUCT + || rdu.kind == syntax.tykind.TY_TUPLE) { let ma: str = "read-resolver: aggregate field read not wired (rule-7)\n"; os.write(2, ma.ptr, ma.len: u64); os.exit(1); @@ -4887,22 +4887,22 @@ fn cgdot(c: *cgen, n: *node) void = { os.write(2, mu.ptr, mu.len: u64); os.exit(1); }; - if (typeisfloat(rdt)) { + if (syntax.typeisfloat(rdt)) { let mov: str = "MOVSD"; - if (typeisf32(rdt)) { mov = "MOVSS"; }; + if (syntax.typeisf32(rdt)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t(BX), X0\n"); return; }; - if (rdu != nil && rdu.kind == tykind.TY_ARRAY) { + if (rdu != nil && rdu.kind == syntax.tykind.TY_ARRAY) { // `[N]T` leaf: leave the field ADDRESS — a base for // an outer index, never a value (#270-1a semantics). emitline("\tMOVQ\tBX, AX\n"); return; }; - if (rdu != nil && (rdu.kind == tykind.TY_STR - || rdu.kind == tykind.TY_SLICE)) { + if (rdu != nil && (rdu.kind == syntax.tykind.TY_STR + || rdu.kind == syntax.tykind.TY_SLICE)) { // str IS []u8 — 3-word {ptr,len,cap} into (AX, BX, // CX). BX is the place base, so load .len (which // targets BX) LAST. @@ -4913,7 +4913,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; let lop: str = "MOVQ"; if (rdt != nil) { - lop = loadopsz(typeissigned(rdt), rdt.slotsize: i32); + lop = loadopsz(syntax.typeissigned(rdt), rdt.slotsize: i32); }; emitline("\t"); emitline(lop); @@ -4922,18 +4922,18 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; -fn cgun(c: *cgen, n: *node) void = { +fn cgun(c: *cgen, n: *syntax.node) void = { // Match C cgen ordering: evaluate operand first (load into AX), // then apply the unary op. AMP / STAR override AX with the // address / deref. The wasted load before AMP keeps our asm // byte-identical to the C version. let fk: i32 = 0; if (n.lhs != nil) { - let lt: *tinfo = n.lhs.type_: *tinfo; - if (typeisf32(lt)) { fk = 1; } - else { if (typeisfloat(lt)) { fk = 2; }; }; + let lt: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; + if (syntax.typeisf32(lt)) { fk = 1; } + else { if (syntax.typeisfloat(lt)) { fk = 2; }; }; }; - if (n.op == tkind.TK_MINUS && fk != 0) { + if (n.op == syntax.tkind.TK_MINUS && fk != 0) { // Float negate: X0 = 0 - X0. Stash orig, load 0.0, subtract. // Zero bit pattern equals 0.0 for both f32 and f64 so we // reuse the integer-zero materialisation. @@ -4955,10 +4955,10 @@ fn cgun(c: *cgen, n: *node) void = { // Address-of has its own evaluation strategy — we want the address // of the operand, not its value. Special-case here so `&arr[i]` // doesn't compile the value load and then discard it. - if (n.op == tkind.TK_AMP) { - let opnd: *node = n.lhs; + if (n.op == syntax.tkind.TK_AMP) { + let opnd: *syntax.node = n.lhs; if (opnd != nil) { - if (opnd.kind == nkind.N_IDENT) { + if (opnd.kind == syntax.nkind.N_IDENT) { let nm: str = opnd.str; let off: i32 = localfind(c, nm); if (off != 0) { @@ -5024,16 +5024,16 @@ fn cgun(c: *cgen, n: *node) void = { // only; spine walker aborts on the *T base. Load // p into AX, then LEAQ field_off(AX), AX. Mirror // of the read at cgdot 1144. - if (opnd.kind == nkind.N_DOT) { + if (opnd.kind == syntax.nkind.N_DOT) { // Shape 1 chained: depth-≥2 via dotchainresolve. // `opnd.lhs.kind == N_DOT` gates the helper at // nsteps ≥ 2 (matches the read path's gate). if (opnd.lhs != nil) { - if (opnd.lhs.kind == nkind.N_DOT) { + if (opnd.lhs.kind == syntax.nkind.N_DOT) { let rootname: str = ""; let rootoff: i32 = 0; let totaloff: i32 = 0; - let leaftype: *tinfo = nil; + let leaftype: *syntax.tinfo = nil; let slicedelta: i32 = -1; let isglobal: bool = false; let ptrroot: bool = false; @@ -5069,13 +5069,13 @@ fn cgun(c: *cgen, n: *node) void = { // the base's tnode to pick value-struct vs slice/ // str pseudo vs pointer-field. if (opnd.lhs != nil) { - if (opnd.lhs.kind == nkind.N_IDENT) { + if (opnd.lhs.kind == syntax.nkind.N_IDENT) { let basenm: str = opnd.lhs.str; let fld: str = opnd.str; let lc: *local = localfindnode(c, basenm); if (lc != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = nkind.N_NONE; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = syntax.nkind.N_NONE; if (tn != nil) { lkind = tn.kind; }; // Pointer-field: &p.f where p:*T. // #102 (ken B6-c3 re-attribution): an @@ -5088,19 +5088,19 @@ fn cgun(c: *cgen, n: *node) void = { // chain; plain rows short-circuit at its // structlookup head, byte-id by // construction. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; let sname: str; sname.ptr = nil; sname.len = 0; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; if (sname.len > 0) { let si: *structinfo = structlookupchain(c, inner); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tMOVQ\t"); emitoff(lc.off: i64); emitline("(BP), AX\n"); @@ -5120,12 +5120,12 @@ fn cgun(c: *cgen, n: *node) void = { // &p.f gate — an alias-NAMED value // struct fell to the generic route. // Same chase, same construction. - if (lkind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { let si: *structinfo = structlookupchain(c, tn); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tLEAQ\t"); emitoff((lc.off + fi.foff): i64); emitline("(BP), AX\n"); @@ -5139,14 +5139,14 @@ fn cgun(c: *cgen, n: *node) void = { // &s.ptr / &s.len / &s.cap. Delta is // 0/8/16 — matches the spine walker. let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { let isslor: bool = false; - if (lkind == nkind.N_TSLICE) { isslor = true; }; - if (lkind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { isslor = true; }; + if (lkind == syntax.nkind.N_TSLICE) { isslor = true; }; + if (lkind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { isslor = true; }; }; if (isslor) { emitline("\tLEAQ\t"); @@ -5163,7 +5163,7 @@ fn cgun(c: *cgen, n: *node) void = { if (gsi != nil) { let fi: *fieldinfo = gsi.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tLEAQ\t"); emitsymname(c, basenm); emitline("(SB), CX\n"); @@ -5179,11 +5179,11 @@ fn cgun(c: *cgen, n: *node) void = { let issl: bool = letvarisslice(c, basenm); if (isstr || issl) { let gdelta: i32 = -1; - if (streq(fld, "ptr")) { gdelta = 0; }; - if (streq(fld, "len")) { gdelta = 8; }; + if (syntax.streq(fld, "ptr")) { gdelta = 0; }; + if (syntax.streq(fld, "len")) { gdelta = 8; }; // str IS []u8: &str.cap is valid too, not slice-only // — mirrors cstage (#1/Phase 3, #11). - if (streq(fld, "cap")) { gdelta = 16; }; + if (syntax.streq(fld, "cap")) { gdelta = 16; }; if (gdelta >= 0) { emitline("\tLEAQ\t"); emitsymname(c, basenm); @@ -5207,7 +5207,7 @@ fn cgun(c: *cgen, n: *node) void = { // via emitfnname (fn address), mirroring that read // path's TY_FN branch. if (opnd.lhs != nil) { - if (opnd.lhs.kind == nkind.N_IDENT) { + if (opnd.lhs.kind == syntax.nkind.N_IDENT) { let basenm: str = opnd.lhs.str; if (localfindnode(c, basenm) == nil) { // A def base (`&Pdef.field`) is NOT a module @@ -5223,7 +5223,7 @@ fn cgun(c: *cgen, n: *node) void = { // pre-#149 gap (file as #150-family). if (!isletvar(c, basenm) && !deflookup(c, basenm)) { let fld: str = opnd.str; - let frt: *node = fnretlookupmod(c, fld, usehint(c, basenm)); + let frt: *syntax.node = fnretlookupmod(c, fld, usehint(c, basenm)); if (frt != nil) { emitline("\tLEAQ\t"); emitfnname(c, fld, usehint(c, basenm)); @@ -5258,10 +5258,10 @@ fn cgun(c: *cgen, n: *node) void = { os.write(2, mam.ptr, mam.len: u64); os.exit(1); }; - if (opnd.kind == nkind.N_INDEX) { + if (opnd.kind == syntax.nkind.N_INDEX) { // &base[i] = base + i*esz, no dereference. - let base: *node = opnd.lhs; - let idx: *node = opnd.rhs; + let base: *syntax.node = opnd.lhs; + let idx: *syntax.node = opnd.rhs; let esz: i32 = 8; let isglobalarr: bool = false; let isglobalptr: bool = false; @@ -5270,13 +5270,13 @@ fn cgun(c: *cgen, n: *node) void = { let baselocal: *local = nil; let isarr: bool = false; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { baselocal = localfindnode(c, base.str); if (baselocal != nil) { esz = elemsizeofc(c, baselocal.tnode); - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { isarr = true; }; + if (tn.kind == syntax.nkind.N_TARRAY) { isarr = true; }; }; } else { // #11: addr-of twin of the #10 cgindex read @@ -5291,7 +5291,7 @@ fn cgun(c: *cgen, n: *node) void = { // esz=bu->sub->size, base is_arr?LEAQ:MOVQ // name(SB) (a str/slice's .ptr IS the symbol's // first word). Align UP, mirroring cgindex. - let tn: *node = letvartnode(c, base.str); + let tn: *syntax.node = letvartnode(c, base.str); // #94: a def-array base resolves via // defvartnode (the def-side sister), the same // fallback cgindex's read-side already takes @@ -5305,7 +5305,7 @@ fn cgun(c: *cgen, n: *node) void = { if (tn != nil) { globalname = base.str; esz = elemsizeofc(c, tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; @@ -5321,26 +5321,26 @@ fn cgun(c: *cgen, n: *node) void = { // classifies off type_chase_named uniformly // (cmd/w6c/cgen.c:4172-4188). TY_NAMED gate // keeps non-alias rows byte-id by construction. - let bt82: *tinfo = base.type_: *tinfo; + let bt82: *syntax.tinfo = base.type_: *syntax.tinfo; let basealias82: bool = false; if (bt82 != nil) { - if (bt82.kind == tykind.TY_NAMED) { basealias82 = true; }; + if (bt82.kind == syntax.tykind.TY_NAMED) { basealias82 = true; }; }; if (basealias82) { - let bu82: *tinfo = tichase(bt82); + let bu82: *syntax.tinfo = tichase(bt82); if (bu82 != nil) { if (baselocal != nil) { - isarr = bu82.kind == tykind.TY_ARRAY; + isarr = bu82.kind == syntax.tykind.TY_ARRAY; }; if (isglobalarr || isglobalptr) { - isglobalarr = bu82.kind == tykind.TY_ARRAY; + isglobalarr = bu82.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; }; - } else { if (base.kind == nkind.N_DOT - || (base.kind == nkind.N_UN - && base.op == tkind.TK_STAR)) { + } else { if (base.kind == syntax.nkind.N_DOT + || (base.kind == syntax.nkind.N_UN + && base.op == syntax.tkind.TK_STAR)) { // `&p.ptr[i]`: stride is the checker-stamped // element tinfo's natural size, mirroring // cgindex's N_DOT arm so &p.ptr[i] and @@ -5349,7 +5349,7 @@ fn cgun(c: *cgen, n: *node) void = { // N_UN deref base (`&(*p)[i]`, #61 C): same // stamped source; cstage reads base->type // uniformly. - let dt: *tinfo = opnd.type_: *tinfo; + let dt: *syntax.tinfo = opnd.type_: *syntax.tinfo; if (dt != nil) { esz = dt.size: i32; }; };}; }; @@ -5415,8 +5415,8 @@ fn cgun(c: *cgen, n: *node) void = { return; }; cgexpr(c, n.lhs); - if (n.op == tkind.TK_MINUS) { emitline("\tNEGQ\tAX\n"); return; }; - if (n.op == tkind.TK_TILDE) { + if (n.op == syntax.tkind.TK_MINUS) { emitline("\tNEGQ\tAX\n"); return; }; + if (n.op == syntax.tkind.TK_TILDE) { emitline("\tNOTQ\tAX\n"); // NOTQ inverts the whole 64-bit register; clamp narrow // unsigned results to type width so subsequent 64-bit @@ -5431,7 +5431,7 @@ fn cgun(c: *cgen, n: *node) void = { }; return; }; - if (n.op == tkind.TK_STAR) { + if (n.op == syntax.tkind.TK_STAR) { // #185: deref of *fn — the pointer value IS the fn address. // cgexpr(n.lhs) left AX = fn-addr; a generic MOVQ (AX),AX // would load the first instruction word and a subsequent @@ -5442,10 +5442,10 @@ fn cgun(c: *cgen, n: *node) void = { // `*[N]T` leaves AX = p's value. The scalar load below // pulled a[0]'s VALUE and `(*p)[i]` then dereferenced it as // the index base — a wild pointer, SIGSEGV on both stages. - let rti: *tinfo = n.type_: *tinfo; + let rti: *syntax.tinfo = n.type_: *syntax.tinfo; rti = tichase(rti); - if (rti != nil && rti.kind == tykind.TY_FN) { return; }; - if (rti != nil && rti.kind == tykind.TY_ARRAY) { return; }; + if (rti != nil && rti.kind == syntax.tykind.TY_FN) { return; }; + if (rti != nil && rti.kind == syntax.tykind.TY_ARRAY) { return; }; // Family C (#35/#46): a tagged box behind *p joins the // mem-based class at ANY size (taggedmemread) — AX = p's // value IS the box address. The scalar load below pulled @@ -5453,7 +5453,7 @@ fn cgun(c: *cgen, n: *node) void = { // garbage payload words — silent-wrong both stages (ken // f35/D3a/D3b). The nullable one-word fold stays a scalar // deref. Mirrors cstage N_UN TK_STAR. - if (rti != nil && rti.kind == tykind.TY_TAGGED) { + if (rti != nil && rti.kind == syntax.tykind.TY_TAGGED) { if (rti.nullable == 0 && rti.size: i32 > 8) { return; }; }; // f64/f32 result rides X0 (SSE), not AX — an integer MOVQ @@ -5486,7 +5486,7 @@ fn cgun(c: *cgen, n: *node) void = { }; return; }; - if (n.op == tkind.TK_NOT) { + if (n.op == syntax.tkind.TK_NOT) { let t: str = mklabel(c, "tt"); let e: str = mklabel(c, "te"); emitline("\tCMPQ\t$0, AX\n"); @@ -5507,8 +5507,8 @@ fn cgun(c: *cgen, n: *node) void = { // module-global str (#154 let_islet branch) or BP+off for a local; a // non-ident evals via cgexpr (AX=ptr, BX=len) and pushes BX then AX. Push // order is len then ptr so the matching POPQ pops ptr first. -fn cgstreqpush(c: *cgen, op: *node) void = { - if (op.kind == nkind.N_IDENT) { +fn cgstreqpush(c: *cgen, op: *syntax.node) void = { + if (op.kind == syntax.nkind.N_IDENT) { let nm: str = op.str; let lc: *local = localfindnode(c, nm); if (lc == nil && isletvar(c, nm)) { @@ -5538,17 +5538,17 @@ fn cgstreqpush(c: *cgen, op: *node) void = { emitline("\tPUSHQ\tAX\n"); }; -fn cgbin(c: *cgen, n: *node) void = { +fn cgbin(c: *cgen, n: *syntax.node) void = { // Short-circuit `&&` / `||`. Operands are bool (0/1); the type // checker enforces it. Eval LHS into AX, branch over RHS on the // short-circuit polarity, otherwise eval RHS into AX. The // surviving AX is the result. Must precede any eager-eval path // below — `if (p != nil && p.x > 0)` would segfault on a nil // deref otherwise. Byte-identical to cmd/w6c/cgen.c N_BIN. - if (n.op == tkind.TK_AND || n.op == tkind.TK_OR) { + if (n.op == syntax.tkind.TK_AND || n.op == syntax.tkind.TK_OR) { let prefix: str = "andend"; let jshrt: str = "JE"; - if (n.op == tkind.TK_OR) { prefix = "orend"; jshrt = "JNE"; }; + if (n.op == syntax.tkind.TK_OR) { prefix = "orend"; jshrt = "JNE"; }; let end: str = mklabel(c, prefix); cgexpr(c, n.lhs); emitline("\tCMPQ\t$0, AX\n"); @@ -5567,15 +5567,15 @@ fn cgbin(c: *cgen, n: *node) void = { // for !=. The gate reads the checker stamp (typeisstr) exactly like // cstage node_isstr. Byte-identical to cstage cbinop (cmd/w6c/ // cgen.c:4564-4623). cstage was fixed by #154; this is its mirror. - if ((n.op == tkind.TK_EQ || n.op == tkind.TK_NEQ) + if ((n.op == syntax.tkind.TK_EQ || n.op == syntax.tkind.TK_NEQ) && n.lhs != nil && n.rhs != nil - && typeisstr(n.lhs.type_: *tinfo) - && typeisstr(n.rhs.type_: *tinfo)) { + && syntax.typeisstr(n.lhs.type_: *syntax.tinfo) + && syntax.typeisstr(n.rhs.type_: *syntax.tinfo)) { cgstreqpush(c, n.rhs); cgstreqpush(c, n.lhs); emitline("\tPOPQ\tDI\n\tPOPQ\tSI\n\tPOPQ\tDX\n\tPOPQ\tCX\n"); emitline("\tCALL\trt_streq(SB)\n"); - if (n.op == tkind.TK_NEQ) { emitline("\tXORQ\t$1, AX\n"); }; + if (n.op == syntax.tkind.TK_NEQ) { emitline("\tXORQ\t$1, AX\n"); }; return; }; @@ -5595,25 +5595,25 @@ fn cgbin(c: *cgen, n: *node) void = { // are therefore dead and removed. let lfk: i32 = 0; if (n.lhs != nil) { - let llt: *tinfo = n.lhs.type_: *tinfo; - if (typeisf32(llt)) { lfk = 1; } - else { if (typeisfloat(llt)) { lfk = 2; }; }; + let llt: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; + if (syntax.typeisf32(llt)) { lfk = 1; } + else { if (syntax.typeisfloat(llt)) { lfk = 2; }; }; }; let rfk: i32 = 0; if (n.rhs != nil) { - let rrt: *tinfo = n.rhs.type_: *tinfo; - if (typeisf32(rrt)) { rfk = 1; } - else { if (typeisfloat(rrt)) { rfk = 2; }; }; + let rrt: *syntax.tinfo = n.rhs.type_: *syntax.tinfo; + if (syntax.typeisf32(rrt)) { rfk = 1; } + else { if (syntax.typeisfloat(rrt)) { rfk = 2; }; }; }; let fk: i32 = lfk; if (fk == 0) { fk = rfk; }; if (fk != 0) { let mov: str = "MOVSD"; if (fk == 1) { mov = "MOVSS"; }; - if (n.op == tkind.TK_PLUS || - n.op == tkind.TK_MINUS || - n.op == tkind.TK_STAR || - n.op == tkind.TK_SLASH) { + if (n.op == syntax.tkind.TK_PLUS || + n.op == syntax.tkind.TK_MINUS || + n.op == syntax.tkind.TK_STAR || + n.op == syntax.tkind.TK_SLASH) { cgexpr(c, n.rhs); emitline("\tSUBQ\t$8, SP\n"); emitline("\t"); emitline(mov); emitline("\tX0, (SP)\n"); @@ -5621,25 +5621,25 @@ fn cgbin(c: *cgen, n: *node) void = { emitline("\t"); emitline(mov); emitline("\t(SP), X1\n"); emitline("\tADDQ\t$8, SP\n"); let op: str = "ADDSD"; - if (n.op == tkind.TK_MINUS) { op = "SUBSD"; }; - if (n.op == tkind.TK_STAR) { op = "MULSD"; }; - if (n.op == tkind.TK_SLASH) { op = "DIVSD"; }; + if (n.op == syntax.tkind.TK_MINUS) { op = "SUBSD"; }; + if (n.op == syntax.tkind.TK_STAR) { op = "MULSD"; }; + if (n.op == syntax.tkind.TK_SLASH) { op = "DIVSD"; }; if (fk == 1) { - if (n.op == tkind.TK_PLUS) { op = "ADDSS"; }; - if (n.op == tkind.TK_MINUS) { op = "SUBSS"; }; - if (n.op == tkind.TK_STAR) { op = "MULSS"; }; - if (n.op == tkind.TK_SLASH) { op = "DIVSS"; }; + if (n.op == syntax.tkind.TK_PLUS) { op = "ADDSS"; }; + if (n.op == syntax.tkind.TK_MINUS) { op = "SUBSS"; }; + if (n.op == syntax.tkind.TK_STAR) { op = "MULSS"; }; + if (n.op == syntax.tkind.TK_SLASH) { op = "DIVSS"; }; }; emitline("\t"); emitline(op); emitline("\tX1, X0\n"); return; }; let isfcmp: bool = false; - if (n.op == tkind.TK_EQ) { isfcmp = true; }; - if (n.op == tkind.TK_NEQ) { isfcmp = true; }; - if (n.op == tkind.TK_LT) { isfcmp = true; }; - if (n.op == tkind.TK_LE) { isfcmp = true; }; - if (n.op == tkind.TK_GT) { isfcmp = true; }; - if (n.op == tkind.TK_GE) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_EQ) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_NEQ) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_LT) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_LE) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_GT) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_GE) { isfcmp = true; }; if (isfcmp) { cgexpr(c, n.rhs); emitline("\tSUBQ\t$8, SP\n"); @@ -5659,7 +5659,7 @@ fn cgbin(c: *cgen, n: *node) void = { // unordered never gives, so they are ALREADY NaN-correct // and stay byte-identical to the pre-#97 single-template // arm — no redundant PF guard. - if (n.op == tkind.TK_NEQ) { + if (n.op == syntax.tkind.TK_NEQ) { // not-equal OR unordered -> true let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); @@ -5672,12 +5672,12 @@ fn cgbin(c: *cgen, n: *node) void = { emitlabel(e); return; }; - if (n.op == tkind.TK_EQ || n.op == tkind.TK_LT || - n.op == tkind.TK_LE) { + if (n.op == syntax.tkind.TK_EQ || n.op == syntax.tkind.TK_LT || + n.op == syntax.tkind.TK_LE) { // unordered -> false; otherwise the ordered Jcc decides. let jcc: str = "JE"; - if (n.op == tkind.TK_LT) { jcc = "JB"; }; - if (n.op == tkind.TK_LE) { jcc = "JBE"; }; + if (n.op == syntax.tkind.TK_LT) { jcc = "JB"; }; + if (n.op == syntax.tkind.TK_LE) { jcc = "JBE"; }; let fl: str = mklabel(c, "cf"); let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); @@ -5694,7 +5694,7 @@ fn cgbin(c: *cgen, n: *node) void = { // `>`/`>=`: JA/JAE already reject unordered (CF=1), so // keep the pre-#97 single-template shape verbatim. let jcc: str = "JA"; - if (n.op == tkind.TK_GE) { jcc = "JAE"; }; + if (n.op == syntax.tkind.TK_GE) { jcc = "JAE"; }; let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); emitline("\t"); emitline(jcc); emitline("\t"); emitline(t); emitline("\n"); @@ -5712,10 +5712,10 @@ fn cgbin(c: *cgen, n: *node) void = { emitline("\tPUSHQ\tAX\n"); cgexpr(c, n.lhs); emitline("\tPOPQ\tBX\n"); - if (n.op == tkind.TK_PLUS) { emitline("\tADDQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_MINUS) { emitline("\tSUBQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_STAR) { emitline("\tIMULQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_SLASH) { + if (n.op == syntax.tkind.TK_PLUS) { emitline("\tADDQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_MINUS) { emitline("\tSUBQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_STAR) { emitline("\tIMULQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_SLASH) { // Signed IDIV reads dividend from RDX:RAX; CQO sign-extends // RAX. Zero-filling DX would treat a negative RAX as a huge // positive 128-bit value. Unsigned DIV needs RDX zero. @@ -5728,7 +5728,7 @@ fn cgbin(c: *cgen, n: *node) void = { }; return; }; - if (n.op == tkind.TK_PERCENT) { + if (n.op == syntax.tkind.TK_PERCENT) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tBX\n"); @@ -5739,15 +5739,15 @@ fn cgbin(c: *cgen, n: *node) void = { emitline("\tMOVQ\tDX, AX\n"); return; }; - if (n.op == tkind.TK_AMP) { emitline("\tANDQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_PIPE) { emitline("\tORQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_CARET) { emitline("\tXORQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_LSHIFT) { + if (n.op == syntax.tkind.TK_AMP) { emitline("\tANDQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_PIPE) { emitline("\tORQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_CARET) { emitline("\tXORQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_LSHIFT) { emitline("\tMOVQ\tBX, CX\n"); emitline("\tSHLQ\tCX, AX\n"); return; }; - if (n.op == tkind.TK_RSHIFT) { + if (n.op == syntax.tkind.TK_RSHIFT) { // #136: signed RSHIFT → SAR (arithmetic, sign-extends MSB); // unsigned → SHR (logical, zero-fill). `unsignd` derived above // at cgbin head from nodeisunsigned(lhs) || nodeisunsigned(rhs). @@ -5763,12 +5763,12 @@ fn cgbin(c: *cgen, n: *node) void = { // materialise 0/1 in AX. Same shape as the C cgen. let iscmp: bool = false; let jcc: str = ""; - if (n.op == tkind.TK_EQ) { iscmp = true; jcc = "JE"; }; - if (n.op == tkind.TK_NEQ) { iscmp = true; jcc = "JNE"; }; - if (n.op == tkind.TK_LT) { iscmp = true; if (unsignd) { jcc = "JB"; } else { jcc = "JL"; }; }; - if (n.op == tkind.TK_LE) { iscmp = true; if (unsignd) { jcc = "JBE"; } else { jcc = "JLE"; }; }; - if (n.op == tkind.TK_GT) { iscmp = true; if (unsignd) { jcc = "JA"; } else { jcc = "JG"; }; }; - if (n.op == tkind.TK_GE) { iscmp = true; if (unsignd) { jcc = "JAE"; } else { jcc = "JGE"; }; }; + if (n.op == syntax.tkind.TK_EQ) { iscmp = true; jcc = "JE"; }; + if (n.op == syntax.tkind.TK_NEQ) { iscmp = true; jcc = "JNE"; }; + if (n.op == syntax.tkind.TK_LT) { iscmp = true; if (unsignd) { jcc = "JB"; } else { jcc = "JL"; }; }; + if (n.op == syntax.tkind.TK_LE) { iscmp = true; if (unsignd) { jcc = "JBE"; } else { jcc = "JLE"; }; }; + if (n.op == syntax.tkind.TK_GT) { iscmp = true; if (unsignd) { jcc = "JA"; } else { jcc = "JG"; }; }; + if (n.op == syntax.tkind.TK_GE) { iscmp = true; if (unsignd) { jcc = "JAE"; } else { jcc = "JGE"; }; }; if (iscmp) { let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); @@ -5797,11 +5797,11 @@ fn cgbin(c: *cgen, n: *node) void = { // DX=0) or the success variant (tag=0, DX=ptr) after the // value-init stores complete. Callers wrap with `!` / `?` to // consume the union. -fn cgalloc(c: *cgen, n: *node) void = { - let v: *node = n.list; +fn cgalloc(c: *cgen, n: *syntax.node) void = { + let v: *syntax.node = n.list; let sz: i32 = 8; let si: *structinfo = nil; - if (v.kind == nkind.N_STRUCTLIT) { + if (v.kind == syntax.nkind.N_STRUCTLIT) { // #26: chase the alias chain on the literal's type ref so an // alias head (`type pt = point; alloc(pt{...})`) resolves to // the underlying struct's layout — name-keyed structlookup on @@ -5827,16 +5827,16 @@ fn cgalloc(c: *cgen, n: *node) void = { emitline("\tJMP\t"); emitline(donel); emitline("\n"); emitlabel(okl); emitline("\tPUSHQ\tAX\n"); - if (v.kind == nkind.N_STRUCTLIT) { + if (v.kind == syntax.nkind.N_STRUCTLIT) { if (si != nil) { - let f: *node = v.list; + let f: *syntax.node = v.list; for (f != nil) { - if (f.kind == nkind.N_FIELD) { + if (f.kind == syntax.nkind.N_FIELD) { let fname: str = f.str; let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fname)) { + if (syntax.streq(fn_, fname)) { cgexpr(c, f.lhs); // alloc(T{ fval = v }) for f64/f32 field: cgexpr left // the value in X0, not AX — route the store via MOVSD/MOVSS. @@ -5991,8 +5991,8 @@ fn cgappendslot(c: *cgen, direct: bool, off: i32, scr: i32, esz: i32, dst: str) // ; POPQ AX // ; MOV* AX, (BX) ; store (MOVB / MOVQ) // nkind.N_SPREAD wraps the same body in a counted loop over items.len. -fn cgappend(c: *cgen, n: *node) void = { - let sn: *node = n.list; +fn cgappend(c: *cgen, n: *syntax.node) void = { + let sn: *syntax.node = n.list; if (sn == nil) { return; }; // FA1 (#15): the old `sn.kind != N_IDENT → return` and // `snlocal == nil → return` gates were SILENT zero-emission @@ -6003,7 +6003,7 @@ fn cgappend(c: *cgen, n: *node) void = { let sndirect: bool = false; let sn_off: i32 = 0; let snlocal: *local = nil; - if (sn.kind == nkind.N_IDENT) { + if (sn.kind == syntax.nkind.N_IDENT) { snlocal = localfindnode(c, sn.str); if (snlocal != nil) { sndirect = true; @@ -6011,8 +6011,8 @@ fn cgappend(c: *cgen, n: *node) void = { }; }; let esz: i32 = 0; - let etnode: *node = nil; - let sti: *tinfo = nil; + let etnode: *syntax.node = nil; + let sti: *syntax.tinfo = nil; if (sndirect) { // #34: esz off the DECLARED slice local's stamped tnode via // elemsizeofc — bare elemsizeof returns the 8 sentinel for a @@ -6021,18 +6021,18 @@ fn cgappend(c: *cgen, n: *node) void = { // the slot index vs cstage's su->sub->size. esz = elemsizeofc(c, snlocal.tnode); if (snlocal.tnode != nil) { - let stk: nkind = snlocal.tnode.kind; - if (stk == nkind.N_TSLICE) { etnode = snlocal.tnode.lhs; }; - if (stk == nkind.N_TARRAY) { etnode = snlocal.tnode.lhs; }; - if (stk == nkind.N_TPTR) { etnode = snlocal.tnode.lhs; }; - sti = snlocal.tnode.type_: *tinfo; + let stk: syntax.nkind = snlocal.tnode.kind; + if (stk == syntax.nkind.N_TSLICE) { etnode = snlocal.tnode.lhs; }; + if (stk == syntax.nkind.N_TARRAY) { etnode = snlocal.tnode.lhs; }; + if (stk == syntax.nkind.N_TPTR) { etnode = snlocal.tnode.lhs; }; + sti = snlocal.tnode.type_: *syntax.tinfo; }; } else { // FA1: `*p` has no declared tnode — key esz/element kind off // the checker-STAMPED target tinfo (#209/#211 discipline), the // same source cstage reads (sn->type → su->sub->size). - sti = sn.type_: *tinfo; - let fsti: *tinfo = sti; + sti = sn.type_: *syntax.tinfo; + let fsti: *syntax.tinfo = sti; fsti = tichase(fsti); if (fsti != nil && fsti.sub != nil) { esz = fsti.sub.size: i32; }; if (esz <= 0) { @@ -6049,17 +6049,17 @@ fn cgappend(c: *cgen, n: *node) void = { // Mirrors cstage cgen.c's append arm + the #270/#12/#20 // array-literal element dispatch (cgarrlitfillbp). sti = tichase(sti); - let esubti: *tinfo = nil; + let esubti: *syntax.tinfo = nil; if (sti != nil) { esubti = sti.sub; }; // FA1: pre-peel handle — the indirect struct-lit fill keys its // structinfo off the NAMED element tinfo's name (the same leaf // structlookupchain resolves from the declared tnode). - let esubnamed: *tinfo = esubti; + let esubnamed: *syntax.tinfo = esubti; esubti = tichase(esubti); - let elstr: bool = esubti != nil && esubti.kind == tykind.TY_STR; - let elslice: bool = esubti != nil && esubti.kind == tykind.TY_SLICE; - let eltagged: bool = esubti != nil && esubti.kind == tykind.TY_TAGGED; - let elstruct: bool = esubti != nil && esubti.kind == tykind.TY_STRUCT; + let elstr: bool = esubti != nil && esubti.kind == syntax.tykind.TY_STR; + let elslice: bool = esubti != nil && esubti.kind == syntax.tykind.TY_SLICE; + let eltagged: bool = esubti != nil && esubti.kind == syntax.tykind.TY_TAGGED; + let elstruct: bool = esubti != nil && esubti.kind == syntax.tykind.TY_STRUCT; let elwide: bool = elstr || elslice || eltagged || elstruct; if (!elwide && esz > 8) { let m34k: str = "#34: append() element kind unsupported (rule-7)\n"; @@ -6087,31 +6087,31 @@ fn cgappend(c: *cgen, n: *node) void = { emitline("(BP)\n"); }; - let vn: *node = sn.next; + let vn: *syntax.node = sn.next; for (vn != nil) { - if (vn.kind == nkind.N_SPREAD) { + if (vn.kind == syntax.nkind.N_SPREAD) { // #34 review: a non-ident/non-local spread source used // to be silently SKIPPED here while cstage fell past // its spread arm into the single-value stores with the // N_SPREAD node (garbage store) — divergent. - let it: *node = vn.lhs; + let it: *syntax.node = vn.lhs; // #35: only a {ptr,len,cap}-headered source reads as a // header below; a [N]T array place IS its storage — the // ident path used to read its first 16 data bytes as // ptr/len, silently. Loud until wired (task #27); str // shares the slice header layout. - let itu: *tinfo = nil; - if (it != nil) { itu = it.type_: *tinfo; }; + let itu: *syntax.tinfo = nil; + if (it != nil) { itu = it.type_: *syntax.tinfo; }; itu = tichase(itu); - if (itu == nil || (itu.kind != tykind.TY_SLICE - && itu.kind != tykind.TY_STR)) { + if (itu == nil || (itu.kind != syntax.tykind.TY_SLICE + && itu.kind != syntax.tykind.TY_STR)) { let m35p: str = "#35: append() spread source shape unsupported (rule-7)\n"; os.write(2, m35p.ptr, m35p.len: u64); os.exit(1); }; let it_off: i32 = 0; let itscr: i32 = 0; - if (it.kind == nkind.N_IDENT) { + if (it.kind == syntax.nkind.N_IDENT) { let itlocal: *local = localfindnode(c, it.str); if (itlocal != nil) { it_off = itlocal.off; }; }; @@ -6145,7 +6145,7 @@ fn cgappend(c: *cgen, n: *node) void = { // FA1: no etnode behind `*p` — signedness off the // stamped element tinfo, the predicate cstage's // fldloadop applies to su->sub. - load_op = loadopsz(typeissigned(esubti), esz); + load_op = loadopsz(syntax.typeissigned(esubti), esz); }; emitline("\tSUBQ\t$8, SP\n"); emitline("\tMOVQ\t$0, (SP)\n"); @@ -6327,21 +6327,21 @@ fn cgappend(c: *cgen, n: *node) void = { let arootoff: i32 = 0; let asroot: i32 = 0; let asoff: i32 = 0; - let aroot: *node = nil; - let aidx: *node = nil; - if (elstruct && vn.kind != nkind.N_STRUCTLIT && vn.kind != nkind.N_IDENT) { - let ch: *node = vn; + let aroot: *syntax.node = nil; + let aidx: *syntax.node = nil; + if (elstruct && vn.kind != syntax.nkind.N_STRUCTLIT && vn.kind != syntax.nkind.N_IDENT) { + let ch: *syntax.node = vn; let aok: bool = true; - for (aok && ch.kind == nkind.N_DOT) { - let ab: *node = ch.lhs; - let af: *tfield = nil; + for (aok && ch.kind == syntax.nkind.N_DOT) { + let ab: *syntax.node = ch.lhs; + let af: *syntax.tfield = nil; if (ab != nil) { - let abu: *tinfo = ab.type_: *tinfo; + let abu: *syntax.tinfo = ab.type_: *syntax.tinfo; abu = tichase(abu); - if (abu != nil && abu.kind == tykind.TY_STRUCT) { - let fl: *tfield = abu.fields; + if (abu != nil && abu.kind == syntax.tykind.TY_STRUCT) { + let fl: *syntax.tfield = abu.fields; for (fl != nil) { - if (streq(fl.name, ch.str)) { af = fl; break; }; + if (syntax.streq(fl.name, ch.str)) { af = fl; break; }; fl = fl.tnext; }; }; @@ -6350,27 +6350,27 @@ fn cgappend(c: *cgen, n: *node) void = { afld += af.offset: i32; ch = ab; }; - if (aok && ch.kind == nkind.N_INDEX) { - let ab: *node = ch.lhs; - let aet: *tinfo = ch.type_: *tinfo; + if (aok && ch.kind == syntax.nkind.N_INDEX) { + let ab: *syntax.node = ch.lhs; + let aet: *syntax.tinfo = ch.type_: *syntax.tinfo; aet = tichase(aet); - let abu: *tinfo = nil; + let abu: *syntax.tinfo = nil; if (ab != nil) { - abu = ab.type_: *tinfo; + abu = ab.type_: *syntax.tinfo; abu = tichase(abu); }; if (ab == nil || abu == nil || aet == nil - || (abu.kind != tykind.TY_SLICE && abu.kind != tykind.TY_ARRAY)) { + || (abu.kind != syntax.tykind.TY_SLICE && abu.kind != syntax.tykind.TY_ARRAY)) { aok = false; } else { - abaseslice = abu.kind == tykind.TY_SLICE; + abaseslice = abu.kind == syntax.tykind.TY_SLICE; aidxesz = aet.size: i32; aidx = ch.rhs; ch = ab; }; }; if (aok) { - if (ch.kind == nkind.N_IDENT) { + if (ch.kind == syntax.nkind.N_IDENT) { let rl: *local = localfindnode(c, ch.str); if (rl != nil) { arootoff = rl.off; @@ -6380,15 +6380,15 @@ fn cgappend(c: *cgen, n: *node) void = { if (defvarstructinfo(c, ch.str) != nil) { gok = true; }; }; if (!gok) { - let dtn: *node = defvartnode(c, ch.str); + let dtn: *syntax.node = defvartnode(c, ch.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { gok = true; }; + if (dtn.kind == syntax.nkind.N_TARRAY) { gok = true; }; }; }; if (!gok) { aok = false; }; }; } else { - if (ch.kind != nkind.N_UN || ch.op != tkind.TK_STAR) { + if (ch.kind != syntax.nkind.N_UN || ch.op != syntax.tkind.TK_STAR) { aok = false; }; }; @@ -6399,7 +6399,7 @@ fn cgappend(c: *cgen, n: *node) void = { os.exit(1); }; aroot = ch; - if (aroot.kind == nkind.N_UN) { + if (aroot.kind == syntax.nkind.N_UN) { asroot = localadd(c, "@appendsroot", 8, nil); cgexpr(c, aroot.lhs); emitline("\tMOVQ\tAX, "); @@ -6452,7 +6452,7 @@ fn cgappend(c: *cgen, n: *node) void = { vn = vn.next; continue; }; - if (vn.kind == nkind.N_STRUCTLIT) { + if (vn.kind == syntax.nkind.N_STRUCTLIT) { // #59 (#50's eval-order kin): resolve the struct // info, then fill the literal into a fresh // per-SITE scratch (must stay live across @@ -6467,7 +6467,7 @@ fn cgappend(c: *cgen, n: *node) void = { // FA1: no declared tnode to chain through — // the stamped NAMED element tinfo carries the // same leaf structlookupchain would resolve. - if (esubnamed.kind == tykind.TY_NAMED) { + if (esubnamed.kind == syntax.tykind.TY_NAMED) { esi = structlookup(c, esubnamed.name); }; }; @@ -6530,7 +6530,7 @@ fn cgappend(c: *cgen, n: *node) void = { }; cgappendgrow(c, sndirect, sn_off, snscr, esz); cgappendslot(c, sndirect, sn_off, snscr, esz, "BX"); - if (vn.kind == nkind.N_IDENT) { + if (vn.kind == syntax.nkind.N_IDENT) { let sl: *local = localfindnode(c, vn.str); if (sl == nil) { let m34i: str = "#34: append() struct element source ident is not a local (rule-7)\n"; @@ -6586,7 +6586,7 @@ fn cgappend(c: *cgen, n: *node) void = { emitline("\tMOVQ\tBX, "); emitoff(pscroff: i64); emitline("(BP)\n"); - if (aroot.kind == nkind.N_IDENT) { + if (aroot.kind == syntax.nkind.N_IDENT) { if (arootoff != 0) { emitline("\tLEAQ\t"); emitoff(arootoff: i64); @@ -6683,15 +6683,15 @@ fn cgappend(c: *cgen, n: *node) void = { // src (j+1) ahead of dst (j), the safe memmove-down direction. Mirrors // cmd/w6c/cgen.c's N_CALL delete arm instruction-for-instruction // (rule-10 byte-id). -fn cgdelete(c: *cgen, n: *node) void = { - let d: *node = n.list; // N_INDEX, checker-validated - let base: *node = d.lhs; +fn cgdelete(c: *cgen, n: *syntax.node) void = { + let d: *syntax.node = n.list; // N_INDEX, checker-validated + let base: *syntax.node = d.lhs; // esz off the STAMPED base tinfo (#34/#48 discipline — never the // value node). Peel TY_NAMED on indexable AND element, mirroring // cstage's type_chase_named on both (#8 family). - let sti: *tinfo = base.type_: *tinfo; + let sti: *syntax.tinfo = base.type_: *syntax.tinfo; sti = tichase(sti); - let esub: *tinfo = nil; + let esub: *syntax.tinfo = nil; if (sti != nil) { esub = sti.sub; }; esub = tichase(esub); let esz: i32 = 0; @@ -6704,7 +6704,7 @@ fn cgdelete(c: *cgen, n: *node) void = { let hdr_lea: bool = false; let hdr_off: i32 = 0; let hdr_ok: bool = false; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, base.str); if (lc != nil) { hdr_lea = true; @@ -6714,9 +6714,9 @@ fn cgdelete(c: *cgen, n: *node) void = { }; // (*p)[i]: the header lives behind a local ptr-to-slice — the // regex fold-2b delete_thread shape (threads: *[]thread). - if (!hdr_ok && base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR && base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (!hdr_ok && base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR && base.lhs != nil) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let pc: *local = localfindnode(c, base.lhs.str); if (pc != nil) { hdr_off = pc.off; @@ -6815,15 +6815,15 @@ fn cgdelete(c: *cgen, n: *node) void = { // Bounds are implicit (no range check, matching cgdelete and the rest // of cgen). Mirrors cmd/w6c/cgen.c's N_CALL delete range arm // instruction-for-instruction (rule-10 byte-id). -fn cgdeleterange(c: *cgen, n: *node) void = { - let d: *node = n.list; // N_SLICE, checker-validated - let base: *node = d.lhs; +fn cgdeleterange(c: *cgen, n: *syntax.node) void = { + let d: *syntax.node = n.list; // N_SLICE, checker-validated + let base: *syntax.node = d.lhs; // esz off the STAMPED base tinfo (#34/#48 discipline — never the // value node). Peel TY_NAMED on indexable AND element, mirroring // cstage's type_chase_named on both (#8 family). - let sti: *tinfo = base.type_: *tinfo; + let sti: *syntax.tinfo = base.type_: *syntax.tinfo; sti = tichase(sti); - let esub: *tinfo = nil; + let esub: *syntax.tinfo = nil; if (sti != nil) { esub = sti.sub; }; esub = tichase(esub); let esz: i32 = 0; @@ -6838,7 +6838,7 @@ fn cgdeleterange(c: *cgen, n: *node) void = { let hdr_ok: bool = false; let hdr_idx: bool = false; let osz: i32 = 0; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, base.str); if (lc != nil) { hdr_lea = true; @@ -6848,9 +6848,9 @@ fn cgdeleterange(c: *cgen, n: *node) void = { }; // (*p)[lo:hi]: header behind a local ptr-to-slice — cgdelete's // regex_shape twin. - if (!hdr_ok && base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR && base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (!hdr_ok && base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR && base.lhs != nil) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let pc: *local = localfindnode(c, base.lhs.str); if (pc != nil) { hdr_off = pc.off; @@ -6863,9 +6863,9 @@ fn cgdeleterange(c: *cgen, n: *node) void = { // the fold-5a consumer shape (ref/hare/regex/regex.ha:333 // delete(jump_idxs[group_level][..])). Outer stride = the inner // header type's own table size (sti). - if (!hdr_ok && base.kind == nkind.N_INDEX) { + if (!hdr_ok && base.kind == syntax.nkind.N_INDEX) { if (base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let oc: *local = localfindnode(c, base.lhs.str); if (oc != nil) { hdr_idx = true; @@ -7013,16 +7013,16 @@ fn cgdeleterange(c: *cgen, n: *node) void = { // are implicit (no index check, matching delete). Mirrors cmd/w6c/ // cgen.c's N_CALL insert arm instruction-for-instruction (rule-10 // byte-id). -fn cginsert(c: *cgen, n: *node) void = { - let d: *node = n.list; // N_INDEX, checker-validated - let base: *node = d.lhs; - let v: *node = d.next; +fn cginsert(c: *cgen, n: *syntax.node) void = { + let d: *syntax.node = n.list; // N_INDEX, checker-validated + let base: *syntax.node = d.lhs; + let v: *syntax.node = d.next; // esz off the STAMPED base tinfo (#34/#48 discipline — never the // value node). Peel TY_NAMED on indexable AND element, mirroring // cstage's type_chase_named on both (#8 family). - let sti: *tinfo = base.type_: *tinfo; + let sti: *syntax.tinfo = base.type_: *syntax.tinfo; sti = tichase(sti); - let esub: *tinfo = nil; + let esub: *syntax.tinfo = nil; if (sti != nil) { esub = sti.sub; }; esub = tichase(esub); let esz: i32 = 0; @@ -7035,7 +7035,7 @@ fn cginsert(c: *cgen, n: *node) void = { let hdr_lea: bool = false; let hdr_off: i32 = 0; let hdr_ok: bool = false; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, base.str); if (lc != nil) { hdr_lea = true; @@ -7045,9 +7045,9 @@ fn cginsert(c: *cgen, n: *node) void = { }; // (*p)[i]: the header lives behind a local ptr-to-slice — // delete's regex_shape twin. - if (!hdr_ok && base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR && base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (!hdr_ok && base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR && base.lhs != nil) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let pc: *local = localfindnode(c, base.lhs.str); if (pc != nil) { hdr_off = pc.off; @@ -7241,21 +7241,21 @@ fn cginsert(c: *cgen, n: *node) void = { emitline("\tADDQ\t$24, SP\n"); }; -fn cgcall(c: *cgen, n: *node) void = { +fn cgcall(c: *cgen, n: *syntax.node) void = { // Hare-style `append(s, v)` / `append(s, items...)` builtin — // special-cased before pushargsrev so the spread variant can run // a counted loop over the items slice instead of a normal call. - let callee: *node = n.lhs; + let callee: *syntax.node = n.lhs; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { // abort([msg]) / assert(cond[, msg]) — checker-tagged // builtins (callee TY_ERR is the routing key, cstage's // `lhs->type == ty_err` at cmd/w6c/cgen.c:6618,6645); // lower to rt_abort. A user-shadowed abort/assert is // untagged and stays on the regular call path (#58). - let bti: *tinfo = callee.type_: *tinfo; - if (bti != nil && bti.kind == tykind.TY_ERR) { - if (streq(callee.str, "abort")) { + let bti: *syntax.tinfo = callee.type_: *syntax.tinfo; + if (bti != nil && bti.kind == syntax.tykind.TY_ERR) { + if (syntax.streq(callee.str, "abort")) { if (n.list != nil) { cgexpr(c, n.list); emitline("\tMOVQ\tAX, DI\n"); @@ -7267,14 +7267,14 @@ fn cgcall(c: *cgen, n: *node) void = { emitline("\tCALL\trt_abort(SB)\n"); return; }; - if (streq(callee.str, "assert") && n.list != nil) { + if (syntax.streq(callee.str, "assert") && n.list != nil) { cgexpr(c, n.list); let skip: str = mklabel(c, "as"); emitline("\tCMPQ\t$0, AX\n"); emitline("\tJNE\t"); emitline(skip); emitline("\n"); - let msg: *node = n.list.next; + let msg: *syntax.node = n.list.next; if (msg != nil) { cgexpr(c, msg); emitline("\tMOVQ\tAX, DI\n"); @@ -7288,7 +7288,7 @@ fn cgcall(c: *cgen, n: *node) void = { return; }; }; - if (streq(callee.str, "append")) { + if (syntax.streq(callee.str, "append")) { if (n.list != nil) { if (n.list.next != nil) { cgappend(c, n); @@ -7307,7 +7307,7 @@ fn cgcall(c: *cgen, n: *node) void = { // scope_lookup_prefer gating on the `abort` precedent; // without it, the bare same-module call lands in the // typed-builtin path and shadows the user decl. Task #23. - if (streq(callee.str, "alloc")) { + if (syntax.streq(callee.str, "alloc")) { if (n.list != nil) { if (!samemodfn(c, "alloc")) { cgalloc(c, n); @@ -7333,20 +7333,20 @@ fn cgcall(c: *cgen, n: *node) void = { // DATA POINTER as the length. Non-place operands (call // result, slicing expr, string literal — previously the same // silent ptr-garbage) die LOUD per rule 7. - if (streq(callee.str, "len")) { + if (syntax.streq(callee.str, "len")) { if (n.list != nil) { - let a: *node = n.list; - let at: *tinfo = a.type_: *tinfo; - let u: *tinfo = at; + let a: *syntax.node = n.list; + let at: *syntax.tinfo = a.type_: *syntax.tinfo; + let u: *syntax.tinfo = at; u = tichase(u); let hdrish: bool = false; if (u != nil) { - if (u.kind == tykind.TY_SLICE - || u.kind == tykind.TY_STR) { + if (u.kind == syntax.tykind.TY_SLICE + || u.kind == syntax.tykind.TY_STR) { hdrish = true; }; }; - if (hdrish && a.kind == nkind.N_IDENT) { + if (hdrish && a.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.str); if (lc != nil) { emitline("\tMOVQ\t"); @@ -7383,20 +7383,20 @@ fn cgcall(c: *cgen, n: *node) void = { // directly at BP + element_off + 8, mirroring // the N_IDENT slice arm above and the // tuple-field-offset walk (cgenexpr.ww N_TTUPLE). - if (hdrish && a.kind == nkind.N_DOT + if (hdrish && a.kind == syntax.nkind.N_DOT && a.lhs != nil - && a.lhs.kind == nkind.N_IDENT) { + && a.lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.lhs.str); if (lc != nil) { - let tn: *node = lc.tnode; - for (tn != nil && tn.kind == nkind.N_TNAME) { + let tn: *syntax.node = lc.tnode; + for (tn != nil && tn.kind == syntax.nkind.N_TNAME) { tn = aliaslookup(c, tn.str); }; if (tn != nil) { - if (tn.kind == nkind.N_TTUPLE) { + if (tn.kind == syntax.nkind.N_TTUPLE) { let idx: i32 = fldnumidx(a.str); if (idx >= 0) { - let tp: *node = tn.list; + let tp: *syntax.node = tn.list; let foff: i32 = 0; let i: i32 = 0; for (i < idx) { @@ -7426,15 +7426,15 @@ fn cgcall(c: *cgen, n: *node) void = { // hit; twin of the cgdot global-tuple // arm and cstage's #235 global base. if (lc == nil) { - let gtn: *node = letvartnode(c, a.lhs.str); - for (gtn != nil && gtn.kind == nkind.N_TNAME) { + let gtn: *syntax.node = letvartnode(c, a.lhs.str); + for (gtn != nil && gtn.kind == syntax.nkind.N_TNAME) { gtn = aliaslookup(c, gtn.str); }; if (gtn != nil) { - if (gtn.kind == nkind.N_TTUPLE) { + if (gtn.kind == syntax.nkind.N_TTUPLE) { let gidx: i32 = fldnumidx(a.str); if (gidx >= 0) { - let gtp: *node = gtn.list; + let gtp: *syntax.node = gtn.list; let gfoff: i32 = 0; let gi: i32 = 0; for (gi < gidx) { @@ -7472,13 +7472,13 @@ fn cgcall(c: *cgen, n: *node) void = { // the same MOVQ BX,AX shape as the #14 .len // pseudo-field fix. Same family as #18 (shared // cstage==wwstage gap, not rule-10). - if (hdrish && a.kind == nkind.N_INDEX) { + if (hdrish && a.kind == syntax.nkind.N_INDEX) { cgexpr(c, a); emitline("\tMOVQ\tBX, AX\n"); return; }; if (u != nil) { - if (u.kind == tykind.TY_ARRAY) { + if (u.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(u.alen: i64); emitline(", AX\n"); @@ -7509,7 +7509,7 @@ fn cgcall(c: *cgen, n: *node) void = { // so Hare code ports verbatim with its side effects // intact. Pre-#27 wwstage fell through to a generic // CALL free → undefined reference at link. - if (streq(callee.str, "free")) { + if (syntax.streq(callee.str, "free")) { if (n.list != nil) { if (n.list.next == nil) { cgexpr(c, n.list); @@ -7521,10 +7521,10 @@ fn cgcall(c: *cgen, n: *node) void = { // delete-half + fold-5a P2 range form; mirror of // cstage cgen.c's N_CALL delete arm (which branches // on d->kind == N_SLICE internally). - if (streq(callee.str, "delete")) { + if (syntax.streq(callee.str, "delete")) { if (n.list != nil) { if (n.list.next == nil) { - if (n.list.kind == nkind.N_SLICE) { + if (n.list.kind == syntax.nkind.N_SLICE) { cgdeleterange(c, n); return; }; @@ -7535,7 +7535,7 @@ fn cgcall(c: *cgen, n: *node) void = { }; // insert(xs[idx], v) — #35 insert-half; mirror of // cstage cgen.c's N_CALL insert arm. - if (streq(callee.str, "insert")) { + if (syntax.streq(callee.str, "insert")) { if (n.list != nil) { if (n.list.next != nil) { if (n.list.next.next == nil) { @@ -7558,15 +7558,15 @@ fn cgcall(c: *cgen, n: *node) void = { // fast path and dropped the variant tag word on widened slice args. // Cstage finds params via the checker-set `n->lhs->type`, sidestepping // the name-driven registry entirely (cmd/w6c/cgen.c:4161-4165). - let calleeparams: *node = nil; + let calleeparams: *syntax.node = nil; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { calleeparams = fnparamslookup(c, callee.str); - } else { if (callee.kind == nkind.N_DOT) { + } else { if (callee.kind == syntax.nkind.N_DOT) { let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; @@ -7586,37 +7586,37 @@ fn cgcall(c: *cgen, n: *node) void = { // nvar>0, vararg_sl always — keeping later match labels aligned. { let nfixed_v: i32 = 0; - let varp: *node = callee_variadic_param(c, callee, &nfixed_v); + let varp: *syntax.node = callee_variadic_param(c, callee, &nfixed_v); if (varp != nil) { let nargs0: i32 = 0; - let aw: *node = n.list; + let aw: *syntax.node = n.list; for (aw != nil) { nargs0 += 1; aw = aw.next; }; let nvar: i32 = nargs0 - nfixed_v; if (nvar < 0) { nvar = 0; }; let forwarding: bool = false; if (nvar == 1) { - let aaf: *node = n.list; + let aaf: *syntax.node = n.list; let kk: i32 = 0; for (kk < nfixed_v) { aaf = aaf.next; kk += 1; }; if (aaf != nil) { - if (aaf.kind == nkind.N_SPREAD) { + if (aaf.kind == syntax.nkind.N_SPREAD) { forwarding = true; }; }; }; if (forwarding) { - let prev: *node = nil; - let cur2: *node = n.list; + let prev: *syntax.node = nil; + let cur2: *syntax.node = n.list; let kk2: i32 = 0; for (kk2 < nfixed_v) { prev = cur2; cur2 = cur2.next; kk2 += 1; }; - let inner: *node = cur2.lhs; + let inner: *syntax.node = cur2.lhs; if (inner != nil) { inner.next = nil; }; if (prev == nil) { n.list = inner; } else { prev.next = inner; }; @@ -7636,14 +7636,14 @@ fn cgcall(c: *cgen, n: *node) void = { // .lhs; Ken's gate: only deref when the wrap // shape is confirmed N_TSLICE (mirrors cstage // cgen.c:4352 `vsu->kind == TY_SLICE` guard). - let velem: *node = varp.lhs; + let velem: *syntax.node = varp.lhs; if (varp.lhs != nil - && varp.lhs.kind == nkind.N_TSLICE) { + && varp.lhs.kind == syntax.nkind.N_TSLICE) { velem = varp.lhs.lhs; }; let esz: i32 = 8; if (velem != nil) { - if (velem.kind == nkind.N_TNAME) { + if (velem.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, velem.str); if (ps > 0) { esz = ps; } else { esz = slotsize(c, velem); }; @@ -7657,7 +7657,7 @@ fn cgcall(c: *cgen, n: *node) void = { // gather buffer — unwired (rule 7). cstage twin // guards before its v_is_tagged gather. if (velem != nil) { - if (taggedmemargsize(velem.type_: *tinfo) > 0) { + if (taggedmemargsize(velem.type_: *syntax.tinfo) > 0) { let mv: str = "#38b: >48B tagged variadic element unwired\n"; os.write(2, mv.ptr, mv.len: u64); os.exit(1); @@ -7685,14 +7685,14 @@ fn cgcall(c: *cgen, n: *node) void = { let sname: str = mklabel(c, "vararg_sl"); let soff: i32 = localadd(c, sname, tyslicesize(): i32, varp.lhs); - let aa2: *node = n.list; + let aa2: *syntax.node = n.list; let kk3: i32 = 0; for (kk3 < nfixed_v) { aa2 = aa2.next; kk3 += 1; }; let j: i32 = 0; - let prevarg: *node = n.list; + let prevarg: *syntax.node = n.list; if (nfixed_v == 0) { prevarg = nil; } else { let kk4: i32 = 0; @@ -7707,7 +7707,7 @@ fn cgcall(c: *cgen, n: *node) void = { // dst is the per-element tagged type; // pass velem (cstage cgen.c:4382 passes // velem, not the slice wrap vsu). - cgwidentaggedstore(c, velem.type_: *tinfo, + cgwidentaggedstore(c, velem.type_: *syntax.tinfo, aa2, "BP", slot, esz); } else { if (velemstr) { cgexpr(c, aa2); @@ -7759,7 +7759,7 @@ fn cgcall(c: *cgen, n: *node) void = { emitline("\tMOVQ\tAX, "); emitoff((soff + 16): i64); emitline("(BP)\n"); - let sn: *node = newnode(nkind.N_IDENT, + let sn: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, "", 0, 0); sn.str = sname; // Synthesised after the checker has run, so the @@ -7791,7 +7791,7 @@ fn cgcall(c: *cgen, n: *node) void = { let sretcalloff: i32 = 0; // #220: GLOBAL dest — RDI gets `LEAQ name(SB)` below; no @sretscr // slot (the callee writes the struct straight into g's storage). - let sretdestn: *node = nil; + let sretdestn: *syntax.node = nil; if (sretcs > 0) { if (c.sretdestnode != nil) { sretdestn = c.sretdestnode; @@ -7814,8 +7814,8 @@ fn cgcall(c: *cgen, n: *node) void = { let intidx: i32 = 0; if (sretcs > 0) { intidx = 1; }; let fpidx: i32 = 0; - let a: *node = n.list; - let dparam: *node = calleeparams; + let a: *syntax.node = n.list; + let dparam: *syntax.node = calleeparams; let popped: i32 = 0; let stackslots: i32 = 0; for (a != nil) { @@ -7825,15 +7825,15 @@ fn cgcall(c: *cgen, n: *node) void = { // pushargsrev (a widened concrete arg is mem-class only // via its param). let dmemsz: i32 = 0; - if (dparam != nil) { if (dparam.kind == nkind.N_PARAM) { - if (dparam.op != tkind.TK_ELLIPSIS) { + if (dparam != nil) { if (dparam.kind == syntax.nkind.N_PARAM) { + if (dparam.op != syntax.tkind.TK_ELLIPSIS) { if (dparam.lhs != nil) { - dmemsz = taggedmemargsize(dparam.lhs.type_: *tinfo); + dmemsz = taggedmemargsize(dparam.lhs.type_: *syntax.tinfo); }; }; }; }; if (dmemsz == 0) { - dmemsz = taggedmemargsize(a.type_: *tinfo); + dmemsz = taggedmemargsize(a.type_: *syntax.tinfo); }; if (dmemsz > 0) { if (dparam != nil) { dparam = dparam.next; }; @@ -7872,9 +7872,9 @@ fn cgcall(c: *cgen, n: *node) void = { }; let fk: i32 = 0; if (a != nil) { - let at: *tinfo = a.type_: *tinfo; - if (typeisf32(at)) { fk = 1; } - else { if (typeisfloat(at)) { fk = 2; }; }; + let at: *syntax.tinfo = a.type_: *syntax.tinfo; + if (syntax.typeisf32(at)) { fk = 1; } + else { if (syntax.typeisfloat(at)) { fk = 2; }; }; }; if (fk != 0) { let mov: str = "MOVSD"; @@ -7896,17 +7896,17 @@ fn cgcall(c: *cgen, n: *node) void = { // tuple LITERAL arg (the declared-tagged box words pop // together with the i64 that follows), mirroring the // param-aware send; else the source tuple type. - let dptt: *node = nil; - if (a.kind == nkind.N_TUPLE) { if (dparam != nil) { - if (dparam.kind == nkind.N_PARAM && dparam.lhs != nil) { - let dtn2: *node = dparam.lhs; - for (dtn2 != nil && dtn2.kind == nkind.N_TNAME) { + let dptt: *syntax.node = nil; + if (a.kind == syntax.nkind.N_TUPLE) { if (dparam != nil) { + if (dparam.kind == syntax.nkind.N_PARAM && dparam.lhs != nil) { + let dtn2: *syntax.node = dparam.lhs; + for (dtn2 != nil && dtn2.kind == syntax.nkind.N_TNAME) { dtn2 = aliaslookup(c, dtn2.str); }; - if (dtn2 != nil) { if (dtn2.kind == nkind.N_TTUPLE) { dptt = dtn2; }; }; + if (dtn2 != nil) { if (dtn2.kind == syntax.nkind.N_TTUPLE) { dptt = dtn2; }; }; }; }; }; - let tuparg: *node = dptt; + let tuparg: *syntax.node = dptt; if (tuparg == nil) { tuparg = nodetuplearg(c, a); }; if (tuparg != nil) { // #163/#32: drain the tuple's staged words (slot+0 @@ -7922,10 +7922,10 @@ fn cgcall(c: *cgen, n: *node) void = { // them (kind-discriminated twin walk). The param-aware // path (dptt) walks declared element TYPE nodes. let tuplit: bool = false; - if (dptt == nil) { if (tuparg.kind == nkind.N_TUPLE) { tuplit = true; }; }; - let p: *node = tuparg.list; + if (dptt == nil) { if (tuparg.kind == syntax.nkind.N_TUPLE) { tuplit = true; }; }; + let p: *syntax.node = tuparg.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (tuplit) { et = p; }; if (isfloattype(c, et)) { if (fpidx >= 8) { @@ -7974,7 +7974,7 @@ fn cgcall(c: *cgen, n: *node) void = { }; } else { let stfc: i32 = 0; - if (a.kind == nkind.N_IDENT) { + if (a.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.str); if (lc != nil) { stfc = structfloatclass(c, lc.tnode); } else { @@ -7984,7 +7984,7 @@ fn cgcall(c: *cgen, n: *node) void = { // class off the global's declared tnode (letvartnode), the same // SysV classification the local path uses. cstage keys // structfloatclass off the operand TYPE, not a local slot. - let gtn: *node = letvartnode(c, a.str); + let gtn: *syntax.node = letvartnode(c, a.str); if (gtn != nil) { stfc = structfloatclass(c, gtn); }; }; }; @@ -8044,7 +8044,7 @@ fn cgcall(c: *cgen, n: *node) void = { // drain exactly that many so intidx tracks per-arg // (the ≤16B struct IDENT case is the stfc branch // above). Mirror of cstage node_isaggarg drain arm. - let aggsz: i32 = aggargsizetn(a.type_: *tinfo); + let aggsz: i32 = aggargsizetn(a.type_: *syntax.tinfo); if (aggsz > 0) { extra = (aggsz + 7) / 8 - 1; }; let words: i32 = 1 + extra; let w: i32 = 0; @@ -8107,7 +8107,7 @@ fn cgcall(c: *cgen, n: *node) void = { // the linker rightly fails. let isfnptrcall: bool = false; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { let cn: str = callee.str; if (localfindnode(c, cn) != nil) { isfnptrcall = true; @@ -8122,28 +8122,28 @@ fn cgcall(c: *cgen, n: *node) void = { // `CALL (SB)` (empty symbol) for the N_UN-callee shape — the // IDENT/DOT name-emit branches missed and isfnptrcall stayed // false. - if (callee.kind != nkind.N_IDENT - && callee.kind != nkind.N_DOT) { + if (callee.kind != syntax.nkind.N_IDENT + && callee.kind != syntax.nkind.N_DOT) { isfnptrcall = true; }; - if (callee.kind == nkind.N_DOT) { - let base: *node = callee.lhs; + if (callee.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = callee.lhs; let fld: str = callee.str; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; let lc: *local = localfindnode(c, bn); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - let lkind: nkind = tn.kind; + let lkind: syntax.nkind = tn.kind; let sname: str; sname.ptr = nil; sname.len = 0; - if (lkind == nkind.N_TNAME) { sname = tn.str; }; - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TNAME) { sname = tn.str; }; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; }; if (sname.len > 0) { @@ -8152,10 +8152,10 @@ fn cgcall(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { - let ft: *node = fi.tnode; + if (syntax.streq(fn_, fld)) { + let ft: *syntax.node = fi.tnode; if (ft != nil) { - if (ft.kind == nkind.N_TFN) { + if (ft.kind == syntax.nkind.N_TFN) { isfnptrcall = true; }; }; @@ -8210,12 +8210,12 @@ fn cgcall(c: *cgen, n: *node) void = { } else { emitline("\tCALL\t"); if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { // Bare `f()` — same-module by ww's resolver, // so c.curmod is the disambiguation hint. calleename = callee.str; emitfnname(c, calleename, c.curmod); - } else { if (callee.kind == nkind.N_DOT) { + } else { if (callee.kind == syntax.nkind.N_DOT) { // `m.f()` — pass the explicit module bareword // so cross-module same-leaf exports resolve. calleename = callee.str; @@ -8223,7 +8223,7 @@ fn cgcall(c: *cgen, n: *node) void = { hint.ptr = nil; hint.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { hint = usehint(c, callee.lhs.str); }; }; @@ -8246,8 +8246,8 @@ fn cgcall(c: *cgen, n: *node) void = { return; }; -fn cgassign(c: *cgen, n: *node) void = { - let lhs: *node = n.lhs; +fn cgassign(c: *cgen, n: *syntax.node) void = { + let lhs: *syntax.node = n.lhs; // #145 (c1.5a): bulk slice-copy-assign `s.arr[lo:hi] = bs` (LHS is // N_SLICE). No legacy cgassign arm catches N_SLICE — the statement // silently emitted nothing (both stages, byte-id-green, #263-class). @@ -8259,8 +8259,8 @@ fn cgassign(c: *cgen, n: *node) void = { // the length is RUNTIME (w6a has no REP/MOVSB). Only plain `=`. The // Hare len(bs)==hi-lo assert is task #149 (rule-7: documented, not a // c2 blocker — appendlit's lengths are equal by construction). - if (lhs != nil) { if (lhs.kind == nkind.N_SLICE - && n.op == tkind.TK_ASSIGN) { + if (lhs != nil) { if (lhs.kind == syntax.nkind.N_SLICE + && n.op == syntax.tkind.TK_ASSIGN) { let esz: i32 = slicebaseesz(c, lhs.lhs); cgexpr(c, lhs); if (esz > 1) { @@ -8303,20 +8303,20 @@ fn cgassign(c: *cgen, n: *node) void = { let placeslit: bool = false; let placedotidx: bool = false; if (lhs != nil) { - if (lhs.kind == nkind.N_DOT && lhs.lhs != nil) { - if (lhs.lhs.kind == nkind.N_INDEX) { + if (lhs.kind == syntax.nkind.N_DOT && lhs.lhs != nil) { + if (lhs.lhs.kind == syntax.nkind.N_INDEX) { placedotidx = true; }; }; - if ((lhs.kind == nkind.N_INDEX - || (lhs.kind == nkind.N_UN && lhs.op == tkind.TK_STAR) + if ((lhs.kind == syntax.nkind.N_INDEX + || (lhs.kind == syntax.nkind.N_UN && lhs.op == syntax.tkind.TK_STAR) || placedotidx) - && n.op == tkind.TK_ASSIGN && n.rhs != nil) { - if (n.rhs.kind == nkind.N_STRUCTLIT) { - let iet: *tinfo = lhs.type_: *tinfo; + && n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil) { + if (n.rhs.kind == syntax.nkind.N_STRUCTLIT) { + let iet: *syntax.tinfo = lhs.type_: *syntax.tinfo; iet = tichase(iet); if (iet != nil) { - if (iet.kind == tykind.TY_STRUCT) { + if (iet.kind == syntax.tykind.TY_STRUCT) { placeslit = true; }; }; @@ -8331,14 +8331,14 @@ fn cgassign(c: *cgen, n: *node) void = { // (byte-id-pinned). Mirror of cstage deref_agg. let derefagg: bool = false; if (lhs != nil) { - if (lhs.kind == nkind.N_UN && lhs.op == tkind.TK_STAR - && n.op == tkind.TK_ASSIGN) { - let du: *tinfo = lhs.type_: *tinfo; + if (lhs.kind == syntax.nkind.N_UN && lhs.op == syntax.tkind.TK_STAR + && n.op == syntax.tkind.TK_ASSIGN) { + let du: *syntax.tinfo = lhs.type_: *syntax.tinfo; du = tichase(du); if (du != nil) { - if (du.kind == tykind.TY_STRUCT - || du.kind == tykind.TY_ARRAY - || du.kind == tykind.TY_TUPLE) { + if (du.kind == syntax.tykind.TY_STRUCT + || du.kind == syntax.tykind.TY_ARRAY + || du.kind == syntax.tykind.TY_TUPLE) { derefagg = true; }; }; @@ -8348,9 +8348,9 @@ fn cgassign(c: *cgen, n: *node) void = { // write nothing. Detected by lhs being an nkind.N_IDENT with empty str // (planted by parseprimary on the tkind.TK_UNDER token). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { if (lhs.str.len == 0) { - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { cgexpr(c, n.rhs); return; }; @@ -8362,12 +8362,12 @@ fn cgassign(c: *cgen, n: *node) void = { // decl-init fills. Pre-#32 the same scalar tail zeroed one // word silently; die loud until the fill lands. Slice-typed // places are already loud in the checker. - if (n.op == tkind.TK_ASSIGN && lhs != nil && n.rhs != nil) { - if (n.rhs.kind == nkind.N_ARRLIT) { - let alt: *tinfo = lhs.type_: *tinfo; + if (n.op == syntax.tkind.TK_ASSIGN && lhs != nil && n.rhs != nil) { + if (n.rhs.kind == syntax.nkind.N_ARRLIT) { + let alt: *syntax.tinfo = lhs.type_: *syntax.tinfo; alt = tichase(alt); if (alt != nil) { - if (alt.kind == tykind.TY_ARRAY) { + if (alt.kind == syntax.tykind.TY_ARRAY) { let mal: str = "array-literal store at assignment unwired (task #32)\n"; os.write(2, mal.ptr, mal.len: u64); os.exit(1); @@ -8383,10 +8383,10 @@ fn cgassign(c: *cgen, n: *node) void = { // guard. Plain `=` (the tagged-ident reassign arm just below) is // untouched. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT && n.op != tkind.TK_ASSIGN) { - let itu: *tinfo = tichase(lhs.type_: *tinfo); + if (lhs.kind == syntax.nkind.N_IDENT && n.op != syntax.tkind.TK_ASSIGN) { + let itu: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); if (itu != nil) { - if (itu.kind == tykind.TY_TAGGED) { + if (itu.kind == syntax.tykind.TY_TAGGED) { let m21: str = "ident compound on tagged not wired (#21/rule-7)\n"; os.write(2, m21.ptr, m21.len: u64); os.exit(1); @@ -8399,8 +8399,8 @@ fn cgassign(c: *cgen, n: *node) void = { // as cglet's tagged-init). Covers nullable fold, tagged source, // struct payload, str payload, scalar payload, with tag remap. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - if (n.op == tkind.TK_ASSIGN) { + if (lhs.kind == syntax.nkind.N_IDENT) { + if (n.op == syntax.tkind.TK_ASSIGN) { let lc: *local = localfindnode(c, lhs.str); if (lc != nil) { if (istaggedtype(c, lc.tnode)) { @@ -8413,20 +8413,20 @@ fn cgassign(c: *cgen, n: *node) void = { // arm + the generic sret receive. let asret: i32 = 0; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { + if (n.rhs.kind == syntax.nkind.N_CALL) { asret = callsretsize(c, n.rhs); }; }; if (asret > 0) { - let aru: *tinfo = n.rhs.type_: *tinfo; + let aru: *syntax.tinfo = n.rhs.type_: *syntax.tinfo; aru = tichase(aru); - let alu: *tinfo = lc.tnode.type_: *tinfo; + let alu: *syntax.tinfo = lc.tnode.type_: *syntax.tinfo; alu = tichase(alu); let aexact: bool = false; if (aru != nil && aru == alu) { aexact = true; } else { - if (typeeq(n.rhs.type_: *tinfo, - lc.tnode.type_: *tinfo)) { + if (syntax.typeeq(n.rhs.type_: *syntax.tinfo, + lc.tnode.type_: *syntax.tinfo)) { aexact = true; }; }; @@ -8441,7 +8441,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; let lsz: i32 = slotsize(c, lc.tnode); - cgwidentaggedstore(c, lc.tnode.type_: *tinfo, + cgwidentaggedstore(c, lc.tnode.type_: *syntax.tinfo, n.rhs, "BP", lc.off, lsz); return; }; @@ -8449,10 +8449,10 @@ fn cgassign(c: *cgen, n: *node) void = { // #38b: sret receive into a tagged GLOBAL // lvalue unwired (rule 7; cstage twin fatals). if (lc == nil && n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { - let gru: *tinfo = lhs.type_: *tinfo; + if (n.rhs.kind == syntax.nkind.N_CALL) { + let gru: *syntax.tinfo = lhs.type_: *syntax.tinfo; gru = tichase(gru); - if (gru != nil && gru.kind == tykind.TY_TAGGED + if (gru != nil && gru.kind == syntax.tykind.TY_TAGGED && callsretsize(c, n.rhs) > 0) { let m38g: str = "#38b: sret receive into a tagged GLOBAL lvalue unwired\n"; os.write(2, m38g.ptr, m38g.len: u64); @@ -8467,14 +8467,14 @@ fn cgassign(c: *cgen, n: *node) void = { // scalar store below clobbered the tag word. cstage drops the // store entirely — cs!=ww residual until the cstage half (#41). if (lc == nil) { - let gtn: *node = letvartnode(c, lhs.str); + let gtn: *syntax.node = letvartnode(c, lhs.str); if (gtn != nil) { if (istaggedtype(c, gtn)) { let gsz: i32 = slotsize(c, gtn); emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), BX\n"); - cgwidentaggedstore(c, gtn.type_: *tinfo, n.rhs, "BX", 0, gsz); + cgwidentaggedstore(c, gtn.type_: *syntax.tinfo, n.rhs, "BX", 0, gsz); return; }; }; @@ -8491,11 +8491,11 @@ fn cgassign(c: *cgen, n: *node) void = { // truncates to one word here — task #31 A/E/G; struct-lit // diverts at the placeslit gate, array-lit dies loud (#32). if (lhs != nil) { - if (lhs.kind == nkind.N_UN) { - if (lhs.op == tkind.TK_STAR) { - if (n.op == tkind.TK_ASSIGN && !placeslit + if (lhs.kind == syntax.nkind.N_UN) { + if (lhs.op == syntax.tkind.TK_STAR) { + if (n.op == syntax.tkind.TK_ASSIGN && !placeslit && !derefagg) { - let inner: *node = lhs.lhs; + let inner: *syntax.node = lhs.lhs; // #17: tagged-union pointee. The single-store // tail below writes rhs into the tag word only, // dropping the payload and corrupting the union. @@ -8505,8 +8505,8 @@ fn cgassign(c: *cgen, n: *node) void = { // word-copy scratch -> *p. Mirror of the runtime- // index tagged element arm (cgenexpr.ww:8768) and // the cstage twin (cmd/w6c/cgen.c #17 deref arm). - let du: *tinfo = tichase(lhs.type_: *tinfo); - if (du != nil && du.kind == tykind.TY_TAGGED) { + let du: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); + if (du != nil && du.kind == syntax.tykind.TY_TAGGED) { let ssz: i32 = du.size: i32; let scr: i32 = tagscradd(c, ssz); emitline("\tXORQ\tAX, AX\n"); @@ -8537,18 +8537,18 @@ fn cgassign(c: *cgen, n: *node) void = { let elemf32: bool = false; let storeop: str = "MOVQ"; if (inner != nil) { - if (inner.kind == nkind.N_IDENT) { + if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TPTR) { - let pe: *node = tn.lhs; + if (tn.kind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = tn.lhs; if (pe != nil) { - if (pe.kind == nkind.N_TNAME) { - if (streq(pe.str, "str")) { elemstr = true; } - else { if (streq(pe.str, "f64")) { elemfloat = true; } - else { if (streq(pe.str, "f32")) { elemfloat = true; elemf32 = true; } + if (pe.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(pe.str, "str")) { elemstr = true; } + else { if (syntax.streq(pe.str, "f64")) { elemfloat = true; } + else { if (syntax.streq(pe.str, "f32")) { elemfloat = true; elemf32 = true; } else { // primsize-ok (#101/#109): this site OWNS its own ps==0 // typenodeprimresolved chase below — routing through @@ -8581,7 +8581,7 @@ fn cgassign(c: *cgen, n: *node) void = { // deref-store stays 1-word, the SAME divergence // str carries; resolved-vs-syntactic detection // is unified UP in #80, not patched here. - if (pe.kind == nkind.N_TSLICE) { elemstr = true; }; + if (pe.kind == syntax.nkind.N_TSLICE) { elemstr = true; }; }; }; }; @@ -8646,8 +8646,8 @@ fn cgassign(c: *cgen, n: *node) void = { // no-op — exactly the trap that broke fmt.println). Mirror of // cmd/w6c/cgen.c's N_UN/TK_STAR compound branch. if (lhs != nil) { - if (lhs.kind == nkind.N_UN) { - if (lhs.op == tkind.TK_STAR) { + if (lhs.kind == syntax.nkind.N_UN) { + if (lhs.op == syntax.tkind.TK_STAR) { // Size gate (mirror cstage cgen.c handled=sz∈{1,2,4,8}): // a tagged (or any non-scalar) pointee is not a // meaningful compound target — skip this single-word @@ -8656,24 +8656,24 @@ fn cgassign(c: *cgen, n: *node) void = { // (#18). Without it the MOVQ default below clobbers the // tag word and returns: a silent miscompile. let psz: i32 = 8; - let lt: *tinfo = lhs.type_: *tinfo; + let lt: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (lt != nil) { psz = lt.size: i32; }; let scalarpointee: bool = (psz == 1 || psz == 2 || psz == 4 || psz == 8); - if (n.op != tkind.TK_ASSIGN && scalarpointee) { - let inner: *node = lhs.lhs; + if (n.op != syntax.tkind.TK_ASSIGN && scalarpointee) { + let inner: *syntax.node = lhs.lhs; let loadop: str = "MOVQ"; let storeop: str = "MOVQ"; // Pointee node for the lhs-sign side of the /= // and %= dispatch. Mirror of cstage's `vt` at // cmd/w6c/cgen.c's TK_STAR-compound branch. - let pe: *node = nil; + let pe: *syntax.node = nil; if (inner != nil) { - if (inner.kind == nkind.N_IDENT) { + if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TPTR) { + if (tn.kind == syntax.nkind.N_TPTR) { pe = tn.lhs; if (pe != nil) { let ps: i32 = fieldsize(c, pe); @@ -8703,12 +8703,12 @@ fn cgassign(c: *cgen, n: *node) void = { // RSHIFTEQ can route SHRQ vs SARQ on the same key. let unsignd: bool = false; if (pe != nil) { - unsignd = typeisunsigned(pe.type_: *tinfo); + unsignd = syntax.typeisunsigned(pe.type_: *syntax.tinfo); }; if (!unsignd) { unsignd = nodeisunsigned(c, n.rhs); }; - if (n.op == tkind.TK_SLASHEQ || n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ || n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); @@ -8716,7 +8716,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { emitline("\tMOVQ\tDX, AX\n"); }; emitline("\t"); @@ -8725,14 +8725,14 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; let combineop: str = "MOVQ"; - if (n.op == tkind.TK_PLUSEQ) { combineop = "ADDQ"; } - else { if (n.op == tkind.TK_MINUSEQ) { combineop = "SUBQ"; } - else { if (n.op == tkind.TK_STAREQ) { combineop = "IMULQ"; } - else { if (n.op == tkind.TK_AMPEQ) { combineop = "ANDQ"; } - else { if (n.op == tkind.TK_PIPEEQ) { combineop = "ORQ"; } - else { if (n.op == tkind.TK_CARETEQ) { combineop = "XORQ"; } - else { if (n.op == tkind.TK_LSHIFTEQ) { combineop = "SHLQ"; } - else { if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { combineop = "ADDQ"; } + else { if (n.op == syntax.tkind.TK_MINUSEQ) { combineop = "SUBQ"; } + else { if (n.op == syntax.tkind.TK_STAREQ) { combineop = "IMULQ"; } + else { if (n.op == syntax.tkind.TK_AMPEQ) { combineop = "ANDQ"; } + else { if (n.op == syntax.tkind.TK_PIPEEQ) { combineop = "ORQ"; } + else { if (n.op == syntax.tkind.TK_CARETEQ) { combineop = "XORQ"; } + else { if (n.op == syntax.tkind.TK_LSHIFTEQ) { combineop = "SHLQ"; } + else { if (n.op == syntax.tkind.TK_RSHIFTEQ) { // #136: signed RSHIFTEQ → SARQ. if (unsignd) { combineop = "SHRQ"; } else { combineop = "SARQ"; }; @@ -8752,20 +8752,20 @@ fn cgassign(c: *cgen, n: *node) void = { // Array/slice/ptr index store: `arr[i] = v;`. Element size // from base.tnode picks MOVB vs MOVQ. if (lhs != nil) { - if (lhs.kind == nkind.N_INDEX && !placeslit) { - if (n.op == tkind.TK_ASSIGN) { - let base: *node = lhs.lhs; - let idx: *node = lhs.rhs; + if (lhs.kind == syntax.nkind.N_INDEX && !placeslit) { + if (n.op == syntax.tkind.TK_ASSIGN) { + let base: *syntax.node = lhs.lhs; + let idx: *syntax.node = lhs.rhs; let esz: i32 = 8; let baselocal: *local = nil; let isglobalarr: bool = false; let isglobalptr: bool = false; let globalname: str; globalname.ptr = nil; globalname.len = 0; - let elemtn: *node = nil; + let elemtn: *syntax.node = nil; let basealias: bool = false; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal != nil) { @@ -8793,23 +8793,23 @@ fn cgassign(c: *cgen, n: *node) void = { // picks MOVB on the store arm, and the compound // arm's str/slice hard-error still fires on a // []str element). - let tn: *node = letvartnode(c, bn); + let tn: *syntax.node = letvartnode(c, bn); if (tn != nil) { globalname = bn; esz = elemsizeofc(c, tn); // idxelemtn: `*[N]T` drill, see the // local branch above (#61). elemtn = idxelemtn(tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; }; }; }; - } else { if (base.kind == nkind.N_DOT - || (base.kind == nkind.N_UN - && base.op == tkind.TK_STAR)) { + } else { if (base.kind == syntax.nkind.N_DOT + || (base.kind == syntax.nkind.N_UN + && base.op == syntax.tkind.TK_STAR)) { // lhs.type_ is the checker-stamped element tinfo // of the N_INDEX: esz is its natural size and the // tagged-element gate (below) reads the same @@ -8817,9 +8817,9 @@ fn cgassign(c: *cgen, n: *node) void = { // (#60/#72). cstage idx_eff(base->type)->sub->size // (cmd/w6c/cgen.c:3517-18). N_UN deref base // (`(*p)[i] = v`, #61 C): same stamped source. - let dt: *tinfo = lhs.type_: *tinfo; + let dt: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (dt != nil) { esz = dt.size: i32; elemtn = lhs; }; - } else { if (base.kind == nkind.N_INDEX) { + } else { if (base.kind == syntax.nkind.N_INDEX) { // Chained-write write-side parallel of the // cgindex N_INDEX-base arm (#24): `names[i][k] // = v` (names: **u8) — outer element is u8 so @@ -8830,7 +8830,7 @@ fn cgassign(c: *cgen, n: *node) void = { // (#69/#61d, mirror #60). cstage: esz = // idx_eff(base->type)->sub->size // (cmd/w6c/cgen.c:3517-3518). - let et: *tinfo = lhs.type_: *tinfo; + let et: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (et != nil) { esz = et.size: i32; elemtn = lhs; @@ -8845,13 +8845,13 @@ fn cgassign(c: *cgen, n: *node) void = { // cstage N_INDEX store reads idx_eff(base->type)->sub // uniformly (cmd/w6c/cgen.c:3517-3518). if (base != nil) { - if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; + if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; if (bt60 != nil) { - if (bt60.kind == tykind.TY_NAMED) { basealias = true; }; + if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; }; }; if (basealias) { - let et60: *tinfo = tichase(lhs.type_: *tinfo); + let et60: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); if (et60 != nil) { esz = et60.size: i32; elemtn = lhs; @@ -8859,9 +8859,9 @@ fn cgassign(c: *cgen, n: *node) void = { // see cgindex twin: cs-aligned, runtime- // unreachable until #77/#78 global DATA. if (isglobalarr || isglobalptr) { - let bu60: *tinfo = tichase(bt60); + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - isglobalarr = bu60.kind == tykind.TY_ARRAY; + isglobalarr = bu60.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; @@ -8888,7 +8888,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, elemtn.type_: *tinfo, n.rhs, + cgwidentaggedstore(c, elemtn.type_: *syntax.tinfo, n.rhs, "BP", scroff, slot_sz); cgexpr(c, idx); if (slot_sz > 1) { @@ -8906,18 +8906,18 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarr: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isarr = true; }; }; // #60: alias-NAMED base — chased kind // (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarr = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarr = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarr) { emitline("\tLEAQ\t"); @@ -8975,19 +8975,19 @@ fn cgassign(c: *cgen, n: *node) void = { // so the verdict is byte-identical to cstage's cg_sret_retsize. // The base-shape split below then loud-stops every non-local- // array form, base-kind-independent. - if (n.rhs != nil && n.rhs.kind == nkind.N_CALL + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL && callsretsize(c, n.rhs) > 0) { let islocalarr: bool = false; if (baselocal != nil) { - let btn: *node = baselocal.tnode; + let btn: *syntax.node = baselocal.tnode; if (btn != nil) { - if (btn.kind == nkind.N_TARRAY) { islocalarr = true; }; + if (btn.kind == syntax.nkind.N_TARRAY) { islocalarr = true; }; }; }; let constidx: bool = false; let cidx: i32 = 0; if (idx != nil) { - if (idx.kind == nkind.N_INTLIT) { + if (idx.kind == syntax.nkind.N_INTLIT) { constidx = true; cidx = idx.uval: i32; }; @@ -9014,18 +9014,18 @@ fn cgassign(c: *cgen, n: *node) void = { // element N_TTUPLE), in-cap. Mirror of cstage cgen.c #121 // store arm; the materialise + base-resolve are the // cglet / #270-1b byte-id twins. - if (n.rhs.kind == nkind.N_TUPLE && esz > 8 - && base != nil && base.kind == nkind.N_IDENT - && elemtn != nil && elemtn.kind == nkind.N_TTUPLE + if (n.rhs.kind == syntax.nkind.N_TUPLE && esz > 8 + && base != nil && base.kind == syntax.nkind.N_IDENT + && elemtn != nil && elemtn.kind == syntax.nkind.N_TTUPLE && sretretsize(c, elemtn) == 0) { let scr121: i32 = tagscradd(c, esz); cgtuplelittocursor(c, n.rhs, elemtn); let gpc: i32 = 0; let ssc: i32 = 0; let eo: i32 = 0; - let q121: *node = elemtn.list; + let q121: *syntax.node = elemtn.list; for (q121 != nil) { - let qt: *node = q121.lhs; + let qt: *syntax.node = q121.lhs; let isflt: bool = isfloattype(c, qt); let es: i32 = tupeslotn(qt); tupstore(c, gpc, ssc, scr121 + eo, es, qt); @@ -9052,12 +9052,12 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn2: *node = baselocal.tnode; + let tn2: *syntax.node = baselocal.tnode; let isarr2: bool = false; - if (tn2 != nil) { if (tn2.kind == nkind.N_TARRAY) { isarr2 = true; }; }; + if (tn2 != nil) { if (tn2.kind == syntax.nkind.N_TARRAY) { isarr2 = true; }; }; if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarr2 = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarr2 = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarr2) { emitline("\tLEAQ\t"); @@ -9100,10 +9100,10 @@ fn cgassign(c: *cgen, n: *node) void = { // — RAX-only store, task #31-G. esz>8 // non-str/non-slice IS a struct/array/tuple here (the // tagged element already returned above; floats are ≤8). - let aggsrc: bool = (n.rhs.kind == nkind.N_IDENT) - || (n.rhs.kind == nkind.N_DOT) - || (n.rhs.kind == nkind.N_UN - && n.rhs.op == tkind.TK_STAR); + let aggsrc: bool = (n.rhs.kind == syntax.nkind.N_IDENT) + || (n.rhs.kind == syntax.nkind.N_DOT) + || (n.rhs.kind == syntax.nkind.N_UN + && n.rhs.op == syntax.tkind.TK_STAR); if (esz > 8 && !isstrtype(c, elemtn) && !isslicetype(c, elemtn) && aggsrc) { cgexpr(c, idx); // idx → AX @@ -9123,13 +9123,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn2: *node = baselocal.tnode; + let tn2: *syntax.node = baselocal.tnode; let isarr2: bool = false; - if (tn2 != nil) { if (tn2.kind == nkind.N_TARRAY) { isarr2 = true; }; }; + if (tn2 != nil) { if (tn2.kind == syntax.nkind.N_TARRAY) { isarr2 = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarr2 = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarr2 = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarr2) { emitline("\tLEAQ\t"); @@ -9150,11 +9150,11 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tADDQ\tAX, BX\n"); emitline("\tPUSHQ\tBX\n"); // spill dest // rhs source address → SI - if (n.rhs.kind == nkind.N_UN - && n.rhs.op == tkind.TK_STAR) { + if (n.rhs.kind == syntax.nkind.N_UN + && n.rhs.op == syntax.tkind.TK_STAR) { cgexpr(c, n.rhs.lhs); emitline("\tMOVQ\tAX, SI\n"); - } else { if (n.rhs.kind == nkind.N_IDENT) { + } else { if (n.rhs.kind == syntax.nkind.N_IDENT) { let sl: *local = localfindnode(c, n.rhs.str); if (sl != nil) { emitline("\tLEAQ\t"); @@ -9255,13 +9255,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; - if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; }; + if (tn != nil) { if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarray) { emitline("\tLEAQ\t"); @@ -9336,18 +9336,18 @@ fn cgassign(c: *cgen, n: *node) void = { // unwired — cstage's compound template never carried // those payload kinds. Same shape gate as the cstage // branch (cgen.c #133). - if (n.op != tkind.TK_ASSIGN) { - let base: *node = lhs.lhs; - let idx: *node = lhs.rhs; + if (n.op != syntax.tkind.TK_ASSIGN) { + let base: *syntax.node = lhs.lhs; + let idx: *syntax.node = lhs.rhs; let esz: i32 = 8; let baselocal: *local = nil; let isglobalarr: bool = false; let isglobalptr: bool = false; let globalname: str; globalname.ptr = nil; globalname.len = 0; - let elemtn: *node = nil; + let elemtn: *syntax.node = nil; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal != nil) { @@ -9375,29 +9375,29 @@ fn cgassign(c: *cgen, n: *node) void = { // picks MOVB on the store arm, and the compound // arm's str/slice hard-error still fires on a // []str element). - let tn: *node = letvartnode(c, bn); + let tn: *syntax.node = letvartnode(c, bn); if (tn != nil) { globalname = bn; esz = elemsizeofc(c, tn); // idxelemtn: `*[N]T` drill, see the // local branch above (#61). elemtn = idxelemtn(tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; }; }; }; - } else { if (base.kind == nkind.N_DOT - || (base.kind == nkind.N_UN - && base.op == tkind.TK_STAR)) { + } else { if (base.kind == syntax.nkind.N_DOT + || (base.kind == syntax.nkind.N_UN + && base.op == syntax.tkind.TK_STAR)) { // N_UN deref base (`(*p)[i] OP= v`, #61 C): // same stamped source as the store arm. - let dt: *tinfo = lhs.type_: *tinfo; + let dt: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (dt != nil) { esz = dt.size: i32; elemtn = lhs; }; - } else { if (base.kind == nkind.N_INDEX) { - let et: *tinfo = lhs.type_: *tinfo; + } else { if (base.kind == syntax.nkind.N_INDEX) { + let et: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (et != nil) { esz = et.size: i32; elemtn = lhs; @@ -9408,21 +9408,21 @@ fn cgassign(c: *cgen, n: *node) void = { // same stamped-element adoption as the store arm. let basealias: bool = false; if (base != nil) { - if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; + if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; if (bt60 != nil) { - if (bt60.kind == tykind.TY_NAMED) { basealias = true; }; + if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; }; }; if (basealias) { - let et60: *tinfo = tichase(lhs.type_: *tinfo); + let et60: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); if (et60 != nil) { esz = et60.size: i32; elemtn = lhs; }; if (isglobalarr || isglobalptr) { - let bu60: *tinfo = tichase(bt60); + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - isglobalarr = bu60.kind == tykind.TY_ARRAY; + isglobalarr = bu60.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; @@ -9472,13 +9472,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; - if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; }; + if (tn != nil) { if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarray) { emitline("\tLEAQ\t"); @@ -9510,29 +9510,29 @@ fn cgassign(c: *cgen, n: *node) void = { let unsignd_c: bool = false; if (elemtn != nil) { if (elemtn.type_ != nil) { - unsignd_c = typeisunsigned(elemtn.type_: *tinfo); + unsignd_c = syntax.typeisunsigned(elemtn.type_: *syntax.tinfo); }; }; let wired: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd_c) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd_c) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd_c) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired = true; @@ -9560,30 +9560,30 @@ fn cgassign(c: *cgen, n: *node) void = { // N_INDEX-lhs branch above handles bare `arr[i] = v`, not the // field write). if (lhs != nil) { - if (lhs.kind == nkind.N_DOT && lhs.lhs != nil - && lhs.lhs.kind == nkind.N_INDEX && !placeslit) { - let idxbase: *node = lhs.lhs.lhs; - let idx: *node = lhs.lhs.rhs; + if (lhs.kind == syntax.nkind.N_DOT && lhs.lhs != nil + && lhs.lhs.kind == syntax.nkind.N_INDEX && !placeslit) { + let idxbase: *syntax.node = lhs.lhs.lhs; + let idx: *syntax.node = lhs.lhs.rhs; let fld2: str = lhs.str; - if (idxbase != nil) { if (idxbase.kind == nkind.N_IDENT) { + if (idxbase != nil) { if (idxbase.kind == syntax.nkind.N_IDENT) { if (idx != nil) { let lc: *local = localfindnode(c, idxbase.str); if (lc != nil) { if (lc.tnode != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; // idxelemtn: `*[N]T` drills to the pointee // array's element (#61). - let elemt: *node = idxelemtn(tn); - let baseisarray: bool = tn.kind == nkind.N_TARRAY; - let snode: *node = nil; + let elemt: *syntax.node = idxelemtn(tn); + let baseisarray: bool = tn.kind == syntax.nkind.N_TARRAY; + let snode: *syntax.node = nil; let viaptr: bool = false; if (elemt != nil) { - if (elemt.kind == nkind.N_TPTR) { - let inner: *node = elemt.lhs; - if (inner != nil) { if (inner.kind == nkind.N_TNAME) { + if (elemt.kind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = elemt.lhs; + if (inner != nil) { if (inner.kind == syntax.nkind.N_TNAME) { snode = inner; viaptr = true; };}; - } else { if (elemt.kind == nkind.N_TNAME) { + } else { if (elemt.kind == syntax.nkind.N_TNAME) { snode = elemt; };}; }; @@ -9602,12 +9602,12 @@ fn cgassign(c: *cgen, n: *node) void = { if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld2)) { + if (syntax.streq(fi.fname, fld2)) { let esz: i32 = elemsizeofc(c, tn); // f64/f32: rhs in X0. Spill to stack, // compute &arr[i] in BX (deref if *T), // then reload X0 and MOVSD/MOVSS. - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { if (isfloattype(c, fi.tnode)) { let mov: str = "MOVSD"; if (isf32type(c, fi.tnode)) { mov = "MOVSS"; }; @@ -9735,7 +9735,7 @@ fn cgassign(c: *cgen, n: *node) void = { os.write(2, m58m.ptr, m58m.len: u64); os.exit(1); }; - if (typeisfloat(n.rhs.type_: *tinfo)) { + if (syntax.typeisfloat(n.rhs.type_: *syntax.tinfo)) { let m58f: str = "#58: float-payload tagged-field indexed store unreachable until #114\n"; os.write(2, m58f.ptr, m58f.len: u64); os.exit(1); @@ -9761,7 +9761,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tADDQ\tAX, BX\n"); if (viaptr) { emitline("\tMOVQ\t(BX), BX\n"); }; emitline("\tPOPQ\tAX\n"); - let v58tag: i32 = taggedvariantindext(c, fi.tnode.type_: *tinfo, n.rhs); + let v58tag: i32 = taggedvariantindext(c, fi.tnode.type_: *syntax.tinfo, n.rhs); if (v58tag < 0) { v58tag = 0; }; emitline("\tMOVQ\t$"); emitint(v58tag: i64); @@ -9865,29 +9865,29 @@ fn cgassign(c: *cgen, n: *node) void = { let unsignd_x: bool = false; if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { - unsignd_x = typeisunsigned(fi.tnode.type_: *tinfo); + unsignd_x = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; let wired_x: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd_x) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired_x = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd_x) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd_x) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired_x = true; @@ -9921,33 +9921,33 @@ fn cgassign(c: *cgen, n: *node) void = { // by retargeting to the inner IDENT so the via_ptr branch fires // the same as auto-deref `p.f = v`. v1 scope: bare-IDENT inner. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; if (base != nil) { - if (base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR) { + if (base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR) { if (base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { base = base.lhs; }; }; }; }; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; let lc: *local = localfindnode(c, bn); if (lc != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = nkind.N_NONE; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = syntax.nkind.N_NONE; if (tn != nil) { lkind = tn.kind; }; // Pointer-to-struct: deref then store. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; let sname: str; sname.ptr = nil; sname.len = 0; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; if (sname.len > 0) { // structlookupchain (#22) handles the @@ -9958,18 +9958,18 @@ fn cgassign(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // Tagged-union field via *struct base — full slot // rewrite via cgwidentaggedstore basereg="BX". Pre-#26 // fell through to the scalar store and dropped tag // + payload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && istaggedtype(c, fi.tnode)) { let fsz: i32 = slotsize(c, fi.tnode); emitline("\tMOVQ\t"); emitoff(lc.off: i64); emitline("(BP), BX\n"); - cgwidentaggedstore(c, fi.tnode.type_: *tinfo, + cgwidentaggedstore(c, fi.tnode.type_: *syntax.tinfo, n.rhs, "BX", fi.foff, fsz); return; }; @@ -9977,9 +9977,9 @@ fn cgassign(c: *cgen, n: *node) void = { // be a runtime RDI pointer (the BP-relative c.sretdestoff // can't name `p.f`); deferred. HARD-STOP loud, never fall // through to the truncating generic store (rule 7). - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && sretretsize(c, fi.tnode) > 0) { let m234: str = "#234-tail: over-cap tuple sret store to via-ptr field dest unsupported\n"; os.write(2, m234.ptr, m234.len: u64); @@ -9998,11 +9998,11 @@ fn cgassign(c: *cgen, n: *node) void = { // granularity — size via structabisize (cstage // SSoT lu->size, check.c:760; cgen.c:7720 // sz=lu->size at the receive twin). - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -10053,11 +10053,11 @@ fn cgassign(c: *cgen, n: *node) void = { // its trailing bytes. mode=1 (DST_PTR_LOCAL) reloads BX // from lc.off(BP) before zero-fill and before every // field store. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -10066,11 +10066,11 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); let srhs: *local = localfindnode(c, n.rhs.str); @@ -10119,7 +10119,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; };}; }; - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // compound: load current value emitline("\tMOVQ\t"); emitoff(lc.off: i64); @@ -10133,17 +10133,17 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPUSHQ\tBX\n"); }; cgexpr(c, n.rhs); - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { emitline("\tPOPQ\tBX\n"); // PLUSEQ is commutative; MINUSEQ // needs lhs - rhs (BX is old lhs, // AX is rhs). cgdotfieldhardstop(c, fi.tnode); let uns34: bool = false; - if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = typeisunsigned(fi.tnode.type_: *tinfo); }; }; + if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; cgdotfieldcombine(c, n.op, uns34); }; - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { // str/slice field via *struct: str IS []u8, so both // store the full 3-word {ptr,len,cap} from (AX,BX,CX). // CX holds cap, so stage the struct addr in DX and @@ -10196,7 +10196,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; // Direct struct local: store at off+foff. - if (lkind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { // structlookupchain (#22) — same shape // as the cgdot direct-local read site. let si: *structinfo = structlookupchain(c, tn); @@ -10204,15 +10204,15 @@ fn cgassign(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // Tagged-union field in a direct struct local — // full slot rewrite at (lc.off + fi.foff)(BP) // via cgwidentaggedstore basereg="BP". Pre-#26 // fell through and dropped tag + payload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && istaggedtype(c, fi.tnode)) { let fsz: i32 = slotsize(c, fi.tnode); - cgwidentaggedstore(c, fi.tnode.type_: *tinfo, + cgwidentaggedstore(c, fi.tnode.type_: *syntax.tinfo, n.rhs, "BP", lc.off + fi.foff, fsz); return; }; @@ -10224,9 +10224,9 @@ fn cgassign(c: *cgen, n: *node) void = { // (c.sretdestoff = lc.off + fi.foff) so it writes the // WHOLE value there, never the truncating generic store // below. Mirror of cstage cgen.c (#234) field local arm. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && sretretsize(c, fi.tnode) > 0) { c.sretdestoff = lc.off + fi.foff; cgexpr(c, n.rhs); @@ -10242,11 +10242,11 @@ fn cgassign(c: *cgen, n: *node) void = { // N_STRUCTLIT: field-walk; each inner // field stored at +fi.foff+inner_foff(BP). // BP-rel direct, no addr scratch needed. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -10293,11 +10293,11 @@ fn cgassign(c: *cgen, n: *node) void = { // typed structlit value recurses instead of dropping // its trailing bytes. mode=0 (DST_BP) — direct BP-rel, // no BX reload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -10306,11 +10306,11 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); let srhs: *local = localfindnode(c, n.rhs.str); @@ -10356,7 +10356,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; };}; }; - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // Compound on direct struct-local // scalar field: load current → push // → eval rhs → combine → store @@ -10370,13 +10370,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPUSHQ\tBX\n"); }; cgexpr(c, n.rhs); - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { emitline("\tPOPQ\tBX\n"); // PLUSEQ commutes; MINUSEQ needs // lhs-rhs (BX old lhs, AX rhs). cgdotfieldhardstop(c, fi.tnode); let uns34: bool = false; - if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = typeisunsigned(fi.tnode.type_: *tinfo); }; }; + if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; cgdotfieldcombine(c, n.op, uns34); }; // str/slice field direct: str IS []u8, so both store the @@ -10420,21 +10420,21 @@ fn cgassign(c: *cgen, n: *node) void = { }; // str/slice pseudo-field assignment. let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; - let innerkind: nkind = nkind.N_NONE; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; + let innerkind: syntax.nkind = syntax.nkind.N_NONE; if (inner != nil) { innerkind = inner.kind; }; let innerstr: bool = false; - if (innerkind == nkind.N_TNAME) { - if (streq(inner.str, "str")) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TNAME) { + if (syntax.streq(inner.str, "str")) { innerstr = true; }; }; - if (innerkind == nkind.N_TSLICE) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TSLICE) { innerstr = true; }; if (innerstr) { - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // Compound on `(*str|*slice).field`: load // current → push → eval rhs → combine → store. emitline("\tMOVQ\t"); @@ -10467,7 +10467,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // Compound on local `str|slice` pseudo-field: // load current → push → eval rhs → combine → // store (mirror cgen.c:3235 local arm). @@ -10502,25 +10502,25 @@ fn cgassign(c: *cgen, n: *node) void = { // follows the same load → push → eval → combine → store shape // as the via-ptr local path. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; if (localfindnode(c, bn) == nil) { let si: *structinfo = letvarstructinfo(c, bn); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { // #234-tail: GLOBAL (`g.f`) sret field STORE. c.sretdestoff is // BP-relative only and can't name a global slot; the runtime // RDI-pointer dest variant is deferred. HARD-STOP loud, never // the truncating generic store (rule 7). - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && sretretsize(c, fi.tnode) > 0) { let m234: str = "#234-tail: over-cap tuple sret store to global field dest unsupported\n"; os.write(2, m234.ptr, m234.len: u64); @@ -10533,11 +10533,11 @@ fn cgassign(c: *cgen, n: *node) void = { // N_CALL: cgexpr → AX/DX/CX; LEAQ base into BX // after call, sized stores per natural size. // N_STRUCTLIT: field-walk; reload BX per store. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -10588,11 +10588,11 @@ fn cgassign(c: *cgen, n: *node) void = { // its trailing bytes. mode=2 (DST_GLOBAL) reloads BX // via LEAQ bn(SB) before zero-fill and before every // field store. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -10601,11 +10601,11 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); let srhs: *local = localfindnode(c, n.rhs.str); @@ -10660,18 +10660,18 @@ fn cgassign(c: *cgen, n: *node) void = { // is_global arm. Without this the generic TK_ASSIGN // below truncates to 1 word, silently dropping tag // and payload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && istaggedtype(c, fi.tnode)) { let fsz: i32 = slotsize(c, fi.tnode); emitline("\tLEAQ\t"); emitsymname(c, bn); emitline("(SB), BX\n"); cgwidentaggedstore(c, - fi.tnode.type_: *tinfo, + fi.tnode.type_: *syntax.tinfo, n.rhs, "BX", fi.foff, fsz); return; }; - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { cgexpr(c, n.rhs); if (isstrtype(c, fi.tnode) || isslicetype(c, fi.tnode)) { // str OR slice field: str IS []u8, so @@ -10741,7 +10741,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPOPQ\tBX\n"); cgdotfieldhardstop(c, fi.tnode); let uns34: bool = false; - if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = typeisunsigned(fi.tnode.type_: *tinfo); }; }; + if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; cgdotfieldcombine(c, n.op, uns34); let sop: str = fieldstoreop(c, fi); emitline("\tLEAQ\t"); @@ -10771,11 +10771,11 @@ fn cgassign(c: *cgen, n: *node) void = { // store. Only plain `=` is wired here; chained compound on a // pointer-field hasn't surfaced. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; if (base != nil) { - if (base.kind == nkind.N_DOT) { + if (base.kind == syntax.nkind.N_DOT) { // #70 (#12): inner-struct layout via the stamped // base.type_ (peel *→struct) + tinfo.fields, // replacing dotinnerstructptr's structinfo walk. @@ -10787,35 +10787,35 @@ fn cgassign(c: *cgen, n: *node) void = { // exactly avoids an untested widening past cstage. // Global-root chains stay in their pre-existing shared // base-eval breakage (filed #27). - let croot: *node = base; + let croot: *syntax.node = base; let allptr: bool = true; - for (croot != nil && croot.kind == nkind.N_DOT) { - let ct: *tinfo = croot.type_: *tinfo; + for (croot != nil && croot.kind == syntax.nkind.N_DOT) { + let ct: *syntax.tinfo = croot.type_: *syntax.tinfo; ct = tichase(ct); let okp: bool = false; - if (ct != nil) { if (ct.kind == tykind.TY_PTR) { - let cs: *tinfo = ct.sub; + if (ct != nil) { if (ct.kind == syntax.tykind.TY_PTR) { + let cs: *syntax.tinfo = ct.sub; cs = tichase(cs); - if (cs != nil) { if (cs.kind == tykind.TY_STRUCT) { okp = true; }; }; + if (cs != nil) { if (cs.kind == syntax.tykind.TY_STRUCT) { okp = true; }; }; }; }; if (!okp) { allptr = false; }; croot = croot.lhs; }; - let it: *tinfo = nil; - if (allptr && croot != nil && croot.kind == nkind.N_IDENT && + let it: *syntax.tinfo = nil; + if (allptr && croot != nil && croot.kind == syntax.nkind.N_IDENT && localfindnode(c, croot.str) != nil) { - it = base.type_: *tinfo; + it = base.type_: *syntax.tinfo; }; it = tichase(it); - if (it != nil) { if (it.kind == tykind.TY_PTR) { - let st: *tinfo = it.sub; + if (it != nil) { if (it.kind == syntax.tykind.TY_PTR) { + let st: *syntax.tinfo = it.sub; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { - let tf: *tfield = st.fields; + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { + let tf: *syntax.tfield = st.fields; for (tf != nil) { - if (streq(tf.name, fld)) { - let ft: *tinfo = tf.type_; - if (n.op == tkind.TK_ASSIGN) { + if (syntax.streq(tf.name, fld)) { + let ft: *syntax.tinfo = tf.type_; + if (n.op == syntax.tkind.TK_ASSIGN) { // tagged leaf (#38a): eval the *struct // base into BX, then the shared widener // (it spills BX across its internal @@ -10824,8 +10824,8 @@ fn cgassign(c: *cgen, n: *node) void = { // scalar tail below stored ONE sized // word at the field offset: the rhs // landed in the TAG slot (ken b8). - if (typeistagged(ft)) { - let flu: *tinfo = ft; + if (syntax.typeistagged(ft)) { + let flu: *syntax.tinfo = ft; flu = tichase(flu); cgexpr(c, base); emitline("\tMOVQ\tAX, BX\n"); @@ -10834,7 +10834,7 @@ fn cgassign(c: *cgen, n: *node) void = { flu.size: i32); return; }; - if (typeisstr(ft) || typeisslice(ft)) { + if (syntax.typeisstr(ft) || syntax.typeisslice(ft)) { // str/slice: rhs leaves AX=ptr, // BX=len, CX=cap (#1/Phase 3). Spill // all three across the base-expr eval @@ -10866,9 +10866,9 @@ fn cgassign(c: *cgen, n: *node) void = { // f64/f32 chained plain `=`: cgexpr rhs left value in // X0. Spill to stack so cgexpr(base) can use AX, then // reload and MOVSD/MOVSS into the slot. - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; cgexpr(c, n.rhs); emitline("\tSUBQ\t$8, SP\n"); emitline("\t"); @@ -10913,23 +10913,23 @@ fn cgassign(c: *cgen, n: *node) void = { // float/str/slice/tagged field-type // hard-errors LOUD. Signed RSHIFTEQ uses // SARQ (signed) or SHRQ (unsigned) per #136. - if (n.op != tkind.TK_ASSIGN) { - if (typeisstr(ft)) { + if (n.op != syntax.tkind.TK_ASSIGN) { + if (syntax.typeisstr(ft)) { let m: str = "chained-ptr-field compound on str element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (typeisslice(ft)) { + if (syntax.typeisslice(ft)) { let m: str = "chained-ptr-field compound on slice element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let m: str = "chained-ptr-field compound on float element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (typeistagged(ft)) { + if (syntax.typeistagged(ft)) { let m: str = "chained-ptr-field compound on tagged element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -10939,7 +10939,7 @@ fn cgassign(c: *cgen, n: *node) void = { cgexpr(c, base); emitline("\tPUSHQ\tAX\n"); let fsz: i32 = ft.slotsize: i32; - let unsignd_f: bool = typeisunsigned(ft); + let unsignd_f: bool = syntax.typeisunsigned(ft); let lopf: str = loadopsz(!unsignd_f, fsz); emitline("\t"); emitline(lopf); @@ -10949,25 +10949,25 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPOPQ\tBX\n"); emitline("\tPOPQ\tCX\n"); let wired_f: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd_f) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired_f = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd_f) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd_f) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired_f = true; @@ -11001,13 +11001,13 @@ fn cgassign(c: *cgen, n: *node) void = { // the slice/str pseudo-field write through a value-struct chain // silently emit no store. Only plain `=` is wired. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT && lhs.lhs != nil - && lhs.lhs.kind == nkind.N_DOT - && n.op == tkind.TK_ASSIGN) { + if (lhs.kind == syntax.nkind.N_DOT && lhs.lhs != nil + && lhs.lhs.kind == syntax.nkind.N_DOT + && n.op == syntax.tkind.TK_ASSIGN) { let rootname: str = ""; let rootoff: i32 = 0; let totaloff: i32 = 0; - let leaftype: *tinfo = nil; + let leaftype: *syntax.tinfo = nil; let slicedelta: i32 = -1; let isglobal: bool = false; let ptrroot: bool = false; @@ -11049,8 +11049,8 @@ fn cgassign(c: *cgen, n: *node) void = { // kept its old bytes (ken x5d: `o.r.min = 8: size` left // `is size` false). Only plain `=` reaches this walker // (TK_ASSIGN gate above). - if (typeistagged(leaftype)) { - let wlu: *tinfo = leaftype; + if (syntax.typeistagged(leaftype)) { + let wlu: *syntax.tinfo = leaftype; wlu = tichase(wlu); let wtsz: i32 = wlu.size: i32; if (viacx) { @@ -11071,7 +11071,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; return; }; - if (typeisstr(leaftype) || typeisslice(leaftype)) { + if (syntax.typeisstr(leaftype) || syntax.typeisslice(leaftype)) { // str/slice: store ptr/len/cap. cgexpr leaves // CX=cap, so the viacx base goes in DX (not CX) to // avoid clobbering it — same as the single-dot str @@ -11136,17 +11136,17 @@ fn cgassign(c: *cgen, n: *node) void = { let leafstruct: bool = false; let leafname: str = ""; if (leaftype != nil) { - let lp: *tinfo = leaftype; + let lp: *syntax.tinfo = leaftype; lp = tichase(lp); if (lp != nil) { - if (lp.kind == tykind.TY_STRUCT) { leafstruct = true; }; + if (lp.kind == syntax.tykind.TY_STRUCT) { leafstruct = true; }; }; - if (leaftype.kind == tykind.TY_NAMED) { + if (leaftype.kind == syntax.tykind.TY_NAMED) { leafname = leaftype.name; }; }; if (n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && leafstruct) { let lsi: *structinfo = structlookup(c, leafname); if (lsi != nil) { @@ -11230,7 +11230,7 @@ fn cgassign(c: *cgen, n: *node) void = { // LEAQ rootname(SB). // else → mode=0 (DST_BP), direct BP-rel, no reload. if (n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && leafstruct) { let lsi: *structinfo = structlookup(c, leafname); if (lsi != nil) { @@ -11251,7 +11251,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; if (n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && leafstruct) { let ssi: *structinfo = structlookup(c, leafname); let srhs: *local = localfindnode(c, n.rhs.str); @@ -11332,9 +11332,9 @@ fn cgassign(c: *cgen, n: *node) void = { return; };}; }; - if (typeisfloat(leaftype)) { + if (syntax.typeisfloat(leaftype)) { let mov: str = "MOVSD"; - if (typeisf32(leaftype)) { mov = "MOVSS"; }; + if (syntax.typeisf32(leaftype)) { mov = "MOVSS"; }; cgexpr(c, n.rhs); if (viacx) { if (ptrroot) { @@ -11407,24 +11407,24 @@ fn cgassign(c: *cgen, n: *node) void = { // Kept as fallback below the generalized walker for any shape // the walker doesn't recognize. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; - if (base != nil) { if (base.kind == nkind.N_DOT) { - let inner: *node = base.lhs; + if (base != nil) { if (base.kind == syntax.nkind.N_DOT) { + let inner: *syntax.node = base.lhs; let innerfld: str = base.str; - if (inner != nil) { if (inner.kind == nkind.N_IDENT) { + if (inner != nil) { if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { if (lc.tnode != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = tn.kind; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = tn.kind; let outname: str; outname.ptr = nil; outname.len = 0; let isptr: bool = false; - if (lkind == nkind.N_TNAME) { outname = tn.str; }; - if (lkind == nkind.N_TPTR) { - let pe: *node = tn.lhs; - if (pe != nil) { if (pe.kind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { outname = tn.str; }; + if (lkind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = tn.lhs; + if (pe != nil) { if (pe.kind == syntax.nkind.N_TNAME) { outname = pe.str; isptr = true; };}; @@ -11434,16 +11434,16 @@ fn cgassign(c: *cgen, n: *node) void = { if (osi != nil) { let ofi: *fieldinfo = osi.fields; for (ofi != nil) { - if (streq(ofi.fname, innerfld)) { - let oft: *node = ofi.tnode; - if (oft != nil) { if (oft.kind == nkind.N_TNAME) { + if (syntax.streq(ofi.fname, innerfld)) { + let oft: *syntax.node = ofi.tnode; + if (oft != nil) { if (oft.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, oft.str) == 0) { let isi: *structinfo = structlookup(c, oft.str); if (isi != nil) { let ffi: *fieldinfo = isi.fields; for (ffi != nil) { - if (streq(ffi.fname, fld)) { - if (n.op == tkind.TK_ASSIGN) { + if (syntax.streq(ffi.fname, fld)) { + if (n.op == syntax.tkind.TK_ASSIGN) { let totoff: i32 = ofi.foff + ffi.foff; cgexpr(c, n.rhs); if (isstrtype(c, ffi.tnode)) { @@ -11527,7 +11527,7 @@ fn cgassign(c: *cgen, n: *node) void = { // forms (+= -= *= /=); other compounds fall back to // "evaluate rhs, replace". Mirrors C cgen's IDENT-assign path. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let nm: str = lhs.str; let off: i32 = localfind(c, nm); if (off == 0) { @@ -11556,9 +11556,9 @@ fn cgassign(c: *cgen, n: *node) void = { let lvf: *letvar = c.lets; let isfg: bool = false; let isf32g: bool = false; - let lvftn: *node = nil; + let lvftn: *syntax.node = nil; for (lvf != nil) { - if (streq(lvf.name, nm)) { + if (syntax.streq(lvf.name, nm)) { isfg = isfloattype(c, lvf.tnode); isf32g = isf32type(c, lvf.tnode); lvftn = lvf.tnode; @@ -11584,7 +11584,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tLEAQ\t"); emitsymname(c, nm); emitline("(SB), CX\n"); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { emitline("\t"); emitline(mov); emitline("\tX0, (CX)\n"); @@ -11595,10 +11595,10 @@ fn cgassign(c: *cgen, n: *node) void = { // only, so we can't combine direct to memory. let fop: str; fop.ptr = nil; fop.len = 0; - if (n.op == tkind.TK_PLUSEQ) { fop = addf; }; - if (n.op == tkind.TK_MINUSEQ) { fop = subf; }; - if (n.op == tkind.TK_STAREQ) { fop = mulf; }; - if (n.op == tkind.TK_SLASHEQ) { fop = divf; }; + if (n.op == syntax.tkind.TK_PLUSEQ) { fop = addf; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { fop = subf; }; + if (n.op == syntax.tkind.TK_STAREQ) { fop = mulf; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { fop = divf; }; if (fop.len == 0) { // Unsupported (e.g., %= on float): // fall back to plain store of rhs. @@ -11624,15 +11624,15 @@ fn cgassign(c: *cgen, n: *node) void = { // into g's storage. The scalar store below would emit a // truncated `MOVQ AX, g(SB)` and drop the body. Mirror // of the C cgen N_ASSIGN global arm (cmd/w6c/cgen.c). - if (n.op == tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL && lvftn != nil) { + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil + && n.rhs.kind == syntax.nkind.N_CALL && lvftn != nil) { let gsz: i32 = 0; - if (lvftn.kind == nkind.N_TNAME) { + if (lvftn.kind == syntax.nkind.N_TNAME) { let gsi: *structinfo = structlookup(c, lvftn.str); if (gsi != nil) { gsz = structabisize(gsi); }; }; - if (lvftn.kind == nkind.N_TARRAY) { - let gat: *tinfo = lvftn.type_: *tinfo; + if (lvftn.kind == syntax.nkind.N_TARRAY) { + let gat: *syntax.tinfo = lvftn.type_: *syntax.tinfo; gat = tichase(gat); if (gat != nil) { gsz = gat.size: i32; }; }; @@ -11657,11 +11657,11 @@ fn cgassign(c: *cgen, n: *node) void = { // behaviour — no consumer (rule-10 aligned with cstage; // note non-float struct globals also truncate symmetrically // here, byte-id-clean — #276 covers both). - if (n.op == tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL && lvftn != nil - && lvftn.kind == nkind.N_TARRAY) { + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil + && n.rhs.kind == syntax.nkind.N_CALL && lvftn != nil + && lvftn.kind == syntax.nkind.N_TARRAY) { let aggsz: i32 = 0; - let aat: *tinfo = lvftn.type_: *tinfo; + let aat: *syntax.tinfo = lvftn.type_: *syntax.tinfo; aat = tichase(aat); if (aat != nil) { aggsz = aat.size: i32; }; if (aggsz > 0 && aggsz <= 24) { @@ -11703,16 +11703,16 @@ fn cgassign(c: *cgen, n: *node) void = { // addressable rhs → aggargsrcaddr + LEAQ g(SB), BX // + aggcopy. Pre-#49 every shape fell to the scalar // tail below: one MOVQ AX, g(SB). - if (n.op == tkind.TK_ASSIGN && lvftn != nil) { - let gau: *tinfo = lvftn.type_: *tinfo; + if (n.op == syntax.tkind.TK_ASSIGN && lvftn != nil) { + let gau: *syntax.tinfo = lvftn.type_: *syntax.tinfo; gau = tichase(gau); if (gau != nil) { - if (gau.kind == tykind.TY_STRUCT - || gau.kind == tykind.TY_ARRAY - || gau.kind == tykind.TY_TUPLE) { - if (n.rhs != nil && n.rhs.kind == nkind.N_STRUCTLIT) { + if (gau.kind == syntax.tykind.TY_STRUCT + || gau.kind == syntax.tykind.TY_ARRAY + || gau.kind == syntax.tykind.TY_TUPLE) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_STRUCTLIT) { let gsi49: *structinfo = nil; - if (lvftn.kind == nkind.N_TNAME) { + if (lvftn.kind == syntax.nkind.N_TNAME) { gsi49 = structlookup(c, lvftn.str); }; if (gsi49 == nil) { @@ -11725,7 +11725,7 @@ fn cgassign(c: *cgen, n: *node) void = { cgstructlitfill(c, gsi49, n.rhs, 2, 0, nm, 0); return; }; - if (n.rhs != nil && n.rhs.kind == nkind.N_CALL) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL) { let m49e: str = "assign: aggregate call receive shape unwired (task #49/#276/rule-7)\n"; os.write(2, m49e.ptr, m49e.len: u64); os.exit(1); @@ -11744,7 +11744,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; cgexpr(c, n.rhs); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { // str/slice top-level let: str IS []u8, so both store the // full 3-word {ptr,len,cap}. Stash cap in DI before LEAQ // overwrites CX, then store ptr/len/cap via &name(SB) @@ -11769,7 +11769,7 @@ fn cgassign(c: *cgen, n: *node) void = { // a prior `*(&letname): *iN` deref-store doesn't // leave stale upper bytes feeding the combine. let glop: str = localloadop(c, lvftn); - if (streq(glop, "MOVQ")) { + if (syntax.streq(glop, "MOVQ")) { emitline("\tMOVQ\t"); emitsymname(c, nm); emitline("(SB), BX\n"); @@ -11782,22 +11782,22 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\t(CX), BX\n"); }; let didcompound: bool = true; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_LSHIFTEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tSHLQ\tCX, BX\n"); } - else { if (n.op == tkind.TK_RSHIFTEQ) { + else { if (n.op == syntax.tkind.TK_RSHIFTEQ) { // #136: signed RSHIFTEQ → SARQ. let unsignd_r: bool = false; if (lvftn != nil) { if (lvftn.type_ != nil) { - unsignd_r = typeisunsigned(lvftn.type_: *tinfo); + unsignd_r = syntax.typeisunsigned(lvftn.type_: *syntax.tinfo); }; }; if (!unsignd_r) { @@ -11813,10 +11813,10 @@ fn cgassign(c: *cgen, n: *node) void = { // CQO (or zero DX), IDIVQ (or DIVQ) CX, // ferry AX or DX back to BX for the shared // store-BX tail below. - else { if (n.op == tkind.TK_SLASHEQ || n.op == tkind.TK_PERCENTEQ) { + else { if (n.op == syntax.tkind.TK_SLASHEQ || n.op == syntax.tkind.TK_PERCENTEQ) { let unsignd: bool = false; if (lvftn != nil) { - unsignd = typeisunsigned(lvftn.type_: *tinfo); + unsignd = syntax.typeisunsigned(lvftn.type_: *syntax.tinfo); }; if (!unsignd) { unsignd = nodeisunsigned(c, n.rhs); @@ -11830,7 +11830,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ) { emitline("\tMOVQ\tAX, BX\n"); } else { emitline("\tMOVQ\tDX, BX\n"); @@ -11859,9 +11859,9 @@ fn cgassign(c: *cgen, n: *node) void = { // returning call — rettupleof distinguishes it from a // >24B struct, which keeps its own size-aware recv // below. Mirrors the cstage N_ASSIGN-ident over-cap arm. - if (n.op == tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL) { - let rtup: *node = rettupleof(c, n.rhs); + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil + && n.rhs.kind == syntax.nkind.N_CALL) { + let rtup: *syntax.node = rettupleof(c, n.rhs); if (rtup != nil) { let rscs: i32 = callsretsize(c, n.rhs); if (rscs > 0) { @@ -11908,11 +11908,11 @@ fn cgassign(c: *cgen, n: *node) void = { // doesn't emit (tracked separately as the cstage/ // wwstage MOVW divergence task). if (lcn != nil) { - let lctn: *node = lcn.tnode; + let lctn: *syntax.node = lcn.tnode; let lcsname: str; lcsname.ptr = nil; lcsname.len = 0; if (lctn != nil) { - if (lctn.kind == nkind.N_TNAME) { + if (lctn.kind == syntax.nkind.N_TNAME) { lcsname = lctn.str; }; }; @@ -11927,9 +11927,9 @@ fn cgassign(c: *cgen, n: *node) void = { // (natural 12, ABI 16) to MOVQ+MOVL where // cstage writes MOVQ+MOVQ. let lcnsz: i32 = structabisize(lcsi); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { if (n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT) { + && n.rhs.kind == syntax.nkind.N_STRUCTLIT) { // Delegate to the shared BP-relative // structlit fill helper. Handles // TK_ELLIPSIS autofill + per-field @@ -11945,7 +11945,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; if (n.rhs != nil - && n.rhs.kind == nkind.N_CALL) { + && n.rhs.kind == syntax.nkind.N_CALL) { // sret receive (#23): plain // TY_STRUCT > 24B from a CALL. // `s` is the prealloc dest; the @@ -12010,12 +12010,12 @@ fn cgassign(c: *cgen, n: *node) void = { // stores. Array natural size (tinfo.size = sub.size*len) // mirrors cstage lu->size. No structfloatclass (pure-int // element arrays). - if (lcn != nil && n.op == tkind.TK_ASSIGN - && n.rhs != nil && n.rhs.kind == nkind.N_CALL) { - let acati: *tinfo = nil; - if (lcn.tnode != nil) { acati = lcn.tnode.type_: *tinfo; }; + if (lcn != nil && n.op == syntax.tkind.TK_ASSIGN + && n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL) { + let acati: *syntax.tinfo = nil; + if (lcn.tnode != nil) { acati = lcn.tnode.type_: *syntax.tinfo; }; acati = tichase(acati); - if (acati != nil && acati.kind == tykind.TY_ARRAY) { + if (acati != nil && acati.kind == syntax.tykind.TY_ARRAY) { let lcsz: i32 = acati.size: i32; if (lcsz > 24) { let rscs: i32 = callsretsize(c, n.rhs); @@ -12082,7 +12082,7 @@ fn cgassign(c: *cgen, n: *node) void = { mulf = "MULSS"; divf = "DIVSS"; }; - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { emitline("\t"); emitline(mov); emitline("\tX0, "); @@ -12092,10 +12092,10 @@ fn cgassign(c: *cgen, n: *node) void = { }; let fop: str; fop.ptr = nil; fop.len = 0; - if (n.op == tkind.TK_PLUSEQ) { fop = addf; }; - if (n.op == tkind.TK_MINUSEQ) { fop = subf; }; - if (n.op == tkind.TK_STAREQ) { fop = mulf; }; - if (n.op == tkind.TK_SLASHEQ) { fop = divf; }; + if (n.op == syntax.tkind.TK_PLUSEQ) { fop = addf; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { fop = subf; }; + if (n.op == syntax.tkind.TK_STAREQ) { fop = mulf; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { fop = divf; }; if (fop.len == 0) { emitline("\t"); emitline(mov); @@ -12128,19 +12128,19 @@ fn cgassign(c: *cgen, n: *node) void = { // below and word0-copied `b = a` (cstage cgen.c // N_ASSIGN aggregate-ident twin). Kind keys off the // checker-STAMPED tinfo (#209/#211 discipline). - if (n.op == tkind.TK_ASSIGN) { - let agu: *tinfo = nil; + if (n.op == syntax.tkind.TK_ASSIGN) { + let agu: *syntax.tinfo = nil; if (lcn != nil) { if (lcn.tnode != nil) { - agu = lcn.tnode.type_: *tinfo; + agu = lcn.tnode.type_: *syntax.tinfo; }; }; agu = tichase(agu); if (agu != nil) { - if (agu.kind == tykind.TY_STRUCT - || agu.kind == tykind.TY_ARRAY - || agu.kind == tykind.TY_TUPLE) { - if (n.rhs != nil && n.rhs.kind == nkind.N_STRUCTLIT) { + if (agu.kind == syntax.tykind.TY_STRUCT + || agu.kind == syntax.tykind.TY_ARRAY + || agu.kind == syntax.tykind.TY_TUPLE) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_STRUCTLIT) { // wwstage-only bail: the fill is // structinfo-keyed; a literal // reaching past the name-keyed arm @@ -12153,7 +12153,7 @@ fn cgassign(c: *cgen, n: *node) void = { os.write(2, m49a.ptr, m49a.len: u64); os.exit(1); }; - if (n.rhs != nil && n.rhs.kind == nkind.N_CALL) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL) { let m49b: str = "assign: aggregate call receive shape unwired (task #49/#276/rule-7)\n"; os.write(2, m49b.ptr, m49b.len: u64); os.exit(1); @@ -12172,7 +12172,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; cgexpr(c, n.rhs); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { emitline("\tMOVQ\tAX, "); emitoff(off: i64); emitline("(BP)\n"); @@ -12196,14 +12196,14 @@ fn cgassign(c: *cgen, n: *node) void = { // after a 4B deref-store leaves the upper bytes stale. let llop: str = "MOVQ"; if (lcn != nil) { llop = localloadop(c, lcn.tnode); }; - if (streq(llop, "MOVQ")) { - if (n.op == tkind.TK_PLUSEQ) { + if (syntax.streq(llop, "MOVQ")) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, "); emitoff(off: i64); emitline("(BP)\n"); return; }; - if (n.op == tkind.TK_MINUSEQ) { + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, "); emitoff(off: i64); emitline("(BP)\n"); @@ -12216,23 +12216,23 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\t"); emitoff(off: i64); emitline("(BP), BX\n"); - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); }; - if (n.op == tkind.TK_LSHIFTEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tSHLQ\tCX, BX\n"); }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_RSHIFTEQ) { // #136: signed RSHIFTEQ → SARQ. let unsignd_r: bool = false; if (lcn != nil) { if (lcn.tnode != nil) { if (lcn.tnode.type_ != nil) { - unsignd_r = typeisunsigned(lcn.tnode.type_: *tinfo); + unsignd_r = syntax.typeisunsigned(lcn.tnode.type_: *syntax.tinfo); }; }; }; @@ -12250,11 +12250,11 @@ fn cgassign(c: *cgen, n: *node) void = { // shape the global/deref siblings took. Park rhs in // CX, slot value (BX) into AX, CQO/IDIVQ, ferry AX // (quotient) or DX (remainder) back to BX. - if (n.op == tkind.TK_SLASHEQ || n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ || n.op == syntax.tkind.TK_PERCENTEQ) { let unsignd: bool = false; if (lcn != nil) { if (lcn.tnode != nil) { - unsignd = typeisunsigned(lcn.tnode.type_: *tinfo); + unsignd = syntax.typeisunsigned(lcn.tnode.type_: *syntax.tinfo); }; }; if (!unsignd) { @@ -12269,7 +12269,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ) { emitline("\tMOVQ\tAX, BX\n"); } else { emitline("\tMOVQ\tDX, BX\n"); @@ -12293,20 +12293,20 @@ fn cgassign(c: *cgen, n: *node) void = { // indexed/deref shape returned from its legacy arm), and the // C1.25 aggregate branch fills via @placescr. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT || lhs.kind == nkind.N_INDEX - || (lhs.kind == nkind.N_UN && lhs.op == tkind.TK_STAR)) { - let ft: *tinfo = lhs.type_: *tinfo; - let fu: *tinfo = ft; + if (lhs.kind == syntax.nkind.N_DOT || lhs.kind == syntax.nkind.N_INDEX + || (lhs.kind == syntax.nkind.N_UN && lhs.op == syntax.tkind.TK_STAR)) { + let ft: *syntax.tinfo = lhs.type_: *syntax.tinfo; + let fu: *syntax.tinfo = ft; fu = tichase(fu); let fsz: i32 = 8; if (ft != nil) { fsz = ft.size: i32; }; - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mf: str = "assign-resolver: float field not wired (rule-7)\n"; os.write(2, mf.ptr, mf.len: u64); os.exit(1); }; if (fu != nil) { - if (fu.kind == tykind.TY_TAGGED) { + if (fu.kind == syntax.tykind.TY_TAGGED) { let mt: str = "assign-resolver: tagged field not wired (rule-7)\n"; os.write(2, mt.ptr, mt.len: u64); os.exit(1); @@ -12321,16 +12321,16 @@ fn cgassign(c: *cgen, n: *node) void = { // (loud-first, wire-next). Compound on an // aggregate is meaningless and stays loud. // Mirror of the cstage cgen.c C1.25 arm. - if (fu.kind == tykind.TY_STRUCT - || fu.kind == tykind.TY_ARRAY - || fu.kind == tykind.TY_TUPLE) { - if (n.op != tkind.TK_ASSIGN) { + if (fu.kind == syntax.tykind.TY_STRUCT + || fu.kind == syntax.tykind.TY_ARRAY + || fu.kind == syntax.tykind.TY_TUPLE) { + if (n.op != syntax.tkind.TK_ASSIGN) { let mac: str = "assign-resolver: compound on aggregate field not wired (rule-7)\n"; os.write(2, mac.ptr, mac.len: u64); os.exit(1); }; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { + if (n.rhs.kind == syntax.nkind.N_CALL) { // sret-class needs a runtime-RDI dest // (the #234-tail deferral); the ≤24B // reg-return receive is task #24. The @@ -12351,8 +12351,8 @@ fn cgassign(c: *cgen, n: *node) void = { let placed: bool = false; let isslit: bool = false; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_STRUCTLIT - && fu.kind == tykind.TY_STRUCT) { + if (n.rhs.kind == syntax.nkind.N_STRUCTLIT + && fu.kind == syntax.tykind.TY_STRUCT) { isslit = true; }; }; @@ -12370,7 +12370,7 @@ fn cgassign(c: *cgen, n: *node) void = { // below may clobber AX/CX freely. let sname: str; sname.ptr = nil; sname.len = 0; - if (ft.kind == tykind.TY_NAMED) { + if (ft.kind == syntax.tykind.TY_NAMED) { sname = ft.name; }; let si: *structinfo = nil; @@ -12425,13 +12425,13 @@ fn cgassign(c: *cgen, n: *node) void = { }; let fstrsl: bool = false; if (fu != nil) { - if (fu.kind == tykind.TY_STR - || fu.kind == tykind.TY_SLICE) { + if (fu.kind == syntax.tykind.TY_STR + || fu.kind == syntax.tykind.TY_SLICE) { fstrsl = true; }; }; if (fstrsl) { - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { let ms: str = "assign-resolver: compound on str/slice field not wired (rule-7)\n"; os.write(2, ms.ptr, ms.len: u64); os.exit(1); @@ -12453,7 +12453,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tMOVQ\tCX, 16(DX)\n"); return; }; - } else { if (n.op == tkind.TK_ASSIGN) { + } else { if (n.op == syntax.tkind.TK_ASSIGN) { cgexpr(c, n.rhs); emitline("\tPUSHQ\tAX\n"); if (cgplaceaddr(c, lhs, "BX")) { @@ -12474,32 +12474,32 @@ fn cgassign(c: *cgen, n: *node) void = { cgexpr(c, n.rhs); emitline("\tPUSHQ\tAX\n"); if (cgplaceaddr(c, lhs, "BX")) { - let lop: str = loadopsz(typeissigned(ft), fsz); + let lop: str = loadopsz(syntax.typeissigned(ft), fsz); emitline("\t"); emitline(lop); emitline("\t(BX), AX\n"); emitline("\tPOPQ\tCX\n"); - let unsignd: bool = typeisunsigned(ft); + let unsignd: bool = syntax.typeisunsigned(ft); let wired: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired = true; diff --git a/selfhost/cmd/wcc/cgenstmt.ww b/selfhost/cmd/wcc/cgenstmt.ww index cb816433..979b72d2 100644 --- a/selfhost/cmd/wcc/cgenstmt.ww +++ b/selfhost/cmd/wcc/cgenstmt.ww @@ -16,36 +16,36 @@ import strconv; // ---- statement cgen -------------------------------------------------- -fn cgstmt(c: *cgen, n: *node) void = { +fn cgstmt(c: *cgen, n: *syntax.node) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; - if (k == nkind.N_BLOCK) { cgblock(c, n); return; }; + if (k == syntax.nkind.N_BLOCK) { cgblock(c, n); return; }; - if (k == nkind.N_RETURN) { cgreturn(c, n); return; }; + if (k == syntax.nkind.N_RETURN) { cgreturn(c, n); return; }; - if (k == nkind.N_EXPRSTMT) { cgexprstmt(c, n); return; }; + if (k == syntax.nkind.N_EXPRSTMT) { cgexprstmt(c, n); return; }; - if (k == nkind.N_LET) { cglet(c, n); return; }; + if (k == syntax.nkind.N_LET) { cglet(c, n); return; }; - if (k == nkind.N_IF) { cgif(c, n); return; }; + if (k == syntax.nkind.N_IF) { cgif(c, n); return; }; - if (k == nkind.N_FOR) { cgfor(c, n); return; }; + if (k == syntax.nkind.N_FOR) { cgfor(c, n); return; }; - if (k == nkind.N_FORRANGE) { cgforrange(c, n); return; }; + if (k == syntax.nkind.N_FORRANGE) { cgforrange(c, n); return; }; - if (k == nkind.N_SWITCH) { cgswitch(c, n); return; }; + if (k == syntax.nkind.N_SWITCH) { cgswitch(c, n); return; }; - if (k == nkind.N_MASSIGN) { cgmassign(c, n); return; }; + if (k == syntax.nkind.N_MASSIGN) { cgmassign(c, n); return; }; - if (k == nkind.N_MLET) { cgmlet(c, n); return; }; + if (k == syntax.nkind.N_MLET) { cgmlet(c, n); return; }; - if (k == nkind.N_BREAK) { cgbreak(c, n); return; }; - if (k == nkind.N_CONTINUE) { cgcontinue(c, n); return; }; + if (k == syntax.nkind.N_BREAK) { cgbreak(c, n); return; }; + if (k == syntax.nkind.N_CONTINUE) { cgcontinue(c, n); return; }; - if (k == nkind.N_YIELD) { cgyield(c, n); return; }; + if (k == syntax.nkind.N_YIELD) { cgyield(c, n); return; }; - if (k == nkind.N_DEFER) { + if (k == syntax.nkind.N_DEFER) { // #40: at the cap, fail loud in BOTH stages rather than // silently drop the deferred call. cstage's DEFER_MAX was 32 // and also dropped silently past it; the runtime-correct target @@ -63,7 +63,7 @@ fn cgstmt(c: *cgen, n: *node) void = { c.lastwasreturn = 0; }; -fn cgyield(c: *cgen, n: *node) void = { +fn cgyield(c: *cgen, n: *syntax.node) void = { // Evaluate the value into AX (and BX for str), then JMP to the // enclosing match's end label. Falls through silently if there // is no active match — should be a checker error eventually. @@ -78,7 +78,7 @@ fn cgyield(c: *cgen, n: *node) void = { return; }; -fn cgblock(c: *cgen, n: *node) void = { +fn cgblock(c: *cgen, n: *syntax.node) void = { // Save/restore the locals head across the block (post-#27). // Inner-scope `let` bindings prepend to c.locals via localadd; // without this restore, the prepended stubs leak into sibling @@ -91,7 +91,7 @@ fn cgblock(c: *cgen, n: *node) void = { // restore at the function's outermost block — defers (and the // implicit-return epilogue) need locals intact. let saved: *local = c.locals; - let s: *node = n.list; + let s: *syntax.node = n.list; for (s != nil) { cgstmt(c, s); s = s.next; @@ -148,55 +148,55 @@ fn tupsse(i: i32) str = { // predicates this absorbs were the #22 neighbor-slot/zeros miscompile. // Checker twin: check.ww tupleelemslot / check.c N_TTUPLE; cstage twin: // tuple_eslot (cmd/w6c/cgen.c). -export fn tupeslot(ti: *tinfo) i32 = { - let t: *tinfo = ti; +export fn tupeslot(ti: *syntax.tinfo) i32 = { + let t: *syntax.tinfo = ti; t = tichase(t); if (t == nil) { return 8; }; - if (t.kind == tykind.TY_VOID) { return 0; }; + if (t.kind == syntax.tykind.TY_VOID) { return 0; }; // a literal tuple's stamped element can be untyped_str (size 0) — // it occupies the str header slot (the C-t2 type_isstr lesson). - if (t.kind == tykind.TY_UNTYPED_STR) { return tyslicesize(): i32; }; - if (t.kind == tykind.TY_STR || t.kind == tykind.TY_SLICE || - t.kind == tykind.TY_TAGGED) { + if (t.kind == syntax.tykind.TY_UNTYPED_STR) { return tyslicesize(): i32; }; + if (t.kind == syntax.tykind.TY_STR || t.kind == syntax.tykind.TY_SLICE || + t.kind == syntax.tykind.TY_TAGGED) { return ((t.size + 7u64) & ~7u64): i32; }; return 8; }; -export fn tupeslotn(n: *node) i32 = { +export fn tupeslotn(n: *syntax.node) i32 = { if (n == nil) { return 8; }; - return tupeslot(n.type_: *tinfo); + return tupeslot(n.type_: *syntax.tinfo); }; // rettupleof — the N_TTUPLE return-type node of an N_CALL rhs (else nil). // wwstage has no checker, so the receive sites read each tuple element's // width from the called fn's declared return type. Mirrors the callee // resolution shared by cgmlet/cgmassign. -fn rettupleof(c: *cgen, rhs: *node) *node = { +fn rettupleof(c: *cgen, rhs: *syntax.node) *syntax.node = { if (rhs == nil) { return nil; }; - if (rhs.kind != nkind.N_CALL) { return nil; }; - let callee: *node = rhs.lhs; + if (rhs.kind != syntax.nkind.N_CALL) { return nil; }; + let callee: *syntax.node = rhs.lhs; if (callee == nil) { return nil; }; let cnm: str; cnm.ptr = nil; cnm.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { cnm = callee.str; cmod = c.curmod; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { cnm = callee.str; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cnm.len == 0) { return nil; }; - let rtyp: *node = fnretlookupmod(c, cnm, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cnm, cmod); if (rtyp == nil) { return nil; }; - if (rtyp.kind != nkind.N_TTUPLE) { return nil; }; + if (rtyp.kind != syntax.nkind.N_TTUPLE) { return nil; }; return rtyp; }; @@ -209,24 +209,24 @@ fn rettupleof(c: *cgen, rhs: *node) *node = { // nodes). Mirror of cstage node_tuplearg; the cgcall push site // loud-stops any other tuple-typed source shape (rule 7). rettupleof // stays N_CALL-scoped for the destructure/reassign receive sites. -fn nodetuplearg(c: *cgen, a: *node) *node = { +fn nodetuplearg(c: *cgen, a: *syntax.node) *syntax.node = { if (a == nil) { return nil; }; - if (a.kind == nkind.N_TUPLE) { return a; }; - if (a.kind == nkind.N_IDENT) { + if (a.kind == syntax.nkind.N_TUPLE) { return a; }; + if (a.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.str); if (lc == nil) { return nil; }; - let tn: *node = lc.tnode; - for (tn != nil && tn.kind == nkind.N_TNAME) { + let tn: *syntax.node = lc.tnode; + for (tn != nil && tn.kind == syntax.nkind.N_TNAME) { tn = aliaslookup(c, tn.str); }; if (tn != nil) { - if (tn.kind == nkind.N_TTUPLE) { return tn; }; + if (tn.kind == syntax.nkind.N_TTUPLE) { return tn; }; }; return nil; }; - let t: *node = inferletcalltype(c, a); + let t: *syntax.node = inferletcalltype(c, a); if (t != nil) { - if (t.kind == nkind.N_TTUPLE) { return t; }; + if (t.kind == syntax.nkind.N_TTUPLE) { return t; }; }; return nil; }; @@ -238,7 +238,7 @@ fn nodetuplearg(c: *cgen, a: *node) *node = { // registers; a float rides the SSE cursor (X0,X1); a scalar stores 1 // INTEGER word. The caller owns the dual cursor (validated + // advanced). Byte-identical to the cstage tuple_store (cmd/w6c/cgen.c). -fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *node) void = { +fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *syntax.node) void = { if (eslot == 0) { return; }; // void element: the checker's 0-slot if (eslot > 8) { let k: i32 = 0; @@ -280,7 +280,7 @@ fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *node) os.write(2, ls.ptr, ls.len: u64); os.write(2, " ".ptr, 1u64); }; - let kn: str = nkname(tn.kind); + let kn: str = syntax.nkname(tn.kind); os.write(2, kn.ptr, kn.len: u64); os.write(2, "\n".ptr, 1u64); os.exit(1); @@ -317,7 +317,7 @@ fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *node) // declared-TAGGED slot counted ONE word here while the receive walks // the declared eslot — the cursor shifted and every later element // read garbage. Declared-tagged keys the count on the DECLARED box. -fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { +fn tuplitgpwords(c: *cgen, e: *syntax.node, dtn: *syntax.node) i32 = { if (dtn != nil) { if (istaggedtype(c, dtn)) { return tupeslotn(dtn) / 8; }; }; @@ -325,10 +325,10 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { if (nodeisstr(c, e) || nodeisslice(c, e)) { return (tyslicesize() / 8i64): i32; }; - let t: *tinfo = e.type_: *tinfo; + let t: *syntax.tinfo = e.type_: *syntax.tinfo; t = tichase(t); - if (t != nil && (t.kind == tykind.TY_TAGGED || - t.kind == tykind.TY_VOID)) { + if (t != nil && (t.kind == syntax.tykind.TY_TAGGED || + t.kind == syntax.tykind.TY_VOID)) { return tupeslotn(e) / 8; }; return 1; @@ -351,11 +351,11 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { // tagged-@retscr shape) and pushes the box words. A tagged->tagged // SUBSET element (eslot mismatch) needs a tag remap on the way into // the slot — loud (rule 7, the #23/#40 widening family). -fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { - let t: *tinfo = e.type_: *tinfo; +fn tuplitpushelem(c: *cgen, e: *syntax.node, dtn: *syntax.node) void = { + let t: *syntax.tinfo = e.type_: *syntax.tinfo; t = tichase(t); let etagged: bool = false; - if (t != nil) { if (t.kind == tykind.TY_TAGGED) { etagged = true; }; }; + if (t != nil) { if (t.kind == syntax.tykind.TY_TAGGED) { etagged = true; }; }; if (dtn != nil) { if (istaggedtype(c, dtn) && !etagged) { let eslot: i32 = tupeslotn(dtn); @@ -368,7 +368,7 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { emitline("(BP)\n"); z += 8; }; - cgwidentaggedstore(c, dtn.type_: *tinfo, e, + cgwidentaggedstore(c, dtn.type_: *syntax.tinfo, e, "BP", scr, eslot); let pk: i32 = 0; for (pk < eslot / 8) { @@ -390,7 +390,7 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { if (etagged) { let eslot: i32 = tupeslotn(e); let eoff: i32 = 0; - if (e.kind == nkind.N_IDENT) { eoff = localfind(c, e.str); }; + if (e.kind == syntax.nkind.N_IDENT) { eoff = localfind(c, e.str); }; if (eoff == 0) { let m22: str = "#22a: tagged tuple element from a non-local source shape unwired (ident locals only; rule 7; call-source is task #41, widening #23, deref/cast #35)\n"; os.write(2, m22.ptr, m22.len: u64); @@ -407,7 +407,7 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { return; }; cgexpr(c, e); - if (t != nil && t.kind == tykind.TY_VOID) { return; }; + if (t != nil && t.kind == syntax.tykind.TY_VOID) { return; }; emitline("\tPUSHQ\tAX\n"); if (nodeisstr(c, e) || nodeisslice(c, e)) { emitline("\tPUSHQ\tBX\n"); @@ -433,18 +433,18 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { // declared eslot — see tuplitgpwords / tuplitpushelem. Mirrors cstage // cg_tuple_lit_to_cursor's decl walk; decl.list nodes wrap the elem // type in .lhs (the c.fnret.list shape the over-cap arm walks). -fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { - let dp0: *node = nil; +fn cgtuplelittocursor(c: *cgen, tuple: *syntax.node, decl: *syntax.node) void = { + let dp0: *syntax.node = nil; if (decl != nil) { - if (decl.kind == nkind.N_TTUPLE) { dp0 = decl.list; }; + if (decl.kind == syntax.nkind.N_TTUPLE) { dp0 = decl.list; }; }; let ssecap: i32 = TUPLE_SSECAP; let gptotal: i32 = 0; let ssecount: i32 = 0; - let dp: *node = dp0; - let e: *node = tuple.list; + let dp: *syntax.node = dp0; + let e: *syntax.node = tuple.list; for (e != nil) { - let dtn: *node = nil; + let dtn: *syntax.node = nil; if (dp != nil) { dtn = dp.lhs; }; let dtagged: bool = false; if (dtn != nil) { dtagged = istaggedtype(c, dtn); }; @@ -469,7 +469,7 @@ fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { dp = dp0; e = tuple.list; for (e != nil) { - let dtn: *node = nil; + let dtn: *syntax.node = nil; if (dp != nil) { dtn = dp.lhs; }; let dtagged: bool = false; if (dtn != nil) { dtagged = istaggedtype(c, dtn); }; @@ -499,7 +499,7 @@ fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { dp = dp0; e = tuple.list; for (e != nil) { - let dtn: *node = nil; + let dtn: *syntax.node = nil; if (dp != nil) { dtn = dp.lhs; }; let dtagged: bool = false; if (dtn != nil) { dtagged = istaggedtype(c, dtn); }; @@ -527,14 +527,14 @@ fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { // / `return t` / `let q = t` over a tuple ident leave the whole tuple in the // cursor, not just word0 in AX. Over-cap loud-stops (rule 7; #10). Mirror of // cstage cg_tuple_slot_to_cursor. -fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { +fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *syntax.tinfo) void = { let gptotal: i32 = 0; let ssecount: i32 = 0; - let el: *ttupleelem = tu.tupleelems; + let el: *syntax.ttupleelem = tu.tupleelems; for (el != nil) { - let et: *tinfo = el.type_; + let et: *syntax.tinfo = el.type_; et = tichase(et); - if (et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64)) { + if (et != nil && (et.kind == syntax.tykind.TY_F32 || et.kind == syntax.tykind.TY_F64)) { ssecount = ssecount + 1; } else { gptotal = gptotal + tupeslot(el.type_) / 8; @@ -551,13 +551,13 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { let foff: i32 = 0; el = tu.tupleelems; for (el != nil) { - let et: *tinfo = el.type_; + let et: *syntax.tinfo = el.type_; et = tichase(et); - let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); + let isflt: bool = et != nil && (et.kind == syntax.tykind.TY_F32 || et.kind == syntax.tykind.TY_F64); let eslot: i32 = tupeslot(el.type_); if (isflt) { let mov: str = "MOVSD"; - if (et.kind == tykind.TY_F32) { mov = "MOVSS"; }; + if (et.kind == syntax.tykind.TY_F32) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); emitoff((srcoff + foff): i64); emitline("(BP), "); @@ -590,13 +590,13 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { // elements ride a different SysV class — loud-stop (rule 7; the per- // eightbyte tagged-tuple-payload classification is the #243 follow-up). // Mirror of cstage cg_tagged_tuple_payload_shift. -fn cgtaggedtuplepayloadshift(c: *cgen, tup: *tinfo) void = { +fn cgtaggedtuplepayloadshift(c: *cgen, tup: *syntax.tinfo) void = { let words: i32 = 0; - let el: *ttupleelem = tup.tupleelems; + let el: *syntax.ttupleelem = tup.tupleelems; for (el != nil) { - let et: *tinfo = el.type_; + let et: *syntax.tinfo = el.type_; et = tichase(et); - let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); + let isflt: bool = et != nil && (et.kind == syntax.tykind.TY_F32 || et.kind == syntax.tykind.TY_F64); if (isflt || tupeslot(el.type_) != 8) { let msg: str = "tuple-in-union ? unwrap: float/slice/str/tagged payload element needs SysV per-eightbyte classification (see #243); only integer tuple payloads supported\n"; os.write(2, msg.ptr, msg.len: u64); @@ -621,9 +621,9 @@ fn cgtaggedtuplepayloadshift(c: *cgen, tup: *tinfo) void = { }; }; -fn cgreturn(c: *cgen, n: *node) void = { +fn cgreturn(c: *cgen, n: *syntax.node) void = { rundefers(c); - let rhs: *node = n.lhs; + let rhs: *syntax.node = n.lhs; if (rhs != nil) { // #83 / #164 (#107): positional register-return over a SysV // dual class cursor (harec create_unpack_bindings, ref/harec/src/ @@ -646,7 +646,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // below, which routes it via cgwidentaggedstore. Without this // guard the bare-tuple arm fired first and dropped the tag, // returning (AX=word0, DX=word1) with no tag word. - if (rhs.kind == nkind.N_TUPLE && !istaggedtype(c, c.fnret)) { + if (rhs.kind == syntax.nkind.N_TUPLE && !istaggedtype(c, c.fnret)) { let ssecap: i32 = TUPLE_SSECAP; // X0,X1 per SysV let gptotal: i32 = 0; let ssecount: i32 = 0; @@ -658,16 +658,16 @@ fn cgreturn(c: *cgen, n: *node) void = { // declared eslot (2 words sent for a 3-word shape; // ken /tmp/ken57 p8/p9). Same pt walk the over-cap arm // already does (#240/#22b). Mirrors cstage cgreturn. - let rp0: *node = nil; + let rp0: *syntax.node = nil; if (c.fnret != nil) { - if (c.fnret.kind == nkind.N_TTUPLE) { + if (c.fnret.kind == syntax.nkind.N_TTUPLE) { rp0 = c.fnret.list; }; }; - let rp: *node = rp0; - let e: *node = rhs.list; + let rp: *syntax.node = rp0; + let e: *syntax.node = rhs.list; for (e != nil) { - let rdtn: *node = nil; + let rdtn: *syntax.node = nil; if (rp != nil) { rdtn = rp.lhs; }; let rdtag: bool = false; if (rdtn != nil) { rdtag = istaggedtype(c, rdtn); }; @@ -709,15 +709,15 @@ fn cgreturn(c: *cgen, n: *node) void = { // (#10 Fold B). Byte-identical to cstage cgen.c // N_RETURN over-cap tuple arm. let saoff: i32 = localfind(c, "@sretarg"); - let pt: *node = nil; + let pt: *syntax.node = nil; if (c.fnret != nil) { pt = c.fnret.list; }; - let we: *node = rhs.list; + let we: *syntax.node = rhs.list; let foff: i32 = 0; for (we != nil) { - let dt: *tinfo = nil; - if (pt != nil) { dt = pt.lhs.type_: *tinfo; }; + let dt: *syntax.tinfo = nil; + if (pt != nil) { dt = pt.lhs.type_: *syntax.tinfo; }; dt = tichase(dt); - if (dt != nil && dt.kind == tykind.TY_TAGGED) { + if (dt != nil && dt.kind == syntax.tykind.TY_TAGGED) { // #22b (task #28): MEMORY-class tagged // element — the whole box copies through // the sret pointer mem-to-mem from the @@ -732,11 +732,11 @@ fn cgreturn(c: *cgen, n: *node) void = { // follow-ups). Mirror of cstage cgen.c // N_RETURN over-cap tagged arm. let eslot: i32 = tupeslotn(pt.lhs); - let eu: *tinfo = we.type_: *tinfo; + let eu: *syntax.tinfo = we.type_: *syntax.tinfo; eu = tichase(eu); let eoff: i32 = 0; - if (we.kind == nkind.N_IDENT && eu != nil) { - if (eu.kind == tykind.TY_TAGGED && tupeslotn(we) == eslot) { + if (we.kind == syntax.nkind.N_IDENT && eu != nil) { + if (eu.kind == syntax.tykind.TY_TAGGED && tupeslotn(we) == eslot) { eoff = localfind(c, we.str); }; }; @@ -767,7 +767,7 @@ fn cgreturn(c: *cgen, n: *node) void = { let wide: bool = nodeisstr(c, we) || nodeisslice(c, we); let esz: i32 = 8; if (pt != nil) { - let eti: *tinfo = pt.lhs.type_: *tinfo; + let eti: *syntax.tinfo = pt.lhs.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; }; cgexpr(c, we); @@ -843,7 +843,7 @@ fn cgreturn(c: *cgen, n: *node) void = { rp = rp0; e = rhs.list; for (e != nil) { - let rdtn: *node = nil; + let rdtn: *syntax.node = nil; if (rp != nil) { rdtn = rp.lhs; }; let rdtag: bool = false; if (rdtn != nil) { rdtag = istaggedtype(c, rdtn); }; @@ -878,7 +878,7 @@ fn cgreturn(c: *cgen, n: *node) void = { rp = rp0; e = rhs.list; for (e != nil) { - let rdtn: *node = nil; + let rdtn: *syntax.node = nil; if (rp != nil) { rdtn = rp.lhs; }; let rdtag: bool = false; if (rdtn != nil) { rdtag = istaggedtype(c, rdtn); }; @@ -937,17 +937,17 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_INDEX tagged-element return fell to the scalar-variant // shuffle (MOVQ AX,DX; MOVQ $0,AX), dropping the payload. let forwardtagged: bool = false; - if ((rhs.kind == nkind.N_CALL || rhs.kind == nkind.N_INDEX || rhs.kind == nkind.N_DOT) && rhs.type_ != nil && c.fnret != nil && c.fnret.type_ != nil) { - let ru: *tinfo = rhs.type_: *tinfo; + if ((rhs.kind == syntax.nkind.N_CALL || rhs.kind == syntax.nkind.N_INDEX || rhs.kind == syntax.nkind.N_DOT) && rhs.type_ != nil && c.fnret != nil && c.fnret.type_ != nil) { + let ru: *syntax.tinfo = rhs.type_: *syntax.tinfo; ru = tichase(ru); - let fu: *tinfo = c.fnret.type_: *tinfo; + let fu: *syntax.tinfo = c.fnret.type_: *syntax.tinfo; fu = tichase(fu); - if (ru != nil && fu != nil && ru.kind == tykind.TY_TAGGED && fu.kind == tykind.TY_TAGGED) { + if (ru != nil && fu != nil && ru.kind == syntax.tykind.TY_TAGGED && fu.kind == syntax.tykind.TY_TAGGED) { if (ru == fu) { forwardtagged = true; } else if (ru.nullable == fu.nullable) { - let pa: *tparam = ru.params; - let pb: *tparam = fu.params; + let pa: *syntax.tparam = ru.params; + let pb: *syntax.tparam = fu.params; let same: bool = true; for (pa != nil && pb != nil) { if (pa.type_ != pb.type_) { same = false; }; @@ -969,7 +969,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // cgwidentaggedstore's non-BP base. if (sretretsize(c, c.fnret) > 0) { let sa38v: i32 = localfind(c, "@sretarg"); - if (forwardtagged && rhs.kind == nkind.N_CALL) { + if (forwardtagged && rhs.kind == syntax.nkind.N_CALL) { // exact-type N_CALL forward: inner sret's // into outer's dest; an N_INDEX/N_DOT // source routes through the widener's @@ -985,14 +985,14 @@ fn cgreturn(c: *cgen, n: *node) void = { c.lastwasreturn = 1; return; }; - let ru38: *tinfo = rhs.type_: *tinfo; + let ru38: *syntax.tinfo = rhs.type_: *syntax.tinfo; ru38 = tichase(ru38); if (ru38 != nil) { // #37 wired the N_INDEX/N_DOT mem-read into // the widener; the remaining >32B kinds stay // loud. - if (ru38.kind == tykind.TY_TAGGED - && rhs.kind != nkind.N_IDENT + if (ru38.kind == syntax.tykind.TY_TAGGED + && rhs.kind != syntax.nkind.N_IDENT && ru38.size: i32 > TUPLE_GPCAP * 8 && !taggedmemread(c, rhs)) { let m38e: str = "#40: widening tagged return-forward of a >32B source needs mem-to-mem tag-remap (unwired)\n"; @@ -1003,7 +1003,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("\tMOVQ\t"); emitoff(sa38v: i64); emitline("(BP), BX\n"); - cgwidentaggedstore(c, c.fnret.type_: *tinfo, rhs, + cgwidentaggedstore(c, c.fnret.type_: *syntax.tinfo, rhs, "BX", 0, slotsize(c, c.fnret)); emitline("\tMOVQ\t"); emitoff(sa38v: i64); @@ -1028,7 +1028,7 @@ fn cgreturn(c: *cgen, n: *node) void = { }; // #242: a tuple variant packs into the union // payload via cgwidentaggedstore's TY_TUPLE arm. - if (rhs.kind == nkind.N_TUPLE) { + if (rhs.kind == syntax.nkind.N_TUPLE) { needswiden = true; }; // Family C (#35/#46): a mem-based tagged @@ -1052,15 +1052,15 @@ fn cgreturn(c: *cgen, n: *node) void = { // EXACT-type tagged casts on cstage's passthrough // (forwardtagged's own ru==fu equality) so byte-id // holds. - let ru1: *tinfo = rhs.type_: *tinfo; + let ru1: *syntax.tinfo = rhs.type_: *syntax.tinfo; ru1 = tichase(ru1); - let fu1: *tinfo = nil; + let fu1: *syntax.tinfo = nil; if (c.fnret != nil) { - fu1 = c.fnret.type_: *tinfo; + fu1 = c.fnret.type_: *syntax.tinfo; fu1 = tichase(fu1); }; if (ru1 != nil && fu1 != nil) { - if (ru1.kind == tykind.TY_TAGGED && ru1 != fu1) { + if (ru1.kind == syntax.tykind.TY_TAGGED && ru1 != fu1) { needswiden = true; }; // S3/#35: a SAME-TYPE tagged CAST (ru1 == fu1, @@ -1078,7 +1078,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // "N_CAST defeats srcreg"; peeling here instead // would reroute a call/dot source to passthrough // and break byte-id. - if (rhs.kind == nkind.N_CAST && ru1.kind == tykind.TY_TAGGED && ru1 == fu1) { + if (rhs.kind == syntax.nkind.N_CAST && ru1.kind == syntax.tykind.TY_TAGGED && ru1 == fu1) { needswiden = true; }; }; @@ -1107,7 +1107,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, c.fnret.type_: *tinfo, rhs, "BP", + cgwidentaggedstore(c, c.fnret.type_: *syntax.tinfo, rhs, "BP", scroff, rsz); // Tagged-return ABI loads at most 4 eightbytes // (AX/DX/CX/R8). A union whose slot exceeds 32B @@ -1172,9 +1172,9 @@ fn cgreturn(c: *cgen, n: *node) void = { // the SSoT cstage reads via node_isfloat / type_isf32. let rfk: i32 = 0; if (rhs != nil) { - let rety: *tinfo = rhs.type_: *tinfo; - if (typeisf32(rety)) { rfk = 1; } - else { if (typeisfloat(rety)) { rfk = 2; }; }; + let rety: *syntax.tinfo = rhs.type_: *syntax.tinfo; + if (syntax.typeisf32(rety)) { rfk = 1; } + else { if (syntax.typeisfloat(rety)) { rfk = 2; }; }; }; if (nodeisslice(c, rhs)) { // cgexpr leaves (AX=ptr, BX=len, CX=cap). @@ -1257,7 +1257,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // @sretarg(BP), AX is redundant after inner's // RET but kept for byte-id symmetry with the // N_IDENT / N_STRUCTLIT arms below. - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { c.sretforward = 1; cgexpr(c, rhs); emitline("\tMOVQ\t"); @@ -1276,15 +1276,15 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_RETURN sret arm. N_ARRLIT >24B has no consumer // (loud-stops in cstage); not wired here. let addrsrc: bool = false; - if (rhs.kind == nkind.N_IDENT) { okrhs = true; }; - if (rhs.kind == nkind.N_STRUCTLIT) { okrhs = true; }; - if (rhs.kind == nkind.N_DOT) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_INDEX) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_IDENT) { okrhs = true; }; + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { okrhs = true; }; + if (rhs.kind == syntax.nkind.N_DOT) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_INDEX) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { okrhs = true; addrsrc = true; }; }; if (okrhs) { - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { // #63: the >24B sret RETURN twin of the :2421 // let-init fix. sretretsize chases the alias for // the size GATE (so this sret arm fires for a >24B @@ -1297,7 +1297,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // (SILENT wrong, runtime-0). structlookupchain chases // to the base struct; cs fills via the resolved // Type*, runtime-correct. - let trefn: *node = rhs.lhs; + let trefn: *syntax.node = rhs.lhs; let sret_si: *structinfo = structlookupchain(c, trefn); if (sret_si != nil) { let emptys: str; @@ -1406,7 +1406,7 @@ fn cgreturn(c: *cgen, n: *node) void = { let rname: str; rname.ptr = nil; rname.len = 0; if (c.fnret != nil) { - if (c.fnret.kind == nkind.N_TNAME) { + if (c.fnret.kind == syntax.nkind.N_TNAME) { rname = c.fnret.str; }; }; @@ -1423,7 +1423,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_DOT/N_INDEX/deref memcpy into @retscr before the // shared structfloatclass tail (mirror cstage cgen.c). let addrsrc: bool = false; - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { okrhs = true; // #41 (#263 ww-runtime-correct): a module-global struct // source has no BP slot — route it through the addrsrc @@ -1434,13 +1434,13 @@ fn cgreturn(c: *cgen, n: *node) void = { addrsrc = true; }; }; - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { okrhs = true; }; - if (rhs.kind == nkind.N_DOT) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_INDEX) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_DOT) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_INDEX) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { okrhs = true; addrsrc = true; }; }; if (okrhs) { let scroff: i32 = localadd(c, @@ -1455,7 +1455,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("\tMOVQ\tAX, "); emitoff((scroff + 16): i64); emitline("(BP)\n"); - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { // Delegate to the shared BP-relative // structlit fill helper. Same store // sequence the inline pre-#17 walk @@ -1615,7 +1615,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // (tinfo.size = sub.size*len) mirrors cstage rt->size. No // structfloatclass (pure-int arrays); N_CALL forward at reg- // class falls to the default cgexpr passthrough below. - if (c.fnret != nil && c.fnret.kind == nkind.N_TARRAY) { + if (c.fnret != nil && c.fnret.kind == syntax.nkind.N_TARRAY) { // #272: array return-by-value source-shape closure. // Beyond the #267 N_IDENT word-copy, route N_ARRLIT // (literal fill), N_DOT/N_INDEX/deref (aggargsrcaddr + @@ -1623,14 +1623,14 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_RETURN ≤24B arm. N_CALL stays on the cgexpr tail (the // callee already left AX/DX/CX). let arrok: bool = false; - if (rhs.kind == nkind.N_IDENT) { arrok = true; }; - if (rhs.kind == nkind.N_ARRLIT) { arrok = true; }; - if (rhs.kind == nkind.N_DOT) { arrok = true; }; - if (rhs.kind == nkind.N_INDEX) { arrok = true; }; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_IDENT) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_ARRLIT) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_DOT) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_INDEX) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { arrok = true; }; }; - let ati: *tinfo = c.fnret.type_: *tinfo; + let ati: *syntax.tinfo = c.fnret.type_: *syntax.tinfo; ati = tichase(ati); if (arrok && ati != nil) { let rsz: i32 = ati.size: i32; @@ -1646,7 +1646,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("\tMOVQ\tAX, "); emitoff((scroff + 16): i64); emitline("(BP)\n"); - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { let rl: *local = localfindnode(c, rhs.str); let roff: i32 = 0; if (rl != nil) { roff = rl.off; }; @@ -1678,28 +1678,28 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("(BP)\n"); k += 1; }; - } else { if (rhs.kind == nkind.N_ARRLIT) { + } else { if (rhs.kind == syntax.nkind.N_ARRLIT) { // scalar/float element fill; non-scalar // elements loud-stop (rule 7, no consumer). - let esubti: *tinfo = nil; + let esubti: *syntax.tinfo = nil; if (ati.sub != nil) { esubti = ati.sub; }; esubti = tichase(esubti); let esz: i32 = 8; if (esubti != nil) { esz = esubti.size: i32; }; let badel: bool = false; if (esubti != nil) { - if (esubti.kind == tykind.TY_STRUCT) { badel = true; }; - if (esubti.kind == tykind.TY_ARRAY) { badel = true; }; - if (esubti.kind == tykind.TY_TUPLE) { badel = true; }; - if (esubti.kind == tykind.TY_SLICE) { badel = true; }; - if (esubti.kind == tykind.TY_STR) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_STRUCT) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_ARRAY) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_TUPLE) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_SLICE) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_STR) { badel = true; }; }; if (badel) { let m2: str = "#272: array-literal return with non-scalar element unsupported (rule 7, no consumer)\n"; os.write(2, m2.ptr, m2.len: u64); os.exit(1); }; - let esub: *node = c.fnret.lhs; + let esub: *syntax.node = c.fnret.lhs; let isfl: bool = isfloattype(c, esub); let fmov: str = "MOVSD"; if (isf32type(c, esub)) { fmov = "MOVSS"; }; @@ -1707,11 +1707,11 @@ fn cgreturn(c: *cgen, n: *node) void = { if (esz == 1) { op = "MOVB"; } else { if (esz == 2) { op = "MOVW"; } else { if (esz == 4) { op = "MOVL"; }; }; }; let idx: i32 = 0; let repeat: bool = false; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { let isellip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; isellip = true; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; isellip = true; }; }; if (isellip) { e = nil; @@ -1835,14 +1835,14 @@ fn cgreturn(c: *cgen, n: *node) void = { // array-literal return (no consumer) also lands here (#276). let aggret: bool = false; if (c.fnret != nil) { - let rti: *tinfo = c.fnret.type_: *tinfo; + let rti: *syntax.tinfo = c.fnret.type_: *syntax.tinfo; rti = tichase(rti); if (rti != nil) { - if (rti.kind == tykind.TY_ARRAY) { aggret = true; }; - if (rti.kind == tykind.TY_STRUCT) { aggret = true; }; + if (rti.kind == syntax.tykind.TY_ARRAY) { aggret = true; }; + if (rti.kind == syntax.tykind.TY_STRUCT) { aggret = true; }; }; }; - if (aggret && rhs.kind != nkind.N_CALL) { + if (aggret && rhs.kind != syntax.nkind.N_CALL) { let m6: str = "#272/#276/#277: aggregate return reaches scalar default — unclosed shape (named-alias aggregate return or >24B array-literal; wwstage tinfo-dispatch deferred #277)\n"; os.write(2, m6.ptr, m6.len: u64); os.exit(1); @@ -1905,7 +1905,7 @@ fn cgreturn(c: *cgen, n: *node) void = { return; }; -fn cgexprstmt(c: *cgen, n: *node) void = { +fn cgexprstmt(c: *cgen, n: *syntax.node) void = { if (n.lhs != nil) { cgexpr(c, n.lhs); }; c.lastwasreturn = 0; return; @@ -1918,8 +1918,8 @@ fn cgexprstmt(c: *cgen, n: *node) void = { // store-op guarantee for rule-10 byte-id (ken). `arrtn` is the [count]T // type NODE (cglet n.lhs; cgslice the re-stamped tnode on arrlit.lhs, // #25); `rhs` the literal. Twin of cstage cg_arrlit_fill_bp. -fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { - let elemn: *node = arrtn.lhs; +fn cgarrlitfillbp(c: *cgen, arrtn: *syntax.node, rhs: *syntax.node, off: i32) void = { + let elemn: *syntax.node = arrtn.lhs; // #79 (#60 rider): alias-NAMED [count]T (`type A = [4]u32; let // a: A = [...]`) — arrtn is the N_TNAME leaf: elemn nil, esz // stayed the 8 sentinel and the per-element store strode MOVQ @@ -1932,12 +1932,12 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // stash alen for the `...` repeat bound (cstage cg_arrlit_fill_bp // receives the pre-chased bu and reads bu->alen). let aliasalen: i32 = -1; - let ati79: *tinfo = arrtn.type_: *tinfo; - if (ati79 != nil) { if (ati79.kind == tykind.TY_NAMED) { - let au79: *tinfo = tichase(ati79); - if (au79 != nil) { if (au79.kind == tykind.TY_ARRAY + let ati79: *syntax.tinfo = arrtn.type_: *syntax.tinfo; + if (ati79 != nil) { if (ati79.kind == syntax.tykind.TY_NAMED) { + let au79: *syntax.tinfo = tichase(ati79); + if (au79 != nil) { if (au79.kind == syntax.tykind.TY_ARRAY && au79.sub != nil) { - let en79: *node = newnode(nkind.N_TNAME, arrtn.file, arrtn.line, arrtn.col); + let en79: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, arrtn.file, arrtn.line, arrtn.col); en79.str = au79.sub.name; en79.type_ = au79.sub: *void; elemn = en79; @@ -1947,8 +1947,8 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { let esz: i32 = 8; let isstrel: bool = false; if (elemn != nil) { - if (elemn.kind == nkind.N_TNAME) { - if (streq(elemn.str, "str")) { + if (elemn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(elemn.str, "str")) { esz = primtypesize("str"): i32; isstrel = true; } else { @@ -1963,13 +1963,13 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // each element slot from its literal (cgstructlitfillbp) // or source ident (word-copy). esz is the element's // natural size (cstage esub->size). - let esubti: *tinfo = nil; - if (elemn != nil) { esubti = elemn.type_: *tinfo; }; + let esubti: *syntax.tinfo = nil; + if (elemn != nil) { esubti = elemn.type_: *syntax.tinfo; }; esubti = tichase(esubti); let isagg: bool = esubti != nil - && (esubti.kind == tykind.TY_STRUCT - || esubti.kind == tykind.TY_ARRAY - || esubti.kind == tykind.TY_TUPLE); + && (esubti.kind == syntax.tykind.TY_STRUCT + || esubti.kind == syntax.tykind.TY_ARRAY + || esubti.kind == syntax.tykind.TY_TUPLE); if (isagg) { esz = esubti.size: i32; }; // #20/#270 str-slice arm: a slice element (N_TSLICE) is // a 24B {ptr,len,cap} header — it matches no prim/str/agg @@ -1978,7 +1978,7 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // store dropped .len/.cap. Size it from the stamped tinfo // and route it through the 3-word header store below. let isslicel: bool = esubti != nil - && esubti.kind == tykind.TY_SLICE; + && esubti.kind == syntax.tykind.TY_SLICE; if (isslicel) { esz = esubti.size: i32; }; // #12: a tagged-union element. NOT folded into isagg — // isagg's body word-copies/fatals and never boxes the @@ -1989,7 +1989,7 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // 1/2/4, so a tagged 16/24B element keeps the wrong 8 // sentinel stride without this. let istaggedel: bool = esubti != nil - && esubti.kind == tykind.TY_TAGGED; + && esubti.kind == syntax.tykind.TY_TAGGED; if (istaggedel) { esz = esubti.size: i32; }; // #8: a named-narrow element (`[N]tk`, tk = enum i32) is // neither a builtin prim (primsize=0 above, so esz stayed @@ -2016,11 +2016,11 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { if (isf32type(c, elemn)) { fmov = "MOVSS"; }; let idx: i32 = 0; let repeat: bool = false; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { let isellip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; isellip = true; }; @@ -2029,10 +2029,10 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { e = nil; } else { if (isagg) { - if (e.kind == nkind.N_STRUCTLIT) { + if (e.kind == syntax.nkind.N_STRUCTLIT) { let esi: *structinfo = structlookupchain(c, elemn); cgstructlitfillbp(c, esi, e, off + idx * esz); - } else { if (e.kind == nkind.N_IDENT) { + } else { if (e.kind == syntax.nkind.N_IDENT) { let sl: *local = localfindnode(c, e.str); let soff: i32 = 0; if (sl != nil) { soff = sl.off; }; @@ -2128,9 +2128,9 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { if (repeat) { let total: i32 = idx; if (arrtn != nil) { - if (arrtn.kind == nkind.N_TARRAY) { + if (arrtn.kind == syntax.nkind.N_TARRAY) { if (arrtn.rhs != nil) { - if (arrtn.rhs.kind == nkind.N_INTLIT) { + if (arrtn.rhs.kind == syntax.nkind.N_INTLIT) { total = arrtn.rhs.uval: i32; }; }; @@ -2174,10 +2174,10 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // c.locals while cgletbody runs (Hare evals the init in the outer scope: // harec check.c clet runs cexpr before scope_define). localreserve bumps // the frame now so off + nested-let offsets stay stable. -fn cglet(c: *cgen, n: *node) void = { +fn cglet(c: *cgen, n: *syntax.node) void = { let nm: str = n.str; let sz: i32 = letslotsize(c, n); - let tn: *node = n.lhs; + let tn: *syntax.node = n.lhs; if (tn == nil) { tn = inferletcalltype(c, n.rhs); }; let letloc: *local = localreserve(c, nm, sz, tn); cgletbody(c, n, letloc.off); @@ -2190,16 +2190,16 @@ fn cglet(c: *cgen, n: *node) void = { // binding into c.locals only AFTER, so a self-shadowing init // (`let x = f(x)`) resolves x in the OUTER scope (Hare evals the init in // the outer scope: harec check.c clet runs cexpr before scope_define). -fn cgletbody(c: *cgen, n: *node, off: i32) void = { +fn cgletbody(c: *cgen, n: *syntax.node, off: i32) void = { let nm: str = n.str; let sz: i32 = letslotsize(c, n); // `let x = f()?` has no annotation but the cgen's struct-field // paths need a tnode to dispatch off. Infer from f's tagged // success variant — see inferletcalltype. - let tn: *node = n.lhs; + let tn: *syntax.node = n.lhs; if (tn == nil) { tn = inferletcalltype(c, n.rhs); }; if (n.rhs != nil) { - let rhs: *node = n.rhs; + let rhs: *syntax.node = n.rhs; // `let s: []T = alloc([], n)!;` / `?` shortcut (#32, #45). // Mirror of cstage cgen.c N_LET arrlit-empty branch: allocate // n*esz bytes via rt_malloc, then build the {ptr, 0, n} slice @@ -2210,19 +2210,19 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // land an 8B region and a junk slice header). `?` propagates // nomem via AX = tag of nomem in c.fnret, then epilogue RET. { - let scall: *node = nil; + let scall: *syntax.node = nil; let viatryunw: bool = false; let viatryprop: bool = false; - if (rhs.kind == nkind.N_TRYUNW) { + if (rhs.kind == syntax.nkind.N_TRYUNW) { if (rhs.lhs != nil) { - if (rhs.lhs.kind == nkind.N_CALL) { + if (rhs.lhs.kind == syntax.nkind.N_CALL) { scall = rhs.lhs; viatryunw = true; }; }; - } else { if (rhs.kind == nkind.N_TRYPROP) { + } else { if (rhs.kind == syntax.nkind.N_TRYPROP) { if (rhs.lhs != nil) { - if (rhs.lhs.kind == nkind.N_CALL) { + if (rhs.lhs.kind == syntax.nkind.N_CALL) { scall = rhs.lhs; viatryprop = true; }; @@ -2235,18 +2235,18 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // silently miss after #1 if check.ww's astsize ever // drifted from this dispatch. if (scall != nil && tn != nil - && tn.kind == nkind.N_TSLICE && sz == tyslicesize(): i32) { - let callee: *node = scall.lhs; - let a0: *node = scall.list; - let a1: *node = nil; - let a2: *node = nil; + && tn.kind == syntax.nkind.N_TSLICE && sz == tyslicesize(): i32) { + let callee: *syntax.node = scall.lhs; + let a0: *syntax.node = scall.list; + let a1: *syntax.node = nil; + let a2: *syntax.node = nil; if (a0 != nil) { a1 = a0.next; }; if (a1 != nil) { a2 = a1.next; }; if (callee != nil && a0 != nil && a1 != nil && a2 == nil) { - if (callee.kind == nkind.N_IDENT - && streq(callee.str, "alloc") - && a0.kind == nkind.N_ARRLIT + if (callee.kind == syntax.nkind.N_IDENT + && syntax.streq(callee.str, "alloc") + && a0.kind == syntax.nkind.N_ARRLIT && a0.list == nil) { shapeok = true; }; @@ -2260,7 +2260,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // cstage path byte-identically. A bare primsize/slotsize // fork would silently land esz=1 on `[]point`. let esz: i32 = elemsizeofc(c, tn); - let count: *node = scall.list.next; + let count: *syntax.node = scall.list.next; cgexpr(c, count); emitline("\tPUSHQ\tAX\n"); if (esz > 1) { @@ -2301,14 +2301,14 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // holds no tinfo singleton, so find the nomem // variant by its NAMED name over tinfo.params. let nidx: i32 = -1; - let nti: *tinfo = nil; - if (c.fnret != nil) { nti = c.fnret.type_: *tinfo; }; + let nti: *syntax.tinfo = nil; + if (c.fnret != nil) { nti = c.fnret.type_: *syntax.tinfo; }; nti = tichase(nti); - if (nti != nil) { if (nti.kind == tykind.TY_TAGGED) { - let np: *tparam = nti.params; + if (nti != nil) { if (nti.kind == syntax.tykind.TY_TAGGED) { + let np: *syntax.tparam = nti.params; let nidx2: i32 = 0; for (np != nil) { - let nvt: *tinfo = np.type_; + let nvt: *syntax.tinfo = np.type_; if (nvt != nil) { if (variantnamematch(nvt.name, "nomem")) { nidx = nidx2; break; }; }; @@ -2349,23 +2349,23 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // Mirrors cstage cgen.c N_LET tagged arm. if (istaggedtype(c, tn)) { let letsret: i32 = 0; - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { letsret = callsretsize(c, rhs); }; if (letsret == 0) { - cgwidentaggedstore(c, tn.type_: *tinfo, rhs, + cgwidentaggedstore(c, tn.type_: *syntax.tinfo, rhs, "BP", off, sz); c.lastwasreturn = 0; return; }; - let lru: *tinfo = rhs.type_: *tinfo; + let lru: *syntax.tinfo = rhs.type_: *syntax.tinfo; lru = tichase(lru); - let llu: *tinfo = tn.type_: *tinfo; + let llu: *syntax.tinfo = tn.type_: *syntax.tinfo; llu = tichase(llu); let exact38: bool = false; if (lru != nil && lru == llu) { exact38 = true; } else { - if (typeeq(rhs.type_: *tinfo, tn.type_: *tinfo)) { + if (syntax.typeeq(rhs.type_: *syntax.tinfo, tn.type_: *syntax.tinfo)) { exact38 = true; }; }; @@ -2399,12 +2399,12 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // keying). Alias-peel mirrors cstage's type_chase_named; the // unannotated `let t = f()` shape rides the inferletcalltype // tn above. - let ttup: *node = tn; - for (ttup != nil && ttup.kind == nkind.N_TNAME) { + let ttup: *syntax.node = tn; + for (ttup != nil && ttup.kind == syntax.nkind.N_TNAME) { ttup = aliaslookup(c, ttup.str); }; if (ttup != nil) { - if (ttup.kind == nkind.N_TTUPLE + if (ttup.kind == syntax.nkind.N_TTUPLE && sretretsize(c, ttup) == 0) { // #57: a tuple LITERAL rhs carries the DECLARED // type into the cursor fill — its stamped type @@ -2414,7 +2414,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // (let-twin of the return-position bug; probe // /tmp/p57/q1_let). Same emission as the cgexpr // route for every declared-tagged-free literal. - if (rhs.kind == nkind.N_TUPLE) { + if (rhs.kind == syntax.nkind.N_TUPLE) { cgtuplelittocursor(c, rhs, ttup); } else { cgexpr(c, rhs); @@ -2422,9 +2422,9 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { let gpcur: i32 = 0; let ssecur: i32 = 0; let eoff: i32 = 0; - let q: *node = ttup.list; + let q: *syntax.node = ttup.list; for (q != nil) { - let qt: *node = q.lhs; + let qt: *syntax.node = q.lhs; let isflt: bool = isfloattype(c, qt); let eslot: i32 = tupeslotn(qt); tupstore(c, gpcur, ssecur, @@ -2450,8 +2450,8 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // payload (or a void literal) slip through in-cap // (probe /tmp/i22b/p7) — the let-twin of the #22b // classify/emit skew. Mirrors cstage cgen.c N_LET net. - if (ttup.kind == nkind.N_TTUPLE - && rhs.kind != nkind.N_CALL + if (ttup.kind == syntax.nkind.N_TTUPLE + && rhs.kind != syntax.nkind.N_CALL && sretretsize(c, ttup) > 0) { cgexpr(c, rhs); let mnet: str = "over-cap tuple initialiser from a non-call source unwired (see #10/#22b)\n"; @@ -2476,7 +2476,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // (primsize's default-to-8-on-zero pattern is brittle for // composites generally. The str/slice element now stores all 3 // words; [N]tagged element arrays still hit the gap, task #12.) - if (rhs.kind == nkind.N_ARRLIT) { + if (rhs.kind == syntax.nkind.N_ARRLIT) { cgarrlitfillbp(c, n.lhs, rhs, off); c.lastwasreturn = 0; return; @@ -2487,7 +2487,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // values recursing into the helper instead of landing only AX // (the #17 silent-zero fix). Mirror of cstage cgen.c N_LET // structlit branch. - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { // #63: an alias-NAMED struct literal (`type rep2 = rep; // let r = rep2{id=6}`) parses its type ref as N_IDENT/N_TNAME // "rep2", but only the base `rep` is registered — bare @@ -2497,7 +2497,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // alias chain to the base struct, the #92/W2 SSoT already // adopted at cgenstmt:1974/:2687. cs chases via // type_chase_named, runtime-correct. - let trefn: *node = rhs.lhs; + let trefn: *syntax.node = rhs.lhs; let si: *structinfo = structlookupchain(c, trefn); if (si != nil) { cgstructlitfillbp(c, si, rhs, off); @@ -2511,7 +2511,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // before the CALL and the callee writes through it. No // AX/DX/CX shuffle; AX returns the dest pointer per SysV // sret discipline (irrelevant here). - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { let scs: i32 = callsretsize(c, rhs); if (scs > 0) { c.sretdestoff = off; @@ -2551,7 +2551,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // #169 sized tail is unreachable here. structfloatclass gates // to qualifying structs; all-int + f32 fall to the GP recv // below (byte-id / #171b). - if (rhs.kind == nkind.N_CALL && tn != nil) { + if (rhs.kind == syntax.nkind.N_CALL && tn != nil) { let sfc: i32 = structfloatclass(c, tn); if (sfc != 0) { cgexpr(c, rhs); @@ -2582,11 +2582,11 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { return; }; }; - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { let sname: str; sname.ptr = nil; sname.len = 0; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { + if (tn.kind == syntax.nkind.N_TNAME) { sname = tn.str; }; }; @@ -2644,9 +2644,9 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // above (callsretsize keyed). Array natural size (tinfo.size // = sub.size*len) mirrors cstage lu->size. No structfloatclass // (pure-int element arrays). - if (rhs.kind == nkind.N_CALL && tn != nil - && tn.kind == nkind.N_TARRAY) { - let ati: *tinfo = tn.type_: *tinfo; + if (rhs.kind == syntax.nkind.N_CALL && tn != nil + && tn.kind == syntax.nkind.N_TARRAY) { + let ati: *syntax.tinfo = tn.type_: *syntax.tinfo; ati = tichase(ati); if (ati != nil) { let lsz: i32 = ati.size: i32; @@ -2698,11 +2698,11 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // only the first qword (and a stale BX for sz==16 lets // via the str-init tail) — silent partial copy. Mirrors // cstage cgen.c N_LET struct-ident branch (Task #32). - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { let sname: str; sname.ptr = nil; sname.len = 0; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { sname = tn.str; }; + if (tn.kind == syntax.nkind.N_TNAME) { sname = tn.str; }; }; if (sname.len > 0) { let lsi: *structinfo = structlookup(c, sname); @@ -2771,25 +2771,25 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { if (aggsi != nil) { aggn = structabisize(aggsi); } else { - let aggti: *tinfo = nil; - if (tn != nil) { aggti = tn.type_: *tinfo; }; + let aggti: *syntax.tinfo = nil; + if (tn != nil) { aggti = tn.type_: *syntax.tinfo; }; aggti = tichase(aggti); if (aggti != nil) { - if (aggti.kind == tykind.TY_ARRAY) { + if (aggti.kind == syntax.tykind.TY_ARRAY) { aggn = aggti.size: i32; }; }; }; if (aggn > 8) { let havesrc: bool = false; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { cgexpr(c, rhs.lhs); emitline("\tMOVQ\tAX, SI\n"); havesrc = true; }; }; - if (!havesrc) { if (rhs.kind == nkind.N_IDENT) { + if (!havesrc) { if (rhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, rhs.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -2805,10 +2805,10 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // over-copies struct-defs on wwstage // only; mirror the defisaddressable // pairing instead. - let aggdtn: *node = defvartnode(c, rhs.str); + let aggdtn: *syntax.node = defvartnode(c, rhs.str); let aggisdef: bool = defvarstructinfo(c, rhs.str) != nil; if (aggdtn != nil) { - if (aggdtn.kind == nkind.N_TARRAY) { aggisdef = true; }; + if (aggdtn.kind == syntax.nkind.N_TARRAY) { aggisdef = true; }; }; if (isletvar(c, rhs.str) || aggisdef) { emitline("\tLEAQ\t"); @@ -2818,19 +2818,19 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { }; }; }; }; - if (!havesrc) { if (rhs.kind == nkind.N_DOT) { + if (!havesrc) { if (rhs.kind == syntax.nkind.N_DOT) { if (dotchainaddr(c, rhs, "SI")) { havesrc = true; }; }; }; - if (!havesrc) { if (rhs.kind == nkind.N_INDEX) { - let base: *node = rhs.lhs; - let idx: *node = rhs.rhs; - let bu: *tinfo = nil; - if (base != nil) { bu = base.type_: *tinfo; }; + if (!havesrc) { if (rhs.kind == syntax.nkind.N_INDEX) { + let base: *syntax.node = rhs.lhs; + let idx: *syntax.node = rhs.rhs; + let bu: *syntax.tinfo = nil; + if (base != nil) { bu = base.type_: *syntax.tinfo; }; bu = tichase(bu); - if (base != nil && base.kind == nkind.N_IDENT - && bu != nil && bu.kind == tykind.TY_ARRAY) { + if (base != nil && base.kind == syntax.nkind.N_IDENT + && bu != nil && bu.kind == syntax.tykind.TY_ARRAY) { let esz: i32 = 1; if (bu.sub != nil) { esz = bu.sub.size: i32; @@ -2866,8 +2866,8 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // address) or the &abase[bidx] spine (nested // N_IDENT-array base), then add. if (!havesrc && base != nil - && (base.kind == nkind.N_DOT - || base.kind == nkind.N_INDEX)) { + && (base.kind == syntax.nkind.N_DOT + || base.kind == syntax.nkind.N_INDEX)) { let esz2: i32 = 1; if (bu != nil && bu.sub != nil) { esz2 = bu.sub.size: i32; @@ -2881,18 +2881,18 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { }; emitline("\tPUSHQ\tAX\n"); let baseok: bool = false; - if (base.kind == nkind.N_DOT) { + if (base.kind == syntax.nkind.N_DOT) { if (dotbaseaddr(c, base, "AX")) { baseok = true; }; } else { - let ab: *node = base.lhs; - let bidx: *node = base.rhs; - let abu: *tinfo = nil; - if (ab != nil) { abu = ab.type_: *tinfo; }; + let ab: *syntax.node = base.lhs; + let bidx: *syntax.node = base.rhs; + let abu: *syntax.tinfo = nil; + if (ab != nil) { abu = ab.type_: *syntax.tinfo; }; abu = tichase(abu); - if (ab != nil && ab.kind == nkind.N_IDENT - && abu != nil && abu.kind == tykind.TY_ARRAY) { + if (ab != nil && ab.kind == syntax.nkind.N_IDENT + && abu != nil && abu.kind == syntax.tykind.TY_ARRAY) { let aesz: i32 = 1; if (abu.sub != nil) { aesz = abu.sub.size: i32; @@ -2985,10 +2985,10 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // cgen.c N_LET; pre-C4 this shape fell through to the // cgtryunw/cgtryprop gates, which the C4 tail below // now pre-empts in let position). - if (rhs.kind == nkind.N_TRYUNW - || rhs.kind == nkind.N_TRYPROP) { + if (rhs.kind == syntax.nkind.N_TRYUNW + || rhs.kind == syntax.nkind.N_TRYPROP) { if (rhs.lhs != nil) { - if (rhs.lhs.kind == nkind.N_CALL) { + if (rhs.lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, rhs.lhs) > 0) { let m38f: str = "#38b: `?`/`!` on an sret-class call result unwired (mem-based unwrap is a #40-family follow-up)\n"; os.write(2, m38f.ptr, m38f.len: u64); @@ -3085,14 +3085,14 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // would over-zero MOVQ-rounded to 24 and diverge from // cstage's exact 20-byte run. Handles direct N_TARRAY and // alias-to-array (N_TNAME chasing through TY_NAMED) alike. - let zti: *tinfo = n.lhs.type_: *tinfo; + let zti: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; zti = tichase(zti); - if (zti != nil && zti.kind == tykind.TY_ARRAY) { + if (zti != nil && zti.kind == syntax.tykind.TY_ARRAY) { zsz = zti.size: i32; - } else { if (n.lhs.kind == nkind.N_TNAME) { + } else { if (n.lhs.kind == syntax.nkind.N_TNAME) { let szi: *structinfo = structlookupchain(c, n.lhs); if (szi != nil) { - let ti: *tinfo = n.lhs.type_: *tinfo; + let ti: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; ti = tichase(ti); if (ti != nil) { zsz = ti.size: i32; }; }; @@ -3150,7 +3150,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { return; }; -fn cgif(c: *cgen, n: *node) void = { +fn cgif(c: *cgen, n: *syntax.node) void = { let els: str = mklabel(c, "else"); let endl: str = mklabel(c, "end"); cgexpr(c, n.cond); @@ -3170,7 +3170,7 @@ fn cgif(c: *cgen, n: *node) void = { return; }; -fn cgfor(c: *cgen, n: *node) void = { +fn cgfor(c: *cgen, n: *syntax.node) void = { // Match C cgen's label scheme: _loop_N for the top, // _endloop_N for the post-body merge. No separate cont // label when there's no post-expression. @@ -3234,7 +3234,7 @@ fn cgfor(c: *cgen, n: *node) void = { // the first lvalue, then pop DX into the second. Mirrors // cmd/w6c/cgen.c:2424-2440. Lvalues beyond two are dropped (same // as C — no fixture uses >2 today). -fn cgmassign(c: *cgen, n: *node) void = { +fn cgmassign(c: *cgen, n: *syntax.node) void = { // #83: positional per-element destructure REASSIGN. Same cursor as // cgmlet (and cgreturn; harec create_unpack_bindings, // ref/harec/src/check.c:1354-1416), but the slots already exist @@ -3247,7 +3247,7 @@ fn cgmassign(c: *cgen, n: *node) void = { // comma `a, s = f()` multi-assign is a retained ww-EXTENSION beyond // Hare (Hare tuple-unpack is binding-only); ww keeps the Go/rob-pike // multi-assign idiom — rule-9 carve-out. Over-capacity loud-stops. - let rettuple: *node = rettupleof(c, n.rhs); + let rettuple: *syntax.node = rettupleof(c, n.rhs); // #10 Fold B: over-cap tuple destructure REASSIGN. Same sret copy-out // as cgmlet but the slots already exist (localfind); a `_` / missing @@ -3256,7 +3256,7 @@ fn cgmassign(c: *cgen, n: *node) void = { // cstage N_MASSIGN over-cap arm. let sretrecv: i32 = 0; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { + if (n.rhs.kind == syntax.nkind.N_CALL) { sretrecv = callsretsize(c, n.rhs); }; }; @@ -3270,16 +3270,16 @@ fn cgmassign(c: *cgen, n: *node) void = { // fill/receive fall back to the rhs literal element's own stamped type // for the cursor stride (harec `_` advance; pinned by the R3 control). let litrhs: bool = false; - if (n.rhs != nil) { if (n.rhs.kind == nkind.N_TUPLE) { litrhs = true; }; }; - let synthdecl: *node = nil; + if (n.rhs != nil) { if (n.rhs.kind == syntax.nkind.N_TUPLE) { litrhs = true; }; }; + let synthdecl: *syntax.node = nil; if (litrhs) { - synthdecl = newnode(nkind.N_TTUPLE, n.rhs.file, n.rhs.line, n.rhs.col); - let dtail: *node = nil; - let lb0: *node = n.list; + synthdecl = syntax.newnode(syntax.nkind.N_TTUPLE, n.rhs.file, n.rhs.line, n.rhs.col); + let dtail: *syntax.node = nil; + let lb0: *syntax.node = n.list; for (lb0 != nil) { - let w: *node = newnode(nkind.N_TUPLE, n.rhs.file, n.rhs.line, n.rhs.col); + let w: *syntax.node = syntax.newnode(syntax.nkind.N_TUPLE, n.rhs.file, n.rhs.line, n.rhs.col); w.lhs = nil; - if (lb0.kind == nkind.N_IDENT) { + if (lb0.kind == syntax.nkind.N_IDENT) { let lc0: *local = localfindnode(c, lb0.str); if (lc0 != nil) { w.lhs = lc0.tnode; }; }; @@ -3295,12 +3295,12 @@ fn cgmassign(c: *cgen, n: *node) void = { if (sretrecv > 0) { let scr: i32 = localfind(c, "@sretscr"); - let pt2: *node = nil; + let pt2: *syntax.node = nil; if (rettuple != nil) { pt2 = rettuple.list; }; let foff: i32 = 0; - let lb: *node = n.list; + let lb: *syntax.node = n.list; for (lb != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (pt2 != nil) { tn = pt2.lhs; }; let isflt: bool = isfloattype(c, tn); // #22b: the >8B copy-out keys on the ACCESSOR's slot @@ -3313,11 +3313,11 @@ fn cgmassign(c: *cgen, n: *node) void = { let eslot: i32 = tupeslotn(tn); let esz: i32 = 8; if (pt2 != nil) { - let eti: *tinfo = pt2.lhs.type_: *tinfo; + let eti: *syntax.tinfo = pt2.lhs.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; }; let off: i32 = 0; - if (lb.kind == nkind.N_IDENT) { off = localfind(c, lb.str); }; + if (lb.kind == syntax.nkind.N_IDENT) { off = localfind(c, lb.str); }; if (off != 0) { if (isflt) { let mov: str = "MOVSD"; @@ -3367,18 +3367,18 @@ fn cgmassign(c: *cgen, n: *node) void = { let ssecap: i32 = TUPLE_SSECAP; // X0,X1 per SysV let gptotal: i32 = 0; let ssetotal: i32 = 0; - let l: *node = n.list; - let pt: *node = nil; + let l: *syntax.node = n.list; + let pt: *syntax.node = nil; if (rettuple != nil) { pt = rettuple.list; }; // #64: a tuple-LITERAL rhs keys element WIDTH on the DECLARED lvalue // type (synthdecl), not the rettuple (nil for a literal); a `_` slot // (declared type nil) falls back to the rhs literal element's own // stamped type for the cursor stride. - let dp: *node = nil; - let re: *node = nil; + let dp: *syntax.node = nil; + let re: *syntax.node = nil; if (litrhs) { dp = synthdecl.list; re = n.rhs.list; }; for (l != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (litrhs) { if (dp != nil && dp.lhs != nil) { tn = dp.lhs; } else { tn = re; }; } else { @@ -3416,7 +3416,7 @@ fn cgmassign(c: *cgen, n: *node) void = { re = nil; if (litrhs) { dp = synthdecl.list; re = n.rhs.list; }; for (l != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (litrhs) { if (dp != nil && dp.lhs != nil) { tn = dp.lhs; } else { tn = re; }; } else { @@ -3425,7 +3425,7 @@ fn cgmassign(c: *cgen, n: *node) void = { let isflt: bool = isfloattype(c, tn); let eslot: i32 = tupeslotn(tn); let off: i32 = 0; - if (l.kind == nkind.N_IDENT) { off = localfind(c, l.str); }; + if (l.kind == syntax.nkind.N_IDENT) { off = localfind(c, l.str); }; // harec `_` (off==0): skip the store but CONSUME the cursor // slot so the next element stays aligned. if (off != 0) { @@ -3456,8 +3456,8 @@ fn cgmassign(c: *cgen, n: *node) void = { // as (.ptr, .len, .cap). Position-agnostic — the // regs are routed by element type, not by AX/DX. // str IS []u8 (24B): cap rides R8 (#1/Phase 3, task #5). -fn cgmlet(c: *cgen, n: *node) void = { - let rhs: *node = n.rhs; +fn cgmlet(c: *cgen, n: *syntax.node) void = { + let rhs: *syntax.node = n.rhs; if (rhs == nil) { return; }; // #83: positional per-element destructure let-binding. Same cursor @@ -3468,7 +3468,7 @@ fn cgmlet(c: *cgen, n: *node) void = { // walked in lockstep. A slice/str rides its 3-word {ptr,len,cap} // header (ref/hare/rt/ensure.ha:4-8) into a header-sized slot; a // scalar rides 1 word into an 8B slot. Over-capacity loud-stops. - let rettuple: *node = rettupleof(c, rhs); + let rettuple: *syntax.node = rettupleof(c, rhs); // #10 Fold B: over-cap tuple destructure RECEIVE. The callee sret'd // the whole tuple into the @sretscr discard slot (cgcall sees @@ -3477,7 +3477,7 @@ fn cgmlet(c: *cgen, n: *node) void = { // element size — the t.0/t.1 layout), each at its NATURAL width // (#169). Byte-identical to the cstage N_MLET over-cap arm. let sretrecv: i32 = 0; - if (rhs.kind == nkind.N_CALL) { sretrecv = callsretsize(c, rhs); }; + if (rhs.kind == syntax.nkind.N_CALL) { sretrecv = callsretsize(c, rhs); }; // #242: rhs is a tuple already materialised in a local slot (a match- // bound union payload, `let (a,b)=t`), NOT a register-returning call. @@ -3487,22 +3487,22 @@ fn cgmlet(c: *cgen, n: *node) void = { // the SAME layout the tagged construct + match payload-bind write. // Mirror of cstage cgen.c N_MLET tuple-ident arm. The binding element // types ride l.lhs (stamped by the checker's stamptuplebinds). - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { let rl: *local = localfindnode(c, rhs.str); if (rl != nil) { - let rti: *tinfo = rl.tnode.type_: *tinfo; + let rti: *syntax.tinfo = rl.tnode.type_: *syntax.tinfo; rti = tichase(rti); - if (rti != nil) { if (rti.kind == tykind.TY_TUPLE) { + if (rti != nil) { if (rti.kind == syntax.tykind.TY_TUPLE) { let srcoff: i32 = rl.off; let foff: i32 = 0; - let lb: *node = n.list; + let lb: *syntax.node = n.list; for (lb != nil) { - let tn: *node = lb.lhs; + let tn: *syntax.node = lb.lhs; let isflt: bool = isfloattype(c, tn); let eslot: i32 = tupeslotn(tn); let esz: i32 = 8; - let eti: *tinfo = nil; - if (tn != nil) { eti = tn.type_: *tinfo; }; + let eti: *syntax.tinfo = nil; + if (tn != nil) { eti = tn.type_: *syntax.tinfo; }; if (eti != nil) { esz = eti.size: i32; }; let bsz: i32 = 8; if (eslot > 8) { bsz = eslot; }; @@ -3548,18 +3548,18 @@ fn cgmlet(c: *cgen, n: *node) void = { if (sretrecv > 0) { let scr: i32 = localfind(c, "@sretscr"); - let pt2: *node = nil; + let pt2: *syntax.node = nil; if (rettuple != nil) { pt2 = rettuple.list; }; let foff: i32 = 0; - let lb: *node = n.list; + let lb: *syntax.node = n.list; for (lb != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (pt2 != nil) { tn = pt2.lhs; }; let isflt: bool = isfloattype(c, tn); let eslot: i32 = tupeslotn(tn); let esz: i32 = 8; if (pt2 != nil) { - let eti: *tinfo = pt2.lhs.type_: *tinfo; + let eti: *syntax.tinfo = pt2.lhs.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; }; let bsz: i32 = 8; @@ -3607,11 +3607,11 @@ fn cgmlet(c: *cgen, n: *node) void = { let ssecap: i32 = TUPLE_SSECAP; // X0,X1 per SysV let gptotal: i32 = 0; let ssetotal: i32 = 0; - let l: *node = n.list; - let pt: *node = nil; + let l: *syntax.node = n.list; + let pt: *syntax.node = nil; if (rettuple != nil) { pt = rettuple.list; }; for (l != nil) { - let tn: *node = l.lhs; + let tn: *syntax.node = l.lhs; if (tn == nil) { if (pt != nil) { tn = pt.lhs; }; }; @@ -3642,7 +3642,7 @@ fn cgmlet(c: *cgen, n: *node) void = { pt = nil; if (rettuple != nil) { pt = rettuple.list; }; for (l != nil) { - let tn: *node = l.lhs; + let tn: *syntax.node = l.lhs; if (tn == nil) { if (pt != nil) { tn = pt.lhs; }; }; @@ -3668,19 +3668,19 @@ fn cgmlet(c: *cgen, n: *node) void = { // `tp->type->size` read in C cgen N_FORRANGE: 1 for i8/u8/bool, 4 for // i32/u32, 8 for i64/u64/*T/fn, 24 for str/slice (str IS []u8, the slice // header SSoT), tuple → sum of its 8B-floored element slots, default 8. -fn paramfieldsize(t: *node) i32 = { +fn paramfieldsize(t: *syntax.node) i32 = { if (t == nil) { return 8; }; - let k: nkind = t.kind; - if (k == nkind.N_TPTR) { return 8; }; - if (k == nkind.N_TFN) { return 8; }; - if (k == nkind.N_TCHAN) { return 8; }; + let k: syntax.nkind = t.kind; + if (k == syntax.nkind.N_TPTR) { return 8; }; + if (k == syntax.nkind.N_TFN) { return 8; }; + if (k == syntax.nkind.N_TCHAN) { return 8; }; // #43 (F7-c4): a slice tuple-field carries the 24B header (ptr+len+ // cap), not the 8B scalar default. Without this arm the for-range // destructure over `[N]([]T, U)` strode the tuple at 8 not 24 and // read field-2 at the wrong offset (cs=42/ww=8, the cat-A repro). // tyslicesize() is the slice-header SSoT (rule-13); cstage reads the // same width via tp->type->size (cmd/w6c/cgen.c N_FORRANGE). - if (k == nkind.N_TSLICE) { return tyslicesize(): i32; }; + if (k == syntax.nkind.N_TSLICE) { return tyslicesize(): i32; }; // #53: a tagged-union tuple-field carries its full box (tag + widest // payload, slot-padded), NOT the 8B scalar default — a for-range // destructure binding sized 8 loaded only the tag word (cs=56/ww=9, the @@ -3690,10 +3690,10 @@ fn paramfieldsize(t: *node) i32 = { // covers an N_TNAME field naming a tagged union (paramfieldsize's no-`c` // structural contract can't aliaslookup-chase the node). Mirrors the // N_TSLICE arm's type-table SSoT. - let tgi: *tinfo = t.type_: *tinfo; + let tgi: *syntax.tinfo = t.type_: *syntax.tinfo; if (tgi != nil) { tgi = tichase(tgi); - if (tgi != nil && tgi.kind == tykind.TY_TAGGED) { + if (tgi != nil && tgi.kind == syntax.tykind.TY_TAGGED) { return tgi.size: i32; }; }; @@ -3702,9 +3702,9 @@ fn paramfieldsize(t: *node) i32 = { // their 24B header), per the tuple-slot ruling and tupeslot's // roundup8. Recurse structurally so a tuple-of-tuple lands the same // stride cstage's tp->type->size computes. - if (k == nkind.N_TTUPLE) { + if (k == syntax.nkind.N_TTUPLE) { let total: i32 = 0; - let dp: *node = t.list; + let dp: *syntax.node = t.list; for (dp != nil) { let esz: i32 = paramfieldsize(dp.lhs); total = total + (esz + 7) / 8 * 8; @@ -3712,9 +3712,9 @@ fn paramfieldsize(t: *node) i32 = { }; return total; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; - if (streq(nm, "str")) { return primtypesize("str"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("str"): i32; }; // primsize-ok (#101/#109): paramfieldsize is a STRUCTURAL // (no-`c`, no-chase) sizer by design — it takes a *node, not a // *cgen, so it cannot run aliasprimsize's aliaslookup chase @@ -3740,7 +3740,7 @@ fn paramfieldsize(t: *node) i32 = { // paramissigned — does this type need sign-extending on a sub-word // (1/2/4B) load? Mirrors cstage's signed_field check via // fieldissignedc (resolves TBANG / TENUM / alias chains). -fn paramissigned(c: *cgen, t: *node) bool = { +fn paramissigned(c: *cgen, t: *syntax.node) bool = { return fieldissignedc(c, t); }; @@ -3751,22 +3751,22 @@ fn paramissigned(c: *cgen, t: *node) bool = { // either loads the whole element into the named local or pulls each // tuple field into its own local. Mirrors cmd/w6c/cgen.c N_FORRANGE // byte-for-byte (label names + labelseq consumption order). -fn cgforrange(c: *cgen, n: *node) void = { - let slc: *node = n.lhs; +fn cgforrange(c: *cgen, n: *syntax.node) void = { + let slc: *syntax.node = n.lhs; let slclocal: *local = nil; - let slctn: *node = nil; + let slctn: *syntax.node = nil; if (slc != nil) { - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { slclocal = localfindnode(c, slc.str); if (slclocal != nil) { slctn = slclocal.tnode; }; }; }; // Element type — peek through TSLICE/TARRAY for the tuple param walk. - let elemt: *node = nil; + let elemt: *syntax.node = nil; if (slctn != nil) { - let sk: nkind = slctn.kind; - if (sk == nkind.N_TSLICE) { elemt = slctn.lhs; }; - if (sk == nkind.N_TARRAY) { elemt = slctn.lhs; }; + let sk: syntax.nkind = slctn.kind; + if (sk == syntax.nkind.N_TSLICE) { elemt = slctn.lhs; }; + if (sk == syntax.nkind.N_TARRAY) { elemt = slctn.lhs; }; // str IS []u8 (F1: tystr.sub = tyu8). []u8 hands cgen a real // u8 element node (slctn.lhs); a str scrutinee has none, so the // loop var would register tnode=nil and read back as a wide @@ -3775,12 +3775,12 @@ fn cgforrange(c: *cgen, n: *node) void = { // read-back to MOVZBQ on its own — aligning wwstage up to // cstage, whose checker stamps the binding u8. Kind-gated so // str's own type stays nominal. - if (sk == nkind.N_TNAME) { - if (streq(slctn.str, "str")) { - let sti: *tinfo = slctn.type_: *tinfo; + if (sk == syntax.nkind.N_TNAME) { + if (syntax.streq(slctn.str, "str")) { + let sti: *syntax.tinfo = slctn.type_: *syntax.tinfo; if (sti != nil) { if (sti.sub != nil) { - let u8n: *node = newnode(nkind.N_TNAME, slctn.file, slctn.line, slctn.col); + let u8n: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, slctn.file, slctn.line, slctn.col); u8n.str = "u8"; u8n.type_ = sti.sub: *void; elemt = u8n; @@ -3797,18 +3797,18 @@ fn cgforrange(c: *cgen, n: *node) void = { // (slc->type) feeds esz/alen/base classify uniformly) and // synthesise the element node off .sub — the FC0 non-ident // precedent below. - let rti60: *tinfo = nil; + let rti60: *syntax.tinfo = nil; if (slctn != nil) { - if (slctn.kind == nkind.N_TNAME) { - let st60: *tinfo = slctn.type_: *tinfo; + if (slctn.kind == syntax.nkind.N_TNAME) { + let st60: *syntax.tinfo = slctn.type_: *syntax.tinfo; if (st60 != nil) { - if (st60.kind == tykind.TY_NAMED) { rti60 = tichase(st60); }; + if (st60.kind == syntax.tykind.TY_NAMED) { rti60 = tichase(st60); }; }; }; }; if (rti60 != nil && elemt == nil) { if (rti60.sub != nil) { - let en60: *node = newnode(nkind.N_TNAME, slctn.file, slctn.line, slctn.col); + let en60: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, slctn.file, slctn.line, slctn.col); en60.str = rti60.sub.name; en60.type_ = rti60.sub: *void; elemt = en60; @@ -3828,13 +3828,13 @@ fn cgforrange(c: *cgen, n: *node) void = { // #60: alias-NAMED scrutinee — stride off the chased stamped // element (cstage esz = u->sub->size). if (rti60 != nil) { - let es60: *tinfo = tichase(rti60.sub); + let es60: *syntax.tinfo = tichase(rti60.sub); if (es60 != nil) { esz = es60.size: i32; }; }; if (elemt != nil) { - if (elemt.kind == nkind.N_TTUPLE) { + if (elemt.kind == syntax.nkind.N_TTUPLE) { let total: i32 = 0; - let p: *node = elemt.list; + let p: *syntax.node = elemt.list; for (p != nil) { total += paramfieldsize(p.lhs); p = p.next; @@ -3851,15 +3851,15 @@ fn cgforrange(c: *cgen, n: *node) void = { // str/slice/float keys read it like a declared local (the str→u8 // synthesis precedent above). if (slctn == nil && slc != nil) { - let sti2: *tinfo = slc.type_: *tinfo; + let sti2: *syntax.tinfo = slc.type_: *syntax.tinfo; sti2 = tichase(sti2); if (sti2 != nil) { - if (sti2.kind == tykind.TY_SLICE - || sti2.kind == tykind.TY_STR - || sti2.kind == tykind.TY_ARRAY) { + if (sti2.kind == syntax.tykind.TY_SLICE + || sti2.kind == syntax.tykind.TY_STR + || sti2.kind == syntax.tykind.TY_ARRAY) { if (sti2.sub != nil) { esz = sti2.sub.size: i32; - let en: *node = newnode(nkind.N_TNAME, slc.file, slc.line, slc.col); + let en: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, slc.file, slc.line, slc.col); en.str = sti2.sub.name; en.type_ = sti2.sub: *void; elemt = en; @@ -3886,12 +3886,12 @@ fn cgforrange(c: *cgen, n: *node) void = { let loff: i32 = localalloc(c, lname, 8, nil); let baseoff: i32 = 0; if (slc != nil) { - if (slc.kind != nkind.N_IDENT) { - let stu70: *tinfo = slc.type_: *tinfo; + if (slc.kind != syntax.nkind.N_IDENT) { + let stu70: *syntax.tinfo = slc.type_: *syntax.tinfo; stu70 = tichase(stu70); let arr70: bool = false; if (stu70 != nil) { - if (stu70.kind == tykind.TY_ARRAY) { + if (stu70.kind == syntax.tykind.TY_ARRAY) { arr70 = true; }; }; @@ -3904,8 +3904,8 @@ fn cgforrange(c: *cgen, n: *node) void = { // the AX/BX/CX header convention the spill assumes // (the deref-spine load family) — keep it LOUD until // #11 wires the deref load. - if (slc.kind == nkind.N_UN) { - if (slc.op == tkind.TK_STAR) { + if (slc.kind == syntax.nkind.N_UN) { + if (slc.op == syntax.tkind.TK_STAR) { let m11: str = "for-range over a deref base unwired (#11)\n"; os.write(2, m11.ptr, m11.len: u64); os.exit(1); @@ -3924,13 +3924,13 @@ fn cgforrange(c: *cgen, n: *node) void = { // into the for-range spine) is a DISTINCT mechanism — filed as a #121 // sibling, off fold-6's path. if (slc != nil) { - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { if (localfindnode(c, slc.str) == nil) { let isglob: bool = isletvar(c, slc.str); if (!isglob) { - let gdtn: *node = defvartnode(c, slc.str); + let gdtn: *syntax.node = defvartnode(c, slc.str); if (gdtn != nil) { - if (gdtn.kind == nkind.N_TARRAY) { isglob = true; }; + if (gdtn.kind == syntax.nkind.N_TARRAY) { isglob = true; }; }; }; if (isglob) { @@ -3951,12 +3951,12 @@ fn cgforrange(c: *cgen, n: *node) void = { let nbinds: i32 = 0; if (destruct) { - let tp: *node = nil; + let tp: *syntax.node = nil; if (elemt != nil) { - if (elemt.kind == nkind.N_TTUPLE) { tp = elemt.list; }; + if (elemt.kind == syntax.nkind.N_TTUPLE) { tp = elemt.list; }; }; let field_off: i32 = 0; - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { if (nbinds >= 8) { m = nil; } else { @@ -3964,7 +3964,7 @@ fn cgforrange(c: *cgen, n: *node) void = { let signf: bool = false; // tp walks the N_TPARAM wrapper chain; tpt is the // actual element type AST. - let tpt: *node = nil; + let tpt: *syntax.node = nil; if (tp != nil) { tpt = tp.lhs; }; if (tpt != nil) { fsz = paramfieldsize(tpt); @@ -4018,22 +4018,22 @@ fn cgforrange(c: *cgen, n: *node) void = { let isarr: bool = false; let isslicestr: bool = false; if (slctn != nil) { - let tk: nkind = slctn.kind; - if (tk == nkind.N_TSLICE) { isslicestr = true; }; - if (tk == nkind.N_TARRAY) { isarr = true; }; - if (tk == nkind.N_TNAME) { - if (streq(slctn.str, "str")) { isslicestr = true; }; + let tk: syntax.nkind = slctn.kind; + if (tk == syntax.nkind.N_TSLICE) { isslicestr = true; }; + if (tk == syntax.nkind.N_TARRAY) { isarr = true; }; + if (tk == syntax.nkind.N_TNAME) { + if (syntax.streq(slctn.str, "str")) { isslicestr = true; }; }; }; // #60: alias-NAMED scrutinee — classify off the chased stamped // kind (cstage gates on u->kind TY_SLICE/TY_STR vs TY_ARRAY). if (rti60 != nil) { - if (rti60.kind == tykind.TY_ARRAY) { isarr = true; }; - if (rti60.kind == tykind.TY_SLICE) { isslicestr = true; }; - if (rti60.kind == tykind.TY_STR) { isslicestr = true; }; + if (rti60.kind == syntax.tykind.TY_ARRAY) { isarr = true; }; + if (rti60.kind == syntax.tykind.TY_SLICE) { isslicestr = true; }; + if (rti60.kind == syntax.tykind.TY_STR) { isslicestr = true; }; }; if (isslicestr) { - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { if (slclocal != nil) { emitline("\tMOVQ\t"); emitoff((slclocal.off + 8): i64); @@ -4046,7 +4046,7 @@ fn cgforrange(c: *cgen, n: *node) void = { } else { if (isarr) { let alen: i64 = 0i64; if (slctn.rhs != nil) { - if (slctn.rhs.kind == nkind.N_INTLIT) { alen = slctn.rhs.uval: i64; }; + if (slctn.rhs.kind == syntax.nkind.N_INTLIT) { alen = slctn.rhs.uval: i64; }; }; // #60: alias-NAMED scrutinee has no length tnode — bound off // the chased tinfo (cstage aimm(u->alen)). @@ -4115,7 +4115,7 @@ fn cgforrange(c: *cgen, n: *node) void = { emitline(", CX\n"); emitline("\tIMULQ\tCX, AX\n"); }; - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { if (slclocal != nil) { if (isarr) { emitline("\tLEAQ\t"); @@ -4272,7 +4272,7 @@ fn cgforrange(c: *cgen, n: *node) void = { // default and runs after all named arms fail. Mirrors cmd/w6c/cgen.c // N_SWITCH: same labelseq consumption order so labels match byte-for- // byte. -fn cgswitch(c: *cgen, n: *node) void = { +fn cgswitch(c: *cgen, n: *syntax.node) void = { let swname: str = mkscratchname(c, "sw"); let sloff: i32 = localalloc(c, swname, 8, nil); @@ -4282,9 +4282,9 @@ fn cgswitch(c: *cgen, n: *node) void = { emitline("(BP)\n"); let endl: str = mklabel(c, "swend"); - let defcase: *node = nil; + let defcase: *syntax.node = nil; - let cs: *node = n.list; + let cs: *syntax.node = n.list; for (cs != nil) { if (cs.list == nil) { defcase = cs; @@ -4293,7 +4293,7 @@ fn cgswitch(c: *cgen, n: *node) void = { }; let body: str = mklabel(c, "swcase"); let nxt: str = mklabel(c, "swnext"); - let e: *node = cs.list; + let e: *syntax.node = cs.list; for (e != nil) { cgexpr(c, e); emitline("\tMOVQ\t"); @@ -4324,7 +4324,7 @@ fn cgswitch(c: *cgen, n: *node) void = { return; }; -fn cgbreak(c: *cgen, n: *node) void = { +fn cgbreak(c: *cgen, n: *syntax.node) void = { if (c.looptop > 0) { let lbl: str = c.loopendbuf[c.looptop - 1]; emitline("\tJMP\t"); emitline(lbl); emitline("\n"); @@ -4333,7 +4333,7 @@ fn cgbreak(c: *cgen, n: *node) void = { return; }; -fn cgcontinue(c: *cgen, n: *node) void = { +fn cgcontinue(c: *cgen, n: *syntax.node) void = { if (c.looptop > 0) { let lbl: str = c.loopcontbuf[c.looptop - 1]; emitline("\tJMP\t"); emitline(lbl); emitline("\n"); diff --git a/selfhost/cmd/wcc/cgenutil.ww b/selfhost/cmd/wcc/cgenutil.ww index efb5cb7e..3cc6555b 100644 --- a/selfhost/cmd/wcc/cgenutil.ww +++ b/selfhost/cmd/wcc/cgenutil.ww @@ -25,8 +25,8 @@ import strconv; // for the param (callee side) and the call-site slice descriptor // (caller side) both advertise their effective type as []ELEM — // every isslicetype / nodeisslice check then succeeds naturally. -fn slicewrap(c: *cgen, elem: *node) *node = { - let s: *node = newnode(nkind.N_TSLICE, "", 0, 0); +fn slicewrap(c: *cgen, elem: *syntax.node) *syntax.node = { + let s: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); s.lhs = elem; return s; }; @@ -35,12 +35,12 @@ fn slicewrap(c: *cgen, elem: *node) *node = { // param node (the one with op == TK_ELLIPSIS) plus the count of // non-variadic params before it. Returns nil/0 when no variadic. // nfixed_out cannot be nil. -fn findvariadicparam(ps: *node, nfixed_out: *i32) *node = { +fn findvariadicparam(ps: *syntax.node, nfixed_out: *i32) *syntax.node = { *nfixed_out = 0; - let p: *node = ps; + let p: *syntax.node = ps; for (p != nil) { - if (p.kind == nkind.N_PARAM) { - if (p.op == tkind.TK_ELLIPSIS) { + if (p.kind == syntax.nkind.N_PARAM) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { return p; }; *nfixed_out += 1; @@ -62,19 +62,19 @@ fn findvariadicparam(ps: *node, nfixed_out: *i32) *node = { // strings.contains gained a variadic shape and a caller's // bytes.contains call site picked strings.contains' variadic // params for arg-prep while emitting CALL bytes.contains. -fn callee_variadic_param(c: *cgen, callee: *node, nfixed_out: *i32) *node = { +fn callee_variadic_param(c: *cgen, callee: *syntax.node, nfixed_out: *i32) *syntax.node = { *nfixed_out = 0; if (callee == nil) { return nil; }; - let ps: *node = nil; - if (callee.kind == nkind.N_IDENT) { + let ps: *syntax.node = nil; + if (callee.kind == syntax.nkind.N_IDENT) { if (callee.str.len == 0) { return nil; }; ps = fnparamslookup(c, callee.str); - } else { if (callee.kind == nkind.N_DOT) { + } else { if (callee.kind == syntax.nkind.N_DOT) { if (callee.str.len == 0) { return nil; }; let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; @@ -116,21 +116,21 @@ fn callee_variadic_param(c: *cgen, callee: *node, nfixed_out: *i32) *node = { // payload word) or the float-source box was misclassified as a float arg // (#48: MOVSD ate the tag word into X0). Mirrors cstage's precomputed // widen[i]/widen_sz[i] (cmd/w6c/cgen.c cgcall). -fn argtaggedwidensz(c: *cgen, arg0: *node, param: *node) i32 = { +fn argtaggedwidensz(c: *cgen, arg0: *syntax.node, param: *syntax.node) i32 = { if (param == nil) { return 0; }; - if (param.kind != nkind.N_PARAM) { return 0; }; - if (param.op == tkind.TK_ELLIPSIS) { return 0; }; - let ptype: *node = param.lhs; + if (param.kind != syntax.nkind.N_PARAM) { return 0; }; + if (param.op == syntax.tkind.TK_ELLIPSIS) { return 0; }; + let ptype: *syntax.node = param.lhs; if (ptype == nil) { return 0; }; if (!istaggedtype(c, ptype)) { return 0; }; // >48B slot is memory-class: pushargsrev stages it below the register // words and the drain skips it (dmemsz) — never a register widen. - if (taggedmemargsize(ptype.type_: *tinfo) > 0) { return 0; }; - let arg: *node = taggedcastpeel(c, arg0); + if (taggedmemargsize(ptype.type_: *syntax.tinfo) > 0) { return 0; }; + let arg: *syntax.node = taggedcastpeel(c, arg0); let pslot: i32 = slotsize(c, ptype); // Already a matching-slot tagged source → natural push, no widen // (mirrors pushargsrev's aistagged gates: ident/call/index/dot/deref). - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, arg.str); if (lc != nil) { if (istaggedtype(c, lc.tnode)) { @@ -139,13 +139,13 @@ fn argtaggedwidensz(c: *cgen, arg0: *node, param: *node) i32 = { }; }; if (taggedcallslot(c, arg) == pslot) { return 0; }; - if (arg.kind == nkind.N_INDEX) { + if (arg.kind == syntax.nkind.N_INDEX) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == pslot) { return 0; }; }; }; - if (arg.kind == nkind.N_DOT) { + if (arg.kind == syntax.nkind.N_DOT) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == pslot) { return 0; }; }; }; - if (arg.kind == nkind.N_UN && arg.op == tkind.TK_STAR) { + if (arg.kind == syntax.nkind.N_UN && arg.op == syntax.tkind.TK_STAR) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == pslot) { return 0; }; }; }; // The 8B nullable fold pushes one pointer word the scalar drain path @@ -155,9 +155,9 @@ fn argtaggedwidensz(c: *cgen, arg0: *node, param: *node) i32 = { return pslot; }; -fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { +fn pushargsrev(c: *cgen, arg: *syntax.node, param: *syntax.node, memphase: bool) i32 = { if (arg == nil) { return 0; }; - let nextparam: *node = nil; + let nextparam: *syntax.node = nil; if (param != nil) { nextparam = param.next; }; let rest: i32 = pushargsrev(c, arg.next, nextparam, memphase); // Family C (#35): peel tagged→tagged casts FIRST so every gate @@ -173,33 +173,33 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // type (so widening into a >48B slot is caught), else the arg's // own stamped type (fn-ptr callee carries no param nodes). let memsz: i32 = 0; - let memptype: *node = nil; - if (param != nil) { if (param.kind == nkind.N_PARAM) { - if (param.op != tkind.TK_ELLIPSIS) { + let memptype: *syntax.node = nil; + if (param != nil) { if (param.kind == syntax.nkind.N_PARAM) { + if (param.op != syntax.tkind.TK_ELLIPSIS) { memptype = param.lhs; if (memptype != nil) { - memsz = taggedmemargsize(memptype.type_: *tinfo); + memsz = taggedmemargsize(memptype.type_: *syntax.tinfo); }; }; }; }; if (memsz == 0) { - memsz = taggedmemargsize(arg.type_: *tinfo); + memsz = taggedmemargsize(arg.type_: *syntax.tinfo); }; if (memphase != (memsz > 0)) { return rest; }; if (memsz > 0) { // same-type check — mirror cstage's `(pu == au) || // type_eq(p->type, at)` widen detection. let same: bool = false; - let at: *tinfo = arg.type_: *tinfo; + let at: *syntax.tinfo = arg.type_: *syntax.tinfo; if (memptype != nil) { - let pt: *tinfo = memptype.type_: *tinfo; - let pu: *tinfo = pt; + let pt: *syntax.tinfo = memptype.type_: *syntax.tinfo; + let pu: *syntax.tinfo = pt; pu = tichase(pu); - let au: *tinfo = at; + let au: *syntax.tinfo = at; au = tichase(au); if (pu != nil && pu == au) { same = true; }; if (!same && pt != nil && at != nil) { - if (typeeq(pt, at)) { same = true; }; + if (syntax.typeeq(pt, at)) { same = true; }; }; } else { same = true; @@ -219,7 +219,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, memptype.type_: *tinfo, arg, + cgwidentaggedstore(c, memptype.type_: *syntax.tinfo, arg, "BP", scroff, memsz); let pp: i32 = memsz - 8; for (pp >= 0) { @@ -238,12 +238,12 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // return) — its result is in memory behind a dest pointer, // not a register cursor; receive-then-push is the // #40-family follow-up. - if (arg.kind == nkind.N_CALL) { + if (arg.kind == syntax.nkind.N_CALL) { let mc: str = "#38b: sret-class tagged call result as a >48B by-value arg unwired (#40-family follow-up)\n"; os.write(2, mc.ptr, mc.len: u64); os.exit(1); }; - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, arg.str); if (lc != nil) { let w: i32 = memsz / 8 - 1; @@ -294,20 +294,20 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { let widensz: i32 = 0; let widentag: i32 = 0; if (param != nil) { - if (param.kind == nkind.N_PARAM) { + if (param.kind == syntax.nkind.N_PARAM) { // Hare-style variadic `T...`: effective param type is // []T (slice). The arg here is the synthesised slice // descriptor (or a forwarded `xs...` slice), not a // value of T being widened into a tagged slot — skip // the widening detection so the slice-ident fast path // at the bottom of pushargsrev gets the push. - if (param.op == tkind.TK_ELLIPSIS) { + if (param.op == syntax.tkind.TK_ELLIPSIS) { widensz = 0; } else { - let ptype: *node = param.lhs; + let ptype: *syntax.node = param.lhs; if (istaggedtype(c, ptype)) { let aistagged: bool = false; - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, arg.str); if (lc != nil) { // #55: only treat a tagged ident as @@ -351,7 +351,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // slotsize read .type_, so feed the N_INDEX node // directly. cstage reads the element via // base->type->sub (cmd/w6c/cgen.c:3518). - if (arg.kind == nkind.N_INDEX) { + if (arg.kind == syntax.nkind.N_INDEX) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == slotsize(c, ptype)) { aistagged = true; @@ -367,7 +367,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // twin of the N_INDEX arm above; cstage // needs no kind gate (its widen[i] `same` // check is type-keyed on args[i]->type). - if (arg.kind == nkind.N_DOT) { + if (arg.kind == syntax.nkind.N_DOT) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == slotsize(c, ptype)) { aistagged = true; @@ -380,7 +380,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // scalar branch boxed the box. Same // slotsize key as the N_INDEX/N_DOT // stamped-carrier arms above. - if (arg.kind == nkind.N_UN && arg.op == tkind.TK_STAR) { + if (arg.kind == syntax.nkind.N_UN && arg.op == syntax.tkind.TK_STAR) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == slotsize(c, ptype)) { aistagged = true; @@ -389,7 +389,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { }; if (!aistagged) { widensz = slotsize(c, ptype); - let tagged: *node = resolvetagged(c, ptype); + let tagged: *syntax.node = resolvetagged(c, ptype); let t: i32 = taggedvariantindex(c, tagged, arg); if (t < 0) { t = 0; }; widentag = t; @@ -417,7 +417,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // the scratch store, whose #242/#66 tuple arm handles the // literal/cast forms and loud-stops the rest (#72). Mirrors // cstage cg_widen_tagged_push src_is_tuple. - let argtup: *tinfo = arg.type_: *tinfo; + let argtup: *syntax.tinfo = arg.type_: *syntax.tinfo; argtup = tichase(argtup); let argistuple: bool = false; // #55: a tagged SOURCE widened into a wider/reordered tagged param @@ -431,16 +431,16 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // routing (cmd/w6c/cgen.c:2982). let argistagged: bool = false; if (argtup != nil) { - if (argtup.kind == tykind.TY_TUPLE) { + if (argtup.kind == syntax.tykind.TY_TUPLE) { argistuple = true; }; - if (argtup.kind == tykind.TY_TAGGED) { + if (argtup.kind == syntax.tykind.TY_TAGGED) { argistagged = true; }; }; let pname: str = rhsstructpayload(c, arg); if (pname.len > 0 || argistuple || argistagged) { - let ptype: *node = param.lhs; + let ptype: *syntax.node = param.lhs; let scroff: i32 = tagscradd(c, widensz); emitline("\tXORQ\tAX, AX\n"); let zz: i32 = 0; @@ -450,7 +450,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, ptype.type_: *tinfo, arg, "BP", scroff, widensz); + cgwidentaggedstore(c, ptype.type_: *syntax.tinfo, arg, "BP", scroff, widensz); let pp: i32 = widensz - 8; for (pp >= 0) { emitline("\tMOVQ\t"); @@ -526,20 +526,20 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // nkind.N_SLICE expression as arg: `buf[lo:hi]` builds a slice header // on the stack matching C cgen's sequence — push base, push hi, // compute lo, pop into BX/CX, derive len/ptr, push (cap, len, ptr). - if (arg.kind == nkind.N_SLICE) { - let base: *node = arg.lhs; - let lo: *node = arg.rhs; - let hi: *node = arg.cond; + if (arg.kind == syntax.nkind.N_SLICE) { + let base: *syntax.node = arg.lhs; + let lo: *syntax.node = arg.rhs; + let hi: *syntax.node = arg.cond; let baselocal: *local = nil; - let globaltn: *node = nil; + let globaltn: *syntax.node = nil; let globalname: str; globalname.ptr = nil; globalname.len = 0; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal == nil) { - let gt: *node = letvartnode(c, bn); + let gt: *syntax.node = letvartnode(c, bn); if (gt != nil) { globaltn = gt; globalname = bn; @@ -552,9 +552,9 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // checker-stamped element tinfo on base.type_ instead. Cstage // twin reads base->type (cgen.c pushargs N_SLICE esz). Mirror // of the cgslice #252 site. - let dotbu: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_DOT) { - dotbu = base.type_: *tinfo; + let dotbu: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_DOT) { + dotbu = base.type_: *syntax.tinfo; dotbu = tichase(dotbu); };}; // #60 (alias arc #5): alias-NAMED N_IDENT base — the tnode @@ -563,10 +563,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // pusharg twin of the cgslice fix (cstage pushargs N_SLICE // reads bu = type_chase_named(base->type) uniformly). let basealias: bool = false; - let bu60: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; - if (bt60 != nil) { if (bt60.kind == tykind.TY_NAMED) { + let bu60: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt60 != nil) { if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; bu60 = tichase(bt60); };}; @@ -586,18 +586,18 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { esz = dotbu.sub.size: i32; };};}; if (bu60 != nil) { - let es60: *tinfo = tichase(bu60.sub); + let es60: *syntax.tinfo = tichase(bu60.sub); if (es60 != nil) { esz = es60.size: i32; }; }; // base address → push if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarr60: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { isarr60 = true; }; + if (tn.kind == syntax.nkind.N_TARRAY) { isarr60 = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). - if (bu60 != nil) { isarr60 = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { isarr60 = bu60.kind == syntax.tykind.TY_ARRAY; }; if (isarr60) { emitline("\tLEAQ\t"); emitoff(baselocal.off: i64); @@ -608,10 +608,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("(BP), AX\n"); }; } else { if (globaltn != nil) { - let gisarr60: bool = globaltn.kind == nkind.N_TARRAY; + let gisarr60: bool = globaltn.kind == syntax.nkind.N_TARRAY; // #60: alias-NAMED base — chased kind; runtime- // unreachable until #77/#78 global DATA. - if (bu60 != nil) { gisarr60 = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { gisarr60 = bu60.kind == syntax.tykind.TY_ARRAY; }; if (gisarr60) { emitline("\tLEAQ\t"); emitsymname(c, globalname); @@ -634,11 +634,11 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { if (hi != nil) { cgexpr(c, hi); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { - let lenn: *node = tn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (tn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = tn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -649,19 +649,19 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // N_TNAME); a plain `[MAX]u8` base reaches here // with a non-N_INTLIT dim and dropped the // default-hi entirely. cstage reads bu->alen. - let abt: *tinfo = tichase(tn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(tn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); }; }; - } else { if (tn.kind == nkind.N_TSLICE) { + } else { if (tn.kind == syntax.nkind.N_TSLICE) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); - } else { if (tn.kind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { + } else { if (tn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); @@ -671,21 +671,21 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // #60: alias-NAMED base default-hi — chased kind // (see the cgslice twin). if (bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); };}; }; } else { if (globaltn != nil) { - if (globaltn.kind == nkind.N_TARRAY) { - let lenn: *node = globaltn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (globaltn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = globaltn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -693,20 +693,20 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // #56: def/const dim on a global array base — // resolve from the stamped array tinfo (rule-13), // twin of the local arg-push arm above. - let abt: *tinfo = tichase(globaltn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(globaltn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); }; }; - } else { if (globaltn.kind == nkind.N_TSLICE) { + } else { if (globaltn.kind == syntax.nkind.N_TSLICE) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); emitline("\tMOVQ\t8(CX), AX\n"); - } else { if (globaltn.kind == nkind.N_TNAME) { - if (streq(globaltn.str, "str")) { + } else { if (globaltn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(globaltn.str, "str")) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -716,12 +716,12 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // #60: alias-NAMED global base default-hi — chased // kind; runtime-unreachable until #77/#78 global DATA. if (bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -767,7 +767,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // into argregs lands the canonical (ptr/tag, len/v0, cap/v1). // For tagged ident with a >24B slot (slice-payload variant), // push a fourth word from off+24. - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let nm: str = arg.str; let lc: *local = localfindnode(c, nm); if (lc != nil) { @@ -827,9 +827,9 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // from dotchainaddr). The slot-word count is the stamped tinfo // size (the type table, byte-id with cstage struct_arg_size). if (lc == nil) { - let gst: *tinfo = arg.type_: *tinfo; + let gst: *syntax.tinfo = arg.type_: *syntax.tinfo; gst = tichase(gst); - if (gst != nil) { if (gst.kind == tykind.TY_STRUCT) { + if (gst != nil) { if (gst.kind == syntax.tykind.TY_STRUCT) { let gsz: i32 = gst.size: i32; if (gsz > 0 && gsz <= 16 && (isletvar(c, nm) || deflookup(c, nm))) { @@ -866,7 +866,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // would LEAQ an undefined main.(SB) (w6l fails); a // def must fall through to the const-fold path instead. if (gst != nil && isletvar(c, nm)) { - if (gst.kind == tykind.TY_SLICE) { + if (gst.kind == syntax.tykind.TY_SLICE) { emitline("\tLEAQ\t"); emitsymname(c, nm); emitline("(SB), BX\n"); @@ -878,7 +878,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("\tPUSHQ\tAX\n"); return rest + 3; }; - if (gst.kind == tykind.TY_STR) { + if (gst.kind == syntax.tykind.TY_STR) { emitline("\tLEAQ\t"); emitsymname(c, nm); emitline("(SB), CX\n"); @@ -903,7 +903,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // >24B sret'd into @aggargscr then pushed from there. Pre-fix every // such source fell to the scalar default (one PUSHQ for a multi-word // aggregate) and stack-imbalanced against the type-based drain. - let aggsz: i32 = aggargsizetn(arg.type_: *tinfo); + let aggsz: i32 = aggargsizetn(arg.type_: *syntax.tinfo); if (aggsz > 0) { // Exclude a ≤16B-struct IDENT — it owns the structparamsize // fast path above (or, when a cross-module same-leaf collision @@ -914,10 +914,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // args[i]->type) — a name-keyed gate here re-opens the #211/#13 // name-keyed divergence the cstage type gate doesn't have. let structident: bool = false; - if (arg.kind == nkind.N_IDENT) { - let st: *tinfo = arg.type_: *tinfo; + if (arg.kind == syntax.nkind.N_IDENT) { + let st: *syntax.tinfo = arg.type_: *syntax.tinfo; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { if (st.size: i32 <= 16) { structident = true; }; }; }; }; @@ -928,7 +928,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { os.exit(1); }; let nwords: i32 = (aggsz + 7) / 8; - if (arg.kind == nkind.N_CALL) { + if (arg.kind == syntax.nkind.N_CALL) { if (callsretsize(c, arg) > 0) { let scr: i32 = localadd(c, "@aggargscr", aggsz, nil); @@ -984,9 +984,9 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // the MOVSS load on the pop side touches only the low 4. let fk: i32 = 0; if (arg != nil) { - let at: *tinfo = arg.type_: *tinfo; - if (typeisf32(at)) { fk = 1; } - else { if (typeisfloat(at)) { fk = 2; }; }; + let at: *syntax.tinfo = arg.type_: *syntax.tinfo; + if (syntax.typeisf32(at)) { fk = 1; } + else { if (syntax.typeisfloat(at)) { fk = 2; }; }; }; if (fk != 0) { cgexpr(c, arg); @@ -1004,14 +1004,14 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // the box cursor; the restage + push then key on the param tuple type // node (declared element widths), not the literal's element- // constructed types. Mirrors cstage cgcall paramtup. - let paramtt: *node = nil; - if (arg.kind == nkind.N_TUPLE) { if (param != nil) { - if (param.kind == nkind.N_PARAM && param.lhs != nil) { - let ptn: *node = param.lhs; - for (ptn != nil && ptn.kind == nkind.N_TNAME) { + let paramtt: *syntax.node = nil; + if (arg.kind == syntax.nkind.N_TUPLE) { if (param != nil) { + if (param.kind == syntax.nkind.N_PARAM && param.lhs != nil) { + let ptn: *syntax.node = param.lhs; + for (ptn != nil && ptn.kind == syntax.nkind.N_TNAME) { ptn = aliaslookup(c, ptn.str); }; - if (ptn != nil) { if (ptn.kind == nkind.N_TTUPLE) { paramtt = ptn; }; }; + if (ptn != nil) { if (ptn.kind == syntax.nkind.N_TTUPLE) { paramtt = ptn; }; }; }; }; }; if (paramtt != nil) { cgtuplelittocursor(c, arg, paramtt); } @@ -1027,17 +1027,17 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // arg-class regs. When the PARAM tuple type is known (#68), walk its // declared element type nodes (p.lhs); else an N_TUPLE literal's // elements are VALUE exprs classified the way cgtuplelittocursor does. - let tuparg: *node = paramtt; + let tuparg: *syntax.node = paramtt; if (tuparg == nil) { tuparg = nodetuplearg(c, arg); }; if (tuparg != nil) { let tuplit: bool = false; - if (paramtt == nil) { if (tuparg.kind == nkind.N_TUPLE) { tuplit = true; }; }; + if (paramtt == nil) { if (tuparg.kind == syntax.nkind.N_TUPLE) { tuplit = true; }; }; let gptot: i32 = 0; let sstot: i32 = 0; let tsz: i32 = 0; - let p: *node = tuparg.list; + let p: *syntax.node = tuparg.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (tuplit) { et = p; }; // C-t2 (ken demand 1, rule 7): a COMPOSITE element // (nested tuple/struct/array/tagged) occupies more @@ -1047,19 +1047,19 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // skewed). The stamped tinfo classifies both type // nodes and literal value exprs. Mirrors the cstage // restage guard. - let eti: *tinfo = et.type_: *tinfo; + let eti: *syntax.tinfo = et.type_: *syntax.tinfo; eti = tichase(eti); if (eti != nil) { - let bad: bool = eti.kind == tykind.TY_TUPLE - || eti.kind == tykind.TY_STRUCT - || eti.kind == tykind.TY_ARRAY; + let bad: bool = eti.kind == syntax.tykind.TY_TUPLE + || eti.kind == syntax.tykind.TY_STRUCT + || eti.kind == syntax.tykind.TY_ARRAY; // #68: a declared-tagged element graduates to a real // widen — the decl-aware send (cgtuplelittocursor over // the param tuple type) left the box words in the // cursor, so tupstore below carries them. A tagged // element with no param decl stays rule-7 loud (the // cursor was filled stamped-keyed). - if (eti.kind == tykind.TY_TAGGED && paramtt == nil) { bad = true; }; + if (eti.kind == syntax.tykind.TY_TAGGED && paramtt == nil) { bad = true; }; if (bad) { let mne: str = "#32: tuple arg element kind unsupported (nested tuple/struct/array/tagged; rule 7)\n"; os.write(2, mne.ptr, mne.len: u64); @@ -1096,7 +1096,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { let eoff: i32 = 0; p = tuparg.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (tuplit) { et = p; }; let eslot: i32 = 8; if (tuplit) { @@ -1127,10 +1127,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // single-PUSHQ default and silently skewed every later arg // register. Mirrors the cstage cgcall guard. { - let ati: *tinfo = arg.type_: *tinfo; + let ati: *syntax.tinfo = arg.type_: *syntax.tinfo; ati = tichase(ati); if (ati != nil) { - if (ati.kind == tykind.TY_TUPLE) { + if (ati.kind == syntax.tykind.TY_TUPLE) { let m32: str = "#32: tuple arg from unsupported source shape (call/ident/literal/unwrap only; rule 7)\n"; os.write(2, m32.ptr, m32.len: u64); os.exit(1); @@ -1185,8 +1185,8 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // keeps the stamped-carrier kind gate (#67 pattern) — the // remaining kinds (deref/cast/unwrap) are word0-only reads today, // filed residual. - if (arg.kind == nkind.N_INDEX || arg.kind == nkind.N_DOT - || (arg.kind == nkind.N_UN && arg.op == tkind.TK_STAR)) { + if (arg.kind == syntax.nkind.N_INDEX || arg.kind == syntax.nkind.N_DOT + || (arg.kind == syntax.nkind.N_UN && arg.op == syntax.tkind.TK_STAR)) { if (istaggedtype(c, arg)) { let isz: i32 = slotsize(c, arg); // #35 (Family C): a mem-based read left the box @@ -1223,21 +1223,21 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // route a tagged-return call result through the AX/DX/CX/R8 high→low // push convention rather than the concrete-variant widening path // (which drops DX/CX/R8). See task #21. -export fn taggedcallslot(c: *cgen, n: *node) i32 = { +export fn taggedcallslot(c: *cgen, n: *syntax.node) i32 = { if (n == nil) { return 0; }; - if (n.kind != nkind.N_CALL) { return 0; }; - let callee: *node = n.lhs; + if (n.kind != syntax.nkind.N_CALL) { return 0; }; + let callee: *syntax.node = n.lhs; if (callee == nil) { return 0; }; - if (callee.kind != nkind.N_IDENT) { return 0; }; - let rtyp: *node = fnretlookup(c, callee.str); + if (callee.kind != syntax.nkind.N_IDENT) { return 0; }; + let rtyp: *syntax.node = fnretlookup(c, callee.str); if (!istaggedtype(c, rtyp)) { return 0; }; return slotsize(c, rtyp); }; -fn nodeisslice(c: *cgen, n: *node) bool = { +fn nodeisslice(c: *cgen, n: *syntax.node) bool = { if (n == nil) { return false; }; - let k: nkind = n.kind; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_IDENT) { let nm: str = n.str; let lc: *local = localfindnode(c, nm); // F7-c1: the local read collapses onto the checker-stamped @@ -1248,7 +1248,7 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // decl localfindnode keys on); the localfindnode gate stays to // keep the global-var-not-def case routing to false (out of F7 // scope), so this is a zero-delta mechanic validation. - if (lc != nil) { return typeisslice(n.type_: *tinfo); }; + if (lc != nil) { return syntax.typeisslice(n.type_: *syntax.tinfo); }; // #21: a module-level `def g: []T` ident is not a frame // slot (localfindnode→nil), so the local arm above misses // it and it would fall to the scalar single-PUSHQ default, @@ -1260,12 +1260,12 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // const-fold, so the push site and cgcall's pop sizer flip // together on this shared recognizer (load-bearing). if (deflookup(c, nm)) { - return typeisslice(n.type_: *tinfo); + return syntax.typeisslice(n.type_: *syntax.tinfo); }; return false; }; - if (k == nkind.N_SLICE) { return true; }; - if (k == nkind.N_CAST) { return isslicetype(c, n.rhs); }; + if (k == syntax.nkind.N_SLICE) { return true; }; + if (k == syntax.nkind.N_CAST) { return isslicetype(c, n.rhs); }; // #24: N_CALL returning a slice — cgexpr leaves (AX=ptr, // BX=len, CX=cap); pushargsrev's slice arm pushes CX/BX/AX // and cgcall pops 3 words. Without this arm the natural-push @@ -1277,22 +1277,22 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // doesn't shadow the explicit `mod.f()` qualifier — surfaced by // strings.slice returning `frombytes(utf8.slice(...))` // where strings.slice itself returns str. - if (k == nkind.N_CALL) { - let callee: *node = n.lhs; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = n.lhs; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { - let rtyp: *node = fnretlookupmod(c, callee.str, c.curmod); + if (callee.kind == syntax.nkind.N_IDENT) { + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, c.curmod); return isslicetype(c, rtyp); }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; - let rtyp: *node = fnretlookupmod(c, callee.str, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, cmod); return isslicetype(c, rtyp); }; }; @@ -1303,8 +1303,8 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // resolve to the right tinfo via check.ww:1947-1978 (pseudo-field // + struct-field stamps). Cstage cgen.c:182-184 node_isslice = // type_isslice(n->type) — same shape. Collapsed per A.6.3h (#56). - if (k == nkind.N_DOT) { - return typeisslice(n.type_: *tinfo); + if (k == syntax.nkind.N_DOT) { + return syntax.typeisslice(n.type_: *syntax.tinfo); }; // #45 (F7-c2): `arr[i]` whose element is a slice. cgindex leaves // (AX=ptr, BX=len, CX=cap) for a 24B element, but with no N_INDEX @@ -1314,8 +1314,8 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // type (exprtype N_INDEX stamps n.type_, check.ww:2777), mirroring // cstage node_isslice = type_isslice(n->type) and the N_INDEX arms of // nodeisstr (below) + nodeisunsigned (:1798). - if (k == nkind.N_INDEX) { - return typeisslice(n.type_: *tinfo); + if (k == syntax.nkind.N_INDEX) { + return syntax.typeisslice(n.type_: *syntax.tinfo); }; return false; }; @@ -1336,11 +1336,11 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // - N_UN(TK_STAR) of `*str` — cgun itself emits only `MOVQ (AX), AX` // and never loads .len into BX; fixing the recognizer alone won't // help. Tracked alongside the broader cgun-load-shape gap. -fn nodeisstr(c: *cgen, n: *node) bool = { +fn nodeisstr(c: *cgen, n: *syntax.node) bool = { if (n == nil) { return false; }; - let k: nkind = n.kind; - if (k == nkind.N_STRLIT) { return true; }; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_STRLIT) { return true; }; + if (k == syntax.nkind.N_IDENT) { let nm: str = n.str; let lc: *local = localfindnode(c, nm); // F7-c1: the local read collapses onto the checker-stamped @@ -1353,7 +1353,7 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // localfindnode keys on). The localfindnode gate stays to keep // the global-var-not-def case routing to false (out of F7 // scope), so this is a zero-delta mechanic validation. - if (lc != nil) { return typeisstr(n.type_: *tinfo); }; + if (lc != nil) { return syntax.typeisstr(n.type_: *syntax.tinfo); }; // #21: a module-level `def s: str` ident is not a frame slot // (localfindnode→nil), so the local arm above misses it and // it would fall to the scalar single-PUSHQ default, dropping @@ -1365,29 +1365,29 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // $len), so the push site and cgcall's pop sizer flip together // on this shared recognizer (load-bearing). if (deflookup(c, nm)) { - return typeisstr(n.type_: *tinfo); + return syntax.typeisstr(n.type_: *syntax.tinfo); }; return false; }; - if (k == nkind.N_CALL) { - let callee: *node = n.lhs; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = n.lhs; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { - let rtyp: *node = fnretlookupmod(c, callee.str, c.curmod); + if (callee.kind == syntax.nkind.N_IDENT) { + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, c.curmod); return isstrtype(c, rtyp); }; // #34: cross-module N_DOT — route through fnretlookupmod // so a same-leaf caller-module fn (different return shape) // doesn't shadow the explicit qualifier. - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; - let rtyp: *node = fnretlookupmod(c, callee.str, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, cmod); return isstrtype(c, rtyp); }; }; @@ -1402,18 +1402,18 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // = type_isstr(n->type) and nodeisunsigned's N_INDEX arm (:1798). The // base-kind whitelist is gone — every base shape routes through the // one stamp read. - if (k == nkind.N_INDEX) { - return typeisstr(n.type_: *tinfo); + if (k == syntax.nkind.N_INDEX) { + return syntax.typeisstr(n.type_: *syntax.tinfo); }; // N_DOT: read the checker-stamped n.type_. Struct field, nested // dot, value-struct hops, and pseudo-fields (.ptr/.len/.cap) all // resolve to the right tinfo via check.ww:1947-1978. Cstage // cgen.c:168-170 node_isstr = type_isstr(n->type) — same shape. // Collapsed per A.6.3h (#56). - if (k == nkind.N_DOT) { - return typeisstr(n.type_: *tinfo); + if (k == syntax.nkind.N_DOT) { + return syntax.typeisstr(n.type_: *syntax.tinfo); }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { return isstrtype(c, n.rhs); }; return false; @@ -1424,9 +1424,9 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // (cstage N_LET sz==8 ladder SSoT). t.type_ is stamped at check.ww // L426-436 for every type-AST kind callers reach. Collapsed onto the // tinfo helper per A.6.3b (#46). -fn typeis8byteprimitive(c: *cgen, t: *node) bool = { +fn typeis8byteprimitive(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeis8byteprim(t.type_: *tinfo); + return syntax.typeis8byteprim(t.type_: *syntax.tinfo); }; // elemissignedc — given an indexable type-AST (`*T`, `[]T`, `[N]T`), @@ -1434,7 +1434,7 @@ fn typeis8byteprimitive(c: *cgen, t: *node) bool = { // MOVSXD vs MOVL at esz=4 (and MOVSBQ/MOVSWQ at esz=1/2). Mirrors // cstage's `signed_elem` (cmd/w6c/cgen.c idx_eff path). Reads through // the stamped tinfo so alias/enum recursion lives in lib/ww/typ.ww. -fn elemissignedc(c: *cgen, t: *node) bool = { +fn elemissignedc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; // #65 Phase-N step-2 cleanup: peel TY_NAMED before the .sub read. // #64 now flows per-decl NAMED wrappers, so a NAMED-of-(`*T`/`[]T`/ @@ -1446,9 +1446,9 @@ fn elemissignedc(c: *cgen, t: *node) bool = { // idxeffti additionally drills `*[N]T` to the pointee array (#61) // so a signed-narrow element behind a pointer-to-array still // sign-extends on load. - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti == nil) { return false; }; - return typeissigned(ti.sub); + return syntax.typeissigned(ti.sub); }; // elemisfloatc — given an indexable type-AST (`*T`, `[]T`, `[N]T`), is @@ -1459,22 +1459,22 @@ fn elemissignedc(c: *cgen, t: *node) bool = { // .sub read exactly as elemissignedc does (#64/#65). Float-ness comes // from the SAME tinfo the esz already reads — never a fresh node-stamp // (the unstamped-base trap that broke the exprfloatkind collapse, #121). -fn elemisfloatc(c: *cgen, t: *node) bool = { +fn elemisfloatc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; // idxeffti = TY_NAMED peel + the `*[N]T` drill (#61). - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti == nil) { return false; }; - return typeisfloat(ti.sub); + return syntax.typeisfloat(ti.sub); }; // elemisf32c — narrower elemisfloatc: true only when the element is f32, // so cgindex picks MOVSS over MOVSD at the #119 element load. -fn elemisf32c(c: *cgen, t: *node) bool = { +fn elemisf32c(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; // idxeffti = TY_NAMED peel + the `*[N]T` drill (#61). - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti == nil) { return false; }; - return typeisf32(ti.sub); + return syntax.typeisf32(ti.sub); }; // elemisarrayc — given an indexable type-AST (`*T` / `[]T` / `[N]T`), is @@ -1486,20 +1486,20 @@ fn elemisf32c(c: *cgen, t: *node) bool = { // elemsizeof (:920-948) so elem-is-array aligns with the esz this same // tnode feeds. cstage twin: idx_eff(bt)->sub unwrapped == TY_ARRAY // (cmd/w6c/cgen.c). `c` kept for signature symmetry with elemisfloatc. -fn elemisarrayc(c: *cgen, t: *node) bool = { +fn elemisarrayc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - let k: nkind = t.kind; - let elem: *node = nil; - if (k == nkind.N_TPTR) { elem = t.lhs; }; - if (k == nkind.N_TSLICE) { elem = t.lhs; }; - if (k == nkind.N_TARRAY) { elem = t.lhs; }; + let k: syntax.nkind = t.kind; + let elem: *syntax.node = nil; + if (k == syntax.nkind.N_TPTR) { elem = t.lhs; }; + if (k == syntax.nkind.N_TSLICE) { elem = t.lhs; }; + if (k == syntax.nkind.N_TARRAY) { elem = t.lhs; }; if (elem == nil) { return false; }; - if (k == nkind.N_TPTR) { - if (elem.kind == nkind.N_TARRAY) { + if (k == syntax.nkind.N_TPTR) { + if (elem.kind == syntax.nkind.N_TARRAY) { if (elem.lhs != nil) { elem = elem.lhs; }; }; }; - return elem.kind == nkind.N_TARRAY; + return elem.kind == syntax.nkind.N_TARRAY; }; // tichase — transitive TY_NAMED peel, nil-passthrough. Exact wwstage @@ -1509,10 +1509,10 @@ fn elemisarrayc(c: *cgen, t: *node) bool = { // scalar shape (#60's esz=1/pointer-base SEGV family). One chased // accessor is the only spelled way to dealias; raw `.under` reads // outside it are the lint target (rob F2 ruling). -fn tichase(t0: *tinfo) *tinfo = { - let t: *tinfo = t0; +fn tichase(t0: *syntax.tinfo) *syntax.tinfo = { + let t: *syntax.tinfo = t0; // peel-ok: chase body - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + for (t != nil && t.kind == syntax.tykind.TY_NAMED) { t = t.under; }; return t; }; @@ -1521,11 +1521,11 @@ fn tichase(t0: *tinfo) *tinfo = { // element type comes from n.type_ (stamped tinfo) not a tnode. Same // role as typeisslice/typeisstr in lib/ww/typ.ww; kept cgen-local to // avoid widening the frontend surface for one #156 read-half check. -fn tinfoisarray(t: *tinfo) bool = { - let u: *tinfo = t; +fn tinfoisarray(t: *syntax.tinfo) bool = { + let u: *syntax.tinfo = t; u = tichase(u); if (u == nil) { return false; }; - return u.kind == tykind.TY_ARRAY; + return u.kind == syntax.tykind.TY_ARRAY; }; // fieldissignedc — does this field/element type-AST need sign- @@ -1533,9 +1533,9 @@ fn tinfoisarray(t: *tinfo) bool = { // cgen.c:240 `fld_issigned` SSoT). t.type_ is stamped at check.ww // L426-436 for every type-AST kind we see here (TNAME / TPTR / // TBANG / TENUM / TARRAY / TSLICE — see resolvewalk). -fn fieldissignedc(c: *cgen, t: *node) bool = { +fn fieldissignedc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeissigned(t.type_: *tinfo); + return syntax.typeissigned(t.type_: *syntax.tinfo); }; // fieldloadop — pick the load instruction for a non-str struct @@ -1570,7 +1570,7 @@ fn fieldstoreop(c: *cgen, f: *fieldinfo) str = { // pointer-target, slice-element, etc.) rather than a struct fieldinfo. // Used at the index / tuple / pointer-deref sites where there's no // fieldinfo entry but the type-node + size are both known. -fn tnodeloadop(c: *cgen, t: *node, sz: i32) str = { +fn tnodeloadop(c: *cgen, t: *syntax.node, sz: i32) str = { let sigd: bool = fieldissignedc(c, t); if (sz == 1) { if (sigd) { return "MOVSBQ"; }; return "MOVZBQ"; }; if (sz == 2) { if (sigd) { return "MOVSWQ"; }; return "MOVZWQ"; }; @@ -1578,7 +1578,7 @@ fn tnodeloadop(c: *cgen, t: *node, sz: i32) str = { return "MOVQ"; }; -fn tnodestoreop(c: *cgen, t: *node, sz: i32) str = { +fn tnodestoreop(c: *cgen, t: *syntax.node, sz: i32) str = { if (sz == 1) { return "MOVB"; }; if (sz == 2) { return "MOVW"; }; if (sz == 4) { return "MOVL"; }; @@ -1610,13 +1610,13 @@ fn loadopsz(sigd: bool, sz: i32) str = { // reports, with TBANG / TENUM / TNAME-alias chains pre-folded by // tinfofornode (check.ww:1102-1153 TNAME, 1154-1161 TBANG, // 1196-1208 TENUM). -export fn localloadop(c: *cgen, tnode: *node) str = { +export fn localloadop(c: *cgen, tnode: *syntax.node) str = { if (tnode == nil) { return "MOVQ"; }; - let ti: *tinfo = tnode.type_: *tinfo; + let ti: *syntax.tinfo = tnode.type_: *syntax.tinfo; if (ti == nil) { return "MOVQ"; }; let sz: i32 = ti.size: i32; if (sz != 1) { if (sz != 2) { if (sz != 4) { return "MOVQ"; }; }; }; - let sigd: bool = typeissigned(ti); + let sigd: bool = syntax.typeissigned(ti); return loadopsz(sigd, sz); }; @@ -1627,13 +1627,13 @@ export fn localloadop(c: *cgen, tnode: *node) str = { // step). One peel choke-point: every tinfo-keyed index-element answer // (elemsizeofc / elemissignedc / elemisfloatc / elemisf32c) routes // through here. Mirrors cstage idx_eff (cmd/w6c/cgen.c:1163). -fn idxeffti(t0: *tinfo) *tinfo = { - let t: *tinfo = t0; +fn idxeffti(t0: *syntax.tinfo) *syntax.tinfo = { + let t: *syntax.tinfo = t0; t = tichase(t); - if (t != nil && t.kind == tykind.TY_PTR) { - let p: *tinfo = t.sub; + if (t != nil && t.kind == syntax.tykind.TY_PTR) { + let p: *syntax.tinfo = t.sub; p = tichase(p); - if (p != nil && p.kind == tykind.TY_ARRAY) { return p; }; + if (p != nil && p.kind == syntax.tykind.TY_ARRAY) { return p; }; }; return t; }; @@ -1647,14 +1647,14 @@ fn idxeffti(t0: *tinfo) *tinfo = { // N*8-byte aggregate copy from an 8B source: caller-frame smash). // nil for non-indexable kinds (str N_TNAME: callers want nil so // tnodestoreop falls to the u8 byte store). -fn idxelemtn(tn: *node) *node = { +fn idxelemtn(tn: *syntax.node) *syntax.node = { if (tn == nil) { return nil; }; - let k: nkind = tn.kind; - if (k != nkind.N_TARRAY && k != nkind.N_TSLICE - && k != nkind.N_TPTR) { return nil; }; - let elem: *node = tn.lhs; - if (k == nkind.N_TPTR && elem != nil - && elem.kind == nkind.N_TARRAY) { + let k: syntax.nkind = tn.kind; + if (k != syntax.nkind.N_TARRAY && k != syntax.nkind.N_TSLICE + && k != syntax.nkind.N_TPTR) { return nil; }; + let elem: *syntax.node = tn.lhs; + if (k == syntax.nkind.N_TPTR && elem != nil + && elem.kind == syntax.nkind.N_TARRAY) { return elem.lhs; }; return elem; @@ -1666,14 +1666,14 @@ fn idxelemtn(tn: *node) *node = { // For aliased element types (e.g. `[N]formattable`), callers that // need the resolved slot size should use elemsizeofc(c, t) which // follows aliases via slotsize. -fn elemsizeof(t: *node) i32 = { +fn elemsizeof(t: *syntax.node) i32 = { if (t == nil) { return 1; }; - let k: nkind = t.kind; - let elem: *node = nil; - if (k == nkind.N_TPTR) { elem = t.lhs; }; - if (k == nkind.N_TSLICE) { elem = t.lhs; }; - if (k == nkind.N_TARRAY) { elem = t.lhs; }; - if (k == nkind.N_TNAME) { + let k: syntax.nkind = t.kind; + let elem: *syntax.node = nil; + if (k == syntax.nkind.N_TPTR) { elem = t.lhs; }; + if (k == syntax.nkind.N_TSLICE) { elem = t.lhs; }; + if (k == syntax.nkind.N_TARRAY) { elem = t.lhs; }; + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; // str's element is u8 (F1: tystr.sub = tyu8), named directly // rather than read off str.sub because elemsizeof gets a raw @@ -1683,7 +1683,7 @@ fn elemsizeof(t: *node) i32 = { // str.sub-equivalent; the structural collapse onto str.sub is // blocked on tinfo-stamping here, not intent (#24). cstage twin // reads eff->sub->size (cmd/w6c/cgen.c N_INDEX). - if (streq(nm, "str")) { return primtypesize("u8"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("u8"): i32; }; // Indexing a primitive name (rare): element size = the prim. // primsize-ok (#101/#109): elemsizeof is the STRUCTURAL (non- // chasing) sizer by design — its alias-resolving twin elemsizeofc @@ -1702,17 +1702,17 @@ fn elemsizeof(t: *node) i32 = { // double-index (cgindex) needs the sub-array stride — call // elemsizeofc, the 2D-correct entry, which recovers slotsize([M]T) // when elemsizeof returns 8. Never call elemsizeof for a 2D stride. - if (elem.kind == nkind.N_TARRAY) { + if (elem.kind == syntax.nkind.N_TARRAY) { if (elem.lhs != nil) { elem = elem.lhs; }; }; // `*[]T`: stride is the slice header (24B). Hare-faithful — a // pointer-to-slice is a 1D array of slices, not of T. Mirrors the // cstage check.c default `*U → U` path for U=[]T (slice element). - if (elem.kind == nkind.N_TSLICE) { return tyslicesize(): i32; }; - if (elem.kind == nkind.N_TNAME) { + if (elem.kind == syntax.nkind.N_TSLICE) { return tyslicesize(): i32; }; + if (elem.kind == syntax.nkind.N_TNAME) { let nm: str = elem.str; // str element is 16B (ptr+len). primsize returns 0 for it. - if (streq(nm, "str")) { return primtypesize("str"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("str"): i32; }; // primsize-ok (#101/#109): structural sizer — the chase lives // in elemsizeofc (:1579), not here. See the :1475 leg. let ps: i32 = primsize(nm); @@ -1725,7 +1725,7 @@ fn elemsizeof(t: *node) i32 = { // (struct / tagged / `type foo = bar;`) via slotsize. Used where // cgindex / cgassign need a correct stride for `[N]Alias` arrays // whose Alias resolves to a tagged union (e.g. `[N]formattable`). -fn elemsizeofc(c: *cgen, t: *node) i32 = { +fn elemsizeofc(c: *cgen, t: *syntax.node) i32 = { if (t == nil) { return 1; }; // #270-2: a NESTED-array element ([N][M]T) — the OUTER index stride // is the WHOLE sub-array [M]T, not the scalar T that elemsizeof @@ -1742,12 +1742,12 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // every index by N*size(T) — the siphash round() corruption. The // `*[N][M]T` outer stride still resolves below via idxeffti // (pointee array's .sub = [M]T, its natural size). - let nk: nkind = t.kind; - let nest: *node = nil; - if (nk == nkind.N_TSLICE) { nest = t.lhs; }; - if (nk == nkind.N_TARRAY) { nest = t.lhs; }; - if (nest != nil && nest.kind == nkind.N_TARRAY) { - let eti: *tinfo = nest.type_: *tinfo; + let nk: syntax.nkind = t.kind; + let nest: *syntax.node = nil; + if (nk == syntax.nkind.N_TSLICE) { nest = t.lhs; }; + if (nk == syntax.nkind.N_TARRAY) { nest = t.lhs; }; + if (nest != nil && nest.kind == syntax.nkind.N_TARRAY) { + let eti: *syntax.tinfo = nest.type_: *syntax.tinfo; eti = tichase(eti); if (eti != nil) { return eti.size: i32; }; }; @@ -1760,12 +1760,12 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // element chased like the #8 leg below. Non-indexable names // (struct/prim/str aliases) fall through to the old paths — // byte-id preserved there. - if (nk == nkind.N_TNAME) { - let eff: *tinfo = idxeffti(t.type_: *tinfo); + if (nk == syntax.nkind.N_TNAME) { + let eff: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (eff != nil) { - if (eff.kind == tykind.TY_ARRAY - || eff.kind == tykind.TY_SLICE) { - let aes: *tinfo = tichase(eff.sub); + if (eff.kind == syntax.tykind.TY_ARRAY + || eff.kind == syntax.tykind.TY_SLICE) { + let aes: *syntax.tinfo = tichase(eff.sub); if (aes != nil) { return aes.size: i32; }; }; }; @@ -1786,15 +1786,15 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // idxeffti folds that peel together with the `*[N]T` TY_PTR→ // TY_ARRAY drill (#61) so .sub is the array's element, never the // whole pointee array. - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti != nil) { - let esub: *tinfo = ti.sub; + let esub: *syntax.tinfo = ti.sub; esub = tichase(esub); if (esub != nil) { return esub.size: i32; }; }; - let elem: *node = idxelemtn(t); + let elem: *syntax.node = idxelemtn(t); if (elem == nil) { return direct; }; - if (elem.kind == nkind.N_TNAME) { + if (elem.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, elem.str); if (ps > 0) { return ps; }; }; @@ -1811,9 +1811,9 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // // Conservative: if we can't tell, return false (signed). The cost of // being wrong here is byte-different asm vs C, not bad runtime. -fn nodeisunsigned(c: *cgen, n: *node) bool = { +fn nodeisunsigned(c: *cgen, n: *syntax.node) bool = { if (n == nil) { return false; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; // #25 (F7-c5): collapse the whole N_IDENT arm onto the checker-stamped // n.type_, dropping the localfindnode special-case. The prior arm read // the local's declared tnode and returned `false` (signed) for a @@ -1825,21 +1825,21 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // the corpus HAS module-global unsigned counters on the divide/shift // path, so the self-compile .s MOVES — every move is toward cstage // (IDIV→DIV where the global's stamp is unsigned) and runtime-correct. - if (k == nkind.N_IDENT) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_IDENT) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; - if (k == nkind.N_DOT) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_DOT) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { if (n.rhs == nil) { return false; }; - return typeisunsigned(n.rhs.type_: *tinfo); + return syntax.typeisunsigned(n.rhs.type_: *syntax.tinfo); }; - if (k == nkind.N_BIN) { + if (k == syntax.nkind.N_BIN) { if (nodeisunsigned(c, n.lhs)) { return true; }; return nodeisunsigned(c, n.rhs); }; - if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); }; + if (k == syntax.nkind.N_UN) { return nodeisunsigned(c, n.lhs); }; // nkind.N_INDEX: `p[i]` is unsigned iff its element type is // unsigned. Read the checker-stamped result type directly, // mirroring the N_DOT arm above and cstage cgen.c:2541 @@ -1850,8 +1850,8 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // `d.digits[nd] >= 5u8` pick signed JGE instead of unsigned JAE. // Embodies the #121 principle (collapse structural onto stamp). // #134. - if (k == nkind.N_INDEX) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_INDEX) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; // nkind.N_CALL: a call returning an unsigned type (e.g. `fn f() u64`) // is unsigned. Read the checker-stamped result type directly — the @@ -1860,8 +1860,8 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // `n->type = u->ret`; without this arm the wwstage fell through to // `return false`, picking signed IDIV/SAR over unsigned DIV/SHR on a // call-result div/mod/shift operand. #168. - if (k == nkind.N_CALL) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_CALL) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; return false; }; @@ -1870,27 +1870,27 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // statically determinable. Mirrors nodeisunsigned's structural walk. // Used by cgun TK_TILDE to clamp narrow unsigned ~ results to type // width (NOTQ inverts the full 64-bit register). -fn nodeprimwidth(c: *cgen, n: *node) i32 = { +fn nodeprimwidth(c: *cgen, n: *syntax.node) i32 = { if (n == nil) { return 0; }; - let k: nkind = n.kind; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; + if (tn.kind == syntax.nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; }; }; return 0; }; - if (k == nkind.N_CAST) { - let tn: *node = n.rhs; + if (k == syntax.nkind.N_CAST) { + let tn: *syntax.node = n.rhs; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; + if (tn.kind == syntax.nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; }; return 0; }; - if (k == nkind.N_UN) { return nodeprimwidth(c, n.lhs); }; + if (k == syntax.nkind.N_UN) { return nodeprimwidth(c, n.lhs); }; return 0; }; @@ -1947,7 +1947,7 @@ fn structabisize(si: *structinfo) i32 = { let end: i32 = fi.foff + fi.fsz; if (end > n) { n = end; }; if (fi.tnode != nil) { - let ti: *tinfo = fi.tnode.type_: *tinfo; + let ti: *syntax.tinfo = fi.tnode.type_: *syntax.tinfo; ti = tichase(ti); if (ti != nil) { let aln: i32 = ti.align: i32; @@ -1980,7 +1980,7 @@ fn structabisize(si: *structinfo) i32 = { // cgdot / cgassign at every "field-walk on a struct-typed local" // site so a transitively-aliased struct name resolves to its // fieldinfo list regardless of chain depth. -export fn structlookupchain(c: *cgen, tn: *node) *structinfo = { +export fn structlookupchain(c: *cgen, tn: *syntax.node) *structinfo = { if (tn == nil) { return nil; }; // #92: a struct LITERAL's type ref parses as N_IDENT (expression // position, lib/ww/parse/expr.ww) where type specs parse N_TNAME @@ -1988,17 +1988,17 @@ export fn structlookupchain(c: *cgen, tn: *node) *structinfo = { // iterations past the first walk aliaslookup results, which are // N_TNAME by the loop's own reassignment gate. Consumer census // (commit body): no existing caller can pass N_IDENT. - if (tn.kind != nkind.N_TNAME && tn.kind != nkind.N_IDENT) { return nil; }; + if (tn.kind != syntax.nkind.N_TNAME && tn.kind != syntax.nkind.N_IDENT) { return nil; }; let si: *structinfo = structlookup(c, tn.str); if (si != nil) { return si; }; - let cur: *node = tn; + let cur: *syntax.node = tn; for (cur != nil - && (cur.kind == nkind.N_TNAME || cur.kind == nkind.N_IDENT) + && (cur.kind == syntax.nkind.N_TNAME || cur.kind == syntax.nkind.N_IDENT) && si == nil) { - let aliased: *node = aliaslookup(c, cur.str); + let aliased: *syntax.node = aliaslookup(c, cur.str); if (aliased == nil) { cur = nil; } else { - if (aliased.kind == nkind.N_TNAME) { + if (aliased.kind == syntax.nkind.N_TNAME) { si = structlookup(c, aliased.str); cur = aliased; } else { cur = nil; }; @@ -2007,10 +2007,10 @@ export fn structlookupchain(c: *cgen, tn: *node) *structinfo = { return si; }; -export fn sretretsize(c: *cgen, t: *node) i32 = { +export fn sretretsize(c: *cgen, t: *syntax.node) i32 = { if (t == nil) { return 0; }; - let r: *node = t; - if (r.kind == nkind.N_TBANG) { + let r: *syntax.node = t; + if (r.kind == syntax.nkind.N_TBANG) { r = r.lhs; if (r == nil) { return 0; }; }; @@ -2026,7 +2026,7 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { if (tsz38 <= TUPLE_GPCAP * 8) { return 0; }; return tsz38; }; - if (r.kind == nkind.N_TTUPLE) { + if (r.kind == syntax.nkind.N_TTUPLE) { // #10: over-cap tuple → sret. Walk the element TYPE nodes // (pt.lhs) over the SAME caps the SEND/receive use; a float = // 1 SSE eightbyte, a slice/str its 3-word header, a scalar 1 @@ -2037,9 +2037,9 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { let ssecap: i32 = TUPLE_SSECAP; let gptotal: i32 = 0; let ssecount: i32 = 0; - let pt: *node = r.list; + let pt: *syntax.node = r.list; for (pt != nil) { - let et: *node = pt.lhs; + let et: *syntax.node = pt.lhs; if (isfloattype(c, et)) { ssecount = ssecount + 1; } else { @@ -2048,7 +2048,7 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { pt = pt.next; }; if (gptotal > TUPLE_GPCAP || ssecount > ssecap) { - let rti: *tinfo = r.type_: *tinfo; + let rti: *syntax.tinfo = r.type_: *syntax.tinfo; if (rti != nil) { return rti.size: i32; }; }; return 0; @@ -2057,24 +2057,24 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { // (sub.size*len, the type table) gates ≤24 reg / >24 sret, mirroring // cstage cg_sret_retsize TY_ARRAY arm. Pure-int element arrays only; // no float-array-return consumer (structfloatclass stays struct-only). - if (r.kind == nkind.N_TARRAY) { - let ati: *tinfo = r.type_: *tinfo; + if (r.kind == syntax.nkind.N_TARRAY) { + let ati: *syntax.tinfo = r.type_: *syntax.tinfo; ati = tichase(ati); if (ati == nil) { return 0; }; let asz: i32 = ati.size: i32; if (asz <= 24) { return 0; }; return asz; }; - if (r.kind != nkind.N_TNAME) { return 0; }; + if (r.kind != syntax.nkind.N_TNAME) { return 0; }; // Primitives / aliased-to-primitives are never sret. if (aliasprimsize(c, r.str) > 0) { return 0; }; - if (streq(r.str, "str")) { return 0; }; + if (syntax.streq(r.str, "str")) { return 0; }; // #129: same-module alias wins over any-module struct hit. Without // this, `type stream = *vtable` (io) loses to memio.stream (56B // struct) via structlookup's any-module fallback → spurious sret. // Mirrors cstage cg_sret_retsize, which sees TY_PTR, not a name. if (c != nil) { - let al: *node = aliassamemod(c, r.str); + let al: *syntax.node = aliassamemod(c, r.str); if (al != nil) { return sretretsize(c, al); }; @@ -2082,7 +2082,7 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { let si: *structinfo = structlookup(c, r.str); if (si == nil) { if (c != nil) { - let aliased: *node = aliaslookup(c, r.str); + let aliased: *syntax.node = aliaslookup(c, r.str); if (aliased != nil) { return sretretsize(c, aliased); }; @@ -2098,29 +2098,29 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { // > 24B, return its natural size; else 0. Wraps sretretsize over the // callee's resolved return type, used by cglet / cgassign receive // sites and cgcall to detect sret at the receive / emit boundaries. -export fn callsretsize(c: *cgen, n: *node) i32 = { +export fn callsretsize(c: *cgen, n: *syntax.node) i32 = { if (n == nil) { return 0; }; - if (n.kind != nkind.N_CALL) { return 0; }; - let callee: *node = n.lhs; + if (n.kind != syntax.nkind.N_CALL) { return 0; }; + let callee: *syntax.node = n.lhs; if (callee == nil) { return 0; }; let cn: str; cn.ptr = nil; cn.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { cn = callee.str; cmod = c.curmod; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { cn = callee.str; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cn.len == 0) { return 0; }; - let rtyp: *node = fnretlookupmod(c, cn, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cn, cmod); // #129: sretretsize must see the CALLEE's module context so // aliassamemod resolves aliases from the callee's module (not the // caller's). Mirrors cstage operating on resolved Type* objects @@ -2141,15 +2141,15 @@ fn structlookup(c: *cgen, name: str) *structinfo = { // wrong totsize / field offsets. let s: *structinfo = c.structs; for (s != nil) { - if (streq(s.sname, name)) { - if (streq(s.smod, c.curmod)) { return s; }; + if (syntax.streq(s.sname, name)) { + if (syntax.streq(s.smod, c.curmod)) { return s; }; }; s = s.sinext; }; s = c.structs; for (s != nil) { let sn: str = s.sname; - if (streq(sn, name)) { return s; }; + if (syntax.streq(sn, name)) { return s; }; s = s.sinext; }; // Module-qualified form embedded in name (`pkg.S`): scope the @@ -2170,8 +2170,8 @@ fn structlookup(c: *cgen, name: str) *structinfo = { let pkgmod: str = usehint(c, pkg); let b: *structinfo = c.structs; for (b != nil) { - if (streq(b.sname, leaf)) { - if (streq(b.smod, pkgmod)) { + if (syntax.streq(b.sname, leaf)) { + if (syntax.streq(b.smod, pkgmod)) { return b; }; }; @@ -2193,8 +2193,8 @@ fn structlookup(c: *cgen, name: str) *structinfo = { fn structsamemod(c: *cgen, name: str) *structinfo = { let s: *structinfo = c.structs; for (s != nil) { - if (streq(s.sname, name)) { - if (streq(s.smod, c.curmod)) { return s; }; + if (syntax.streq(s.sname, name)) { + if (syntax.streq(s.smod, c.curmod)) { return s; }; }; s = s.sinext; }; @@ -2224,23 +2224,23 @@ fn fldnumidx(s: str) i32 = { // IS the SSoT table aliasprimsize wraps; there is nothing below it to // chase. fn primsize(name: str) i32 = { - if (streq(name, "u8")) { return 1; }; - if (streq(name, "i8")) { return 1; }; - if (streq(name, "bool")) { return 1; }; - if (streq(name, "u16")) { return 2; }; - if (streq(name, "i16")) { return 2; }; - if (streq(name, "u32")) { return 4; }; - if (streq(name, "i32")) { return 4; }; - if (streq(name, "f32")) { return 4; }; - if (streq(name, "u64")) { return 8; }; - if (streq(name, "i64")) { return 8; }; - if (streq(name, "uint")) { return 8; }; - if (streq(name, "int")) { return 8; }; - if (streq(name, "uintptr")) { return 8; }; - if (streq(name, "size")) { return 8; }; - if (streq(name, "f64")) { return 8; }; - if (streq(name, "rune")) { return 4; }; - if (streq(name, "void")) { return 0; }; + if (syntax.streq(name, "u8")) { return 1; }; + if (syntax.streq(name, "i8")) { return 1; }; + if (syntax.streq(name, "bool")) { return 1; }; + if (syntax.streq(name, "u16")) { return 2; }; + if (syntax.streq(name, "i16")) { return 2; }; + if (syntax.streq(name, "u32")) { return 4; }; + if (syntax.streq(name, "i32")) { return 4; }; + if (syntax.streq(name, "f32")) { return 4; }; + if (syntax.streq(name, "u64")) { return 8; }; + if (syntax.streq(name, "i64")) { return 8; }; + if (syntax.streq(name, "uint")) { return 8; }; + if (syntax.streq(name, "int")) { return 8; }; + if (syntax.streq(name, "uintptr")) { return 8; }; + if (syntax.streq(name, "size")) { return 8; }; + if (syntax.streq(name, "f64")) { return 8; }; + if (syntax.streq(name, "rune")) { return 4; }; + if (syntax.streq(name, "void")) { return 0; }; return 0; }; @@ -2261,9 +2261,9 @@ fn primsize(name: str) i32 = { fn aliasprimsize(c: *cgen, nm: str) i32 = { let ps: i32 = primsize(nm); if (ps > 0) { return ps; }; - let cur: *node = aliaslookup(c, nm); + let cur: *syntax.node = aliaslookup(c, nm); for (cur != nil) { - if (cur.kind != nkind.N_TNAME) { return 0; }; + if (cur.kind != syntax.nkind.N_TNAME) { return 0; }; let p: i32 = primsize(cur.str); if (p > 0) { return p; }; cur = aliaslookup(c, cur.str); @@ -2278,16 +2278,16 @@ fn aliasprimsize(c: *cgen, nm: str) i32 = { // enum, etc.). Mirrors cstage's `type_isint(t) ? t->size : 0` / // `type_isunsigned` recursion through TY_NAMED and TY_ENUM. Used by // cgcast's identity-width identity-sign clamp-skip predicate (#33). -export fn typenodeprimresolved(c: *cgen, t: *node, +export fn typenodeprimresolved(c: *cgen, t: *syntax.node, sz_out: *i32, unsigned_out: *bool) void = { *sz_out = 0; *unsigned_out = false; - let cur: *node = t; + let cur: *syntax.node = t; for (cur != nil) { - let k: nkind = cur.kind; - if (k == nkind.N_TBANG) { cur = cur.lhs; } - else { if (k == nkind.N_TENUM) { cur = cur.lhs; } - else { if (k == nkind.N_TNAME) { + let k: syntax.nkind = cur.kind; + if (k == syntax.nkind.N_TBANG) { cur = cur.lhs; } + else { if (k == syntax.nkind.N_TENUM) { cur = cur.lhs; } + else { if (k == syntax.nkind.N_TNAME) { let nm: str = cur.str; // bool is excluded from the int-prim contract: cstage's // `type_isint(TY_BOOL)` is false, so its identity check @@ -2298,17 +2298,17 @@ export fn typenodeprimresolved(c: *cgen, t: *node, // primsize("bool")=1, so the exclusion stays local. The // dedicated `is_bool` path in cgcast owns bool→bool's // ANDQ $255 on both stages. - if (streq(nm, "bool")) { return; }; + if (syntax.streq(nm, "bool")) { return; }; // primsize-ok (#101/#109): this fn IS a prim-resolver // chaser (#33) — primsize is the leaf-primitive probe; // aliaslookup below advances the walk on a miss. let ps: i32 = primsize(nm); if (ps > 0) { *sz_out = ps; - *unsigned_out = typeisunsigned(cur.type_: *tinfo); + *unsigned_out = syntax.typeisunsigned(cur.type_: *syntax.tinfo); return; }; - let al: *node = aliaslookup(c, nm); + let al: *syntax.node = aliaslookup(c, nm); if (al == nil) { return; }; cur = al; } @@ -2324,13 +2324,13 @@ export fn typenodeprimresolved(c: *cgen, t: *node, // caller treats sz=0 as "not identity", which conservatively keeps // the clamp. Mirror of cstage's `n->lhs->type` lookup with the same // TY_NAMED / TY_ENUM recursion through type_isint / type_isunsigned. -export fn exprprimresolved(c: *cgen, n: *node, +export fn exprprimresolved(c: *cgen, n: *syntax.node, sz_out: *i32, unsigned_out: *bool) void = { *sz_out = 0; *unsigned_out = false; if (n == nil) { return; }; - let k: nkind = n.kind; - if (k == nkind.N_INTLIT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_INTLIT) { // Typed-int literal: `7u32` has tsuffix = "u32". Mirrors // cstage's `cexpr` which assigns `lookup_builtin(tsuffix)` // as the node's type — without this, wwstage misses the @@ -2345,12 +2345,12 @@ export fn exprprimresolved(c: *cgen, n: *node, let ps: i32 = primsize(s); if (ps > 0) { *sz_out = ps; - *unsigned_out = typeisunsigned(n.type_: *tinfo); + *unsigned_out = syntax.typeisunsigned(n.type_: *syntax.tinfo); }; }; return; }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { typenodeprimresolved(c, lc.tnode, @@ -2358,15 +2358,15 @@ export fn exprprimresolved(c: *cgen, n: *node, }; return; }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { typenodeprimresolved(c, n.rhs, sz_out, unsigned_out); return; }; - if (k == nkind.N_UN) { + if (k == syntax.nkind.N_UN) { exprprimresolved(c, n.lhs, sz_out, unsigned_out); return; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // #59: read the checker-stamped tinfo instead of re-deriving the // field type via dotfieldtnode's structinfo walk. Mirrors cstage // castsrcprim N_DOT (cmd/w6c/cgen.c:323-344): the base must @@ -2387,16 +2387,16 @@ export fn exprprimresolved(c: *cgen, n: *node, // there, sound through type_isint's NAMED recursion + the // NAMED tinfo carrying its underlying's size (probe // b1c_fld2lvl byte-id). - let bu: *tinfo = nil; - if (n.lhs != nil) { bu = n.lhs.type_: *tinfo; }; + let bu: *syntax.tinfo = nil; + if (n.lhs != nil) { bu = n.lhs.type_: *syntax.tinfo; }; bu = tichase(bu); - if (bu != nil && bu.kind == tykind.TY_PTR) { bu = tichase(bu.sub); }; - if (bu != nil && bu.kind == tykind.TY_STRUCT) { - let u: *tinfo = n.type_: *tinfo; + if (bu != nil && bu.kind == syntax.tykind.TY_PTR) { bu = tichase(bu.sub); }; + if (bu != nil && bu.kind == syntax.tykind.TY_STRUCT) { + let u: *syntax.tinfo = n.type_: *syntax.tinfo; u = tichase(u); - if (typeisint(u)) { + if (syntax.typeisint(u)) { *sz_out = u.size: i32; - *unsigned_out = typeisunsigned(u); + *unsigned_out = syntax.typeisunsigned(u); }; }; return; @@ -2411,7 +2411,7 @@ export fn exprprimresolved(c: *cgen, n: *node, // accept exact match plus suffix-after-`.` on either side. Mirrors // the C cgen's type_eq, which goes through resolved Type pointers. fn variantnamematch(vname: str, pname: str) bool = { - if (streq(vname, pname)) { return true; }; + if (syntax.streq(vname, pname)) { return true; }; // `pname` is qualified, `vname` is bare: drop module prefix. let i: i32 = 0; for (i < pname.len) { @@ -2419,7 +2419,7 @@ fn variantnamematch(vname: str, pname: str) bool = { let tail: str; tail.ptr = pname.ptr + i + 1; tail.len = pname.len - i - 1; - if (streq(tail, vname)) { return true; }; + if (syntax.streq(tail, vname)) { return true; }; }; i += 1; }; @@ -2430,7 +2430,7 @@ fn variantnamematch(vname: str, pname: str) bool = { let tail: str; tail.ptr = vname.ptr + j + 1; tail.len = vname.len - j - 1; - if (streq(tail, pname)) { return true; }; + if (syntax.streq(tail, pname)) { return true; }; }; j += 1; }; @@ -2444,42 +2444,42 @@ fn variantnamematch(vname: str, pname: str) bool = { // the SB-symbol fallback (linker reports `undefined reference to // `). We don't infer for plain `let x = f()` yet — // non-tagged returns don't carry their type back the same way. -fn inferletcalltype(c: *cgen, rhs: *node) *node = { +fn inferletcalltype(c: *cgen, rhs: *syntax.node) *syntax.node = { if (rhs == nil) { return nil; }; // `?` (N_TRYPROP) and `!` (N_TRYUNW) both unwrap a tagged // return to its success variant; the rhs we want the type of // is the inner call expression. let unwrap: bool = false; - let call: *node = rhs; - if (rhs.kind == nkind.N_TRYPROP) { call = rhs.lhs; unwrap = true; }; - if (rhs.kind == nkind.N_TRYUNW) { call = rhs.lhs; unwrap = true; }; + let call: *syntax.node = rhs; + if (rhs.kind == syntax.nkind.N_TRYPROP) { call = rhs.lhs; unwrap = true; }; + if (rhs.kind == syntax.nkind.N_TRYUNW) { call = rhs.lhs; unwrap = true; }; if (call == nil) { return nil; }; - if (call.kind != nkind.N_CALL) { return nil; }; - let callee: *node = call.lhs; + if (call.kind != syntax.nkind.N_CALL) { return nil; }; + let callee: *syntax.node = call.lhs; if (callee == nil) { return nil; }; let cname: str; cname.ptr = nil; cname.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { cname = callee.str; cmod = c.curmod; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { cname = callee.str; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cname.len == 0) { return nil; }; - let rtyp: *node = fnretlookupmod(c, cname, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cname, cmod); if (rtyp == nil) { return nil; }; if (unwrap) { // Strip error variants — success type is the first // variant of the tagged return. - if (rtyp.kind != nkind.N_TTAGGED) { return nil; }; + if (rtyp.kind != syntax.nkind.N_TTAGGED) { return nil; }; return rtyp.list; }; // Plain call: declared return type is the local's type. @@ -2497,7 +2497,7 @@ fn inferletcalltype(c: *cgen, rhs: *node) *node = { // not the default 8B. Without this, the AX:DX:CX spill in cglet's // tagged-init branch writes past the local and tramples the next // slot. -export fn letslotsize(c: *cgen, n: *node) i32 = { +export fn letslotsize(c: *cgen, n: *syntax.node) i32 = { // `[_]T = arrlit;` inferred-length arrays no longer need a slot-size // intercept here: the checker (inferarraylen, check.ww) stamps the // real element count onto the array type's length child before cgen @@ -2505,7 +2505,7 @@ export fn letslotsize(c: *cgen, n: *node) i32 = { // Annotation-less init: defer to the call's return type if we can // infer it. Tagged-union returns need 24B; everything else matches // slotsize on the inferred type. - let tn: *node = n.lhs; + let tn: *syntax.node = n.lhs; if (tn == nil) { tn = inferletcalltype(c, n.rhs); }; if (tn == nil) { return 8; }; let s: i32 = slotsize(c, tn); @@ -2517,9 +2517,9 @@ export fn letslotsize(c: *cgen, n: *node) i32 = { // instead, else its zero width collides with the next local. A // genuine empty struct or [0]T array (also slotsize 0) keeps its 0. if (s == 0) { - let ti: *tinfo = tn.type_: *tinfo; + let ti: *syntax.tinfo = tn.type_: *syntax.tinfo; if (ti != nil) { ti = tichase(ti); }; - if (ti != nil && ti.kind == tykind.TY_VOID) { return 8; }; + if (ti != nil && ti.kind == syntax.tykind.TY_VOID) { return 8; }; }; return s; }; @@ -2543,9 +2543,9 @@ export fn letslotsize(c: *cgen, n: *node) i32 = { // // `c: *cgen` retained unused for callsite stability (localloadop // precedent, 68219a1). -fn slotsize(c: *cgen, typn: *node) i32 = { +fn slotsize(c: *cgen, typn: *syntax.node) i32 = { if (typn == nil) { return 8; }; - let ti: *tinfo = typn.type_: *tinfo; + let ti: *syntax.tinfo = typn.type_: *syntax.tinfo; if (ti == nil) { return 8; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel @@ -2553,11 +2553,11 @@ fn slotsize(c: *cgen, typn: *node) i32 = { // NAMED to the alias-invariant underlying this read consumes. ti = tichase(ti); if (ti == nil) { return 8; }; - let kk: tykind = ti.kind; - if (kk == tykind.TY_VOID) { return 0; }; - if (kk == tykind.TY_PTR || kk == tykind.TY_SLICE || - kk == tykind.TY_CHAN || kk == tykind.TY_FN || - kk == tykind.TY_STR || kk == tykind.TY_TAGGED) { + let kk: syntax.tykind = ti.kind; + if (kk == syntax.tykind.TY_VOID) { return 0; }; + if (kk == syntax.tykind.TY_PTR || kk == syntax.tykind.TY_SLICE || + kk == syntax.tykind.TY_CHAN || kk == syntax.tykind.TY_FN || + kk == syntax.tykind.TY_STR || kk == syntax.tykind.TY_TAGGED) { return ti.size: i32; }; // #75: a struct LOCAL's stack slot is the struct's NATURAL size @@ -2569,10 +2569,10 @@ fn slotsize(c: *cgen, typn: *node) i32 = { // dual-SSoT leak as #44 (field-offset) / #55, one notion over. The // TUPLE arm (8B/elem slot, user ruling #60) and ARRAY arm (element // stride, #48 [N]Alias 24B) keep ti.slotsize — deliberate divergences. - if (kk == tykind.TY_STRUCT) { + if (kk == syntax.tykind.TY_STRUCT) { return ((ti.size + 7u64) & ~7u64): i32; }; - if (kk == tykind.TY_TUPLE || kk == tykind.TY_ARRAY) { + if (kk == syntax.tykind.TY_TUPLE || kk == syntax.tykind.TY_ARRAY) { return ti.slotsize: i32; }; return 8; @@ -2592,9 +2592,9 @@ fn slotsize(c: *cgen, typn: *node) i32 = { // // `c: *cgen` retained unused for callsite stability (slotsize / // localloadop precedent, a828c03 / 68219a1). -fn fieldsize(c: *cgen, tnode: *node) i32 = { +fn fieldsize(c: *cgen, tnode: *syntax.node) i32 = { if (tnode == nil) { return 8; }; - let ti: *tinfo = tnode.type_: *tinfo; + let ti: *syntax.tinfo = tnode.type_: *syntax.tinfo; if (ti == nil) { return 8; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel @@ -2602,14 +2602,14 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = { // NAMED to the alias-invariant underlying this read consumes. ti = tichase(ti); if (ti == nil) { return 8; }; - let k: tykind = ti.kind; - if (k == tykind.TY_STRUCT) { return ti.slotsize: i32; }; - if (k == tykind.TY_ARRAY) { return ti.slotsize: i32; }; - if (k == tykind.TY_TAGGED) { return ti.size: i32; }; - if (k == tykind.TY_SLICE) { return ti.size: i32; }; - if (k == tykind.TY_PTR || k == tykind.TY_FN || - k == tykind.TY_CHAN) { return 8; }; - if (k == tykind.TY_STR) { return ti.size: i32; }; + let k: syntax.tykind = ti.kind; + if (k == syntax.tykind.TY_STRUCT) { return ti.slotsize: i32; }; + if (k == syntax.tykind.TY_ARRAY) { return ti.slotsize: i32; }; + if (k == syntax.tykind.TY_TAGGED) { return ti.size: i32; }; + if (k == syntax.tykind.TY_SLICE) { return ti.size: i32; }; + if (k == syntax.tykind.TY_PTR || k == syntax.tykind.TY_FN || + k == syntax.tykind.TY_CHAN) { return 8; }; + if (k == syntax.tykind.TY_STR) { return ti.size: i32; }; // Primitives + TY_ENUM keep natural width inside structs // (cstage parity: cgen.c reads f->type->size directly). TY_TUPLE // flows here too — pre-collapse fallback was 8, the populated @@ -2633,7 +2633,7 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = { // non-TFIELD identically), so they advance in exact step. si.totsize keeps // the slot-padded total (stack-slot allocator's number) from ti.slotsize, // already 8-rounded at check.ww:2259-2261. -fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { +fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *syntax.node) void = { let si: *structinfo = alloc(structinfo{ sname = name, smod = srcmod, @@ -2643,7 +2643,7 @@ fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { os.write(2, msg.ptr, msg.len: u64); os.exit(1); }; - let ti: *tinfo = tichase(tstruct.type_: *tinfo); + let ti: *syntax.tinfo = tichase(tstruct.type_: *syntax.tinfo); if (ti == nil) { let msg: str = "#44/#55: registerstruct: tichase yielded nil tinfo\n"; os.write(2, msg.ptr, msg.len: u64); @@ -2651,10 +2651,10 @@ fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { }; let head: *fieldinfo = nil; let tail: *fieldinfo = nil; - let f: *node = tstruct.list; - let tf: *tfield = ti.fields; + let f: *syntax.node = tstruct.list; + let tf: *syntax.tfield = ti.fields; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { if (tf == nil) { let msg: str = "#44/#55: registerstruct: AST/tfield walk desync (more TFIELDs than tinfo.fields)\n"; os.write(2, msg.ptr, msg.len: u64); @@ -2678,13 +2678,13 @@ fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { c.structs = si; }; -fn collectstructs(c: *cgen, file: *node) void = { +fn collectstructs(c: *cgen, file: *syntax.node) void = { c.structs = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_TYPEDECL) { - let body: *node = d.lhs; + if (d.kind == syntax.nkind.N_TYPEDECL) { + let body: *syntax.node = d.lhs; // #9: an error-struct (`type X = !struct{...}`) carries an // N_TBANG-wrapped body; peel it so X registers like any // struct. cstage is tinfo-based and needs no table, but @@ -2696,11 +2696,11 @@ fn collectstructs(c: *cgen, file: *node) void = { // cutover, which deletes this name-keyed dispatch outright; // until then the table must be complete (errors.opaque_ is // the first such type). #10 tracks retiring the table. - if (body != nil && body.kind == nkind.N_TBANG) { + if (body != nil && body.kind == syntax.nkind.N_TBANG) { body = body.lhs; }; if (body != nil) { - if (body.kind == nkind.N_TSTRUCT) { + if (body.kind == syntax.nkind.N_TSTRUCT) { registerstruct(c, d.str, d.nmod, body); }; }; @@ -2715,14 +2715,14 @@ fn collectstructs(c: *cgen, file: *node) void = { // Collapsed onto typeisstr per A.6.3b (#46); the prior AST walker is // reconstituted by typeisstr's TY_NAMED chase + tinfofornode's // TBANG-unwrap (check.ww:1145). -fn isstrtype(c: *cgen, t: *node) bool = { +fn isstrtype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisstr(t.type_: *tinfo); + return syntax.typeisstr(t.type_: *syntax.tinfo); }; -fn isslicetype(c: *cgen, t: *node) bool = { +fn isslicetype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisslice(t.type_: *tinfo); + return syntax.typeisslice(t.type_: *syntax.tinfo); }; // resolvetagged — return the underlying N_TTAGGED node for `t`, or nil @@ -2732,16 +2732,16 @@ fn isslicetype(c: *cgen, t: *node) bool = { // `(invalid | overflow)` node. Use at sites that read variant lists // or detect nullable folding off a scrutinee — cgmatch, cgtypetest, // cgtypeassert — so aliased `!(A|B)` shapes still dispatch. -export fn resolvetagged(c: *cgen, t: *node) *node = { - let r: *node = resolvetype(c, t); +export fn resolvetagged(c: *cgen, t: *syntax.node) *syntax.node = { + let r: *syntax.node = resolvetype(c, t); if (r == nil) { return nil; }; - if (r.kind == nkind.N_TBANG) { - let inner: *node = r.lhs; + if (r.kind == syntax.nkind.N_TBANG) { + let inner: *syntax.node = r.lhs; if (inner == nil) { return nil; }; r = resolvetype(c, inner); if (r == nil) { return nil; }; }; - if (r.kind == nkind.N_TTAGGED) { return r; }; + if (r.kind == syntax.nkind.N_TTAGGED) { return r; }; return nil; }; @@ -2750,41 +2750,41 @@ export fn resolvetagged(c: *cgen, t: *node) *node = { // @match_spill slot at first use (#15 first-use+fail-loud convergence). // IDENT scrutinees use a different lookup path (read off the local // directly, no spill) so this returns nil for them too. -fn matchscrutt(c: *cgen, scrut: *node) *node = { +fn matchscrutt(c: *cgen, scrut: *syntax.node) *syntax.node = { if (scrut == nil) { return nil; }; - let k: nkind = scrut.kind; - if (k == nkind.N_IDENT) { return nil; }; - if (k == nkind.N_CALL) { - let callee: *node = scrut.lhs; + let k: syntax.nkind = scrut.kind; + if (k == syntax.nkind.N_IDENT) { return nil; }; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = scrut.lhs; if (callee != nil) { let cnm: str; cnm.ptr = nil; cnm.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { cnm = callee.str; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_IDENT) { cnm = callee.str; }; + if (callee.kind == syntax.nkind.N_DOT) { cnm = callee.str; // Same-module-first disambiguation: a leaf collision // on `next` (utf8.next + caller-side next) otherwise // returns the last-declared (caller) rtype and the // 4-arm match collapses arms 2+ to tag 0. Task #31. if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cnm.len > 0) { - let rtyp: *node = fnretlookupmod(c, cnm, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cnm, cmod); if (rtyp != nil) { return resolvetagged(c, rtyp); }; }; }; return nil; }; - if (k == nkind.N_INDEX) { - let ibase: *node = scrut.lhs; + if (k == syntax.nkind.N_INDEX) { + let ibase: *syntax.node = scrut.lhs; if (ibase == nil) { return nil; }; - if (ibase.kind != nkind.N_IDENT) { + if (ibase.kind != syntax.nkind.N_IDENT) { // #48: non-ident index base (s.field[i], call()[i], // nested). Only idents carry a declared tnode to walk, // so resolve from the checker-stamped element tinfo @@ -2797,16 +2797,16 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { return nil; }; let bl: *local = localfindnode(c, ibase.str); - let btn: *node = nil; + let btn: *syntax.node = nil; if (bl != nil) { btn = bl.tnode; } else { btn = letvartnode(c, ibase.str); }; if (btn == nil) { return nil; }; // idxelemtn: `*[N]T` drills to the pointee array's element (#61). - let etn: *node = idxelemtn(btn); + let etn: *syntax.node = idxelemtn(btn); if (etn == nil) { return nil; }; return resolvetagged(c, etn); }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // #67: read the field's stamped tinfo off the N_DOT node // (post-#66 N_DOT carries the field type) instead of the // dotfieldtnode AST walk. cgmatch's gate reads scrutt.type_ @@ -2821,7 +2821,7 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { // non-ident N_INDEX/N_DOT arms (`match (*p)` spill size + variant // indices key off scrut.type_; pre-#46 nil here clamped the // variant to 0 and mis-sized @match_spill). - if (k == nkind.N_UN && scrut.op == tkind.TK_STAR) { + if (k == syntax.nkind.N_UN && scrut.op == syntax.tkind.TK_STAR) { if (!istaggedtype(c, scrut)) { return nil; }; return scrut; }; @@ -2834,7 +2834,7 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { // when the scrutinee type can't be resolved keeps the historical // alloc for non-tagged / unresolved cases. Called by cgmatch at first // use; #15 first-use+fail-loud pins this size per fn. -fn matchspillsz(c: *cgen, scrutt: *node) i32 = { +fn matchspillsz(c: *cgen, scrutt: *syntax.node) i32 = { if (scrutt == nil) { return 16; }; let sz: i32 = slotsize(c, scrutt); if (sz <= 0) { return 16; }; @@ -2850,13 +2850,13 @@ fn matchspillsz(c: *cgen, scrutt: *node) i32 = { // scalar catch-all, the second-half value registers (DX/CX) were // never spilled, and field reads from the under-allocated slot // trailed into the saved-BP word. -fn structparamsize(c: *cgen, t: *node) i32 = { +fn structparamsize(c: *cgen, t: *syntax.node) i32 = { if (c == nil) { return 0; }; - let r: *node = resolvetype(c, t); + let r: *syntax.node = resolvetype(c, t); if (r == nil) { return 0; }; - if (r.kind != nkind.N_TNAME) { return 0; }; + if (r.kind != syntax.nkind.N_TNAME) { return 0; }; let nm: str = r.str; - if (streq(nm, "str")) { return 0; }; + if (syntax.streq(nm, "str")) { return 0; }; if (aliasprimsize(c, nm) > 0) { return 0; }; let si: *structinfo = structlookup(c, nm); if (si == nil) { return 0; }; @@ -2870,12 +2870,12 @@ fn structparamsize(c: *cgen, t: *node) i32 = { // ≤16B-struct structparamsize carve-out doesn't cover: arrays of any // size and structs > 16B. Reads the stamped tinfo size (the type table, // byte-id with cstage Type.size). -fn aggargsizetn(t: *tinfo) i32 = { +fn aggargsizetn(t: *syntax.tinfo) i32 = { if (t == nil) { return 0; }; - let u: *tinfo = t; + let u: *syntax.tinfo = t; u = tichase(u); if (u == nil) { return 0; }; - if (u.kind == tykind.TY_STRUCT || u.kind == tykind.TY_ARRAY) { + if (u.kind == syntax.tykind.TY_STRUCT || u.kind == syntax.tykind.TY_ARRAY) { return u.size: i32; }; return 0; @@ -2888,12 +2888,12 @@ fn aggargsizetn(t: *tinfo) i32 = { // positive BP offsets. Mirror of cstage tagged_memarg_size; ABI shape // per ref/qbe/amd64/sysv.c:80-85 (inmem) / :411-426 (stack blit). The // ≤48B register convention is pinned in-tree (test/926 boundary rows). -fn taggedmemargsize(t: *tinfo) i32 = { +fn taggedmemargsize(t: *syntax.tinfo) i32 = { if (t == nil) { return 0; }; - let u: *tinfo = t; + let u: *syntax.tinfo = t; u = tichase(u); if (u == nil) { return 0; }; - if (u.kind != tykind.TY_TAGGED) { return 0; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return 0; }; if (u.nullable != 0) { return 0; }; // sizelint-ok: 6 SysV int arg regs (DI..R9) x 8B words — the // same register-capacity constant as cstage tagged_arg_size. @@ -2901,9 +2901,9 @@ fn taggedmemargsize(t: *tinfo) i32 = { return u.size: i32; }; -fn nodeisaggarg(n: *node) bool = { +fn nodeisaggarg(n: *syntax.node) bool = { if (n == nil) { return false; }; - return aggargsizetn(n.type_: *tinfo) > 0; + return aggargsizetn(n.type_: *syntax.tinfo) > 0; }; // aggargfloatstop — true iff the arg is a ≤16B struct with any float @@ -2911,16 +2911,16 @@ fn nodeisaggarg(n: *node) bool = { // the SSE eightbyte transport the GP aggregate push/drain can't model; // both stages loud-stop on it. Same predicate as the cstage Tfield // fld_isfloat walk (cmd/w6c/cgen.c #271 push arm). -fn aggargfloatstop(n: *node) bool = { +fn aggargfloatstop(n: *syntax.node) bool = { if (n == nil) { return false; }; - let st: *tinfo = n.type_: *tinfo; + let st: *syntax.tinfo = n.type_: *syntax.tinfo; st = tichase(st); if (st == nil) { return false; }; - if (st.kind != tykind.TY_STRUCT) { return false; }; + if (st.kind != syntax.tykind.TY_STRUCT) { return false; }; if (st.size: i32 > 16) { return false; }; - let f: *tfield = st.fields; + let f: *syntax.tfield = st.fields; for (f != nil) { - if (typeisfloat(f.type_)) { return true; }; + if (syntax.typeisfloat(f.type_)) { return true; }; f = f.tnext; }; return false; @@ -2939,13 +2939,13 @@ fn aggargfloatstop(n: *node) bool = { // eightbyte is pure-INT or a lone f64 AND at least one is f64. f32 / // sub-eightbyte packing deferred (#165b). Mirrors cstage // struct_float_class (cmd/w6c/cgen.c). -fn structfloatclass(c: *cgen, t: *node) i32 = { +fn structfloatclass(c: *cgen, t: *syntax.node) i32 = { if (c == nil) { return 0; }; - let r: *node = resolvetype(c, t); + let r: *syntax.node = resolvetype(c, t); if (r == nil) { return 0; }; - if (r.kind != nkind.N_TNAME) { return 0; }; + if (r.kind != syntax.nkind.N_TNAME) { return 0; }; let nm: str = r.str; - if (streq(nm, "str")) { return 0; }; + if (syntax.streq(nm, "str")) { return 0; }; if (aliasprimsize(c, nm) > 0) { return 0; }; let si: *structinfo = structlookup(c, nm); if (si == nil) { return 0; }; @@ -2980,10 +2980,10 @@ fn structfloatclass(c: *cgen, t: *node) i32 = { // and every tuple field; the fsz>8 guard below also lets a // <=8B one slip, so such a struct would wrongly SSE-route on // this stage but stay GP on cstage (a #165b leak). - let rf: *node = resolvetype(c, fi.tnode); + let rf: *syntax.node = resolvetype(c, fi.tnode); if (rf != nil) { - if (rf.kind == nkind.N_TARRAY) { return 0; }; - if (rf.kind == nkind.N_TTUPLE) { return 0; }; + if (rf.kind == syntax.nkind.N_TARRAY) { return 0; }; + if (rf.kind == syntax.nkind.N_TTUPLE) { return 0; }; }; if (fsz > 8) { return 0; }; if ((foff + fsz - 1) / 8 != e) { return 0; }; @@ -3008,49 +3008,49 @@ fn structfloatclass(c: *cgen, t: *node) i32 = { // resolve to TY_TAGGED — tinfofornode handles the N_TBANG unwrap // (check.ww:1145) so we don't re-walk it here. Cite cstage cgen.c // (`type_chase_named` + TY_TAGGED). Collapsed per A.6.3b (#46). -fn istaggedtype(c: *cgen, t: *node) bool = { +fn istaggedtype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeistagged(t.type_: *tinfo); + return syntax.typeistagged(t.type_: *syntax.tinfo); }; // tnodeisagg — struct/array/tuple kind off the checker-STAMPED tinfo // (the #49 funnel predicate; #209/#211 discipline — never tnode // names). Mirror of cstage's chase-then-kind test at the fill / // assign aggregate arms. -fn tnodeisagg(t: *node) bool = { +fn tnodeisagg(t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *tinfo = t.type_: *tinfo; + let u: *syntax.tinfo = t.type_: *syntax.tinfo; u = tichase(u); if (u == nil) { return false; }; - if (u.kind == tykind.TY_STRUCT) { return true; }; - if (u.kind == tykind.TY_ARRAY) { return true; }; - return u.kind == tykind.TY_TUPLE; + if (u.kind == syntax.tykind.TY_STRUCT) { return true; }; + if (u.kind == syntax.tykind.TY_ARRAY) { return true; }; + return u.kind == syntax.tykind.TY_TUPLE; }; // isfloattype — f32 / f64 / untyped_float (alias-aware). Cite cstage // cgen.c:117 `cg_isfloat`. Dispatches MOVSS/MOVSD-shaped paths across // cglet, cgident, cgassign, cgbin, cgcast, cgcall, cgreturn, fn- // prologue. Collapsed per A.6.3b (#46). -export fn isfloattype(c: *cgen, t: *node) bool = { +export fn isfloattype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisfloat(t.type_: *tinfo); + return syntax.typeisfloat(t.type_: *syntax.tinfo); }; // isf32type — narrower: true only for f32 (after alias chase). Cite // cstage cgen.c:188 `type_isf32`. Picks MOVSS vs MOVSD and the SS- // variant arithmetic / cast opcodes. Collapsed per A.6.3b (#46). -export fn isf32type(c: *cgen, t: *node) bool = { +export fn isf32type(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisf32(t.type_: *tinfo); + return syntax.typeisf32(t.type_: *syntax.tinfo); }; // isnullabletype — `(*T | void)` one-word fold per Hare's // `(*T | null)` semantics. Cite cstage cgen.c:396 `type_isnullable`; // the .nullable flag lands on tinfo at check.ww:1309-1318 when the // two-variant shape matches. Collapsed per A.6.3b (#46). -export fn isnullabletype(t: *node) bool = { +export fn isnullabletype(t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisnullable(t.type_: *tinfo); + return syntax.typeisnullable(t.type_: *syntax.tinfo); }; // nullableptrtag — 0-based index of the *T variant in a nullable @@ -3058,9 +3058,9 @@ export fn isnullabletype(t: *node) bool = { // scan ti.params, strip TY_NAMED on each variant, return idx of first // TY_PTR. Phase 1 (26724fe) populated the chain in tinfofornode's // TTAGGED arm so this walk could retire the AST-keyed predecessor. -export fn nullableptrtag(t: *node) i32 = { +export fn nullableptrtag(t: *syntax.node) i32 = { if (t == nil) { return 0; }; - let ti: *tinfo = t.type_: *tinfo; + let ti: *syntax.tinfo = t.type_: *syntax.tinfo; if (ti == nil) { return 0; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel @@ -3068,19 +3068,19 @@ export fn nullableptrtag(t: *node) i32 = { // NAMED to the alias-invariant underlying this read consumes. ti = tichase(ti); if (ti == nil) { return 0; }; - if (ti.kind != tykind.TY_TAGGED) { return 0; }; - let p: *tparam = ti.params; + if (ti.kind != syntax.tykind.TY_TAGGED) { return 0; }; + let p: *syntax.tparam = ti.params; let i: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; + let vt: *syntax.tinfo = p.type_; if (vt != nil) { // peel-ok: single peel PROBE-CLEARED (batch-2 c3-B2, // 018ef66) — constructible variant params never carry // 2+-level NAMED at this scan; cs twin nullable_ptr_tag // (cmd/w6c/cgen.c:747) keeps the identical single peel. - if (vt.kind == tykind.TY_NAMED) { vt = vt.under; }; + if (vt.kind == syntax.tykind.TY_NAMED) { vt = vt.under; }; if (vt != nil) { - if (vt.kind == tykind.TY_PTR) { return i; }; + if (vt.kind == syntax.tykind.TY_PTR) { return i; }; }; }; p = p.tnext; @@ -3101,18 +3101,18 @@ export fn nullableptrtag(t: *node) i32 = { // Mirrors cstage cg_tag_for_variant(rt, ty_void) (cmd/w6c/cgen.c:900-911): // chase NAMED, scan params, match bare TY_VOID (not `!void`, carried by the // tparam iserror flag). -fn voidvariantindex(tagged: *node) i32 = { +fn voidvariantindex(tagged: *syntax.node) i32 = { if (tagged == nil) { return -1; }; - let ti: *tinfo = tagged.type_: *tinfo; + let ti: *syntax.tinfo = tagged.type_: *syntax.tinfo; if (ti == nil) { return -1; }; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; - let p: *tparam = ti.params; + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; - if (vt != nil && vt.kind == tykind.TY_VOID && !p.iserror) { + let vt: *syntax.tinfo = p.type_; + if (vt != nil && vt.kind == syntax.tykind.TY_VOID && !p.iserror) { return idx; }; p = p.tnext; @@ -3125,9 +3125,9 @@ fn voidvariantindex(tagged: *node) i32 = { // returned value's surface type, find the matching variant's 0-based // index. Compare by exact type name first; if no match, fall back to // "any str-shape variant matches an str-typed value". -fn taggedvariantindex(c: *cgen, tagged: *node, rhs: *node) i32 = { +fn taggedvariantindex(c: *cgen, tagged: *syntax.node, rhs: *syntax.node) i32 = { if (tagged == nil) { return -1; }; - return taggedvariantindext(c, tagged.type_: *tinfo, rhs); + return taggedvariantindext(c, tagged.type_: *syntax.tinfo, rhs); }; // taggedvariantindext — tinfo-keyed core of taggedvariantindex. Given @@ -3142,14 +3142,14 @@ fn taggedvariantindex(c: *cgen, tagged: *node, rhs: *node) i32 = { // pass 1 (cgvariantmatch's tyassignableuntyped arm, the cg_variant_match // :801 mirror); the str/slice shape scan below covers the remaining // LOOSE sources (concrete types that typeeq no variant). -fn taggedvariantindext(c: *cgen, du: *tinfo, rhs: *node) i32 = { +fn taggedvariantindext(c: *cgen, du: *syntax.tinfo, rhs: *syntax.node) i32 = { if (du == nil) { return -1; }; if (rhs == nil) { return -1; }; - let ti: *tinfo = du; + let ti: *syntax.tinfo = du; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; - let r: i32 = flatvariantidxt(ti, rhs.type_: *tinfo, false); + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; + let r: i32 = flatvariantidxt(ti, rhs.type_: *syntax.tinfo, false); if (r >= 0) { return r; }; // Shape fallback: classify rhs as (str, slice, scalar/other) and // pick the first variant of matching shape. Covers LOOSE concrete @@ -3161,12 +3161,12 @@ fn taggedvariantindext(c: *cgen, du: *tinfo, rhs: *node) i32 = { // walk collapses to a flat scan over p.type_. let wantstr: bool = nodeisstr(c, rhs); let wantslice: bool = nodeisslice(c, rhs); - let p: *tparam = ti.params; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; - let visstr: bool = typeisstr(vt); - let visslice: bool = typeisslice(vt); + let vt: *syntax.tinfo = p.type_; + let visstr: bool = syntax.typeisstr(vt); + let visslice: bool = syntax.typeisslice(vt); if (visstr == wantstr && visslice == wantslice) { return idx; }; p = p.tnext; idx += 1; @@ -3188,10 +3188,10 @@ fn taggedvariantindext(c: *cgen, du: *tinfo, rhs: *node) i32 = { // ptr-id (typeeq, typ.ww:514), one-NAMED → kind mismatch → false. ww has // no type_assignable, so the untyped/loose arm (cg_variant_match's first // branch) lives in the caller's str/slice shape fallback, not here. -fn flatvariantidx(c: *cgen, tagged: *node, pat: *node) i32 = { +fn flatvariantidx(c: *cgen, tagged: *syntax.node, pat: *syntax.node) i32 = { if (tagged == nil) { return -1; }; if (pat == nil) { return -1; }; - return flatvariantidxt(tagged.type_: *tinfo, pat.type_: *tinfo, false); + return flatvariantidxt(tagged.type_: *syntax.tinfo, pat.type_: *syntax.tinfo, false); }; // flatvariantidxt — tinfo-keyed core of flatvariantidx: flat 0-based @@ -3211,16 +3211,16 @@ fn flatvariantidx(c: *cgen, tagged: *node, pat: *node) i32 = { // consumers, two modes — not a wrapper. cstage has no twin: its is/as // gate (check.c:2036) never calls cg_tag_for_variant, so cg_tag_for_variant // stays full-only there. -fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { +fn flatvariantidxt(tagged: *syntax.tinfo, want: *syntax.tinfo, exactonly: bool) i32 = { if (want == nil) { return -1; }; - let ti: *tinfo = tagged; + let ti: *syntax.tinfo = tagged; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; // Pass 1: exact match (NAMED-vs-NAMED typeeq, tagged-vs-tagged, bare // typeeq). Exact matches take precedence and need no guard — distinct // variants don't exact-match the same source. - let p: *tparam = ti.params; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { if (cgvariantmatch(p.type_, want)) { return idx; }; @@ -3242,10 +3242,10 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // disambiguated once the nominal-lossy model collapses the chain — // hard-error (drew's ambiguity proviso extended to the chained // set). cs twin cg_tag_for_variant fused in this commit. - if (want.kind == tykind.TY_NAMED) { - let sb: *tinfo = tichase(want); + if (want.kind == syntax.tykind.TY_NAMED) { + let sb: *syntax.tinfo = tichase(want); if (sb == nil) { return -1; }; - let q: *tparam = ti.params; + let q: *syntax.tparam = ti.params; let qi: i32 = 0; let found: i32 = -1; let n: i32 = 0; @@ -3281,7 +3281,7 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { q = ti.params; qi = 0; for (q != nil) { - if (q.type_ != nil && typeeq(tichase(q.type_), sb)) { + if (q.type_ != nil && syntax.typeeq(tichase(q.type_), sb)) { if (found < 0) { found = qi; }; n += 1; }; @@ -3305,8 +3305,8 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // exact `i64`. drew's proviso: guard the structural fallback like the // #218 nested-widen site — a bare source matching >=2 NAMED variants // needs nominal layout to disambiguate, so hard-error. - if (want.kind != tykind.TY_NAMED) { - let q: *tparam = ti.params; + if (want.kind != syntax.tykind.TY_NAMED) { + let q: *syntax.tparam = ti.params; let qi: i32 = 0; let found: i32 = -1; let n: i32 = 0; @@ -3320,9 +3320,9 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // below now guards the CHASED match set. cs twin // cg_tag_for_variant fused in this commit (probe: // both-wrong-identical pre-fix). - let pu: *tinfo = q.type_; - if (pu != nil && pu.kind == tykind.TY_NAMED - && typeeq(tichase(pu), want)) { + let pu: *syntax.tinfo = q.type_; + if (pu != nil && pu.kind == syntax.tykind.TY_NAMED + && syntax.typeeq(tichase(pu), want)) { if (found < 0) { found = qi; }; n += 1; }; @@ -3345,7 +3345,7 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // (type.c:316-324) for a variant that is itself a union. ww's checker // isassignable is node-keyed (AST type exprs), so the tinfo-keyed // widen/match funnel needs this focused mirror (#33). -fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { +fn tyassignableuntyped(dst: *syntax.tinfo, want: *syntax.tinfo) bool = { if (dst == nil) { return false; }; if (want == nil) { return false; }; // c4 (rob RE-RULE 2026-06-05): FULL chase, not the one-level unwrap @@ -3356,8 +3356,8 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // alias variant silently mis-tagged 0 (the str twin was masked by // taggedvariantindext's shape fallback). Aligns ww UP to the cs // twin cmd/wcc/type.c:369-385, harec-shaped since F1 9bd0d8b. - let du: *tinfo = tichase(dst); - if (du != nil && du.kind == tykind.TY_TAGGED) { + let du: *syntax.tinfo = tichase(dst); + if (du != nil && du.kind == syntax.tykind.TY_TAGGED) { // concrete→tagged drill (type.c:316-324): a NESTED tagged // variant compares by type_eq there — never equal to an // untyped source — so only non-tagged variants recurse, on @@ -3365,12 +3365,12 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // detected via the full chase (was one-level: a 2-level // alias-tagged variant slipped INTO the recursion, diverging // from cs's checker-level #199α reject — see the c4 finding). - let p: *tparam = du.params; + let p: *syntax.tparam = du.params; for (p != nil) { - let pu: *tinfo = tichase(p.type_); + let pu: *syntax.tinfo = tichase(p.type_); let nestedtagged: bool = false; if (pu != nil) { - if (pu.kind == tykind.TY_TAGGED) { nestedtagged = true; }; + if (pu.kind == syntax.tykind.TY_TAGGED) { nestedtagged = true; }; }; if (!nestedtagged) { if (tyassignableuntyped(p.type_, want)) { return true; }; @@ -3382,26 +3382,26 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // type.c:369-385 — INT/FLOAT/RUNE run on the UNPEELED dst exactly // like cs (typeisnum/typeisfloat/typeisint self-recurse TY_NAMED); // STR/BOOL/NIL read the chased du like cs reads its chased du. - if (want.kind == tykind.TY_UNTYPED_INT) { return typeisnum(dst); }; - if (want.kind == tykind.TY_UNTYPED_FLOAT) { return typeisfloat(dst); }; - if (want.kind == tykind.TY_UNTYPED_STR) { + if (want.kind == syntax.tykind.TY_UNTYPED_INT) { return syntax.typeisnum(dst); }; + if (want.kind == syntax.tykind.TY_UNTYPED_FLOAT) { return syntax.typeisfloat(dst); }; + if (want.kind == syntax.tykind.TY_UNTYPED_STR) { if (du == nil) { return false; }; - return du.kind == tykind.TY_STR; + return du.kind == syntax.tykind.TY_STR; }; - if (want.kind == tykind.TY_UNTYPED_RUNE) { - if (typeisint(dst)) { return true; }; - return dst.kind == tykind.TY_RUNE; + if (want.kind == syntax.tykind.TY_UNTYPED_RUNE) { + if (syntax.typeisint(dst)) { return true; }; + return dst.kind == syntax.tykind.TY_RUNE; }; - if (want.kind == tykind.TY_UNTYPED_BOOL) { + if (want.kind == syntax.tykind.TY_UNTYPED_BOOL) { if (du == nil) { return false; }; - return du.kind == tykind.TY_BOOL; + return du.kind == syntax.tykind.TY_BOOL; }; - if (want.kind == tykind.TY_UNTYPED_NIL) { + if (want.kind == syntax.tykind.TY_UNTYPED_NIL) { if (du == nil) { return false; }; - if (du.kind == tykind.TY_PTR) { return true; }; - if (du.kind == tykind.TY_SLICE) { return true; }; - if (du.kind == tykind.TY_CHAN) { return true; }; - return du.kind == tykind.TY_FN; + if (du.kind == syntax.tykind.TY_PTR) { return true; }; + if (du.kind == syntax.tykind.TY_SLICE) { return true; }; + if (du.kind == syntax.tykind.TY_CHAN) { return true; }; + return du.kind == syntax.tykind.TY_FN; }; return false; }; @@ -3419,7 +3419,7 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // nominal-lossy; the collision guard in cgwidentaggedstorebp enforces // the invariant for when #199b/B-full lands true nominal layout. // - neither NAMED → structural typeeq -fn cgvariantmatch(vt: *tinfo, want: *tinfo) bool = { +fn cgvariantmatch(vt: *syntax.tinfo, want: *syntax.tinfo) bool = { if (vt == nil) { return false; }; if (want == nil) { return false; }; // #33: pre-fix an untyped scalar fell past the typeeq passes to @@ -3427,23 +3427,23 @@ fn cgvariantmatch(vt: *tinfo, want: *tinfo) bool = { // non-str/slice variant can be `void` — a bare // `let e: (void | size) = 5` stored tag 0 while the is/as side // resolved `size` to 1 (wwstage-only; cstage resolves here). - if (typeisuntyped(want)) { return tyassignableuntyped(vt, want); }; - if (vt.kind == tykind.TY_NAMED && want.kind == tykind.TY_NAMED) { - return typeeq(vt, want); + if (syntax.typeisuntyped(want)) { return tyassignableuntyped(vt, want); }; + if (vt.kind == syntax.tykind.TY_NAMED && want.kind == syntax.tykind.TY_NAMED) { + return syntax.typeeq(vt, want); }; - if (vt.kind == tykind.TY_NAMED || want.kind == tykind.TY_NAMED) { - let vu: *tinfo = vt; + if (vt.kind == syntax.tykind.TY_NAMED || want.kind == syntax.tykind.TY_NAMED) { + let vu: *syntax.tinfo = vt; vu = tichase(vu); - let wu: *tinfo = want; + let wu: *syntax.tinfo = want; wu = tichase(wu); if (vu != nil && wu != nil - && vu.kind == tykind.TY_TAGGED - && wu.kind == tykind.TY_TAGGED) { - return typeeq(vu, wu); + && vu.kind == syntax.tykind.TY_TAGGED + && wu.kind == syntax.tykind.TY_TAGGED) { + return syntax.typeeq(vu, wu); }; return false; }; - return typeeq(vt, want); + return syntax.typeeq(vt, want); }; // cgvariantstructmatch — structural equality ignoring nominal identity @@ -3451,14 +3451,14 @@ fn cgvariantmatch(vt: *tinfo, want: *tinfo) bool = { // variants share the source's *shape*; ≥2 means the structural fallback // could not disambiguate them once nominal identity is lost. Mirrors // cstage cg_variant_struct_match (cmd/w6c/cgen.c). -fn cgvariantstructmatch(vt: *tinfo, want: *tinfo) bool = { - let vu: *tinfo = vt; +fn cgvariantstructmatch(vt: *syntax.tinfo, want: *syntax.tinfo) bool = { + let vu: *syntax.tinfo = vt; vu = tichase(vu); - let wu: *tinfo = want; + let wu: *syntax.tinfo = want; wu = tichase(wu); if (vu == nil) { return false; }; if (wu == nil) { return false; }; - return typeeq(vu, wu); + return syntax.typeeq(vu, wu); }; // flatslicevariantidx — flat 0-based index of a slice-shape variant in @@ -3472,27 +3472,27 @@ fn cgvariantstructmatch(vt: *tinfo, want: *tinfo) bool = { // #66 Phase-N step 3: element compare flips from surface-name to // typeeq(p.type_.sub, elem.type_). Mirrors cstage cg_tag_for_variant // over Type->params. Returns -1 when no slice variant exists. -fn flatslicevariantidx(c: *cgen, tagged: *node, elem: *node) i32 = { +fn flatslicevariantidx(c: *cgen, tagged: *syntax.node, elem: *syntax.node) i32 = { if (tagged == nil) { return -1; }; - let ti: *tinfo = tagged.type_: *tinfo; + let ti: *syntax.tinfo = tagged.type_: *syntax.tinfo; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; - let want: *tinfo = nil; - if (elem != nil) { want = elem.type_: *tinfo; }; + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; + let want: *syntax.tinfo = nil; + if (elem != nil) { want = elem.type_: *syntax.tinfo; }; let fallback: i32 = -1; - let p: *tparam = ti.params; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; + let vt: *syntax.tinfo = p.type_; if (vt != nil) { - if (typeisslice(vt)) { + if (syntax.typeisslice(vt)) { if (fallback < 0) { fallback = idx; }; if (want != nil) { - let su: *tinfo = vt; + let su: *syntax.tinfo = vt; su = tichase(su); if (su != nil) { - if (typeeq(su.sub, want)) { return idx; }; + if (syntax.typeeq(su.sub, want)) { return idx; }; }; }; }; @@ -3511,17 +3511,17 @@ fn flatslicevariantidx(c: *cgen, tagged: *node, elem: *node) i32 = { // TY_NAMED then walk su.params, mapping each source variant to its dst // index by typeeq (flatvariantidxt). Mirrors cg_widen_tag_remap // (cmd/w6c/cgen.c:1177) over su->params + cg_tag_for_variant (:503). -fn cgwidentagremap(c: *cgen, du: *tinfo, su: *tinfo, slot_off: i32) void = { - let dt: *tinfo = du; +fn cgwidentagremap(c: *cgen, du: *syntax.tinfo, su: *syntax.tinfo, slot_off: i32) void = { + let dt: *syntax.tinfo = du; dt = tichase(dt); if (dt == nil) { return; }; - if (dt.kind != tykind.TY_TAGGED) { return; }; - let st: *tinfo = su; + if (dt.kind != syntax.tykind.TY_TAGGED) { return; }; + let st: *syntax.tinfo = su; st = tichase(st); if (st == nil) { return; }; - if (st.kind != tykind.TY_TAGGED) { return; }; + if (st.kind != syntax.tykind.TY_TAGGED) { return; }; let identity: bool = true; - let p: *tparam = st.params; + let p: *syntax.tparam = st.params; let idx: i32 = 0; for (p != nil) { let di: i32 = flatvariantidxt(dt, p.type_, false); @@ -3568,12 +3568,12 @@ fn cgwidentagremap(c: *cgen, du: *tinfo, su: *tinfo, slot_off: i32) void = { // when the name is registered in c.structs — `!void` / `!i32` aliases // share the N_STRUCTLIT / N_TNAME shape but aren't structs, and must // fall through to the scalar/str/tagged-source paths instead. -fn rhsstructpayload(c: *cgen, src: *node) str = { +fn rhsstructpayload(c: *cgen, src: *syntax.node) str = { let empty: str; empty.ptr = nil; empty.len = 0; if (src == nil) { return empty; }; - if (src.kind == nkind.N_STRUCTLIT) { - let trefn: *node = src.lhs; + if (src.kind == syntax.nkind.N_STRUCTLIT) { + let trefn: *syntax.node = src.lhs; if (trefn != nil) { // #92: bare structlookup missed an alias-named literal // — `ali{...}` into a union fell to the scalar widen @@ -3588,12 +3588,12 @@ fn rhsstructpayload(c: *cgen, src: *node) str = { }; return empty; }; - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, src.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { + if (tn.kind == syntax.nkind.N_TNAME) { // #62 Layer-2 (F2 ww half): bare structlookup // missed an alias name (ali->base), so the // struct value fell to the SCALAR widen arm — @@ -3618,12 +3618,12 @@ fn rhsstructpayload(c: *cgen, src: *node) str = { // rhstaggedsource — return the tagged-type node for `src` when src is a // tagged-typed local ident; nil otherwise. The slot-copy path uses this // to walk variants for tag remap. -fn rhstaggedident(c: *cgen, src: *node) *node = { +fn rhstaggedident(c: *cgen, src: *syntax.node) *syntax.node = { if (src == nil) { return nil; }; - if (src.kind != nkind.N_IDENT) { return nil; }; + if (src.kind != syntax.nkind.N_IDENT) { return nil; }; let lc: *local = localfindnode(c, src.str); if (lc == nil) { return nil; }; - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (!istaggedtype(c, tn)) { return nil; }; return resolvetagged(c, tn); }; @@ -3634,9 +3634,9 @@ fn rhstaggedident(c: *cgen, src: *node) *node = { // #28's cgdot fix loads AX/DX/CX/R8 from the field's slot). Used to // decide whether cgexpr/spill works for the tagged-source branch of // cgwidentaggedstore. -fn rhstaggedabicall(c: *cgen, src: *node) bool = { +fn rhstaggedabicall(c: *cgen, src: *syntax.node) bool = { if (src == nil) { return false; }; - if (src.kind == nkind.N_CALL) { + if (src.kind == syntax.nkind.N_CALL) { // #211: a call's result type is the CALLEE's fn-type ret, which // the checker stamps onto this N_CALL node (check.ww N_CALL: both // the SK_FN path and the fn-VALUE/field path set e.type_ = the @@ -3647,10 +3647,10 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // sister reads u->ret off the callee type (cmd/wcc/check.c:1433, // :1490); harec selects by interned type id, not name (ref/harec/ // src/types.c:714). Mirrors the N_DOT branch below. - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; return false; }; - if (src.kind == nkind.N_INDEX) { + if (src.kind == syntax.nkind.N_INDEX) { // The checker stamps every N_INDEX node's type_ to the element // tinfo (check.ww:2334-2337 indexresult) for ANY base shape — // N_IDENT, N_DOT (`x.o[i]`), or chained N_INDEX (`m[i][j]`). Read @@ -3660,7 +3660,7 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // so a tagged element materialized via `x.o[i]` (correct AX/DX // slot from cgindex) was then spilled by the scalar-widen arm, // dropping the tag/payload-high word — silent cs≠ww. - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; return false; }; // N_DOT of a tagged-typed struct field — cgdot loads @@ -3670,19 +3670,19 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // stamp) instead of re-deriving via dotfieldtnode — matches // cstage cg_widen_tagged_store reading src->type directly // (cmd/w6c/cgen.c:1302-1305). typeistagged(nil) is false. - if (src.kind == nkind.N_DOT) { - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (src.kind == syntax.nkind.N_DOT) { + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; }; // Family C (#35/#46): a DEREF source is mem-based (taggedmemread, // any size) — the widen-store's memread arm copies the box from // the address cgexpr leaves in AX. An unwrap (`?`/`!`) source // fills the cursor after the tagged-success payload shift (the // cgtryprop/cgtryunw twin of cstage's kind-blind su-tagged arm). - if (src.kind == nkind.N_UN && src.op == tkind.TK_STAR) { - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (src.kind == syntax.nkind.N_UN && src.op == syntax.tkind.TK_STAR) { + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; }; - if (src.kind == nkind.N_TRYPROP || src.kind == nkind.N_TRYUNW) { - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (src.kind == syntax.nkind.N_TRYPROP || src.kind == syntax.nkind.N_TRYUNW) { + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; }; return false; }; @@ -3699,21 +3699,21 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // (which carried only the tag) and consumers copy from memory. ≤32B // INDEX/DOT keep the cursor byte-for-byte (the #37 no-drift bar); // the nullable one-word fold stays a scalar deref. -fn taggedmemread(c: *cgen, e: *node) bool = { +fn taggedmemread(c: *cgen, e: *syntax.node) bool = { if (e == nil) { return false; }; - if (e.kind == nkind.N_UN && e.op == tkind.TK_STAR) { - let du: *tinfo = e.type_: *tinfo; + if (e.kind == syntax.nkind.N_UN && e.op == syntax.tkind.TK_STAR) { + let du: *syntax.tinfo = e.type_: *syntax.tinfo; du = tichase(du); if (du == nil) { return false; }; - if (du.kind != tykind.TY_TAGGED) { return false; }; + if (du.kind != syntax.tykind.TY_TAGGED) { return false; }; if (du.nullable != 0) { return false; }; return du.size: i32 > 8; }; - if (e.kind != nkind.N_INDEX && e.kind != nkind.N_DOT) { return false; }; - let u: *tinfo = e.type_: *tinfo; + if (e.kind != syntax.nkind.N_INDEX && e.kind != syntax.nkind.N_DOT) { return false; }; + let u: *syntax.tinfo = e.type_: *syntax.tinfo; u = tichase(u); if (u == nil) { return false; }; - if (u.kind != tykind.TY_TAGGED) { return false; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return false; }; return u.size: i32 > TUPLE_GPCAP * 8; }; @@ -3725,17 +3725,17 @@ fn taggedmemread(c: *cgen, e: *node) bool = { // variant casts (`7: size`) keep their node for variant-tag lookup; // the nullable one-word fold never spills a cursor — excluded. // Mirrors cstage cg_tagged_castpeel. -fn taggedcastpeel(c: *cgen, e: *node) *node = { - for (e != nil && e.kind == nkind.N_CAST && e.lhs != nil) { - let cu: *tinfo = e.type_: *tinfo; +fn taggedcastpeel(c: *cgen, e: *syntax.node) *syntax.node = { + for (e != nil && e.kind == syntax.nkind.N_CAST && e.lhs != nil) { + let cu: *syntax.tinfo = e.type_: *syntax.tinfo; cu = tichase(cu); if (cu == nil) { return e; }; - if (cu.kind != tykind.TY_TAGGED) { return e; }; + if (cu.kind != syntax.tykind.TY_TAGGED) { return e; }; if (cu.nullable != 0) { return e; }; - let iu: *tinfo = e.lhs.type_: *tinfo; + let iu: *syntax.tinfo = e.lhs.type_: *syntax.tinfo; iu = tichase(iu); if (iu == nil) { return e; }; - if (iu.kind != tykind.TY_TAGGED) { return e; }; + if (iu.kind != syntax.tykind.TY_TAGGED) { return e; }; if (iu.nullable != 0) { return e; }; e = e.lhs; }; @@ -3748,13 +3748,13 @@ fn taggedcastpeel(c: *cgen, e: *node) *node = { // cast changes the tag numbering and must NOT be peeled — those die // loud at the consumer's cast catch-all instead. Mirrors cstage // cg_tagged_idcastpeel. -fn taggedidcastpeel(c: *cgen, e: *node) *node = { - for (e != nil && e.kind == nkind.N_CAST && e.lhs != nil) { - if (!typeeq(e.type_: *tinfo, e.lhs.type_: *tinfo)) { return e; }; - let cu: *tinfo = e.type_: *tinfo; +fn taggedidcastpeel(c: *cgen, e: *syntax.node) *syntax.node = { + for (e != nil && e.kind == syntax.nkind.N_CAST && e.lhs != nil) { + if (!syntax.typeeq(e.type_: *syntax.tinfo, e.lhs.type_: *syntax.tinfo)) { return e; }; + let cu: *syntax.tinfo = e.type_: *syntax.tinfo; cu = tichase(cu); if (cu == nil) { return e; }; - if (cu.kind != tykind.TY_TAGGED) { return e; }; + if (cu.kind != syntax.tykind.TY_TAGGED) { return e; }; e = e.lhs; }; return e; @@ -3831,9 +3831,9 @@ fn cgloadtaggedfield(c: *cgen, basereg: str, foff: i32, slot_sz: i32) void = { // tag last. // - str src: tag@+0, ptr@+8, len@+16, cap@+24 (str IS []u8, #1/Phase 3). // - scalar src: tag@+0, value@+8. -fn cgwidentaggedstore(c: *cgen, dst: *tinfo, src: *node, +fn cgwidentaggedstore(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, basereg: str, slot_off: i32, slot_sz: i32) void = { - if (streq(basereg, "BP")) { + if (syntax.streq(basereg, "BP")) { cgwidentaggedstorebp(c, dst, src, slot_off, slot_sz); return; }; @@ -3880,16 +3880,16 @@ fn cgwidentaggedstore(c: *cgen, dst: *tinfo, src: *node, // for the natural "BP" case and via the wrapper's scratch path for // pointer-rooted dst. Direct callers exist only in case of future // inlined uses inside this file; new code should call the wrapper. -fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_sz: i32) void = { +fn cgwidentaggedstorebp(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, slot_off: i32, slot_sz: i32) void = { // #68: dst is the tagged tinfo. Peel TY_NAMED → du and gate // TY_TAGGED, mirroring cstage cg_widen_tagged_store's // `du = (dst->kind==TY_NAMED)?dst->under:dst` + TY_TAGGED guard // (cmd/w6c/cgen.c:1273). resolvetagged's N_TBANG unwrap is already // handled upstream by tinfofornode (check.ww:1203-1210). - let dt: *tinfo = dst; + let dt: *syntax.tinfo = dst; dt = tichase(dt); if (dt == nil) { return; }; - if (dt.kind != tykind.TY_TAGGED) { return; }; + if (dt.kind != syntax.tykind.TY_TAGGED) { return; }; // Nullable fold: one 8B word holding the pointer (or 0 for void). if (dt.nullable != 0) { cgexpr(c, src); @@ -3912,11 +3912,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // a concrete variant (`7: i32`) is left intact so the existing // scalar / str / slice branches pick the right variant tag. if (src != nil) { - if (src.kind == nkind.N_CAST) { + if (src.kind == syntax.nkind.N_CAST) { if (src.lhs != nil) { - let inner: *node = src.lhs; + let inner: *syntax.node = src.lhs; let inneristagged: bool = false; - if (inner.kind == nkind.N_IDENT) { + if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { inneristagged = istaggedtype(c, lc.tnode); @@ -3939,16 +3939,16 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // the a==b fast path. let castisdst: bool = false; let castsubset: bool = false; - let castrhs: *node = src.rhs; + let castrhs: *syntax.node = src.rhs; if (castrhs != nil) { - let castt: *tinfo = castrhs.type_: *tinfo; - let castu: *tinfo = castt; + let castt: *syntax.tinfo = castrhs.type_: *syntax.tinfo; + let castu: *syntax.tinfo = castt; castu = tichase(castu); if (castu != nil) { if (castu == dt) { castisdst = true; - } else { if (castu.kind == tykind.TY_TAGGED) { - if (typeeq(castt, dst)) { + } else { if (castu.kind == syntax.tykind.TY_TAGGED) { + if (syntax.typeeq(castt, dst)) { castisdst = true; } else { castsubset = true; @@ -3985,7 +3985,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // chased the same src.type_. Mirrors cstage cg_widen_tagged_store's // `su = type_chase_named(st)` position (c138605). Tag lookups keep // the un-chased src.type_ (nominal identity is the alias). - let su: *tinfo = src.type_: *tinfo; + let su: *syntax.tinfo = src.type_: *syntax.tinfo; su = tichase(su); // #218: is the source itself a single NESTED variant of dt (its // whole tagged type matches one dt variant), rather than a flattened @@ -4001,14 +4001,14 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s || rhstaggedabicall(c, src); // #51 (#263): a module-global tagged ident is also a tagged source // (no local slot — handled by the global branch in the nested copy). - if (!srctagged) { if (src.kind == nkind.N_IDENT) { + if (!srctagged) { if (src.kind == syntax.nkind.N_IDENT) { if (localfindnode(c, src.str) == nil) { - let gtn51: *node = letvartnode(c, src.str); + let gtn51: *syntax.node = letvartnode(c, src.str); if (gtn51 != nil) { if (istaggedtype(c, gtn51)) { srctagged = true; }; }; }; }; }; if (srctagged) { - let nested: i32 = flatvariantidxt(dt, src.type_: *tinfo, false); + let nested: i32 = flatvariantidxt(dt, src.type_: *syntax.tinfo, false); if (nested >= 0) { // drew collision guard: the structural fallback over- // matches if ≥2 nominally-distinct dt variants share the @@ -4017,10 +4017,10 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // layer — hard-error NOW so a future collision STOPS the // compiler instead of silently mis-tagging. let nmatch: i32 = 0; - let gp: *tparam = dt.params; + let gp: *syntax.tparam = dt.params; for (gp != nil) { if (cgvariantstructmatch(gp.type_, - src.type_: *tinfo)) { + src.type_: *syntax.tinfo)) { nmatch += 1; }; gp = gp.tnext; @@ -4039,7 +4039,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s emitline("(BP)\n"); zk += 8; }; - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, src.str); if (lc != nil) { let soff: i32 = lc.off; @@ -4081,7 +4081,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // memory (AX = dest pointer), not the cursor — // the spill below would store the pointer as // the payload. Mem-to-mem widen is #40. - if (src.kind == nkind.N_CALL) { + if (src.kind == syntax.nkind.N_CALL) { if (callsretsize(c, src) > 0) { let m40a: str = "#40: sret-class call result cannot be cursor-widened into a tagged slot (mem-to-mem widen unwired)\n"; os.write(2, m40a.ptr, m40a.len: u64); @@ -4115,7 +4115,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // surviving taggedcastpeel (cast to a THIRD // union) has no cursor — loud, not word0 // garbage. Mirrors cstage. - if (src.kind == nkind.N_CAST) { + if (src.kind == syntax.nkind.N_CAST) { let m35a: str = "#35: tagged cast source shape unwired at the widen nested arm (rule 7)\n"; os.write(2, m35a.ptr, m35a.len: u64); os.exit(1); @@ -4152,7 +4152,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // Tagged source ident: byte-copy slot words then tag-remap. // rhstaggedident gates "src is a tagged-typed local ident"; the // remap reads the source tagged tinfo off the local's tnode (#68). - let st: *node = rhstaggedident(c, src); + let st: *syntax.node = rhstaggedident(c, src); if (st != nil) { let lc: *local = localfindnode(c, src.str); let ssz: i32 = slotsize(c, lc.tnode); @@ -4177,7 +4177,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s p += 8; }; }; - cgwidentagremap(c, dt, lc.tnode.type_: *tinfo, slot_off); + cgwidentagremap(c, dt, lc.tnode.type_: *syntax.tinfo, slot_off); return; }; // Tagged source via AX/DX/CX/R8 register ABI (N_CALL, N_INDEX @@ -4186,7 +4186,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s if (rhstaggedabicall(c, src)) { // #38b: an sret-classified call result is in memory (AX = // dest pointer), not the cursor. #40. - if (src.kind == nkind.N_CALL) { + if (src.kind == syntax.nkind.N_CALL) { if (callsretsize(c, src) > 0) { let m40b: str = "#40: sret-class call result cannot be cursor-widened into a tagged slot (mem-to-mem widen unwired)\n"; os.write(2, m40b.ptr, m40b.len: u64); @@ -4220,7 +4220,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s pp37 += 8; }; }; - cgwidentagremap(c, dt, src.type_: *tinfo, slot_off); + cgwidentagremap(c, dt, src.type_: *syntax.tinfo, slot_off); return; }; // #55: spill the AX/DX/CX/R8 cursor by the SOURCE box width @@ -4264,7 +4264,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s pp += 8; }; }; - cgwidentagremap(c, dt, src.type_: *tinfo, slot_off); + cgwidentagremap(c, dt, src.type_: *syntax.tinfo, slot_off); return; }; // #37 (rule 7): a >32B TAGGED source of a kind the resolver arms @@ -4274,7 +4274,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // cg_widen_tagged_store's generic-else bound. Surfaced by // reviewer-37's `let w = *p` probe on a 56B box: cstage loud, // wwstage silent (rule-10 break). - if (su != nil && su.kind == tykind.TY_TAGGED + if (su != nil && su.kind == syntax.tykind.TY_TAGGED && su.size: i32 > TUPLE_GPCAP * 8) { let m37f: str = "#37: >32B tagged source of a non-mem-based kind unwired (rule 7)\n"; os.write(2, m37f.ptr, m37f.len: u64); @@ -4284,8 +4284,8 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // taggedcastpeel (cast to a THIRD union) would fall to the // scalar arm below and silently truncate — loud. Mirrors // cstage's widen subset-arm cast bound. - if (src.kind == nkind.N_CAST && su != nil - && su.kind == tykind.TY_TAGGED && su.nullable == 0) { + if (src.kind == syntax.nkind.N_CAST && su != nil + && su.kind == syntax.tykind.TY_TAGGED && su.nullable == 0) { let m35b: str = "#35: tagged cast source shape unwired at the widen subset arm (rule 7)\n"; os.write(2, m35b.ptr, m35b.len: u64); os.exit(1); @@ -4304,13 +4304,13 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // slot 1+. Peel to the inner tuple here; src.type_ stays the CAST's // type, which resolves the variant tag by exact named match, so the // #241 untyped-element un-matchability does not arise for this form. - let tupsrc: *node = nil; + let tupsrc: *syntax.node = nil; let tupcast: bool = false; if (src != nil) { - if (src.kind == nkind.N_TUPLE) { tupsrc = src; }; - if (src.kind == nkind.N_CAST) { + if (src.kind == syntax.nkind.N_TUPLE) { tupsrc = src; }; + if (src.kind == syntax.nkind.N_CAST) { if (src.lhs != nil) { - if (src.lhs.kind == nkind.N_TUPLE) { + if (src.lhs.kind == syntax.nkind.N_TUPLE) { tupsrc = src.lhs; tupcast = true; }; @@ -4322,7 +4322,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // Mirrors cstage cg_widen_tagged_store. }; if (tupsrc != nil) { - if (su != nil) { if (su.kind == tykind.TY_TUPLE) { + if (su != nil) { if (su.kind == syntax.tykind.TY_TUPLE) { // #242/#241: mirror cstage's loud-stop CONDITION, not its // -1 mechanism (rule 10, align the RICHER side DOWN). // wwstage types `true`/`false` as bool and a suffix-less `7` @@ -4336,15 +4336,15 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // literal typing -> symmetric accept. BARE form only (#66): // the cast form resolves its tag from the cast's type on // BOTH stages, so bare elements are fine there. - let bl: *node = tupsrc.list; + let bl: *syntax.node = tupsrc.list; for (bl != nil && !tupcast) { let bare: bool = false; - if (bl.kind == nkind.N_TRUE) { bare = true; }; - if (bl.kind == nkind.N_FALSE) { bare = true; }; - if (bl.kind == nkind.N_INTLIT && bl.tsuffix.len == 0) { + if (bl.kind == syntax.nkind.N_TRUE) { bare = true; }; + if (bl.kind == syntax.nkind.N_FALSE) { bare = true; }; + if (bl.kind == syntax.nkind.N_INTLIT && bl.tsuffix.len == 0) { bare = true; }; - if (bl.kind == nkind.N_FLOATLIT && bl.tsuffix.len == 0) { + if (bl.kind == syntax.nkind.N_FLOATLIT && bl.tsuffix.len == 0) { bare = true; }; if (bare) { @@ -4359,7 +4359,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // str/slice shape fallback would silently pick tag 0 for an // unmatched tuple, diverging from cstage cg_tag_for_variant // (which returns -1) and masking the loud-stop below. - let ttag: i32 = flatvariantidxt(dt, src.type_: *tinfo, false); + let ttag: i32 = flatvariantidxt(dt, src.type_: *syntax.tinfo, false); // #242: an untyped/literal tuple element (`(true,7)`) leaves // the src tuple un-matchable, so the variant tag can't // resolve — the supported shape is a tuple of TYPED exprs @@ -4377,7 +4377,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // SysV eightbyte tuple classification is a deferred // follow-up. Symmetric with cstage cg_widen_tagged_store. let ttotal: i32 = 0; - let ce: *node = tupsrc.list; + let ce: *syntax.node = tupsrc.list; for (ce != nil) { // #47 gap-A: a tagged element rides its OWN // box (tag + payload, roundup8) per tuple slot @@ -4385,9 +4385,9 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // N_TTUPLE accumulation (check.ww:1640-1646); // the store loop below boxes it recursively // (two-level widen). Symmetric with cstage. - let ceti: *tinfo = ce.type_: *tinfo; + let ceti: *syntax.tinfo = ce.type_: *syntax.tinfo; ceti = tichase(ceti); - if (ceti != nil && ceti.kind == tykind.TY_TAGGED) { + if (ceti != nil && ceti.kind == syntax.tykind.TY_TAGGED) { ttotal += (ceti.size: i32 + 7) & ~7; } else { if (nodeisstr(c, ce) || nodeisslice(c, ce)) { ttotal += 24; @@ -4408,7 +4408,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s tzk += 8; }; let tfoff: i32 = 0; - let te: *node = tupsrc.list; + let te: *syntax.node = tupsrc.list; for (te != nil) { // #47 gap-A: a tagged element is its own // tag+payload box. Recurse so the inner box @@ -4418,11 +4418,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // (inner boxes here, outer tuple tag stamped // below). slot stride = roundup8(box). Symmetric // with cstage cg_widen_tagged_store. - let teti: *tinfo = te.type_: *tinfo; + let teti: *syntax.tinfo = te.type_: *syntax.tinfo; teti = tichase(teti); - if (teti != nil && teti.kind == tykind.TY_TAGGED) { + if (teti != nil && teti.kind == syntax.tykind.TY_TAGGED) { let ebox: i32 = (teti.size: i32 + 7) & ~7; - cgwidentaggedstore(c, te.type_: *tinfo, te, + cgwidentaggedstore(c, te.type_: *syntax.tinfo, te, "BP", slot_off + 8 + tfoff, ebox); tfoff += ebox; te = te.next; @@ -4431,7 +4431,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s let isflt: bool = isfloattype(c, te); let wide: bool = nodeisstr(c, te) || nodeisslice(c, te); let esz: i32 = 8; - let eti: *tinfo = te.type_: *tinfo; + let eti: *syntax.tinfo = te.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; cgexpr(c, te); if (isflt) { @@ -4484,23 +4484,23 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // A cast wrapping a concrete-variant tuple (`(tbl[i]: ci)`) // survived the widen-cast peel above; its operand is the // addressable expr. Mirror of cstage cg_widen_tagged_store. - if (su != nil) { if (su.kind == tykind.TY_TUPLE) { - let addrsrc: *node = src; - if (addrsrc.kind == nkind.N_CAST) { + if (su != nil) { if (su.kind == syntax.tykind.TY_TUPLE) { + let addrsrc: *syntax.node = src; + if (addrsrc.kind == syntax.nkind.N_CAST) { if (addrsrc.lhs != nil) { addrsrc = addrsrc.lhs; }; }; let okkind: bool = false; - if (addrsrc.kind == nkind.N_IDENT) { okkind = true; }; - if (addrsrc.kind == nkind.N_INDEX) { okkind = true; }; - if (addrsrc.kind == nkind.N_UN) { - if (addrsrc.op == tkind.TK_STAR) { okkind = true; }; + if (addrsrc.kind == syntax.nkind.N_IDENT) { okkind = true; }; + if (addrsrc.kind == syntax.nkind.N_INDEX) { okkind = true; }; + if (addrsrc.kind == syntax.nkind.N_UN) { + if (addrsrc.op == syntax.tkind.TK_STAR) { okkind = true; }; }; if (!okkind) { let mk: str = "cgwidentaggedstore: tuple-typed source shape unwired (only the bare/cast tuple literal and the addressable ident/index/deref trio carry a full payload; see #116)\n"; os.write(2, mk.ptr, mk.len: u64); os.exit(1); }; - let ntag: i32 = flatvariantidxt(dt, src.type_: *tinfo, false); + let ntag: i32 = flatvariantidxt(dt, src.type_: *syntax.tinfo, false); if (ntag < 0) { let mt: str = "cgwidentaggedstore: tuple-in-union variant tag unresolved (untyped/literal tuple element; see #242 / #241)\n"; os.write(2, mt.ptr, mt.len: u64); @@ -4553,10 +4553,10 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // fell to the scalar word0 arm — payload truncated. Land g(SB) in SI and // byte-copy the struct words into slot+8; cstage zero-fills the payload // (cstage half #43). Local/literal sources keep the existing arms (byte-id). - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { if (localfindnode(c, src.str) == nil) { - let gtn: *node = letvartnode(c, src.str); - if (gtn != nil) { if (gtn.kind == nkind.N_TNAME) { + let gtn: *syntax.node = letvartnode(c, src.str); + if (gtn != nil) { if (gtn.kind == syntax.nkind.N_TNAME) { let gsi: *structinfo = structlookupchain(c, gtn); if (gsi != nil) { emitline("\tXORQ\tAX, AX\n"); @@ -4617,7 +4617,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s }; let tag: i32 = taggedvariantindext(c, dt, src); if (tag < 0) { tag = 0; }; - if (src.kind == nkind.N_STRUCTLIT) { + if (src.kind == syntax.nkind.N_STRUCTLIT) { // #23: delegate to the single fill path. The // inline field loop this replaces was a // parallel fill that drifted: it lacked the @@ -4718,9 +4718,9 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // value" is dead and removed. let fkind: i32 = 0; if (src != nil) { - let srct: *tinfo = src.type_: *tinfo; - if (typeisf32(srct)) { fkind = 1; } - else { if (typeisfloat(srct)) { fkind = 2; }; }; + let srct: *syntax.tinfo = src.type_: *syntax.tinfo; + if (syntax.typeisf32(srct)) { fkind = 1; } + else { if (syntax.typeisfloat(srct)) { fkind = 2; }; }; }; if (fkind != 0) { let fmov: str = "MOVSD"; @@ -4752,17 +4752,17 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // like the slice axis, not nominal identity. let wantf32: bool = (fkind == 1); let ftag: i32 = -1; - let fti: *tinfo = dt; + let fti: *syntax.tinfo = dt; fti = tichase(fti); - if (fti != nil) { if (fti.kind == tykind.TY_TAGGED) { - let fp: *tparam = fti.params; + if (fti != nil) { if (fti.kind == syntax.tykind.TY_TAGGED) { + let fp: *syntax.tparam = fti.params; let fidx: i32 = 0; for (fp != nil) { - let fvt: *tinfo = fp.type_; + let fvt: *syntax.tinfo = fp.type_; fvt = tichase(fvt); if (fvt != nil) { - if (typeisfloat(fvt)) { - if (typeisf32(fvt) == wantf32) { ftag = fidx; break; }; + if (syntax.typeisfloat(fvt)) { + if (syntax.typeisf32(fvt) == wantf32) { ftag = fidx; break; }; }; }; fp = fp.tnext; @@ -4837,9 +4837,9 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // offset), so this is offset-preserving. Leaf out-param is the field's // stamped *tinfo (was *fieldinfo); the str/slice pseudo-leaf leaves it // nil and the callers gate on slicedelta>=0 first. -export fn dotchainresolve(c: *cgen, n: *node, +export fn dotchainresolve(c: *cgen, n: *syntax.node, outrootname: *str, outrootoff: *i32, outtotaloff: *i32, - outleaftype: **tinfo, outslicedelta: *i32, + outleaftype: **syntax.tinfo, outslicedelta: *i32, outisglobal: *bool, outptrroot: *bool) bool = { *outrootname = ""; *outrootoff = 0; @@ -4849,12 +4849,12 @@ export fn dotchainresolve(c: *cgen, n: *node, *outleaftype = nil; *outslicedelta = -1; if (n == nil) { return false; }; - if (n.kind != nkind.N_DOT) { return false; }; - let stk: [16]*node; + if (n.kind != syntax.nkind.N_DOT) { return false; }; + let stk: [16]*syntax.node; let nsteps: i32 = 0; - let cur: *node = n; + let cur: *syntax.node = n; for (cur != nil) { - if (cur.kind != nkind.N_DOT) { break; }; + if (cur.kind != syntax.nkind.N_DOT) { break; }; if (nsteps >= 16) { return false; }; stk[nsteps] = cur; nsteps += 1; @@ -4862,13 +4862,13 @@ export fn dotchainresolve(c: *cgen, n: *node, }; if (nsteps < 2) { return false; }; if (cur == nil) { return false; }; - if (cur.kind != nkind.N_IDENT) { return false; }; + if (cur.kind != syntax.nkind.N_IDENT) { return false; }; *outrootname = cur.str; let resolved: bool = false; let lc: *local = localfindnode(c, cur.str); if (lc != nil) { if (lc.tnode != nil) { - if (lc.tnode.kind == nkind.N_TNAME) { + if (lc.tnode.kind == syntax.nkind.N_TNAME) { *outrootoff = lc.off; resolved = true; }; @@ -4876,10 +4876,10 @@ export fn dotchainresolve(c: *cgen, n: *node, // pointee struct supplies the field layout. Callers // that opt in via *outptrroot emit a MOVQ load of the // slot before indexing. - if (lc.tnode.kind == nkind.N_TPTR) { - let pe: *node = lc.tnode.lhs; + if (lc.tnode.kind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = lc.tnode.lhs; if (pe != nil) { - if (pe.kind == nkind.N_TNAME) { + if (pe.kind == syntax.nkind.N_TNAME) { *outrootoff = lc.off; *outptrroot = true; resolved = true; @@ -4899,24 +4899,24 @@ export fn dotchainresolve(c: *cgen, n: *node, // Root struct layout = the stamped root-ident type_, peeled NAMED // (plus one TY_PTR hop for a `*struct` root). tfield.type_ then // supplies each nested struct directly, so no name re-lookup. - let curstruct: *tinfo = cur.type_: *tinfo; + let curstruct: *syntax.tinfo = cur.type_: *syntax.tinfo; curstruct = tichase(curstruct); if (*outptrroot) { if (curstruct == nil) { return false; }; - if (curstruct.kind != tykind.TY_PTR) { return false; }; + if (curstruct.kind != syntax.tykind.TY_PTR) { return false; }; curstruct = curstruct.sub; curstruct = tichase(curstruct); }; let i: i32 = nsteps - 1; for (i >= 0) { if (curstruct == nil) { return false; }; - if (curstruct.kind != tykind.TY_STRUCT) { return false; }; + if (curstruct.kind != syntax.tykind.TY_STRUCT) { return false; }; if (stk[i] == nil) { return false; }; let stepnm: str = stk[i].str; - let tf: *tfield = curstruct.fields; - let found: *tfield = nil; + let tf: *syntax.tfield = curstruct.fields; + let found: *syntax.tfield = nil; for (tf != nil) { - if (streq(tf.name, stepnm)) { found = tf; break; }; + if (syntax.streq(tf.name, stepnm)) { found = tf; break; }; tf = tf.tnext; }; if (found == nil) { return false; }; @@ -4926,37 +4926,37 @@ export fn dotchainresolve(c: *cgen, n: *node, *outleaftype = found.type_; return true; }; - let ft: *tinfo = found.type_; + let ft: *syntax.tinfo = found.type_; ft = tichase(ft); if (ft == nil) { return false; }; - if (ft.kind == tykind.TY_STR) { + if (ft.kind == syntax.tykind.TY_STR) { // str IS []u8: .cap is the third header word, same as // the TY_SLICE leaf below — cstage treats str≡slice for // .ptr/.len/.cap (cmd/w6c/cgen.c:2478) (#1/Phase 3, #11). if (i != 1) { return false; }; let pseudo: str = stk[0].str; let delta: i32 = -1; - if (streq(pseudo, "ptr")) { delta = 0; } - else { if (streq(pseudo, "len")) { delta = 8; } - else { if (streq(pseudo, "cap")) { delta = 16; }; }; }; + if (syntax.streq(pseudo, "ptr")) { delta = 0; } + else { if (syntax.streq(pseudo, "len")) { delta = 8; } + else { if (syntax.streq(pseudo, "cap")) { delta = 16; }; }; }; if (delta < 0) { return false; }; *outtotaloff = *outtotaloff + foff; *outslicedelta = delta; return true; }; - if (ft.kind == tykind.TY_SLICE) { + if (ft.kind == syntax.tykind.TY_SLICE) { if (i != 1) { return false; }; let pseudo: str = stk[0].str; let delta: i32 = -1; - if (streq(pseudo, "ptr")) { delta = 0; } - else { if (streq(pseudo, "len")) { delta = 8; } - else { if (streq(pseudo, "cap")) { delta = 16; }; }; }; + if (syntax.streq(pseudo, "ptr")) { delta = 0; } + else { if (syntax.streq(pseudo, "len")) { delta = 8; } + else { if (syntax.streq(pseudo, "cap")) { delta = 16; }; }; }; if (delta < 0) { return false; }; *outtotaloff = *outtotaloff + foff; *outslicedelta = delta; return true; }; - if (ft.kind != tykind.TY_STRUCT) { return false; }; + if (ft.kind != syntax.tykind.TY_STRUCT) { return false; }; *outtotaloff = *outtotaloff + foff; curstruct = ft; i -= 1; @@ -5022,14 +5022,14 @@ export fn dotchainresolve(c: *cgen, n: *node, // byte-identically — cstage hasn't yet learned MOVW for fsz==2. Once // #13 aligns both stages, the dispatch can switch to fieldstoreop // which already returns MOVW where appropriate. -fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, +fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *syntax.node, mode: i32, srcoff: i32, srcname: str, disp: i32) void = { if (si == nil) { return; }; let basereg: str = "BP"; if (mode != 0) { basereg = "BX"; }; let totsize: i32 = structabisize(si); - if (lit.op == tkind.TK_ELLIPSIS) { + if (lit.op == syntax.tkind.TK_ELLIPSIS) { // `..., ...` autofill — zero the entire slot first so // unmentioned fields read as 0. Sized stores: 8/4/1. For // non-BP modes, reload BX once before the loop (cgexpr-free @@ -5080,14 +5080,14 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, zi += 1; }; }; - let fieldnode: *node = lit.list; + let fieldnode: *syntax.node = lit.list; for (fieldnode != nil) { - if (fieldnode.kind == nkind.N_FIELD) { + if (fieldnode.kind == syntax.nkind.N_FIELD) { let fname: str = fieldnode.str; let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fname)) { + if (syntax.streq(fn_, fname)) { // Tagged-union field: delegate to the shared // widening writer (handles str/scalar/struct // literal/ident payload + tagged-subset tag @@ -5104,7 +5104,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, emitsymname(c, srcname); emitline("(SB), BX\n"); }; - cgwidentaggedstore(c, fi.tnode.type_: *tinfo, + cgwidentaggedstore(c, fi.tnode.type_: *syntax.tinfo, fieldnode.lhs, basereg, disp + fi.foff, fi.fsz); fi = nil; @@ -5116,9 +5116,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // the rest silently stayed zero. let nested: bool = false; if (fieldnode.lhs != nil) { - if (fieldnode.lhs.kind == nkind.N_STRUCTLIT) { + if (fieldnode.lhs.kind == syntax.nkind.N_STRUCTLIT) { if (fi.tnode != nil) { - if (fi.tnode.kind == nkind.N_TNAME) { + if (fi.tnode.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, fi.tnode.str) == 0) { let isi: *structinfo = structlookup(c, fi.tnode.str); if (isi != nil) { @@ -5162,9 +5162,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, let callwhole: bool = false; if (!nested) { if (fieldnode.lhs != nil) { - if (fieldnode.lhs.kind == nkind.N_CALL) { + if (fieldnode.lhs.kind == syntax.nkind.N_CALL) { if (fi.tnode != nil) { - if (fi.tnode.kind == nkind.N_TNAME) { + if (fi.tnode.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, fi.tnode.str) == 0) { let csi: *structinfo = structlookup(c, fi.tnode.str); if (csi != nil) { @@ -5293,9 +5293,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, }; fi = nil; } else if (fi.tnode != nil - && fi.tnode.kind == nkind.N_TARRAY + && fi.tnode.kind == syntax.nkind.N_TARRAY && fieldnode.lhs != nil - && fieldnode.lhs.kind == nkind.N_ARRLIT) { + && fieldnode.lhs.kind == syntax.nkind.N_ARRLIT) { // #249: array field from an N_ARRLIT. Without this // the generic tail below cgexprs the N_ARRLIT (→ AX) // and stores one sized word, silently DROPPING every @@ -5305,7 +5305,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // str/slice/struct/tagged elements are the N_LET // multi-word gap — loud rule-7 error (cstage // cg_structlit_fill twin). - let elemn: *node = fi.tnode.lhs; + let elemn: *syntax.node = fi.tnode.lhs; let isstrel: bool = isstrtype(c, elemn); let istagel: bool = istaggedtype(c, elemn); let issliceel: bool = isslicetype(c, elemn); @@ -5319,9 +5319,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // type_chase_named key (cgen.c:3179, B5-c1). let isstructel: bool = false; if (elemn != nil) { - let eu: *tinfo = tichase(elemn.type_: *tinfo); + let eu: *syntax.tinfo = tichase(elemn.type_: *syntax.tinfo); if (eu != nil) { - if (eu.kind == tykind.TY_STRUCT) { + if (eu.kind == syntax.tykind.TY_STRUCT) { isstructel = true; }; }; @@ -5336,7 +5336,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, }; let esz: i32 = 8; if (elemn != nil) { - if (elemn.kind == nkind.N_TNAME) { + if (elemn.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, elemn.str); if (ps > 0) { esz = ps; }; }; @@ -5347,11 +5347,11 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, if (isf32type(c, elemn)) { fmov = "MOVSS"; }; let idx: i32 = 0; let repeat: bool = false; - let e: *node = fieldnode.lhs.list; + let e: *syntax.node = fieldnode.lhs.list; for (e != nil) { let isellip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; isellip = true; }; @@ -5394,7 +5394,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, if (repeat) { let total: i32 = idx; if (fi.tnode.rhs != nil) { - if (fi.tnode.rhs.kind == nkind.N_INTLIT) { + if (fi.tnode.rhs.kind == syntax.nkind.N_INTLIT) { total = fi.tnode.rhs.uval: i32; }; }; @@ -5475,7 +5475,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, }; let agsz49: i32 = 0; if (fi.tnode != nil) { - let agti49: *tinfo = fi.tnode.type_: *tinfo; + let agti49: *syntax.tinfo = fi.tnode.type_: *syntax.tinfo; agti49 = tichase(agti49); if (agti49 != nil) { agsz49 = agti49.size: i32; }; }; @@ -5546,7 +5546,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // Thin wrapper preserving the BP-rel call shape used by cglet, // cgreturn, cgassign N_IDENT-lhs N_STRUCTLIT, and the C1.25 // @placescr materialise (cg_structlit_fill_bp's named twin). -fn cgstructlitfillbp(c: *cgen, si: *structinfo, lit: *node, bpoff: i32) void = { +fn cgstructlitfillbp(c: *cgen, si: *structinfo, lit: *syntax.node, bpoff: i32) void = { if (si == nil) { return; }; cgstructlitfill(c, si, lit, 0, 0, "", bpoff); }; diff --git a/selfhost/cmd/wcc/check.ww b/selfhost/cmd/wcc/check.ww index fb5f2771..00ffcfc9 100644 --- a/selfhost/cmd/wcc/check.ww +++ b/selfhost/cmd/wcc/check.ww @@ -24,24 +24,24 @@ import syntax; import strconv; type checker = struct { - tc: *tctx, - top: *scope, - cur: *scope, + tc: *syntax.tctx, + top: *syntax.scope, + cur: *syntax.scope, nresolved: i32, nunresolved: i32, errs: i32, istest: i32, // #15: `w6c_ww -T` — collect @test fns + // synth the entry; loud-reject a user main. verbose: i32, // when non-zero, log each unresolved name - fnret: *node, // enclosing fn's return type AST (for `?`) + fnret: *syntax.node, // enclosing fn's return type AST (for `?`) curmod: str, // importing-module bareword for the decl // currently being walked; "" for primary // compilation unit. Drives same-module // preference in bare-leaf lookups. - file: *node, // N_FILE root; used by checkmoduleshadow + file: *syntax.node, // N_FILE root; used by checkmoduleshadow // to consult the declaring source's own // `use` directives. - allococtx: *node, // #3/B': the one empty alloc([], n) call node + allococtx: *syntax.node, // #3/B': the one empty alloc([], n) call node // with let-declared slice context this walk; // any other empty alloc has no element hint // and must fail to infer (harec @@ -70,9 +70,9 @@ fn cerr(m: str) void = { // and every NAMED-chain chase loop downstream spun forever (the #69 // compiler hang); a struct-value cycle recursed the slot walkers to // stack overflow. -fn circularnamed(c: *checker, t: *tinfo, n: *node) bool = { +fn circularnamed(c: *checker, t: *syntax.tinfo, n: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != tykind.TY_NAMED) { return false; }; + if (t.kind != syntax.tykind.TY_NAMED) { return false; }; if (t.resolving == 0) { return false; }; if (n != nil) { cerr(n.file); cerr(": "); }; cerr("error: circular type dependency: '"); @@ -92,24 +92,24 @@ fn circularnamed(c: *checker, t: *tinfo, n: *node) bool = { // seedprimitives — install the built-in type names so `i32`, `str`, // etc. can be looked up like ordinary symbols. fn seedprimitives(c: *checker) void = { - scopedefine(c.top, "void", skind.SK_TYPE, c.tc.tyvoid, nil); - scopedefine(c.top, "bool", skind.SK_TYPE, c.tc.tybool, nil); - scopedefine(c.top, "rune", skind.SK_TYPE, c.tc.tyrune, nil); - scopedefine(c.top, "i8", skind.SK_TYPE, c.tc.tyi8, nil); - scopedefine(c.top, "i16", skind.SK_TYPE, c.tc.tyi16, nil); - scopedefine(c.top, "i32", skind.SK_TYPE, c.tc.tyi32, nil); - scopedefine(c.top, "i64", skind.SK_TYPE, c.tc.tyi64, nil); - scopedefine(c.top, "u8", skind.SK_TYPE, c.tc.tyu8, nil); - scopedefine(c.top, "u16", skind.SK_TYPE, c.tc.tyu16, nil); - scopedefine(c.top, "u32", skind.SK_TYPE, c.tc.tyu32, nil); - scopedefine(c.top, "u64", skind.SK_TYPE, c.tc.tyu64, nil); - scopedefine(c.top, "int", skind.SK_TYPE, c.tc.tyint, nil); - scopedefine(c.top, "uint", skind.SK_TYPE, c.tc.tyuint, nil); - scopedefine(c.top, "uintptr", skind.SK_TYPE, c.tc.tyuintptr, nil); - scopedefine(c.top, "f32", skind.SK_TYPE, c.tc.tyf32, nil); - scopedefine(c.top, "f64", skind.SK_TYPE, c.tc.tyf64, nil); - scopedefine(c.top, "str", skind.SK_TYPE, c.tc.tystr, nil); - scopedefine(c.top, "never", skind.SK_TYPE, c.tc.tynever, nil); + syntax.scopedefine(c.top, "void", syntax.skind.SK_TYPE, c.tc.tyvoid, nil); + syntax.scopedefine(c.top, "bool", syntax.skind.SK_TYPE, c.tc.tybool, nil); + syntax.scopedefine(c.top, "rune", syntax.skind.SK_TYPE, c.tc.tyrune, nil); + syntax.scopedefine(c.top, "i8", syntax.skind.SK_TYPE, c.tc.tyi8, nil); + syntax.scopedefine(c.top, "i16", syntax.skind.SK_TYPE, c.tc.tyi16, nil); + syntax.scopedefine(c.top, "i32", syntax.skind.SK_TYPE, c.tc.tyi32, nil); + syntax.scopedefine(c.top, "i64", syntax.skind.SK_TYPE, c.tc.tyi64, nil); + syntax.scopedefine(c.top, "u8", syntax.skind.SK_TYPE, c.tc.tyu8, nil); + syntax.scopedefine(c.top, "u16", syntax.skind.SK_TYPE, c.tc.tyu16, nil); + syntax.scopedefine(c.top, "u32", syntax.skind.SK_TYPE, c.tc.tyu32, nil); + syntax.scopedefine(c.top, "u64", syntax.skind.SK_TYPE, c.tc.tyu64, nil); + syntax.scopedefine(c.top, "int", syntax.skind.SK_TYPE, c.tc.tyint, nil); + syntax.scopedefine(c.top, "uint", syntax.skind.SK_TYPE, c.tc.tyuint, nil); + syntax.scopedefine(c.top, "uintptr", syntax.skind.SK_TYPE, c.tc.tyuintptr, nil); + syntax.scopedefine(c.top, "f32", syntax.skind.SK_TYPE, c.tc.tyf32, nil); + syntax.scopedefine(c.top, "f64", syntax.skind.SK_TYPE, c.tc.tyf64, nil); + syntax.scopedefine(c.top, "str", syntax.skind.SK_TYPE, c.tc.tystr, nil); + syntax.scopedefine(c.top, "never", syntax.skind.SK_TYPE, c.tc.tynever, nil); // #29: predeclare `type nomem = !void;` so user code needn't // declare it locally. Synthesize an nkind.N_TYPEDECL whose lhs is // nkind.N_TBANG{nkind.N_TNAME("void")} so varianterr and other @@ -119,34 +119,34 @@ fn seedprimitives(c: *checker) void = { // separate alias chain — see collectaliases in cgen.ww for the // companion seed. let empty: str; - let tnvoid: *node = newnode(nkind.N_TNAME, empty, 0, 0); + let tnvoid: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, empty, 0, 0); tnvoid.str = "void"; - let bang: *node = newnode(nkind.N_TBANG, empty, 0, 0); + let bang: *syntax.node = syntax.newnode(syntax.nkind.N_TBANG, empty, 0, 0); bang.lhs = tnvoid; - let nomemdecl: *node = newnode(nkind.N_TYPEDECL, empty, 0, 0); + let nomemdecl: *syntax.node = syntax.newnode(syntax.nkind.N_TYPEDECL, empty, 0, 0); nomemdecl.str = "nomem"; nomemdecl.lhs = bang; - scopedefine(c.top, "nomem", skind.SK_TYPE, nil, nomemdecl); + syntax.scopedefine(c.top, "nomem", syntax.skind.SK_TYPE, nil, nomemdecl); // `nil`, `true`, `false` are keywords — handled at the lex/parser // level, no symbol needed. // `len`, `alloc`, `free`, `append`, `delete`, `insert` are // pseudo-builtins; scopedefine them so their use sites resolve. // The actual semantics live in cgen. - scopedefine(c.top, "len", skind.SK_FN, nil, nil); - scopedefine(c.top, "alloc", skind.SK_FN, nil, nil); - scopedefine(c.top, "free", skind.SK_FN, nil, nil); - scopedefine(c.top, "append", skind.SK_FN, nil, nil); - scopedefine(c.top, "delete", skind.SK_FN, nil, nil); - scopedefine(c.top, "insert", skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "len", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "alloc", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "free", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "append", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "delete", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "insert", syntax.skind.SK_FN, nil, nil); // #42: typed builtins folded to integer literals at check time — // `size(T)` / `align(T)` (arg is a type-expression planted by the // parser at lib/ww/parse/expr.ww:254-267) and `offset(e.f)` (arg is // an N_DOT). exprtype intercepts these and rewrites the N_CALL to // N_INTLIT so cgen never sees an unresolved size/align/offset symbol. // Mirrors cmd/wcc/check.c:907-955. - scopedefine(c.top, "size", skind.SK_FN, nil, nil); - scopedefine(c.top, "align", skind.SK_FN, nil, nil); - scopedefine(c.top, "offset", skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "size", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "align", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "offset", syntax.skind.SK_FN, nil, nil); }; // declmod — module-tag stamp for a top-level decl. @@ -157,19 +157,19 @@ fn seedprimitives(c: *checker) void = { // directive matches some `use IDENT;` bareword in this compilation // unit. Primary-file decls return "" so they coexist (mod="") with // imported decls of the same leaf name in scopelookupinmodule. -fn declmod(file: *node, d: *node) str = { +fn declmod(file: *syntax.node, d: *syntax.node) str = { let empty: str; if (d == nil) { return empty; }; if (d.nmod.len == 0) { return empty; }; if (file == nil) { return empty; }; - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { // M1 #22: a decl is imported iff some `use` directive's full // dotted import path equals the decl's module (now the path). // Single-level packages have usepath == leaf so this is // unchanged; nested (`encoding.utf8`) match here, not on leaf. - if (u.kind == nkind.N_USE) { - if (streq(u.usepath, d.nmod)) { return d.nmod; }; + if (u.kind == syntax.nkind.N_USE) { + if (syntax.streq(u.usepath, d.nmod)) { return d.nmod; }; }; u = u.next; }; @@ -181,14 +181,14 @@ fn declmod(file: *node, d: *node) str = { // module-qualified resolution and codegen hint (M1 #22). Single-level // packages have usepath == alias so the result is unchanged. The // current tree has one occurrence per leaf, so the map is unambiguous. -fn usepathfor(file: *node, alias: str) str = { +fn usepathfor(file: *syntax.node, alias: str) str = { let empty: str; if (file == nil) { return empty; }; if (alias.len == 0) { return empty; }; - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { - if (u.kind == nkind.N_USE) { - if (streq(u.str, alias)) { + if (u.kind == syntax.nkind.N_USE) { + if (syntax.streq(u.str, alias)) { if (u.usepath.len != 0) { return u.usepath; }; return u.str; }; @@ -210,19 +210,19 @@ fn modkeyfor(c: *checker, alias: str) str = { // `modtag` carry `use ;`? Mirrors cstage's src_imports — // `modtag.len == 0` means primary, matching declmod's empty-str // return for primary-source decls. -fn srcimports(file: *node, modtag: str, name: str) bool = { +fn srcimports(file: *syntax.node, modtag: str, name: str) bool = { if (file == nil) { return false; }; if (name.len == 0) { return false; }; - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { - if (u.kind == nkind.N_USE) { + if (u.kind == syntax.nkind.N_USE) { // Skip self-imports: lib/fmt/fmttest.ww carries // `use fmt;` while its module tag is also "fmt". // That directive doesn't introduce a foreign // module bareword and lib/fmt's own // `fn bsprintf(fmt: str, ...)` is not a shadow. if (u.nmod.len > 0) { - if (streq(u.nmod, u.usepath)) { + if (syntax.streq(u.nmod, u.usepath)) { u = u.next; continue; }; @@ -231,9 +231,9 @@ fn srcimports(file: *node, modtag: str, name: str) bool = { let m: bool = false; if (modtag.len == 0) { if (um.len == 0) { m = true; }; - } else { if (streq(um, modtag)) { m = true; }; }; + } else { if (syntax.streq(um, modtag)) { m = true; }; }; if (m) { - if (streq(u.str, name)) { return true; }; + if (syntax.streq(u.str, name)) { return true; }; }; }; u = u.next; @@ -252,11 +252,11 @@ fn checkmoduleshadow(c: *checker, name: str, kindstr: str) void = { if (name.len == 0) { return; }; if (c.cur == c.top) { return; }; let seen: bool = false; - let s: *scope = c.cur; + let s: *syntax.scope = c.cur; for (s != nil) { - let r: *sym = scopelookuplocal(s, name); + let r: *syntax.sym = syntax.scopelookuplocal(s, name); if (r != nil) { - if (r.skind == skind.SK_USE) { + if (r.skind == syntax.skind.SK_USE) { seen = true; s = nil; }; @@ -300,9 +300,9 @@ fn checkmoduleshadow(c: *checker, name: str, kindstr: str) void = { // (cmd/wcc/check.c:2852/2911/2932/2955) — see dupdecl below. (Same-scope // LOCAL dup `let a=1; let a=2;` is a different path and stays deferred to // #11; test/wcc/708 + test/wcc/696 are that cstage-only neg-case.) -fn installdecl(c: *checker, file: *node, d: *node) void = { +fn installdecl(c: *checker, file: *syntax.node, d: *syntax.node) void = { if (d == nil) { return; }; - let k: nkind = d.kind; + let k: syntax.nkind = d.kind; let nm: str = d.str; let mod: str = declmod(file, d); // check-(c) self-import: a package may not import itself. Pure @@ -310,10 +310,10 @@ fn installdecl(c: *checker, file: *node, d: *node) void = { // unused + (b)/(d) membership DEFERRED to task #8 (filename-keyed // pulls lack import->file->symbol provenance). Message byte-identical // to cstage check.c. - if (k == nkind.N_USE) { + if (k == syntax.nkind.N_USE) { // M1 #22: self-import ⟺ the imported path equals the use's own // (owning) module path. Compares paths, not leaves. - if (mod.len != 0 && streq(d.usepath, mod)) { + if (mod.len != 0 && syntax.streq(d.usepath, mod)) { cerr("self-import: package '"); cerr(mod); cerr("' cannot import itself\n"); c.errs += 1i32; }; @@ -331,17 +331,17 @@ fn installdecl(c: *checker, file: *node, d: *node) void = { // (check.c:2823-2834 `if (prev) prev->use_alias = 1`). A pure // duplicate import (prev already SK_USE) keeps the coexisting- // entry path (orthogonal to #30, pre-existing wwstage behavior). - let prev: *sym = scopelookuplocal(c.top, nm); - if (prev != nil) { if (prev.skind != skind.SK_USE) { + let prev: *syntax.sym = syntax.scopelookuplocal(c.top, nm); + if (prev != nil) { if (prev.skind != syntax.skind.SK_USE) { prev.use_alias = 1i32; return; }; }; - scopedefine(c.top, nm, skind.SK_USE, nil, d); return; + syntax.scopedefine(c.top, nm, syntax.skind.SK_USE, nil, d); return; }; - if (k == nkind.N_DEF) { installtop(c, d, nm, mod, skind.SK_DEF, "def"); return; }; - if (k == nkind.N_TYPEDECL) { installtop(c, d, nm, mod, skind.SK_TYPE, "type"); return; }; - if (k == nkind.N_FNDECL) { installtop(c, d, nm, mod, skind.SK_FN, "fn"); return; }; - if (k == nkind.N_LET) { installtop(c, d, nm, mod, skind.SK_VAR, "let"); return; }; + if (k == syntax.nkind.N_DEF) { installtop(c, d, nm, mod, syntax.skind.SK_DEF, "def"); return; }; + if (k == syntax.nkind.N_TYPEDECL) { installtop(c, d, nm, mod, syntax.skind.SK_TYPE, "type"); return; }; + if (k == syntax.nkind.N_FNDECL) { installtop(c, d, nm, mod, syntax.skind.SK_FN, "fn"); return; }; + if (k == syntax.nkind.N_LET) { installtop(c, d, nm, mod, syntax.skind.SK_VAR, "let"); return; }; }; // installtop — install a top-level decl name into c.top, rejecting a @@ -365,7 +365,7 @@ fn installdecl(c: *checker, file: *node, d: *node) void = { // carrying no real source decl (primtypes: decl=nil; `nomem`: a // checkinit-synthesized N_TYPEDECL with an empty .file) — user decls // always carry their parsed source file. -fn installtop(c: *checker, d: *node, nm: str, mod: str, k: skind, kind: str) void = { +fn installtop(c: *checker, d: *syntax.node, nm: str, mod: str, k: syntax.skind, kind: str) void = { // #30: a top-level value/type decl whose leaf ALSO names an imported // module PROMOTES that same-leaf SK_USE in place — one correctly-kinded // sym carrying use_alias=1, so bare refs (call/structlit/var) resolve to @@ -380,16 +380,16 @@ fn installtop(c: *checker, d: *node, nm: str, mod: str, k: skind, kind: str) voi // (set use_alias on the pre-installed value sym). Both directions reach // the identical single-sym end state, so cstage and wwstage agree on // every source order (#30). - let puse: *sym = scopelookuplocal(c.top, nm); - if (puse != nil) { if (puse.skind == skind.SK_USE) { + let puse: *syntax.sym = syntax.scopelookuplocal(c.top, nm); + if (puse != nil) { if (puse.skind == syntax.skind.SK_USE) { puse.skind = k; puse.decl = d; puse.use_alias = 1i32; if (mod.len > 0) { if (puse.mod.len == 0) { puse.mod = mod; }; }; return; }; }; - if (scopedefineinmodule(c.top, nm, mod, k, nil, d) != nil) { return; }; - let prev: *sym = scopesamekeysym(c.top, nm, mod); + if (syntax.scopedefineinmodule(c.top, nm, mod, k, nil, d) != nil) { return; }; + let prev: *syntax.sym = syntax.scopesamekeysym(c.top, nm, mod); if (prev != nil) { if (prev.decl == nil) { return; }; if (prev.decl.file.len == 0) { return; }; @@ -421,26 +421,26 @@ fn installtop(c: *checker, d: *node, nm: str, mod: str, k: skind, kind: str) voi // empty-str N_IDENT with no decl to read a type back from): harec drops // `_` yet still advances the tuple slot, so that slot's element type is // the honest type to stamp — `_` is UNBOUND, not UNTYPED. -fn stamptuplebinds(c: *checker, binds: *node, elems: *node, +fn stamptuplebinds(c: *checker, binds: *syntax.node, elems: *syntax.node, define: bool, what: str) void = { - let b: *node = binds; - let pt: *node = elems; + let b: *syntax.node = binds; + let pt: *syntax.node = elems; for (b != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (pt != nil) { et = pt.lhs; }; if (define) { if (b.lhs == nil) { b.lhs = et; }; let bnm: str = b.str; if (bnm.len > 0) { checkmoduleshadow(c, bnm, what); - scopedefine(c.cur, bnm, skind.SK_VAR, nil, b); + syntax.scopedefine(c.cur, bnm, syntax.skind.SK_VAR, nil, b); }; }; if (b.type_ == nil) { - let src: *node = b.lhs; + let src: *syntax.node = b.lhs; if (src == nil) { src = et; }; if (src != nil) { - let ti: *tinfo = tinfofornode(c, src); + let ti: *syntax.tinfo = tinfofornode(c, src); if (ti != nil) { b.type_ = ti: *void; }; }; }; @@ -457,27 +457,27 @@ fn stamptuplebinds(c: *checker, binds: *node, elems: *node, // the C checker's collect-then-resolve flow within a function). // Also runs the typed checks (match exhaustiveness, ? subset) in // the same pass — they need the same scope state. -fn resolvewalk(c: *checker, n: *node) void = { +fn resolvewalk(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; // Typed checks fire on the way down so the scrutinee/operand // is examined before the arm bodies install new bindings. - if (k == nkind.N_MATCH) { checkmatchexhaust(c, n); }; - if (k == nkind.N_TRYPROP) { checktryprop(c, n); }; - if (k == nkind.N_TRYUNW) { checktryprop(c, n); }; - if (k == nkind.N_TYPETEST) { checkisas(c, n); }; - if (k == nkind.N_TYPEASSERT) { checkisas(c, n); }; - if (k == nkind.N_LET) { checkletassign(c, n); }; - if (k == nkind.N_RETURN) { checkretassign(c, n); }; + if (k == syntax.nkind.N_MATCH) { checkmatchexhaust(c, n); }; + if (k == syntax.nkind.N_TRYPROP) { checktryprop(c, n); }; + if (k == syntax.nkind.N_TRYUNW) { checktryprop(c, n); }; + if (k == syntax.nkind.N_TYPETEST) { checkisas(c, n); }; + if (k == syntax.nkind.N_TYPEASSERT) { checkisas(c, n); }; + if (k == syntax.nkind.N_LET) { checkletassign(c, n); }; + if (k == syntax.nkind.N_RETURN) { checkretassign(c, n); }; // `use IDENT;` — name is a module label, not a free ident. - if (k == nkind.N_USE) { return; }; + if (k == syntax.nkind.N_USE) { return; }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { let nm: str = n.str; if (nm.len > 0) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, nm); if (s == nil) { // Unshadowed abort/assert binds no sym BY // DESIGN (the EXPR_ASSERT family has no callee @@ -498,10 +498,10 @@ fn resolvewalk(c: *checker, n: *node) void = { }; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = n.str; if (nm.len > 0) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, nm); // `pkg.Type` — strip the last dot prefix and look up // the leaf with a mod filter so same-leaf-name types // from different imports (`bufio.stream` vs @@ -517,12 +517,12 @@ fn resolvewalk(c: *checker, n: *node) void = { let head: str; head.ptr = nm.ptr; head.len = dot; - let m: *sym = scopelookup(c.cur, head); + let m: *syntax.sym = syntax.scopelookup(c.cur, head); if (m != nil) { let leaf: str; leaf.ptr = nm.ptr + (dot + 1): u64; leaf.len = nm.len - (dot + 1); - s = scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); + s = syntax.scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); }; }; }; @@ -549,7 +549,7 @@ fn resolvewalk(c: *checker, n: *node) void = { // only by wwdump_ww as a diagnostic, so silent-accept here avoids // false-positives on legal cross-block shadow until #11 adds the // scoping infrastructure. - if (k == nkind.N_FORRANGE) { + if (k == syntax.nkind.N_FORRANGE) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; if (n.list != nil) { // Tuple destructure `for (let (a,b) .. xs)`: peel the @@ -557,13 +557,13 @@ fn resolvewalk(c: *checker, n: *node) void = { // element types onto the binders, the same lockstep walk // harec runs for the for-each header // (ref/harec/src/check.c:2308-2317 → create_unpack_bindings). - let elems: *node = nil; - let it: *node = exprtype(c, n.lhs, nil); + let elems: *syntax.node = nil; + let it: *syntax.node = exprtype(c, n.lhs, nil); if (it != nil) { - let et: *node = nil; - if (it.kind == nkind.N_TSLICE) { et = it.lhs; }; - if (it.kind == nkind.N_TARRAY) { et = it.lhs; }; - if (et != nil) { if (et.kind == nkind.N_TTUPLE) { + let et: *syntax.node = nil; + if (it.kind == syntax.nkind.N_TSLICE) { et = it.lhs; }; + if (it.kind == syntax.nkind.N_TARRAY) { et = it.lhs; }; + if (et != nil) { if (et.kind == syntax.nkind.N_TTUPLE) { elems = et.list; }; }; }; @@ -585,8 +585,8 @@ fn resolvewalk(c: *checker, n: *node) void = { // `b.lhs = et` idiom. A str scrutinee keeps the // old decl: cgen synthesises the u8 elem there // and no dot applies to a u8 binding. - let et: *node = nil; - let it: *node = exprtype(c, n.lhs, nil); + let et: *syntax.node = nil; + let it: *syntax.node = exprtype(c, n.lhs, nil); // #80 (F2a batch-4 c4): an alias-typed iterable // arrives as N_TNAME — without the AST-level // dealias the binder fell to the N_FORRANGE @@ -595,16 +595,16 @@ fn resolvewalk(c: *checker, n: *node) void = { // accepts: its scope_define types the elem). if (it != nil) { it = resolvealias(c, unwrapbang(it)); }; if (it != nil) { - if (it.kind == nkind.N_TSLICE) { et = it.lhs; }; - if (it.kind == nkind.N_TARRAY) { et = it.lhs; }; + if (it.kind == syntax.nkind.N_TSLICE) { et = it.lhs; }; + if (it.kind == syntax.nkind.N_TARRAY) { et = it.lhs; }; }; if (et != nil) { - let bn: *node = newnode(nkind.N_LET, n.file, n.line, n.col); + let bn: *syntax.node = syntax.newnode(syntax.nkind.N_LET, n.file, n.line, n.col); bn.str = bnm; bn.lhs = et; - scopedefine(c.cur, bnm, skind.SK_VAR, nil, bn); + syntax.scopedefine(c.cur, bnm, syntax.skind.SK_VAR, nil, bn); } else { - scopedefine(c.cur, bnm, skind.SK_VAR, nil, n); + syntax.scopedefine(c.cur, bnm, syntax.skind.SK_VAR, nil, n); }; }; }; @@ -619,14 +619,14 @@ fn resolvewalk(c: *checker, n: *node) void = { // `let e: *T` (scopedefine drops same-scope dupes silently and // would leave references to `e` resolving to the outer type). // Mirrors cmd/wcc/check.c's newscope/saved-restore around cstmt. - if (k == nkind.N_MCASE) { + if (k == syntax.nkind.N_MCASE) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; - let outer: *scope = c.cur; - c.cur = newscope(outer); + let outer: *syntax.scope = c.cur; + c.cur = syntax.newscope(outer); let nm: str = n.str; if (nm.len > 0) { checkmoduleshadow(c, nm, "binding"); - scopedefine(c.cur, nm, skind.SK_VAR, nil, n); + syntax.scopedefine(c.cur, nm, syntax.skind.SK_VAR, nil, n); }; if (n.body != nil) { resolvewalk(c, n.body); }; c.cur = outer; @@ -642,10 +642,10 @@ fn resolvewalk(c: *checker, n: *node) void = { // becomes a false-positive on the next driver (`wwdump_ww -r` // flagged the u64→i32 pair in selfhost/cmd/ww/enumeratedir). // Mirrors cstage cstmt N_BLOCK at cmd/wcc/check.c:1559-1566. - if (k == nkind.N_BLOCK) { - let outer: *scope = c.cur; - c.cur = newscope(outer); - let m: *node = n.list; + if (k == syntax.nkind.N_BLOCK) { + let outer: *syntax.scope = c.cur; + c.cur = syntax.newscope(outer); + let m: *syntax.node = n.list; for (m != nil) { resolvewalk(c, m); m = m.next; @@ -679,9 +679,9 @@ fn resolvewalk(c: *checker, n: *node) void = { // their own type. Mirrors the N_FORRANGE binding-install shape above; // the bindings would otherwise install (unstamped) via the generic // N_LET walk, so this early return must register them itself. - if (k == nkind.N_MLET) { + if (k == syntax.nkind.N_MLET) { if (n.rhs != nil) { resolvewalk(c, n.rhs); }; - let pt: *node = nil; + let pt: *syntax.node = nil; // #242: consume the rhs's tuple type for ANY rhs, not just an // N_CALL — `let (a,b) = t` over a plain tuple ident (e.g. a // match-bound union payload) must stamp its bindings too, or @@ -690,8 +690,8 @@ fn resolvewalk(c: *checker, n: *node) void = { if (n.rhs != nil) { // `rt` would shadow the imported lib/rt module // (checkmoduleshadow errors); `rty` avoids it. - let rty: *node = exprtype(c, n.rhs, nil); - if (rty != nil) { if (rty.kind == nkind.N_TTUPLE) { + let rty: *syntax.node = exprtype(c, n.rhs, nil); + if (rty != nil) { if (rty.kind == syntax.nkind.N_TTUPLE) { pt = rty.list; }; }; }; @@ -706,13 +706,13 @@ fn resolvewalk(c: *checker, n: *node) void = { // still-nil slots, which is exactly the discard `_` (no decl, so the // N_IDENT exprtype path leaves it untyped). Distribution mirrors the // N_MLET/N_FORRANGE binders; see stamptuplebinds. - if (k == nkind.N_MASSIGN) { + if (k == syntax.nkind.N_MASSIGN) { if (n.rhs != nil) { resolvewalk(c, n.rhs); }; - let pt: *node = nil; + let pt: *syntax.node = nil; // #242: consume the rhs tuple type for ANY rhs (see N_MLET). if (n.rhs != nil) { - let rty: *node = exprtype(c, n.rhs, nil); - if (rty != nil && rty.kind == nkind.N_TTUPLE) { + let rty: *syntax.node = exprtype(c, n.rhs, nil); + if (rty != nil && rty.kind == syntax.nkind.N_TTUPLE) { pt = rty.list; } else { // #38/F2 (review item 39): the multi-assign rhs must be a @@ -728,29 +728,29 @@ fn resolvewalk(c: *checker, n: *node) void = { deffolderr(c, n, "multi-assign rhs is not a tuple"); }; }; - let l: *node = n.list; + let l: *syntax.node = n.list; for (l != nil) { resolvewalk(c, l); l = l.next; }; stamptuplebinds(c, n.list, pt, false, ""); return; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // Walk only the base; the .field name is a member, not a // free identifier. if (n.lhs != nil) { resolvewalk(c, n.lhs); }; // A.6.0: branch returns early; stamp here so the post-walk // dispatch below sees N_DOT covered. exprtype N_DOT arm is // added in A.6.1; for now this is a no-op nil return. - let _t: *node = exprtype(c, n, nil); + let _t: *syntax.node = exprtype(c, n, nil); return; }; - if (k == nkind.N_FIELD) { + if (k == syntax.nkind.N_FIELD) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; return; }; - if (k == nkind.N_TFIELD) { + if (k == syntax.nkind.N_TFIELD) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; return; }; @@ -763,7 +763,7 @@ fn resolvewalk(c: *checker, n: *node) void = { if (n.body != nil) { resolvewalk(c, n.body); }; if (n.els != nil) { resolvewalk(c, n.els); }; if (n.list != nil) { - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { resolvewalk(c, m); m = m.next; @@ -776,19 +776,19 @@ fn resolvewalk(c: *checker, n: *node) void = { // user-defined aliases). Cgen's slotsize fast-path reads off // n.type_; uncovered shapes fall through to the cstage-mirror // walker until the next sub-commit graduates them. - if (k == nkind.N_TNAME || k == nkind.N_TPTR || - k == nkind.N_TSLICE || k == nkind.N_TCHAN || - k == nkind.N_TBANG || k == nkind.N_TARRAY || - k == nkind.N_TFN || k == nkind.N_TSTRUCT || - k == nkind.N_TTUPLE || k == nkind.N_TTAGGED || - k == nkind.N_TENUM) { + if (k == syntax.nkind.N_TNAME || k == syntax.nkind.N_TPTR || + k == syntax.nkind.N_TSLICE || k == syntax.nkind.N_TCHAN || + k == syntax.nkind.N_TBANG || k == syntax.nkind.N_TARRAY || + k == syntax.nkind.N_TFN || k == syntax.nkind.N_TSTRUCT || + k == syntax.nkind.N_TTUPLE || k == syntax.nkind.N_TTAGGED || + k == syntax.nkind.N_TENUM) { if (n.type_ == nil) { - let ti: *tinfo = tinfofornode(c, n); + let ti: *syntax.tinfo = tinfofornode(c, n); if (ti != nil) { n.type_ = ti: *void; }; }; }; - if (k == nkind.N_TENUM) { stampenumvals(c, n); }; + if (k == syntax.nkind.N_TENUM) { stampenumvals(c, n); }; // #42's size/align/offset fold trigger lived here pre-A.6.0; the // A.6.0 end-of-fn general dispatch (below) now fires exprtype on @@ -805,17 +805,17 @@ fn resolvewalk(c: *checker, n: *node) void = { // still silent-accepts here; promoting that to an error stays // queued behind #11 (test/wcc/708 + test/wcc/696 are the cstage- // only neg-case precedent). - if (k == nkind.N_LET) { + if (k == syntax.nkind.N_LET) { let nm: str = n.str; if (nm.len > 0) { checkmoduleshadow(c, nm, "let"); - let s: *sym = scopedefine(c.cur, nm, skind.SK_VAR, nil, n); + let s: *syntax.sym = syntax.scopedefine(c.cur, nm, syntax.skind.SK_VAR, nil, n); // catB-22: flag a `const` binding so checkassign can // reject a later reassignment. The parser stamps // n.op = TK_CONST (parse/stmt.ww). Mirror cstage // cmd/wcc/check.c:2408. if (s != nil) { - if (n.op == tkind.TK_CONST) { s.is_const = 1i32; }; + if (n.op == syntax.tkind.TK_CONST) { s.is_const = 1i32; }; }; }; }; @@ -828,8 +828,8 @@ fn resolvewalk(c: *checker, n: *node) void = { // / return only — see coercefloatlit's docstring for the rule-10 scope // (the cstage twin coerces in clet / cstmt N_RETURN). c.fnret is set // by resolvefnbody for the enclosing fn, mirroring checkretassign. - if (k == nkind.N_LET) { coercefloatlit(c, n.rhs, n.lhs); }; - if (k == nkind.N_RETURN) { coercefloatlit(c, n.lhs, c.fnret); }; + if (k == syntax.nkind.N_LET) { coercefloatlit(c, n.rhs, n.lhs); }; + if (k == syntax.nkind.N_RETURN) { coercefloatlit(c, n.lhs, c.fnret); }; // A.6.0: post-order dispatch of exprtype on every expression-yielding // node kind so n.type_ stamps fire universally — not only when reached @@ -852,24 +852,24 @@ fn resolvewalk(c: *checker, n: *node) void = { // exprtype below so a regular N_CALL is still an N_CALL (not folded to // an N_INTLIT by the size/align intercept). Mirrors cstage's post- // order cexpr desugar at the call-arg / N_ASSIGN sites. - if (k == nkind.N_CALL) { desugarcallargs(c, n); }; - if (k == nkind.N_ASSIGN) { checkassign(c, n); }; + if (k == syntax.nkind.N_CALL) { desugarcallargs(c, n); }; + if (k == syntax.nkind.N_ASSIGN) { checkassign(c, n); }; - if (k == nkind.N_INTLIT || k == nkind.N_FLOATLIT || - k == nkind.N_STRLIT || k == nkind.N_RUNELIT || - k == nkind.N_TRUE || k == nkind.N_FALSE || - k == nkind.N_NIL || k == nkind.N_VOIDLIT || - k == nkind.N_IDENT || k == nkind.N_BIN || - k == nkind.N_UN || k == nkind.N_CALL || - k == nkind.N_INDEX || k == nkind.N_CAST || - k == nkind.N_STRUCTLIT || k == nkind.N_ARRLIT || - k == nkind.N_RECV || - k == nkind.N_SLICE || k == nkind.N_SPREAD || - k == nkind.N_TUPLE || k == nkind.N_TRYPROP || - k == nkind.N_TRYUNW || k == nkind.N_TYPETEST || - k == nkind.N_TYPEASSERT || k == nkind.N_YIELD || - k == nkind.N_MATCH) { - let _t: *node = exprtype(c, n, nil); + if (k == syntax.nkind.N_INTLIT || k == syntax.nkind.N_FLOATLIT || + k == syntax.nkind.N_STRLIT || k == syntax.nkind.N_RUNELIT || + k == syntax.nkind.N_TRUE || k == syntax.nkind.N_FALSE || + k == syntax.nkind.N_NIL || k == syntax.nkind.N_VOIDLIT || + k == syntax.nkind.N_IDENT || k == syntax.nkind.N_BIN || + k == syntax.nkind.N_UN || k == syntax.nkind.N_CALL || + k == syntax.nkind.N_INDEX || k == syntax.nkind.N_CAST || + k == syntax.nkind.N_STRUCTLIT || k == syntax.nkind.N_ARRLIT || + k == syntax.nkind.N_RECV || + k == syntax.nkind.N_SLICE || k == syntax.nkind.N_SPREAD || + k == syntax.nkind.N_TUPLE || k == syntax.nkind.N_TRYPROP || + k == syntax.nkind.N_TRYUNW || k == syntax.nkind.N_TYPETEST || + k == syntax.nkind.N_TYPEASSERT || k == syntax.nkind.N_YIELD || + k == syntax.nkind.N_MATCH) { + let _t: *syntax.node = exprtype(c, n, nil); }; }; @@ -882,9 +882,9 @@ fn resolvewalk(c: *checker, n: *node) void = { // propagation, and !-flag semantics. // unwrapbang — strip an nkind.N_TBANG wrapper; leaves other nodes alone. -fn unwrapbang(n: *node) *node = { +fn unwrapbang(n: *syntax.node) *syntax.node = { if (n == nil) { return nil; }; - if (n.kind == nkind.N_TBANG) { return n.lhs; }; + if (n.kind == syntax.nkind.N_TBANG) { return n.lhs; }; return n; }; @@ -895,9 +895,9 @@ fn unwrapbang(n: *node) *node = { // decl sym (nominal identity = sym.type_ ptr-identity) instead of // flattening to the underlying. Mirrors cstage resolve_typename // (cmd/wcc/check.c:60-88), which returns the sym's NAMED, not the base. -fn aliassym(c: *checker, n: *node) *sym = { +fn aliassym(c: *checker, n: *syntax.node) *syntax.sym = { if (n == nil) { return nil; }; - if (n.kind != nkind.N_TNAME) { return nil; }; + if (n.kind != syntax.nkind.N_TNAME) { return nil; }; let nm: str = n.str; // #51: pkg.alias type refs land here as a single TNAME whose // str is the joined form (lib/ww/parse/parse.ww:258-265 in @@ -912,7 +912,7 @@ fn aliassym(c: *checker, n: *node) *sym = { if (nm[i] == 46u8) { dotidx = i; }; i += 1; }; - let s: *sym = nil; + let s: *syntax.sym = nil; if (dotidx >= 0) { let head: str; head.ptr = nm.ptr; @@ -920,7 +920,7 @@ fn aliassym(c: *checker, n: *node) *sym = { let leaf: str; leaf.ptr = nm.ptr + ((dotidx + 1): u64); leaf.len = nm.len - dotidx - 1; - s = scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); + s = syntax.scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); } else { // #53: same-module preference. Mirrors cstage // cmd/wcc/check.c:66 scope_lookup_prefer. Without this, @@ -933,7 +933,7 @@ fn aliassym(c: *checker, n: *node) *sym = { // scopelookupprefer (the #56/#4/#11a wave). The only bare-leaf // type lookups left — varianterr (:1051) + scruttype (:1098) — // stay mod-blind but have no reproducible divergence; #58. - s = scopelookupprefer(c.cur, c.curmod, nm); + s = syntax.scopelookupprefer(c.cur, c.curmod, nm); // #61 A.5: bare TNAME that collides with an imported // module bareword. Two shapes hit this: // - `let l: lex;` where `lex` struct lives in @@ -949,20 +949,20 @@ fn aliassym(c: *checker, n: *node) *sym = { // regardless of its declaring package. Mirrors the // bare-vs-qualified pattern from task #57. if (s != nil) { - if (s.skind != skind.SK_TYPE) { + if (s.skind != syntax.skind.SK_TYPE) { // #58/#50: prefer the curmod-matching SK_TYPE. // Two modules exporting the same type leaf (e.g. // utf8.invalid !void vs strconv.invalid !i32) // otherwise resolve install-order-dependent here // when a value binding shadows the leaf; cstage // passes c->cur_mod to scope_lookup_type (sym.c). - let sm: *sym = scopelookuptype(c.cur, c.curmod, nm); + let sm: *syntax.sym = syntax.scopelookuptype(c.cur, c.curmod, nm); if (sm != nil) { s = sm; }; }; }; }; if (s == nil) { return nil; }; - if (s.skind != skind.SK_TYPE) { return nil; }; + if (s.skind != syntax.skind.SK_TYPE) { return nil; }; return s; }; @@ -970,13 +970,13 @@ fn aliassym(c: *checker, n: *node) *sym = { // the typedecl's body (possibly recursively). Pass-through for any // other node. The chain stops once we hit a non-nkind.N_TNAME node or a // name we can't resolve. -fn resolvealias(c: *checker, n: *node) *node = { - let cur: *node = n; +fn resolvealias(c: *checker, n: *syntax.node) *syntax.node = { + let cur: *syntax.node = n; for (cur != nil) { - if (cur.kind != nkind.N_TNAME) { return cur; }; - let s: *sym = aliassym(c, cur); + if (cur.kind != syntax.nkind.N_TNAME) { return cur; }; + let s: *syntax.sym = aliassym(c, cur); if (s == nil) { return cur; }; - let body: *node = nil; + let body: *syntax.node = nil; if (s.decl != nil) { body = s.decl.lhs; }; if (body == nil) { return cur; }; cur = unwrapbang(body); @@ -992,9 +992,9 @@ fn resolvealias(c: *checker, n: *node) *node = { // bare `oserror` vs qualified `os.oserror` resolve to the SAME // SK_TYPE sym (aliassym maps both via #51/#53), so a cross-module // nominal forward compares equal where the surface streq said false. -fn typeeqast(c: *checker, a: *node, b: *node) bool = { - let aa: *node = unwrapbang(a); - let bb: *node = unwrapbang(b); +fn typeeqast(c: *checker, a: *syntax.node, b: *syntax.node) bool = { + let aa: *syntax.node = unwrapbang(a); + let bb: *syntax.node = unwrapbang(b); if (aa == nil) { return bb == nil; }; if (bb == nil) { return false; }; // Identity fast-path, mirroring cstage type_eq's first line @@ -1006,31 +1006,31 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // cstage accepts via this identity check. if (aa == bb) { return true; }; if (aa.kind != bb.kind) { return false; }; - let k: nkind = aa.kind; - if (k == nkind.N_TNAME) { - if (streq(aa.str, bb.str)) { return true; }; - let sa: *sym = aliassym(c, aa); - let sb: *sym = aliassym(c, bb); + let k: syntax.nkind = aa.kind; + if (k == syntax.nkind.N_TNAME) { + if (syntax.streq(aa.str, bb.str)) { return true; }; + let sa: *syntax.sym = aliassym(c, aa); + let sb: *syntax.sym = aliassym(c, bb); if (sa != nil && sa == sb) { return true; }; return false; }; - if (k == nkind.N_TPTR) { return typeeqast(c, aa.lhs, bb.lhs); }; - if (k == nkind.N_TSLICE){ return typeeqast(c, aa.lhs, bb.lhs); }; - if (k == nkind.N_TCHAN) { return typeeqast(c, aa.lhs, bb.lhs); }; - if (k == nkind.N_TFN) { + if (k == syntax.nkind.N_TPTR) { return typeeqast(c, aa.lhs, bb.lhs); }; + if (k == syntax.nkind.N_TSLICE){ return typeeqast(c, aa.lhs, bb.lhs); }; + if (k == syntax.nkind.N_TCHAN) { return typeeqast(c, aa.lhs, bb.lhs); }; + if (k == syntax.nkind.N_TFN) { // Divergence: cstage type.c:239 compares resolved Type; we // compare AST. See #178. if (!typeeqast(c, aa.lhs, bb.lhs)) { return false; }; - let pa: *node = aa.list; - let pb: *node = bb.list; + let pa: *syntax.node = aa.list; + let pb: *syntax.node = bb.list; for (pa != nil) { if (pb == nil) { return false; }; - let ac: bool = streq(pa.str, "..."); - let bc: bool = streq(pb.str, "..."); + let ac: bool = syntax.streq(pa.str, "..."); + let bc: bool = syntax.streq(pb.str, "..."); if (ac != bc) { return false; }; if (!ac) { - let va: bool = pa.op == tkind.TK_ELLIPSIS; - let vb: bool = pb.op == tkind.TK_ELLIPSIS; + let va: bool = pa.op == syntax.tkind.TK_ELLIPSIS; + let vb: bool = pb.op == syntax.tkind.TK_ELLIPSIS; if (va != vb) { return false; }; if (!typeeqast(c, pa.lhs, pb.lhs)) { return false; }; }; @@ -1046,9 +1046,9 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // would confidently reject a bare-&fn into a structural `*fn(...)` // slot (test 766 fn_tuple_return). Elements are N_TPARAM-wrapped // (parse.ww:302-318), so compare each link's .lhs. - if (k == nkind.N_TTUPLE) { - let pa: *node = aa.list; - let pb: *node = bb.list; + if (k == syntax.nkind.N_TTUPLE) { + let pa: *syntax.node = aa.list; + let pb: *syntax.node = bb.list; for (pa != nil) { if (pb == nil) { return false; }; if (!typeeqast(c, pa.lhs, pb.lhs)) { return false; }; @@ -1067,9 +1067,9 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // Divergence: cstage's nullable-flag check (type.c:293) is a resolved- // Type property with no AST analogue; for case-match both sides share // a spelling so it's moot — no phantom AST nullable check. - if (k == nkind.N_TTAGGED) { - let pa: *node = aa.list; - let pb: *node = bb.list; + if (k == syntax.nkind.N_TTAGGED) { + let pa: *syntax.node = aa.list; + let pb: *syntax.node = bb.list; for (pa != nil) { if (pb == nil) { return false; }; // #115: a `...inner` spread variant stays unflattened at @@ -1080,8 +1080,8 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // match a plain `ab`, accepting a case cstage rejects. // Conservatively loud-reject any spread until the flatten // lands; b1c's (void|size) has none, so byte-id is untouched. - if (pa.op == tkind.TK_ELLIPSIS) { return false; }; - if (pb.op == tkind.TK_ELLIPSIS) { return false; }; + if (pa.op == syntax.tkind.TK_ELLIPSIS) { return false; }; + if (pb.op == syntax.tkind.TK_ELLIPSIS) { return false; }; if (!typeeqast(c, pa, pb)) { return false; }; pa = pa.next; pb = pb.next; @@ -1097,20 +1097,20 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // varianterr — does this variant carry the `!` mark? Either // the variant itself is nkind.N_TBANG or it's an alias whose typedecl // body is `!T`. Mirrors C check.c's iserror-after-NAMED rule. -fn varianterr(c: *checker, v: *node) bool = { +fn varianterr(c: *checker, v: *syntax.node) bool = { if (v == nil) { return false; }; - if (v.kind == nkind.N_TBANG) { return true; }; - if (v.kind == nkind.N_TNAME) { + if (v.kind == syntax.nkind.N_TBANG) { return true; }; + if (v.kind == syntax.nkind.N_TNAME) { // #58: mod-blind by leaf — latent. A same-leaf error-vs-plain // type pair across two modules could in principle flip iserror, // but the union's variants resolve at its declaration before // varianterr runs, so no repro exists. Tracked: #58. - let s: *sym = scopelookup(c.cur, v.str); + let s: *syntax.sym = syntax.scopelookup(c.cur, v.str); if (s != nil) { - if (s.skind == skind.SK_TYPE) { + if (s.skind == syntax.skind.SK_TYPE) { if (s.decl != nil) { if (s.decl.lhs != nil) { - if (s.decl.lhs.kind == nkind.N_TBANG) { + if (s.decl.lhs.kind == syntax.nkind.N_TBANG) { return true; }; }; @@ -1124,8 +1124,8 @@ fn varianterr(c: *checker, v: *node) bool = { // taggedhaserr — true iff any variant of `n` (assumed // nkind.N_TTAGGED) is `!`-marked. Picks the explicit-flag semantics over // the legacy "first variant = success" rule. -fn taggedhaserr(c: *checker, n: *node) bool = { - let v: *node = n.list; +fn taggedhaserr(c: *checker, n: *syntax.node) bool = { + let v: *syntax.node = n.list; for (v != nil) { if (varianterr(c, v)) { return true; }; v = v.next; @@ -1136,7 +1136,7 @@ fn taggedhaserr(c: *checker, n: *node) bool = { // iserrvariant — under flag-aware mode (any !-marked variant), // returns true iff `v` is `!`-marked. Under legacy mode (no flags), // returns true iff `v` is not the first variant of `tagged`. -fn iserrvariant(c: *checker, tagged: *node, v: *node) bool = { +fn iserrvariant(c: *checker, tagged: *syntax.node, v: *syntax.node) bool = { if (taggedhaserr(c, tagged)) { return varianterr(c, v); }; @@ -1149,14 +1149,14 @@ fn iserrvariant(c: *checker, tagged: *node, v: *node) bool = { // scrutinee. Handles nkind.N_IDENT (look up local/param's declared // type) and nkind.N_DOT (module-qualified ref). Returns nil if we // can't statically determine the type. Used by exhaustiveness. -fn scruttype(c: *checker, e: *node) *node = { +fn scruttype(c: *checker, e: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - if (e.kind == nkind.N_IDENT) { + if (e.kind == syntax.nkind.N_IDENT) { // #58: mod-blind by leaf — lenient-only. Feeds match // exhaustiveness; codegen reads the stamped n.type_, so a // mis-resolution cannot drive a wrong binary (no repro). // Tracked: #58. - let s: *sym = scopelookup(c.cur, e.str); + let s: *syntax.sym = syntax.scopelookup(c.cur, e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; // For nkind.N_LET / nkind.N_PARAM: declared type is decl.lhs. @@ -1168,10 +1168,10 @@ fn scruttype(c: *checker, e: *node) *node = { // shape resolvealias' dotted-name branch now consumes. Falls // silently to nil when lhs is a value (struct-field access) — // the rest of the lenient-check contract. - if (e.kind == nkind.N_DOT) { + if (e.kind == syntax.nkind.N_DOT) { if (e.lhs == nil) { return nil; }; - if (e.lhs.kind != nkind.N_IDENT) { return nil; }; - let s: *sym = scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.str), e.str); + if (e.lhs.kind != syntax.nkind.N_IDENT) { return nil; }; + let s: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.str), e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; return s.decl.lhs; @@ -1182,8 +1182,8 @@ fn scruttype(c: *checker, e: *node) *node = { // mktname — fabricate an nkind.N_TNAME node with str = `nm`. Used by // exprtype to return primitive type nodes for literal // expressions. The arena keeps them around as long as the checker. -fn mktname(c: *checker, nm: str) *node = { - let n: *node = newnode(nkind.N_TNAME, "", 0, 0); +fn mktname(c: *checker, nm: str) *syntax.node = { + let n: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, "", 0, 0); n.str = nm; return n; }; @@ -1195,16 +1195,16 @@ fn mktname(c: *checker, nm: str) *node = { // names; callers fall back to alias/struct/enum lookup. Cstage's // equivalent SSoT is cmd/wcc/type.c:46-79 (ty_void/ty_bool/.../ty_str). fn primtypesize(nm: str) i64 = { - if (streq(nm, "void")) { return 0i64; }; - if (streq(nm, "bool")) { return 1i64; }; - if (streq(nm, "i8") || streq(nm, "u8")) { return 1i64; }; - if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; }; - if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; }; - if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64")) { return 8i64; }; - if (streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr") || streq(nm, "size")) { return 8i64; }; + if (syntax.streq(nm, "void")) { return 0i64; }; + if (syntax.streq(nm, "bool")) { return 1i64; }; + if (syntax.streq(nm, "i8") || syntax.streq(nm, "u8")) { return 1i64; }; + if (syntax.streq(nm, "i16") || syntax.streq(nm, "u16")) { return 2i64; }; + if (syntax.streq(nm, "i32") || syntax.streq(nm, "u32") || syntax.streq(nm, "f32") || syntax.streq(nm, "rune")) { return 4i64; }; + if (syntax.streq(nm, "i64") || syntax.streq(nm, "u64") || syntax.streq(nm, "f64")) { return 8i64; }; + if (syntax.streq(nm, "int") || syntax.streq(nm, "uint") || syntax.streq(nm, "uintptr") || syntax.streq(nm, "size")) { return 8i64; }; // str IS []u8: 24B, sourced from the slice header SSoT so str and // []u8 can never drift; no second hardcoded 24 (#1/Phase 3). - if (streq(nm, "str")) { return tyslicesize(); }; + if (syntax.streq(nm, "str")) { return tyslicesize(); }; return -1i64; }; @@ -1219,27 +1219,27 @@ fn tyslicesize() i64 = { return 24i64; }; // sizelint-ok: SSoT for ty_slice head // materialises tinfo for user types so the fold has to walk the AST // directly. Struct layout follows cstage check.c:471-526 (align each // field, max align for the whole record, round size up to alignment). -fn astalign(c: *checker, t: *node) i64 = { +fn astalign(c: *checker, t: *syntax.node) i64 = { if (t == nil) { return 1i64; }; - let k: nkind = t.kind; - if (k == nkind.N_TBANG) { return astalign(c, t.lhs); }; - if (k == nkind.N_TPTR) { return 8i64; }; - if (k == nkind.N_TSLICE) { return 8i64; }; - if (k == nkind.N_TCHAN) { return 8i64; }; - if (k == nkind.N_TFN) { return 8i64; }; - if (k == nkind.N_TARRAY) { return astalign(c, t.lhs); }; - if (k == nkind.N_TTAGGED) { + let k: syntax.nkind = t.kind; + if (k == syntax.nkind.N_TBANG) { return astalign(c, t.lhs); }; + if (k == syntax.nkind.N_TPTR) { return 8i64; }; + if (k == syntax.nkind.N_TSLICE) { return 8i64; }; + if (k == syntax.nkind.N_TCHAN) { return 8i64; }; + if (k == syntax.nkind.N_TFN) { return 8i64; }; + if (k == syntax.nkind.N_TARRAY) { return astalign(c, t.lhs); }; + if (k == syntax.nkind.N_TTAGGED) { // Route through the normalization SSoT: a lone survivor // collapses (align((i32|never))==align(i32)==4, not the tag // word's 8), matching cstage align() reading resolve_type(...) // ->align (cmd/wcc/check.c:1550). Same #1 family as astsize. - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { return ti.align: i64; }; return 8i64; }; - if (k == nkind.N_TTUPLE) { + if (k == syntax.nkind.N_TTUPLE) { let m: i64 = 1i64; - let p: *node = t.list; + let p: *syntax.node = t.list; for (p != nil) { let pa: i64 = astalign(c, p.lhs); if (pa > m) { m = pa; }; @@ -1247,11 +1247,11 @@ fn astalign(c: *checker, t: *node) i64 = { }; return m; }; - if (k == nkind.N_TSTRUCT) { + if (k == syntax.nkind.N_TSTRUCT) { let m: i64 = 1i64; - let f: *node = t.list; + let f: *syntax.node = t.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { let fa: i64 = astalign(c, f.lhs); if (fa > m) { m = fa; }; }; @@ -1259,17 +1259,17 @@ fn astalign(c: *checker, t: *node) i64 = { }; return m; }; - if (k == nkind.N_TENUM) { + if (k == syntax.nkind.N_TENUM) { if (t.lhs != nil) { return astalign(c, t.lhs); }; return 4i64; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; - if (streq(nm, "void") || streq(nm, "bool") || streq(nm, "i8") || streq(nm, "u8")) { return 1i64; }; - if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; }; - if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; }; - if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64") || streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr") || streq(nm, "size") || streq(nm, "str")) { return 8i64; }; - let resolved: *node = resolvealias(c, t); + if (syntax.streq(nm, "void") || syntax.streq(nm, "bool") || syntax.streq(nm, "i8") || syntax.streq(nm, "u8")) { return 1i64; }; + if (syntax.streq(nm, "i16") || syntax.streq(nm, "u16")) { return 2i64; }; + if (syntax.streq(nm, "i32") || syntax.streq(nm, "u32") || syntax.streq(nm, "f32") || syntax.streq(nm, "rune")) { return 4i64; }; + if (syntax.streq(nm, "i64") || syntax.streq(nm, "u64") || syntax.streq(nm, "f64") || syntax.streq(nm, "int") || syntax.streq(nm, "uint") || syntax.streq(nm, "uintptr") || syntax.streq(nm, "size") || syntax.streq(nm, "str")) { return 8i64; }; + let resolved: *syntax.node = resolvealias(c, t); if (resolved != nil && resolved != t) { return astalign(c, resolved); }; @@ -1277,38 +1277,38 @@ fn astalign(c: *checker, t: *node) i64 = { return 1i64; }; -fn astsize(c: *checker, t: *node) i64 = { +fn astsize(c: *checker, t: *syntax.node) i64 = { if (t == nil) { return 0i64; }; - let k: nkind = t.kind; - if (k == nkind.N_TBANG) { return astsize(c, t.lhs); }; - if (k == nkind.N_TPTR) { return 8i64; }; - if (k == nkind.N_TSLICE) { return tyslicesize(); }; - if (k == nkind.N_TCHAN) { return 8i64; }; - if (k == nkind.N_TFN) { return 8i64; }; - if (k == nkind.N_TARRAY) { + let k: syntax.nkind = t.kind; + if (k == syntax.nkind.N_TBANG) { return astsize(c, t.lhs); }; + if (k == syntax.nkind.N_TPTR) { return 8i64; }; + if (k == syntax.nkind.N_TSLICE) { return tyslicesize(); }; + if (k == syntax.nkind.N_TCHAN) { return 8i64; }; + if (k == syntax.nkind.N_TFN) { return 8i64; }; + if (k == syntax.nkind.N_TARRAY) { // #141: a def-dimensioned field array sized to 0 here, so the // struct loop (off += astsize(field)) overlapped the next // field; arrayelen folds the def. let elen: i64 = arrayelen(c, t.rhs): i64; return astsize(c, t.lhs) * elen; }; - if (k == nkind.N_TTUPLE) { + if (k == syntax.nkind.N_TTUPLE) { // Route through the type table, NOT a packed element-sum: // slot layout is the tuple SSoT (C-t0, user-ratified) and // tupleelemslot is its one wwstage answer. The packed walk // this replaces was a C-t0 escape — size((u32,u32)) folded // to 8 here while cstage (check.c N_TTUPLE) and the wwstage // type table both said 16 (task #22 commit 0). - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { return ti.size: i64; }; return 0i64; }; - if (k == nkind.N_TSTRUCT) { + if (k == syntax.nkind.N_TSTRUCT) { let off: i64 = 0i64; let maxal: i64 = 1i64; - let f: *node = t.list; + let f: *syntax.node = t.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { let fa: i64 = astalign(c, f.lhs); if (fa > maxal) { maxal = fa; }; off = (off + fa - 1i64) & ~(fa - 1i64); @@ -1318,7 +1318,7 @@ fn astsize(c: *checker, t: *node) i64 = { }; return (off + maxal - 1i64) & ~(maxal - 1i64); }; - if (k == nkind.N_TTAGGED) { + if (k == syntax.nkind.N_TTAGGED) { // Route through tinfofornode (the tagged-normalization SSoT) // so the size() fold matches cgen's layout AND cstage: the raw // 8+roundup8(max) here ignored never-drop / dedup / single- @@ -1326,19 +1326,19 @@ fn astsize(c: *checker, t: *node) i64 = { // size((i32|never)) 16 not 4 (#1). Mirrors the N_TTUPLE arm // above and cstage size() reading resolve_type(...)->size // (cmd/wcc/check.c:1547-1550). - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { return ti.size: i64; }; return 0i64; }; - if (k == nkind.N_TENUM) { + if (k == syntax.nkind.N_TENUM) { if (t.lhs != nil) { return astsize(c, t.lhs); }; return 4i64; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; let ps: i64 = primtypesize(nm); if (ps >= 0i64) { return ps; }; - let resolved: *node = resolvealias(c, t); + let resolved: *syntax.node = resolvealias(c, t); if (resolved != nil && resolved != t) { return astsize(c, resolved); }; @@ -1360,36 +1360,36 @@ fn astsize(c: *checker, t: *node) i64 = { // require_sized guards that reject unsized aggregates at the type decl // (so the cstage size/align fold only ever sees a leaf opaque); harec // ref/harec/src/check.c:2720, type_store.c:1147 (tuple) / :449 (tagged). -fn astunsized(c: *checker, t: *node) bool = { +fn astunsized(c: *checker, t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return false; }; - let k: nkind = u.kind; - if (k == nkind.N_TNAME) { - if (streq(u.str, "opaque")) { return true; }; + let k: syntax.nkind = u.kind; + if (k == syntax.nkind.N_TNAME) { + if (syntax.streq(u.str, "opaque")) { return true; }; return false; }; - if (k == nkind.N_TARRAY) { return astunsized(c, u.lhs); }; - if (k == nkind.N_TTUPLE) { - let p: *node = u.list; + if (k == syntax.nkind.N_TARRAY) { return astunsized(c, u.lhs); }; + if (k == syntax.nkind.N_TTUPLE) { + let p: *syntax.node = u.list; for (p != nil) { if (astunsized(c, p.lhs)) { return true; }; p = p.next; }; return false; }; - if (k == nkind.N_TSTRUCT) { - let f: *node = u.list; + if (k == syntax.nkind.N_TSTRUCT) { + let f: *syntax.node = u.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { if (astunsized(c, f.lhs)) { return true; }; }; f = f.next; }; return false; }; - if (k == nkind.N_TTAGGED) { - let v: *node = u.list; + if (k == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = u.list; for (v != nil) { if (astunsized(c, v)) { return true; }; v = v.next; @@ -1432,11 +1432,11 @@ fn astunsized(c: *checker, t: *node) bool = { // call use it). The #241 `yield ` fallback (the dominant // match-bind-then-yield idiom, Hare's parseint `case let t => yield t`) // stays, now resolving btype to a tinfo. -fn matchyieldtype(c: *checker, body: *node, bname: str, btype: *node, - nodeout: **node) *tinfo = { +fn matchyieldtype(c: *checker, body: *syntax.node, bname: str, btype: *syntax.node, + nodeout: **syntax.node) *syntax.tinfo = { if (body == nil) { return nil; }; - let k: nkind = body.kind; - if (k == nkind.N_YIELD) { + let k: syntax.nkind = body.kind; + if (k == syntax.nkind.N_YIELD) { if (body.lhs == nil) { return nil; }; if (body.lhs.type_ != nil) { // For the bare-binder idiom `yield `, ALSO surface @@ -1448,40 +1448,40 @@ fn matchyieldtype(c: *checker, body: *node, bname: str, btype: *node, // match idiom in tree, grep-confirmed). btype is the binder's // declared type node, which IS the match's type here; the // cached tinfo returned below equals tinfofornode(btype). - if (body.lhs.kind == nkind.N_IDENT && bname.len > 0 - && streq(body.lhs.str, bname)) { + if (body.lhs.kind == syntax.nkind.N_IDENT && bname.len > 0 + && syntax.streq(body.lhs.str, bname)) { *nodeout = btype; }; - return body.lhs.type_: *tinfo; + return body.lhs.type_: *syntax.tinfo; }; - let t: *node = exprtype(c, body.lhs, nil); + let t: *syntax.node = exprtype(c, body.lhs, nil); if (t != nil) { *nodeout = t; return tinfofornode(c, t); }; - if (body.lhs.kind == nkind.N_IDENT && bname.len > 0 - && streq(body.lhs.str, bname)) { + if (body.lhs.kind == syntax.nkind.N_IDENT && bname.len > 0 + && syntax.streq(body.lhs.str, bname)) { *nodeout = btype; return tinfofornode(c, btype); }; return nil; }; - if (k == nkind.N_MATCH) { return nil; }; - if (k == nkind.N_BLOCK) { - let s: *node = body.list; + if (k == syntax.nkind.N_MATCH) { return nil; }; + if (k == syntax.nkind.N_BLOCK) { + let s: *syntax.node = body.list; for (s != nil) { - let t: *tinfo = matchyieldtype(c, s, bname, btype, nodeout); + let t: *syntax.tinfo = matchyieldtype(c, s, bname, btype, nodeout); if (t != nil) { return t; }; s = s.next; }; return nil; }; - if (k == nkind.N_IF) { - let t: *tinfo = matchyieldtype(c, body.body, bname, btype, nodeout); + if (k == syntax.nkind.N_IF) { + let t: *syntax.tinfo = matchyieldtype(c, body.body, bname, btype, nodeout); if (t != nil) { return t; }; return matchyieldtype(c, body.els, bname, btype, nodeout); }; - if (k == nkind.N_FOR || k == nkind.N_FORRANGE) { + if (k == syntax.nkind.N_FOR || k == syntax.nkind.N_FORRANGE) { return matchyieldtype(c, body.body, bname, btype, nodeout); }; return nil; @@ -1496,13 +1496,13 @@ fn matchyieldtype(c: *checker, body: *node, bname: str, btype: *node, // family mismatch (the catA repro: an int arm vs a str arm) and never an // untyped->concrete promotion (untyped_int vs i32/f64 both land in class 1) // that cstage accepts. The families mirror typeisnum/typeisstr (lib/ww/typ.ww). -fn yieldclass(t: *tinfo) i32 = { - let u: *tinfo = tichase(t); +fn yieldclass(t: *syntax.tinfo) i32 = { + let u: *syntax.tinfo = tichase(t); if (u == nil) { return 0i32; }; - if (typeisnum(u)) { return 1i32; }; - if (typeisstr(u)) { return 2i32; }; - if (u.kind == tykind.TY_BOOL) { return 3i32; }; - if (u.kind == tykind.TY_UNTYPED_BOOL) { return 3i32; }; + if (syntax.typeisnum(u)) { return 1i32; }; + if (syntax.typeisstr(u)) { return 2i32; }; + if (u.kind == syntax.tykind.TY_BOOL) { return 3i32; }; + if (u.kind == syntax.tykind.TY_UNTYPED_BOOL) { return 3i32; }; return 0i32; }; @@ -1511,25 +1511,25 @@ fn yieldclass(t: *tinfo) i32 = { // (for `p.field` where p is *Struct), require N_TSTRUCT, walk fields // honouring per-field alignment, return -1 if the field name is // absent so the caller can flag the error and fold to 0. -fn astoffset(c: *checker, dot: *node) i64 = { +fn astoffset(c: *checker, dot: *syntax.node) i64 = { if (dot == nil) { return -1i64; }; - if (dot.kind != nkind.N_DOT) { return -1i64; }; - let recv: *node = scruttype(c, dot.lhs); + if (dot.kind != syntax.nkind.N_DOT) { return -1i64; }; + let recv: *syntax.node = scruttype(c, dot.lhs); if (recv == nil) { return -1i64; }; - let rtyp: *node = resolvealias(c, unwrapbang(recv)); + let rtyp: *syntax.node = resolvealias(c, unwrapbang(recv)); if (rtyp == nil) { return -1i64; }; - if (rtyp.kind == nkind.N_TPTR) { + if (rtyp.kind == syntax.nkind.N_TPTR) { rtyp = resolvealias(c, unwrapbang(rtyp.lhs)); }; if (rtyp == nil) { return -1i64; }; - if (rtyp.kind != nkind.N_TSTRUCT) { return -1i64; }; + if (rtyp.kind != syntax.nkind.N_TSTRUCT) { return -1i64; }; let off: i64 = 0i64; - let f: *node = rtyp.list; + let f: *syntax.node = rtyp.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { let fa: i64 = astalign(c, f.lhs); off = (off + fa - 1i64) & ~(fa - 1i64); - if (streq(f.str, dot.str)) { return off; }; + if (syntax.streq(f.str, dot.str)) { return off; }; off += astsize(c, f.lhs); }; f = f.next; @@ -1563,8 +1563,8 @@ fn arenau64tos(v: u64) str = { // Used by the #42 size/align/offset intercepts so cgen sees the // folded literal rather than an unresolved call. Mirrors cstage // cmd/wcc/check.c:919-927 / :951-958. -fn foldtointlit(c: *checker, n: *node, v: i64) void = { - n.kind = nkind.N_INTLIT; +fn foldtointlit(c: *checker, n: *syntax.node, v: i64) void = { + n.kind = syntax.nkind.N_INTLIT; n.uval = v: u64; n.str = arenau64tos(v: u64); n.lhs = nil; @@ -1580,23 +1580,23 @@ fn foldtointlit(c: *checker, n: *node, v: i64) void = { // literal — rule 10 lives at the check pass for #88. Returns false on // division by zero or an op outside the constant subset; the caller // maps that to its own diagnostic. -fn foldbinop(op: tkind, a: u64, b: u64, out: *u64) bool = { - if (op == tkind.TK_PLUS) { *out = a + b; return true; }; - if (op == tkind.TK_MINUS) { *out = a - b; return true; }; - if (op == tkind.TK_STAR) { *out = a * b; return true; }; - if (op == tkind.TK_SLASH) { +fn foldbinop(op: syntax.tkind, a: u64, b: u64, out: *u64) bool = { + if (op == syntax.tkind.TK_PLUS) { *out = a + b; return true; }; + if (op == syntax.tkind.TK_MINUS) { *out = a - b; return true; }; + if (op == syntax.tkind.TK_STAR) { *out = a * b; return true; }; + if (op == syntax.tkind.TK_SLASH) { if (b == 0u64) { return false; }; *out = a / b; return true; }; - if (op == tkind.TK_PERCENT) { + if (op == syntax.tkind.TK_PERCENT) { if (b == 0u64) { return false; }; *out = a % b; return true; }; - if (op == tkind.TK_AMP) { *out = a & b; return true; }; - if (op == tkind.TK_PIPE) { *out = a | b; return true; }; - if (op == tkind.TK_CARET) { *out = a ^ b; return true; }; - if (op == tkind.TK_LSHIFT) { *out = a << b; return true; }; - if (op == tkind.TK_RSHIFT) { *out = a >> b; return true; }; + if (op == syntax.tkind.TK_AMP) { *out = a & b; return true; }; + if (op == syntax.tkind.TK_PIPE) { *out = a | b; return true; }; + if (op == syntax.tkind.TK_CARET) { *out = a ^ b; return true; }; + if (op == syntax.tkind.TK_LSHIFT) { *out = a << b; return true; }; + if (op == syntax.tkind.TK_RSHIFT) { *out = a >> b; return true; }; return false; }; @@ -1605,7 +1605,7 @@ fn foldbinop(op: tkind, a: u64, b: u64, out: *u64) bool = { // gates cgen off in main.ww:165, so this fails the build rather than // emitting a missing DATA row silently (rule 7). cstage twin: err() // in cmd/wcc/check.c. -fn deffolderr(c: *checker, n: *node, msg: str) void = { +fn deffolderr(c: *checker, n: *syntax.node, msg: str) void = { cerr(n.file); cerr(": error: "); cerr(msg); @@ -1621,12 +1621,12 @@ fn deffolderr(c: *checker, n: *node, msg: str) void = { // (t.size, rule 13); the 8s are CHAR_BIT and the u64 byte-width, not // type-layout sizes, so they sit outside rule 13's scope. Pure-u64 so // the range check is bit-identical to cstage (rule 10). -fn defcastfits(t: *tinfo, v: u64) bool = { - if (!typeisint(t)) { return true; }; // non-int target: keep value +fn defcastfits(t: *syntax.tinfo, v: u64) bool = { + if (!syntax.typeisint(t)) { return true; }; // non-int target: keep value let w: u64 = t.size; if (w >= 8u64) { return true; }; // 64-bit target: no narrowing let bits: u64 = w * 8u64; - if (typeisunsigned(t)) { return (v >> bits) == 0u64; }; + if (syntax.typeisunsigned(t)) { return (v >> bits) == 0u64; }; // signed: truncate to `bits` then sign-extend; fits iff unchanged let mask: u64 = (1u64 << bits) - 1u64; let sign: u64 = 1u64 << (bits - 1u64); @@ -1653,45 +1653,45 @@ fn defcastfits(t: *tinfo, v: u64) bool = { // `depth` bounds a def->def->def chain; a cycle (def A = B; def B = A, // incl. cross-module) hits the cap and fails loud rather than hanging // (rule 7), mirroring the cgen nsteps>=16 abort precedent. -fn evaldefconst(c: *checker, n: *node, out: *u64, depth: i32) bool = { +fn evaldefconst(c: *checker, n: *syntax.node, out: *u64, depth: i32) bool = { if (n == nil) { return false; }; if (depth >= 16) { deffolderr(c, n, "def value: reference chain too deep (cycle?)"); return false; }; if (foldintliteral(n, out)) { return true; }; - let k: nkind = n.kind; - if (k == nkind.N_BIN) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_BIN) { let a: u64 = 0u64; let b: u64 = 0u64; if (!evaldefconst(c, n.lhs, &a, depth + 1)) { return false; }; if (!evaldefconst(c, n.rhs, &b, depth + 1)) { return false; }; if (foldbinop(n.op, a, b, out)) { return true; }; - if ((n.op == tkind.TK_SLASH || n.op == tkind.TK_PERCENT) && b == 0u64) { + if ((n.op == syntax.tkind.TK_SLASH || n.op == syntax.tkind.TK_PERCENT) && b == 0u64) { deffolderr(c, n, "def value: division by zero"); } else { deffolderr(c, n, "def value: unsupported binary op"); }; return false; }; - if (k == nkind.N_UN) { + if (k == syntax.nkind.N_UN) { // foldintliteral already covers unary-over-leaf; this arm // catches unary over a resolved ref, e.g. `-A`. let v: u64 = 0u64; if (!evaldefconst(c, n.lhs, &v, depth + 1)) { return false; }; - if (n.op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (n.op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (n.op == tkind.TK_PLUS) { *out = v; return true; }; + if (n.op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (n.op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (n.op == syntax.tkind.TK_PLUS) { *out = v; return true; }; deffolderr(c, n, "def value: unsupported unary op"); return false; }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { // n.lhs = value; n.type_ = resolved target (stamped by // exprtype's N_CAST arm during resolvewalk). Strip the cast // keeping the value; a narrowing cast that loses it fails loud. let v: u64 = 0u64; if (!evaldefconst(c, n.lhs, &v, depth + 1)) { return false; }; - let t: *tinfo = (n.type_): *tinfo; + let t: *syntax.tinfo = (n.type_): *syntax.tinfo; if (!defcastfits(t, v)) { deffolderr(c, n, "def value: narrowing cast loses value"); return false; @@ -1699,20 +1699,20 @@ fn evaldefconst(c: *checker, n: *node, out: *u64, depth: i32) bool = { *out = v; return true; }; - if (k == nkind.N_IDENT) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, n.str); + if (k == syntax.nkind.N_IDENT) { + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, n.str); if (s == nil) { return false; }; - if (s.skind != skind.SK_DEF) { return false; }; + if (s.skind != syntax.skind.SK_DEF) { return false; }; if (s.decl == nil) { return false; }; if (s.decl.rhs == nil) { return false; }; return evaldefconst(c, s.decl.rhs, out, depth + 1); }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { if (n.lhs == nil) { return false; }; - if (n.lhs.kind != nkind.N_IDENT) { return false; }; - let s: *sym = scopelookupinmodule(c.cur, modkeyfor(c, n.lhs.str), n.str); + if (n.lhs.kind != syntax.nkind.N_IDENT) { return false; }; + let s: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, n.lhs.str), n.str); if (s == nil) { return false; }; - if (s.skind != skind.SK_DEF) { return false; }; + if (s.skind != syntax.skind.SK_DEF) { return false; }; if (s.decl == nil) { return false; }; if (s.decl.rhs == nil) { return false; }; return evaldefconst(c, s.decl.rhs, out, depth + 1); @@ -1725,10 +1725,10 @@ fn evaldefconst(c: *checker, n: *node, out: *u64, depth: i32) bool = { // width and pass-3 asserttyped see a properly-typed literal leaf. Lets // cgen's existing emitdefconstants lay down the row with no codegen // change (#88). Shape mirrors foldtointlit (the #42 stamp). -fn stampintlit(n: *node, v: u64) void = { - n.kind = nkind.N_INTLIT; +fn stampintlit(n: *syntax.node, v: u64) void = { + n.kind = syntax.nkind.N_INTLIT; n.uval = v; - n.op = tkind.TK_NONE; + n.op = syntax.tkind.TK_NONE; n.str = arenau64tos(v); n.lhs = nil; n.rhs = nil; @@ -1750,9 +1750,9 @@ fn stampintlit(n: *node, v: u64) void = { // SSoT), so every N_TARRAY length reader routes here to fold the dim // identically — astsize (struct layout), tinfofornode (canonical // tinfo), checkarrlitfits (count gate). -fn arrayelen(c: *checker, rhs: *node) u64 = { +fn arrayelen(c: *checker, rhs: *syntax.node) u64 = { if (rhs == nil) { return 0u64; }; - if (rhs.kind == nkind.N_INTLIT) { return rhs.uval; }; + if (rhs.kind == syntax.nkind.N_INTLIT) { return rhs.uval; }; let v: u64 = 0u64; if (evaldefconst(c, rhs, &v, 0)) { return v; }; return 0u64; @@ -1781,33 +1781,33 @@ fn arrayelen(c: *checker, rhs: *node) u64 = { // practice — harec accepts the same shape without memoisation per // resolve_enum_field's wrap_resolver chain // (ref/harec/src/check.c:4438) — so the quadratic is harmless. -fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = { +fn enumvalfold(body: *syntax.node, until: *syntax.node, e: *syntax.node, out: *u64) bool = { if (e == nil) { return false; }; - let k: nkind = e.kind; - if (k == nkind.N_INTLIT) { *out = e.uval; return true; }; - if (k == nkind.N_RUNELIT) { *out = e.uval; return true; }; - if (k == nkind.N_TRUE) { *out = 1u64; return true; }; - if (k == nkind.N_FALSE) { *out = 0u64; return true; }; - if (k == nkind.N_NIL) { *out = 0u64; return true; }; - if (k == nkind.N_UN) { + let k: syntax.nkind = e.kind; + if (k == syntax.nkind.N_INTLIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_RUNELIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_TRUE) { *out = 1u64; return true; }; + if (k == syntax.nkind.N_FALSE) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_NIL) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_UN) { let v: u64 = 0u64; if (!enumvalfold(body, until, e.lhs, &v)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (op == tkind.TK_PLUS) { *out = v; return true; }; + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (op == syntax.tkind.TK_PLUS) { *out = v; return true; }; return false; }; - if (k == nkind.N_BIN) { + if (k == syntax.nkind.N_BIN) { let a: u64 = 0u64; let b: u64 = 0u64; if (!enumvalfold(body, until, e.lhs, &a)) { return false; }; if (!enumvalfold(body, until, e.rhs, &b)) { return false; }; return foldbinop(e.op, a, b, out); }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { let prev: u64 = (-1i64): u64; - let m: *node = body.list; + let m: *syntax.node = body.list; for (m != nil && m != until) { let val: u64 = 0u64; if (m.lhs == nil) { @@ -1816,7 +1816,7 @@ fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = { if (!enumvalfold(body, m, m.lhs, &val)) { return false; }; }; prev = val; - if (streq(m.str, e.str)) { *out = val; return true; }; + if (syntax.streq(m.str, e.str)) { *out = val; return true; }; m = m.next; }; return false; @@ -1837,13 +1837,13 @@ fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = { // mirror that. The value itself is folded to a constant at every use // site (enumvalfold) and at codegen (cgen.ww enumevalmember), so cgen // never reads these node types — this stamp is checker metadata only. -fn stampenumvals(c: *checker, n: *node) void = { - let under: *tinfo = c.tc.tyi32; +fn stampenumvals(c: *checker, n: *syntax.node) void = { + let under: *syntax.tinfo = c.tc.tyi32; if (n.lhs != nil) { - let s: *tinfo = tinfofornode(c, n.lhs); + let s: *syntax.tinfo = tinfofornode(c, n.lhs); if (s != nil) { under = s; }; }; - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { stampnilexpr(m.lhs, under); m = m.next; @@ -1854,7 +1854,7 @@ fn stampenumvals(c: *checker, n: *node) void = { // `ti`. lhs/rhs cover the enum constexpr grammar enumvalfold accepts // (literals, unary, binary, sibling backref); non-nil nodes keep the // type exprtype already derived. -fn stampnilexpr(n: *node, ti: *tinfo) void = { +fn stampnilexpr(n: *syntax.node, ti: *syntax.tinfo) void = { if (n == nil) { return; }; if (n.type_ == nil) { n.type_ = ti: *void; }; stampnilexpr(n.lhs, ti); @@ -1871,36 +1871,36 @@ fn stampnilexpr(n: *node, ti: *tinfo) void = { // 8; void contributes 0 (never appears in tuples emitted by user // code, but kept for SSoT symmetry with cgen's N_TNAME-"void" // fallback arm). -fn tupleelemslot(pt: *tinfo) u64 = { +fn tupleelemslot(pt: *syntax.tinfo) u64 = { if (pt == nil) { return 8u64; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. - let t: *tinfo = pt; + let t: *syntax.tinfo = pt; t = tichase(t); if (t == nil) { return 8u64; }; - let pk: tykind = t.kind; - if (pk == tykind.TY_VOID) { return 0u64; }; - if (pk == tykind.TY_STR) { return t.size; }; - if (pk == tykind.TY_SLICE) { return t.size; }; + let pk: syntax.tykind = t.kind; + if (pk == syntax.tykind.TY_VOID) { return 0u64; }; + if (pk == syntax.tykind.TY_STR) { return t.size; }; + if (pk == syntax.tykind.TY_SLICE) { return t.size; }; // #22 (user-ratified 2026-06-04): slot = roundup8(size(elem)) — 8B // is a FLOOR, not a ceiling. (str,str)=48B predates this; tagged // was the one truncated >8B kind (the #237 fieldslotsize-missing- // TY_TUPLE precedent: fieldslotsize below already carried this // arm). Cstage twin: check.c N_TTUPLE; cgen accessor: tuple_eslot // / tupeslot. - if (pk == tykind.TY_TAGGED) { return (t.size + 7u64) & ~7u64; }; - if (pk == tykind.TY_PTR || pk == tykind.TY_FN || - pk == tykind.TY_CHAN || pk == tykind.TY_I64 || - pk == tykind.TY_U64 || pk == tykind.TY_INT || - pk == tykind.TY_UINT || pk == tykind.TY_UINTPTR || - pk == tykind.TY_SIZE || pk == tykind.TY_F64) { return 8u64; }; - if (pk == tykind.TY_BOOL || pk == tykind.TY_RUNE || - pk == tykind.TY_I8 || pk == tykind.TY_I16 || - pk == tykind.TY_I32 || pk == tykind.TY_U8 || - pk == tykind.TY_U16 || pk == tykind.TY_U32 || - pk == tykind.TY_F32 || pk == tykind.TY_ENUM) { return 8u64; }; + if (pk == syntax.tykind.TY_TAGGED) { return (t.size + 7u64) & ~7u64; }; + if (pk == syntax.tykind.TY_PTR || pk == syntax.tykind.TY_FN || + pk == syntax.tykind.TY_CHAN || pk == syntax.tykind.TY_I64 || + pk == syntax.tykind.TY_U64 || pk == syntax.tykind.TY_INT || + pk == syntax.tykind.TY_UINT || pk == syntax.tykind.TY_UINTPTR || + pk == syntax.tykind.TY_SIZE || pk == syntax.tykind.TY_F64) { return 8u64; }; + if (pk == syntax.tykind.TY_BOOL || pk == syntax.tykind.TY_RUNE || + pk == syntax.tykind.TY_I8 || pk == syntax.tykind.TY_I16 || + pk == syntax.tykind.TY_I32 || pk == syntax.tykind.TY_U8 || + pk == syntax.tykind.TY_U16 || pk == syntax.tykind.TY_U32 || + pk == syntax.tykind.TY_F32 || pk == syntax.tykind.TY_ENUM) { return 8u64; }; // Composite — one 8B eightbyte, NOT t.slotsize: cgen's cursor // transport strides `wide ? size : 8` at every tuple site (both // stages), so a composite element rides one register word today. @@ -1917,44 +1917,44 @@ fn tupleelemslot(pt: *tinfo) u64 = { // slot-padded total (si.totsize equivalent); primitives keep their // natural width (struct interior packing is unaffected by stack-slot // pad-to-8); arrays use their slot-padded element-stride * elen. -fn fieldslotsize(ft: *tinfo) u64 = { +fn fieldslotsize(ft: *syntax.tinfo) u64 = { if (ft == nil) { return 8u64; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. - let t: *tinfo = ft; + let t: *syntax.tinfo = ft; t = tichase(t); if (t == nil) { return 8u64; }; - let fk: tykind = t.kind; - if (fk == tykind.TY_STRUCT) { return t.slotsize; }; - if (fk == tykind.TY_ARRAY) { return t.slotsize; }; - if (fk == tykind.TY_TAGGED) { return t.size; }; + let fk: syntax.tykind = t.kind; + if (fk == syntax.tykind.TY_STRUCT) { return t.slotsize; }; + if (fk == syntax.tykind.TY_ARRAY) { return t.slotsize; }; + if (fk == syntax.tykind.TY_TAGGED) { return t.size; }; // str / slice read t.size so the typ.ww SSoT seed is the single // source for #1 (str→24) / #34 (slice graduation) — no hardcoded // literal here to drift. - if (fk == tykind.TY_SLICE) { return t.size; }; - if (fk == tykind.TY_PTR || fk == tykind.TY_FN || - fk == tykind.TY_CHAN) { return 8u64; }; - if (fk == tykind.TY_STR) { return t.size; }; + if (fk == syntax.tykind.TY_SLICE) { return t.size; }; + if (fk == syntax.tykind.TY_PTR || fk == syntax.tykind.TY_FN || + fk == syntax.tykind.TY_CHAN) { return 8u64; }; + if (fk == syntax.tykind.TY_STR) { return t.size; }; // #237: a tuple-typed struct field carries its own slot total (the // per-element slot sum stamped at the N_TTUPLE arm above — slices at // 24 each). Without this it fell to the 8B default below, undersizing // the enclosing struct's slotsize (size stayed correct), so a `let s:S` // slot was too small — a silent stack-corrupting miscompile. Aligns // with cgenutil.ww fieldsize, which already returns the tuple's size. - if (fk == tykind.TY_TUPLE) { return t.slotsize; }; + if (fk == syntax.tykind.TY_TUPLE) { return t.slotsize; }; // Primitives keep natural width inside structs (matches // cgenutil fieldsize: primsize, not pad-to-8). - if (fk == tykind.TY_BOOL || fk == tykind.TY_RUNE || - fk == tykind.TY_I8 || fk == tykind.TY_I16 || - fk == tykind.TY_I32 || fk == tykind.TY_I64 || - fk == tykind.TY_U8 || fk == tykind.TY_U16 || - fk == tykind.TY_U32 || fk == tykind.TY_U64 || - fk == tykind.TY_INT || fk == tykind.TY_UINT || - fk == tykind.TY_UINTPTR || fk == tykind.TY_SIZE || - fk == tykind.TY_F32 || fk == tykind.TY_F64 || - fk == tykind.TY_ENUM) { return t.size; }; + if (fk == syntax.tykind.TY_BOOL || fk == syntax.tykind.TY_RUNE || + fk == syntax.tykind.TY_I8 || fk == syntax.tykind.TY_I16 || + fk == syntax.tykind.TY_I32 || fk == syntax.tykind.TY_I64 || + fk == syntax.tykind.TY_U8 || fk == syntax.tykind.TY_U16 || + fk == syntax.tykind.TY_U32 || fk == syntax.tykind.TY_U64 || + fk == syntax.tykind.TY_INT || fk == syntax.tykind.TY_UINT || + fk == syntax.tykind.TY_UINTPTR || fk == syntax.tykind.TY_SIZE || + fk == syntax.tykind.TY_F32 || fk == syntax.tykind.TY_F64 || + fk == syntax.tykind.TY_ENUM) { return t.size; }; return 8u64; }; @@ -1979,53 +1979,53 @@ fn fieldslotsize(ft: *tinfo) u64 = { // typeeq's contract (TY_NAMED → only same ptr, else structural; lib/ww/ // typ.ww:581). nil guards match variant_match's `a==NULL||b==NULL → 0` // so two unresolved variants never collapse. -fn variantpresent(head: *tparam, vt: *tinfo) bool = { +fn variantpresent(head: *syntax.tparam, vt: *syntax.tinfo) bool = { if (vt == nil) { return false; }; - let p: *tparam = head; + let p: *syntax.tparam = head; for (p != nil) { if (p.type_ != nil) { - if (typeeq(p.type_, vt)) { return true; }; + if (syntax.typeeq(p.type_, vt)) { return true; }; }; p = p.tnext; }; return false; }; -fn tinfofornode(c: *checker, n: *node) *tinfo = { +fn tinfofornode(c: *checker, n: *syntax.node) *syntax.tinfo = { if (n == nil) { return nil; }; - let cached: *tinfo = tinfocachelookup(c.tc, n); + let cached: *syntax.tinfo = syntax.tinfocachelookup(c.tc, n); if (cached != nil) { return cached; }; - let r: *tinfo = nil; - let k: nkind = n.kind; + let r: *syntax.tinfo = nil; + let k: syntax.nkind = n.kind; switch (k) { - case nkind.N_TNAME: + case syntax.nkind.N_TNAME: let nm: str = n.str; - if (streq(nm, "void")) { r = c.tc.tyvoid; }; - if (streq(nm, "bool")) { r = c.tc.tybool; }; - if (streq(nm, "rune")) { r = c.tc.tyrune; }; - if (streq(nm, "i8")) { r = c.tc.tyi8; }; - if (streq(nm, "i16")) { r = c.tc.tyi16; }; - if (streq(nm, "i32")) { r = c.tc.tyi32; }; - if (streq(nm, "i64")) { r = c.tc.tyi64; }; - if (streq(nm, "u8")) { r = c.tc.tyu8; }; - if (streq(nm, "u16")) { r = c.tc.tyu16; }; - if (streq(nm, "u32")) { r = c.tc.tyu32; }; - if (streq(nm, "u64")) { r = c.tc.tyu64; }; - if (streq(nm, "int")) { r = c.tc.tyint; }; - if (streq(nm, "uint")) { r = c.tc.tyuint; }; - if (streq(nm, "uintptr")) { r = c.tc.tyuintptr; }; - if (streq(nm, "size")) { r = c.tc.tysize; }; // #85 fold-2 - if (streq(nm, "opaque")) { r = c.tc.tyopaque; }; // #108(a) - if (streq(nm, "f32")) { r = c.tc.tyf32; }; - if (streq(nm, "f64")) { r = c.tc.tyf64; }; - if (streq(nm, "str")) { r = c.tc.tystr; }; - if (streq(nm, "never")) { r = c.tc.tynever; }; - if (streq(nm, "untyped_int")) { r = c.tc.tyuntypedint; }; - if (streq(nm, "untyped_float")) { r = c.tc.tyuntypedfloat; }; - if (streq(nm, "untyped_str")) { r = c.tc.tyuntypedstr; }; - if (streq(nm, "untyped_rune")) { r = c.tc.tyuntypedrune; }; - if (streq(nm, "untyped_bool")) { r = c.tc.tyuntypedbool; }; - if (streq(nm, "untyped_nil")) { r = c.tc.tyuntypednil; }; + if (syntax.streq(nm, "void")) { r = c.tc.tyvoid; }; + if (syntax.streq(nm, "bool")) { r = c.tc.tybool; }; + if (syntax.streq(nm, "rune")) { r = c.tc.tyrune; }; + if (syntax.streq(nm, "i8")) { r = c.tc.tyi8; }; + if (syntax.streq(nm, "i16")) { r = c.tc.tyi16; }; + if (syntax.streq(nm, "i32")) { r = c.tc.tyi32; }; + if (syntax.streq(nm, "i64")) { r = c.tc.tyi64; }; + if (syntax.streq(nm, "u8")) { r = c.tc.tyu8; }; + if (syntax.streq(nm, "u16")) { r = c.tc.tyu16; }; + if (syntax.streq(nm, "u32")) { r = c.tc.tyu32; }; + if (syntax.streq(nm, "u64")) { r = c.tc.tyu64; }; + if (syntax.streq(nm, "int")) { r = c.tc.tyint; }; + if (syntax.streq(nm, "uint")) { r = c.tc.tyuint; }; + if (syntax.streq(nm, "uintptr")) { r = c.tc.tyuintptr; }; + if (syntax.streq(nm, "size")) { r = c.tc.tysize; }; // #85 fold-2 + if (syntax.streq(nm, "opaque")) { r = c.tc.tyopaque; }; // #108(a) + if (syntax.streq(nm, "f32")) { r = c.tc.tyf32; }; + if (syntax.streq(nm, "f64")) { r = c.tc.tyf64; }; + if (syntax.streq(nm, "str")) { r = c.tc.tystr; }; + if (syntax.streq(nm, "never")) { r = c.tc.tynever; }; + if (syntax.streq(nm, "untyped_int")) { r = c.tc.tyuntypedint; }; + if (syntax.streq(nm, "untyped_float")) { r = c.tc.tyuntypedfloat; }; + if (syntax.streq(nm, "untyped_str")) { r = c.tc.tyuntypedstr; }; + if (syntax.streq(nm, "untyped_rune")) { r = c.tc.tyuntypedrune; }; + if (syntax.streq(nm, "untyped_bool")) { r = c.tc.tyuntypedbool; }; + if (syntax.streq(nm, "untyped_nil")) { r = c.tc.tyuntypednil; }; if (r == nil) { // #64 Phase-N step 2 (THE FLIP): build a per-decl // TY_NAMED wrapper instead of collapsing the alias to @@ -2039,12 +2039,12 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // (cmd/wcc/check.c:1900-1929): pass1 creates the NAMED, // pass2 patches under/size off resolve_type(d->lhs), // where resolve_typename returns the inner NAMED. - let s: *sym = aliassym(c, n); + let s: *syntax.sym = aliassym(c, n); if (s != nil) { if (s.type_ != nil) { r = s.type_; } else { - let body: *node = nil; + let body: *syntax.node = nil; if (s.decl != nil) { body = unwrapbang(s.decl.lhs); }; @@ -2058,10 +2058,10 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // (check.c:1909/1917) ahead of pass2's // under patch, and A.2's TSTRUCT/TFN/ // TTAGGED tinfocachebind cycle-break. - let named: *tinfo = typenamed(s.name, nil); + let named: *syntax.tinfo = syntax.typenamed(s.name, nil); s.type_ = named; named.resolving = 1; - let under: *tinfo = tinfofornode(c, body); + let under: *syntax.tinfo = tinfofornode(c, body); // #62/#69: alias-root cycle (`type a = b; // type b = a` / `type a = a`) — checked // BEFORE clearing the flag so self-aliases @@ -2088,7 +2088,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { }; }; }; - case nkind.N_TBANG: + case syntax.nkind.N_TBANG: // #61 audit §1.8: `!T` propagates the inner shape; cstage's // resolve_type sets ty->iserror on the wrapper but no wwstage // cgen reader consumes it yet, so A.1 drops the flag and @@ -2096,13 +2096,13 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // unwrapbang pre-walk; graduate alongside the first cgen // site that needs iserror discrimination. r = tinfofornode(c, n.lhs); - case nkind.N_TPTR: - r = typeptr(tinfofornode(c, n.lhs)); - case nkind.N_TSLICE: - r = typeslice(tinfofornode(c, n.lhs)); - case nkind.N_TCHAN: - r = typechan(tinfofornode(c, n.lhs)); - case nkind.N_TARRAY: + case syntax.nkind.N_TPTR: + r = syntax.typeptr(tinfofornode(c, n.lhs)); + case syntax.nkind.N_TSLICE: + r = syntax.typeslice(tinfofornode(c, n.lhs)); + case syntax.nkind.N_TCHAN: + r = syntax.typechan(tinfofornode(c, n.lhs)); + case syntax.nkind.N_TARRAY: // Cstage cmd/wcc/check.c:314-326: length must be an integer // literal (`[_]T` keeps alen=0 as the inferred-length sentinel // patched at letslotsize-time). @@ -2125,7 +2125,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // fold SSoT for astsize's later size() read. let elen: u64 = 0u64; // #141: fold def-dim if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_INTLIT) { + if (n.rhs.kind == syntax.nkind.N_INTLIT) { elen = n.rhs.uval; } else { let v: u64 = 0u64; @@ -2138,36 +2138,36 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { }; }; }; - let sub: *tinfo = tinfofornode(c, n.lhs); + let sub: *syntax.tinfo = tinfofornode(c, n.lhs); // #62/#69: `type a = [2]a` value cycle — loud, cstage twin. if (circularnamed(c, sub, n)) { sub = c.tc.tyerr; }; - r = typearray(sub, elen); - case nkind.N_TFN: + r = syntax.typearray(sub, elen); + case syntax.nkind.N_TFN: // Cstage cmd/wcc/check.c:437-466: function types are 8B / 8B // (call-target pointer shape). Pre-bind before recursing into // the return type so a recursive `type F = fn() F` self-ref // doesn't spin (cycle-break mirror of the TSTRUCT/TTAGGED // pattern below). - r = newtype(tykind.TY_FN); + r = syntax.newtype(syntax.tykind.TY_FN); r.size = 8u64; r.align = 8u64; r.slotsize = 8u64; - tinfocachebind(c.tc, n, r); + syntax.tinfocachebind(c.tc, n, r); r.ret = tinfofornode(c, n.lhs); - case nkind.N_TENUM: + case syntax.nkind.N_TENUM: // Cstage cmd/wcc/check.c:529-542: storage type's size/align // (default i32 = 4B/4B). Cgen's slotsize-TENUM fallback pads // to 8B per its stack-slot contract; tinfo.size carries the // raw storage width so size(EnumT) folds to the correct value. - r = newtype(tykind.TY_ENUM); - let storage: *tinfo = nil; + r = syntax.newtype(syntax.tykind.TY_ENUM); + let storage: *syntax.tinfo = nil; if (n.lhs != nil) { storage = tinfofornode(c, n.lhs); }; if (storage == nil) { storage = c.tc.tyi32; }; r.sub = storage; r.size = storage.size; r.align = storage.align; r.slotsize = storage.size; - case nkind.N_TTUPLE: + case syntax.nkind.N_TTUPLE: // Slot layout is the tuple SSoT (tuple arc C-t0, user-ratified): // ti.size = ti.slotsize = per-element slot sum (tupleelemslot — // a str/slice its header, everything else one 8B eightbyte), @@ -2182,8 +2182,8 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // cgen strode 8B slots — the checker-says-8/cgen-does-16 split // behind the packed-tuple miscompile family (#32/#33/#48). // Pre-bind for cycle protection (recursive tuple shapes). - r = newtype(tykind.TY_TUPLE); - tinfocachebind(c.tc, n, r); + r = syntax.newtype(syntax.tykind.TY_TUPLE); + syntax.tinfocachebind(c.tc, n, r); // #57 A.6.3i-phase-1: populate r.tupleelems as a ttupleelem // linked list (head=positional 0) in lock-step with the // size/align accumulator. Harec analog ref/harec/src/type_ @@ -2197,28 +2197,28 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // A.6.3f-a) for the head/tail append pattern. Offsets are // slot-cumulative (C-t0), distinct from harec's // add_padding(&offset, memb.align) at type_store.c:561. - let teh: *ttupleelem = nil; - let tet: *ttupleelem = nil; + let teh: *syntax.ttupleelem = nil; + let tet: *syntax.ttupleelem = nil; let slottotal: u64 = 0u64; let maxal: u64 = 1u64; - let p: *node = n.list; + let p: *syntax.node = n.list; for (p != nil) { - let pt: *tinfo = tinfofornode(c, p.lhs); + let pt: *syntax.tinfo = tinfofornode(c, p.lhs); // #62/#69: tuple-member value cycle — loud, cstage twin. if (circularnamed(c, pt, p.lhs)) { pt = c.tc.tyerr; }; // #24: a composite element (array/struct/nested tuple // >8B) cannot ride the 8B cursor slot — the #60 layout // drops it on construction and segvs on t.N[i] read. // Reject until #60/DISP-A inlines it; cstage twin. - let cu: *tinfo = tichase(pt); - if (cu != nil && (cu.kind == tykind.TY_ARRAY - || cu.kind == tykind.TY_STRUCT - || cu.kind == tykind.TY_TUPLE)) { + let cu: *syntax.tinfo = tichase(pt); + if (cu != nil && (cu.kind == syntax.tykind.TY_ARRAY + || cu.kind == syntax.tykind.TY_STRUCT + || cu.kind == syntax.tykind.TY_TUPLE)) { cerr("error: tuple element must be a scalar, str, slice, or tagged-union (composite element deferred to task #60)\n"); c.errs += 1; pt = c.tc.tyerr; }; - let te: *ttupleelem = alloc(ttupleelem{type_=pt, offset=slottotal, tnext=nil})!; + let te: *syntax.ttupleelem = alloc(syntax.ttupleelem{type_=pt, offset=slottotal, tnext=nil})!; if (teh == nil) { teh = te; } else { tet.tnext = te; }; tet = te; if (pt != nil) { @@ -2231,7 +2231,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { r.size = slottotal; r.align = maxal; r.slotsize = slottotal; - case nkind.N_TSTRUCT: + case syntax.nkind.N_TSTRUCT: // Cstage cmd/wcc/check.c:468-527: per-field alignment, max // align for the whole record, total rounded up to alignment. // Anonymous-embed promotion is deferred (#13). @@ -2251,8 +2251,8 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // struct; size-derived alignment; final round to 8). That // slot total lands in ti.slotsize so the cgen fast-path can // graduate TY_STRUCT off the AST walker. - r = newtype(tykind.TY_STRUCT); - tinfocachebind(c.tc, n, r); + r = syntax.newtype(syntax.tykind.TY_STRUCT); + syntax.tinfocachebind(c.tc, n, r); // #57 A.6.3i-phase-1: populate r.fields as a tfield linked // list (head=first declared field) in lock-step with the // natural-layout offset accumulator. Mirrors cstage cmd/wcc/ @@ -2263,15 +2263,15 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // ref/harec/src/type_store.c:314-347 struct_init_from_atype. // Anonymous-embed promotion not populated here (#13 per // the cstage cite at check.ww:1263). - let fh: *tfield = nil; - let ft_: *tfield = nil; + let fh: *syntax.tfield = nil; + let ft_: *syntax.tfield = nil; let off: u64 = 0u64; let maxalign: u64 = 1u64; let soff: u64 = 0u64; - let f: *node = n.list; + let f: *syntax.node = n.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { - let ft: *tinfo = tinfofornode(c, f.lhs); + if (f.kind == syntax.nkind.N_TFIELD) { + let ft: *syntax.tinfo = tinfofornode(c, f.lhs); // #62/#69: struct-field value cycle (`type s1 = // struct { x: s2 }; type s2 = struct { x: s1 }`) // — loud; pre-#62 this stack-overflowed the slot @@ -2283,7 +2283,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { off = (off + ft.align - 1u64) & ~(ft.align - 1u64); }; let fldoff: u64 = off; - let tf: *tfield = alloc(tfield{name=f.str, type_=ft, offset=fldoff, tnext=nil})!; + let tf: *syntax.tfield = alloc(syntax.tfield{name=f.str, type_=ft, offset=fldoff, tnext=nil})!; if (fh == nil) { fh = tf; } else { ft_.tnext = tf; }; ft_ = tf; off += ft.size; @@ -2311,7 +2311,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { soff = (soff + 7u64) & ~7u64; }; r.slotsize = soff; - case nkind.N_TTAGGED: + case syntax.nkind.N_TTAGGED: // THE tagged-union normalization SSoT (astsize/astalign delegate // here). Mirrors cstage resolve_type N_TTAGGED (cmd/wcc/check.c: // 801-882): 8B tag + max(variant) rounded up to 8, AFTER type-set @@ -2324,32 +2324,32 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // and (i32|i32|str) numbered str's tag 2 not 1 (cgen reads the // deduped ti.params). Pre-bind for cycle protection (recursive // sum-type shapes through NAMED variants). - r = newtype(tykind.TY_TAGGED); - tinfocachebind(c.tc, n, r); + r = syntax.newtype(syntax.tykind.TY_TAGGED); + syntax.tinfocachebind(c.tc, n, r); // #50 / A.6.3f phase 1: populate ti.params as a tparam linked // list (head=first surviving variant). #61a: flatten `...inner` // tagged spreads into the chain and stamp each variant's iserror. // Same shared Tparam shape ww reuses across struct-fields / // tuple-fields / fn-params / tagged-variants (sea-of-stars per // rule 12). - let head: *tparam = nil; - let tail: *tparam = nil; + let head: *syntax.tparam = nil; + let tail: *syntax.tparam = nil; let maxsz: u64 = 0u64; let al: u64 = 8u64; let nv: i32 = 0; - let v: *node = n.list; + let v: *syntax.node = n.list; for (v != nil) { - let vt: *tinfo = tinfofornode(c, v); + let vt: *syntax.tinfo = tinfofornode(c, v); // #62/#69: union-member value cycle — loud, cstage twin. if (circularnamed(c, vt, v)) { vt = c.tc.tyerr; }; - let isspread: bool = (v.op == tkind.TK_ELLIPSIS); - let vu: *tinfo = vt; + let isspread: bool = (v.op == syntax.tkind.TK_ELLIPSIS); + let vu: *syntax.tinfo = vt; // Full chase (F2a batch-4 c3-B1): the single peel left a // 2-level-alias inner union a SURFACE member — the box // sized off the inner union's own header, not its // spliced variants (cs twin check.c:755 chases). if (isspread) { vu = tichase(vu); }; - if (isspread && vu != nil && vu.kind == tykind.TY_TAGGED) { + if (isspread && vu != nil && vu.kind == syntax.tykind.TY_TAGGED) { // #209: a `...inner` spread's PAYLOAD is its // members, not the whole inner union — size/align // off each surviving spliced member (cstage check.c: @@ -2358,10 +2358,10 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // and desync the `field` slot from cstage's). Spliced // variants carry the inner union's already-stamped // iserror; no re-derivation. - let src: *tparam = vu.params; + let src: *syntax.tparam = vu.params; for (src != nil) { - let st: *tinfo = src.type_; - if (st != nil && st.kind == tykind.TY_NEVER) { + let st: *syntax.tinfo = src.type_; + if (st != nil && st.kind == syntax.tykind.TY_NEVER) { src = src.tnext; continue; }; if (variantpresent(head, st)) { @@ -2371,14 +2371,14 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { if (st.size > maxsz) { maxsz = st.size; }; if (st.align > al) { al = st.align; }; }; - let tp: *tparam = alloc(tparam{name="", type_=src.type_, iserror=src.iserror, tnext=nil})!; + let tp: *syntax.tparam = alloc(syntax.tparam{name="", type_=src.type_, iserror=src.iserror, tnext=nil})!; if (head == nil) { head = tp; } else { tail.tnext = tp; }; tail = tp; nv += 1; src = src.tnext; }; } else { - if (vt != nil && vt.kind == tykind.TY_NEVER) { + if (vt != nil && vt.kind == syntax.tykind.TY_NEVER) { v = v.next; continue; }; if (variantpresent(head, vt)) { @@ -2389,7 +2389,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { if (vt.align > al) { al = vt.align; }; }; let ve: bool = varianterr(c, v); - let tp: *tparam = alloc(tparam{name="", type_=vt, iserror=ve, tnext=nil})!; + let tp: *syntax.tparam = alloc(syntax.tparam{name="", type_=vt, iserror=ve, tnext=nil})!; if (head == nil) { head = tp; } else { tail.tnext = tp; }; tail = tp; nv += 1; @@ -2413,12 +2413,12 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // the tinfo layer; pre-#1 it AST-keyed n.list instead. let isnull: bool = false; if (nv == 2) { - let pa: *tparam = head; - let pb: *tparam = head.tnext; - let aptr: bool = (pa.type_ != nil && pa.type_.kind == tykind.TY_PTR); - let bptr: bool = (pb.type_ != nil && pb.type_.kind == tykind.TY_PTR); - let avoid: bool = (pa.type_ != nil && pa.type_.kind == tykind.TY_VOID && !pa.iserror); - let bvoid: bool = (pb.type_ != nil && pb.type_.kind == tykind.TY_VOID && !pb.iserror); + let pa: *syntax.tparam = head; + let pb: *syntax.tparam = head.tnext; + let aptr: bool = (pa.type_ != nil && pa.type_.kind == syntax.tykind.TY_PTR); + let bptr: bool = (pb.type_ != nil && pb.type_.kind == syntax.tykind.TY_PTR); + let avoid: bool = (pa.type_ != nil && pa.type_.kind == syntax.tykind.TY_VOID && !pa.iserror); + let bvoid: bool = (pb.type_ != nil && pb.type_.kind == syntax.tykind.TY_VOID && !pb.iserror); if (aptr) { if (bvoid) { isnull = true; }; }; if (avoid) { if (bptr) { isnull = true; }; }; }; @@ -2441,7 +2441,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // chan paths which already populate slotsize, plus TBANG which // inherits the inner's tinfo unchanged). if (r.slotsize == 0u64) { r.slotsize = r.size; }; - tinfocachebind(c.tc, n, r); + syntax.tinfocachebind(c.tc, n, r); }; return r; }; @@ -2458,7 +2458,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // with sym.decl == nil; #19 retires these as dedicated AST kinds). // Propagation, not silent gap — asserttyped gates those idents at the // consumer layer, so a nil operand never reaches the loud reject below. -fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { +fn unifyarith(c: *checker, e: *syntax.node, ltn: *syntax.node, rtn: *syntax.node) *syntax.node = { let lu: bool = isuntypedint(ltn) || isuntypedfloat(ltn); let ru: bool = isuntypedint(rtn) || isuntypedfloat(rtn); if (lu && ru) { @@ -2482,8 +2482,8 @@ fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { // above. Mirror cstage here off the operand node so the rune-literal / // integer mix stays valid (35 selfhost+lib sites) under the #26 reject. if (e != nil) { - let lr: bool = e.lhs != nil && e.lhs.kind == nkind.N_RUNELIT; - let rr: bool = e.rhs != nil && e.rhs.kind == nkind.N_RUNELIT; + let lr: bool = e.lhs != nil && e.lhs.kind == syntax.nkind.N_RUNELIT; + let rr: bool = e.rhs != nil && e.rhs.kind == syntax.nkind.N_RUNELIT; if (lr && isinttypeast(rtn)) { return rtn; }; if (rr && isinttypeast(ltn)) { return ltn; }; }; @@ -2498,13 +2498,13 @@ fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { // SK_TYPE too but decl == nil (check.ww:95-112), so aliassym alone // would mis-flag i32 as "named". This decl != nil gate is the wwstage // analog of cstage's `kind == TY_NAMED` (primitives are TY_I32 etc). - let ls: *sym = aliassym(c, unwrapbang(ltn)); - let rs: *sym = aliassym(c, unwrapbang(rtn)); + let ls: *syntax.sym = aliassym(c, unwrapbang(ltn)); + let rs: *syntax.sym = aliassym(c, unwrapbang(rtn)); let la: bool = ls != nil && ls.decl != nil; let ra: bool = rs != nil && rs.decl != nil; if (!(la && ra)) { - let da: *node = resolvealias(c, ltn); - let db: *node = resolvealias(c, rtn); + let da: *syntax.node = resolvealias(c, ltn); + let db: *syntax.node = resolvealias(c, rtn); if (da != nil && db != nil && varianterr(c, ltn) == varianterr(c, rtn) && typeeqast(c, da, db)) { @@ -2535,16 +2535,16 @@ fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { // f32 off the operands' float-kind, not the node stamp, so a stamped literal // inside an arith-binop / behind a unary minus does NOT narrow there — // binop / unary-minus / assign / call-arg / struct-field wait on #120. -fn coercefloatlit(c: *checker, e: *node, target: *node) void = { +fn coercefloatlit(c: *checker, e: *syntax.node, target: *syntax.node) void = { if (e == nil) { return; }; if (target == nil) { return; }; - let tu: *node = resolvealias(c, unwrapbang(target)); + let tu: *syntax.node = resolvealias(c, unwrapbang(target)); if (tu == nil) { return; }; - if (tu.kind != nkind.N_TNAME) { return; }; - if (!streq(tu.str, "f32")) { return; }; - if (e.kind == nkind.N_FLOATLIT) { - if ((e.type_: *tinfo) == c.tc.tyuntypedfloat) { - let f32t: *node = mktname(c, "f32"); + if (tu.kind != syntax.nkind.N_TNAME) { return; }; + if (!syntax.streq(tu.str, "f32")) { return; }; + if (e.kind == syntax.nkind.N_FLOATLIT) { + if ((e.type_: *syntax.tinfo) == c.tc.tyuntypedfloat) { + let f32t: *syntax.node = mktname(c, "f32"); e.type_ = tinfofornode(c, f32t): *void; }; }; @@ -2572,17 +2572,17 @@ fn coercefloatlit(c: *checker, e: *node, target: *node) void = { // keep harec's per-element range gate via checkarrlitfits's foldint / // defcastfits path (:4634). For a tagged-union target (fnmatch pat_next's // (u8 | star | ...)) return the first integer variant. -fn coercerunelit(c: *checker, e: *node, target: *node) *node = { +fn coercerunelit(c: *checker, e: *syntax.node, target: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - if (e.kind != nkind.N_RUNELIT) { return nil; }; + if (e.kind != syntax.nkind.N_RUNELIT) { return nil; }; if (target == nil) { return nil; }; - let tu: *node = resolvealias(c, unwrapbang(target)); + let tu: *syntax.node = resolvealias(c, unwrapbang(target)); if (tu == nil) { return nil; }; if (isinttypeast(tu)) { return tu; }; - if (tu.kind == nkind.N_TTAGGED) { - let v: *node = tu.list; + if (tu.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = tu.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { if (isinttypeast(vu)) { return vu; }; }; @@ -2597,29 +2597,29 @@ fn coercerunelit(c: *checker, e: *node, target: *node) *node = { // returned by exprtype; ptr arithmetic / bitwise / shifts / comparisons / // logicals all reflect cstage's rules. Type-mismatch diagnostics are // elided here (cstage gates the same shape). -fn binoptype(c: *checker, e: *node) *node = { - let op: tkind = e.op; - let ltn: *node = exprtype(c, e.lhs, nil); - let rtn: *node = exprtype(c, e.rhs, nil); +fn binoptype(c: *checker, e: *syntax.node) *syntax.node = { + let op: syntax.tkind = e.op; + let ltn: *syntax.node = exprtype(c, e.lhs, nil); + let rtn: *syntax.node = exprtype(c, e.rhs, nil); // #38/F2: ptr ± int / int + ptr use intkindast (the type_isint mirror, // incl untyped_int / untyped_rune / alias-chased) — NOT isinttypeast, // which misses untyped_int. cstage's ptr-arith arm gates on type_isint // (check.c:1179/1181), so `p + 1` (untyped_int) returns the ptr there // and never reaches the isnum gate; aligning these arms keeps the new // arithmetic gate below from rejecting valid pointer arithmetic. - if (op == tkind.TK_PLUS || op == tkind.TK_MINUS) { - if (ltn != nil && ltn.kind == nkind.N_TPTR && intkindast(c, rtn)) { + if (op == syntax.tkind.TK_PLUS || op == syntax.tkind.TK_MINUS) { + if (ltn != nil && ltn.kind == syntax.nkind.N_TPTR && intkindast(c, rtn)) { return ltn; }; }; - if (op == tkind.TK_PLUS) { - if (intkindast(c, ltn) && rtn != nil && rtn.kind == nkind.N_TPTR) { + if (op == syntax.tkind.TK_PLUS) { + if (intkindast(c, ltn) && rtn != nil && rtn.kind == syntax.nkind.N_TPTR) { return rtn; }; }; - if (op == tkind.TK_MINUS) { + if (op == syntax.tkind.TK_MINUS) { if (ltn != nil && rtn != nil - && ltn.kind == nkind.N_TPTR && rtn.kind == nkind.N_TPTR) { + && ltn.kind == syntax.nkind.N_TPTR && rtn.kind == syntax.nkind.N_TPTR) { return mktname(c, "i64"); }; }; @@ -2629,27 +2629,27 @@ fn binoptype(c: *checker, e: *node) *node = { // `let c: str = a + b;` (str+str) compiled to an integer ADD of the two // header pointers, silent garbage. The ptr-arithmetic special cases // above already returned, so a survivor here is plain value arithmetic. - if (op == tkind.TK_PLUS || op == tkind.TK_MINUS || - op == tkind.TK_STAR || op == tkind.TK_SLASH || - op == tkind.TK_PERCENT) { + if (op == syntax.tkind.TK_PLUS || op == syntax.tkind.TK_MINUS || + op == syntax.tkind.TK_STAR || op == syntax.tkind.TK_SLASH || + op == syntax.tkind.TK_PERCENT) { if ((ltn != nil && !numkindast(c, ltn)) || (rtn != nil && !numkindast(c, rtn))) { deffolderr(c, e, "arithmetic on non-numeric type"); }; return unifyarith(c, e, ltn, rtn); }; - if (op == tkind.TK_AMP || op == tkind.TK_PIPE || - op == tkind.TK_CARET || op == tkind.TK_LSHIFT || - op == tkind.TK_RSHIFT) { + if (op == syntax.tkind.TK_AMP || op == syntax.tkind.TK_PIPE || + op == syntax.tkind.TK_CARET || op == syntax.tkind.TK_LSHIFT || + op == syntax.tkind.TK_RSHIFT) { if ((ltn != nil && !intkindast(c, ltn)) || (rtn != nil && !intkindast(c, rtn))) { deffolderr(c, e, "bitwise on non-integer type"); }; return unifyarith(c, e, ltn, rtn); }; - if (op == tkind.TK_EQ || op == tkind.TK_NEQ || - op == tkind.TK_LT || op == tkind.TK_LE || - op == tkind.TK_GT || op == tkind.TK_GE) { + if (op == syntax.tkind.TK_EQ || op == syntax.tkind.TK_NEQ || + op == syntax.tkind.TK_LT || op == syntax.tkind.TK_LE || + op == syntax.tkind.TK_GT || op == syntax.tkind.TK_GE) { // cstage routes every comparison through unify_arith (check.c:1195/ // 1200 cbinop), which loud-rejects a differing-types pair, e.g. // strconv.invalid != i32. wwstage routes the ORDERED arm through @@ -2668,8 +2668,8 @@ fn binoptype(c: *checker, e: *node) *node = { // cstage's cbinop equality arm (check.c:1194-1196) gates nothing, // so str==str / ptr==ptr remain valid; aligning those down would // over-reject what cstage accepts. - if (op == tkind.TK_LT || op == tkind.TK_LE || - op == tkind.TK_GT || op == tkind.TK_GE) { + if (op == syntax.tkind.TK_LT || op == syntax.tkind.TK_LE || + op == syntax.tkind.TK_GT || op == syntax.tkind.TK_GE) { if ((ltn != nil && !numkindast(c, ltn)) || (rtn != nil && !numkindast(c, rtn))) { deffolderr(c, e, "ordered comparison on non-numeric"); @@ -2688,7 +2688,7 @@ fn binoptype(c: *checker, e: *node) *node = { }; return mktname(c, "bool"); }; - if (op == tkind.TK_AND || op == tkind.TK_OR) { + if (op == syntax.tkind.TK_AND || op == syntax.tkind.TK_OR) { // #38/F2 (review item 5): logical operands must be bool (cstage // check.c:1208-1211 gates each side via type_chase_named). cstage // formats per-side with tokname; ww's piecewise cerr can't splice @@ -2712,16 +2712,16 @@ fn binoptype(c: *checker, e: *node) *node = { // type_promote. The slice/str .len/.cap pseudo-field address-of widening // to *i64 mirrors check.c:672-682 directly — its purpose is documented // at the cstage site. -fn unoptype(c: *checker, e: *node) *node = { - let op: tkind = e.op; - let opt: *node = exprtype(c, e.lhs, nil); +fn unoptype(c: *checker, e: *syntax.node) *syntax.node = { + let op: syntax.tkind = e.op; + let opt: *syntax.node = exprtype(c, e.lhs, nil); // #38/F2 (review item 5): unop operand-kind gates the wwstage checker // elided. Mirror cstage cunop (cmd/wcc/check.c:1224-1238): unary +/- // want a numeric operand, ~ wants an integer, ! wants a bool. A nil // opt is an already-errored / inherent-IDENT bail — not re-rejected. - if (op == tkind.TK_MINUS || op == tkind.TK_PLUS) { + if (op == syntax.tkind.TK_MINUS || op == syntax.tkind.TK_PLUS) { if (opt != nil && !numkindast(c, opt)) { - if (op == tkind.TK_MINUS) { + if (op == syntax.tkind.TK_MINUS) { deffolderr(c, e, "- on non-numeric"); } else { deffolderr(c, e, "+ on non-numeric"); @@ -2729,19 +2729,19 @@ fn unoptype(c: *checker, e: *node) *node = { }; return opt; }; - if (op == tkind.TK_NOT) { + if (op == syntax.tkind.TK_NOT) { if (opt != nil && !boolkindast(c, opt)) { deffolderr(c, e, "! on non-bool"); }; return mktname(c, "bool"); }; - if (op == tkind.TK_TILDE) { + if (op == syntax.tkind.TK_TILDE) { if (opt != nil && !intkindast(c, opt)) { deffolderr(c, e, "~ on non-integer"); }; return opt; }; - if (op == tkind.TK_STAR) { + if (op == syntax.tkind.TK_STAR) { // opt nil here means the operand was an inherent-IDENT bail // (exprtype N_IDENT arm L1596-1599 — SK_USE / pseudo-builtin // sym.decl == nil — or another helper's nil propagation); @@ -2751,17 +2751,17 @@ fn unoptype(c: *checker, e: *node) *node = { // resolvealias passes through non-nil unchanged (L513 // `for (cur != nil)` only exits via `return cur` or `return n`). if (opt == nil) { return nil; }; - let u: *node = resolvealias(c, unwrapbang(opt)); + let u: *syntax.node = resolvealias(c, unwrapbang(opt)); // Invalid input (non-pointer dereference); cstage errors at // cmd/wcc/check.c:660. 5-lite-b #34. - if (u.kind != nkind.N_TPTR) { return nil; }; + if (u.kind != syntax.nkind.N_TPTR) { return nil; }; return u.lhs; }; - if (op == tkind.TK_AMP) { - if (e.lhs != nil && e.lhs.kind == nkind.N_DOT) { + if (op == syntax.tkind.TK_AMP) { + if (e.lhs != nil && e.lhs.kind == syntax.nkind.N_DOT) { let fld: str = e.lhs.str; - if (streq(fld, "len") || streq(fld, "cap")) { - let base: *node = e.lhs.lhs; + if (syntax.streq(fld, "len") || syntax.streq(fld, "cap")) { + let base: *syntax.node = e.lhs.lhs; if (base != nil && base.type_ != nil) { // Full chase per hop (F2a batch-4 c3-B2): // the one-peel-per-hop walk lost 2-level @@ -2771,12 +2771,12 @@ fn unoptype(c: *checker, e: *node) *node = { // stays loud for ALL alias bases (task // #96) — this aligns the stamped type // only; rows graduate with #96. - let bu: *tinfo = tichase(base.type_: *tinfo); - if (bu != nil && bu.kind == tykind.TY_PTR) { bu = bu.sub; }; + let bu: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu != nil && bu.kind == syntax.tykind.TY_PTR) { bu = bu.sub; }; bu = tichase(bu); if (bu != nil) { - if (bu.kind == tykind.TY_SLICE || bu.kind == tykind.TY_STR) { - let pp: *node = newnode(nkind.N_TPTR, "", 0, 0); + if (bu.kind == syntax.tykind.TY_SLICE || bu.kind == syntax.tykind.TY_STR) { + let pp: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pp.lhs = mktname(c, "i64"); return pp; }; @@ -2795,21 +2795,21 @@ fn unoptype(c: *checker, e: *node) *node = { // cstage, where a fn ident already types as TY_FN // (cmd/wcc/check.c:668), so `&fn` is `*fn` natively. if (e.lhs != nil) { - if (e.lhs.kind == nkind.N_IDENT) { + if (e.lhs.kind == syntax.nkind.N_IDENT) { // #4: curmod preference. A bare `&handler` whose leaf // also names a fn in a LATER module otherwise binds // the foreign signature (scopedefineinmodule prepends); // cstage types a fn ident via scope_lookup_prefer with // cur_mod (cmd/wcc/check.c:1305). - let fs: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); + let fs: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.lhs.str); if (fs != nil) { - if (fs.skind == skind.SK_FN) { + if (fs.skind == syntax.skind.SK_FN) { if (fs.decl != nil) { - if (fs.decl.kind == nkind.N_FNDECL) { - let synth: *node = newnode(nkind.N_TFN, "", 0, 0); + if (fs.decl.kind == syntax.nkind.N_FNDECL) { + let synth: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); synth.lhs = fs.decl.lhs; synth.list = fs.decl.list; - let pf: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pf: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pf.lhs = synth; return pf; }; @@ -2825,17 +2825,17 @@ fn unoptype(c: *checker, e: *node) *node = { // typeeq → confident reject; cstage types `&mod.fn` as `*fn` // natively (a dotted fn ref is TY_FN), so this aligns ww UP to // cstage's actual acceptance reason. - if (e.lhs.kind == nkind.N_DOT) { - if (e.lhs.lhs != nil && e.lhs.lhs.kind == nkind.N_IDENT) { - let fs: *sym = scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.lhs.str), e.lhs.str); + if (e.lhs.kind == syntax.nkind.N_DOT) { + if (e.lhs.lhs != nil && e.lhs.lhs.kind == syntax.nkind.N_IDENT) { + let fs: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.lhs.str), e.lhs.str); if (fs != nil) { - if (fs.skind == skind.SK_FN) { + if (fs.skind == syntax.skind.SK_FN) { if (fs.decl != nil) { - if (fs.decl.kind == nkind.N_FNDECL) { - let synth: *node = newnode(nkind.N_TFN, "", 0, 0); + if (fs.decl.kind == syntax.nkind.N_FNDECL) { + let synth: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); synth.lhs = fs.decl.lhs; synth.list = fs.decl.list; - let pf: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pf: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pf.lhs = synth; return pf; }; @@ -2849,7 +2849,7 @@ fn unoptype(c: *checker, e: *node) *node = { // #34). Generic &expr widens to *opt; without opt we can't // synthesize the pointer node. if (opt == nil) { return nil; }; - let pp: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pp: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pp.lhs = opt; return pp; }; @@ -2865,32 +2865,32 @@ fn unoptype(c: *checker, e: *node) *node = { // to T (pointer-to-array); `*[]T` does NOT decay (yields []T via the // generic *U → U fallback — Hare-faithful, a pointer-to-slice is a 1D // array of slices, not of T); generic *T → T. -fn indexresult(c: *checker, e: *node) *node = { - let basetn: *node = exprtype(c, e.lhs, nil); - let _idx: *node = exprtype(c, e.rhs, nil); - let u: *node = resolvealias(c, unwrapbang(basetn)); +fn indexresult(c: *checker, e: *syntax.node) *syntax.node = { + let basetn: *syntax.node = exprtype(c, e.lhs, nil); + let _idx: *syntax.node = exprtype(c, e.rhs, nil); + let u: *syntax.node = resolvealias(c, unwrapbang(basetn)); // basetn nil → propagation from inherent-IDENT bail at exprtype // N_IDENT arm L1596-1599 (5-lite-b #34, A.6.2.1c #24). // unwrapbang(nil)=nil and resolvealias(nil)=nil pass through. if (u == nil) { return nil; }; - if (u.kind == nkind.N_TSLICE) { return u.lhs; }; - if (u.kind == nkind.N_TARRAY) { return u.lhs; }; - if (u.kind == nkind.N_TNAME) { + if (u.kind == syntax.nkind.N_TSLICE) { return u.lhs; }; + if (u.kind == syntax.nkind.N_TARRAY) { return u.lhs; }; + if (u.kind == syntax.nkind.N_TNAME) { // rule-9 divergence-doc (drew .ai/drew-14-ruling.md): `str[i] -> // u8` is a deliberate Go-like direct byte-index, a SANCTIONED ww // divergence from Hare's `strings::toutf8(s)[i]` (the Hare // reference checker rejects str-index, harec check.c:362). // lib/strings is load-bearing on it (compare/dup/join). - if (streq(u.str, "str")) { + if (syntax.streq(u.str, "str")) { // #14: reject INDEX of a bare def-global scalar str — an // inline compile-time constant with no storage to index // (cgen refs an unbacked symbol -> link-fail ww / segfault // cs). let/param/local + string-literal operands stay // valid; only the SK_DEF scalar-str operand is // unindexable. cstage twin: check.c N_INDEX TY_STR arm. - if (e.lhs != nil && e.lhs.kind == nkind.N_IDENT) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); - if (s != nil && s.skind == skind.SK_DEF) { + if (e.lhs != nil && e.lhs.kind == syntax.nkind.N_IDENT) { + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.lhs.str); + if (s != nil && s.skind == syntax.skind.SK_DEF) { cerr("error: cannot index a def-constant str '"); cerr(e.lhs.str); cerr("'; bind it to a `let` (def strings are inline constants, not storage-backed)\n"); @@ -2901,10 +2901,10 @@ fn indexresult(c: *checker, e: *node) *node = { return mktname(c, "u8"); }; }; - if (u.kind == nkind.N_TPTR) { - let inner: *node = u.lhs; - let iu: *node = resolvealias(c, unwrapbang(inner)); - if (iu != nil && iu.kind == nkind.N_TARRAY) { + if (u.kind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = u.lhs; + let iu: *syntax.node = resolvealias(c, unwrapbang(inner)); + if (iu != nil && iu.kind == syntax.nkind.N_TARRAY) { return iu.lhs; }; return inner; @@ -2941,79 +2941,79 @@ fn indexresult(c: *checker, e: *node) *node = { // inherent-IDENT bails (SK_USE, pseudo-builtin sym.decl==nil, // N_DOT-LHS syntactic position, EXPR_ASSERT-family abort/assert) until // #19 retires the bail shape. -fn exprtype(c: *checker, e: *node, hint: *node) *node = { +fn exprtype(c: *checker, e: *syntax.node, hint: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - let k: nkind = e.kind; + let k: syntax.nkind = e.kind; // #61 audit §1.8 — A.2 widens A.1's single N_INTLIT population to // every primitive literal arm + N_IDENT. Cgen size walkers // (slotsize first; elemsize/fieldsize/letemitsize follow) consult // node.type_ as the SSoT; populating literals + idents closes the // loop from the read side. - if (k == nkind.N_INTLIT) { + if (k == syntax.nkind.N_INTLIT) { // Typed-int literal (`7u32`, `0i8`): tsuffix names a builtin // primitive. Mirrors cstage cmd/wcc/check.c:694-701 cexpr's // `lookup_builtin(n->tsuffix)`; falls through to untyped_int // when the suffix doesn't resolve. if (e.tsuffix.len > 0) { - let suf: *node = mktname(c, e.tsuffix); - let ti: *tinfo = tinfofornode(c, suf); + let suf: *syntax.node = mktname(c, e.tsuffix); + let ti: *syntax.tinfo = tinfofornode(c, suf); if (ti != nil) { e.type_ = ti: *void; return suf; }; }; - let tn: *node = mktname(c, "untyped_int"); + let tn: *syntax.node = mktname(c, "untyped_int"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_FLOATLIT) { + if (k == syntax.nkind.N_FLOATLIT) { // Typed-float literal (`1.5f32`, `0.0f64`): tsuffix names a // builtin primitive. Mirrors cstage cmd/wcc/check.c:702-709 // cexpr's `lookup_builtin(n->tsuffix)`; falls through to // untyped_float when the suffix doesn't resolve. if (e.tsuffix.len > 0) { - let suf: *node = mktname(c, e.tsuffix); - let ti: *tinfo = tinfofornode(c, suf); + let suf: *syntax.node = mktname(c, e.tsuffix); + let ti: *syntax.tinfo = tinfofornode(c, suf); if (ti != nil) { e.type_ = ti: *void; return suf; }; }; - let tn: *node = mktname(c, "untyped_float"); + let tn: *syntax.node = mktname(c, "untyped_float"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_STRLIT) { - let tn: *node = mktname(c, "str"); + if (k == syntax.nkind.N_STRLIT) { + let tn: *syntax.node = mktname(c, "str"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_RUNELIT) { - let tn: *node = mktname(c, "rune"); + if (k == syntax.nkind.N_RUNELIT) { + let tn: *syntax.node = mktname(c, "rune"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_TRUE) { - let tn: *node = mktname(c, "bool"); + if (k == syntax.nkind.N_TRUE) { + let tn: *syntax.node = mktname(c, "bool"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_FALSE) { - let tn: *node = mktname(c, "bool"); + if (k == syntax.nkind.N_FALSE) { + let tn: *syntax.node = mktname(c, "bool"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_VOIDLIT) { - let tn: *node = mktname(c, "void"); + if (k == syntax.nkind.N_VOIDLIT) { + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_NIL) { - let tn: *node = mktname(c, "untyped_nil"); + if (k == syntax.nkind.N_NIL) { + let tn: *syntax.node = mktname(c, "untyped_nil"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { // #55: bare-leaf value-ident must prefer curmod. Flat-scope // scopelookup bucket-walks and can bind a same-leaf symbol from // the wrong module under a foreign curmod, dragging its decl's @@ -3021,7 +3021,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // bare `error` then binds strconv.error not io.error). Mirrors // cstage cmd/wcc/check.c:66 scope_lookup_prefer; sibling #56 at // L2439, #53 at L688. Tracked in the cluster note at L685-687. - let s: *sym = scopelookupprefer(c.cur, c.curmod, e.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; // #34: a bare fn-name rvalue types as its FN TYPE, not its return @@ -3036,21 +3036,21 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // root of the #24 fn-family over-rejects (`let p: fn()i32 = g` compared // i32 vs the fn type). cgen lowers a fn rvalue name-keyed via // fnretlookup (cgenexpr.ww:1100), never off this stamp → byte-id-neutral. - if (s.skind == skind.SK_FN) { - let ft: *node = newnode(nkind.N_TFN, "", 0, 0); + if (s.skind == syntax.skind.SK_FN) { + let ft: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); ft.lhs = s.decl.lhs; ft.list = s.decl.list; e.type_ = tinfofornode(c, ft): *void; return ft; }; - let t: *node = s.decl.lhs; + let t: *syntax.node = s.decl.lhs; // Propagate the declared type's tinfo onto the use site so // downstream cgen walkers can read n.type_ off an ident. if (t != nil) { if (t.type_ != nil) { e.type_ = t.type_; } else { - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { e.type_ = ti: *void; t.type_ = ti: *void; @@ -3059,29 +3059,29 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; return t; }; - if (k == nkind.N_BIN) { - let tn: *node = binoptype(c, e); + if (k == syntax.nkind.N_BIN) { + let tn: *syntax.node = binoptype(c, e); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_UN) { - let tn: *node = unoptype(c, e); + if (k == syntax.nkind.N_UN) { + let tn: *syntax.node = unoptype(c, e); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_INDEX) { - let tn: *node = indexresult(c, e); + if (k == syntax.nkind.N_INDEX) { + let tn: *syntax.node = indexresult(c, e); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { // `expr: T` — explicit cast; the type expr is e.rhs. Mirrors // cstage cmd/wcc/check.c:737 `n->type = resolve_type(c, n->rhs)`. e.type_ = tinfofornode(c, e.rhs): *void; return e.rhs; }; - if (k == nkind.N_CALL) { - let callee: *node = e.lhs; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = e.lhs; if (callee == nil) { return nil; }; // #31: synthesize the `alloc(value)` / `alloc([], n)` builtin // return shape so checkletassign sees the same `(*T | nomem)` / @@ -3090,18 +3090,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // silently accepts `let p: *T = alloc(v);` — rule 10 trap. // Same-module gate mirrors cstage's `c->cur_mod && // scope_lookup_in_module(...)` check from task #23. - if (callee.kind == nkind.N_IDENT) { - if (streq(callee.str, "alloc")) { + if (callee.kind == syntax.nkind.N_IDENT) { + if (syntax.streq(callee.str, "alloc")) { let shadowed: bool = false; if (c.curmod.len > 0) { - if (scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { + if (syntax.scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { shadowed = true; }; }; if (!shadowed) { if (e.list != nil) { // Slice form: `alloc([], n)`. - if (e.list.kind == nkind.N_ARRLIT) { + if (e.list.kind == syntax.nkind.N_ARRLIT) { if (e.list.list == nil) { if (e.list.next != nil) { if (e.list.next.next == nil) { @@ -3122,11 +3122,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { deffolderr(c, e, "cannot infer slice element type for alloc([], n) without a type hint; annotate the binding, e.g. let x: []T = alloc([], n)"); return nil; }; - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = mktname(c, "u8"); - let nome: *node = mktname(c, "nomem"); + let nome: *syntax.node = mktname(c, "nomem"); sl.next = nome; - let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTAGGED, "", 0, 0); tt.list = sl; e.type_ = tinfofornode(c, tt): *void; return tt; @@ -3136,12 +3136,12 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; // Value form: `alloc(value)`. if (e.list.next == nil) { - let argt: *node = exprtype(c, e.list, nil); - let ptr: *node = newnode(nkind.N_TPTR, "", 0, 0); + let argt: *syntax.node = exprtype(c, e.list, nil); + let ptr: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); ptr.lhs = argt; - let nome: *node = mktname(c, "nomem"); + let nome: *syntax.node = mktname(c, "nomem"); ptr.next = nome; - let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTAGGED, "", 0, 0); tt.list = ptr; e.type_ = tinfofornode(c, tt): *void; return tt; @@ -3156,11 +3156,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // mirrors the alloc precedent (#23) so a user `fn size(...)` // inside this module suppresses the builtin. Mirrors cstage // cmd/wcc/check.c:907-960. - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { let bname: str = callee.str; - let issize: bool = streq(bname, "size"); - let isalign: bool = streq(bname, "align"); - let isoffset: bool = streq(bname, "offset"); + let issize: bool = syntax.streq(bname, "size"); + let isalign: bool = syntax.streq(bname, "align"); + let isoffset: bool = syntax.streq(bname, "offset"); if (issize || isalign || isoffset) { // #38/F2 (review item 7): UNCONDITIONAL intercept — cstage // gates size/align/offset on NOTHING (cmd/wcc/check.c:1538- @@ -3177,7 +3177,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // otherwise folded the unresolved N_TNAME to 0 silently // (rc=0 wrong binary). offset's arg is a value N_DOT and // keeps its own "no field" diagnostic below. - if ((issize || isalign) && e.list.kind == nkind.N_TNAME + if ((issize || isalign) && e.list.kind == syntax.nkind.N_TNAME && tinfofornode(c, e.list) == nil) { cerr(e.list.file); cerr(": error: unknown type '"); @@ -3191,7 +3191,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // ty_untyped_int after the fold AND returns it // to the caller (the Hare-correct type), so a // `let x: size = size(T)` binding is assignable. - let utn: *node = mktname(c, "untyped_int"); + let utn: *syntax.node = mktname(c, "untyped_int"); if (issize) { // #108(b): rule-10 twin of the cstage // size/align unsized guard. @@ -3216,7 +3216,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // (N_DOT), parsed via parsearglist — not a // type expression. if (isoffset) { - if (e.list.next == nil && e.list.kind == nkind.N_DOT) { + if (e.list.next == nil && e.list.kind == syntax.nkind.N_DOT) { let off: i64 = astoffset(c, e.list); if (off < 0i64) { cerr("offset: no field '"); @@ -3247,7 +3247,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // this task; #19 (Drew's δ — dedicated AST kinds) is the // Hare-faithful path. This is the intercept-shim minimum to // unblock #15 (A.6.2.1e assertion enable). - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { // abort([msg]) / assert(cond[, msg]) — the EXPR_ASSERT // family (harec ref/harec/src/check.c:877,893), lowered // to rt_abort. Builtin only when no user symbol shadows @@ -3257,10 +3257,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // flat-scope root is filed as task #14). // The TY_ERR stamp on the callee is cgen's routing key // (cstage spells it `n->lhs->type = ty_err`). - if (streq(callee.str, "abort") - && scopelookupprefer(c.cur, c.curmod, "abort") == nil) { + if (syntax.streq(callee.str, "abort") + && syntax.scopelookupprefer(c.cur, c.curmod, "abort") == nil) { if (e.list != nil) { - let mt: *node = exprtype(c, e.list, nil); + let mt: *syntax.node = exprtype(c, e.list, nil); let conf: bool = false; if (!isassignable(c, mktname(c, "str"), mt, &conf)) { cerr("abort: message must be str\n"); @@ -3271,14 +3271,14 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { c.errs += 1; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; callee.type_ = c.tc.tyerr: *void; return tn; }; - if (streq(callee.str, "assert") && e.list != nil - && scopelookupprefer(c.cur, c.curmod, "assert") == nil) { - let ct: *node = exprtype(c, e.list, nil); + if (syntax.streq(callee.str, "assert") && e.list != nil + && syntax.scopelookupprefer(c.cur, c.curmod, "assert") == nil) { + let ct: *syntax.node = exprtype(c, e.list, nil); if (ct != nil) { // No alias peel: cstage compares ty_bool by // IDENTITY (cmd/wcc/check.c:1560), so a @@ -3286,11 +3286,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // align down (rule 10). Widening belongs to // the alias-peel choke-point arc (task #5, // #47/#68), both stages together. - let cu: *node = unwrapbang(ct); + let cu: *syntax.node = unwrapbang(ct); let condok: bool = false; - if (cu.kind == nkind.N_TNAME) { - if (streq(cu.str, "bool") - || streq(cu.str, "untyped_bool")) { + if (cu.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(cu.str, "bool") + || syntax.streq(cu.str, "untyped_bool")) { condok = true; }; }; @@ -3300,7 +3300,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; }; if (e.list.next != nil) { - let mt: *node = exprtype(c, e.list.next, nil); + let mt: *syntax.node = exprtype(c, e.list.next, nil); let conf: bool = false; if (!isassignable(c, mktname(c, "str"), mt, &conf)) { cerr("assert: message must be str\n"); @@ -3311,18 +3311,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { c.errs += 1; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; callee.type_ = c.tc.tyerr: *void; return tn; }; - if (streq(callee.str, "len")) { - let tn: *node = mktname(c, "i32"); + if (syntax.streq(callee.str, "len")) { + let tn: *syntax.node = mktname(c, "i32"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (streq(callee.str, "append") || streq(callee.str, "free")) { - let tn: *node = mktname(c, "void"); + if (syntax.streq(callee.str, "append") || syntax.streq(callee.str, "free")) { + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -3335,8 +3335,8 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // delete(xs[i..j])); either way the OBJECT must be a // slice. The range form is the fold-5a prereq P2 // (regex.ha:333 delete(jump_idxs[group_level][..])). - if (streq(callee.str, "delete")) { - let d: *node = e.list; + if (syntax.streq(callee.str, "delete")) { + let d: *syntax.node = e.list; if (d == nil || d.next != nil) { cerr("delete: takes exactly one argument\n"); c.errs += 1; @@ -3345,22 +3345,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { exprtype(c, d, nil); // harec check.c:2016's reject; wording // adapted to ww's delete: prefix. - if (d.kind != nkind.N_INDEX && d.kind != nkind.N_SLICE) { + if (d.kind != syntax.nkind.N_INDEX && d.kind != syntax.nkind.N_SLICE) { cerr("delete: operand must be an indexing or slicing expression\n"); c.errs += 1; } else { - let basetn: *node = exprtype(c, d.lhs, nil); - let u: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, d.lhs, nil); + let u: *syntax.node = resolvealias(c, unwrapbang(basetn)); // harec check.c:2024 wording; a // fixed-size [N]T base and a str // base land here. - if (u == nil || u.kind != nkind.N_TSLICE) { + if (u == nil || u.kind != syntax.nkind.N_TSLICE) { cerr("delete must operate on a slice\n"); c.errs += 1; }; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -3375,34 +3375,34 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // form (harec :821/:837) stay filed on #35; a range // PLACE is not Hare (harec asserts ACCESS_INDEX at // :784) — rejected, no task cite. - if (streq(callee.str, "insert")) { - let d: *node = e.list; + if (syntax.streq(callee.str, "insert")) { + let d: *syntax.node = e.list; if (d == nil || d.next == nil || d.next.next != nil) { cerr("insert: takes exactly two arguments\n"); c.errs += 1; }; if (d != nil) { exprtype(c, d, nil); - if (d.kind == nkind.N_SLICE) { + if (d.kind == syntax.nkind.N_SLICE) { cerr("insert: range place is invalid; operand must be an indexing expression xs[i]\n"); c.errs += 1; } else { - if (d.kind != nkind.N_INDEX) { + if (d.kind != syntax.nkind.N_INDEX) { cerr("insert: operand must be an indexing expression xs[i]\n"); c.errs += 1; } else { - let basetn: *node = exprtype(c, d.lhs, nil); - let u: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, d.lhs, nil); + let u: *syntax.node = resolvealias(c, unwrapbang(basetn)); // harec check.c:807 wording; a // fixed-size [N]T base lands here. - if (u == nil || u.kind != nkind.N_TSLICE) { + if (u == nil || u.kind != syntax.nkind.N_TSLICE) { cerr("insert must operate on a slice\n"); c.errs += 1; }; }; }; if (d.next != nil) { - if (d.next.kind == nkind.N_SPREAD) { + if (d.next.kind == syntax.nkind.N_SPREAD) { cerr("insert: spread form insert(xs[i], vs...) unimplemented (task #35)\n"); c.errs += 1; } else { @@ -3410,15 +3410,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; }; let nm: str; nm.ptr = nil; nm.len = 0; - if (callee.kind == nkind.N_IDENT) { nm = callee.str; }; - if (callee.kind == nkind.N_DOT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_IDENT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_DOT) { nm = callee.str; }; // #56: bare-leaf N_IDENT calls go through scopelookupprefer so // `foo()` inside module M binds to M.foo rather than another // module's same-leaf foo at the head of the flat scope bucket. @@ -3457,15 +3457,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // cgen post-#180+#185 already lowers the deref-call correctly, // so lifting the asserttyped bail is silent-SIGSEGV-safe. if (nm.len > 0) { - let s: *sym = nil; - if (callee.kind == nkind.N_IDENT) { - s = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = nil; + if (callee.kind == syntax.nkind.N_IDENT) { + s = syntax.scopelookupprefer(c.cur, c.curmod, nm); } else { - let ms: *sym = nil; - if (callee.lhs != nil && callee.lhs.kind == nkind.N_IDENT) { - ms = scopelookupprefer(c.cur, c.curmod, callee.lhs.str); - if (ms != nil && ms.skind != skind.SK_USE) { - let mu: *sym = scopelookupuselocal(ms.scope, callee.lhs.str); + let ms: *syntax.sym = nil; + if (callee.lhs != nil && callee.lhs.kind == syntax.nkind.N_IDENT) { + ms = syntax.scopelookupprefer(c.cur, c.curmod, callee.lhs.str); + if (ms != nil && ms.skind != syntax.skind.SK_USE) { + let mu: *syntax.sym = syntax.scopelookupuselocal(ms.scope, callee.lhs.str); if (mu != nil) { ms = mu; }; }; }; @@ -3484,11 +3484,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // :1378-1433 (call result IS the callee type's ret; no // global-leaf path) and harec check_autodereference // (ref/harec/src/check.c:1566-1581). - if (ms != nil && (ms.skind == skind.SK_USE || ms.use_alias != 0i32)) { - s = scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), nm); + if (ms != nil && (ms.skind == syntax.skind.SK_USE || ms.use_alias != 0i32)) { + s = syntax.scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), nm); }; }; - if (s != nil) { if (s.skind == skind.SK_FN) { if (s.decl != nil) { + if (s != nil) { if (s.skind == syntax.skind.SK_FN) { if (s.decl != nil) { // fn-decl's lhs is the return-type AST node. Mirrors cstage // cmd/wcc/check.c:984+ regular-CALL `n->type = // build_fn_type(c, s->decl)->ret` shape. @@ -3506,18 +3506,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // name path stays primary because a fn-NAME callee node in wwstage // already carries its RETURN type (fn-decl.lhs), not its fn-type — // so a `fn make() fn() void` callee would otherwise mis-yield void. - let ct: *node = resolvealias(c, unwrapbang(exprtype(c, callee, nil))); - for (ct != nil && ct.kind == nkind.N_TPTR) { + let ct: *syntax.node = resolvealias(c, unwrapbang(exprtype(c, callee, nil))); + for (ct != nil && ct.kind == syntax.nkind.N_TPTR) { ct = resolvealias(c, unwrapbang(ct.lhs)); }; - if (ct != nil) { if (ct.kind == nkind.N_TFN) { - let res: *node = ct.lhs; + if (ct != nil) { if (ct.kind == syntax.nkind.N_TFN) { + let res: *syntax.node = ct.lhs; e.type_ = tinfofornode(c, res): *void; return res; }; }; return nil; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // A.6.1.5a — fold cases only. Mirrors cstage cmd/wcc/check.c // :740-832. Struct field + pseudo-field (.len/.cap/.ptr) lands // in A.6.1.5b. SK_USE gates case 1; a #6a-D dot-lhs collision @@ -3530,11 +3530,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // to enumvalfold, matching cstage cmd/wcc/check.c:210-284 and // harec's enum-resolve constexpr set at // ref/harec/src/check.c:4419-4434. - let lhsn: *node = e.lhs; - if (lhsn != nil) { if (lhsn.kind == nkind.N_IDENT) { - let ms: *sym = scopelookupprefer(c.cur, c.curmod, lhsn.str); - if (ms != nil && ms.skind != skind.SK_USE) { - let mu: *sym = scopelookupuselocal(ms.scope, lhsn.str); + let lhsn: *syntax.node = e.lhs; + if (lhsn != nil) { if (lhsn.kind == syntax.nkind.N_IDENT) { + let ms: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, lhsn.str); + if (ms != nil && ms.skind != syntax.skind.SK_USE) { + let mu: *syntax.sym = syntax.scopelookupuselocal(ms.scope, lhsn.str); if (mu != nil) { ms = mu; }; }; if (ms != nil) { @@ -3544,21 +3544,21 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // through to outer case — cgen has its own module- // qualified resolution and the lenient checker policy // keeps the silent miss documented at scruttype L656. - if (ms.skind == skind.SK_USE || ms.use_alias != 0i32) { - let fs: *sym = scopelookupinmodule(c.cur, modkeyfor(c, lhsn.str), e.str); + if (ms.skind == syntax.skind.SK_USE || ms.use_alias != 0i32) { + let fs: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, lhsn.str), e.str); if (fs != nil) { if (fs.decl != nil) { // #34: a module-qualified bare fn rvalue `mod.fn` types as // its FN TYPE (twin of the N_IDENT arm, :2688); decl.lhs is // the RETURN type for an N_FNDECL. Pins 706 (`let p1: fn()i32 // = mod1.ping`). - if (fs.skind == skind.SK_FN) { - let ft: *node = newnode(nkind.N_TFN, "", 0, 0); + if (fs.skind == syntax.skind.SK_FN) { + let ft: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); ft.lhs = fs.decl.lhs; ft.list = fs.decl.list; e.type_ = tinfofornode(c, ft): *void; return ft; }; - let tn: *node = fs.decl.lhs; + let tn: *syntax.node = fs.decl.lhs; if (tn != nil) { e.type_ = tinfofornode(c, tn): *void; return tn; @@ -3568,12 +3568,12 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Fold case 2 inner: bare `EnumT.MEMBER` where EnumT // is an SK_TYPE in the flat scope. Mirror cstage // check.c:780-803. - if (ms.skind == skind.SK_TYPE) { if (ms.decl != nil) { - let body: *node = ms.decl.lhs; - let ub: *node = resolvealias(c, unwrapbang(body)); - if (ub != nil) { if (ub.kind == nkind.N_TENUM) { + if (ms.skind == syntax.skind.SK_TYPE) { if (ms.decl != nil) { + let body: *syntax.node = ms.decl.lhs; + let ub: *syntax.node = resolvealias(c, unwrapbang(body)); + if (ub != nil) { if (ub.kind == syntax.nkind.N_TENUM) { let prev: u64 = (-1i64): u64; - let m: *node = ub.list; + let m: *syntax.node = ub.list; for (m != nil) { let val: u64 = 0u64; if (m.lhs == nil) { @@ -3582,7 +3582,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { if (!enumvalfold(ub, m, m.lhs, &val)) { return nil; }; }; prev = val; - if (streq(m.str, e.str)) { + if (syntax.streq(m.str, e.str)) { foldtointlit(c, e, val: i64); e.type_ = tinfofornode(c, body): *void; return body; @@ -3598,15 +3598,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // via case 1 above to the enum body. Mirror cstage // check.c:805-832. Peel one TPTR for `(*EnumT).MEMBER` (rare // but cstage handles it at L808). - let basetn: *node = exprtype(c, lhsn, nil); + let basetn: *syntax.node = exprtype(c, lhsn, nil); if (basetn != nil) { - let bu: *node = resolvealias(c, unwrapbang(basetn)); - if (bu != nil) { if (bu.kind == nkind.N_TPTR) { + let bu: *syntax.node = resolvealias(c, unwrapbang(basetn)); + if (bu != nil) { if (bu.kind == syntax.nkind.N_TPTR) { bu = resolvealias(c, unwrapbang(bu.lhs)); }; }; - if (bu != nil) { if (bu.kind == nkind.N_TENUM) { + if (bu != nil) { if (bu.kind == syntax.nkind.N_TENUM) { let prev: u64 = (-1i64): u64; - let m: *node = bu.list; + let m: *syntax.node = bu.list; for (m != nil) { let val: u64 = 0u64; if (m.lhs == nil) { @@ -3615,7 +3615,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { if (!enumvalfold(bu, m, m.lhs, &val)) { return nil; }; }; prev = val; - if (streq(m.str, e.str)) { + if (syntax.streq(m.str, e.str)) { foldtointlit(c, e, val: i64); e.type_ = tinfofornode(c, basetn): *void; return basetn; @@ -3631,10 +3631,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // L833-842. `str` lives as N_TNAME("str") in wwstage — no // dedicated N_TSTR kind — so test the trio shape here. if (bu != nil) { - let isstr: bool = (bu.kind == nkind.N_TNAME) && streq(bu.str, "str"); - if (bu.kind == nkind.N_TSLICE || bu.kind == nkind.N_TARRAY || isstr) { - if (streq(e.str, "len")) { - let tn: *node = mktname(c, "i32"); + let isstr: bool = (bu.kind == syntax.nkind.N_TNAME) && syntax.streq(bu.str, "str"); + if (bu.kind == syntax.nkind.N_TSLICE || bu.kind == syntax.nkind.N_TARRAY || isstr) { + if (syntax.streq(e.str, "len")) { + let tn: *syntax.node = mktname(c, "i32"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -3642,13 +3642,13 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // invalid (drew ruling). cstage check.c errs // symmetrically. c.errs>0 gates cgen off → build // fails (the #11 inferarraylen idiom). - if (bu.kind == nkind.N_TARRAY && streq(e.str, "cap")) { + if (bu.kind == syntax.nkind.N_TARRAY && syntax.streq(e.str, "cap")) { cerr("error: no field 'cap' on a fixed-size array (arrays have no capacity; use .len)\n"); c.errs += 1; return nil; }; - if (streq(e.str, "cap")) { - let tn: *node = mktname(c, "i32"); + if (syntax.streq(e.str, "cap")) { + let tn: *syntax.node = mktname(c, "i32"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -3656,10 +3656,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // &A[0], a sanctioned ww spelling / faithful Hare // desugaring (14 live consumers). KEEP — .ptr valid. // See .ai/drew-gapa-ptr-ruling.md. - if (streq(e.str, "ptr")) { - let elem: *node = bu.lhs; + if (syntax.streq(e.str, "ptr")) { + let elem: *syntax.node = bu.lhs; if (isstr) { elem = mktname(c, "u8"); }; - let pp: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pp: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pp.lhs = elem; e.type_ = tinfofornode(c, pp): *void; return pp; @@ -3667,10 +3667,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; }; // Struct field walk. Cstage L843-849 errors on missing field. - if (bu != nil) { if (bu.kind == nkind.N_TSTRUCT) { - let f: *node = bu.list; + if (bu != nil) { if (bu.kind == syntax.nkind.N_TSTRUCT) { + let f: *syntax.node = bu.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { if (streq(f.str, e.str)) { + if (f.kind == syntax.nkind.N_TFIELD) { if (syntax.streq(f.str, e.str)) { e.type_ = tinfofornode(c, f.lhs): *void; return f.lhs; }; }; @@ -3680,16 +3680,16 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Tuple positional access `t.0`, `t.1`, …. Cstage L850-866 // errors on non-numeric / out-of-range; wwstage falls // through. fldnumidx (cgenutil) returns -1 on non-digit. - if (bu != nil) { if (bu.kind == nkind.N_TTUPLE) { + if (bu != nil) { if (bu.kind == syntax.nkind.N_TTUPLE) { let idx: i32 = fldnumidx(e.str); if (idx >= 0) { - let p: *node = bu.list; + let p: *syntax.node = bu.list; for (idx > 0 && p != nil) { p = p.next; idx -= 1; }; if (p != nil) { - let pt: *node = p.lhs; + let pt: *syntax.node = p.lhs; e.type_ = tinfofornode(c, pt): *void; return pt; }; @@ -3698,7 +3698,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; return nil; }; - if (k == nkind.N_STRUCTLIT) { + if (k == syntax.nkind.N_STRUCTLIT) { // A.6.1.6 — head-only stamp of the struct-lit's overall type. // Mirror cstage cmd/wcc/check.c:1161-1197; field-level walk // (cstage L1178-1194) parked behind #23 / Phase 2 — field @@ -3709,10 +3709,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // TYPE_IDENT in e.lhs; e.lhs == nil would be a future Hare- // style anonymous struct lit we don't yet parse — bail. if (e.lhs == nil) { return nil; }; - if (e.lhs.kind == nkind.N_IDENT) { - let ms: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); - if (ms != nil) { if (ms.skind == skind.SK_TYPE) { if (ms.decl != nil) { - let tn: *node = ms.decl.lhs; + if (e.lhs.kind == syntax.nkind.N_IDENT) { + let ms: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.lhs.str); + if (ms != nil) { if (ms.skind == syntax.skind.SK_TYPE) { if (ms.decl != nil) { + let tn: *syntax.node = ms.decl.lhs; if (tn != nil) { // #66 Phase-N step 3: stamp e.type_ to the NOMINAL // per-decl NAMED, not the flattened body. `overflow{}` @@ -3730,8 +3730,8 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Return the body node tn unchanged: byte-id rides // e.type_ (cgen), while the checker's AST-level // assign/return checks keep their prior input. - let tnm: *node = mktname(c, e.lhs.str); - let nti: *tinfo = tinfofornode(c, tnm); + let tnm: *syntax.node = mktname(c, e.lhs.str); + let nti: *syntax.tinfo = tinfofornode(c, tnm); if (nti != nil) { e.type_ = nti: *void; } else { e.type_ = tinfofornode(c, tn): *void; }; // #251: range-check array-typed field inits @@ -3744,18 +3744,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // and closes the rule-7 silent out-of-range truncate // at this site (cstage check.c:1546 range-checks via // arrlit_init_fits). - let stn: *node = resolvealias(c, tn); - if (stn != nil && stn.kind == nkind.N_TSTRUCT) { - let fi: *node = e.list; + let stn: *syntax.node = resolvealias(c, tn); + if (stn != nil && stn.kind == syntax.nkind.N_TSTRUCT) { + let fi: *syntax.node = e.list; for (fi != nil) { - if (fi.kind == nkind.N_FIELD + if (fi.kind == syntax.nkind.N_FIELD && fi.lhs != nil - && fi.lhs.kind == nkind.N_ARRLIT) { - let ftn: *node = nil; - let tf: *node = stn.list; + && fi.lhs.kind == syntax.nkind.N_ARRLIT) { + let ftn: *syntax.node = nil; + let tf: *syntax.node = stn.list; for (tf != nil) { - if (tf.kind == nkind.N_TFIELD) { - if (streq(tf.str, fi.str)) { ftn = tf.lhs; }; + if (tf.kind == syntax.nkind.N_TFIELD) { + if (syntax.streq(tf.str, fi.str)) { ftn = tf.lhs; }; }; tf = tf.next; }; @@ -3778,7 +3778,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, e.lhs): *void; return e.lhs; }; - if (k == nkind.N_ARRLIT) { + if (k == syntax.nkind.N_ARRLIT) { // A.6.1.7 — head-only stamp of the array-lit's overall type. // Mirror cstage cmd/wcc/check.c:1198-1211: walk elements, // skip the `...` repeat sentinel (parse/expr.ww:101-105), @@ -3795,16 +3795,16 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // precedent at L1509. Consumers default-type via the declared // `let` slot until A.6.3 lands. Mixed-type elements follow // cstage first-element-wins; no unify check (future scope). - let elt: *node = nil; + let elt: *syntax.node = nil; let count: u64 = 0u64; - let it: *node = e.list; + let it: *syntax.node = e.list; for (it != nil) { let skip: bool = false; - if (it.kind == nkind.N_FIELD) { - if (streq(it.str, "...")) { skip = true; }; + if (it.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(it.str, "...")) { skip = true; }; }; if (!skip) { - let t: *node = exprtype(c, it, nil); + let t: *syntax.node = exprtype(c, it, nil); if (elt == nil) { // #19: N_STRUCTLIT exprtype returns the struct BODY // (N_TSTRUCT) per #66, but the array->slice @@ -3816,9 +3816,9 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // is the same N_TNAME shape (typeeqast is already // streq-keyed for TNAME). Non-named elements keep the // existing first-element shape. - if (it.kind == nkind.N_STRUCTLIT + if (it.kind == syntax.nkind.N_STRUCTLIT && it.lhs != nil - && it.lhs.kind == nkind.N_IDENT) { + && it.lhs.kind == syntax.nkind.N_IDENT) { elt = mktname(c, it.lhs.str); } else { elt = t; @@ -3840,23 +3840,23 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Hare-fidelity: harec lower_flexible defaults a flexible iconst // to `int` (ref/harec/src/types.c:835). int = machine word (8B); // the old i32 truncated values >2^31 (#263 trap). - if (elt != nil && elt.kind == nkind.N_TNAME) { - if (streq(elt.str, "untyped_int")) { + if (elt != nil && elt.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(elt.str, "untyped_int")) { elt = mktname(c, "int"); - } else { if (streq(elt.str, "untyped_float")) { + } else { if (syntax.streq(elt.str, "untyped_float")) { elt = mktname(c, "f64"); - } else { if (streq(elt.str, "untyped_str")) { + } else { if (syntax.streq(elt.str, "untyped_str")) { elt = mktname(c, "str"); - } else { if (streq(elt.str, "untyped_rune")) { + } else { if (syntax.streq(elt.str, "untyped_rune")) { elt = mktname(c, "rune"); - } else { if (streq(elt.str, "untyped_bool")) { + } else { if (syntax.streq(elt.str, "untyped_bool")) { elt = mktname(c, "bool"); }; }; }; }; }; }; // Empty inferred arrlit: default to int, symmetric with cstage // check.c:1859 empty-fallback ty_int (#103). Was "i32". if (elt == nil) { elt = mktname(c, "int"); }; - let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0); + let arr: *syntax.node = syntax.newnode(syntax.nkind.N_TARRAY, "", 0, 0); // #6(niche): stamp the SYNTHESIZED element TNAME so the inferred // array's cgen is IDENTICAL to an explicit [N]T's (whose element is // resolvewalk-stamped). For a scalar element (int/u8) cgen's @@ -3868,7 +3868,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // real exprtype result whose type_ is already set. if (elt.type_ == nil) { elt.type_ = tinfofornode(c, elt): *void; }; arr.lhs = elt; - let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let cn: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); cn.uval = count; // #6(niche): stamp the SYNTHESIZED count literal. When this arr is // planted on an inferred array global's n.lhs (the array twin of @@ -3889,7 +3889,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { arr.type_ = e.type_; return arr; }; - if (k == nkind.N_SLICE) { + if (k == syntax.nkind.N_SLICE) { // A.6.2.0a — head-only stamp of the slice expression's overall // type. Mirrors cstage cmd/wcc/check.c:1214-1228 N_SLICE: peel // alias on the base; [N]T → []T, []T → []T (return base), str @@ -3900,22 +3900,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Documented cstage divergence: cstage L1227 errors on a // non-sliceable base; wwstage returns nil (lenient on miss), // matching scruttype L656 / A.6.1.5b N_DOT precedent. - let basetn: *node = exprtype(c, e.lhs, nil); - let bu: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, e.lhs, nil); + let bu: *syntax.node = resolvealias(c, unwrapbang(basetn)); if (bu == nil) { return nil; }; - if (bu.kind == nkind.N_TARRAY) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + if (bu.kind == syntax.nkind.N_TARRAY) { + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = bu.lhs; e.type_ = tinfofornode(c, sl): *void; return sl; }; - if (bu.kind == nkind.N_TSLICE) { + if (bu.kind == syntax.nkind.N_TSLICE) { e.type_ = tinfofornode(c, basetn): *void; return basetn; }; - if (bu.kind == nkind.N_TNAME) { - if (streq(bu.str, "str")) { - let tn: *node = mktname(c, "str"); + if (bu.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(bu.str, "str")) { + let tn: *syntax.node = mktname(c, "str"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -3925,15 +3925,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // the index route (idxeffti) and unlike Hare. Loud on the // usual []T annotation; for-range likewise. Team task #18 // (#61-residual A). - if (bu.kind == nkind.N_TPTR && bu.lhs != nil) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + if (bu.kind == syntax.nkind.N_TPTR && bu.lhs != nil) { + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = bu.lhs; e.type_ = tinfofornode(c, sl): *void; return sl; }; return nil; }; - if (k == nkind.N_TUPLE) { + if (k == syntax.nkind.N_TUPLE) { // A.6.2.0b — head-only stamp of the tuple expression's // overall type. Mirrors cstage cmd/wcc/check.c:1437-1451 // N_TUPLE: walk e.list, type each element via exprtype, and @@ -3949,47 +3949,47 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // expression), so empty is unreachable and yields nil here // (matches scruttype L656 / A.6.1.5b N_DOT lenient-on-miss). if (e.list == nil) { return nil; }; - let head: *node = nil; - let tail: *node = nil; - let it: *node = e.list; + let head: *syntax.node = nil; + let tail: *syntax.node = nil; + let it: *syntax.node = e.list; for (it != nil) { - let elemt: *node = exprtype(c, it, nil); - let w: *node = newnode(nkind.N_TPARAM, "", 0, 0); + let elemt: *syntax.node = exprtype(c, it, nil); + let w: *syntax.node = syntax.newnode(syntax.nkind.N_TPARAM, "", 0, 0); w.lhs = elemt; if (head == nil) { head = w; } else { tail.next = w; }; tail = w; it = it.next; }; - let tt: *node = newnode(nkind.N_TTUPLE, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTUPLE, "", 0, 0); tt.list = head; e.type_ = tinfofornode(c, tt): *void; return tt; }; - if (k == nkind.N_RECV) { + if (k == syntax.nkind.N_RECV) { // A.6.2.0d — head-only stamp of the receive expression's // overall type. Mirrors cstage cmd/wcc/check.c:1230-1236 // N_RECV: peel alias on the channel base; chan T → T. // Documented cstage divergence: cstage L1234 errors on a // non-chan base; wwstage returns nil (lenient on miss), // matching scruttype L656 / A.6.1.5b N_DOT precedent. - let basetn: *node = exprtype(c, e.lhs, nil); - let bu: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, e.lhs, nil); + let bu: *syntax.node = resolvealias(c, unwrapbang(basetn)); if (bu == nil) { return nil; }; - if (bu.kind == nkind.N_TCHAN) { + if (bu.kind == syntax.nkind.N_TCHAN) { e.type_ = tinfofornode(c, bu.lhs): *void; return bu.lhs; }; return nil; }; - if (k == nkind.N_SPREAD) { + if (k == syntax.nkind.N_SPREAD) { // A.6.2.0e — pass-through stamp. Mirrors cstage check.c:1212-1213. // The spread expression `xs...` carries the operand's type. - let t: *node = exprtype(c, e.lhs, nil); + let t: *syntax.node = exprtype(c, e.lhs, nil); if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; return t; }; - if (k == nkind.N_MATCH) { + if (k == syntax.nkind.N_MATCH) { // A.6.2.0g — port of cstage cmd/wcc/check.c:1316-1330 match-as- // expression stamp. The match's type is the first arm's yield // operand type; void if no arm yields. Wwstage skips cstage's @@ -4004,15 +4004,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // node (nil on the post-walk cached read) for the assignability // node the consumers (checkletassign/checkretassign) read off this // arm's *node return; see matchyieldtype's docstring + #279. - let yt: *tinfo = nil; - let retn: *node = nil; - let cs: *node = e.list; + let yt: *syntax.tinfo = nil; + let retn: *syntax.node = nil; + let cs: *syntax.node = e.list; for (cs != nil) { // cs.str/cs.lhs = the arm's case-binding name + declared // type (the N_MCASE binder); fed to matchyieldtype's #241 // scope-popped `yield ` fallback. - let armn: *node = nil; - let t: *tinfo = matchyieldtype(c, cs.body, cs.str, cs.lhs, &armn); + let armn: *syntax.node = nil; + let t: *syntax.tinfo = matchyieldtype(c, cs.body, cs.str, cs.lhs, &armn); if (t != nil) { if (yt == nil) { // First yielding arm: it is the match's type; @@ -4039,7 +4039,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // untyped_float) - a precision gap, not a silent // miscompile of the catA repro; closeable only with a // real tinfo type_assignable. - if (!typeeq(yt, t)) { + if (!syntax.typeeq(yt, t)) { let ca: i32 = yieldclass(yt); let cb: i32 = yieldclass(t); if (ca != 0i32 && cb != 0i32 && ca != cb) { @@ -4056,7 +4056,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = yt: *void; return retn; }; - if (k == nkind.N_YIELD) { + if (k == syntax.nkind.N_YIELD) { // A.6.2.0f — pass-through stamp; cstage check.c:1708 does NOT // stamp N_YIELD (statement-shaped). Wwstage's A.6.2 invariant // requires every post-dispatch kind have type_ set. Yield's @@ -4065,25 +4065,25 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // expression with a type). Bare `yield;` (no operand) stamps // void. if (e.lhs == nil) { - let v: *node = mktname(c, "void"); + let v: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, v): *void; return v; }; - let t: *node = exprtype(c, e.lhs, nil); + let t: *syntax.node = exprtype(c, e.lhs, nil); if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; return t; }; - if (k == nkind.N_TRYPROP) { + if (k == syntax.nkind.N_TRYPROP) { // success unwrap: the success-variant type of operand's // tagged union. - let opt: *node = exprtype(c, e.lhs, nil); - let ou: *node = resolvealias(c, unwrapbang(opt)); + let opt: *syntax.node = exprtype(c, e.lhs, nil); + let ou: *syntax.node = resolvealias(c, unwrapbang(opt)); if (ou == nil) { return nil; }; - if (ou.kind != nkind.N_TTAGGED) { return nil; }; + if (ou.kind != syntax.nkind.N_TTAGGED) { return nil; }; // Hare semantics: success = first non-error variant if // any !-flag is present; else first variant. if (taggedhaserr(c, ou)) { - let v: *node = ou.list; + let v: *syntax.node = ou.list; for (v != nil) { if (!iserrvariant(c, ou, v)) { e.type_ = tinfofornode(c, v): *void; @@ -4096,16 +4096,16 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, ou.list): *void; return ou.list; }; - if (k == nkind.N_TRYUNW) { + if (k == syntax.nkind.N_TRYUNW) { // `e!` abort-on-error unwrap; success variant is what the // receiver gets, identical to `?` shape modulo control flow. // #31: required so `let p: *T = alloc(v)!;` resolves to *T. - let opt: *node = exprtype(c, e.lhs, nil); - let ou: *node = resolvealias(c, unwrapbang(opt)); + let opt: *syntax.node = exprtype(c, e.lhs, nil); + let ou: *syntax.node = resolvealias(c, unwrapbang(opt)); if (ou == nil) { return nil; }; - if (ou.kind != nkind.N_TTAGGED) { return nil; }; + if (ou.kind != syntax.nkind.N_TTAGGED) { return nil; }; if (taggedhaserr(c, ou)) { - let v: *node = ou.list; + let v: *syntax.node = ou.list; for (v != nil) { if (!iserrvariant(c, ou, v)) { e.type_ = tinfofornode(c, v): *void; @@ -4118,15 +4118,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, ou.list): *void; return ou.list; }; - if (k == nkind.N_TYPEASSERT) { + if (k == syntax.nkind.N_TYPEASSERT) { // `e as T` → T. Mirrors cstage cmd/wcc/check.c TYPEASSERT // `n->type = resolve_type(c, n->rhs)`. e.type_ = tinfofornode(c, e.rhs): *void; return e.rhs; }; - if (k == nkind.N_TYPETEST) { + if (k == syntax.nkind.N_TYPETEST) { // `e is T` → bool - let tn: *node = mktname(c, "bool"); + let tn: *syntax.node = mktname(c, "bool"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -4136,22 +4136,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // isuntypedint / is_str_like / is_bool_like — helpers used // by the assignability check below to allow common AST shapes // through without needing real type inference. -fn isuntypedint(t: *node) bool = { +fn isuntypedint(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "untyped_int"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "untyped_int"); }; -fn isuntypedfloat(t: *node) bool = { +fn isuntypedfloat(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "untyped_float"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "untyped_float"); }; -fn isuntypednil(t: *node) bool = { +fn isuntypednil(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "untyped_nil"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "untyped_nil"); }; // isinttypeast — int-typed AST node. Either a primitive int name @@ -4159,24 +4159,24 @@ fn isuntypednil(t: *node) bool = { // excluded so the enum↔int reinterpret in checkisas (#52) refuses a // surprise `enum as f64` shape. Mirrors cstage's type_isint // (cmd/wcc/type.c) restricted to the kinds reachable from AST. -fn isinttypeast(t: *node) bool = { +fn isinttypeast(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind == nkind.N_TENUM) { return true; }; - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind == syntax.nkind.N_TENUM) { return true; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let s: str = t.str; - if (streq(s, "i8")) { return true; }; - if (streq(s, "i16")) { return true; }; - if (streq(s, "i32")) { return true; }; - if (streq(s, "i64")) { return true; }; - if (streq(s, "u8")) { return true; }; - if (streq(s, "u16")) { return true; }; - if (streq(s, "u32")) { return true; }; - if (streq(s, "u64")) { return true; }; - if (streq(s, "int")) { return true; }; - if (streq(s, "uint")) { return true; }; - if (streq(s, "uintptr")) { return true; }; - if (streq(s, "size")) { return true; }; - if (streq(s, "rune")) { return true; }; + if (syntax.streq(s, "i8")) { return true; }; + if (syntax.streq(s, "i16")) { return true; }; + if (syntax.streq(s, "i32")) { return true; }; + if (syntax.streq(s, "i64")) { return true; }; + if (syntax.streq(s, "u8")) { return true; }; + if (syntax.streq(s, "u16")) { return true; }; + if (syntax.streq(s, "u32")) { return true; }; + if (syntax.streq(s, "u64")) { return true; }; + if (syntax.streq(s, "int")) { return true; }; + if (syntax.streq(s, "uint")) { return true; }; + if (syntax.streq(s, "uintptr")) { return true; }; + if (syntax.streq(s, "size")) { return true; }; + if (syntax.streq(s, "rune")) { return true; }; return false; }; @@ -4190,64 +4190,64 @@ fn isinttypeast(t: *node) bool = { // (chasing) accepts. nil operands are treated as already-errored upstream // (the unifyarith nil-bail shapes) and NOT re-rejected — the cstage twin's // `l == ty_err` escape. -fn intkindast(c: *checker, t: *node) bool = { +fn intkindast(c: *checker, t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (isinttypeast(u)) { return true; }; // int family + enum + rune if (isuntypedint(u)) { return true; }; - if (u != nil && u.kind == nkind.N_TNAME && streq(u.str, "untyped_rune")) { + if (u != nil && u.kind == syntax.nkind.N_TNAME && syntax.streq(u.str, "untyped_rune")) { return true; }; return false; }; -fn numkindast(c: *checker, t: *node) bool = { +fn numkindast(c: *checker, t: *syntax.node) bool = { if (intkindast(c, t)) { return true; }; if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return false; }; - if (u.kind != nkind.N_TNAME) { return false; }; + if (u.kind != syntax.nkind.N_TNAME) { return false; }; let s: str = u.str; - if (streq(s, "f32")) { return true; }; - if (streq(s, "f64")) { return true; }; - if (streq(s, "untyped_float")) { return true; }; + if (syntax.streq(s, "f32")) { return true; }; + if (syntax.streq(s, "f64")) { return true; }; + if (syntax.streq(s, "untyped_float")) { return true; }; return false; }; -fn boolkindast(c: *checker, t: *node) bool = { +fn boolkindast(c: *checker, t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return false; }; - if (u.kind != nkind.N_TNAME) { return false; }; - return streq(u.str, "bool") || streq(u.str, "untyped_bool"); + if (u.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(u.str, "bool") || syntax.streq(u.str, "untyped_bool"); }; -fn isnumerictname(t: *node) bool = { +fn isnumerictname(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let s: str = t.str; - if (streq(s, "i8")) { return true; }; - if (streq(s, "i16")) { return true; }; - if (streq(s, "i32")) { return true; }; - if (streq(s, "i64")) { return true; }; - if (streq(s, "u8")) { return true; }; - if (streq(s, "u16")) { return true; }; - if (streq(s, "u32")) { return true; }; - if (streq(s, "u64")) { return true; }; - if (streq(s, "int")) { return true; }; - if (streq(s, "uint")) { return true; }; - if (streq(s, "uintptr")) { return true; }; - if (streq(s, "size")) { return true; }; - if (streq(s, "rune")) { return true; }; - if (streq(s, "f32")) { return true; }; - if (streq(s, "f64")) { return true; }; + if (syntax.streq(s, "i8")) { return true; }; + if (syntax.streq(s, "i16")) { return true; }; + if (syntax.streq(s, "i32")) { return true; }; + if (syntax.streq(s, "i64")) { return true; }; + if (syntax.streq(s, "u8")) { return true; }; + if (syntax.streq(s, "u16")) { return true; }; + if (syntax.streq(s, "u32")) { return true; }; + if (syntax.streq(s, "u64")) { return true; }; + if (syntax.streq(s, "int")) { return true; }; + if (syntax.streq(s, "uint")) { return true; }; + if (syntax.streq(s, "uintptr")) { return true; }; + if (syntax.streq(s, "size")) { return true; }; + if (syntax.streq(s, "rune")) { return true; }; + if (syntax.streq(s, "f32")) { return true; }; + if (syntax.streq(s, "f64")) { return true; }; return false; }; -fn isstrtname(t: *node) bool = { +fn isstrtname(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "str"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "str"); }; // tagshape — #24/#37: the coarse variant-shape bucket of a (resolved) type @@ -4258,9 +4258,9 @@ fn isstrtname(t: *node) bool = { // aggregate-shape-lenient leg to keep a tagged accept lenient ONLY against a // shape-compatible variant — same classifier cgen boxes with, so the checker // accept and the cgen box agree (rule-12: reuse the in-tree classifier). -fn tagshape(t: *node) i32 = { +fn tagshape(t: *syntax.node) i32 = { if (t == nil) { return 0i32; }; - if (t.kind == nkind.N_TSLICE) { return 2i32; }; + if (t.kind == syntax.nkind.N_TSLICE) { return 2i32; }; if (isstrtname(t)) { return 1i32; }; return 0i32; }; @@ -4271,14 +4271,14 @@ fn tagshape(t: *node) i32 = { // Mirror of cstage addrfn_ptr_matches (cmd/wcc/check.c, project #206); // reuses typeeqast — the same structural-fn comparator cstage uses via // type_eq(TY_FN,TY_FN) — for symmetry. -fn addrfnptrmatches(c: *checker, ptr: *node, synth: *node) bool = { +fn addrfnptrmatches(c: *checker, ptr: *syntax.node, synth: *syntax.node) bool = { if (ptr == nil) { return false; }; - let pu: *node = resolvealias(c, unwrapbang(ptr)); + let pu: *syntax.node = resolvealias(c, unwrapbang(ptr)); if (pu == nil) { return false; }; - if (pu.kind != nkind.N_TPTR) { return false; }; - let ref: *node = resolvealias(c, unwrapbang(pu.lhs)); + if (pu.kind != syntax.nkind.N_TPTR) { return false; }; + let ref: *syntax.node = resolvealias(c, unwrapbang(pu.lhs)); if (ref == nil) { return false; }; - if (ref.kind != nkind.N_TFN) { return false; }; + if (ref.kind != syntax.nkind.N_TFN) { return false; }; return typeeqast(c, synth, ref); }; @@ -4297,35 +4297,35 @@ fn addrfnptrmatches(c: *checker, ptr: *node, synth: *node) bool = { // the rhs node. N_FNDECL and N_TFN share parseparams' param-node shape // (lib/ww/parse/decl.ww + parse.ww), so a synthetic N_TFN over the fn // decl's lhs/list compares correctly under typeeqast. -fn assignableaddrfn(c: *checker, dst: *node, rhs: *node) bool = { +fn assignableaddrfn(c: *checker, dst: *syntax.node, rhs: *syntax.node) bool = { if (dst == nil) { return false; }; if (rhs == nil) { return false; }; - if (rhs.kind != nkind.N_UN) { return false; }; - if (rhs.op != tkind.TK_AMP) { return false; }; - let id: *node = rhs.lhs; + if (rhs.kind != syntax.nkind.N_UN) { return false; }; + if (rhs.op != syntax.tkind.TK_AMP) { return false; }; + let id: *syntax.node = rhs.lhs; if (id == nil) { return false; }; - if (id.kind != nkind.N_IDENT) { return false; }; + if (id.kind != syntax.nkind.N_IDENT) { return false; }; // #4: curmod preference. Without it a `&handler` whose leaf also // names a fn in a later module misbinds the foreign fn's signature // here (scopedefineinmodule prepends → chain-first = last module), // silently admitting a *fn into a foreign-sig slot or rejecting a // valid same-module &fn. cstage uses scope_lookup_prefer with // cur_mod (cmd/wcc/check.c:410, assignable_addrfn). - let s: *sym = scopelookupprefer(c.cur, c.curmod, id.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, id.str); if (s == nil) { return false; }; - if (s.skind != skind.SK_FN) { return false; }; + if (s.skind != syntax.skind.SK_FN) { return false; }; if (s.decl == nil) { return false; }; - let d: *node = s.decl; - if (d.kind != nkind.N_FNDECL) { return false; }; - let synth: *node = newnode(nkind.N_TFN, "", 0, 0); + let d: *syntax.node = s.decl; + if (d.kind != syntax.nkind.N_FNDECL) { return false; }; + let synth: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); synth.lhs = d.lhs; synth.list = d.list; - let du: *node = resolvealias(c, unwrapbang(dst)); + let du: *syntax.node = resolvealias(c, unwrapbang(dst)); if (du == nil) { return false; }; - if (du.kind == nkind.N_TPTR) { return addrfnptrmatches(c, du, synth); }; - if (du.kind == nkind.N_TTAGGED) { + if (du.kind == syntax.nkind.N_TPTR) { return addrfnptrmatches(c, du, synth); }; + if (du.kind == syntax.nkind.N_TTAGGED) { let nmatch: i32 = 0; - let v: *node = du.list; + let v: *syntax.node = du.list; for (v != nil) { if (addrfnptrmatches(c, v, synth)) { nmatch = nmatch + 1; }; v = v.next; @@ -4342,13 +4342,13 @@ fn assignableaddrfn(c: *checker, dst: *node, rhs: *node) bool = { // `confident` lets the caller decide whether to emit an error // when the result is false: if !confident, the caller should not // flag it. -fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { +fn isassignable(c: *checker, dst: *syntax.node, src: *syntax.node, confident: *bool) bool = { *confident = false; if (dst == nil) { return true; }; // no declared target if (src == nil) { return true; }; // unknown src type *confident = true; - let du: *node = resolvealias(c, unwrapbang(dst)); - let su: *node = resolvealias(c, unwrapbang(src)); + let du: *syntax.node = resolvealias(c, unwrapbang(dst)); + let su: *syntax.node = resolvealias(c, unwrapbang(src)); if (du == nil) { *confident = false; return true; }; if (su == nil) { *confident = false; return true; }; if (typeeqast(c, du, su)) { return true; }; @@ -4359,8 +4359,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // reject (mirror cstage type.c type_assignable's #258 arm + fallthrough // to 0). The acceptance sites then desugar the array expr to an // explicit full slice via desugararrayslice; cgen is untouched. - if (du.kind == nkind.N_TSLICE) { - if (su.kind == nkind.N_TARRAY) { + if (du.kind == syntax.nkind.N_TSLICE) { + if (su.kind == syntax.nkind.N_TARRAY) { if (typeeqast(c, du.lhs, su.lhs)) { return true; }; return false; }; @@ -4369,10 +4369,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { if (isuntypedint(su)) { if (isnumerictname(du)) { return true; }; // (T | ...) tagged: only OK if some variant accepts untyped_int. - if (du.kind == nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { if (isnumerictname(vu)) { return true; }; // mirror cstage type_isnum(enum)=true (type.c:201 -> @@ -4380,7 +4380,7 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // accept an untyped int. Without this the #23 fix would // flip an enum-variant union to reject while cstage // accepts = a NEW divergence (A3 trap). - if (vu.kind == nkind.N_TENUM) { return true; }; + if (vu.kind == syntax.nkind.N_TENUM) { return true; }; }; v = v.next; }; @@ -4393,8 +4393,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // general call-arg check made this path reachable). Mirror the // tagged→tagged spread escape (:4117). Spread decl-form flatten // is #199b, deferred. - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { *confident = false; return true; }; @@ -4413,10 +4413,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { return false; }; // Known non-numeric primitive: confidently wrong. - if (du.kind == nkind.N_TNAME) { - if (streq(du.str, "bool")) { return false; }; - if (streq(du.str, "void")) { return false; }; - if (streq(du.str, "str")) { return false; }; + if (du.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(du.str, "bool")) { return false; }; + if (syntax.streq(du.str, "void")) { return false; }; + if (syntax.streq(du.str, "str")) { return false; }; }; // #24: untyped int into a known AGGREGATE (slice/array/ptr/fn/chan/ // tuple/struct) — confident reject. `let xs: []int = 5` read the int @@ -4424,10 +4424,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // left it unconfident → silent accept). cstage type_assignable // rejects untyped_int into a non-numeric aggregate (cmd/wcc/type.c). // The TTAGGED case is handled above; this is the bare aggregate. - if (du.kind == nkind.N_TSLICE || du.kind == nkind.N_TARRAY - || du.kind == nkind.N_TPTR || du.kind == nkind.N_TFN - || du.kind == nkind.N_TCHAN || du.kind == nkind.N_TTUPLE - || du.kind == nkind.N_TSTRUCT) { + if (du.kind == syntax.nkind.N_TSLICE || du.kind == syntax.nkind.N_TARRAY + || du.kind == syntax.nkind.N_TPTR || du.kind == syntax.nkind.N_TFN + || du.kind == syntax.nkind.N_TCHAN || du.kind == syntax.nkind.N_TTUPLE + || du.kind == syntax.nkind.N_TSTRUCT) { return false; }; // Unknown shapes: stay quiet. @@ -4436,10 +4436,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { }; if (isuntypedfloat(su)) { if (isnumerictname(du)) { return true; }; - if (du.kind == nkind.N_TNAME) { - if (streq(du.str, "bool")) { return false; }; - if (streq(du.str, "void")) { return false; }; - if (streq(du.str, "str")) { return false; }; + if (du.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(du.str, "bool")) { return false; }; + if (syntax.streq(du.str, "void")) { return false; }; + if (syntax.streq(du.str, "str")) { return false; }; }; // A4 (#23 float-twin): (T | ...) tagged dst — accept iff a DIRECT // variant is a float type. cstage type_assignable for an @@ -4451,22 +4451,22 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // true (:3777). Without it the catch-all (:3972) over-accepts an // untyped float into ANY tagged (silent tag=0). Faithful // flatten+rebox deferred post-CSP (nominal id, #23/#40). - if (du.kind == nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { - if (vu.kind == nkind.N_TNAME) { - if (streq(vu.str, "f32")) { return true; }; - if (streq(vu.str, "f64")) { return true; }; + if (vu.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(vu.str, "f32")) { return true; }; + if (syntax.streq(vu.str, "f64")) { return true; }; }; }; v = v.next; }; // #24: spread variant keeps the lenient escape (cstage flattens; // wwstage can't) — same rationale as the untyped-int arm above. - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { *confident = false; return true; }; @@ -4475,10 +4475,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { }; // #24: untyped float into a known AGGREGATE — confident reject (twin // of the untyped-int aggregate arm above; `let xs: []f64 = 1.5`). - if (du.kind == nkind.N_TSLICE || du.kind == nkind.N_TARRAY - || du.kind == nkind.N_TPTR || du.kind == nkind.N_TFN - || du.kind == nkind.N_TCHAN || du.kind == nkind.N_TTUPLE - || du.kind == nkind.N_TSTRUCT) { + if (du.kind == syntax.nkind.N_TSLICE || du.kind == syntax.nkind.N_TARRAY + || du.kind == syntax.nkind.N_TPTR || du.kind == syntax.nkind.N_TFN + || du.kind == syntax.nkind.N_TCHAN || du.kind == syntax.nkind.N_TTUPLE + || du.kind == syntax.nkind.N_TSTRUCT) { return false; }; *confident = false; @@ -4486,25 +4486,25 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { }; if (isuntypednil(su)) { // nil → ptr/slice/chan/fn/nullable - if (du.kind == nkind.N_TPTR) { return true; }; - if (du.kind == nkind.N_TSLICE) { return true; }; - if (du.kind == nkind.N_TCHAN) { return true; }; - if (du.kind == nkind.N_TFN) { return true; }; + if (du.kind == syntax.nkind.N_TPTR) { return true; }; + if (du.kind == syntax.nkind.N_TSLICE) { return true; }; + if (du.kind == syntax.nkind.N_TCHAN) { return true; }; + if (du.kind == syntax.nkind.N_TFN) { return true; }; // nullable `(*T | void)` — already accepted by typeeqast // when matched whole; nil is OK there too. - if (du.kind == nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { - if (v.kind == nkind.N_TPTR) { return true; }; - if (v.kind == nkind.N_TSLICE) { return true; }; - if (v.kind == nkind.N_TCHAN) { return true; }; - if (v.kind == nkind.N_TFN) { return true; }; + if (v.kind == syntax.nkind.N_TPTR) { return true; }; + if (v.kind == syntax.nkind.N_TSLICE) { return true; }; + if (v.kind == syntax.nkind.N_TCHAN) { return true; }; + if (v.kind == syntax.nkind.N_TFN) { return true; }; v = v.next; }; // #24: spread variant keeps the lenient escape (cstage flattens; // wwstage can't) — same rationale as the untyped-int arm above. - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { *confident = false; return true; }; @@ -4529,8 +4529,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // harec keeps the drill at types.c:702-739 (#199b deferred port). // Restores SSoT with `is`/`as` non-recursive lookup (#198 sibling). // Callers compose `let inner: Wrapper = sub; let r: parent = inner;`. - if (du.kind == nkind.N_TTAGGED && su.kind != nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED && su.kind != syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { // Spread `...wrapper` keeps the recursive drill: the // wrapper's flat variants are intentionally inlined into @@ -4538,10 +4538,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // expanded yet (cstage flattens at resolve_type; wwstage // stays AST-keyed). Plain wrapper variant gets the // direct-only gate. - let vspread: bool = (v.op == tkind.TK_ELLIPSIS); - let vu: *node = resolvealias(c, unwrapbang(v)); + let vspread: bool = (v.op == syntax.tkind.TK_ELLIPSIS); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); let vtagged: bool = false; - if (vu != nil) { if (vu.kind == nkind.N_TTAGGED) { vtagged = true; }; }; + if (vu != nil) { if (vu.kind == syntax.nkind.N_TTAGGED) { vtagged = true; }; }; if (vtagged && !vspread) { if (typeeqast(c, v, src)) { return true; }; } else { @@ -4598,11 +4598,11 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // qualleaf bridge). Pre-c3 the collision was ALSO accepted (call-arg // ran no check; let/return short-circuited on the scalar variant) — c3 // is NEUTRAL on it. - if (su.kind != nkind.N_TNAME) { + if (su.kind != syntax.nkind.N_TNAME) { let ss: i32 = tagshape(su); - let sp: *node = du.list; + let sp: *syntax.node = du.list; for (sp != nil) { - let svu: *node = resolvealias(c, unwrapbang(sp)); + let svu: *syntax.node = resolvealias(c, unwrapbang(sp)); if (svu != nil) { if (tagshape(svu) == ss) { *confident = false; @@ -4620,7 +4620,7 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // (don't be confident) — common when forwarding a fallible // return through another fn with the same shape but possibly // a different surface spelling. - if (du.kind == nkind.N_TTAGGED && su.kind == nkind.N_TTAGGED) { + if (du.kind == syntax.nkind.N_TTAGGED && su.kind == syntax.nkind.N_TTAGGED) { // #205: NAMED-variant nominal compare BEFORE permissive // fallthrough. Mirror of cstage type.c type_assignable // tagged→tagged arm (#199 α concrete→tagged sibling). @@ -4629,11 +4629,11 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // identity — wrapper's leaves are NOT direct variants of // dst, so a structural subset walk would reject. SSoT // with `is`/`as` variant lookup (#198 family). - let v: *node = du.list; + let v: *syntax.node = du.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { - if (vu.kind == nkind.N_TTAGGED) { + if (vu.kind == syntax.nkind.N_TTAGGED) { if (typeeqast(c, v, src)) { return true; }; }; }; @@ -4647,11 +4647,11 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // spread-widen cstage accepts → new cs≠ww divergence. Spread // decl-form layout is #199b, deferred. let hasspread: bool = false; - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { hasspread = true; }; + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { hasspread = true; }; }; - for (let p: *node = su.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { hasspread = true; }; + for (let p: *syntax.node = su.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { hasspread = true; }; }; if (hasspread) { *confident = false; @@ -4676,15 +4676,15 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // gap. Sound for the bootstrap — no two of its variants share a leaf // (drew); the cross-module same-leaf collision (a.foo vs b.foo) is a // known over-accept deferred to #10 / filed in the #4 census. - for (let sp: *node = su.list; sp != nil; sp = sp.next) { + for (let sp: *syntax.node = su.list; sp != nil; sp = sp.next) { let ok: bool = false; - for (let dp: *node = du.list; dp != nil; dp = dp.next) { + for (let dp: *syntax.node = du.list; dp != nil; dp = dp.next) { if (typeeqast(c, dp, sp)) { ok = true; break; }; - let su2: *node = unwrapbang(sp); - let du2: *node = unwrapbang(dp); + let su2: *syntax.node = unwrapbang(sp); + let du2: *syntax.node = unwrapbang(dp); if (su2 != nil && du2 != nil && - su2.kind == nkind.N_TNAME && du2.kind == nkind.N_TNAME && - streq(qualleaf(su2.str), qualleaf(du2.str))) { + su2.kind == syntax.nkind.N_TNAME && du2.kind == syntax.nkind.N_TNAME && + syntax.streq(qualleaf(su2.str), qualleaf(du2.str))) { ok = true; break; }; }; @@ -4695,18 +4695,18 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // tagged → non-tagged: requires `?` / `!` / match to project a // variant. #31: this is what traps `let p: *T = alloc(v);` // where the builtin returns `(*T | nomem)` and the LHS is bare. - if (su.kind == nkind.N_TTAGGED && du.kind != nkind.N_TTAGGED) { + if (su.kind == syntax.nkind.N_TTAGGED && du.kind != syntax.nkind.N_TTAGGED) { return false; }; // Two known primitives with different names are confidently // incompatible. `i32 ↔ bool`, `str ↔ i32`, etc. - if (du.kind == nkind.N_TNAME && su.kind == nkind.N_TNAME) { + if (du.kind == syntax.nkind.N_TNAME && su.kind == syntax.nkind.N_TNAME) { let known_d: bool = isnumerictname(du) || isstrtname(du); - if (!known_d) { if (streq(du.str, "bool")) { known_d = true; }; }; - if (!known_d) { if (streq(du.str, "void")) { known_d = true; }; }; + if (!known_d) { if (syntax.streq(du.str, "bool")) { known_d = true; }; }; + if (!known_d) { if (syntax.streq(du.str, "void")) { known_d = true; }; }; let known_s: bool = isnumerictname(su) || isstrtname(su); - if (!known_s) { if (streq(su.str, "bool")) { known_s = true; }; }; - if (!known_s) { if (streq(su.str, "void")) { known_s = true; }; }; + if (!known_s) { if (syntax.streq(su.str, "bool")) { known_s = true; }; }; + if (!known_s) { if (syntax.streq(su.str, "void")) { known_s = true; }; }; if (known_d) { if (known_s) { // Both primitives, different names → no. @@ -4724,14 +4724,14 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // handled at the assignment caller sites via assignableaddrfn, NOT // here. Without this the lenient catch-all below silently accepted // the laundering shape. - if (du.kind == nkind.N_TPTR) { - if (su.kind == nkind.N_TPTR) { - let dref: *node = resolvealias(c, unwrapbang(du.lhs)); - let sref: *node = resolvealias(c, unwrapbang(su.lhs)); + if (du.kind == syntax.nkind.N_TPTR) { + if (su.kind == syntax.nkind.N_TPTR) { + let dref: *syntax.node = resolvealias(c, unwrapbang(du.lhs)); + let sref: *syntax.node = resolvealias(c, unwrapbang(su.lhs)); if (dref != nil) { if (sref != nil) { - if (dref.kind == nkind.N_TFN) { - if (sref.kind == nkind.N_TFN) { + if (dref.kind == syntax.nkind.N_TFN) { + if (sref.kind == syntax.nkind.N_TFN) { return false; }; }; @@ -4749,8 +4749,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // The matched-sig case already returned true via typeeqast at the top. // The `&fn` (*fn) vs bare-fn KIND mismatch (du N_TFN, su N_TPTR) is a // different shape, closed by c3's aggregate-kind reject, not here. - if (du.kind == nkind.N_TFN) { - if (su.kind == nkind.N_TFN) { + if (du.kind == syntax.nkind.N_TFN) { + if (su.kind == syntax.nkind.N_TFN) { return false; }; }; @@ -4772,20 +4772,20 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // rejects via structural type_assignable, a filed residual under-reject, // NOT a new over-reject. A NAMED struct/alias dst that does NOT resolve // to a known kind stays N_TNAME-non-prim → neither set → lenient. - let dprim: bool = du.kind == nkind.N_TNAME + let dprim: bool = du.kind == syntax.nkind.N_TNAME && (isnumerictname(du) || isstrtname(du) - || streq(du.str, "bool") || streq(du.str, "void")); - let sprim: bool = su.kind == nkind.N_TNAME + || syntax.streq(du.str, "bool") || syntax.streq(du.str, "void")); + let sprim: bool = su.kind == syntax.nkind.N_TNAME && (isnumerictname(su) || isstrtname(su) - || streq(su.str, "bool") || streq(su.str, "void")); - let daggr: bool = du.kind == nkind.N_TSLICE || du.kind == nkind.N_TARRAY - || du.kind == nkind.N_TPTR || du.kind == nkind.N_TFN - || du.kind == nkind.N_TCHAN || du.kind == nkind.N_TTUPLE - || du.kind == nkind.N_TSTRUCT; - let saggr: bool = su.kind == nkind.N_TSLICE || su.kind == nkind.N_TARRAY - || su.kind == nkind.N_TPTR || su.kind == nkind.N_TFN - || su.kind == nkind.N_TCHAN || su.kind == nkind.N_TTUPLE - || su.kind == nkind.N_TSTRUCT; + || syntax.streq(su.str, "bool") || syntax.streq(su.str, "void")); + let daggr: bool = du.kind == syntax.nkind.N_TSLICE || du.kind == syntax.nkind.N_TARRAY + || du.kind == syntax.nkind.N_TPTR || du.kind == syntax.nkind.N_TFN + || du.kind == syntax.nkind.N_TCHAN || du.kind == syntax.nkind.N_TTUPLE + || du.kind == syntax.nkind.N_TSTRUCT; + let saggr: bool = su.kind == syntax.nkind.N_TSLICE || su.kind == syntax.nkind.N_TARRAY + || su.kind == syntax.nkind.N_TPTR || su.kind == syntax.nkind.N_TFN + || su.kind == syntax.nkind.N_TCHAN || su.kind == syntax.nkind.N_TTUPLE + || su.kind == syntax.nkind.N_TSTRUCT; if (sprim && daggr) { return false; }; if (dprim && saggr) { return false; }; // #24: two aggregates of DIFFERENT kinds → confident reject (array/slice @@ -4799,7 +4799,7 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // principle as the concrete→tagged aggregate-lenient arm above; the // struct-into-ptr genuine mismatch stays a filed #224/#10 under-reject. if (daggr && saggr && du.kind != su.kind - && du.kind != nkind.N_TSTRUCT && su.kind != nkind.N_TSTRUCT) { + && du.kind != syntax.nkind.N_TSTRUCT && su.kind != syntax.nkind.N_TSTRUCT) { return false; }; // Anything else: don't claim confidence. @@ -4859,15 +4859,15 @@ fn qualmod(nm: str, defmod: str) str = { // precise Type-identity form is #10 (tinfo SSoT). typeeqast handles the // exact-string cases first, so this fires only on the qualified-vs-bare // mix. -fn casevariantpairmatch(v: *node, pat: *node, unionmod: str) bool = { - let vv: *node = unwrapbang(v); - let pp: *node = unwrapbang(pat); +fn casevariantpairmatch(v: *syntax.node, pat: *syntax.node, unionmod: str) bool = { + let vv: *syntax.node = unwrapbang(v); + let pp: *syntax.node = unwrapbang(pat); if (vv == nil) { return false; }; if (pp == nil) { return false; }; - if (vv.kind != nkind.N_TNAME) { return false; }; - if (pp.kind != nkind.N_TNAME) { return false; }; - if (!streq(qualleaf(vv.str), qualleaf(pp.str))) { return false; }; - return streq(qualmod(vv.str, unionmod), qualmod(pp.str, unionmod)); + if (vv.kind != syntax.nkind.N_TNAME) { return false; }; + if (pp.kind != syntax.nkind.N_TNAME) { return false; }; + if (!syntax.streq(qualleaf(vv.str), qualleaf(pp.str))) { return false; }; + return syntax.streq(qualmod(vv.str, unionmod), qualmod(pp.str, unionmod)); }; // taggeddefmod — defining module of the typedecl whose body IS the @@ -4875,29 +4875,29 @@ fn casevariantpairmatch(v: *node, pat: *node, unionmod: str) bool = { // Bare variants in that body are defined here: io.error = // !(errors.error | underread | nomem) (module io) -> "io"; errors.error // -> "errors". Falls back to c.curmod when the chain can't resolve. -fn taggeddefmod(c: *checker, st: *node) str = { +fn taggeddefmod(c: *checker, st: *syntax.node) str = { let defmod: str = c.curmod; - let cur: *node = unwrapbang(st); + let cur: *syntax.node = unwrapbang(st); for (cur != nil) { - if (cur.kind != nkind.N_TNAME) { return defmod; }; - let s: *sym = aliassym(c, cur); + if (cur.kind != syntax.nkind.N_TNAME) { return defmod; }; + let s: *syntax.sym = aliassym(c, cur); if (s == nil) { return defmod; }; if (s.decl == nil) { return defmod; }; if (s.decl.nmod.len > 0) { defmod = s.decl.nmod; }; - let body: *node = unwrapbang(s.decl.lhs); + let body: *syntax.node = unwrapbang(s.decl.lhs); if (body == nil) { return defmod; }; - if (body.kind == nkind.N_TTAGGED) { return defmod; }; + if (body.kind == syntax.nkind.N_TTAGGED) { return defmod; }; cur = body; }; return defmod; }; -fn casecovers(c: *checker, cs: *node, want: *node, unionmod: str) bool = { +fn casecovers(c: *checker, cs: *syntax.node, want: *syntax.node, unionmod: str) bool = { if (cs.lhs != nil) { if (typeeqast(c, cs.lhs, want)) { return true; }; if (casevariantpairmatch(want, cs.lhs, unionmod)) { return true; }; }; - let alt: *node = cs.list; + let alt: *syntax.node = cs.list; for (alt != nil) { if (typeeqast(c, alt, want)) { return true; }; if (casevariantpairmatch(want, alt, unionmod)) { return true; }; @@ -4906,10 +4906,10 @@ fn casecovers(c: *checker, cs: *node, want: *node, unionmod: str) bool = { return false; }; -fn errmatchvariant(c: *checker, n: *node, vname: *node) void = { +fn errmatchvariant(c: *checker, n: *syntax.node, vname: *syntax.node) void = { cerr("match: variant not handled"); if (vname != nil) { - if (vname.kind == nkind.N_TNAME) { + if (vname.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(vname.str); cerr(")"); @@ -4930,13 +4930,13 @@ fn errmatchvariant(c: *checker, n: *node, vname: *node) void = { // attributing them the inner union's defining module. Mirrors cstage's // resolve_type flatten (cmd/wcc/check.c:651-674) at the AST layer; the // cgen side already dispatches off the flattened tinfo.params (#61a). -fn casevariantin(c: *checker, tagged: *node, pat: *node, unionmod: str) bool = { - let v: *node = tagged.list; +fn casevariantin(c: *checker, tagged: *syntax.node, pat: *syntax.node, unionmod: str) bool = { + let v: *syntax.node = tagged.list; for (v != nil) { - if (v.op == tkind.TK_ELLIPSIS) { - let inner: *node = resolvealias(c, unwrapbang(v)); + if (v.op == syntax.tkind.TK_ELLIPSIS) { + let inner: *syntax.node = resolvealias(c, unwrapbang(v)); if (inner != nil) { - if (inner.kind == nkind.N_TTAGGED) { + if (inner.kind == syntax.nkind.N_TTAGGED) { if (casevariantin(c, inner, pat, taggeddefmod(c, v))) { return true; @@ -4953,10 +4953,10 @@ fn casevariantin(c: *checker, tagged: *node, pat: *node, unionmod: str) bool = { return false; }; -fn errbadcase(c: *checker, pat: *node) void = { +fn errbadcase(c: *checker, pat: *syntax.node) void = { cerr("case: not a variant of scrutinee"); if (pat != nil) { - if (pat.kind == nkind.N_TNAME) { + if (pat.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(pat.str); cerr(")"); @@ -4966,10 +4966,10 @@ fn errbadcase(c: *checker, pat: *node) void = { c.errs += 1; }; -fn checkmatchexhaust(c: *checker, n: *node) void = { +fn checkmatchexhaust(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { return; }; - let st: *node = scruttype(c, n.lhs); + let st: *syntax.node = scruttype(c, n.lhs); // F9 (task #12): direct `match (expr?)` / `match (expr!)` — cstage // types the try-result as the success variant and rejects when it // is not itself a tagged union (check.c "match on non-tagged- @@ -4980,14 +4980,14 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { // normal exhaustiveness walk, matching cstage's accept. let istry: bool = false; if (st == nil) { - if (n.lhs.kind == nkind.N_TRYPROP || n.lhs.kind == nkind.N_TRYUNW) { + if (n.lhs.kind == syntax.nkind.N_TRYPROP || n.lhs.kind == syntax.nkind.N_TRYUNW) { istry = true; st = exprtype(c, n.lhs, nil); }; }; - let u: *node = resolvealias(c, unwrapbang(st)); + let u: *syntax.node = resolvealias(c, unwrapbang(st)); if (u == nil) { return; }; - if (u.kind != nkind.N_TTAGGED) { + if (u.kind != syntax.nkind.N_TTAGGED) { if (istry) { cerr("match on non-tagged-union try-result\n"); c.errs += 1; @@ -5002,13 +5002,13 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { // Validity: every `case T` pattern (and multi-pattern alts) // must name a variant of u. Catches typos and dead arms that // the dispatch would never reach. - let cs0: *node = n.list; + let cs0: *syntax.node = n.list; for (cs0 != nil) { if (cs0.lhs != nil) { if (!casevariantin(c, u, cs0.lhs, unionmod)) { errbadcase(c, cs0.lhs); }; - let alt: *node = cs0.list; + let alt: *syntax.node = cs0.list; for (alt != nil) { if (!casevariantin(c, u, alt, unionmod)) { errbadcase(c, alt); @@ -5019,13 +5019,13 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { cs0 = cs0.next; }; // Default arm absorbs anything; skip exhaustiveness. - let cs: *node = n.list; + let cs: *syntax.node = n.list; for (cs != nil) { if (cs.lhs == nil) { return; }; // default cs = cs.next; }; // For each variant of u, look for a covering case. - let v: *node = u.list; + let v: *syntax.node = u.list; for (v != nil) { checkvariantcovered(c, n, v, unionmod); v = v.next; @@ -5039,13 +5039,13 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { // members are checked instead. Mirrors the casevariantin spread recursion // + cstage's flattened u->params exhaustiveness walk (cmd/wcc/check.c: // 1648-1669). Leaf variants keep their NODE so errmatchvariant names them. -fn checkvariantcovered(c: *checker, n: *node, v: *node, unionmod: str) void = { - if (v.op == tkind.TK_ELLIPSIS) { - let inner: *node = resolvealias(c, unwrapbang(v)); +fn checkvariantcovered(c: *checker, n: *syntax.node, v: *syntax.node, unionmod: str) void = { + if (v.op == syntax.tkind.TK_ELLIPSIS) { + let inner: *syntax.node = resolvealias(c, unwrapbang(v)); if (inner != nil) { - if (inner.kind == nkind.N_TTAGGED) { + if (inner.kind == syntax.nkind.N_TTAGGED) { let im: str = taggeddefmod(c, v); - let m: *node = inner.list; + let m: *syntax.node = inner.list; for (m != nil) { checkvariantcovered(c, n, m, im); m = m.next; @@ -5055,7 +5055,7 @@ fn checkvariantcovered(c: *checker, n: *node, v: *node, unionmod: str) void = { }; }; let covered: bool = false; - let cs2: *node = n.list; + let cs2: *syntax.node = n.list; for (cs2 != nil) { if (casecovers(c, cs2, v, unionmod)) { covered = true; @@ -5075,16 +5075,16 @@ fn checkvariantcovered(c: *checker, n: *node, v: *node, unionmod: str) void = { // (binary ops, complex exprs we don't infer), we stay quiet — full // type inference lives only on the C side. -fn errnotassign(c: *checker, dst: *node, src: *node, where: str) void = { +fn errnotassign(c: *checker, dst: *syntax.node, src: *syntax.node, where: str) void = { cerr(where); cerr(": not assignable"); if (src != nil) { - if (src.kind == nkind.N_TNAME) { + if (src.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(src.str); cerr(" → "); if (dst != nil) { - if (dst.kind == nkind.N_TNAME) { + if (dst.kind == syntax.nkind.N_TNAME) { cerr(dst.str); }; }; @@ -5106,26 +5106,26 @@ fn errnotassign(c: *checker, dst: *node, src: *node, where: str) void = { // the array-variant box is refused. Mirrors the concrete→tagged variant // select in isassignable (:3859) and cstage tagged_array_variant so the // variant chosen here is the one the box would materialize. -fn taggedarrayvariantctor(c: *checker, dst: *node, src: *node) bool = { +fn taggedarrayvariantctor(c: *checker, dst: *syntax.node, src: *syntax.node) bool = { if (dst == nil) { return false; }; if (src == nil) { return false; }; - let du: *node = resolvealias(c, unwrapbang(dst)); - let su: *node = resolvealias(c, unwrapbang(src)); + let du: *syntax.node = resolvealias(c, unwrapbang(dst)); + let su: *syntax.node = resolvealias(c, unwrapbang(src)); if (du == nil) { return false; }; - if (du.kind != nkind.N_TTAGGED) { return false; }; - if (su != nil) { if (su.kind == nkind.N_TTAGGED) { return false; }; }; - let v: *node = du.list; + if (du.kind != syntax.nkind.N_TTAGGED) { return false; }; + if (su != nil) { if (su.kind == syntax.nkind.N_TTAGGED) { return false; }; }; + let v: *syntax.node = du.list; for (v != nil) { - let vspread: bool = (v.op == tkind.TK_ELLIPSIS); - let vu: *node = resolvealias(c, unwrapbang(v)); + let vspread: bool = (v.op == syntax.tkind.TK_ELLIPSIS); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); let vtagged: bool = false; - if (vu != nil) { if (vu.kind == nkind.N_TTAGGED) { vtagged = true; }; }; + if (vu != nil) { if (vu.kind == syntax.nkind.N_TTAGGED) { vtagged = true; }; }; if (vtagged && !vspread) { if (typeeqast(c, v, src)) { return false; }; } else { let innerconf: bool = false; if (isassignable(c, v, src, &innerconf)) { - if (vu != nil) { if (vu.kind == nkind.N_TARRAY) { return true; }; }; + if (vu != nil) { if (vu.kind == syntax.nkind.N_TARRAY) { return true; }; }; return false; }; }; @@ -5144,7 +5144,7 @@ fn taggedarrayvariantctor(c: *checker, dst: *node, src: *node) bool = { // declared type at cgen, so no element-type restamp is needed — #251 // proved coerce_floatlit's restamp shape does NOT transfer (cgen reads // the declared type's element size, not the literal node's stamp). -fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { +fn checkarrlitfits(c: *checker, arrtn: *syntax.node, rhs: *syntax.node) void = { if (arrtn == nil) { return; }; if (rhs == nil) { return; }; // #106: chase a TY_NAMED alias (`type A=[2]int`) to the underlying @@ -5155,8 +5155,8 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // struct/return/call-arg) alias-aware by construction. arrtn = resolvealias(c, unwrapbang(arrtn)); if (arrtn == nil) { return; }; - if (arrtn.kind != nkind.N_TARRAY) { return; }; - if (rhs.kind != nkind.N_ARRLIT) { return; }; + if (arrtn.kind != syntax.nkind.N_TARRAY) { return; }; + if (rhs.kind != syntax.nkind.N_ARRLIT) { return; }; // #71: more elements than the declared [N] passed every per-element // check below and then smashed the frame at cgen (each element is // stored at its natural offset — the overflow clobbered neighbours @@ -5179,11 +5179,11 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // the wwstage twin of cstage's dropped `alen > 0`. if (arrtn.rhs != nil) { let cnt: u64 = 0u64; - let ce: *node = rhs.list; + let ce: *syntax.node = rhs.list; for (ce != nil) { let cskip: bool = false; - if (ce.kind == nkind.N_FIELD) { - if (streq(ce.str, "...")) { cskip = true; }; + if (ce.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(ce.str, "...")) { cskip = true; }; }; if (!cskip) { cnt += 1u64; }; ce = ce.next; @@ -5198,20 +5198,20 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { return; }; }; - let elemtn: *node = arrtn.lhs; - let at: *tinfo = tinfofornode(c, arrtn); - let et: *tinfo = nil; + let elemtn: *syntax.node = arrtn.lhs; + let at: *syntax.tinfo = tinfofornode(c, arrtn); + let et: *syntax.tinfo = nil; if (at != nil) { et = at.sub; }; et = tichase(et); - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { let skip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { skip = true; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { skip = true; }; }; if (!skip) { - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; // #71: a NESTED array-literal element must run the same // count check against the inner [N] — cstage catches the // nested shape through its typed-literal assignability net @@ -5226,9 +5226,9 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // the segv). resolvealias is transitive, so alias spellings // of any depth take the same recursion; a direct N_TARRAY // passes through unchanged. - let eltr: *node = resolvealias(c, elemtn); - if (eltr != nil && eltr.kind == nkind.N_TARRAY - && ev != nil && ev.kind == nkind.N_ARRLIT) { + let eltr: *syntax.node = resolvealias(c, elemtn); + if (eltr != nil && eltr.kind == syntax.nkind.N_TARRAY + && ev != nil && ev.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, eltr, ev); e = e.next; continue; @@ -5236,7 +5236,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { let v: u64 = 0u64; let folded: bool = false; if (et != nil) { - if (typeisint(et)) { + if (syntax.typeisint(et)) { if (ev != nil) { folded = foldintliteral(ev, &v); }; @@ -5250,7 +5250,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { return; }; } else { - let est: *node = exprtype(c, ev, elemtn); + let est: *syntax.node = exprtype(c, ev, elemtn); let conf2: bool = false; if (est != nil) { if (!isassignable(c, elemtn, est, &conf2)) { @@ -5277,7 +5277,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // N_TUPLE) recurses. Shared by checkletassign (let) and // checkretassign (return). Mirrors cstage's element-wise // type_assignable count-reject; no-ops on scalar elements. -fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { +fn checktuplearrfits(c: *checker, ttn: *syntax.node, tup: *syntax.node) void = { if (ttn == nil) { return; }; if (tup == nil) { return; }; // #38/F2 (review item 10): a tuple literal whose arity differs from the @@ -5291,10 +5291,10 @@ fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { // reject a mismatch before the per-element fits walk. Recursion through // this one choke point gates every nesting depth. let dn: u64 = 0u64; - let dc: *node = ttn.list; + let dc: *syntax.node = ttn.list; for (dc != nil) { dn += 1u64; dc = dc.next; }; let vn: u64 = 0u64; - let vc: *node = tup.list; + let vc: *syntax.node = tup.list; for (vc != nil) { vn += 1u64; vc = vc.next; }; if (dn != vn) { cerr("tuple literal has "); @@ -5305,15 +5305,15 @@ fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { c.errs += 1; return; }; - let dt: *node = ttn.list; - let vt: *node = tup.list; + let dt: *syntax.node = ttn.list; + let vt: *syntax.node = tup.list; for (dt != nil && vt != nil) { - if (vt.kind == nkind.N_ARRLIT) { + if (vt.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, dt.lhs, vt); } else { - if (vt.kind == nkind.N_TUPLE) { - let drt: *node = resolvealias(c, unwrapbang(dt.lhs)); - if (drt != nil && drt.kind == nkind.N_TTUPLE) { + if (vt.kind == syntax.nkind.N_TUPLE) { + let drt: *syntax.node = resolvealias(c, unwrapbang(dt.lhs)); + if (drt != nil && drt.kind == syntax.nkind.N_TTUPLE) { checktuplearrfits(c, drt, vt); }; }; @@ -5344,32 +5344,32 @@ fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { // position there is no addressable backing — loud-reject so the gap is a // compile error, not a dangling-ptr miscompile. Both stages reject here // (rule-10, byte-id-trivial: no asm). Full non-let support is #33. -fn rejectarrlitborrow(c: *checker, dsttn: *node, val: *node) bool = { +fn rejectarrlitborrow(c: *checker, dsttn: *syntax.node, val: *syntax.node) bool = { if (val == nil) { return false; }; - if (val.kind != nkind.N_ARRLIT) { return false; }; - let du: *node = resolvealias(c, unwrapbang(dsttn)); + if (val.kind != syntax.nkind.N_ARRLIT) { return false; }; + let du: *syntax.node = resolvealias(c, unwrapbang(dsttn)); if (du == nil) { return false; }; - if (du.kind != nkind.N_TSLICE) { return false; }; + if (du.kind != syntax.nkind.N_TSLICE) { return false; }; let m: str = "array literal cannot borrow as a slice here; bind it to a `let` first\n"; cerr(m); c.errs += 1; return true; }; -fn desugararrayslice(c: *checker, dsttn: *node, srctn: *node, val: *node) *node = { +fn desugararrayslice(c: *checker, dsttn: *syntax.node, srctn: *syntax.node, val: *syntax.node) *syntax.node = { if (dsttn == nil) { return val; }; if (srctn == nil) { return val; }; if (val == nil) { return val; }; - let du: *node = resolvealias(c, unwrapbang(dsttn)); - let su: *node = resolvealias(c, unwrapbang(srctn)); + let du: *syntax.node = resolvealias(c, unwrapbang(dsttn)); + let su: *syntax.node = resolvealias(c, unwrapbang(srctn)); if (du == nil) { return val; }; if (su == nil) { return val; }; - if (du.kind != nkind.N_TSLICE) { return val; }; - if (su.kind != nkind.N_TARRAY) { return val; }; + if (du.kind != syntax.nkind.N_TSLICE) { return val; }; + if (su.kind != syntax.nkind.N_TARRAY) { return val; }; if (!typeeqast(c, du.lhs, su.lhs)) { return val; }; - let sl: *node = newnode(nkind.N_SLICE, val.file, val.line, val.col); + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_SLICE, val.file, val.line, val.col); sl.lhs = val; // sliced base; lo (.rhs) / hi (.cond) nil → 0 : len(arr) - let slt: *node = newnode(nkind.N_TSLICE, "", 0, 0); + let slt: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); slt.lhs = su.lhs; sl.type_ = tinfofornode(c, slt): *void; sl.next = val.next; @@ -5383,28 +5383,28 @@ fn desugararrayslice(c: *checker, dsttn: *node, srctn: *node, val: *node) *node // module-qualified via the SK_USE receiver). nil for builtins / fn-value // callees — they have no declared param list to drive the #258 desugar, // and the selfhost corpus has no array→slice arg there anyway. -fn calleefndecl(c: *checker, callee: *node) *node = { +fn calleefndecl(c: *checker, callee: *syntax.node) *syntax.node = { if (callee == nil) { return nil; }; - if (callee.kind == nkind.N_IDENT) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, callee.str); + if (callee.kind == syntax.nkind.N_IDENT) { + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, callee.str); if (s != nil) { - if (s.skind == skind.SK_FN) { return s.decl; }; + if (s.skind == syntax.skind.SK_FN) { return s.decl; }; }; return nil; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { - let ms: *sym = scopelookupprefer(c.cur, c.curmod, callee.lhs.str); - if (ms != nil && ms.skind != skind.SK_USE) { - let mu: *sym = scopelookupuselocal(ms.scope, callee.lhs.str); + if (callee.lhs.kind == syntax.nkind.N_IDENT) { + let ms: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, callee.lhs.str); + if (ms != nil && ms.skind != syntax.skind.SK_USE) { + let mu: *syntax.sym = syntax.scopelookupuselocal(ms.scope, callee.lhs.str); if (mu != nil) { ms = mu; }; }; if (ms != nil) { - if (ms.skind == skind.SK_USE || ms.use_alias != 0i32) { - let fs: *sym = scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), callee.str); + if (ms.skind == syntax.skind.SK_USE || ms.use_alias != 0i32) { + let fs: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), callee.str); if (fs != nil) { - if (fs.skind == skind.SK_FN) { return fs.decl; }; + if (fs.skind == syntax.skind.SK_FN) { return fs.decl; }; }; }; }; @@ -5419,7 +5419,7 @@ fn calleefndecl(c: *checker, callee: *node) *node = { // passed where a []T param is expected. Mirrors cstage cmd/wcc/check.c's // non-variadic call-arg arm. Variadic (`T...`) slots are skipped (the // arg flows into the gather as an element, not the slice itself). -fn desugarcallargs(c: *checker, n: *node) void = { +fn desugarcallargs(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; // #24: a 1-arg `free(x)` is the Hare no-op pseudo-builtin (#27), NOT the // rt 2-arg `free(p: *void, n: u64)` that calleefndecl resolves to in the @@ -5431,12 +5431,12 @@ fn desugarcallargs(c: *checker, n: *node) void = { // `free(slice)` (regex finish #27) isn't checked against rt_free's *void // param. `free` is the only builtin name with a colliding real decl // (len/alloc/append/delete/insert keep nil decls → calleefndecl bails). - if (n.lhs != nil) { if (n.lhs.kind == nkind.N_IDENT) { - if (streq(n.lhs.str, "free")) { + if (n.lhs != nil) { if (n.lhs.kind == syntax.nkind.N_IDENT) { + if (syntax.streq(n.lhs.str, "free")) { if (n.list != nil) { if (n.list.next == nil) { return; }; }; }; }; }; - let decl: *node = calleefndecl(c, n.lhs); + let decl: *syntax.node = calleefndecl(c, n.lhs); // task #51: calleefndecl nils every fn-VALUE callee — a deref `(*fp)(...)` // (N_UN), an SK_VAR fn-ptr ident, a struct-field fn call — so this bail // skips the #258 array→slice desugar AND the general arg typecheck for @@ -5445,22 +5445,22 @@ fn desugarcallargs(c: *checker, n: *node) void = { // (cmd/wcc/check.c:1828 type_chase_named(cexpr(callee))). The type-keyed // callee path is MECHANISM (not a checker gate) — filed as task #51. if (decl == nil) { return; }; - let param: *node = decl.list; - let prev: *node = nil; - let a: *node = n.list; + let param: *syntax.node = decl.list; + let prev: *syntax.node = nil; + let a: *syntax.node = n.list; for (a != nil) { - let nexta: *node = a.next; + let nexta: *syntax.node = a.next; if (param != nil) { - if (param.kind == nkind.N_PARAM) { - if (param.op != tkind.TK_ELLIPSIS) { - let atype: *node = exprtype(c, a, nil); + if (param.kind == syntax.nkind.N_PARAM) { + if (param.op != syntax.tkind.TK_ELLIPSIS) { + let atype: *syntax.node = exprtype(c, a, nil); // #29: a rune literal narrowing into an integer param // (`take('b')` where take(b: u8)). Override atype to the // integer target so c3's general isassignable accepts, // mirroring cstage's coarse untyped_rune rule. See // coercerunelit. cgen is byte-id-neutral (narrows by the // param/destination width). - let runet: *node = coercerunelit(c, a, param.lhs); + let runet: *syntax.node = coercerunelit(c, a, param.lhs); if (runet != nil) { atype = runet; }; // #24: GENERAL per-arg assignability — align UP to // cstage check.c:1867-1870, which type_assignables @@ -5486,20 +5486,20 @@ fn desugarcallargs(c: *checker, n: *node) void = { // of falling to cgen #271's late aggregate-arg loud. // param.lhs is the declared param type (alias-aware // via the resolvealias chase in checkarrlitfits). - if (a.kind == nkind.N_ARRLIT) { + if (a.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, param.lhs, a); }; // #31/#33: bare array-literal arg has no backing // — loud-reject (supported only at a `let`). if (!rejectarrlitborrow(c, param.lhs, a)) { - let rep: *node = desugararrayslice(c, param.lhs, atype, a); + let rep: *syntax.node = desugararrayslice(c, param.lhs, atype, a); if (rep != a) { if (prev == nil) { n.list = rep; } else { prev.next = rep; }; a = rep; }; }; }; - if (param.op != tkind.TK_ELLIPSIS) { param = param.next; }; + if (param.op != syntax.tkind.TK_ELLIPSIS) { param = param.next; }; }; }; prev = a; @@ -5512,7 +5512,7 @@ fn desugarcallargs(c: *checker, n: *node) void = { // route an array→slice rhs through the shared desugar so w6c_ww emits // the same borrow as w6c (rule-10). No error diagnostics — cstage gates // the shape. -fn checkassign(c: *checker, n: *node) void = { +fn checkassign(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { return; }; if (n.rhs == nil) { return; }; @@ -5520,9 +5520,9 @@ fn checkassign(c: *checker, n: *node) void = { // is_const bit set at the let-install above). A bare `_` discard // lvalue carries an empty str and is skipped. Mirror cstage // cmd/wcc/check.c:1889-1896. - if (n.lhs.kind == nkind.N_IDENT) { + if (n.lhs.kind == syntax.nkind.N_IDENT) { if (n.lhs.str.len > 0) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, n.lhs.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, n.lhs.str); if (s != nil) { if (s.is_const != 0i32) { cerr("error: cannot assign to const binding\n"); @@ -5531,14 +5531,14 @@ fn checkassign(c: *checker, n: *node) void = { }; }; }; - let ltn: *node = exprtype(c, n.lhs, nil); - let rtn: *node = exprtype(c, n.rhs, nil); + let ltn: *syntax.node = exprtype(c, n.lhs, nil); + let rtn: *syntax.node = exprtype(c, n.rhs, nil); // #29: a rune literal narrowing into an integer assign/index-store // target (`buf[i] = 'F'`). Override rtn to the integer target so a // general assign typecheck accepts, mirroring cstage's coarse // untyped_rune rule. See coercerunelit. cgen narrows by the destination // width (byte-id-neutral). Removes the getopt `'X': u8` index casts. - let runet: *node = coercerunelit(c, n.rhs, ltn); + let runet: *syntax.node = coercerunelit(c, n.rhs, ltn); if (runet != nil) { rtn = runet; }; // #24/#36 (rule-7 deferred-divergence, NEVER silent): the ASSIGN seam // does NOT yet route the general conf-gated UNION (isassignable || @@ -5575,35 +5575,35 @@ fn checkassign(c: *checker, n: *node) void = { // never a silent zero-length array (rule 7). Idempotent (skips once the // length child is set), so the module-level double-call (checkfile's // pre-resolvewalk call + checkletassign here) raises at most one error. -fn inferarraylen(c: *checker, n: *node) void = { +fn inferarraylen(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { return; }; - if (n.lhs.kind != nkind.N_TARRAY) { return; }; + if (n.lhs.kind != syntax.nkind.N_TARRAY) { return; }; if (n.lhs.rhs != nil) { return; }; // explicit [N] or already inferred - if (n.rhs == nil || n.rhs.kind != nkind.N_ARRLIT) { + if (n.rhs == nil || n.rhs.kind != syntax.nkind.N_ARRLIT) { cerr("error: [_]T needs an array-literal initialiser\n"); c.errs += 1; - let z: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let z: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); z.uval = 0u64; n.lhs.rhs = z; // sentinel: idempotent, error already raised return; }; let cnt: u64 = 0u64; - let it: *node = n.rhs.list; + let it: *syntax.node = n.rhs.list; for (it != nil) { let skip: bool = false; - if (it.kind == nkind.N_FIELD) { - if (streq(it.str, "...")) { skip = true; }; + if (it.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(it.str, "...")) { skip = true; }; }; if (!skip) { cnt += 1u64; }; it = it.next; }; - let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let cn: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); cn.uval = cnt; n.lhs.rhs = cn; }; -fn checkletassign(c: *checker, n: *node) void = { +fn checkletassign(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; inferarraylen(c, n); // #7: must run before the n.rhs==nil bail if (n.rhs == nil) { return; }; // no init @@ -5614,34 +5614,34 @@ fn checkletassign(c: *checker, n: *node) void = { // exprtype, so flag the exact call node up front; exprtype errors on // any empty alloc that isn't this one). Peel the same ?/! wrapper #45 // peels so the flagged node matches. - let octx: *node = nil; - if (n.lhs != nil && n.lhs.kind == nkind.N_TSLICE) { - let inner: *node = n.rhs; - if (inner.kind == nkind.N_TRYPROP) { + let octx: *syntax.node = nil; + if (n.lhs != nil && n.lhs.kind == syntax.nkind.N_TSLICE) { + let inner: *syntax.node = n.rhs; + if (inner.kind == syntax.nkind.N_TRYPROP) { inner = inner.lhs; - } else { if (inner.kind == nkind.N_TRYUNW) { + } else { if (inner.kind == syntax.nkind.N_TRYUNW) { inner = inner.lhs; }; }; - if (inner != nil && inner.kind == nkind.N_CALL) { - let callee: *node = inner.lhs; - let a0: *node = inner.list; - let a1: *node = nil; - let a2: *node = nil; + if (inner != nil && inner.kind == syntax.nkind.N_CALL) { + let callee: *syntax.node = inner.lhs; + let a0: *syntax.node = inner.list; + let a1: *syntax.node = nil; + let a2: *syntax.node = nil; if (a0 != nil) { a1 = a0.next; }; if (a1 != nil) { a2 = a1.next; }; if (callee != nil - && callee.kind == nkind.N_IDENT - && streq(callee.str, "alloc") - && a0 != nil && a0.kind == nkind.N_ARRLIT + && callee.kind == syntax.nkind.N_IDENT + && syntax.streq(callee.str, "alloc") + && a0 != nil && a0.kind == syntax.nkind.N_ARRLIT && a0.list == nil && a1 != nil && a2 == nil) { octx = inner; }; }; }; - let savedoctx: *node = c.allococtx; + let savedoctx: *syntax.node = c.allococtx; c.allococtx = octx; - let src: *node = exprtype(c, n.rhs, nil); + let src: *syntax.node = exprtype(c, n.rhs, nil); c.allococtx = savedoctx; // Inferred binding (`let r = expr;`, no type annotation). Mirror // cstage cmd/wcc/check.c:1477 clet `if (t == NULL && initt) t = @@ -5662,10 +5662,10 @@ fn checkletassign(c: *checker, n: *node) void = { // one downstream. cstage needs no twin: check.c:1477 clet carries // Sym.type (tinfo), and its emission is annotation-invariant // (probed identical asm annotated vs not). - if (src != nil && src.kind == nkind.N_TSTRUCT - && n.rhs.kind == nkind.N_STRUCTLIT - && n.rhs.lhs != nil && n.rhs.lhs.kind == nkind.N_IDENT) { - let ltn: *node = mktname(c, n.rhs.lhs.str); + if (src != nil && src.kind == syntax.nkind.N_TSTRUCT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT + && n.rhs.lhs != nil && n.rhs.lhs.kind == syntax.nkind.N_IDENT) { + let ltn: *syntax.node = mktname(c, n.rhs.lhs.str); ltn.type_ = tinfofornode(c, ltn): *void; n.lhs = ltn; return; @@ -5681,44 +5681,44 @@ fn checkletassign(c: *checker, n: *node) void = { // so isassignable sees exact equality. cgenstmt cglet drives the // element size from n.lhs already (cmd/wcc/cgenstmt.ww), so this // stays symmetric with cstage check.c clet's parallel retype. - if (n.lhs.kind == nkind.N_TSLICE) { + if (n.lhs.kind == syntax.nkind.N_TSLICE) { let wrapped: bool = false; - let inner: *node = n.rhs; - if (inner.kind == nkind.N_TRYPROP) { + let inner: *syntax.node = n.rhs; + if (inner.kind == syntax.nkind.N_TRYPROP) { wrapped = true; inner = inner.lhs; - } else { if (inner.kind == nkind.N_TRYUNW) { + } else { if (inner.kind == syntax.nkind.N_TRYUNW) { wrapped = true; inner = inner.lhs; }; }; - if (inner != nil && inner.kind == nkind.N_CALL) { - let callee: *node = inner.lhs; - let a0: *node = inner.list; - let a1: *node = nil; - let a2: *node = nil; + if (inner != nil && inner.kind == syntax.nkind.N_CALL) { + let callee: *syntax.node = inner.lhs; + let a0: *syntax.node = inner.list; + let a1: *syntax.node = nil; + let a2: *syntax.node = nil; if (a0 != nil) { a1 = a0.next; }; if (a1 != nil) { a2 = a1.next; }; if (callee != nil - && callee.kind == nkind.N_IDENT - && streq(callee.str, "alloc") - && a0 != nil && a0.kind == nkind.N_ARRLIT + && callee.kind == syntax.nkind.N_IDENT + && syntax.streq(callee.str, "alloc") + && a0 != nil && a0.kind == syntax.nkind.N_ARRLIT && a0.list == nil && a1 != nil && a2 == nil) { let shadowed: bool = false; if (c.curmod.len > 0) { - if (scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { + if (syntax.scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { shadowed = true; }; }; if (!shadowed) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = n.lhs.lhs; if (wrapped) { src = sl; } else { - let nome: *node = mktname(c, "nomem"); + let nome: *syntax.node = mktname(c, "nomem"); sl.next = nome; - let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTAGGED, "", 0, 0); tt.list = sl; src = tt; }; @@ -5744,8 +5744,8 @@ fn checkletassign(c: *checker, n: *node) void = { // here too so an alias-of-array routes through the same over-fill. A // direct N_TARRAY is unchanged (resolvealias is idempotent), and the // early return matches the direct-array branch's pre-existing return. - let llhs: *node = resolvealias(c, unwrapbang(n.lhs)); - if (llhs != nil && llhs.kind == nkind.N_TARRAY && n.rhs.kind == nkind.N_ARRLIT) { + let llhs: *syntax.node = resolvealias(c, unwrapbang(n.lhs)); + if (llhs != nil && llhs.kind == syntax.nkind.N_TARRAY && n.rhs.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, n.lhs, n.rhs); return; }; @@ -5759,8 +5759,8 @@ fn checkletassign(c: *checker, n: *node) void = { // early return — the rest of checkletassign still runs for the tuple. // N_TTUPLE elements wrap their type on .lhs (N_TPARAM chain, // stamptuplebinds:311); the N_TUPLE rhs values chain directly on .list. - if (llhs != nil && llhs.kind == nkind.N_TTUPLE - && n.rhs.kind == nkind.N_TUPLE) { + if (llhs != nil && llhs.kind == syntax.nkind.N_TTUPLE + && n.rhs.kind == syntax.nkind.N_TUPLE) { checktuplearrfits(c, llhs, n.rhs); }; // #25/#31: an array literal initialising a SLICE local. Re-stamp the @@ -5771,21 +5771,21 @@ fn checkletassign(c: *checker, n: *node) void = { // [count]T), then drive isassignable + the borrow off [count]T. Twin of // cstage arrlit_init_fits' slice arm. Local-only (c.cur != c.top): the // borrow runs at runtime; module-level slice-from-arrlit stays #32. - if (c.cur != c.top && n.lhs.kind == nkind.N_TSLICE - && n.rhs.kind == nkind.N_ARRLIT) { + if (c.cur != c.top && n.lhs.kind == syntax.nkind.N_TSLICE + && n.rhs.kind == syntax.nkind.N_ARRLIT) { let cnt: u64 = 0u64; - let e0: *node = n.rhs.list; + let e0: *syntax.node = n.rhs.list; for (e0 != nil) { let skip: bool = false; - if (e0.kind == nkind.N_FIELD) { - if (streq(e0.str, "...")) { skip = true; }; + if (e0.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e0.str, "...")) { skip = true; }; }; if (!skip) { cnt += 1u64; }; e0 = e0.next; }; - let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let cn: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); cn.uval = cnt; - let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0); + let arr: *syntax.node = syntax.newnode(syntax.nkind.N_TARRAY, "", 0, 0); arr.lhs = n.lhs.lhs; // declared slice element type arr.rhs = cn; checkarrlitfits(c, arr, n.rhs); @@ -5801,7 +5801,7 @@ fn checkletassign(c: *checker, n: *node) void = { // #29: an un-suffixed rune literal narrowing into an integer let target // (`let b: u8 = 'a'`). Override src to the integer target so isassignable // accepts, mirroring cstage's coarse untyped_rune rule. See coercerunelit. - let runet: *node = coercerunelit(c, n.rhs, n.lhs); + let runet: *syntax.node = coercerunelit(c, n.rhs, n.lhs); if (runet != nil) { src = runet; }; let conf: bool = false; let ok: bool = isassignable(c, n.lhs, src, &conf); @@ -5834,7 +5834,7 @@ fn checkletassign(c: *checker, n: *node) void = { }; }; -fn checkretassign(c: *checker, n: *node) void = { +fn checkretassign(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { // bare `return;` — mirror cstage cmd/wcc/check.c:2428-2439: @@ -5845,7 +5845,7 @@ fn checkretassign(c: *checker, n: *node) void = { // reaches the same verdict (void→void typeeqast; void→tagged via // the void variant; void→i32 a confident primitive mismatch). if (c.fnret == nil) { return; }; - let vt: *node = mktname(c, "void"); + let vt: *syntax.node = mktname(c, "void"); let vconf: bool = false; let vok: bool = isassignable(c, c.fnret, vt, &vconf); if (vconf) { if (!vok) { errnotassign(c, c.fnret, vt, "return"); }; }; @@ -5859,7 +5859,7 @@ fn checkretassign(c: *checker, n: *node) void = { // would short-circuit the check (the alias path set conf=true, so neg3 // caught it but the direct neg0 slipped). Alias-aware via the // resolvealias chase at the top of checkarrlitfits. - if (n.lhs.kind == nkind.N_ARRLIT) { + if (n.lhs.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, c.fnret, n.lhs); }; // #25: array-typed element of a TUPLE RETURN with an overlong array @@ -5870,18 +5870,18 @@ fn checkretassign(c: *checker, n: *node) void = { // BEFORE the isassignable/conf guards (a tuple return drives // conf=false → short-circuit), same reason as the #12 array arm // above. Alias/!-aware on the fnret tuple type. - let rrt: *node = resolvealias(c, unwrapbang(c.fnret)); - if (rrt != nil && rrt.kind == nkind.N_TTUPLE - && n.lhs.kind == nkind.N_TUPLE) { + let rrt: *syntax.node = resolvealias(c, unwrapbang(c.fnret)); + if (rrt != nil && rrt.kind == syntax.nkind.N_TTUPLE + && n.lhs.kind == syntax.nkind.N_TUPLE) { checktuplearrfits(c, rrt, n.lhs); }; - let src: *node = exprtype(c, n.lhs, nil); + let src: *syntax.node = exprtype(c, n.lhs, nil); if (src == nil) { return; }; // #29: a rune literal returned into an integer (or integer-variant) // fnret (`return '\\';` into u8 or (u8 | star | ...)). Override src so // isassignable accepts; cgen boxes via the shape fallback. See // coercerunelit. Removes the fnmatch.ww:126 `'\\': u8` workaround cast. - let runet: *node = coercerunelit(c, n.lhs, c.fnret); + let runet: *syntax.node = coercerunelit(c, n.lhs, c.fnret); if (runet != nil) { src = runet; }; let conf: bool = false; let ok: bool = isassignable(c, c.fnret, src, &conf); @@ -5910,10 +5910,10 @@ fn checkretassign(c: *checker, n: *node) void = { // union and that T name one of its variants. Operates on AST type // expressions; falls back silently when we can't determine e's // type (matches the case-variant rule for match). -fn checkisas(c: *checker, n: *node) void = { +fn checkisas(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; // e is in n.lhs (value), T is in n.rhs (type expr). - let st: *node = scruttype(c, n.lhs); + let st: *syntax.node = scruttype(c, n.lhs); // F9 (task #12): direct `expr? is T` / `expr! is T` — cstage cexpr // types the ?/! result as the success variant and the non-tagged // gate below then rejects (check.c "is on non-tagged-union"). @@ -5923,11 +5923,11 @@ fn checkisas(c: *checker, n: *node) void = { // union variant) flows on into the variant checks, matching // cstage's accept. if (st == nil && n.lhs != nil) { - if (n.lhs.kind == nkind.N_TRYPROP || n.lhs.kind == nkind.N_TRYUNW) { + if (n.lhs.kind == syntax.nkind.N_TRYPROP || n.lhs.kind == syntax.nkind.N_TRYUNW) { st = exprtype(c, n.lhs, nil); }; }; - let u: *node = resolvealias(c, unwrapbang(st)); + let u: *syntax.node = resolvealias(c, unwrapbang(st)); if (u == nil) { return; }; // #52: enum ↔ int reinterpret (`enum as intT` / `intT as enum`). // Mirrors cstage cmd/wcc/check.c:1346-1357 — N_TYPEASSERT with an @@ -5937,22 +5937,22 @@ fn checkisas(c: *checker, n: *node) void = { // the lib/os syscall casts stop false-positiving. `is` (TYPETEST) // stays rejected on non-tagged operands — cstage cmd/wcc/check.c // gates the bypass on N_TYPEASSERT only. - if (n.kind == nkind.N_TYPEASSERT) { - let v: *node = resolvealias(c, unwrapbang(n.rhs)); + if (n.kind == syntax.nkind.N_TYPEASSERT) { + let v: *syntax.node = resolvealias(c, unwrapbang(n.rhs)); let lhsenum: bool = false; let rhsenum: bool = false; - if (u != nil) { if (u.kind == nkind.N_TENUM) { lhsenum = true; }; }; - if (v != nil) { if (v.kind == nkind.N_TENUM) { rhsenum = true; }; }; + if (u != nil) { if (u.kind == syntax.nkind.N_TENUM) { lhsenum = true; }; }; + if (v != nil) { if (v.kind == syntax.nkind.N_TENUM) { rhsenum = true; }; }; if (lhsenum || rhsenum) { if (isinttypeast(u)) { if (isinttypeast(v)) { return; }; }; }; }; - if (u.kind != nkind.N_TTAGGED) { + if (u.kind != syntax.nkind.N_TTAGGED) { cerr("is/as: operand is not a tagged union\n"); c.errs += 1; return; }; - let want: *node = n.rhs; + let want: *syntax.node = n.rhs; if (want == nil) { return; }; // #198: route through tinfo.params (the #61a-flattened chain built // at L1789-1845 N_TTAGGED) — the prior AST u.list walk via @@ -5963,8 +5963,8 @@ fn checkisas(c: *checker, n: *node) void = { // keys off at cgenexpr.ww:155). project_tinfo_lossy_nominal: name- // keying was the pre-Phase-N workaround for tinfo lossy on nominal // identity; typeeq inside flatvariantidxt now handles NAMED ptr-id. - let utinfo: *tinfo = tinfofornode(c, u); - let wanttinfo: *tinfo = tinfofornode(c, want); + let utinfo: *syntax.tinfo = tinfofornode(c, u); + let wanttinfo: *syntax.tinfo = tinfofornode(c, want); if (utinfo != nil) { if (wanttinfo != nil) { // exact-only (#95-c3): is/as acceptance is nominal variant // membership; the cgen tag-synthesis chain/structural arms must @@ -5975,7 +5975,7 @@ fn checkisas(c: *checker, n: *node) void = { }; }; if (casevariantin(c, u, want, taggeddefmod(c, st))) { return; }; cerr("is/as: not a variant of operand"); - if (want.kind == nkind.N_TNAME) { + if (want.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(want.str); cerr(")"); @@ -5993,35 +5993,35 @@ fn checkisas(c: *checker, n: *node) void = { // we look at the expr's *declared* type for nkind.N_IDENT/nkind.N_CALL // cases. -fn exprtypeoftry(c: *checker, e: *node) *node = { +fn exprtypeoftry(c: *checker, e: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - if (e.kind == nkind.N_IDENT) { + if (e.kind == syntax.nkind.N_IDENT) { // #11a: curmod preference (the #53/#55 family). A bare ident // whose leaf also names a global in a later module otherwise // binds the foreign decl's type, mis-typing the try operand and // either spuriously rejecting valid `?` code or skipping the F8 // reject. Mirrors exprtype's own N_IDENT arm (scopelookupprefer // at :2897); cstage types the operand via cexpr with cur_mod. - let s: *sym = scopelookupprefer(c.cur, c.curmod, e.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; return s.decl.lhs; }; - if (e.kind == nkind.N_CALL) { + if (e.kind == syntax.nkind.N_CALL) { // callee return type lookup: callee is e.lhs (nkind.N_IDENT or // nkind.N_DOT). We need the fn-decl's lhs (return-type AST). - let callee: *node = e.lhs; + let callee: *syntax.node = e.lhs; if (callee == nil) { return nil; }; let nm: str; nm.ptr = nil; nm.len = 0; - if (callee.kind == nkind.N_IDENT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_IDENT) { nm = callee.str; }; // #11b/task #51: an N_DOT callee `mod.f()?` is looked up by BARE // LEAF here, NOT via the module qualifier (callee.lhs) the way // exprtype's own N_CALL arm does (:3095 scopelookupinmodule) — a // cross-module same-leaf `f` misbinds. The mechanism fix (module- // keyed callee resolution + the deref-callee `(*fp)()?` shape that // returns nil below) rides task #51 with the fn-ptr-callee desugar. - if (callee.kind == nkind.N_DOT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_DOT) { nm = callee.str; }; if (nm.len == 0) { return nil; }; // #11a: curmod preference for the bare-leaf callee. A same-leaf // `op()?` declared in a later module otherwise binds the foreign @@ -6030,9 +6030,9 @@ fn exprtypeoftry(c: *checker, e: *node) *node = { // N_CALL arm (scopelookupprefer at :3336). The N_DOT-callee leaf // (callee.str above) still resolves bare-leaf, not via the module // qualifier callee.lhs.str — that module-keyed fix rides task #51. - let s: *sym = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, nm); if (s == nil) { return nil; }; - if (s.skind != skind.SK_FN) { return nil; }; + if (s.skind != syntax.skind.SK_FN) { return nil; }; if (s.decl == nil) { return nil; }; return s.decl.lhs; }; @@ -6056,12 +6056,12 @@ fn exprtypeoftry(c: *checker, e: *node) *node = { // or a spliced member carries the error, so each flattened member routes // through varianterr, matching cstage's per-param iserror. Mirrors the #209 // spread recursion tinfofornode already runs over vu.params (check.ww:2275). -fn trycountvariants(c: *checker, outer: *node, v: *node, nsuccp: *int, +fn trycountvariants(c: *checker, outer: *syntax.node, v: *syntax.node, nsuccp: *int, haserrp: *bool, depth: i32) void = { for (v != nil) { - if (v.op == tkind.TK_ELLIPSIS && depth < 8i32) { - let inner: *node = resolvealias(c, unwrapbang(v)); - if (inner != nil && inner.kind == nkind.N_TTAGGED) { + if (v.op == syntax.tkind.TK_ELLIPSIS && depth < 8i32) { + let inner: *syntax.node = resolvealias(c, unwrapbang(v)); + if (inner != nil && inner.kind == syntax.nkind.N_TTAGGED) { trycountvariants(c, outer, inner.list, nsuccp, haserrp, depth + 1i32); v = v.next; @@ -6074,12 +6074,12 @@ fn trycountvariants(c: *checker, outer: *node, v: *node, nsuccp: *int, }; }; -fn checktryprop(c: *checker, n: *node) void = { +fn checktryprop(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; - let t: *node = exprtypeoftry(c, n.lhs); - let u: *node = resolvealias(c, unwrapbang(t)); + let t: *syntax.node = exprtypeoftry(c, n.lhs); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return; }; - if (u.kind != nkind.N_TTAGGED) { return; }; + if (u.kind != syntax.nkind.N_TTAGGED) { return; }; // F8 interim gate (task #5): try-propagation assumes ONE success // member end-to-end — exprtype collapses to the first non-error // variant and cgen emits a single tag compare, so any OTHER @@ -6094,33 +6094,33 @@ fn checktryprop(c: *checker, n: *node) void = { // multi-success gate counts the spliced members, not the spread alias. trycountvariants(c, u, u.list, &nsucc, &haserr, 0i32); if (nsucc > 1) { - if (n.kind == nkind.N_TRYPROP) { cerr("?"); } else { cerr("!"); }; + if (n.kind == syntax.nkind.N_TRYPROP) { cerr("?"); } else { cerr("!"); }; cerr(": multi-success union unwired (task #14): bind and match instead\n"); c.errs += 1; return; }; // `!` has no propagation, so no error-subset check (mirrors // cstage's N_TRYPROP-only guard on the subset walk). - if (n.kind != nkind.N_TRYPROP) { return; }; + if (n.kind != syntax.nkind.N_TRYPROP) { return; }; if (!haserr) { return; }; // Enclosing fn must return a tagged union with each operand // error variant present. - let r: *node = resolvealias(c, unwrapbang(c.fnret)); + let r: *syntax.node = resolvealias(c, unwrapbang(c.fnret)); if (r == nil) { cerr("?: enclosing fn has no tagged-union return\n"); c.errs += 1; return; }; - if (r.kind != nkind.N_TTAGGED) { + if (r.kind != syntax.nkind.N_TTAGGED) { cerr("?: enclosing fn return is not tagged\n"); c.errs += 1; return; }; - let ev: *node = u.list; + let ev: *syntax.node = u.list; for (ev != nil) { if (iserrvariant(c, u, ev)) { let found: bool = false; - let rv: *node = r.list; + let rv: *syntax.node = r.list; for (rv != nil) { if (typeeqast(c, rv, ev)) { found = true; @@ -6146,10 +6146,10 @@ fn checktryprop(c: *checker, n: *node) void = { // into w6c_ww so the diagnostic class lands as a single coordinated // step rather than dribbling in. Matches the cstage-only neg-case // precedent at test/wcc/708 + test/wcc/696. -fn installparams(c: *checker, params: *node) void = { - let p: *node = params; +fn installparams(c: *checker, params: *syntax.node) void = { + let p: *syntax.node = params; for (p != nil) { - if (p.kind == nkind.N_PARAM) { + if (p.kind == syntax.nkind.N_PARAM) { // Hare-style variadic `T...`: normalize p.lhs to []T so // downstream consumers (N_IDENT exprtype lookups via // s.decl.lhs, cgen's variadic-slot synthesis) see the @@ -6157,9 +6157,9 @@ fn installparams(c: *checker, params: *node) void = { // `tp->type = type_slice(c->a, pt)` and harec // check_func_type. Surface-fidelity preserved: wwdump // -a runs parser only and never reaches this mutation. - if (p.op == tkind.TK_ELLIPSIS) { - if (p.lhs != nil && p.lhs.kind != nkind.N_TSLICE) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + if (p.op == syntax.tkind.TK_ELLIPSIS) { + if (p.lhs != nil && p.lhs.kind != syntax.nkind.N_TSLICE) { + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = p.lhs; p.lhs = sl; }; @@ -6167,7 +6167,7 @@ fn installparams(c: *checker, params: *node) void = { let nm: str = p.str; if (nm.len > 0) { checkmoduleshadow(c, nm, "param"); - scopedefine(c.cur, nm, skind.SK_PARAM, nil, p); + syntax.scopedefine(c.cur, nm, syntax.skind.SK_PARAM, nil, p); }; }; p = p.next; @@ -6178,22 +6178,22 @@ fn installparams(c: *checker, params: *node) void = { // then walk the body. Local lets installed by walk_stmt (a future // extension); for the current pass we just resolve-walk without // per-statement scopes. -fn resolvefnbody(c: *checker, fnnode: *node) void = { - let outer: *scope = c.cur; - c.cur = newscope(c.cur); +fn resolvefnbody(c: *checker, fnnode: *syntax.node) void = { + let outer: *syntax.scope = c.cur; + c.cur = syntax.newscope(c.cur); installparams(c, fnnode.list); // #61 audit §1.8 — A.2: walk each param's declared type-expr so // tinfofornode stamps n.type_ on it. installparams binds the name // but never recurses into the type; without this, cgen's slotsize // fast-path hits the fallback for every param load/store. - let p: *node = fnnode.list; + let p: *syntax.node = fnnode.list; for (p != nil) { - if (p.kind == nkind.N_PARAM) { + if (p.kind == syntax.nkind.N_PARAM) { if (p.lhs != nil) { resolvewalk(c, p.lhs); }; }; p = p.next; }; - let prevret: *node = c.fnret; + let prevret: *syntax.node = c.fnret; c.fnret = fnnode.lhs; // return type AST, used by `?` check if (fnnode.body != nil) { resolvewalk(c, fnnode.body); @@ -6211,13 +6211,13 @@ fn resolvefnbody(c: *checker, fnnode: *node) void = { // callee carry no type by design. Recognized exactly as the cstage // builtin intercept (cmd/wcc/check.c:1314,1328): the reserved name // with no shadowing user symbol. -fn isassertfam(c: *checker, id: *node) bool = { +fn isassertfam(c: *checker, id: *syntax.node) bool = { if (id == nil) { return false; }; - if (id.kind != nkind.N_IDENT) { return false; }; - if (!streq(id.str, "abort") && !streq(id.str, "assert")) { + if (id.kind != syntax.nkind.N_IDENT) { return false; }; + if (!syntax.streq(id.str, "abort") && !syntax.streq(id.str, "assert")) { return false; }; - return scopelookupprefer(c.cur, c.curmod, id.str) == nil; + return syntax.scopelookupprefer(c.cur, c.curmod, id.str) == nil; }; // asserttyped — post-checker invariant gate (#15, A.6.2.1e). Walks the @@ -6256,43 +6256,43 @@ fn isassertfam(c: *checker, id: *node) bool = { // // `indot` tracks gate 3: true only when the immediate caller is an // N_DOT recursing into its .lhs. -fn asserttyped(c: *checker, n: *node, indot: bool) void = { +fn asserttyped(c: *checker, n: *syntax.node, indot: bool) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; let isexpr: bool = - k == nkind.N_INTLIT || k == nkind.N_FLOATLIT || - k == nkind.N_STRLIT || k == nkind.N_RUNELIT || - k == nkind.N_TRUE || k == nkind.N_FALSE || - k == nkind.N_NIL || k == nkind.N_VOIDLIT || - k == nkind.N_IDENT || k == nkind.N_BIN || - k == nkind.N_UN || k == nkind.N_CALL || - k == nkind.N_INDEX || k == nkind.N_CAST || - k == nkind.N_STRUCTLIT || k == nkind.N_ARRLIT || - k == nkind.N_RECV || k == nkind.N_DOT || - k == nkind.N_SLICE || k == nkind.N_SPREAD || - k == nkind.N_TUPLE || k == nkind.N_TRYPROP || - k == nkind.N_TRYUNW || k == nkind.N_TYPETEST || - k == nkind.N_TYPEASSERT || k == nkind.N_YIELD || - k == nkind.N_MATCH; + k == syntax.nkind.N_INTLIT || k == syntax.nkind.N_FLOATLIT || + k == syntax.nkind.N_STRLIT || k == syntax.nkind.N_RUNELIT || + k == syntax.nkind.N_TRUE || k == syntax.nkind.N_FALSE || + k == syntax.nkind.N_NIL || k == syntax.nkind.N_VOIDLIT || + k == syntax.nkind.N_IDENT || k == syntax.nkind.N_BIN || + k == syntax.nkind.N_UN || k == syntax.nkind.N_CALL || + k == syntax.nkind.N_INDEX || k == syntax.nkind.N_CAST || + k == syntax.nkind.N_STRUCTLIT || k == syntax.nkind.N_ARRLIT || + k == syntax.nkind.N_RECV || k == syntax.nkind.N_DOT || + k == syntax.nkind.N_SLICE || k == syntax.nkind.N_SPREAD || + k == syntax.nkind.N_TUPLE || k == syntax.nkind.N_TRYPROP || + k == syntax.nkind.N_TRYUNW || k == syntax.nkind.N_TYPETEST || + k == syntax.nkind.N_TYPEASSERT || k == syntax.nkind.N_YIELD || + k == syntax.nkind.N_MATCH; let skip: bool = false; - if (isexpr && k == nkind.N_IDENT) { + if (isexpr && k == syntax.nkind.N_IDENT) { if (indot) { skip = true; }; if (!skip) { - let s: *sym = scopelookup(c.cur, n.str); + let s: *syntax.sym = syntax.scopelookup(c.cur, n.str); if (s != nil) { - if (s.skind == skind.SK_USE) { skip = true; }; + if (s.skind == syntax.skind.SK_USE) { skip = true; }; if (s.decl == nil) { skip = true; }; }; }; if (!skip) { if (isassertfam(c, n)) { skip = true; }; }; }; - if (isexpr && k == nkind.N_CALL) { + if (isexpr && k == syntax.nkind.N_CALL) { if (isassertfam(c, n.lhs)) { skip = true; }; }; if (isexpr && !skip) { if (n.type_ == nil) { cerr("asserttyped: "); - let kn: str = nkname(k); + let kn: str = syntax.nkname(k); cerr(kn); cerr(" "); if (n.file.len > 0) { @@ -6310,7 +6310,7 @@ fn asserttyped(c: *checker, n: *node, indot: bool) void = { os.exit(1); }; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { if (n.lhs != nil) { asserttyped(c, n.lhs, true); }; return; }; @@ -6320,16 +6320,16 @@ fn asserttyped(c: *checker, n: *node, indot: bool) void = { if (n.cond != nil) { asserttyped(c, n.cond, false); }; if (n.body != nil) { asserttyped(c, n.body, false); }; if (n.els != nil) { asserttyped(c, n.els, false); }; - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { asserttyped(c, m, false); m = m.next; }; }; -export fn checkinit(c: *checker, tc: *tctx) void = { +export fn checkinit(c: *checker, tc: *syntax.tctx) void = { c.tc = tc; - c.top = newscope(nil); + c.top = syntax.newscope(nil); c.cur = c.top; c.nresolved = 0; c.nunresolved = 0; @@ -6344,13 +6344,13 @@ export fn checkinit(c: *checker, tc: *tctx) void = { seedprimitives(c); }; -export fn checkfile(c: *checker, file: *node) void = { +export fn checkfile(c: *checker, file: *syntax.node) void = { if (file == nil) { return; }; - if (file.kind != nkind.N_FILE) { return; }; + if (file.kind != syntax.nkind.N_FILE) { return; }; c.file = file; // Pass 1: install all top-level names. - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { installdecl(c, file, d); d = d.next; @@ -6363,12 +6363,12 @@ export fn checkfile(c: *checker, file: *node) void = { // collision by construction (#31). Two ROOT entries still collide on // the bare symbol → reject loud (rule 7). Walks USER decls only — runs // before the -T synth main is appended below. Twin of cmd/wcc/check.c. - let firstmain: *node = nil; - let mm: *node = file.list; + let firstmain: *syntax.node = nil; + let mm: *syntax.node = file.list; for (mm != nil) { - let ismain: bool = (mm.kind == nkind.N_FNDECL - || mm.kind == nkind.N_LET || mm.kind == nkind.N_DEF - || mm.kind == nkind.N_TYPEDECL) && streq(mm.str, "main"); + let ismain: bool = (mm.kind == syntax.nkind.N_FNDECL + || mm.kind == syntax.nkind.N_LET || mm.kind == syntax.nkind.N_DEF + || mm.kind == syntax.nkind.N_TYPEDECL) && syntax.streq(mm.str, "main"); if (ismain && mm.imported == 0) { if (firstmain == nil) { firstmain = mm; @@ -6410,10 +6410,10 @@ export fn checkfile(c: *checker, file: *node) void = { let pl: i32 = file.line; let pc: i32 = file.col; // (b) the synth entry OWNS `main` — loud-reject a user one. - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { - if (u.kind == nkind.N_FNDECL && u.body != nil - && streq(u.str, "main")) { + if (u.kind == syntax.nkind.N_FNDECL && u.body != nil + && syntax.streq(u.str, "main")) { cerr(u.file); cerr(": error: test mode: main is synthesized by -T; remove the explicit main\n"); c.errs += 1; @@ -6426,7 +6426,7 @@ export fn checkfile(c: *checker, file: *node) void = { // so the synth `run(__wwtests)` iterates the user's table, not // the collected @tests — reserve the NAME so the collision is // loud regardless of type. Any decl kind (const/let/fn). - if (streq(u.str, "__wwtests")) { + if (syntax.streq(u.str, "__wwtests")) { cerr(u.file); cerr(": error: test mode: __wwtests is reserved by -T; rename the declaration\n"); c.errs += 1; @@ -6435,17 +6435,17 @@ export fn checkfile(c: *checker, file: *node) void = { }; // (c) collect @test fns in file.list order; build one table row // `("", &)` per validated @test fn. - let rhead: *node = nil; - let rtail: *node = nil; + let rhead: *syntax.node = nil; + let rtail: *syntax.node = nil; let ntest: i32 = 0; - let t: *node = file.list; + let t: *syntax.node = file.list; for (t != nil) { - if (t.kind == nkind.N_FNDECL) { + if (t.kind == syntax.nkind.N_FNDECL) { let istest: bool = false; - let at: *node = t.attr; + let at: *syntax.node = t.attr; for (at != nil) { - if (at.kind == nkind.N_ATTR - && streq(at.str, "test")) { + if (at.kind == syntax.nkind.N_ATTR + && syntax.streq(at.str, "test")) { istest = true; }; at = at.next; @@ -6455,8 +6455,8 @@ export fn checkfile(c: *checker, file: *node) void = { // into t.lhs, so void-returning is lhs==nil // OR an N_TNAME "void". let retvoid: bool = t.lhs == nil - || (t.lhs.kind == nkind.N_TNAME - && streq(t.lhs.str, "void")); + || (t.lhs.kind == syntax.nkind.N_TNAME + && syntax.streq(t.lhs.str, "void")); if (t.list != nil || !retvoid) { cerr(t.file); cerr(": error: @test fn '"); @@ -6464,14 +6464,14 @@ export fn checkfile(c: *checker, file: *node) void = { cerr("' must be fn() void\n"); c.errs += 1; } else { - let nm: *node = newnode(nkind.N_STRLIT, pf, pl, pc); + let nm: *syntax.node = syntax.newnode(syntax.nkind.N_STRLIT, pf, pl, pc); nm.str = t.str; - let id: *node = newnode(nkind.N_IDENT, pf, pl, pc); + let id: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc); id.str = t.str; - let amp: *node = newnode(nkind.N_UN, pf, pl, pc); - amp.op = tkind.TK_AMP; + let amp: *syntax.node = syntax.newnode(syntax.nkind.N_UN, pf, pl, pc); + amp.op = syntax.tkind.TK_AMP; amp.lhs = id; - let row: *node = newnode(nkind.N_TUPLE, pf, pl, pc); + let row: *syntax.node = syntax.newnode(syntax.nkind.N_TUPLE, pf, pl, pc); row.list = nm; nm.next = amp; if (rhead == nil) { rhead = row; } @@ -6484,39 +6484,39 @@ export fn checkfile(c: *checker, file: *node) void = { t = t.next; }; - let body: *node = newnode(nkind.N_BLOCK, pf, pl, pc); - let tab: *node = nil; + let body: *syntax.node = syntax.newnode(syntax.nkind.N_BLOCK, pf, pl, pc); + let tab: *syntax.node = nil; if (ntest == 0i32) { // no @test fns in this unit — exit 0, nothing to run. - let ret: *node = newnode(nkind.N_RETURN, pf, pl, pc); - let zero: *node = newnode(nkind.N_INTLIT, pf, pl, pc); + let ret: *syntax.node = syntax.newnode(syntax.nkind.N_RETURN, pf, pl, pc); + let zero: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, pf, pl, pc); zero.uval = 0u64; ret.lhs = zero; body.list = ret; } else { // const __wwtests: [](str, *fn() void) = [rows...]; // wwstage tuple-type elements wrap in N_TPARAM (parse.ww:308). - let e0: *node = newnode(nkind.N_TNAME, pf, pl, pc); + let e0: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, pf, pl, pc); e0.str = "str"; - let p0: *node = newnode(nkind.N_TPARAM, pf, pl, pc); + let p0: *syntax.node = syntax.newnode(syntax.nkind.N_TPARAM, pf, pl, pc); p0.lhs = e0; - let vret: *node = newnode(nkind.N_TNAME, pf, pl, pc); + let vret: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, pf, pl, pc); vret.str = "void"; - let vfn: *node = newnode(nkind.N_TFN, pf, pl, pc); + let vfn: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, pf, pl, pc); vfn.lhs = vret; - let e1: *node = newnode(nkind.N_TPTR, pf, pl, pc); + let e1: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, pf, pl, pc); e1.lhs = vfn; - let p1: *node = newnode(nkind.N_TPARAM, pf, pl, pc); + let p1: *syntax.node = syntax.newnode(syntax.nkind.N_TPARAM, pf, pl, pc); p1.lhs = e1; - let tup: *node = newnode(nkind.N_TTUPLE, pf, pl, pc); + let tup: *syntax.node = syntax.newnode(syntax.nkind.N_TTUPLE, pf, pl, pc); tup.list = p0; p0.next = p1; - let tsl: *node = newnode(nkind.N_TSLICE, pf, pl, pc); + let tsl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, pf, pl, pc); tsl.lhs = tup; - let arr: *node = newnode(nkind.N_ARRLIT, pf, pl, pc); + let arr: *syntax.node = syntax.newnode(syntax.nkind.N_ARRLIT, pf, pl, pc); arr.list = rhead; - tab = newnode(nkind.N_LET, pf, pl, pc); - tab.op = tkind.TK_CONST; + tab = syntax.newnode(syntax.nkind.N_LET, pf, pl, pc); + tab.op = syntax.tkind.TK_CONST; tab.str = "__wwtests"; tab.lhs = tsl; tab.rhs = arr; @@ -6527,23 +6527,23 @@ export fn checkfile(c: *checker, file: *node) void = { // duplicate-decl reject (#23) the same way, so a pathological // user `const __wwtests` stays a downstream type error in // both stages rather than a dup-diagnostic in only one. - scopedefineinmodule(c.top, tab.str, "", skind.SK_VAR, nil, tab); + syntax.scopedefineinmodule(c.top, tab.str, "", syntax.skind.SK_VAR, nil, tab); - let arg: *node = newnode(nkind.N_IDENT, pf, pl, pc); + let arg: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc); arg.str = "__wwtests"; - let call: *node = newnode(nkind.N_CALL, pf, pl, pc); - let cid: *node = newnode(nkind.N_IDENT, pf, pl, pc); + let call: *syntax.node = syntax.newnode(syntax.nkind.N_CALL, pf, pl, pc); + let cid: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc); cid.str = "run"; call.lhs = cid; call.list = arg; - let ret: *node = newnode(nkind.N_RETURN, pf, pl, pc); + let ret: *syntax.node = syntax.newnode(syntax.nkind.N_RETURN, pf, pl, pc); ret.lhs = call; body.list = ret; }; - let m: *node = newnode(nkind.N_FNDECL, pf, pl, pc); + let m: *syntax.node = syntax.newnode(syntax.nkind.N_FNDECL, pf, pl, pc); m.str = "main"; m.exported = 1i32; - let rety: *node = newnode(nkind.N_TNAME, pf, pl, pc); + let rety: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, pf, pl, pc); rety.str = "i32"; m.lhs = rety; m.body = body; @@ -6551,7 +6551,7 @@ export fn checkfile(c: *checker, file: *node) void = { // type_ pre-set on main: installdecl never stamps a fn's type_ on // the ww side — cgfn reads lhs/list on demand. Pass-2 below // resolve-walks the appended bodies. - let tl: *node = file.list; + let tl: *syntax.node = file.list; if (tl == nil) { if (tab != nil) { file.list = tab; tab.next = m; } else { file.list = m; }; @@ -6575,12 +6575,12 @@ export fn checkfile(c: *checker, file: *node) void = { // dispatch. Mirror resolvewalk L405 which descends n.attr on // inner nodes. if (d.attr != nil) { resolvewalk(c, d.attr); }; - let k: nkind = d.kind; + let k: syntax.nkind = d.kind; switch (k) { - case nkind.N_FNDECL: + case syntax.nkind.N_FNDECL: if (d.lhs != nil) { resolvewalk(c, d.lhs); }; // return type resolvefnbody(c, d); - case nkind.N_DEF: + case syntax.nkind.N_DEF: // #11: a module-level `def xs: [_]T = arrlit;` must infer // its length BEFORE resolvewalk stamps d.lhs's tinfo, the // def twin of the N_LET arm below. #7 wired only the let @@ -6613,9 +6613,9 @@ export fn checkfile(c: *checker, file: *node) void = { }; }; }; - case nkind.N_TYPEDECL: + case syntax.nkind.N_TYPEDECL: if (d.lhs != nil) { resolvewalk(c, d.lhs); }; - case nkind.N_LET: + case syntax.nkind.N_LET: // #7: a module-level `let xs: [_]T = arrlit;` must infer // its length BEFORE resolvewalk stamps d.lhs's tinfo — // otherwise the array tinfo caches the alen=0 sentinel and @@ -6674,21 +6674,21 @@ export fn checkfile(c: *checker, file: *node) void = { // untouched: its synth main calls the @test fns, so they must remain. // Twin: cmd/wcc/check.c. if (c.istest == 0) { - let prev: *node = nil; - let e: *node = file.list; + let prev: *syntax.node = nil; + let e: *syntax.node = file.list; for (e != nil) { let istest: bool = false; - if (e.kind == nkind.N_FNDECL) { - let at: *node = e.attr; + if (e.kind == syntax.nkind.N_FNDECL) { + let at: *syntax.node = e.attr; for (at != nil) { - if (at.kind == nkind.N_ATTR - && streq(at.str, "test")) { + if (at.kind == syntax.nkind.N_ATTR + && syntax.streq(at.str, "test")) { istest = true; }; at = at.next; }; }; - let nx: *node = e.next; + let nx: *syntax.node = e.next; if (istest) { if (prev == nil) { file.list = nx; } else { prev.next = nx; }; diff --git a/selfhost/cmd/wcc/wwi.ww b/selfhost/cmd/wcc/wwi.ww index c55c688c..2d2edff9 100644 --- a/selfhost/cmd/wcc/wwi.ww +++ b/selfhost/cmd/wcc/wwi.ww @@ -78,9 +78,9 @@ fn wquote(fd: i32, s: str) void = { // primitive/keyword resolves to no SK_TYPE → leaf. By producer time // checkfile has finished and c.cur == c.top. -fn wwitypesym(c: *checker, nm: str) *sym = { +fn wwitypesym(c: *checker, nm: str) *syntax.sym = { let empty: str; - let s: *sym = scopelookuptype(c.cur, empty, nm); + let s: *syntax.sym = syntax.scopelookuptype(c.cur, empty, nm); if (s == nil) { let dotidx: i32 = -1; let i: i32 = 0; @@ -92,15 +92,15 @@ fn wwitypesym(c: *checker, nm: str) *sym = { let leaf: str; leaf.ptr = nm.ptr + ((dotidx + 1): u64); leaf.len = nm.len - dotidx - 1; - s = scopelookuptype(c.cur, empty, leaf); + s = syntax.scopelookuptype(c.cur, empty, leaf); }; }; if (s == nil) { return nil; }; - if (s.skind != skind.SK_TYPE) { return nil; }; + if (s.skind != syntax.skind.SK_TYPE) { return nil; }; return s; }; -fn wwireject(d: *node, nm: str) void = { +fn wwireject(d: *syntax.node, nm: str) void = { wputs(2, d.file); wputs(2, ":"); wputs(2, strconv.u64tos(d.line: u64, strconv.base.DEC)); @@ -112,20 +112,20 @@ fn wwireject(d: *node, nm: str) void = { }; // Returns 1 if a non-exported nominal was named (loud), else 0. -fn wwichecktype(c: *checker, d: *node, t: *node) i32 = { +fn wwichecktype(c: *checker, d: *syntax.node, t: *syntax.node) i32 = { if (t == nil) { return 0; }; // rule-10: the wwstage checker wraps N_TTUPLE.list elements in // N_TPARAM (ast.ww:101); cstage keeps the type-AST pristine. Unwrap // transparently so the recursion sees the same shape cstage walks. - if (t.kind == nkind.N_TPARAM) { return wwichecktype(c, d, t.lhs); }; + if (t.kind == syntax.nkind.N_TPARAM) { return wwichecktype(c, d, t.lhs); }; let bad: i32 = 0; - if (t.kind == nkind.N_TNAME) { - let s: *sym = wwitypesym(c, t.str); + if (t.kind == syntax.nkind.N_TNAME) { + let s: *syntax.sym = wwitypesym(c, t.str); // sym.exported is vestigial (never set); the nominal's export // status lives on its decl node, parser-set. if (s != nil) { if (s.decl != nil) { - if (s.decl.kind == nkind.N_TYPEDECL) { + if (s.decl.kind == syntax.nkind.N_TYPEDECL) { // file.len == 0 ⇒ a checkinit-synthesized // predeclared builtin (the ONLY empty-source // decls: nomemdecl check.ww:126, the `void` @@ -143,35 +143,35 @@ fn wwichecktype(c: *checker, d: *node, t: *node) i32 = { }; }; } else { if ( - t.kind == nkind.N_TPTR || - t.kind == nkind.N_TSLICE || - t.kind == nkind.N_TBANG || - t.kind == nkind.N_TCHAN + t.kind == syntax.nkind.N_TPTR || + t.kind == syntax.nkind.N_TSLICE || + t.kind == syntax.nkind.N_TBANG || + t.kind == syntax.nkind.N_TCHAN ) { bad = bad | wwichecktype(c, d, t.lhs); - } else { if (t.kind == nkind.N_TARRAY) { + } else { if (t.kind == syntax.nkind.N_TARRAY) { // element only; the length is a const-expr, not a type. bad = bad | wwichecktype(c, d, t.lhs); - } else { if (t.kind == nkind.N_TFN) { - let p: *node = t.list; + } else { if (t.kind == syntax.nkind.N_TFN) { + let p: *syntax.node = t.list; for (p != nil) { bad = bad | wwichecktype(c, d, p.lhs); p = p.next; }; bad = bad | wwichecktype(c, d, t.lhs); - } else { if (t.kind == nkind.N_TSTRUCT) { - let f: *node = t.list; + } else { if (t.kind == syntax.nkind.N_TSTRUCT) { + let f: *syntax.node = t.list; for (f != nil) { bad = bad | wwichecktype(c, d, f.lhs); f = f.next; }; - } else { if (t.kind == nkind.N_TTAGGED || t.kind == nkind.N_TTUPLE) { - let e: *node = t.list; + } else { if (t.kind == syntax.nkind.N_TTAGGED || t.kind == syntax.nkind.N_TTUPLE) { + let e: *syntax.node = t.list; for (e != nil) { bad = bad | wwichecktype(c, d, e); e = e.next; }; - } else { if (t.kind == nkind.N_TENUM) { + } else { if (t.kind == syntax.nkind.N_TENUM) { // the inline enum body is the definition, not a reference; // recurse only its storage type (members are values). bad = bad | wwichecktype(c, d, t.lhs); @@ -179,21 +179,21 @@ fn wwichecktype(c: *checker, d: *node, t: *node) i32 = { return bad; }; -fn wwicheckdecl(c: *checker, d: *node) i32 = { +fn wwicheckdecl(c: *checker, d: *syntax.node) i32 = { let bad: i32 = 0; - if (d.kind == nkind.N_FNDECL) { - let p: *node = d.list; + if (d.kind == syntax.nkind.N_FNDECL) { + let p: *syntax.node = d.list; for (p != nil) { bad = bad | wwichecktype(c, d, p.lhs); p = p.next; }; bad = bad | wwichecktype(c, d, d.lhs); // ret - } else { if (d.kind == nkind.N_TYPEDECL) { + } else { if (d.kind == syntax.nkind.N_TYPEDECL) { bad = bad | wwichecktype(c, d, d.lhs); - } else { if (d.kind == nkind.N_DEF) { + } else { if (d.kind == syntax.nkind.N_DEF) { // the declared type; the rhs const value is not a type. bad = bad | wwichecktype(c, d, d.lhs); - } else { if (d.kind == nkind.N_LET) { + } else { if (d.kind == syntax.nkind.N_LET) { bad = bad | wwichecktype(c, d, d.lhs); };};};}; return bad; @@ -239,39 +239,39 @@ fn wwirune(fd: i32, cp: u64) void = { wputb(fd, '\''); }; -fn wwiexpr(fd: i32, e: *node) void = { +fn wwiexpr(fd: i32, e: *syntax.node) void = { if (e == nil) { return; }; - if (e.kind == nkind.N_INTLIT) { + if (e.kind == syntax.nkind.N_INTLIT) { wputs(fd, strconv.u64tos(e.uval, strconv.base.DEC)); if (e.tsuffix.len > 0) { wputs(fd, e.tsuffix); }; - } else { if (e.kind == nkind.N_IDENT || e.kind == nkind.N_TNAME) { + } else { if (e.kind == syntax.nkind.N_IDENT || e.kind == syntax.nkind.N_TNAME) { wputs(fd, e.str); - } else { if (e.kind == nkind.N_DOT) { + } else { if (e.kind == syntax.nkind.N_DOT) { wwiexpr(fd, e.lhs); wputb(fd, '.'); wputs(fd, e.str); - } else { if (e.kind == nkind.N_TRUE) { + } else { if (e.kind == syntax.nkind.N_TRUE) { wputs(fd, "true"); - } else { if (e.kind == nkind.N_FALSE) { + } else { if (e.kind == syntax.nkind.N_FALSE) { wputs(fd, "false"); - } else { if (e.kind == nkind.N_NIL) { + } else { if (e.kind == syntax.nkind.N_NIL) { wputs(fd, "nil"); - } else { if (e.kind == nkind.N_STRLIT) { + } else { if (e.kind == syntax.nkind.N_STRLIT) { wquote(fd, e.str); - } else { if (e.kind == nkind.N_RUNELIT) { + } else { if (e.kind == syntax.nkind.N_RUNELIT) { // A bare rune literal in a const-expr (types.RUNE_MIN = '\0'); // casts never reach here — the checker folds a const cast to an // integer literal before the producer runs (RUNE_MAX // `0x10ffff: rune` emits as the plain int 1114111). wwirune(fd, e.uval); - } else { if (e.kind == nkind.N_BIN) { + } else { if (e.kind == syntax.nkind.N_BIN) { wwiexpr(fd, e.lhs); wputb(fd, 32u8); - wputs(fd, tokname(e.op)); + wputs(fd, syntax.tokname(e.op)); wputb(fd, 32u8); wwiexpr(fd, e.rhs); - } else { if (e.kind == nkind.N_UN) { - wputs(fd, tokname(e.op)); + } else { if (e.kind == syntax.nkind.N_UN) { + wputs(fd, syntax.tokname(e.op)); wwiexpr(fd, e.lhs); } else { wputs(2, "wwi: unhandled const-expr node kind\n"); @@ -279,8 +279,8 @@ fn wwiexpr(fd: i32, e: *node) void = { };};};};};};};};};}; }; -fn wwiparam(fd: i32, p: *node) void = { - if (streq(p.str, "...")) { // C-style FFI `...` +fn wwiparam(fd: i32, p: *syntax.node) void = { + if (syntax.streq(p.str, "...")) { // C-style FFI `...` wputs(fd, "..."); return; }; @@ -291,46 +291,46 @@ fn wwiparam(fd: i32, p: *node) void = { // rule-10: the wwstage checker desugars a Hare variadic `T...` param // in place to `[]T` (lhs becomes N_TSLICE); cstage leaves lhs == T. // Peel the inserted slice so both stages emit the surface `T...`. - if (p.op == tkind.TK_ELLIPSIS && p.lhs != nil && p.lhs.kind == nkind.N_TSLICE) { + if (p.op == syntax.tkind.TK_ELLIPSIS && p.lhs != nil && p.lhs.kind == syntax.nkind.N_TSLICE) { wwitype(fd, p.lhs.lhs); } else { wwitype(fd, p.lhs); }; - if (p.op == tkind.TK_ELLIPSIS) { // Hare `T...` variadic + if (p.op == syntax.tkind.TK_ELLIPSIS) { // Hare `T...` variadic wputs(fd, "..."); }; }; -fn wwitype(fd: i32, t: *node) void = { +fn wwitype(fd: i32, t: *syntax.node) void = { if (t == nil) { // absent return type spells void wputs(fd, "void"); return; }; // rule-10: unwrap the wwstage-only N_TPARAM tuple-element wrapper // (ast.ww:101) so the unparse matches cstage's pristine type-AST. - if (t.kind == nkind.N_TPARAM) { wwitype(fd, t.lhs); return; }; - if (t.kind == nkind.N_TNAME) { + if (t.kind == syntax.nkind.N_TPARAM) { wwitype(fd, t.lhs); return; }; + if (t.kind == syntax.nkind.N_TNAME) { if (t.str.len > 0) { wputs(fd, t.str); } else { wputs(fd, "void"); }; - } else { if (t.kind == nkind.N_TPTR) { + } else { if (t.kind == syntax.nkind.N_TPTR) { wputb(fd, '*'); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TSLICE) { + } else { if (t.kind == syntax.nkind.N_TSLICE) { wputs(fd, "[]"); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TARRAY) { + } else { if (t.kind == syntax.nkind.N_TARRAY) { wputb(fd, '['); if (t.rhs != nil) { wwiexpr(fd, t.rhs); } else { wputb(fd, '_'); }; wputb(fd, ']'); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TBANG) { + } else { if (t.kind == syntax.nkind.N_TBANG) { wputb(fd, '!'); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TCHAN) { + } else { if (t.kind == syntax.nkind.N_TCHAN) { wputs(fd, "chan "); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TFN) { + } else { if (t.kind == syntax.nkind.N_TFN) { wputs(fd, "fn("); - let p: *node = t.list; + let p: *syntax.node = t.list; for (p != nil) { if (p != t.list) { wputs(fd, ", "); }; wwiparam(fd, p); @@ -338,9 +338,9 @@ fn wwitype(fd: i32, t: *node) void = { }; wputs(fd, ") "); wwitype(fd, t.lhs); - } else { if (t.kind == nkind.N_TSTRUCT) { + } else { if (t.kind == syntax.nkind.N_TSTRUCT) { wputs(fd, "struct { "); - let f: *node = t.list; + let f: *syntax.node = t.list; for (f != nil) { if (f != t.list) { wputs(fd, ", "); }; if (f.str.len > 0) { @@ -351,32 +351,32 @@ fn wwitype(fd: i32, t: *node) void = { f = f.next; }; wputs(fd, " }"); - } else { if (t.kind == nkind.N_TTUPLE) { + } else { if (t.kind == syntax.nkind.N_TTUPLE) { wputb(fd, '('); - let e: *node = t.list; + let e: *syntax.node = t.list; for (e != nil) { if (e != t.list) { wputs(fd, ", "); }; wwitype(fd, e); e = e.next; }; wputb(fd, ')'); - } else { if (t.kind == nkind.N_TTAGGED) { + } else { if (t.kind == syntax.nkind.N_TTAGGED) { wputb(fd, '('); - let e: *node = t.list; + let e: *syntax.node = t.list; for (e != nil) { if (e != t.list) { wputs(fd, " | "); }; wwitype(fd, e); e = e.next; }; wputb(fd, ')'); - } else { if (t.kind == nkind.N_TENUM) { + } else { if (t.kind == syntax.nkind.N_TENUM) { wputs(fd, "enum "); if (t.lhs != nil) { wwitype(fd, t.lhs); wputb(fd, 32u8); }; wputs(fd, "{ "); - let m: *node = t.list; + let m: *syntax.node = t.list; for (m != nil) { if (m != t.list) { wputs(fd, ", "); }; wputs(fd, m.str); @@ -401,18 +401,18 @@ fn wwitype(fd: i32, t: *node) void = { // today (task #47 report). @test never reaches a `.wwi` (test fns are not // export-marked), so it needs no exclusion arm. fn wwiattrrelevant(nm: str) bool = { - return streq(nm, "symbol"); + return syntax.streq(nm, "symbol"); }; -fn wwiattrs(fd: i32, d: *node) void = { - let a: *node = d.attr; +fn wwiattrs(fd: i32, d: *syntax.node) void = { + let a: *syntax.node = d.attr; for (a != nil) { - if (a.kind == nkind.N_ATTR && wwiattrrelevant(a.str)) { + if (a.kind == syntax.nkind.N_ATTR && wwiattrrelevant(a.str)) { wputb(fd, '@'); wputs(fd, a.str); if (a.list != nil) { wputb(fd, '('); - let arg: *node = a.list; + let arg: *syntax.node = a.list; for (arg != nil) { if (arg != a.list) { wputs(fd, ", "); }; wwiexpr(fd, arg); @@ -426,13 +426,13 @@ fn wwiattrs(fd: i32, d: *node) void = { }; }; -fn wwidecl(fd: i32, d: *node) void = { - if (d.kind == nkind.N_FNDECL) { +fn wwidecl(fd: i32, d: *syntax.node) void = { + if (d.kind == syntax.nkind.N_FNDECL) { wwiattrs(fd, d); wputs(fd, "export fn "); wputs(fd, d.str); wputb(fd, '('); - let p: *node = d.list; + let p: *syntax.node = d.list; for (p != nil) { if (p != d.list) { wputs(fd, ", "); }; wwiparam(fd, p); @@ -441,13 +441,13 @@ fn wwidecl(fd: i32, d: *node) void = { wputs(fd, ") "); wwitype(fd, d.lhs); wputs(fd, ";\n"); - } else { if (d.kind == nkind.N_TYPEDECL) { + } else { if (d.kind == syntax.nkind.N_TYPEDECL) { wputs(fd, "export type "); wputs(fd, d.str); wputs(fd, " = "); wwitype(fd, d.lhs); wputs(fd, ";\n"); - } else { if (d.kind == nkind.N_DEF) { + } else { if (d.kind == syntax.nkind.N_DEF) { wputs(fd, "export def "); wputs(fd, d.str); wputs(fd, ": "); @@ -461,15 +461,15 @@ fn wwidecl(fd: i32, d: *node) void = { // side const-fold of an aggregate def's FIELDS — a no-op, ww // never folds struct-literal field access, and an aggregate-def // field demanded in a const-fold context stays a LOUD error (#71). - if (d.rhs != nil && (d.rhs.kind == nkind.N_STRUCTLIT || - d.rhs.kind == nkind.N_ARRLIT)) { + if (d.rhs != nil && (d.rhs.kind == syntax.nkind.N_STRUCTLIT || + d.rhs.kind == syntax.nkind.N_ARRLIT)) { wputs(fd, ";\n"); } else { wputs(fd, " = "); wwiexpr(fd, d.rhs); wputs(fd, ";\n"); }; - } else { if (d.kind == nkind.N_LET) { + } else { if (d.kind == syntax.nkind.N_LET) { wputs(fd, "export let "); wputs(fd, d.str); wputs(fd, ": "); @@ -484,16 +484,16 @@ fn wwidecl(fd: i32, d: *node) void = { // --- deterministic ordering (rob §3) ---------------------------------- -fn wwiprimary(n: *node) bool = { +fn wwiprimary(n: *syntax.node) bool = { // imported==1 marks a decl reached through a `//ww:module ` // boundary (an imported module's concatenated section). if (n == nil) { return false; }; return n.imported == 0; }; -fn wwiisdecl(d: *node) bool = { - return d.kind == nkind.N_FNDECL || d.kind == nkind.N_TYPEDECL || - d.kind == nkind.N_DEF || d.kind == nkind.N_LET; +fn wwiisdecl(d: *syntax.node) bool = { + return d.kind == syntax.nkind.N_FNDECL || d.kind == syntax.nkind.N_TYPEDECL || + d.kind == syntax.nkind.N_DEF || d.kind == syntax.nkind.N_LET; }; // strcmp — byte lexicographic, mirror C strcmp sign (<0/0/>0). Both @@ -513,7 +513,7 @@ fn wwistrcmp(a: str, b: str) i32 = { // the symbol name; ties broken by original index — so the result is // stable regardless of any same-name collision, matching cstage's qsort // + idx tiebreak. -fn wwisortdecls(keys: []str, nodes: []*node, n: i32) void = { +fn wwisortdecls(keys: []str, nodes: []*syntax.node, n: i32) void = { let i: i32 = 0; for (i < n) { let best: i32 = i; @@ -525,17 +525,17 @@ fn wwisortdecls(keys: []str, nodes: []*node, n: i32) void = { }; if (best != i) { let tk: str = keys[i]; keys[i] = keys[best]; keys[best] = tk; - let tn: *node = nodes[i]; nodes[i] = nodes[best]; nodes[best] = tn; + let tn: *syntax.node = nodes[i]; nodes[i] = nodes[best]; nodes[best] = tn; }; i += 1; }; }; -export fn wwiemit(c: *checker, file: *node, path: str) i32 = { +export fn wwiemit(c: *checker, file: *syntax.node, path: str) i32 = { // §5: check_exported_type FIRST, before any byte — a producer // without it can emit a dangling `.wwi`. let bad: i32 = 0; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { if (wwiprimary(d) && d.exported != 0 && wwiisdecl(d)) { bad = bad | wwicheckdecl(c, d); @@ -555,7 +555,7 @@ export fn wwiemit(c: *checker, file: *node, path: str) i32 = { // package line: leaf of the first primary decl's module tag. let pkg: str = "main"; - let pd: *node = file.list; + let pd: *syntax.node = file.list; for (pd != nil) { if (wwiprimary(pd) && pd.nmod.len > 0) { let dotidx: i32 = -1; @@ -583,20 +583,20 @@ export fn wwiemit(c: *checker, file: *node, path: str) i32 = { // imports — primary N_USE, byte-sorted by import path. let nuse: i32 = 0; - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { - if (u.kind == nkind.N_USE && wwiprimary(u)) { nuse += 1; }; + if (u.kind == syntax.nkind.N_USE && wwiprimary(u)) { nuse += 1; }; u = u.next; }; if (nuse > 0) { let upaths: []str = alloc([], nuse: u64)!; upaths.len = nuse; - let unodes: []*node = alloc([], nuse: u64)!; + let unodes: []*syntax.node = alloc([], nuse: u64)!; unodes.len = nuse; let k: i32 = 0; u = file.list; for (u != nil) { - if (u.kind == nkind.N_USE && wwiprimary(u)) { + if (u.kind == syntax.nkind.N_USE && wwiprimary(u)) { if (u.usepath.len > 0) { upaths[k] = u.usepath; } else { upaths[k] = u.str; }; unodes[k] = u; k += 1; @@ -623,7 +623,7 @@ export fn wwiemit(c: *checker, file: *node, path: str) i32 = { if (ndecl > 0) { let dkeys: []str = alloc([], ndecl: u64)!; dkeys.len = ndecl; - let dnodes: []*node = alloc([], ndecl: u64)!; + let dnodes: []*syntax.node = alloc([], ndecl: u64)!; dnodes.len = ndecl; let k: i32 = 0; d = file.list; diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index c9255e1e..1724ea40 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -10767,24 +10767,24 @@ import syntax; import strconv; type checker = struct { - tc: *tctx, - top: *scope, - cur: *scope, + tc: *syntax.tctx, + top: *syntax.scope, + cur: *syntax.scope, nresolved: i32, nunresolved: i32, errs: i32, istest: i32, // #15: `w6c_ww -T` — collect @test fns + // synth the entry; loud-reject a user main. verbose: i32, // when non-zero, log each unresolved name - fnret: *node, // enclosing fn's return type AST (for `?`) + fnret: *syntax.node, // enclosing fn's return type AST (for `?`) curmod: str, // importing-module bareword for the decl // currently being walked; "" for primary // compilation unit. Drives same-module // preference in bare-leaf lookups. - file: *node, // N_FILE root; used by checkmoduleshadow + file: *syntax.node, // N_FILE root; used by checkmoduleshadow // to consult the declaring source's own // `use` directives. - allococtx: *node, // #3/B': the one empty alloc([], n) call node + allococtx: *syntax.node, // #3/B': the one empty alloc([], n) call node // with let-declared slice context this walk; // any other empty alloc has no element hint // and must fail to infer (harec @@ -10813,9 +10813,9 @@ fn cerr(m: str) void = { // and every NAMED-chain chase loop downstream spun forever (the #69 // compiler hang); a struct-value cycle recursed the slot walkers to // stack overflow. -fn circularnamed(c: *checker, t: *tinfo, n: *node) bool = { +fn circularnamed(c: *checker, t: *syntax.tinfo, n: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != tykind.TY_NAMED) { return false; }; + if (t.kind != syntax.tykind.TY_NAMED) { return false; }; if (t.resolving == 0) { return false; }; if (n != nil) { cerr(n.file); cerr(": "); }; cerr("error: circular type dependency: '"); @@ -10835,24 +10835,24 @@ fn circularnamed(c: *checker, t: *tinfo, n: *node) bool = { // seedprimitives — install the built-in type names so `i32`, `str`, // etc. can be looked up like ordinary symbols. fn seedprimitives(c: *checker) void = { - scopedefine(c.top, "void", skind.SK_TYPE, c.tc.tyvoid, nil); - scopedefine(c.top, "bool", skind.SK_TYPE, c.tc.tybool, nil); - scopedefine(c.top, "rune", skind.SK_TYPE, c.tc.tyrune, nil); - scopedefine(c.top, "i8", skind.SK_TYPE, c.tc.tyi8, nil); - scopedefine(c.top, "i16", skind.SK_TYPE, c.tc.tyi16, nil); - scopedefine(c.top, "i32", skind.SK_TYPE, c.tc.tyi32, nil); - scopedefine(c.top, "i64", skind.SK_TYPE, c.tc.tyi64, nil); - scopedefine(c.top, "u8", skind.SK_TYPE, c.tc.tyu8, nil); - scopedefine(c.top, "u16", skind.SK_TYPE, c.tc.tyu16, nil); - scopedefine(c.top, "u32", skind.SK_TYPE, c.tc.tyu32, nil); - scopedefine(c.top, "u64", skind.SK_TYPE, c.tc.tyu64, nil); - scopedefine(c.top, "int", skind.SK_TYPE, c.tc.tyint, nil); - scopedefine(c.top, "uint", skind.SK_TYPE, c.tc.tyuint, nil); - scopedefine(c.top, "uintptr", skind.SK_TYPE, c.tc.tyuintptr, nil); - scopedefine(c.top, "f32", skind.SK_TYPE, c.tc.tyf32, nil); - scopedefine(c.top, "f64", skind.SK_TYPE, c.tc.tyf64, nil); - scopedefine(c.top, "str", skind.SK_TYPE, c.tc.tystr, nil); - scopedefine(c.top, "never", skind.SK_TYPE, c.tc.tynever, nil); + syntax.scopedefine(c.top, "void", syntax.skind.SK_TYPE, c.tc.tyvoid, nil); + syntax.scopedefine(c.top, "bool", syntax.skind.SK_TYPE, c.tc.tybool, nil); + syntax.scopedefine(c.top, "rune", syntax.skind.SK_TYPE, c.tc.tyrune, nil); + syntax.scopedefine(c.top, "i8", syntax.skind.SK_TYPE, c.tc.tyi8, nil); + syntax.scopedefine(c.top, "i16", syntax.skind.SK_TYPE, c.tc.tyi16, nil); + syntax.scopedefine(c.top, "i32", syntax.skind.SK_TYPE, c.tc.tyi32, nil); + syntax.scopedefine(c.top, "i64", syntax.skind.SK_TYPE, c.tc.tyi64, nil); + syntax.scopedefine(c.top, "u8", syntax.skind.SK_TYPE, c.tc.tyu8, nil); + syntax.scopedefine(c.top, "u16", syntax.skind.SK_TYPE, c.tc.tyu16, nil); + syntax.scopedefine(c.top, "u32", syntax.skind.SK_TYPE, c.tc.tyu32, nil); + syntax.scopedefine(c.top, "u64", syntax.skind.SK_TYPE, c.tc.tyu64, nil); + syntax.scopedefine(c.top, "int", syntax.skind.SK_TYPE, c.tc.tyint, nil); + syntax.scopedefine(c.top, "uint", syntax.skind.SK_TYPE, c.tc.tyuint, nil); + syntax.scopedefine(c.top, "uintptr", syntax.skind.SK_TYPE, c.tc.tyuintptr, nil); + syntax.scopedefine(c.top, "f32", syntax.skind.SK_TYPE, c.tc.tyf32, nil); + syntax.scopedefine(c.top, "f64", syntax.skind.SK_TYPE, c.tc.tyf64, nil); + syntax.scopedefine(c.top, "str", syntax.skind.SK_TYPE, c.tc.tystr, nil); + syntax.scopedefine(c.top, "never", syntax.skind.SK_TYPE, c.tc.tynever, nil); // #29: predeclare `type nomem = !void;` so user code needn't // declare it locally. Synthesize an nkind.N_TYPEDECL whose lhs is // nkind.N_TBANG{nkind.N_TNAME("void")} so varianterr and other @@ -10862,34 +10862,34 @@ fn seedprimitives(c: *checker) void = { // separate alias chain — see collectaliases in cgen.ww for the // companion seed. let empty: str; - let tnvoid: *node = newnode(nkind.N_TNAME, empty, 0, 0); + let tnvoid: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, empty, 0, 0); tnvoid.str = "void"; - let bang: *node = newnode(nkind.N_TBANG, empty, 0, 0); + let bang: *syntax.node = syntax.newnode(syntax.nkind.N_TBANG, empty, 0, 0); bang.lhs = tnvoid; - let nomemdecl: *node = newnode(nkind.N_TYPEDECL, empty, 0, 0); + let nomemdecl: *syntax.node = syntax.newnode(syntax.nkind.N_TYPEDECL, empty, 0, 0); nomemdecl.str = "nomem"; nomemdecl.lhs = bang; - scopedefine(c.top, "nomem", skind.SK_TYPE, nil, nomemdecl); + syntax.scopedefine(c.top, "nomem", syntax.skind.SK_TYPE, nil, nomemdecl); // `nil`, `true`, `false` are keywords — handled at the lex/parser // level, no symbol needed. // `len`, `alloc`, `free`, `append`, `delete`, `insert` are // pseudo-builtins; scopedefine them so their use sites resolve. // The actual semantics live in cgen. - scopedefine(c.top, "len", skind.SK_FN, nil, nil); - scopedefine(c.top, "alloc", skind.SK_FN, nil, nil); - scopedefine(c.top, "free", skind.SK_FN, nil, nil); - scopedefine(c.top, "append", skind.SK_FN, nil, nil); - scopedefine(c.top, "delete", skind.SK_FN, nil, nil); - scopedefine(c.top, "insert", skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "len", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "alloc", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "free", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "append", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "delete", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "insert", syntax.skind.SK_FN, nil, nil); // #42: typed builtins folded to integer literals at check time — // `size(T)` / `align(T)` (arg is a type-expression planted by the // parser at lib/ww/parse/expr.ww:254-267) and `offset(e.f)` (arg is // an N_DOT). exprtype intercepts these and rewrites the N_CALL to // N_INTLIT so cgen never sees an unresolved size/align/offset symbol. // Mirrors cmd/wcc/check.c:907-955. - scopedefine(c.top, "size", skind.SK_FN, nil, nil); - scopedefine(c.top, "align", skind.SK_FN, nil, nil); - scopedefine(c.top, "offset", skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "size", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "align", syntax.skind.SK_FN, nil, nil); + syntax.scopedefine(c.top, "offset", syntax.skind.SK_FN, nil, nil); }; // declmod — module-tag stamp for a top-level decl. @@ -10900,19 +10900,19 @@ fn seedprimitives(c: *checker) void = { // directive matches some `use IDENT;` bareword in this compilation // unit. Primary-file decls return "" so they coexist (mod="") with // imported decls of the same leaf name in scopelookupinmodule. -fn declmod(file: *node, d: *node) str = { +fn declmod(file: *syntax.node, d: *syntax.node) str = { let empty: str; if (d == nil) { return empty; }; if (d.nmod.len == 0) { return empty; }; if (file == nil) { return empty; }; - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { // M1 #22: a decl is imported iff some `use` directive's full // dotted import path equals the decl's module (now the path). // Single-level packages have usepath == leaf so this is // unchanged; nested (`encoding.utf8`) match here, not on leaf. - if (u.kind == nkind.N_USE) { - if (streq(u.usepath, d.nmod)) { return d.nmod; }; + if (u.kind == syntax.nkind.N_USE) { + if (syntax.streq(u.usepath, d.nmod)) { return d.nmod; }; }; u = u.next; }; @@ -10924,14 +10924,14 @@ fn declmod(file: *node, d: *node) str = { // module-qualified resolution and codegen hint (M1 #22). Single-level // packages have usepath == alias so the result is unchanged. The // current tree has one occurrence per leaf, so the map is unambiguous. -fn usepathfor(file: *node, alias: str) str = { +fn usepathfor(file: *syntax.node, alias: str) str = { let empty: str; if (file == nil) { return empty; }; if (alias.len == 0) { return empty; }; - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { - if (u.kind == nkind.N_USE) { - if (streq(u.str, alias)) { + if (u.kind == syntax.nkind.N_USE) { + if (syntax.streq(u.str, alias)) { if (u.usepath.len != 0) { return u.usepath; }; return u.str; }; @@ -10953,19 +10953,19 @@ fn modkeyfor(c: *checker, alias: str) str = { // `modtag` carry `use ;`? Mirrors cstage's src_imports — // `modtag.len == 0` means primary, matching declmod's empty-str // return for primary-source decls. -fn srcimports(file: *node, modtag: str, name: str) bool = { +fn srcimports(file: *syntax.node, modtag: str, name: str) bool = { if (file == nil) { return false; }; if (name.len == 0) { return false; }; - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { - if (u.kind == nkind.N_USE) { + if (u.kind == syntax.nkind.N_USE) { // Skip self-imports: lib/fmt/fmttest.ww carries // `use fmt;` while its module tag is also "fmt". // That directive doesn't introduce a foreign // module bareword and lib/fmt's own // `fn bsprintf(fmt: str, ...)` is not a shadow. if (u.nmod.len > 0) { - if (streq(u.nmod, u.usepath)) { + if (syntax.streq(u.nmod, u.usepath)) { u = u.next; continue; }; @@ -10974,9 +10974,9 @@ fn srcimports(file: *node, modtag: str, name: str) bool = { let m: bool = false; if (modtag.len == 0) { if (um.len == 0) { m = true; }; - } else { if (streq(um, modtag)) { m = true; }; }; + } else { if (syntax.streq(um, modtag)) { m = true; }; }; if (m) { - if (streq(u.str, name)) { return true; }; + if (syntax.streq(u.str, name)) { return true; }; }; }; u = u.next; @@ -10995,11 +10995,11 @@ fn checkmoduleshadow(c: *checker, name: str, kindstr: str) void = { if (name.len == 0) { return; }; if (c.cur == c.top) { return; }; let seen: bool = false; - let s: *scope = c.cur; + let s: *syntax.scope = c.cur; for (s != nil) { - let r: *sym = scopelookuplocal(s, name); + let r: *syntax.sym = syntax.scopelookuplocal(s, name); if (r != nil) { - if (r.skind == skind.SK_USE) { + if (r.skind == syntax.skind.SK_USE) { seen = true; s = nil; }; @@ -11043,9 +11043,9 @@ fn checkmoduleshadow(c: *checker, name: str, kindstr: str) void = { // (cmd/wcc/check.c:2852/2911/2932/2955) — see dupdecl below. (Same-scope // LOCAL dup `let a=1; let a=2;` is a different path and stays deferred to // #11; test/wcc/708 + test/wcc/696 are that cstage-only neg-case.) -fn installdecl(c: *checker, file: *node, d: *node) void = { +fn installdecl(c: *checker, file: *syntax.node, d: *syntax.node) void = { if (d == nil) { return; }; - let k: nkind = d.kind; + let k: syntax.nkind = d.kind; let nm: str = d.str; let mod: str = declmod(file, d); // check-(c) self-import: a package may not import itself. Pure @@ -11053,10 +11053,10 @@ fn installdecl(c: *checker, file: *node, d: *node) void = { // unused + (b)/(d) membership DEFERRED to task #8 (filename-keyed // pulls lack import->file->symbol provenance). Message byte-identical // to cstage check.c. - if (k == nkind.N_USE) { + if (k == syntax.nkind.N_USE) { // M1 #22: self-import ⟺ the imported path equals the use's own // (owning) module path. Compares paths, not leaves. - if (mod.len != 0 && streq(d.usepath, mod)) { + if (mod.len != 0 && syntax.streq(d.usepath, mod)) { cerr("self-import: package '"); cerr(mod); cerr("' cannot import itself\n"); c.errs += 1i32; }; @@ -11074,17 +11074,17 @@ fn installdecl(c: *checker, file: *node, d: *node) void = { // (check.c:2823-2834 `if (prev) prev->use_alias = 1`). A pure // duplicate import (prev already SK_USE) keeps the coexisting- // entry path (orthogonal to #30, pre-existing wwstage behavior). - let prev: *sym = scopelookuplocal(c.top, nm); - if (prev != nil) { if (prev.skind != skind.SK_USE) { + let prev: *syntax.sym = syntax.scopelookuplocal(c.top, nm); + if (prev != nil) { if (prev.skind != syntax.skind.SK_USE) { prev.use_alias = 1i32; return; }; }; - scopedefine(c.top, nm, skind.SK_USE, nil, d); return; + syntax.scopedefine(c.top, nm, syntax.skind.SK_USE, nil, d); return; }; - if (k == nkind.N_DEF) { installtop(c, d, nm, mod, skind.SK_DEF, "def"); return; }; - if (k == nkind.N_TYPEDECL) { installtop(c, d, nm, mod, skind.SK_TYPE, "type"); return; }; - if (k == nkind.N_FNDECL) { installtop(c, d, nm, mod, skind.SK_FN, "fn"); return; }; - if (k == nkind.N_LET) { installtop(c, d, nm, mod, skind.SK_VAR, "let"); return; }; + if (k == syntax.nkind.N_DEF) { installtop(c, d, nm, mod, syntax.skind.SK_DEF, "def"); return; }; + if (k == syntax.nkind.N_TYPEDECL) { installtop(c, d, nm, mod, syntax.skind.SK_TYPE, "type"); return; }; + if (k == syntax.nkind.N_FNDECL) { installtop(c, d, nm, mod, syntax.skind.SK_FN, "fn"); return; }; + if (k == syntax.nkind.N_LET) { installtop(c, d, nm, mod, syntax.skind.SK_VAR, "let"); return; }; }; // installtop — install a top-level decl name into c.top, rejecting a @@ -11108,7 +11108,7 @@ fn installdecl(c: *checker, file: *node, d: *node) void = { // carrying no real source decl (primtypes: decl=nil; `nomem`: a // checkinit-synthesized N_TYPEDECL with an empty .file) — user decls // always carry their parsed source file. -fn installtop(c: *checker, d: *node, nm: str, mod: str, k: skind, kind: str) void = { +fn installtop(c: *checker, d: *syntax.node, nm: str, mod: str, k: syntax.skind, kind: str) void = { // #30: a top-level value/type decl whose leaf ALSO names an imported // module PROMOTES that same-leaf SK_USE in place — one correctly-kinded // sym carrying use_alias=1, so bare refs (call/structlit/var) resolve to @@ -11123,16 +11123,16 @@ fn installtop(c: *checker, d: *node, nm: str, mod: str, k: skind, kind: str) voi // (set use_alias on the pre-installed value sym). Both directions reach // the identical single-sym end state, so cstage and wwstage agree on // every source order (#30). - let puse: *sym = scopelookuplocal(c.top, nm); - if (puse != nil) { if (puse.skind == skind.SK_USE) { + let puse: *syntax.sym = syntax.scopelookuplocal(c.top, nm); + if (puse != nil) { if (puse.skind == syntax.skind.SK_USE) { puse.skind = k; puse.decl = d; puse.use_alias = 1i32; if (mod.len > 0) { if (puse.mod.len == 0) { puse.mod = mod; }; }; return; }; }; - if (scopedefineinmodule(c.top, nm, mod, k, nil, d) != nil) { return; }; - let prev: *sym = scopesamekeysym(c.top, nm, mod); + if (syntax.scopedefineinmodule(c.top, nm, mod, k, nil, d) != nil) { return; }; + let prev: *syntax.sym = syntax.scopesamekeysym(c.top, nm, mod); if (prev != nil) { if (prev.decl == nil) { return; }; if (prev.decl.file.len == 0) { return; }; @@ -11164,26 +11164,26 @@ fn installtop(c: *checker, d: *node, nm: str, mod: str, k: skind, kind: str) voi // empty-str N_IDENT with no decl to read a type back from): harec drops // `_` yet still advances the tuple slot, so that slot's element type is // the honest type to stamp — `_` is UNBOUND, not UNTYPED. -fn stamptuplebinds(c: *checker, binds: *node, elems: *node, +fn stamptuplebinds(c: *checker, binds: *syntax.node, elems: *syntax.node, define: bool, what: str) void = { - let b: *node = binds; - let pt: *node = elems; + let b: *syntax.node = binds; + let pt: *syntax.node = elems; for (b != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (pt != nil) { et = pt.lhs; }; if (define) { if (b.lhs == nil) { b.lhs = et; }; let bnm: str = b.str; if (bnm.len > 0) { checkmoduleshadow(c, bnm, what); - scopedefine(c.cur, bnm, skind.SK_VAR, nil, b); + syntax.scopedefine(c.cur, bnm, syntax.skind.SK_VAR, nil, b); }; }; if (b.type_ == nil) { - let src: *node = b.lhs; + let src: *syntax.node = b.lhs; if (src == nil) { src = et; }; if (src != nil) { - let ti: *tinfo = tinfofornode(c, src); + let ti: *syntax.tinfo = tinfofornode(c, src); if (ti != nil) { b.type_ = ti: *void; }; }; }; @@ -11200,27 +11200,27 @@ fn stamptuplebinds(c: *checker, binds: *node, elems: *node, // the C checker's collect-then-resolve flow within a function). // Also runs the typed checks (match exhaustiveness, ? subset) in // the same pass — they need the same scope state. -fn resolvewalk(c: *checker, n: *node) void = { +fn resolvewalk(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; // Typed checks fire on the way down so the scrutinee/operand // is examined before the arm bodies install new bindings. - if (k == nkind.N_MATCH) { checkmatchexhaust(c, n); }; - if (k == nkind.N_TRYPROP) { checktryprop(c, n); }; - if (k == nkind.N_TRYUNW) { checktryprop(c, n); }; - if (k == nkind.N_TYPETEST) { checkisas(c, n); }; - if (k == nkind.N_TYPEASSERT) { checkisas(c, n); }; - if (k == nkind.N_LET) { checkletassign(c, n); }; - if (k == nkind.N_RETURN) { checkretassign(c, n); }; + if (k == syntax.nkind.N_MATCH) { checkmatchexhaust(c, n); }; + if (k == syntax.nkind.N_TRYPROP) { checktryprop(c, n); }; + if (k == syntax.nkind.N_TRYUNW) { checktryprop(c, n); }; + if (k == syntax.nkind.N_TYPETEST) { checkisas(c, n); }; + if (k == syntax.nkind.N_TYPEASSERT) { checkisas(c, n); }; + if (k == syntax.nkind.N_LET) { checkletassign(c, n); }; + if (k == syntax.nkind.N_RETURN) { checkretassign(c, n); }; // `use IDENT;` — name is a module label, not a free ident. - if (k == nkind.N_USE) { return; }; + if (k == syntax.nkind.N_USE) { return; }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { let nm: str = n.str; if (nm.len > 0) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, nm); if (s == nil) { // Unshadowed abort/assert binds no sym BY // DESIGN (the EXPR_ASSERT family has no callee @@ -11241,10 +11241,10 @@ fn resolvewalk(c: *checker, n: *node) void = { }; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = n.str; if (nm.len > 0) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, nm); // `pkg.Type` — strip the last dot prefix and look up // the leaf with a mod filter so same-leaf-name types // from different imports (`bufio.stream` vs @@ -11260,12 +11260,12 @@ fn resolvewalk(c: *checker, n: *node) void = { let head: str; head.ptr = nm.ptr; head.len = dot; - let m: *sym = scopelookup(c.cur, head); + let m: *syntax.sym = syntax.scopelookup(c.cur, head); if (m != nil) { let leaf: str; leaf.ptr = nm.ptr + (dot + 1): u64; leaf.len = nm.len - (dot + 1); - s = scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); + s = syntax.scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); }; }; }; @@ -11292,7 +11292,7 @@ fn resolvewalk(c: *checker, n: *node) void = { // only by wwdump_ww as a diagnostic, so silent-accept here avoids // false-positives on legal cross-block shadow until #11 adds the // scoping infrastructure. - if (k == nkind.N_FORRANGE) { + if (k == syntax.nkind.N_FORRANGE) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; if (n.list != nil) { // Tuple destructure `for (let (a,b) .. xs)`: peel the @@ -11300,13 +11300,13 @@ fn resolvewalk(c: *checker, n: *node) void = { // element types onto the binders, the same lockstep walk // harec runs for the for-each header // (ref/harec/src/check.c:2308-2317 → create_unpack_bindings). - let elems: *node = nil; - let it: *node = exprtype(c, n.lhs, nil); + let elems: *syntax.node = nil; + let it: *syntax.node = exprtype(c, n.lhs, nil); if (it != nil) { - let et: *node = nil; - if (it.kind == nkind.N_TSLICE) { et = it.lhs; }; - if (it.kind == nkind.N_TARRAY) { et = it.lhs; }; - if (et != nil) { if (et.kind == nkind.N_TTUPLE) { + let et: *syntax.node = nil; + if (it.kind == syntax.nkind.N_TSLICE) { et = it.lhs; }; + if (it.kind == syntax.nkind.N_TARRAY) { et = it.lhs; }; + if (et != nil) { if (et.kind == syntax.nkind.N_TTUPLE) { elems = et.list; }; }; }; @@ -11328,8 +11328,8 @@ fn resolvewalk(c: *checker, n: *node) void = { // `b.lhs = et` idiom. A str scrutinee keeps the // old decl: cgen synthesises the u8 elem there // and no dot applies to a u8 binding. - let et: *node = nil; - let it: *node = exprtype(c, n.lhs, nil); + let et: *syntax.node = nil; + let it: *syntax.node = exprtype(c, n.lhs, nil); // #80 (F2a batch-4 c4): an alias-typed iterable // arrives as N_TNAME — without the AST-level // dealias the binder fell to the N_FORRANGE @@ -11338,16 +11338,16 @@ fn resolvewalk(c: *checker, n: *node) void = { // accepts: its scope_define types the elem). if (it != nil) { it = resolvealias(c, unwrapbang(it)); }; if (it != nil) { - if (it.kind == nkind.N_TSLICE) { et = it.lhs; }; - if (it.kind == nkind.N_TARRAY) { et = it.lhs; }; + if (it.kind == syntax.nkind.N_TSLICE) { et = it.lhs; }; + if (it.kind == syntax.nkind.N_TARRAY) { et = it.lhs; }; }; if (et != nil) { - let bn: *node = newnode(nkind.N_LET, n.file, n.line, n.col); + let bn: *syntax.node = syntax.newnode(syntax.nkind.N_LET, n.file, n.line, n.col); bn.str = bnm; bn.lhs = et; - scopedefine(c.cur, bnm, skind.SK_VAR, nil, bn); + syntax.scopedefine(c.cur, bnm, syntax.skind.SK_VAR, nil, bn); } else { - scopedefine(c.cur, bnm, skind.SK_VAR, nil, n); + syntax.scopedefine(c.cur, bnm, syntax.skind.SK_VAR, nil, n); }; }; }; @@ -11362,14 +11362,14 @@ fn resolvewalk(c: *checker, n: *node) void = { // `let e: *T` (scopedefine drops same-scope dupes silently and // would leave references to `e` resolving to the outer type). // Mirrors cmd/wcc/check.c's newscope/saved-restore around cstmt. - if (k == nkind.N_MCASE) { + if (k == syntax.nkind.N_MCASE) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; - let outer: *scope = c.cur; - c.cur = newscope(outer); + let outer: *syntax.scope = c.cur; + c.cur = syntax.newscope(outer); let nm: str = n.str; if (nm.len > 0) { checkmoduleshadow(c, nm, "binding"); - scopedefine(c.cur, nm, skind.SK_VAR, nil, n); + syntax.scopedefine(c.cur, nm, syntax.skind.SK_VAR, nil, n); }; if (n.body != nil) { resolvewalk(c, n.body); }; c.cur = outer; @@ -11385,10 +11385,10 @@ fn resolvewalk(c: *checker, n: *node) void = { // becomes a false-positive on the next driver (`wwdump_ww -r` // flagged the u64→i32 pair in selfhost/cmd/ww/enumeratedir). // Mirrors cstage cstmt N_BLOCK at cmd/wcc/check.c:1559-1566. - if (k == nkind.N_BLOCK) { - let outer: *scope = c.cur; - c.cur = newscope(outer); - let m: *node = n.list; + if (k == syntax.nkind.N_BLOCK) { + let outer: *syntax.scope = c.cur; + c.cur = syntax.newscope(outer); + let m: *syntax.node = n.list; for (m != nil) { resolvewalk(c, m); m = m.next; @@ -11422,9 +11422,9 @@ fn resolvewalk(c: *checker, n: *node) void = { // their own type. Mirrors the N_FORRANGE binding-install shape above; // the bindings would otherwise install (unstamped) via the generic // N_LET walk, so this early return must register them itself. - if (k == nkind.N_MLET) { + if (k == syntax.nkind.N_MLET) { if (n.rhs != nil) { resolvewalk(c, n.rhs); }; - let pt: *node = nil; + let pt: *syntax.node = nil; // #242: consume the rhs's tuple type for ANY rhs, not just an // N_CALL — `let (a,b) = t` over a plain tuple ident (e.g. a // match-bound union payload) must stamp its bindings too, or @@ -11433,8 +11433,8 @@ fn resolvewalk(c: *checker, n: *node) void = { if (n.rhs != nil) { // `rt` would shadow the imported lib/rt module // (checkmoduleshadow errors); `rty` avoids it. - let rty: *node = exprtype(c, n.rhs, nil); - if (rty != nil) { if (rty.kind == nkind.N_TTUPLE) { + let rty: *syntax.node = exprtype(c, n.rhs, nil); + if (rty != nil) { if (rty.kind == syntax.nkind.N_TTUPLE) { pt = rty.list; }; }; }; @@ -11449,13 +11449,13 @@ fn resolvewalk(c: *checker, n: *node) void = { // still-nil slots, which is exactly the discard `_` (no decl, so the // N_IDENT exprtype path leaves it untyped). Distribution mirrors the // N_MLET/N_FORRANGE binders; see stamptuplebinds. - if (k == nkind.N_MASSIGN) { + if (k == syntax.nkind.N_MASSIGN) { if (n.rhs != nil) { resolvewalk(c, n.rhs); }; - let pt: *node = nil; + let pt: *syntax.node = nil; // #242: consume the rhs tuple type for ANY rhs (see N_MLET). if (n.rhs != nil) { - let rty: *node = exprtype(c, n.rhs, nil); - if (rty != nil && rty.kind == nkind.N_TTUPLE) { + let rty: *syntax.node = exprtype(c, n.rhs, nil); + if (rty != nil && rty.kind == syntax.nkind.N_TTUPLE) { pt = rty.list; } else { // #38/F2 (review item 39): the multi-assign rhs must be a @@ -11471,29 +11471,29 @@ fn resolvewalk(c: *checker, n: *node) void = { deffolderr(c, n, "multi-assign rhs is not a tuple"); }; }; - let l: *node = n.list; + let l: *syntax.node = n.list; for (l != nil) { resolvewalk(c, l); l = l.next; }; stamptuplebinds(c, n.list, pt, false, ""); return; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // Walk only the base; the .field name is a member, not a // free identifier. if (n.lhs != nil) { resolvewalk(c, n.lhs); }; // A.6.0: branch returns early; stamp here so the post-walk // dispatch below sees N_DOT covered. exprtype N_DOT arm is // added in A.6.1; for now this is a no-op nil return. - let _t: *node = exprtype(c, n, nil); + let _t: *syntax.node = exprtype(c, n, nil); return; }; - if (k == nkind.N_FIELD) { + if (k == syntax.nkind.N_FIELD) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; return; }; - if (k == nkind.N_TFIELD) { + if (k == syntax.nkind.N_TFIELD) { if (n.lhs != nil) { resolvewalk(c, n.lhs); }; return; }; @@ -11506,7 +11506,7 @@ fn resolvewalk(c: *checker, n: *node) void = { if (n.body != nil) { resolvewalk(c, n.body); }; if (n.els != nil) { resolvewalk(c, n.els); }; if (n.list != nil) { - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { resolvewalk(c, m); m = m.next; @@ -11519,19 +11519,19 @@ fn resolvewalk(c: *checker, n: *node) void = { // user-defined aliases). Cgen's slotsize fast-path reads off // n.type_; uncovered shapes fall through to the cstage-mirror // walker until the next sub-commit graduates them. - if (k == nkind.N_TNAME || k == nkind.N_TPTR || - k == nkind.N_TSLICE || k == nkind.N_TCHAN || - k == nkind.N_TBANG || k == nkind.N_TARRAY || - k == nkind.N_TFN || k == nkind.N_TSTRUCT || - k == nkind.N_TTUPLE || k == nkind.N_TTAGGED || - k == nkind.N_TENUM) { + if (k == syntax.nkind.N_TNAME || k == syntax.nkind.N_TPTR || + k == syntax.nkind.N_TSLICE || k == syntax.nkind.N_TCHAN || + k == syntax.nkind.N_TBANG || k == syntax.nkind.N_TARRAY || + k == syntax.nkind.N_TFN || k == syntax.nkind.N_TSTRUCT || + k == syntax.nkind.N_TTUPLE || k == syntax.nkind.N_TTAGGED || + k == syntax.nkind.N_TENUM) { if (n.type_ == nil) { - let ti: *tinfo = tinfofornode(c, n); + let ti: *syntax.tinfo = tinfofornode(c, n); if (ti != nil) { n.type_ = ti: *void; }; }; }; - if (k == nkind.N_TENUM) { stampenumvals(c, n); }; + if (k == syntax.nkind.N_TENUM) { stampenumvals(c, n); }; // #42's size/align/offset fold trigger lived here pre-A.6.0; the // A.6.0 end-of-fn general dispatch (below) now fires exprtype on @@ -11548,17 +11548,17 @@ fn resolvewalk(c: *checker, n: *node) void = { // still silent-accepts here; promoting that to an error stays // queued behind #11 (test/wcc/708 + test/wcc/696 are the cstage- // only neg-case precedent). - if (k == nkind.N_LET) { + if (k == syntax.nkind.N_LET) { let nm: str = n.str; if (nm.len > 0) { checkmoduleshadow(c, nm, "let"); - let s: *sym = scopedefine(c.cur, nm, skind.SK_VAR, nil, n); + let s: *syntax.sym = syntax.scopedefine(c.cur, nm, syntax.skind.SK_VAR, nil, n); // catB-22: flag a `const` binding so checkassign can // reject a later reassignment. The parser stamps // n.op = TK_CONST (parse/stmt.ww). Mirror cstage // cmd/wcc/check.c:2408. if (s != nil) { - if (n.op == tkind.TK_CONST) { s.is_const = 1i32; }; + if (n.op == syntax.tkind.TK_CONST) { s.is_const = 1i32; }; }; }; }; @@ -11571,8 +11571,8 @@ fn resolvewalk(c: *checker, n: *node) void = { // / return only — see coercefloatlit's docstring for the rule-10 scope // (the cstage twin coerces in clet / cstmt N_RETURN). c.fnret is set // by resolvefnbody for the enclosing fn, mirroring checkretassign. - if (k == nkind.N_LET) { coercefloatlit(c, n.rhs, n.lhs); }; - if (k == nkind.N_RETURN) { coercefloatlit(c, n.lhs, c.fnret); }; + if (k == syntax.nkind.N_LET) { coercefloatlit(c, n.rhs, n.lhs); }; + if (k == syntax.nkind.N_RETURN) { coercefloatlit(c, n.lhs, c.fnret); }; // A.6.0: post-order dispatch of exprtype on every expression-yielding // node kind so n.type_ stamps fire universally — not only when reached @@ -11595,24 +11595,24 @@ fn resolvewalk(c: *checker, n: *node) void = { // exprtype below so a regular N_CALL is still an N_CALL (not folded to // an N_INTLIT by the size/align intercept). Mirrors cstage's post- // order cexpr desugar at the call-arg / N_ASSIGN sites. - if (k == nkind.N_CALL) { desugarcallargs(c, n); }; - if (k == nkind.N_ASSIGN) { checkassign(c, n); }; + if (k == syntax.nkind.N_CALL) { desugarcallargs(c, n); }; + if (k == syntax.nkind.N_ASSIGN) { checkassign(c, n); }; - if (k == nkind.N_INTLIT || k == nkind.N_FLOATLIT || - k == nkind.N_STRLIT || k == nkind.N_RUNELIT || - k == nkind.N_TRUE || k == nkind.N_FALSE || - k == nkind.N_NIL || k == nkind.N_VOIDLIT || - k == nkind.N_IDENT || k == nkind.N_BIN || - k == nkind.N_UN || k == nkind.N_CALL || - k == nkind.N_INDEX || k == nkind.N_CAST || - k == nkind.N_STRUCTLIT || k == nkind.N_ARRLIT || - k == nkind.N_RECV || - k == nkind.N_SLICE || k == nkind.N_SPREAD || - k == nkind.N_TUPLE || k == nkind.N_TRYPROP || - k == nkind.N_TRYUNW || k == nkind.N_TYPETEST || - k == nkind.N_TYPEASSERT || k == nkind.N_YIELD || - k == nkind.N_MATCH) { - let _t: *node = exprtype(c, n, nil); + if (k == syntax.nkind.N_INTLIT || k == syntax.nkind.N_FLOATLIT || + k == syntax.nkind.N_STRLIT || k == syntax.nkind.N_RUNELIT || + k == syntax.nkind.N_TRUE || k == syntax.nkind.N_FALSE || + k == syntax.nkind.N_NIL || k == syntax.nkind.N_VOIDLIT || + k == syntax.nkind.N_IDENT || k == syntax.nkind.N_BIN || + k == syntax.nkind.N_UN || k == syntax.nkind.N_CALL || + k == syntax.nkind.N_INDEX || k == syntax.nkind.N_CAST || + k == syntax.nkind.N_STRUCTLIT || k == syntax.nkind.N_ARRLIT || + k == syntax.nkind.N_RECV || + k == syntax.nkind.N_SLICE || k == syntax.nkind.N_SPREAD || + k == syntax.nkind.N_TUPLE || k == syntax.nkind.N_TRYPROP || + k == syntax.nkind.N_TRYUNW || k == syntax.nkind.N_TYPETEST || + k == syntax.nkind.N_TYPEASSERT || k == syntax.nkind.N_YIELD || + k == syntax.nkind.N_MATCH) { + let _t: *syntax.node = exprtype(c, n, nil); }; }; @@ -11625,9 +11625,9 @@ fn resolvewalk(c: *checker, n: *node) void = { // propagation, and !-flag semantics. // unwrapbang — strip an nkind.N_TBANG wrapper; leaves other nodes alone. -fn unwrapbang(n: *node) *node = { +fn unwrapbang(n: *syntax.node) *syntax.node = { if (n == nil) { return nil; }; - if (n.kind == nkind.N_TBANG) { return n.lhs; }; + if (n.kind == syntax.nkind.N_TBANG) { return n.lhs; }; return n; }; @@ -11638,9 +11638,9 @@ fn unwrapbang(n: *node) *node = { // decl sym (nominal identity = sym.type_ ptr-identity) instead of // flattening to the underlying. Mirrors cstage resolve_typename // (cmd/wcc/check.c:60-88), which returns the sym's NAMED, not the base. -fn aliassym(c: *checker, n: *node) *sym = { +fn aliassym(c: *checker, n: *syntax.node) *syntax.sym = { if (n == nil) { return nil; }; - if (n.kind != nkind.N_TNAME) { return nil; }; + if (n.kind != syntax.nkind.N_TNAME) { return nil; }; let nm: str = n.str; // #51: pkg.alias type refs land here as a single TNAME whose // str is the joined form (lib/ww/parse/parse.ww:258-265 in @@ -11655,7 +11655,7 @@ fn aliassym(c: *checker, n: *node) *sym = { if (nm[i] == 46u8) { dotidx = i; }; i += 1; }; - let s: *sym = nil; + let s: *syntax.sym = nil; if (dotidx >= 0) { let head: str; head.ptr = nm.ptr; @@ -11663,7 +11663,7 @@ fn aliassym(c: *checker, n: *node) *sym = { let leaf: str; leaf.ptr = nm.ptr + ((dotidx + 1): u64); leaf.len = nm.len - dotidx - 1; - s = scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); + s = syntax.scopelookupinmodule(c.cur, modkeyfor(c, head), leaf); } else { // #53: same-module preference. Mirrors cstage // cmd/wcc/check.c:66 scope_lookup_prefer. Without this, @@ -11676,7 +11676,7 @@ fn aliassym(c: *checker, n: *node) *sym = { // scopelookupprefer (the #56/#4/#11a wave). The only bare-leaf // type lookups left — varianterr (:1051) + scruttype (:1098) — // stay mod-blind but have no reproducible divergence; #58. - s = scopelookupprefer(c.cur, c.curmod, nm); + s = syntax.scopelookupprefer(c.cur, c.curmod, nm); // #61 A.5: bare TNAME that collides with an imported // module bareword. Two shapes hit this: // - `let l: lex;` where `lex` struct lives in @@ -11692,20 +11692,20 @@ fn aliassym(c: *checker, n: *node) *sym = { // regardless of its declaring package. Mirrors the // bare-vs-qualified pattern from task #57. if (s != nil) { - if (s.skind != skind.SK_TYPE) { + if (s.skind != syntax.skind.SK_TYPE) { // #58/#50: prefer the curmod-matching SK_TYPE. // Two modules exporting the same type leaf (e.g. // utf8.invalid !void vs strconv.invalid !i32) // otherwise resolve install-order-dependent here // when a value binding shadows the leaf; cstage // passes c->cur_mod to scope_lookup_type (sym.c). - let sm: *sym = scopelookuptype(c.cur, c.curmod, nm); + let sm: *syntax.sym = syntax.scopelookuptype(c.cur, c.curmod, nm); if (sm != nil) { s = sm; }; }; }; }; if (s == nil) { return nil; }; - if (s.skind != skind.SK_TYPE) { return nil; }; + if (s.skind != syntax.skind.SK_TYPE) { return nil; }; return s; }; @@ -11713,13 +11713,13 @@ fn aliassym(c: *checker, n: *node) *sym = { // the typedecl's body (possibly recursively). Pass-through for any // other node. The chain stops once we hit a non-nkind.N_TNAME node or a // name we can't resolve. -fn resolvealias(c: *checker, n: *node) *node = { - let cur: *node = n; +fn resolvealias(c: *checker, n: *syntax.node) *syntax.node = { + let cur: *syntax.node = n; for (cur != nil) { - if (cur.kind != nkind.N_TNAME) { return cur; }; - let s: *sym = aliassym(c, cur); + if (cur.kind != syntax.nkind.N_TNAME) { return cur; }; + let s: *syntax.sym = aliassym(c, cur); if (s == nil) { return cur; }; - let body: *node = nil; + let body: *syntax.node = nil; if (s.decl != nil) { body = s.decl.lhs; }; if (body == nil) { return cur; }; cur = unwrapbang(body); @@ -11735,9 +11735,9 @@ fn resolvealias(c: *checker, n: *node) *node = { // bare `oserror` vs qualified `os.oserror` resolve to the SAME // SK_TYPE sym (aliassym maps both via #51/#53), so a cross-module // nominal forward compares equal where the surface streq said false. -fn typeeqast(c: *checker, a: *node, b: *node) bool = { - let aa: *node = unwrapbang(a); - let bb: *node = unwrapbang(b); +fn typeeqast(c: *checker, a: *syntax.node, b: *syntax.node) bool = { + let aa: *syntax.node = unwrapbang(a); + let bb: *syntax.node = unwrapbang(b); if (aa == nil) { return bb == nil; }; if (bb == nil) { return false; }; // Identity fast-path, mirroring cstage type_eq's first line @@ -11749,31 +11749,31 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // cstage accepts via this identity check. if (aa == bb) { return true; }; if (aa.kind != bb.kind) { return false; }; - let k: nkind = aa.kind; - if (k == nkind.N_TNAME) { - if (streq(aa.str, bb.str)) { return true; }; - let sa: *sym = aliassym(c, aa); - let sb: *sym = aliassym(c, bb); + let k: syntax.nkind = aa.kind; + if (k == syntax.nkind.N_TNAME) { + if (syntax.streq(aa.str, bb.str)) { return true; }; + let sa: *syntax.sym = aliassym(c, aa); + let sb: *syntax.sym = aliassym(c, bb); if (sa != nil && sa == sb) { return true; }; return false; }; - if (k == nkind.N_TPTR) { return typeeqast(c, aa.lhs, bb.lhs); }; - if (k == nkind.N_TSLICE){ return typeeqast(c, aa.lhs, bb.lhs); }; - if (k == nkind.N_TCHAN) { return typeeqast(c, aa.lhs, bb.lhs); }; - if (k == nkind.N_TFN) { + if (k == syntax.nkind.N_TPTR) { return typeeqast(c, aa.lhs, bb.lhs); }; + if (k == syntax.nkind.N_TSLICE){ return typeeqast(c, aa.lhs, bb.lhs); }; + if (k == syntax.nkind.N_TCHAN) { return typeeqast(c, aa.lhs, bb.lhs); }; + if (k == syntax.nkind.N_TFN) { // Divergence: cstage type.c:239 compares resolved Type; we // compare AST. See #178. if (!typeeqast(c, aa.lhs, bb.lhs)) { return false; }; - let pa: *node = aa.list; - let pb: *node = bb.list; + let pa: *syntax.node = aa.list; + let pb: *syntax.node = bb.list; for (pa != nil) { if (pb == nil) { return false; }; - let ac: bool = streq(pa.str, "..."); - let bc: bool = streq(pb.str, "..."); + let ac: bool = syntax.streq(pa.str, "..."); + let bc: bool = syntax.streq(pb.str, "..."); if (ac != bc) { return false; }; if (!ac) { - let va: bool = pa.op == tkind.TK_ELLIPSIS; - let vb: bool = pb.op == tkind.TK_ELLIPSIS; + let va: bool = pa.op == syntax.tkind.TK_ELLIPSIS; + let vb: bool = pb.op == syntax.tkind.TK_ELLIPSIS; if (va != vb) { return false; }; if (!typeeqast(c, pa.lhs, pb.lhs)) { return false; }; }; @@ -11789,9 +11789,9 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // would confidently reject a bare-&fn into a structural `*fn(...)` // slot (test 766 fn_tuple_return). Elements are N_TPARAM-wrapped // (parse.ww:302-318), so compare each link's .lhs. - if (k == nkind.N_TTUPLE) { - let pa: *node = aa.list; - let pb: *node = bb.list; + if (k == syntax.nkind.N_TTUPLE) { + let pa: *syntax.node = aa.list; + let pb: *syntax.node = bb.list; for (pa != nil) { if (pb == nil) { return false; }; if (!typeeqast(c, pa.lhs, pb.lhs)) { return false; }; @@ -11810,9 +11810,9 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // Divergence: cstage's nullable-flag check (type.c:293) is a resolved- // Type property with no AST analogue; for case-match both sides share // a spelling so it's moot — no phantom AST nullable check. - if (k == nkind.N_TTAGGED) { - let pa: *node = aa.list; - let pb: *node = bb.list; + if (k == syntax.nkind.N_TTAGGED) { + let pa: *syntax.node = aa.list; + let pb: *syntax.node = bb.list; for (pa != nil) { if (pb == nil) { return false; }; // #115: a `...inner` spread variant stays unflattened at @@ -11823,8 +11823,8 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // match a plain `ab`, accepting a case cstage rejects. // Conservatively loud-reject any spread until the flatten // lands; b1c's (void|size) has none, so byte-id is untouched. - if (pa.op == tkind.TK_ELLIPSIS) { return false; }; - if (pb.op == tkind.TK_ELLIPSIS) { return false; }; + if (pa.op == syntax.tkind.TK_ELLIPSIS) { return false; }; + if (pb.op == syntax.tkind.TK_ELLIPSIS) { return false; }; if (!typeeqast(c, pa, pb)) { return false; }; pa = pa.next; pb = pb.next; @@ -11840,20 +11840,20 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = { // varianterr — does this variant carry the `!` mark? Either // the variant itself is nkind.N_TBANG or it's an alias whose typedecl // body is `!T`. Mirrors C check.c's iserror-after-NAMED rule. -fn varianterr(c: *checker, v: *node) bool = { +fn varianterr(c: *checker, v: *syntax.node) bool = { if (v == nil) { return false; }; - if (v.kind == nkind.N_TBANG) { return true; }; - if (v.kind == nkind.N_TNAME) { + if (v.kind == syntax.nkind.N_TBANG) { return true; }; + if (v.kind == syntax.nkind.N_TNAME) { // #58: mod-blind by leaf — latent. A same-leaf error-vs-plain // type pair across two modules could in principle flip iserror, // but the union's variants resolve at its declaration before // varianterr runs, so no repro exists. Tracked: #58. - let s: *sym = scopelookup(c.cur, v.str); + let s: *syntax.sym = syntax.scopelookup(c.cur, v.str); if (s != nil) { - if (s.skind == skind.SK_TYPE) { + if (s.skind == syntax.skind.SK_TYPE) { if (s.decl != nil) { if (s.decl.lhs != nil) { - if (s.decl.lhs.kind == nkind.N_TBANG) { + if (s.decl.lhs.kind == syntax.nkind.N_TBANG) { return true; }; }; @@ -11867,8 +11867,8 @@ fn varianterr(c: *checker, v: *node) bool = { // taggedhaserr — true iff any variant of `n` (assumed // nkind.N_TTAGGED) is `!`-marked. Picks the explicit-flag semantics over // the legacy "first variant = success" rule. -fn taggedhaserr(c: *checker, n: *node) bool = { - let v: *node = n.list; +fn taggedhaserr(c: *checker, n: *syntax.node) bool = { + let v: *syntax.node = n.list; for (v != nil) { if (varianterr(c, v)) { return true; }; v = v.next; @@ -11879,7 +11879,7 @@ fn taggedhaserr(c: *checker, n: *node) bool = { // iserrvariant — under flag-aware mode (any !-marked variant), // returns true iff `v` is `!`-marked. Under legacy mode (no flags), // returns true iff `v` is not the first variant of `tagged`. -fn iserrvariant(c: *checker, tagged: *node, v: *node) bool = { +fn iserrvariant(c: *checker, tagged: *syntax.node, v: *syntax.node) bool = { if (taggedhaserr(c, tagged)) { return varianterr(c, v); }; @@ -11892,14 +11892,14 @@ fn iserrvariant(c: *checker, tagged: *node, v: *node) bool = { // scrutinee. Handles nkind.N_IDENT (look up local/param's declared // type) and nkind.N_DOT (module-qualified ref). Returns nil if we // can't statically determine the type. Used by exhaustiveness. -fn scruttype(c: *checker, e: *node) *node = { +fn scruttype(c: *checker, e: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - if (e.kind == nkind.N_IDENT) { + if (e.kind == syntax.nkind.N_IDENT) { // #58: mod-blind by leaf — lenient-only. Feeds match // exhaustiveness; codegen reads the stamped n.type_, so a // mis-resolution cannot drive a wrong binary (no repro). // Tracked: #58. - let s: *sym = scopelookup(c.cur, e.str); + let s: *syntax.sym = syntax.scopelookup(c.cur, e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; // For nkind.N_LET / nkind.N_PARAM: declared type is decl.lhs. @@ -11911,10 +11911,10 @@ fn scruttype(c: *checker, e: *node) *node = { // shape resolvealias' dotted-name branch now consumes. Falls // silently to nil when lhs is a value (struct-field access) — // the rest of the lenient-check contract. - if (e.kind == nkind.N_DOT) { + if (e.kind == syntax.nkind.N_DOT) { if (e.lhs == nil) { return nil; }; - if (e.lhs.kind != nkind.N_IDENT) { return nil; }; - let s: *sym = scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.str), e.str); + if (e.lhs.kind != syntax.nkind.N_IDENT) { return nil; }; + let s: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.str), e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; return s.decl.lhs; @@ -11925,8 +11925,8 @@ fn scruttype(c: *checker, e: *node) *node = { // mktname — fabricate an nkind.N_TNAME node with str = `nm`. Used by // exprtype to return primitive type nodes for literal // expressions. The arena keeps them around as long as the checker. -fn mktname(c: *checker, nm: str) *node = { - let n: *node = newnode(nkind.N_TNAME, "", 0, 0); +fn mktname(c: *checker, nm: str) *syntax.node = { + let n: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, "", 0, 0); n.str = nm; return n; }; @@ -11938,16 +11938,16 @@ fn mktname(c: *checker, nm: str) *node = { // names; callers fall back to alias/struct/enum lookup. Cstage's // equivalent SSoT is cmd/wcc/type.c:46-79 (ty_void/ty_bool/.../ty_str). fn primtypesize(nm: str) i64 = { - if (streq(nm, "void")) { return 0i64; }; - if (streq(nm, "bool")) { return 1i64; }; - if (streq(nm, "i8") || streq(nm, "u8")) { return 1i64; }; - if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; }; - if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; }; - if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64")) { return 8i64; }; - if (streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr") || streq(nm, "size")) { return 8i64; }; + if (syntax.streq(nm, "void")) { return 0i64; }; + if (syntax.streq(nm, "bool")) { return 1i64; }; + if (syntax.streq(nm, "i8") || syntax.streq(nm, "u8")) { return 1i64; }; + if (syntax.streq(nm, "i16") || syntax.streq(nm, "u16")) { return 2i64; }; + if (syntax.streq(nm, "i32") || syntax.streq(nm, "u32") || syntax.streq(nm, "f32") || syntax.streq(nm, "rune")) { return 4i64; }; + if (syntax.streq(nm, "i64") || syntax.streq(nm, "u64") || syntax.streq(nm, "f64")) { return 8i64; }; + if (syntax.streq(nm, "int") || syntax.streq(nm, "uint") || syntax.streq(nm, "uintptr") || syntax.streq(nm, "size")) { return 8i64; }; // str IS []u8: 24B, sourced from the slice header SSoT so str and // []u8 can never drift; no second hardcoded 24 (#1/Phase 3). - if (streq(nm, "str")) { return tyslicesize(); }; + if (syntax.streq(nm, "str")) { return tyslicesize(); }; return -1i64; }; @@ -11962,27 +11962,27 @@ fn tyslicesize() i64 = { return 24i64; }; // sizelint-ok: SSoT for ty_slice head // materialises tinfo for user types so the fold has to walk the AST // directly. Struct layout follows cstage check.c:471-526 (align each // field, max align for the whole record, round size up to alignment). -fn astalign(c: *checker, t: *node) i64 = { +fn astalign(c: *checker, t: *syntax.node) i64 = { if (t == nil) { return 1i64; }; - let k: nkind = t.kind; - if (k == nkind.N_TBANG) { return astalign(c, t.lhs); }; - if (k == nkind.N_TPTR) { return 8i64; }; - if (k == nkind.N_TSLICE) { return 8i64; }; - if (k == nkind.N_TCHAN) { return 8i64; }; - if (k == nkind.N_TFN) { return 8i64; }; - if (k == nkind.N_TARRAY) { return astalign(c, t.lhs); }; - if (k == nkind.N_TTAGGED) { + let k: syntax.nkind = t.kind; + if (k == syntax.nkind.N_TBANG) { return astalign(c, t.lhs); }; + if (k == syntax.nkind.N_TPTR) { return 8i64; }; + if (k == syntax.nkind.N_TSLICE) { return 8i64; }; + if (k == syntax.nkind.N_TCHAN) { return 8i64; }; + if (k == syntax.nkind.N_TFN) { return 8i64; }; + if (k == syntax.nkind.N_TARRAY) { return astalign(c, t.lhs); }; + if (k == syntax.nkind.N_TTAGGED) { // Route through the normalization SSoT: a lone survivor // collapses (align((i32|never))==align(i32)==4, not the tag // word's 8), matching cstage align() reading resolve_type(...) // ->align (cmd/wcc/check.c:1550). Same #1 family as astsize. - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { return ti.align: i64; }; return 8i64; }; - if (k == nkind.N_TTUPLE) { + if (k == syntax.nkind.N_TTUPLE) { let m: i64 = 1i64; - let p: *node = t.list; + let p: *syntax.node = t.list; for (p != nil) { let pa: i64 = astalign(c, p.lhs); if (pa > m) { m = pa; }; @@ -11990,11 +11990,11 @@ fn astalign(c: *checker, t: *node) i64 = { }; return m; }; - if (k == nkind.N_TSTRUCT) { + if (k == syntax.nkind.N_TSTRUCT) { let m: i64 = 1i64; - let f: *node = t.list; + let f: *syntax.node = t.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { let fa: i64 = astalign(c, f.lhs); if (fa > m) { m = fa; }; }; @@ -12002,17 +12002,17 @@ fn astalign(c: *checker, t: *node) i64 = { }; return m; }; - if (k == nkind.N_TENUM) { + if (k == syntax.nkind.N_TENUM) { if (t.lhs != nil) { return astalign(c, t.lhs); }; return 4i64; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; - if (streq(nm, "void") || streq(nm, "bool") || streq(nm, "i8") || streq(nm, "u8")) { return 1i64; }; - if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; }; - if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; }; - if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64") || streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr") || streq(nm, "size") || streq(nm, "str")) { return 8i64; }; - let resolved: *node = resolvealias(c, t); + if (syntax.streq(nm, "void") || syntax.streq(nm, "bool") || syntax.streq(nm, "i8") || syntax.streq(nm, "u8")) { return 1i64; }; + if (syntax.streq(nm, "i16") || syntax.streq(nm, "u16")) { return 2i64; }; + if (syntax.streq(nm, "i32") || syntax.streq(nm, "u32") || syntax.streq(nm, "f32") || syntax.streq(nm, "rune")) { return 4i64; }; + if (syntax.streq(nm, "i64") || syntax.streq(nm, "u64") || syntax.streq(nm, "f64") || syntax.streq(nm, "int") || syntax.streq(nm, "uint") || syntax.streq(nm, "uintptr") || syntax.streq(nm, "size") || syntax.streq(nm, "str")) { return 8i64; }; + let resolved: *syntax.node = resolvealias(c, t); if (resolved != nil && resolved != t) { return astalign(c, resolved); }; @@ -12020,38 +12020,38 @@ fn astalign(c: *checker, t: *node) i64 = { return 1i64; }; -fn astsize(c: *checker, t: *node) i64 = { +fn astsize(c: *checker, t: *syntax.node) i64 = { if (t == nil) { return 0i64; }; - let k: nkind = t.kind; - if (k == nkind.N_TBANG) { return astsize(c, t.lhs); }; - if (k == nkind.N_TPTR) { return 8i64; }; - if (k == nkind.N_TSLICE) { return tyslicesize(); }; - if (k == nkind.N_TCHAN) { return 8i64; }; - if (k == nkind.N_TFN) { return 8i64; }; - if (k == nkind.N_TARRAY) { + let k: syntax.nkind = t.kind; + if (k == syntax.nkind.N_TBANG) { return astsize(c, t.lhs); }; + if (k == syntax.nkind.N_TPTR) { return 8i64; }; + if (k == syntax.nkind.N_TSLICE) { return tyslicesize(); }; + if (k == syntax.nkind.N_TCHAN) { return 8i64; }; + if (k == syntax.nkind.N_TFN) { return 8i64; }; + if (k == syntax.nkind.N_TARRAY) { // #141: a def-dimensioned field array sized to 0 here, so the // struct loop (off += astsize(field)) overlapped the next // field; arrayelen folds the def. let elen: i64 = arrayelen(c, t.rhs): i64; return astsize(c, t.lhs) * elen; }; - if (k == nkind.N_TTUPLE) { + if (k == syntax.nkind.N_TTUPLE) { // Route through the type table, NOT a packed element-sum: // slot layout is the tuple SSoT (C-t0, user-ratified) and // tupleelemslot is its one wwstage answer. The packed walk // this replaces was a C-t0 escape — size((u32,u32)) folded // to 8 here while cstage (check.c N_TTUPLE) and the wwstage // type table both said 16 (task #22 commit 0). - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { return ti.size: i64; }; return 0i64; }; - if (k == nkind.N_TSTRUCT) { + if (k == syntax.nkind.N_TSTRUCT) { let off: i64 = 0i64; let maxal: i64 = 1i64; - let f: *node = t.list; + let f: *syntax.node = t.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { let fa: i64 = astalign(c, f.lhs); if (fa > maxal) { maxal = fa; }; off = (off + fa - 1i64) & ~(fa - 1i64); @@ -12061,7 +12061,7 @@ fn astsize(c: *checker, t: *node) i64 = { }; return (off + maxal - 1i64) & ~(maxal - 1i64); }; - if (k == nkind.N_TTAGGED) { + if (k == syntax.nkind.N_TTAGGED) { // Route through tinfofornode (the tagged-normalization SSoT) // so the size() fold matches cgen's layout AND cstage: the raw // 8+roundup8(max) here ignored never-drop / dedup / single- @@ -12069,19 +12069,19 @@ fn astsize(c: *checker, t: *node) i64 = { // size((i32|never)) 16 not 4 (#1). Mirrors the N_TTUPLE arm // above and cstage size() reading resolve_type(...)->size // (cmd/wcc/check.c:1547-1550). - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { return ti.size: i64; }; return 0i64; }; - if (k == nkind.N_TENUM) { + if (k == syntax.nkind.N_TENUM) { if (t.lhs != nil) { return astsize(c, t.lhs); }; return 4i64; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; let ps: i64 = primtypesize(nm); if (ps >= 0i64) { return ps; }; - let resolved: *node = resolvealias(c, t); + let resolved: *syntax.node = resolvealias(c, t); if (resolved != nil && resolved != t) { return astsize(c, resolved); }; @@ -12103,36 +12103,36 @@ fn astsize(c: *checker, t: *node) i64 = { // require_sized guards that reject unsized aggregates at the type decl // (so the cstage size/align fold only ever sees a leaf opaque); harec // ref/harec/src/check.c:2720, type_store.c:1147 (tuple) / :449 (tagged). -fn astunsized(c: *checker, t: *node) bool = { +fn astunsized(c: *checker, t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return false; }; - let k: nkind = u.kind; - if (k == nkind.N_TNAME) { - if (streq(u.str, "opaque")) { return true; }; + let k: syntax.nkind = u.kind; + if (k == syntax.nkind.N_TNAME) { + if (syntax.streq(u.str, "opaque")) { return true; }; return false; }; - if (k == nkind.N_TARRAY) { return astunsized(c, u.lhs); }; - if (k == nkind.N_TTUPLE) { - let p: *node = u.list; + if (k == syntax.nkind.N_TARRAY) { return astunsized(c, u.lhs); }; + if (k == syntax.nkind.N_TTUPLE) { + let p: *syntax.node = u.list; for (p != nil) { if (astunsized(c, p.lhs)) { return true; }; p = p.next; }; return false; }; - if (k == nkind.N_TSTRUCT) { - let f: *node = u.list; + if (k == syntax.nkind.N_TSTRUCT) { + let f: *syntax.node = u.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { if (astunsized(c, f.lhs)) { return true; }; }; f = f.next; }; return false; }; - if (k == nkind.N_TTAGGED) { - let v: *node = u.list; + if (k == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = u.list; for (v != nil) { if (astunsized(c, v)) { return true; }; v = v.next; @@ -12175,11 +12175,11 @@ fn astunsized(c: *checker, t: *node) bool = { // call use it). The #241 `yield ` fallback (the dominant // match-bind-then-yield idiom, Hare's parseint `case let t => yield t`) // stays, now resolving btype to a tinfo. -fn matchyieldtype(c: *checker, body: *node, bname: str, btype: *node, - nodeout: **node) *tinfo = { +fn matchyieldtype(c: *checker, body: *syntax.node, bname: str, btype: *syntax.node, + nodeout: **syntax.node) *syntax.tinfo = { if (body == nil) { return nil; }; - let k: nkind = body.kind; - if (k == nkind.N_YIELD) { + let k: syntax.nkind = body.kind; + if (k == syntax.nkind.N_YIELD) { if (body.lhs == nil) { return nil; }; if (body.lhs.type_ != nil) { // For the bare-binder idiom `yield `, ALSO surface @@ -12191,40 +12191,40 @@ fn matchyieldtype(c: *checker, body: *node, bname: str, btype: *node, // match idiom in tree, grep-confirmed). btype is the binder's // declared type node, which IS the match's type here; the // cached tinfo returned below equals tinfofornode(btype). - if (body.lhs.kind == nkind.N_IDENT && bname.len > 0 - && streq(body.lhs.str, bname)) { + if (body.lhs.kind == syntax.nkind.N_IDENT && bname.len > 0 + && syntax.streq(body.lhs.str, bname)) { *nodeout = btype; }; - return body.lhs.type_: *tinfo; + return body.lhs.type_: *syntax.tinfo; }; - let t: *node = exprtype(c, body.lhs, nil); + let t: *syntax.node = exprtype(c, body.lhs, nil); if (t != nil) { *nodeout = t; return tinfofornode(c, t); }; - if (body.lhs.kind == nkind.N_IDENT && bname.len > 0 - && streq(body.lhs.str, bname)) { + if (body.lhs.kind == syntax.nkind.N_IDENT && bname.len > 0 + && syntax.streq(body.lhs.str, bname)) { *nodeout = btype; return tinfofornode(c, btype); }; return nil; }; - if (k == nkind.N_MATCH) { return nil; }; - if (k == nkind.N_BLOCK) { - let s: *node = body.list; + if (k == syntax.nkind.N_MATCH) { return nil; }; + if (k == syntax.nkind.N_BLOCK) { + let s: *syntax.node = body.list; for (s != nil) { - let t: *tinfo = matchyieldtype(c, s, bname, btype, nodeout); + let t: *syntax.tinfo = matchyieldtype(c, s, bname, btype, nodeout); if (t != nil) { return t; }; s = s.next; }; return nil; }; - if (k == nkind.N_IF) { - let t: *tinfo = matchyieldtype(c, body.body, bname, btype, nodeout); + if (k == syntax.nkind.N_IF) { + let t: *syntax.tinfo = matchyieldtype(c, body.body, bname, btype, nodeout); if (t != nil) { return t; }; return matchyieldtype(c, body.els, bname, btype, nodeout); }; - if (k == nkind.N_FOR || k == nkind.N_FORRANGE) { + if (k == syntax.nkind.N_FOR || k == syntax.nkind.N_FORRANGE) { return matchyieldtype(c, body.body, bname, btype, nodeout); }; return nil; @@ -12239,13 +12239,13 @@ fn matchyieldtype(c: *checker, body: *node, bname: str, btype: *node, // family mismatch (the catA repro: an int arm vs a str arm) and never an // untyped->concrete promotion (untyped_int vs i32/f64 both land in class 1) // that cstage accepts. The families mirror typeisnum/typeisstr (lib/ww/typ.ww). -fn yieldclass(t: *tinfo) i32 = { - let u: *tinfo = tichase(t); +fn yieldclass(t: *syntax.tinfo) i32 = { + let u: *syntax.tinfo = tichase(t); if (u == nil) { return 0i32; }; - if (typeisnum(u)) { return 1i32; }; - if (typeisstr(u)) { return 2i32; }; - if (u.kind == tykind.TY_BOOL) { return 3i32; }; - if (u.kind == tykind.TY_UNTYPED_BOOL) { return 3i32; }; + if (syntax.typeisnum(u)) { return 1i32; }; + if (syntax.typeisstr(u)) { return 2i32; }; + if (u.kind == syntax.tykind.TY_BOOL) { return 3i32; }; + if (u.kind == syntax.tykind.TY_UNTYPED_BOOL) { return 3i32; }; return 0i32; }; @@ -12254,25 +12254,25 @@ fn yieldclass(t: *tinfo) i32 = { // (for `p.field` where p is *Struct), require N_TSTRUCT, walk fields // honouring per-field alignment, return -1 if the field name is // absent so the caller can flag the error and fold to 0. -fn astoffset(c: *checker, dot: *node) i64 = { +fn astoffset(c: *checker, dot: *syntax.node) i64 = { if (dot == nil) { return -1i64; }; - if (dot.kind != nkind.N_DOT) { return -1i64; }; - let recv: *node = scruttype(c, dot.lhs); + if (dot.kind != syntax.nkind.N_DOT) { return -1i64; }; + let recv: *syntax.node = scruttype(c, dot.lhs); if (recv == nil) { return -1i64; }; - let rtyp: *node = resolvealias(c, unwrapbang(recv)); + let rtyp: *syntax.node = resolvealias(c, unwrapbang(recv)); if (rtyp == nil) { return -1i64; }; - if (rtyp.kind == nkind.N_TPTR) { + if (rtyp.kind == syntax.nkind.N_TPTR) { rtyp = resolvealias(c, unwrapbang(rtyp.lhs)); }; if (rtyp == nil) { return -1i64; }; - if (rtyp.kind != nkind.N_TSTRUCT) { return -1i64; }; + if (rtyp.kind != syntax.nkind.N_TSTRUCT) { return -1i64; }; let off: i64 = 0i64; - let f: *node = rtyp.list; + let f: *syntax.node = rtyp.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { let fa: i64 = astalign(c, f.lhs); off = (off + fa - 1i64) & ~(fa - 1i64); - if (streq(f.str, dot.str)) { return off; }; + if (syntax.streq(f.str, dot.str)) { return off; }; off += astsize(c, f.lhs); }; f = f.next; @@ -12306,8 +12306,8 @@ fn arenau64tos(v: u64) str = { // Used by the #42 size/align/offset intercepts so cgen sees the // folded literal rather than an unresolved call. Mirrors cstage // cmd/wcc/check.c:919-927 / :951-958. -fn foldtointlit(c: *checker, n: *node, v: i64) void = { - n.kind = nkind.N_INTLIT; +fn foldtointlit(c: *checker, n: *syntax.node, v: i64) void = { + n.kind = syntax.nkind.N_INTLIT; n.uval = v: u64; n.str = arenau64tos(v: u64); n.lhs = nil; @@ -12323,23 +12323,23 @@ fn foldtointlit(c: *checker, n: *node, v: i64) void = { // literal — rule 10 lives at the check pass for #88. Returns false on // division by zero or an op outside the constant subset; the caller // maps that to its own diagnostic. -fn foldbinop(op: tkind, a: u64, b: u64, out: *u64) bool = { - if (op == tkind.TK_PLUS) { *out = a + b; return true; }; - if (op == tkind.TK_MINUS) { *out = a - b; return true; }; - if (op == tkind.TK_STAR) { *out = a * b; return true; }; - if (op == tkind.TK_SLASH) { +fn foldbinop(op: syntax.tkind, a: u64, b: u64, out: *u64) bool = { + if (op == syntax.tkind.TK_PLUS) { *out = a + b; return true; }; + if (op == syntax.tkind.TK_MINUS) { *out = a - b; return true; }; + if (op == syntax.tkind.TK_STAR) { *out = a * b; return true; }; + if (op == syntax.tkind.TK_SLASH) { if (b == 0u64) { return false; }; *out = a / b; return true; }; - if (op == tkind.TK_PERCENT) { + if (op == syntax.tkind.TK_PERCENT) { if (b == 0u64) { return false; }; *out = a % b; return true; }; - if (op == tkind.TK_AMP) { *out = a & b; return true; }; - if (op == tkind.TK_PIPE) { *out = a | b; return true; }; - if (op == tkind.TK_CARET) { *out = a ^ b; return true; }; - if (op == tkind.TK_LSHIFT) { *out = a << b; return true; }; - if (op == tkind.TK_RSHIFT) { *out = a >> b; return true; }; + if (op == syntax.tkind.TK_AMP) { *out = a & b; return true; }; + if (op == syntax.tkind.TK_PIPE) { *out = a | b; return true; }; + if (op == syntax.tkind.TK_CARET) { *out = a ^ b; return true; }; + if (op == syntax.tkind.TK_LSHIFT) { *out = a << b; return true; }; + if (op == syntax.tkind.TK_RSHIFT) { *out = a >> b; return true; }; return false; }; @@ -12348,7 +12348,7 @@ fn foldbinop(op: tkind, a: u64, b: u64, out: *u64) bool = { // gates cgen off in main.ww:165, so this fails the build rather than // emitting a missing DATA row silently (rule 7). cstage twin: err() // in cmd/wcc/check.c. -fn deffolderr(c: *checker, n: *node, msg: str) void = { +fn deffolderr(c: *checker, n: *syntax.node, msg: str) void = { cerr(n.file); cerr(": error: "); cerr(msg); @@ -12364,12 +12364,12 @@ fn deffolderr(c: *checker, n: *node, msg: str) void = { // (t.size, rule 13); the 8s are CHAR_BIT and the u64 byte-width, not // type-layout sizes, so they sit outside rule 13's scope. Pure-u64 so // the range check is bit-identical to cstage (rule 10). -fn defcastfits(t: *tinfo, v: u64) bool = { - if (!typeisint(t)) { return true; }; // non-int target: keep value +fn defcastfits(t: *syntax.tinfo, v: u64) bool = { + if (!syntax.typeisint(t)) { return true; }; // non-int target: keep value let w: u64 = t.size; if (w >= 8u64) { return true; }; // 64-bit target: no narrowing let bits: u64 = w * 8u64; - if (typeisunsigned(t)) { return (v >> bits) == 0u64; }; + if (syntax.typeisunsigned(t)) { return (v >> bits) == 0u64; }; // signed: truncate to `bits` then sign-extend; fits iff unchanged let mask: u64 = (1u64 << bits) - 1u64; let sign: u64 = 1u64 << (bits - 1u64); @@ -12396,45 +12396,45 @@ fn defcastfits(t: *tinfo, v: u64) bool = { // `depth` bounds a def->def->def chain; a cycle (def A = B; def B = A, // incl. cross-module) hits the cap and fails loud rather than hanging // (rule 7), mirroring the cgen nsteps>=16 abort precedent. -fn evaldefconst(c: *checker, n: *node, out: *u64, depth: i32) bool = { +fn evaldefconst(c: *checker, n: *syntax.node, out: *u64, depth: i32) bool = { if (n == nil) { return false; }; if (depth >= 16) { deffolderr(c, n, "def value: reference chain too deep (cycle?)"); return false; }; if (foldintliteral(n, out)) { return true; }; - let k: nkind = n.kind; - if (k == nkind.N_BIN) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_BIN) { let a: u64 = 0u64; let b: u64 = 0u64; if (!evaldefconst(c, n.lhs, &a, depth + 1)) { return false; }; if (!evaldefconst(c, n.rhs, &b, depth + 1)) { return false; }; if (foldbinop(n.op, a, b, out)) { return true; }; - if ((n.op == tkind.TK_SLASH || n.op == tkind.TK_PERCENT) && b == 0u64) { + if ((n.op == syntax.tkind.TK_SLASH || n.op == syntax.tkind.TK_PERCENT) && b == 0u64) { deffolderr(c, n, "def value: division by zero"); } else { deffolderr(c, n, "def value: unsupported binary op"); }; return false; }; - if (k == nkind.N_UN) { + if (k == syntax.nkind.N_UN) { // foldintliteral already covers unary-over-leaf; this arm // catches unary over a resolved ref, e.g. `-A`. let v: u64 = 0u64; if (!evaldefconst(c, n.lhs, &v, depth + 1)) { return false; }; - if (n.op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (n.op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (n.op == tkind.TK_PLUS) { *out = v; return true; }; + if (n.op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (n.op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (n.op == syntax.tkind.TK_PLUS) { *out = v; return true; }; deffolderr(c, n, "def value: unsupported unary op"); return false; }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { // n.lhs = value; n.type_ = resolved target (stamped by // exprtype's N_CAST arm during resolvewalk). Strip the cast // keeping the value; a narrowing cast that loses it fails loud. let v: u64 = 0u64; if (!evaldefconst(c, n.lhs, &v, depth + 1)) { return false; }; - let t: *tinfo = (n.type_): *tinfo; + let t: *syntax.tinfo = (n.type_): *syntax.tinfo; if (!defcastfits(t, v)) { deffolderr(c, n, "def value: narrowing cast loses value"); return false; @@ -12442,20 +12442,20 @@ fn evaldefconst(c: *checker, n: *node, out: *u64, depth: i32) bool = { *out = v; return true; }; - if (k == nkind.N_IDENT) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, n.str); + if (k == syntax.nkind.N_IDENT) { + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, n.str); if (s == nil) { return false; }; - if (s.skind != skind.SK_DEF) { return false; }; + if (s.skind != syntax.skind.SK_DEF) { return false; }; if (s.decl == nil) { return false; }; if (s.decl.rhs == nil) { return false; }; return evaldefconst(c, s.decl.rhs, out, depth + 1); }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { if (n.lhs == nil) { return false; }; - if (n.lhs.kind != nkind.N_IDENT) { return false; }; - let s: *sym = scopelookupinmodule(c.cur, modkeyfor(c, n.lhs.str), n.str); + if (n.lhs.kind != syntax.nkind.N_IDENT) { return false; }; + let s: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, n.lhs.str), n.str); if (s == nil) { return false; }; - if (s.skind != skind.SK_DEF) { return false; }; + if (s.skind != syntax.skind.SK_DEF) { return false; }; if (s.decl == nil) { return false; }; if (s.decl.rhs == nil) { return false; }; return evaldefconst(c, s.decl.rhs, out, depth + 1); @@ -12468,10 +12468,10 @@ fn evaldefconst(c: *checker, n: *node, out: *u64, depth: i32) bool = { // width and pass-3 asserttyped see a properly-typed literal leaf. Lets // cgen's existing emitdefconstants lay down the row with no codegen // change (#88). Shape mirrors foldtointlit (the #42 stamp). -fn stampintlit(n: *node, v: u64) void = { - n.kind = nkind.N_INTLIT; +fn stampintlit(n: *syntax.node, v: u64) void = { + n.kind = syntax.nkind.N_INTLIT; n.uval = v; - n.op = tkind.TK_NONE; + n.op = syntax.tkind.TK_NONE; n.str = arenau64tos(v); n.lhs = nil; n.rhs = nil; @@ -12493,9 +12493,9 @@ fn stampintlit(n: *node, v: u64) void = { // SSoT), so every N_TARRAY length reader routes here to fold the dim // identically — astsize (struct layout), tinfofornode (canonical // tinfo), checkarrlitfits (count gate). -fn arrayelen(c: *checker, rhs: *node) u64 = { +fn arrayelen(c: *checker, rhs: *syntax.node) u64 = { if (rhs == nil) { return 0u64; }; - if (rhs.kind == nkind.N_INTLIT) { return rhs.uval; }; + if (rhs.kind == syntax.nkind.N_INTLIT) { return rhs.uval; }; let v: u64 = 0u64; if (evaldefconst(c, rhs, &v, 0)) { return v; }; return 0u64; @@ -12524,33 +12524,33 @@ fn arrayelen(c: *checker, rhs: *node) u64 = { // practice — harec accepts the same shape without memoisation per // resolve_enum_field's wrap_resolver chain // (ref/harec/src/check.c:4438) — so the quadratic is harmless. -fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = { +fn enumvalfold(body: *syntax.node, until: *syntax.node, e: *syntax.node, out: *u64) bool = { if (e == nil) { return false; }; - let k: nkind = e.kind; - if (k == nkind.N_INTLIT) { *out = e.uval; return true; }; - if (k == nkind.N_RUNELIT) { *out = e.uval; return true; }; - if (k == nkind.N_TRUE) { *out = 1u64; return true; }; - if (k == nkind.N_FALSE) { *out = 0u64; return true; }; - if (k == nkind.N_NIL) { *out = 0u64; return true; }; - if (k == nkind.N_UN) { + let k: syntax.nkind = e.kind; + if (k == syntax.nkind.N_INTLIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_RUNELIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_TRUE) { *out = 1u64; return true; }; + if (k == syntax.nkind.N_FALSE) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_NIL) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_UN) { let v: u64 = 0u64; if (!enumvalfold(body, until, e.lhs, &v)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (op == tkind.TK_PLUS) { *out = v; return true; }; + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (op == syntax.tkind.TK_PLUS) { *out = v; return true; }; return false; }; - if (k == nkind.N_BIN) { + if (k == syntax.nkind.N_BIN) { let a: u64 = 0u64; let b: u64 = 0u64; if (!enumvalfold(body, until, e.lhs, &a)) { return false; }; if (!enumvalfold(body, until, e.rhs, &b)) { return false; }; return foldbinop(e.op, a, b, out); }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { let prev: u64 = (-1i64): u64; - let m: *node = body.list; + let m: *syntax.node = body.list; for (m != nil && m != until) { let val: u64 = 0u64; if (m.lhs == nil) { @@ -12559,7 +12559,7 @@ fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = { if (!enumvalfold(body, m, m.lhs, &val)) { return false; }; }; prev = val; - if (streq(m.str, e.str)) { *out = val; return true; }; + if (syntax.streq(m.str, e.str)) { *out = val; return true; }; m = m.next; }; return false; @@ -12580,13 +12580,13 @@ fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = { // mirror that. The value itself is folded to a constant at every use // site (enumvalfold) and at codegen (cgen.ww enumevalmember), so cgen // never reads these node types — this stamp is checker metadata only. -fn stampenumvals(c: *checker, n: *node) void = { - let under: *tinfo = c.tc.tyi32; +fn stampenumvals(c: *checker, n: *syntax.node) void = { + let under: *syntax.tinfo = c.tc.tyi32; if (n.lhs != nil) { - let s: *tinfo = tinfofornode(c, n.lhs); + let s: *syntax.tinfo = tinfofornode(c, n.lhs); if (s != nil) { under = s; }; }; - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { stampnilexpr(m.lhs, under); m = m.next; @@ -12597,7 +12597,7 @@ fn stampenumvals(c: *checker, n: *node) void = { // `ti`. lhs/rhs cover the enum constexpr grammar enumvalfold accepts // (literals, unary, binary, sibling backref); non-nil nodes keep the // type exprtype already derived. -fn stampnilexpr(n: *node, ti: *tinfo) void = { +fn stampnilexpr(n: *syntax.node, ti: *syntax.tinfo) void = { if (n == nil) { return; }; if (n.type_ == nil) { n.type_ = ti: *void; }; stampnilexpr(n.lhs, ti); @@ -12614,36 +12614,36 @@ fn stampnilexpr(n: *node, ti: *tinfo) void = { // 8; void contributes 0 (never appears in tuples emitted by user // code, but kept for SSoT symmetry with cgen's N_TNAME-"void" // fallback arm). -fn tupleelemslot(pt: *tinfo) u64 = { +fn tupleelemslot(pt: *syntax.tinfo) u64 = { if (pt == nil) { return 8u64; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. - let t: *tinfo = pt; + let t: *syntax.tinfo = pt; t = tichase(t); if (t == nil) { return 8u64; }; - let pk: tykind = t.kind; - if (pk == tykind.TY_VOID) { return 0u64; }; - if (pk == tykind.TY_STR) { return t.size; }; - if (pk == tykind.TY_SLICE) { return t.size; }; + let pk: syntax.tykind = t.kind; + if (pk == syntax.tykind.TY_VOID) { return 0u64; }; + if (pk == syntax.tykind.TY_STR) { return t.size; }; + if (pk == syntax.tykind.TY_SLICE) { return t.size; }; // #22 (user-ratified 2026-06-04): slot = roundup8(size(elem)) — 8B // is a FLOOR, not a ceiling. (str,str)=48B predates this; tagged // was the one truncated >8B kind (the #237 fieldslotsize-missing- // TY_TUPLE precedent: fieldslotsize below already carried this // arm). Cstage twin: check.c N_TTUPLE; cgen accessor: tuple_eslot // / tupeslot. - if (pk == tykind.TY_TAGGED) { return (t.size + 7u64) & ~7u64; }; - if (pk == tykind.TY_PTR || pk == tykind.TY_FN || - pk == tykind.TY_CHAN || pk == tykind.TY_I64 || - pk == tykind.TY_U64 || pk == tykind.TY_INT || - pk == tykind.TY_UINT || pk == tykind.TY_UINTPTR || - pk == tykind.TY_SIZE || pk == tykind.TY_F64) { return 8u64; }; - if (pk == tykind.TY_BOOL || pk == tykind.TY_RUNE || - pk == tykind.TY_I8 || pk == tykind.TY_I16 || - pk == tykind.TY_I32 || pk == tykind.TY_U8 || - pk == tykind.TY_U16 || pk == tykind.TY_U32 || - pk == tykind.TY_F32 || pk == tykind.TY_ENUM) { return 8u64; }; + if (pk == syntax.tykind.TY_TAGGED) { return (t.size + 7u64) & ~7u64; }; + if (pk == syntax.tykind.TY_PTR || pk == syntax.tykind.TY_FN || + pk == syntax.tykind.TY_CHAN || pk == syntax.tykind.TY_I64 || + pk == syntax.tykind.TY_U64 || pk == syntax.tykind.TY_INT || + pk == syntax.tykind.TY_UINT || pk == syntax.tykind.TY_UINTPTR || + pk == syntax.tykind.TY_SIZE || pk == syntax.tykind.TY_F64) { return 8u64; }; + if (pk == syntax.tykind.TY_BOOL || pk == syntax.tykind.TY_RUNE || + pk == syntax.tykind.TY_I8 || pk == syntax.tykind.TY_I16 || + pk == syntax.tykind.TY_I32 || pk == syntax.tykind.TY_U8 || + pk == syntax.tykind.TY_U16 || pk == syntax.tykind.TY_U32 || + pk == syntax.tykind.TY_F32 || pk == syntax.tykind.TY_ENUM) { return 8u64; }; // Composite — one 8B eightbyte, NOT t.slotsize: cgen's cursor // transport strides `wide ? size : 8` at every tuple site (both // stages), so a composite element rides one register word today. @@ -12660,44 +12660,44 @@ fn tupleelemslot(pt: *tinfo) u64 = { // slot-padded total (si.totsize equivalent); primitives keep their // natural width (struct interior packing is unaffected by stack-slot // pad-to-8); arrays use their slot-padded element-stride * elen. -fn fieldslotsize(ft: *tinfo) u64 = { +fn fieldslotsize(ft: *syntax.tinfo) u64 = { if (ft == nil) { return 8u64; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. - let t: *tinfo = ft; + let t: *syntax.tinfo = ft; t = tichase(t); if (t == nil) { return 8u64; }; - let fk: tykind = t.kind; - if (fk == tykind.TY_STRUCT) { return t.slotsize; }; - if (fk == tykind.TY_ARRAY) { return t.slotsize; }; - if (fk == tykind.TY_TAGGED) { return t.size; }; + let fk: syntax.tykind = t.kind; + if (fk == syntax.tykind.TY_STRUCT) { return t.slotsize; }; + if (fk == syntax.tykind.TY_ARRAY) { return t.slotsize; }; + if (fk == syntax.tykind.TY_TAGGED) { return t.size; }; // str / slice read t.size so the typ.ww SSoT seed is the single // source for #1 (str→24) / #34 (slice graduation) — no hardcoded // literal here to drift. - if (fk == tykind.TY_SLICE) { return t.size; }; - if (fk == tykind.TY_PTR || fk == tykind.TY_FN || - fk == tykind.TY_CHAN) { return 8u64; }; - if (fk == tykind.TY_STR) { return t.size; }; + if (fk == syntax.tykind.TY_SLICE) { return t.size; }; + if (fk == syntax.tykind.TY_PTR || fk == syntax.tykind.TY_FN || + fk == syntax.tykind.TY_CHAN) { return 8u64; }; + if (fk == syntax.tykind.TY_STR) { return t.size; }; // #237: a tuple-typed struct field carries its own slot total (the // per-element slot sum stamped at the N_TTUPLE arm above — slices at // 24 each). Without this it fell to the 8B default below, undersizing // the enclosing struct's slotsize (size stayed correct), so a `let s:S` // slot was too small — a silent stack-corrupting miscompile. Aligns // with cgenutil.ww fieldsize, which already returns the tuple's size. - if (fk == tykind.TY_TUPLE) { return t.slotsize; }; + if (fk == syntax.tykind.TY_TUPLE) { return t.slotsize; }; // Primitives keep natural width inside structs (matches // cgenutil fieldsize: primsize, not pad-to-8). - if (fk == tykind.TY_BOOL || fk == tykind.TY_RUNE || - fk == tykind.TY_I8 || fk == tykind.TY_I16 || - fk == tykind.TY_I32 || fk == tykind.TY_I64 || - fk == tykind.TY_U8 || fk == tykind.TY_U16 || - fk == tykind.TY_U32 || fk == tykind.TY_U64 || - fk == tykind.TY_INT || fk == tykind.TY_UINT || - fk == tykind.TY_UINTPTR || fk == tykind.TY_SIZE || - fk == tykind.TY_F32 || fk == tykind.TY_F64 || - fk == tykind.TY_ENUM) { return t.size; }; + if (fk == syntax.tykind.TY_BOOL || fk == syntax.tykind.TY_RUNE || + fk == syntax.tykind.TY_I8 || fk == syntax.tykind.TY_I16 || + fk == syntax.tykind.TY_I32 || fk == syntax.tykind.TY_I64 || + fk == syntax.tykind.TY_U8 || fk == syntax.tykind.TY_U16 || + fk == syntax.tykind.TY_U32 || fk == syntax.tykind.TY_U64 || + fk == syntax.tykind.TY_INT || fk == syntax.tykind.TY_UINT || + fk == syntax.tykind.TY_UINTPTR || fk == syntax.tykind.TY_SIZE || + fk == syntax.tykind.TY_F32 || fk == syntax.tykind.TY_F64 || + fk == syntax.tykind.TY_ENUM) { return t.size; }; return 8u64; }; @@ -12722,53 +12722,53 @@ fn fieldslotsize(ft: *tinfo) u64 = { // typeeq's contract (TY_NAMED → only same ptr, else structural; lib/ww/ // typ.ww:581). nil guards match variant_match's `a==NULL||b==NULL → 0` // so two unresolved variants never collapse. -fn variantpresent(head: *tparam, vt: *tinfo) bool = { +fn variantpresent(head: *syntax.tparam, vt: *syntax.tinfo) bool = { if (vt == nil) { return false; }; - let p: *tparam = head; + let p: *syntax.tparam = head; for (p != nil) { if (p.type_ != nil) { - if (typeeq(p.type_, vt)) { return true; }; + if (syntax.typeeq(p.type_, vt)) { return true; }; }; p = p.tnext; }; return false; }; -fn tinfofornode(c: *checker, n: *node) *tinfo = { +fn tinfofornode(c: *checker, n: *syntax.node) *syntax.tinfo = { if (n == nil) { return nil; }; - let cached: *tinfo = tinfocachelookup(c.tc, n); + let cached: *syntax.tinfo = syntax.tinfocachelookup(c.tc, n); if (cached != nil) { return cached; }; - let r: *tinfo = nil; - let k: nkind = n.kind; + let r: *syntax.tinfo = nil; + let k: syntax.nkind = n.kind; switch (k) { - case nkind.N_TNAME: + case syntax.nkind.N_TNAME: let nm: str = n.str; - if (streq(nm, "void")) { r = c.tc.tyvoid; }; - if (streq(nm, "bool")) { r = c.tc.tybool; }; - if (streq(nm, "rune")) { r = c.tc.tyrune; }; - if (streq(nm, "i8")) { r = c.tc.tyi8; }; - if (streq(nm, "i16")) { r = c.tc.tyi16; }; - if (streq(nm, "i32")) { r = c.tc.tyi32; }; - if (streq(nm, "i64")) { r = c.tc.tyi64; }; - if (streq(nm, "u8")) { r = c.tc.tyu8; }; - if (streq(nm, "u16")) { r = c.tc.tyu16; }; - if (streq(nm, "u32")) { r = c.tc.tyu32; }; - if (streq(nm, "u64")) { r = c.tc.tyu64; }; - if (streq(nm, "int")) { r = c.tc.tyint; }; - if (streq(nm, "uint")) { r = c.tc.tyuint; }; - if (streq(nm, "uintptr")) { r = c.tc.tyuintptr; }; - if (streq(nm, "size")) { r = c.tc.tysize; }; // #85 fold-2 - if (streq(nm, "opaque")) { r = c.tc.tyopaque; }; // #108(a) - if (streq(nm, "f32")) { r = c.tc.tyf32; }; - if (streq(nm, "f64")) { r = c.tc.tyf64; }; - if (streq(nm, "str")) { r = c.tc.tystr; }; - if (streq(nm, "never")) { r = c.tc.tynever; }; - if (streq(nm, "untyped_int")) { r = c.tc.tyuntypedint; }; - if (streq(nm, "untyped_float")) { r = c.tc.tyuntypedfloat; }; - if (streq(nm, "untyped_str")) { r = c.tc.tyuntypedstr; }; - if (streq(nm, "untyped_rune")) { r = c.tc.tyuntypedrune; }; - if (streq(nm, "untyped_bool")) { r = c.tc.tyuntypedbool; }; - if (streq(nm, "untyped_nil")) { r = c.tc.tyuntypednil; }; + if (syntax.streq(nm, "void")) { r = c.tc.tyvoid; }; + if (syntax.streq(nm, "bool")) { r = c.tc.tybool; }; + if (syntax.streq(nm, "rune")) { r = c.tc.tyrune; }; + if (syntax.streq(nm, "i8")) { r = c.tc.tyi8; }; + if (syntax.streq(nm, "i16")) { r = c.tc.tyi16; }; + if (syntax.streq(nm, "i32")) { r = c.tc.tyi32; }; + if (syntax.streq(nm, "i64")) { r = c.tc.tyi64; }; + if (syntax.streq(nm, "u8")) { r = c.tc.tyu8; }; + if (syntax.streq(nm, "u16")) { r = c.tc.tyu16; }; + if (syntax.streq(nm, "u32")) { r = c.tc.tyu32; }; + if (syntax.streq(nm, "u64")) { r = c.tc.tyu64; }; + if (syntax.streq(nm, "int")) { r = c.tc.tyint; }; + if (syntax.streq(nm, "uint")) { r = c.tc.tyuint; }; + if (syntax.streq(nm, "uintptr")) { r = c.tc.tyuintptr; }; + if (syntax.streq(nm, "size")) { r = c.tc.tysize; }; // #85 fold-2 + if (syntax.streq(nm, "opaque")) { r = c.tc.tyopaque; }; // #108(a) + if (syntax.streq(nm, "f32")) { r = c.tc.tyf32; }; + if (syntax.streq(nm, "f64")) { r = c.tc.tyf64; }; + if (syntax.streq(nm, "str")) { r = c.tc.tystr; }; + if (syntax.streq(nm, "never")) { r = c.tc.tynever; }; + if (syntax.streq(nm, "untyped_int")) { r = c.tc.tyuntypedint; }; + if (syntax.streq(nm, "untyped_float")) { r = c.tc.tyuntypedfloat; }; + if (syntax.streq(nm, "untyped_str")) { r = c.tc.tyuntypedstr; }; + if (syntax.streq(nm, "untyped_rune")) { r = c.tc.tyuntypedrune; }; + if (syntax.streq(nm, "untyped_bool")) { r = c.tc.tyuntypedbool; }; + if (syntax.streq(nm, "untyped_nil")) { r = c.tc.tyuntypednil; }; if (r == nil) { // #64 Phase-N step 2 (THE FLIP): build a per-decl // TY_NAMED wrapper instead of collapsing the alias to @@ -12782,12 +12782,12 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // (cmd/wcc/check.c:1900-1929): pass1 creates the NAMED, // pass2 patches under/size off resolve_type(d->lhs), // where resolve_typename returns the inner NAMED. - let s: *sym = aliassym(c, n); + let s: *syntax.sym = aliassym(c, n); if (s != nil) { if (s.type_ != nil) { r = s.type_; } else { - let body: *node = nil; + let body: *syntax.node = nil; if (s.decl != nil) { body = unwrapbang(s.decl.lhs); }; @@ -12801,10 +12801,10 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // (check.c:1909/1917) ahead of pass2's // under patch, and A.2's TSTRUCT/TFN/ // TTAGGED tinfocachebind cycle-break. - let named: *tinfo = typenamed(s.name, nil); + let named: *syntax.tinfo = syntax.typenamed(s.name, nil); s.type_ = named; named.resolving = 1; - let under: *tinfo = tinfofornode(c, body); + let under: *syntax.tinfo = tinfofornode(c, body); // #62/#69: alias-root cycle (`type a = b; // type b = a` / `type a = a`) — checked // BEFORE clearing the flag so self-aliases @@ -12831,7 +12831,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { }; }; }; - case nkind.N_TBANG: + case syntax.nkind.N_TBANG: // #61 audit §1.8: `!T` propagates the inner shape; cstage's // resolve_type sets ty->iserror on the wrapper but no wwstage // cgen reader consumes it yet, so A.1 drops the flag and @@ -12839,13 +12839,13 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // unwrapbang pre-walk; graduate alongside the first cgen // site that needs iserror discrimination. r = tinfofornode(c, n.lhs); - case nkind.N_TPTR: - r = typeptr(tinfofornode(c, n.lhs)); - case nkind.N_TSLICE: - r = typeslice(tinfofornode(c, n.lhs)); - case nkind.N_TCHAN: - r = typechan(tinfofornode(c, n.lhs)); - case nkind.N_TARRAY: + case syntax.nkind.N_TPTR: + r = syntax.typeptr(tinfofornode(c, n.lhs)); + case syntax.nkind.N_TSLICE: + r = syntax.typeslice(tinfofornode(c, n.lhs)); + case syntax.nkind.N_TCHAN: + r = syntax.typechan(tinfofornode(c, n.lhs)); + case syntax.nkind.N_TARRAY: // Cstage cmd/wcc/check.c:314-326: length must be an integer // literal (`[_]T` keeps alen=0 as the inferred-length sentinel // patched at letslotsize-time). @@ -12868,7 +12868,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // fold SSoT for astsize's later size() read. let elen: u64 = 0u64; // #141: fold def-dim if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_INTLIT) { + if (n.rhs.kind == syntax.nkind.N_INTLIT) { elen = n.rhs.uval; } else { let v: u64 = 0u64; @@ -12881,36 +12881,36 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { }; }; }; - let sub: *tinfo = tinfofornode(c, n.lhs); + let sub: *syntax.tinfo = tinfofornode(c, n.lhs); // #62/#69: `type a = [2]a` value cycle — loud, cstage twin. if (circularnamed(c, sub, n)) { sub = c.tc.tyerr; }; - r = typearray(sub, elen); - case nkind.N_TFN: + r = syntax.typearray(sub, elen); + case syntax.nkind.N_TFN: // Cstage cmd/wcc/check.c:437-466: function types are 8B / 8B // (call-target pointer shape). Pre-bind before recursing into // the return type so a recursive `type F = fn() F` self-ref // doesn't spin (cycle-break mirror of the TSTRUCT/TTAGGED // pattern below). - r = newtype(tykind.TY_FN); + r = syntax.newtype(syntax.tykind.TY_FN); r.size = 8u64; r.align = 8u64; r.slotsize = 8u64; - tinfocachebind(c.tc, n, r); + syntax.tinfocachebind(c.tc, n, r); r.ret = tinfofornode(c, n.lhs); - case nkind.N_TENUM: + case syntax.nkind.N_TENUM: // Cstage cmd/wcc/check.c:529-542: storage type's size/align // (default i32 = 4B/4B). Cgen's slotsize-TENUM fallback pads // to 8B per its stack-slot contract; tinfo.size carries the // raw storage width so size(EnumT) folds to the correct value. - r = newtype(tykind.TY_ENUM); - let storage: *tinfo = nil; + r = syntax.newtype(syntax.tykind.TY_ENUM); + let storage: *syntax.tinfo = nil; if (n.lhs != nil) { storage = tinfofornode(c, n.lhs); }; if (storage == nil) { storage = c.tc.tyi32; }; r.sub = storage; r.size = storage.size; r.align = storage.align; r.slotsize = storage.size; - case nkind.N_TTUPLE: + case syntax.nkind.N_TTUPLE: // Slot layout is the tuple SSoT (tuple arc C-t0, user-ratified): // ti.size = ti.slotsize = per-element slot sum (tupleelemslot — // a str/slice its header, everything else one 8B eightbyte), @@ -12925,8 +12925,8 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // cgen strode 8B slots — the checker-says-8/cgen-does-16 split // behind the packed-tuple miscompile family (#32/#33/#48). // Pre-bind for cycle protection (recursive tuple shapes). - r = newtype(tykind.TY_TUPLE); - tinfocachebind(c.tc, n, r); + r = syntax.newtype(syntax.tykind.TY_TUPLE); + syntax.tinfocachebind(c.tc, n, r); // #57 A.6.3i-phase-1: populate r.tupleelems as a ttupleelem // linked list (head=positional 0) in lock-step with the // size/align accumulator. Harec analog ref/harec/src/type_ @@ -12940,28 +12940,28 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // A.6.3f-a) for the head/tail append pattern. Offsets are // slot-cumulative (C-t0), distinct from harec's // add_padding(&offset, memb.align) at type_store.c:561. - let teh: *ttupleelem = nil; - let tet: *ttupleelem = nil; + let teh: *syntax.ttupleelem = nil; + let tet: *syntax.ttupleelem = nil; let slottotal: u64 = 0u64; let maxal: u64 = 1u64; - let p: *node = n.list; + let p: *syntax.node = n.list; for (p != nil) { - let pt: *tinfo = tinfofornode(c, p.lhs); + let pt: *syntax.tinfo = tinfofornode(c, p.lhs); // #62/#69: tuple-member value cycle — loud, cstage twin. if (circularnamed(c, pt, p.lhs)) { pt = c.tc.tyerr; }; // #24: a composite element (array/struct/nested tuple // >8B) cannot ride the 8B cursor slot — the #60 layout // drops it on construction and segvs on t.N[i] read. // Reject until #60/DISP-A inlines it; cstage twin. - let cu: *tinfo = tichase(pt); - if (cu != nil && (cu.kind == tykind.TY_ARRAY - || cu.kind == tykind.TY_STRUCT - || cu.kind == tykind.TY_TUPLE)) { + let cu: *syntax.tinfo = tichase(pt); + if (cu != nil && (cu.kind == syntax.tykind.TY_ARRAY + || cu.kind == syntax.tykind.TY_STRUCT + || cu.kind == syntax.tykind.TY_TUPLE)) { cerr("error: tuple element must be a scalar, str, slice, or tagged-union (composite element deferred to task #60)\n"); c.errs += 1; pt = c.tc.tyerr; }; - let te: *ttupleelem = alloc(ttupleelem{type_=pt, offset=slottotal, tnext=nil})!; + let te: *syntax.ttupleelem = alloc(syntax.ttupleelem{type_=pt, offset=slottotal, tnext=nil})!; if (teh == nil) { teh = te; } else { tet.tnext = te; }; tet = te; if (pt != nil) { @@ -12974,7 +12974,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { r.size = slottotal; r.align = maxal; r.slotsize = slottotal; - case nkind.N_TSTRUCT: + case syntax.nkind.N_TSTRUCT: // Cstage cmd/wcc/check.c:468-527: per-field alignment, max // align for the whole record, total rounded up to alignment. // Anonymous-embed promotion is deferred (#13). @@ -12994,8 +12994,8 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // struct; size-derived alignment; final round to 8). That // slot total lands in ti.slotsize so the cgen fast-path can // graduate TY_STRUCT off the AST walker. - r = newtype(tykind.TY_STRUCT); - tinfocachebind(c.tc, n, r); + r = syntax.newtype(syntax.tykind.TY_STRUCT); + syntax.tinfocachebind(c.tc, n, r); // #57 A.6.3i-phase-1: populate r.fields as a tfield linked // list (head=first declared field) in lock-step with the // natural-layout offset accumulator. Mirrors cstage cmd/wcc/ @@ -13006,15 +13006,15 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // ref/harec/src/type_store.c:314-347 struct_init_from_atype. // Anonymous-embed promotion not populated here (#13 per // the cstage cite at check.ww:1263). - let fh: *tfield = nil; - let ft_: *tfield = nil; + let fh: *syntax.tfield = nil; + let ft_: *syntax.tfield = nil; let off: u64 = 0u64; let maxalign: u64 = 1u64; let soff: u64 = 0u64; - let f: *node = n.list; + let f: *syntax.node = n.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { - let ft: *tinfo = tinfofornode(c, f.lhs); + if (f.kind == syntax.nkind.N_TFIELD) { + let ft: *syntax.tinfo = tinfofornode(c, f.lhs); // #62/#69: struct-field value cycle (`type s1 = // struct { x: s2 }; type s2 = struct { x: s1 }`) // — loud; pre-#62 this stack-overflowed the slot @@ -13026,7 +13026,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { off = (off + ft.align - 1u64) & ~(ft.align - 1u64); }; let fldoff: u64 = off; - let tf: *tfield = alloc(tfield{name=f.str, type_=ft, offset=fldoff, tnext=nil})!; + let tf: *syntax.tfield = alloc(syntax.tfield{name=f.str, type_=ft, offset=fldoff, tnext=nil})!; if (fh == nil) { fh = tf; } else { ft_.tnext = tf; }; ft_ = tf; off += ft.size; @@ -13054,7 +13054,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { soff = (soff + 7u64) & ~7u64; }; r.slotsize = soff; - case nkind.N_TTAGGED: + case syntax.nkind.N_TTAGGED: // THE tagged-union normalization SSoT (astsize/astalign delegate // here). Mirrors cstage resolve_type N_TTAGGED (cmd/wcc/check.c: // 801-882): 8B tag + max(variant) rounded up to 8, AFTER type-set @@ -13067,32 +13067,32 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // and (i32|i32|str) numbered str's tag 2 not 1 (cgen reads the // deduped ti.params). Pre-bind for cycle protection (recursive // sum-type shapes through NAMED variants). - r = newtype(tykind.TY_TAGGED); - tinfocachebind(c.tc, n, r); + r = syntax.newtype(syntax.tykind.TY_TAGGED); + syntax.tinfocachebind(c.tc, n, r); // #50 / A.6.3f phase 1: populate ti.params as a tparam linked // list (head=first surviving variant). #61a: flatten `...inner` // tagged spreads into the chain and stamp each variant's iserror. // Same shared Tparam shape ww reuses across struct-fields / // tuple-fields / fn-params / tagged-variants (sea-of-stars per // rule 12). - let head: *tparam = nil; - let tail: *tparam = nil; + let head: *syntax.tparam = nil; + let tail: *syntax.tparam = nil; let maxsz: u64 = 0u64; let al: u64 = 8u64; let nv: i32 = 0; - let v: *node = n.list; + let v: *syntax.node = n.list; for (v != nil) { - let vt: *tinfo = tinfofornode(c, v); + let vt: *syntax.tinfo = tinfofornode(c, v); // #62/#69: union-member value cycle — loud, cstage twin. if (circularnamed(c, vt, v)) { vt = c.tc.tyerr; }; - let isspread: bool = (v.op == tkind.TK_ELLIPSIS); - let vu: *tinfo = vt; + let isspread: bool = (v.op == syntax.tkind.TK_ELLIPSIS); + let vu: *syntax.tinfo = vt; // Full chase (F2a batch-4 c3-B1): the single peel left a // 2-level-alias inner union a SURFACE member — the box // sized off the inner union's own header, not its // spliced variants (cs twin check.c:755 chases). if (isspread) { vu = tichase(vu); }; - if (isspread && vu != nil && vu.kind == tykind.TY_TAGGED) { + if (isspread && vu != nil && vu.kind == syntax.tykind.TY_TAGGED) { // #209: a `...inner` spread's PAYLOAD is its // members, not the whole inner union — size/align // off each surviving spliced member (cstage check.c: @@ -13101,10 +13101,10 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // and desync the `field` slot from cstage's). Spliced // variants carry the inner union's already-stamped // iserror; no re-derivation. - let src: *tparam = vu.params; + let src: *syntax.tparam = vu.params; for (src != nil) { - let st: *tinfo = src.type_; - if (st != nil && st.kind == tykind.TY_NEVER) { + let st: *syntax.tinfo = src.type_; + if (st != nil && st.kind == syntax.tykind.TY_NEVER) { src = src.tnext; continue; }; if (variantpresent(head, st)) { @@ -13114,14 +13114,14 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { if (st.size > maxsz) { maxsz = st.size; }; if (st.align > al) { al = st.align; }; }; - let tp: *tparam = alloc(tparam{name="", type_=src.type_, iserror=src.iserror, tnext=nil})!; + let tp: *syntax.tparam = alloc(syntax.tparam{name="", type_=src.type_, iserror=src.iserror, tnext=nil})!; if (head == nil) { head = tp; } else { tail.tnext = tp; }; tail = tp; nv += 1; src = src.tnext; }; } else { - if (vt != nil && vt.kind == tykind.TY_NEVER) { + if (vt != nil && vt.kind == syntax.tykind.TY_NEVER) { v = v.next; continue; }; if (variantpresent(head, vt)) { @@ -13132,7 +13132,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { if (vt.align > al) { al = vt.align; }; }; let ve: bool = varianterr(c, v); - let tp: *tparam = alloc(tparam{name="", type_=vt, iserror=ve, tnext=nil})!; + let tp: *syntax.tparam = alloc(syntax.tparam{name="", type_=vt, iserror=ve, tnext=nil})!; if (head == nil) { head = tp; } else { tail.tnext = tp; }; tail = tp; nv += 1; @@ -13156,12 +13156,12 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // the tinfo layer; pre-#1 it AST-keyed n.list instead. let isnull: bool = false; if (nv == 2) { - let pa: *tparam = head; - let pb: *tparam = head.tnext; - let aptr: bool = (pa.type_ != nil && pa.type_.kind == tykind.TY_PTR); - let bptr: bool = (pb.type_ != nil && pb.type_.kind == tykind.TY_PTR); - let avoid: bool = (pa.type_ != nil && pa.type_.kind == tykind.TY_VOID && !pa.iserror); - let bvoid: bool = (pb.type_ != nil && pb.type_.kind == tykind.TY_VOID && !pb.iserror); + let pa: *syntax.tparam = head; + let pb: *syntax.tparam = head.tnext; + let aptr: bool = (pa.type_ != nil && pa.type_.kind == syntax.tykind.TY_PTR); + let bptr: bool = (pb.type_ != nil && pb.type_.kind == syntax.tykind.TY_PTR); + let avoid: bool = (pa.type_ != nil && pa.type_.kind == syntax.tykind.TY_VOID && !pa.iserror); + let bvoid: bool = (pb.type_ != nil && pb.type_.kind == syntax.tykind.TY_VOID && !pb.iserror); if (aptr) { if (bvoid) { isnull = true; }; }; if (avoid) { if (bptr) { isnull = true; }; }; }; @@ -13184,7 +13184,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // chan paths which already populate slotsize, plus TBANG which // inherits the inner's tinfo unchanged). if (r.slotsize == 0u64) { r.slotsize = r.size; }; - tinfocachebind(c.tc, n, r); + syntax.tinfocachebind(c.tc, n, r); }; return r; }; @@ -13201,7 +13201,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { // with sym.decl == nil; #19 retires these as dedicated AST kinds). // Propagation, not silent gap — asserttyped gates those idents at the // consumer layer, so a nil operand never reaches the loud reject below. -fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { +fn unifyarith(c: *checker, e: *syntax.node, ltn: *syntax.node, rtn: *syntax.node) *syntax.node = { let lu: bool = isuntypedint(ltn) || isuntypedfloat(ltn); let ru: bool = isuntypedint(rtn) || isuntypedfloat(rtn); if (lu && ru) { @@ -13225,8 +13225,8 @@ fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { // above. Mirror cstage here off the operand node so the rune-literal / // integer mix stays valid (35 selfhost+lib sites) under the #26 reject. if (e != nil) { - let lr: bool = e.lhs != nil && e.lhs.kind == nkind.N_RUNELIT; - let rr: bool = e.rhs != nil && e.rhs.kind == nkind.N_RUNELIT; + let lr: bool = e.lhs != nil && e.lhs.kind == syntax.nkind.N_RUNELIT; + let rr: bool = e.rhs != nil && e.rhs.kind == syntax.nkind.N_RUNELIT; if (lr && isinttypeast(rtn)) { return rtn; }; if (rr && isinttypeast(ltn)) { return ltn; }; }; @@ -13241,13 +13241,13 @@ fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { // SK_TYPE too but decl == nil (check.ww:95-112), so aliassym alone // would mis-flag i32 as "named". This decl != nil gate is the wwstage // analog of cstage's `kind == TY_NAMED` (primitives are TY_I32 etc). - let ls: *sym = aliassym(c, unwrapbang(ltn)); - let rs: *sym = aliassym(c, unwrapbang(rtn)); + let ls: *syntax.sym = aliassym(c, unwrapbang(ltn)); + let rs: *syntax.sym = aliassym(c, unwrapbang(rtn)); let la: bool = ls != nil && ls.decl != nil; let ra: bool = rs != nil && rs.decl != nil; if (!(la && ra)) { - let da: *node = resolvealias(c, ltn); - let db: *node = resolvealias(c, rtn); + let da: *syntax.node = resolvealias(c, ltn); + let db: *syntax.node = resolvealias(c, rtn); if (da != nil && db != nil && varianterr(c, ltn) == varianterr(c, rtn) && typeeqast(c, da, db)) { @@ -13278,16 +13278,16 @@ fn unifyarith(c: *checker, e: *node, ltn: *node, rtn: *node) *node = { // f32 off the operands' float-kind, not the node stamp, so a stamped literal // inside an arith-binop / behind a unary minus does NOT narrow there — // binop / unary-minus / assign / call-arg / struct-field wait on #120. -fn coercefloatlit(c: *checker, e: *node, target: *node) void = { +fn coercefloatlit(c: *checker, e: *syntax.node, target: *syntax.node) void = { if (e == nil) { return; }; if (target == nil) { return; }; - let tu: *node = resolvealias(c, unwrapbang(target)); + let tu: *syntax.node = resolvealias(c, unwrapbang(target)); if (tu == nil) { return; }; - if (tu.kind != nkind.N_TNAME) { return; }; - if (!streq(tu.str, "f32")) { return; }; - if (e.kind == nkind.N_FLOATLIT) { - if ((e.type_: *tinfo) == c.tc.tyuntypedfloat) { - let f32t: *node = mktname(c, "f32"); + if (tu.kind != syntax.nkind.N_TNAME) { return; }; + if (!syntax.streq(tu.str, "f32")) { return; }; + if (e.kind == syntax.nkind.N_FLOATLIT) { + if ((e.type_: *syntax.tinfo) == c.tc.tyuntypedfloat) { + let f32t: *syntax.node = mktname(c, "f32"); e.type_ = tinfofornode(c, f32t): *void; }; }; @@ -13315,17 +13315,17 @@ fn coercefloatlit(c: *checker, e: *node, target: *node) void = { // keep harec's per-element range gate via checkarrlitfits's foldint / // defcastfits path (:4634). For a tagged-union target (fnmatch pat_next's // (u8 | star | ...)) return the first integer variant. -fn coercerunelit(c: *checker, e: *node, target: *node) *node = { +fn coercerunelit(c: *checker, e: *syntax.node, target: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - if (e.kind != nkind.N_RUNELIT) { return nil; }; + if (e.kind != syntax.nkind.N_RUNELIT) { return nil; }; if (target == nil) { return nil; }; - let tu: *node = resolvealias(c, unwrapbang(target)); + let tu: *syntax.node = resolvealias(c, unwrapbang(target)); if (tu == nil) { return nil; }; if (isinttypeast(tu)) { return tu; }; - if (tu.kind == nkind.N_TTAGGED) { - let v: *node = tu.list; + if (tu.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = tu.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { if (isinttypeast(vu)) { return vu; }; }; @@ -13340,29 +13340,29 @@ fn coercerunelit(c: *checker, e: *node, target: *node) *node = { // returned by exprtype; ptr arithmetic / bitwise / shifts / comparisons / // logicals all reflect cstage's rules. Type-mismatch diagnostics are // elided here (cstage gates the same shape). -fn binoptype(c: *checker, e: *node) *node = { - let op: tkind = e.op; - let ltn: *node = exprtype(c, e.lhs, nil); - let rtn: *node = exprtype(c, e.rhs, nil); +fn binoptype(c: *checker, e: *syntax.node) *syntax.node = { + let op: syntax.tkind = e.op; + let ltn: *syntax.node = exprtype(c, e.lhs, nil); + let rtn: *syntax.node = exprtype(c, e.rhs, nil); // #38/F2: ptr ± int / int + ptr use intkindast (the type_isint mirror, // incl untyped_int / untyped_rune / alias-chased) — NOT isinttypeast, // which misses untyped_int. cstage's ptr-arith arm gates on type_isint // (check.c:1179/1181), so `p + 1` (untyped_int) returns the ptr there // and never reaches the isnum gate; aligning these arms keeps the new // arithmetic gate below from rejecting valid pointer arithmetic. - if (op == tkind.TK_PLUS || op == tkind.TK_MINUS) { - if (ltn != nil && ltn.kind == nkind.N_TPTR && intkindast(c, rtn)) { + if (op == syntax.tkind.TK_PLUS || op == syntax.tkind.TK_MINUS) { + if (ltn != nil && ltn.kind == syntax.nkind.N_TPTR && intkindast(c, rtn)) { return ltn; }; }; - if (op == tkind.TK_PLUS) { - if (intkindast(c, ltn) && rtn != nil && rtn.kind == nkind.N_TPTR) { + if (op == syntax.tkind.TK_PLUS) { + if (intkindast(c, ltn) && rtn != nil && rtn.kind == syntax.nkind.N_TPTR) { return rtn; }; }; - if (op == tkind.TK_MINUS) { + if (op == syntax.tkind.TK_MINUS) { if (ltn != nil && rtn != nil - && ltn.kind == nkind.N_TPTR && rtn.kind == nkind.N_TPTR) { + && ltn.kind == syntax.nkind.N_TPTR && rtn.kind == syntax.nkind.N_TPTR) { return mktname(c, "i64"); }; }; @@ -13372,27 +13372,27 @@ fn binoptype(c: *checker, e: *node) *node = { // `let c: str = a + b;` (str+str) compiled to an integer ADD of the two // header pointers, silent garbage. The ptr-arithmetic special cases // above already returned, so a survivor here is plain value arithmetic. - if (op == tkind.TK_PLUS || op == tkind.TK_MINUS || - op == tkind.TK_STAR || op == tkind.TK_SLASH || - op == tkind.TK_PERCENT) { + if (op == syntax.tkind.TK_PLUS || op == syntax.tkind.TK_MINUS || + op == syntax.tkind.TK_STAR || op == syntax.tkind.TK_SLASH || + op == syntax.tkind.TK_PERCENT) { if ((ltn != nil && !numkindast(c, ltn)) || (rtn != nil && !numkindast(c, rtn))) { deffolderr(c, e, "arithmetic on non-numeric type"); }; return unifyarith(c, e, ltn, rtn); }; - if (op == tkind.TK_AMP || op == tkind.TK_PIPE || - op == tkind.TK_CARET || op == tkind.TK_LSHIFT || - op == tkind.TK_RSHIFT) { + if (op == syntax.tkind.TK_AMP || op == syntax.tkind.TK_PIPE || + op == syntax.tkind.TK_CARET || op == syntax.tkind.TK_LSHIFT || + op == syntax.tkind.TK_RSHIFT) { if ((ltn != nil && !intkindast(c, ltn)) || (rtn != nil && !intkindast(c, rtn))) { deffolderr(c, e, "bitwise on non-integer type"); }; return unifyarith(c, e, ltn, rtn); }; - if (op == tkind.TK_EQ || op == tkind.TK_NEQ || - op == tkind.TK_LT || op == tkind.TK_LE || - op == tkind.TK_GT || op == tkind.TK_GE) { + if (op == syntax.tkind.TK_EQ || op == syntax.tkind.TK_NEQ || + op == syntax.tkind.TK_LT || op == syntax.tkind.TK_LE || + op == syntax.tkind.TK_GT || op == syntax.tkind.TK_GE) { // cstage routes every comparison through unify_arith (check.c:1195/ // 1200 cbinop), which loud-rejects a differing-types pair, e.g. // strconv.invalid != i32. wwstage routes the ORDERED arm through @@ -13411,8 +13411,8 @@ fn binoptype(c: *checker, e: *node) *node = { // cstage's cbinop equality arm (check.c:1194-1196) gates nothing, // so str==str / ptr==ptr remain valid; aligning those down would // over-reject what cstage accepts. - if (op == tkind.TK_LT || op == tkind.TK_LE || - op == tkind.TK_GT || op == tkind.TK_GE) { + if (op == syntax.tkind.TK_LT || op == syntax.tkind.TK_LE || + op == syntax.tkind.TK_GT || op == syntax.tkind.TK_GE) { if ((ltn != nil && !numkindast(c, ltn)) || (rtn != nil && !numkindast(c, rtn))) { deffolderr(c, e, "ordered comparison on non-numeric"); @@ -13431,7 +13431,7 @@ fn binoptype(c: *checker, e: *node) *node = { }; return mktname(c, "bool"); }; - if (op == tkind.TK_AND || op == tkind.TK_OR) { + if (op == syntax.tkind.TK_AND || op == syntax.tkind.TK_OR) { // #38/F2 (review item 5): logical operands must be bool (cstage // check.c:1208-1211 gates each side via type_chase_named). cstage // formats per-side with tokname; ww's piecewise cerr can't splice @@ -13455,16 +13455,16 @@ fn binoptype(c: *checker, e: *node) *node = { // type_promote. The slice/str .len/.cap pseudo-field address-of widening // to *i64 mirrors check.c:672-682 directly — its purpose is documented // at the cstage site. -fn unoptype(c: *checker, e: *node) *node = { - let op: tkind = e.op; - let opt: *node = exprtype(c, e.lhs, nil); +fn unoptype(c: *checker, e: *syntax.node) *syntax.node = { + let op: syntax.tkind = e.op; + let opt: *syntax.node = exprtype(c, e.lhs, nil); // #38/F2 (review item 5): unop operand-kind gates the wwstage checker // elided. Mirror cstage cunop (cmd/wcc/check.c:1224-1238): unary +/- // want a numeric operand, ~ wants an integer, ! wants a bool. A nil // opt is an already-errored / inherent-IDENT bail — not re-rejected. - if (op == tkind.TK_MINUS || op == tkind.TK_PLUS) { + if (op == syntax.tkind.TK_MINUS || op == syntax.tkind.TK_PLUS) { if (opt != nil && !numkindast(c, opt)) { - if (op == tkind.TK_MINUS) { + if (op == syntax.tkind.TK_MINUS) { deffolderr(c, e, "- on non-numeric"); } else { deffolderr(c, e, "+ on non-numeric"); @@ -13472,19 +13472,19 @@ fn unoptype(c: *checker, e: *node) *node = { }; return opt; }; - if (op == tkind.TK_NOT) { + if (op == syntax.tkind.TK_NOT) { if (opt != nil && !boolkindast(c, opt)) { deffolderr(c, e, "! on non-bool"); }; return mktname(c, "bool"); }; - if (op == tkind.TK_TILDE) { + if (op == syntax.tkind.TK_TILDE) { if (opt != nil && !intkindast(c, opt)) { deffolderr(c, e, "~ on non-integer"); }; return opt; }; - if (op == tkind.TK_STAR) { + if (op == syntax.tkind.TK_STAR) { // opt nil here means the operand was an inherent-IDENT bail // (exprtype N_IDENT arm L1596-1599 — SK_USE / pseudo-builtin // sym.decl == nil — or another helper's nil propagation); @@ -13494,17 +13494,17 @@ fn unoptype(c: *checker, e: *node) *node = { // resolvealias passes through non-nil unchanged (L513 // `for (cur != nil)` only exits via `return cur` or `return n`). if (opt == nil) { return nil; }; - let u: *node = resolvealias(c, unwrapbang(opt)); + let u: *syntax.node = resolvealias(c, unwrapbang(opt)); // Invalid input (non-pointer dereference); cstage errors at // cmd/wcc/check.c:660. 5-lite-b #34. - if (u.kind != nkind.N_TPTR) { return nil; }; + if (u.kind != syntax.nkind.N_TPTR) { return nil; }; return u.lhs; }; - if (op == tkind.TK_AMP) { - if (e.lhs != nil && e.lhs.kind == nkind.N_DOT) { + if (op == syntax.tkind.TK_AMP) { + if (e.lhs != nil && e.lhs.kind == syntax.nkind.N_DOT) { let fld: str = e.lhs.str; - if (streq(fld, "len") || streq(fld, "cap")) { - let base: *node = e.lhs.lhs; + if (syntax.streq(fld, "len") || syntax.streq(fld, "cap")) { + let base: *syntax.node = e.lhs.lhs; if (base != nil && base.type_ != nil) { // Full chase per hop (F2a batch-4 c3-B2): // the one-peel-per-hop walk lost 2-level @@ -13514,12 +13514,12 @@ fn unoptype(c: *checker, e: *node) *node = { // stays loud for ALL alias bases (task // #96) — this aligns the stamped type // only; rows graduate with #96. - let bu: *tinfo = tichase(base.type_: *tinfo); - if (bu != nil && bu.kind == tykind.TY_PTR) { bu = bu.sub; }; + let bu: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu != nil && bu.kind == syntax.tykind.TY_PTR) { bu = bu.sub; }; bu = tichase(bu); if (bu != nil) { - if (bu.kind == tykind.TY_SLICE || bu.kind == tykind.TY_STR) { - let pp: *node = newnode(nkind.N_TPTR, "", 0, 0); + if (bu.kind == syntax.tykind.TY_SLICE || bu.kind == syntax.tykind.TY_STR) { + let pp: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pp.lhs = mktname(c, "i64"); return pp; }; @@ -13538,21 +13538,21 @@ fn unoptype(c: *checker, e: *node) *node = { // cstage, where a fn ident already types as TY_FN // (cmd/wcc/check.c:668), so `&fn` is `*fn` natively. if (e.lhs != nil) { - if (e.lhs.kind == nkind.N_IDENT) { + if (e.lhs.kind == syntax.nkind.N_IDENT) { // #4: curmod preference. A bare `&handler` whose leaf // also names a fn in a LATER module otherwise binds // the foreign signature (scopedefineinmodule prepends); // cstage types a fn ident via scope_lookup_prefer with // cur_mod (cmd/wcc/check.c:1305). - let fs: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); + let fs: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.lhs.str); if (fs != nil) { - if (fs.skind == skind.SK_FN) { + if (fs.skind == syntax.skind.SK_FN) { if (fs.decl != nil) { - if (fs.decl.kind == nkind.N_FNDECL) { - let synth: *node = newnode(nkind.N_TFN, "", 0, 0); + if (fs.decl.kind == syntax.nkind.N_FNDECL) { + let synth: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); synth.lhs = fs.decl.lhs; synth.list = fs.decl.list; - let pf: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pf: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pf.lhs = synth; return pf; }; @@ -13568,17 +13568,17 @@ fn unoptype(c: *checker, e: *node) *node = { // typeeq → confident reject; cstage types `&mod.fn` as `*fn` // natively (a dotted fn ref is TY_FN), so this aligns ww UP to // cstage's actual acceptance reason. - if (e.lhs.kind == nkind.N_DOT) { - if (e.lhs.lhs != nil && e.lhs.lhs.kind == nkind.N_IDENT) { - let fs: *sym = scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.lhs.str), e.lhs.str); + if (e.lhs.kind == syntax.nkind.N_DOT) { + if (e.lhs.lhs != nil && e.lhs.lhs.kind == syntax.nkind.N_IDENT) { + let fs: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, e.lhs.lhs.str), e.lhs.str); if (fs != nil) { - if (fs.skind == skind.SK_FN) { + if (fs.skind == syntax.skind.SK_FN) { if (fs.decl != nil) { - if (fs.decl.kind == nkind.N_FNDECL) { - let synth: *node = newnode(nkind.N_TFN, "", 0, 0); + if (fs.decl.kind == syntax.nkind.N_FNDECL) { + let synth: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); synth.lhs = fs.decl.lhs; synth.list = fs.decl.list; - let pf: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pf: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pf.lhs = synth; return pf; }; @@ -13592,7 +13592,7 @@ fn unoptype(c: *checker, e: *node) *node = { // #34). Generic &expr widens to *opt; without opt we can't // synthesize the pointer node. if (opt == nil) { return nil; }; - let pp: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pp: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pp.lhs = opt; return pp; }; @@ -13608,32 +13608,32 @@ fn unoptype(c: *checker, e: *node) *node = { // to T (pointer-to-array); `*[]T` does NOT decay (yields []T via the // generic *U → U fallback — Hare-faithful, a pointer-to-slice is a 1D // array of slices, not of T); generic *T → T. -fn indexresult(c: *checker, e: *node) *node = { - let basetn: *node = exprtype(c, e.lhs, nil); - let _idx: *node = exprtype(c, e.rhs, nil); - let u: *node = resolvealias(c, unwrapbang(basetn)); +fn indexresult(c: *checker, e: *syntax.node) *syntax.node = { + let basetn: *syntax.node = exprtype(c, e.lhs, nil); + let _idx: *syntax.node = exprtype(c, e.rhs, nil); + let u: *syntax.node = resolvealias(c, unwrapbang(basetn)); // basetn nil → propagation from inherent-IDENT bail at exprtype // N_IDENT arm L1596-1599 (5-lite-b #34, A.6.2.1c #24). // unwrapbang(nil)=nil and resolvealias(nil)=nil pass through. if (u == nil) { return nil; }; - if (u.kind == nkind.N_TSLICE) { return u.lhs; }; - if (u.kind == nkind.N_TARRAY) { return u.lhs; }; - if (u.kind == nkind.N_TNAME) { + if (u.kind == syntax.nkind.N_TSLICE) { return u.lhs; }; + if (u.kind == syntax.nkind.N_TARRAY) { return u.lhs; }; + if (u.kind == syntax.nkind.N_TNAME) { // rule-9 divergence-doc (drew .ai/drew-14-ruling.md): `str[i] -> // u8` is a deliberate Go-like direct byte-index, a SANCTIONED ww // divergence from Hare's `strings::toutf8(s)[i]` (the Hare // reference checker rejects str-index, harec check.c:362). // lib/strings is load-bearing on it (compare/dup/join). - if (streq(u.str, "str")) { + if (syntax.streq(u.str, "str")) { // #14: reject INDEX of a bare def-global scalar str — an // inline compile-time constant with no storage to index // (cgen refs an unbacked symbol -> link-fail ww / segfault // cs). let/param/local + string-literal operands stay // valid; only the SK_DEF scalar-str operand is // unindexable. cstage twin: check.c N_INDEX TY_STR arm. - if (e.lhs != nil && e.lhs.kind == nkind.N_IDENT) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); - if (s != nil && s.skind == skind.SK_DEF) { + if (e.lhs != nil && e.lhs.kind == syntax.nkind.N_IDENT) { + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.lhs.str); + if (s != nil && s.skind == syntax.skind.SK_DEF) { cerr("error: cannot index a def-constant str '"); cerr(e.lhs.str); cerr("'; bind it to a `let` (def strings are inline constants, not storage-backed)\n"); @@ -13644,10 +13644,10 @@ fn indexresult(c: *checker, e: *node) *node = { return mktname(c, "u8"); }; }; - if (u.kind == nkind.N_TPTR) { - let inner: *node = u.lhs; - let iu: *node = resolvealias(c, unwrapbang(inner)); - if (iu != nil && iu.kind == nkind.N_TARRAY) { + if (u.kind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = u.lhs; + let iu: *syntax.node = resolvealias(c, unwrapbang(inner)); + if (iu != nil && iu.kind == syntax.nkind.N_TARRAY) { return iu.lhs; }; return inner; @@ -13684,79 +13684,79 @@ fn indexresult(c: *checker, e: *node) *node = { // inherent-IDENT bails (SK_USE, pseudo-builtin sym.decl==nil, // N_DOT-LHS syntactic position, EXPR_ASSERT-family abort/assert) until // #19 retires the bail shape. -fn exprtype(c: *checker, e: *node, hint: *node) *node = { +fn exprtype(c: *checker, e: *syntax.node, hint: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - let k: nkind = e.kind; + let k: syntax.nkind = e.kind; // #61 audit §1.8 — A.2 widens A.1's single N_INTLIT population to // every primitive literal arm + N_IDENT. Cgen size walkers // (slotsize first; elemsize/fieldsize/letemitsize follow) consult // node.type_ as the SSoT; populating literals + idents closes the // loop from the read side. - if (k == nkind.N_INTLIT) { + if (k == syntax.nkind.N_INTLIT) { // Typed-int literal (`7u32`, `0i8`): tsuffix names a builtin // primitive. Mirrors cstage cmd/wcc/check.c:694-701 cexpr's // `lookup_builtin(n->tsuffix)`; falls through to untyped_int // when the suffix doesn't resolve. if (e.tsuffix.len > 0) { - let suf: *node = mktname(c, e.tsuffix); - let ti: *tinfo = tinfofornode(c, suf); + let suf: *syntax.node = mktname(c, e.tsuffix); + let ti: *syntax.tinfo = tinfofornode(c, suf); if (ti != nil) { e.type_ = ti: *void; return suf; }; }; - let tn: *node = mktname(c, "untyped_int"); + let tn: *syntax.node = mktname(c, "untyped_int"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_FLOATLIT) { + if (k == syntax.nkind.N_FLOATLIT) { // Typed-float literal (`1.5f32`, `0.0f64`): tsuffix names a // builtin primitive. Mirrors cstage cmd/wcc/check.c:702-709 // cexpr's `lookup_builtin(n->tsuffix)`; falls through to // untyped_float when the suffix doesn't resolve. if (e.tsuffix.len > 0) { - let suf: *node = mktname(c, e.tsuffix); - let ti: *tinfo = tinfofornode(c, suf); + let suf: *syntax.node = mktname(c, e.tsuffix); + let ti: *syntax.tinfo = tinfofornode(c, suf); if (ti != nil) { e.type_ = ti: *void; return suf; }; }; - let tn: *node = mktname(c, "untyped_float"); + let tn: *syntax.node = mktname(c, "untyped_float"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_STRLIT) { - let tn: *node = mktname(c, "str"); + if (k == syntax.nkind.N_STRLIT) { + let tn: *syntax.node = mktname(c, "str"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_RUNELIT) { - let tn: *node = mktname(c, "rune"); + if (k == syntax.nkind.N_RUNELIT) { + let tn: *syntax.node = mktname(c, "rune"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_TRUE) { - let tn: *node = mktname(c, "bool"); + if (k == syntax.nkind.N_TRUE) { + let tn: *syntax.node = mktname(c, "bool"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_FALSE) { - let tn: *node = mktname(c, "bool"); + if (k == syntax.nkind.N_FALSE) { + let tn: *syntax.node = mktname(c, "bool"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_VOIDLIT) { - let tn: *node = mktname(c, "void"); + if (k == syntax.nkind.N_VOIDLIT) { + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_NIL) { - let tn: *node = mktname(c, "untyped_nil"); + if (k == syntax.nkind.N_NIL) { + let tn: *syntax.node = mktname(c, "untyped_nil"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { // #55: bare-leaf value-ident must prefer curmod. Flat-scope // scopelookup bucket-walks and can bind a same-leaf symbol from // the wrong module under a foreign curmod, dragging its decl's @@ -13764,7 +13764,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // bare `error` then binds strconv.error not io.error). Mirrors // cstage cmd/wcc/check.c:66 scope_lookup_prefer; sibling #56 at // L2439, #53 at L688. Tracked in the cluster note at L685-687. - let s: *sym = scopelookupprefer(c.cur, c.curmod, e.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; // #34: a bare fn-name rvalue types as its FN TYPE, not its return @@ -13779,21 +13779,21 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // root of the #24 fn-family over-rejects (`let p: fn()i32 = g` compared // i32 vs the fn type). cgen lowers a fn rvalue name-keyed via // fnretlookup (cgenexpr.ww:1100), never off this stamp → byte-id-neutral. - if (s.skind == skind.SK_FN) { - let ft: *node = newnode(nkind.N_TFN, "", 0, 0); + if (s.skind == syntax.skind.SK_FN) { + let ft: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); ft.lhs = s.decl.lhs; ft.list = s.decl.list; e.type_ = tinfofornode(c, ft): *void; return ft; }; - let t: *node = s.decl.lhs; + let t: *syntax.node = s.decl.lhs; // Propagate the declared type's tinfo onto the use site so // downstream cgen walkers can read n.type_ off an ident. if (t != nil) { if (t.type_ != nil) { e.type_ = t.type_; } else { - let ti: *tinfo = tinfofornode(c, t); + let ti: *syntax.tinfo = tinfofornode(c, t); if (ti != nil) { e.type_ = ti: *void; t.type_ = ti: *void; @@ -13802,29 +13802,29 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; return t; }; - if (k == nkind.N_BIN) { - let tn: *node = binoptype(c, e); + if (k == syntax.nkind.N_BIN) { + let tn: *syntax.node = binoptype(c, e); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_UN) { - let tn: *node = unoptype(c, e); + if (k == syntax.nkind.N_UN) { + let tn: *syntax.node = unoptype(c, e); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_INDEX) { - let tn: *node = indexresult(c, e); + if (k == syntax.nkind.N_INDEX) { + let tn: *syntax.node = indexresult(c, e); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { // `expr: T` — explicit cast; the type expr is e.rhs. Mirrors // cstage cmd/wcc/check.c:737 `n->type = resolve_type(c, n->rhs)`. e.type_ = tinfofornode(c, e.rhs): *void; return e.rhs; }; - if (k == nkind.N_CALL) { - let callee: *node = e.lhs; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = e.lhs; if (callee == nil) { return nil; }; // #31: synthesize the `alloc(value)` / `alloc([], n)` builtin // return shape so checkletassign sees the same `(*T | nomem)` / @@ -13833,18 +13833,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // silently accepts `let p: *T = alloc(v);` — rule 10 trap. // Same-module gate mirrors cstage's `c->cur_mod && // scope_lookup_in_module(...)` check from task #23. - if (callee.kind == nkind.N_IDENT) { - if (streq(callee.str, "alloc")) { + if (callee.kind == syntax.nkind.N_IDENT) { + if (syntax.streq(callee.str, "alloc")) { let shadowed: bool = false; if (c.curmod.len > 0) { - if (scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { + if (syntax.scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { shadowed = true; }; }; if (!shadowed) { if (e.list != nil) { // Slice form: `alloc([], n)`. - if (e.list.kind == nkind.N_ARRLIT) { + if (e.list.kind == syntax.nkind.N_ARRLIT) { if (e.list.list == nil) { if (e.list.next != nil) { if (e.list.next.next == nil) { @@ -13865,11 +13865,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { deffolderr(c, e, "cannot infer slice element type for alloc([], n) without a type hint; annotate the binding, e.g. let x: []T = alloc([], n)"); return nil; }; - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = mktname(c, "u8"); - let nome: *node = mktname(c, "nomem"); + let nome: *syntax.node = mktname(c, "nomem"); sl.next = nome; - let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTAGGED, "", 0, 0); tt.list = sl; e.type_ = tinfofornode(c, tt): *void; return tt; @@ -13879,12 +13879,12 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; // Value form: `alloc(value)`. if (e.list.next == nil) { - let argt: *node = exprtype(c, e.list, nil); - let ptr: *node = newnode(nkind.N_TPTR, "", 0, 0); + let argt: *syntax.node = exprtype(c, e.list, nil); + let ptr: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); ptr.lhs = argt; - let nome: *node = mktname(c, "nomem"); + let nome: *syntax.node = mktname(c, "nomem"); ptr.next = nome; - let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTAGGED, "", 0, 0); tt.list = ptr; e.type_ = tinfofornode(c, tt): *void; return tt; @@ -13899,11 +13899,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // mirrors the alloc precedent (#23) so a user `fn size(...)` // inside this module suppresses the builtin. Mirrors cstage // cmd/wcc/check.c:907-960. - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { let bname: str = callee.str; - let issize: bool = streq(bname, "size"); - let isalign: bool = streq(bname, "align"); - let isoffset: bool = streq(bname, "offset"); + let issize: bool = syntax.streq(bname, "size"); + let isalign: bool = syntax.streq(bname, "align"); + let isoffset: bool = syntax.streq(bname, "offset"); if (issize || isalign || isoffset) { // #38/F2 (review item 7): UNCONDITIONAL intercept — cstage // gates size/align/offset on NOTHING (cmd/wcc/check.c:1538- @@ -13920,7 +13920,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // otherwise folded the unresolved N_TNAME to 0 silently // (rc=0 wrong binary). offset's arg is a value N_DOT and // keeps its own "no field" diagnostic below. - if ((issize || isalign) && e.list.kind == nkind.N_TNAME + if ((issize || isalign) && e.list.kind == syntax.nkind.N_TNAME && tinfofornode(c, e.list) == nil) { cerr(e.list.file); cerr(": error: unknown type '"); @@ -13934,7 +13934,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // ty_untyped_int after the fold AND returns it // to the caller (the Hare-correct type), so a // `let x: size = size(T)` binding is assignable. - let utn: *node = mktname(c, "untyped_int"); + let utn: *syntax.node = mktname(c, "untyped_int"); if (issize) { // #108(b): rule-10 twin of the cstage // size/align unsized guard. @@ -13959,7 +13959,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // (N_DOT), parsed via parsearglist — not a // type expression. if (isoffset) { - if (e.list.next == nil && e.list.kind == nkind.N_DOT) { + if (e.list.next == nil && e.list.kind == syntax.nkind.N_DOT) { let off: i64 = astoffset(c, e.list); if (off < 0i64) { cerr("offset: no field '"); @@ -13990,7 +13990,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // this task; #19 (Drew's δ — dedicated AST kinds) is the // Hare-faithful path. This is the intercept-shim minimum to // unblock #15 (A.6.2.1e assertion enable). - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { // abort([msg]) / assert(cond[, msg]) — the EXPR_ASSERT // family (harec ref/harec/src/check.c:877,893), lowered // to rt_abort. Builtin only when no user symbol shadows @@ -14000,10 +14000,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // flat-scope root is filed as task #14). // The TY_ERR stamp on the callee is cgen's routing key // (cstage spells it `n->lhs->type = ty_err`). - if (streq(callee.str, "abort") - && scopelookupprefer(c.cur, c.curmod, "abort") == nil) { + if (syntax.streq(callee.str, "abort") + && syntax.scopelookupprefer(c.cur, c.curmod, "abort") == nil) { if (e.list != nil) { - let mt: *node = exprtype(c, e.list, nil); + let mt: *syntax.node = exprtype(c, e.list, nil); let conf: bool = false; if (!isassignable(c, mktname(c, "str"), mt, &conf)) { cerr("abort: message must be str\n"); @@ -14014,14 +14014,14 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { c.errs += 1; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; callee.type_ = c.tc.tyerr: *void; return tn; }; - if (streq(callee.str, "assert") && e.list != nil - && scopelookupprefer(c.cur, c.curmod, "assert") == nil) { - let ct: *node = exprtype(c, e.list, nil); + if (syntax.streq(callee.str, "assert") && e.list != nil + && syntax.scopelookupprefer(c.cur, c.curmod, "assert") == nil) { + let ct: *syntax.node = exprtype(c, e.list, nil); if (ct != nil) { // No alias peel: cstage compares ty_bool by // IDENTITY (cmd/wcc/check.c:1560), so a @@ -14029,11 +14029,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // align down (rule 10). Widening belongs to // the alias-peel choke-point arc (task #5, // #47/#68), both stages together. - let cu: *node = unwrapbang(ct); + let cu: *syntax.node = unwrapbang(ct); let condok: bool = false; - if (cu.kind == nkind.N_TNAME) { - if (streq(cu.str, "bool") - || streq(cu.str, "untyped_bool")) { + if (cu.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(cu.str, "bool") + || syntax.streq(cu.str, "untyped_bool")) { condok = true; }; }; @@ -14043,7 +14043,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; }; if (e.list.next != nil) { - let mt: *node = exprtype(c, e.list.next, nil); + let mt: *syntax.node = exprtype(c, e.list.next, nil); let conf: bool = false; if (!isassignable(c, mktname(c, "str"), mt, &conf)) { cerr("assert: message must be str\n"); @@ -14054,18 +14054,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { c.errs += 1; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; callee.type_ = c.tc.tyerr: *void; return tn; }; - if (streq(callee.str, "len")) { - let tn: *node = mktname(c, "i32"); + if (syntax.streq(callee.str, "len")) { + let tn: *syntax.node = mktname(c, "i32"); e.type_ = tinfofornode(c, tn): *void; return tn; }; - if (streq(callee.str, "append") || streq(callee.str, "free")) { - let tn: *node = mktname(c, "void"); + if (syntax.streq(callee.str, "append") || syntax.streq(callee.str, "free")) { + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14078,8 +14078,8 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // delete(xs[i..j])); either way the OBJECT must be a // slice. The range form is the fold-5a prereq P2 // (regex.ha:333 delete(jump_idxs[group_level][..])). - if (streq(callee.str, "delete")) { - let d: *node = e.list; + if (syntax.streq(callee.str, "delete")) { + let d: *syntax.node = e.list; if (d == nil || d.next != nil) { cerr("delete: takes exactly one argument\n"); c.errs += 1; @@ -14088,22 +14088,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { exprtype(c, d, nil); // harec check.c:2016's reject; wording // adapted to ww's delete: prefix. - if (d.kind != nkind.N_INDEX && d.kind != nkind.N_SLICE) { + if (d.kind != syntax.nkind.N_INDEX && d.kind != syntax.nkind.N_SLICE) { cerr("delete: operand must be an indexing or slicing expression\n"); c.errs += 1; } else { - let basetn: *node = exprtype(c, d.lhs, nil); - let u: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, d.lhs, nil); + let u: *syntax.node = resolvealias(c, unwrapbang(basetn)); // harec check.c:2024 wording; a // fixed-size [N]T base and a str // base land here. - if (u == nil || u.kind != nkind.N_TSLICE) { + if (u == nil || u.kind != syntax.nkind.N_TSLICE) { cerr("delete must operate on a slice\n"); c.errs += 1; }; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14118,34 +14118,34 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // form (harec :821/:837) stay filed on #35; a range // PLACE is not Hare (harec asserts ACCESS_INDEX at // :784) — rejected, no task cite. - if (streq(callee.str, "insert")) { - let d: *node = e.list; + if (syntax.streq(callee.str, "insert")) { + let d: *syntax.node = e.list; if (d == nil || d.next == nil || d.next.next != nil) { cerr("insert: takes exactly two arguments\n"); c.errs += 1; }; if (d != nil) { exprtype(c, d, nil); - if (d.kind == nkind.N_SLICE) { + if (d.kind == syntax.nkind.N_SLICE) { cerr("insert: range place is invalid; operand must be an indexing expression xs[i]\n"); c.errs += 1; } else { - if (d.kind != nkind.N_INDEX) { + if (d.kind != syntax.nkind.N_INDEX) { cerr("insert: operand must be an indexing expression xs[i]\n"); c.errs += 1; } else { - let basetn: *node = exprtype(c, d.lhs, nil); - let u: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, d.lhs, nil); + let u: *syntax.node = resolvealias(c, unwrapbang(basetn)); // harec check.c:807 wording; a // fixed-size [N]T base lands here. - if (u == nil || u.kind != nkind.N_TSLICE) { + if (u == nil || u.kind != syntax.nkind.N_TSLICE) { cerr("insert must operate on a slice\n"); c.errs += 1; }; }; }; if (d.next != nil) { - if (d.next.kind == nkind.N_SPREAD) { + if (d.next.kind == syntax.nkind.N_SPREAD) { cerr("insert: spread form insert(xs[i], vs...) unimplemented (task #35)\n"); c.errs += 1; } else { @@ -14153,15 +14153,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; }; }; - let tn: *node = mktname(c, "void"); + let tn: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, tn): *void; return tn; }; }; let nm: str; nm.ptr = nil; nm.len = 0; - if (callee.kind == nkind.N_IDENT) { nm = callee.str; }; - if (callee.kind == nkind.N_DOT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_IDENT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_DOT) { nm = callee.str; }; // #56: bare-leaf N_IDENT calls go through scopelookupprefer so // `foo()` inside module M binds to M.foo rather than another // module's same-leaf foo at the head of the flat scope bucket. @@ -14200,15 +14200,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // cgen post-#180+#185 already lowers the deref-call correctly, // so lifting the asserttyped bail is silent-SIGSEGV-safe. if (nm.len > 0) { - let s: *sym = nil; - if (callee.kind == nkind.N_IDENT) { - s = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = nil; + if (callee.kind == syntax.nkind.N_IDENT) { + s = syntax.scopelookupprefer(c.cur, c.curmod, nm); } else { - let ms: *sym = nil; - if (callee.lhs != nil && callee.lhs.kind == nkind.N_IDENT) { - ms = scopelookupprefer(c.cur, c.curmod, callee.lhs.str); - if (ms != nil && ms.skind != skind.SK_USE) { - let mu: *sym = scopelookupuselocal(ms.scope, callee.lhs.str); + let ms: *syntax.sym = nil; + if (callee.lhs != nil && callee.lhs.kind == syntax.nkind.N_IDENT) { + ms = syntax.scopelookupprefer(c.cur, c.curmod, callee.lhs.str); + if (ms != nil && ms.skind != syntax.skind.SK_USE) { + let mu: *syntax.sym = syntax.scopelookupuselocal(ms.scope, callee.lhs.str); if (mu != nil) { ms = mu; }; }; }; @@ -14227,11 +14227,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // :1378-1433 (call result IS the callee type's ret; no // global-leaf path) and harec check_autodereference // (ref/harec/src/check.c:1566-1581). - if (ms != nil && (ms.skind == skind.SK_USE || ms.use_alias != 0i32)) { - s = scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), nm); + if (ms != nil && (ms.skind == syntax.skind.SK_USE || ms.use_alias != 0i32)) { + s = syntax.scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), nm); }; }; - if (s != nil) { if (s.skind == skind.SK_FN) { if (s.decl != nil) { + if (s != nil) { if (s.skind == syntax.skind.SK_FN) { if (s.decl != nil) { // fn-decl's lhs is the return-type AST node. Mirrors cstage // cmd/wcc/check.c:984+ regular-CALL `n->type = // build_fn_type(c, s->decl)->ret` shape. @@ -14249,18 +14249,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // name path stays primary because a fn-NAME callee node in wwstage // already carries its RETURN type (fn-decl.lhs), not its fn-type — // so a `fn make() fn() void` callee would otherwise mis-yield void. - let ct: *node = resolvealias(c, unwrapbang(exprtype(c, callee, nil))); - for (ct != nil && ct.kind == nkind.N_TPTR) { + let ct: *syntax.node = resolvealias(c, unwrapbang(exprtype(c, callee, nil))); + for (ct != nil && ct.kind == syntax.nkind.N_TPTR) { ct = resolvealias(c, unwrapbang(ct.lhs)); }; - if (ct != nil) { if (ct.kind == nkind.N_TFN) { - let res: *node = ct.lhs; + if (ct != nil) { if (ct.kind == syntax.nkind.N_TFN) { + let res: *syntax.node = ct.lhs; e.type_ = tinfofornode(c, res): *void; return res; }; }; return nil; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // A.6.1.5a — fold cases only. Mirrors cstage cmd/wcc/check.c // :740-832. Struct field + pseudo-field (.len/.cap/.ptr) lands // in A.6.1.5b. SK_USE gates case 1; a #6a-D dot-lhs collision @@ -14273,11 +14273,11 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // to enumvalfold, matching cstage cmd/wcc/check.c:210-284 and // harec's enum-resolve constexpr set at // ref/harec/src/check.c:4419-4434. - let lhsn: *node = e.lhs; - if (lhsn != nil) { if (lhsn.kind == nkind.N_IDENT) { - let ms: *sym = scopelookupprefer(c.cur, c.curmod, lhsn.str); - if (ms != nil && ms.skind != skind.SK_USE) { - let mu: *sym = scopelookupuselocal(ms.scope, lhsn.str); + let lhsn: *syntax.node = e.lhs; + if (lhsn != nil) { if (lhsn.kind == syntax.nkind.N_IDENT) { + let ms: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, lhsn.str); + if (ms != nil && ms.skind != syntax.skind.SK_USE) { + let mu: *syntax.sym = syntax.scopelookupuselocal(ms.scope, lhsn.str); if (mu != nil) { ms = mu; }; }; if (ms != nil) { @@ -14287,21 +14287,21 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // through to outer case — cgen has its own module- // qualified resolution and the lenient checker policy // keeps the silent miss documented at scruttype L656. - if (ms.skind == skind.SK_USE || ms.use_alias != 0i32) { - let fs: *sym = scopelookupinmodule(c.cur, modkeyfor(c, lhsn.str), e.str); + if (ms.skind == syntax.skind.SK_USE || ms.use_alias != 0i32) { + let fs: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, lhsn.str), e.str); if (fs != nil) { if (fs.decl != nil) { // #34: a module-qualified bare fn rvalue `mod.fn` types as // its FN TYPE (twin of the N_IDENT arm, :2688); decl.lhs is // the RETURN type for an N_FNDECL. Pins 706 (`let p1: fn()i32 // = mod1.ping`). - if (fs.skind == skind.SK_FN) { - let ft: *node = newnode(nkind.N_TFN, "", 0, 0); + if (fs.skind == syntax.skind.SK_FN) { + let ft: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); ft.lhs = fs.decl.lhs; ft.list = fs.decl.list; e.type_ = tinfofornode(c, ft): *void; return ft; }; - let tn: *node = fs.decl.lhs; + let tn: *syntax.node = fs.decl.lhs; if (tn != nil) { e.type_ = tinfofornode(c, tn): *void; return tn; @@ -14311,12 +14311,12 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Fold case 2 inner: bare `EnumT.MEMBER` where EnumT // is an SK_TYPE in the flat scope. Mirror cstage // check.c:780-803. - if (ms.skind == skind.SK_TYPE) { if (ms.decl != nil) { - let body: *node = ms.decl.lhs; - let ub: *node = resolvealias(c, unwrapbang(body)); - if (ub != nil) { if (ub.kind == nkind.N_TENUM) { + if (ms.skind == syntax.skind.SK_TYPE) { if (ms.decl != nil) { + let body: *syntax.node = ms.decl.lhs; + let ub: *syntax.node = resolvealias(c, unwrapbang(body)); + if (ub != nil) { if (ub.kind == syntax.nkind.N_TENUM) { let prev: u64 = (-1i64): u64; - let m: *node = ub.list; + let m: *syntax.node = ub.list; for (m != nil) { let val: u64 = 0u64; if (m.lhs == nil) { @@ -14325,7 +14325,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { if (!enumvalfold(ub, m, m.lhs, &val)) { return nil; }; }; prev = val; - if (streq(m.str, e.str)) { + if (syntax.streq(m.str, e.str)) { foldtointlit(c, e, val: i64); e.type_ = tinfofornode(c, body): *void; return body; @@ -14341,15 +14341,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // via case 1 above to the enum body. Mirror cstage // check.c:805-832. Peel one TPTR for `(*EnumT).MEMBER` (rare // but cstage handles it at L808). - let basetn: *node = exprtype(c, lhsn, nil); + let basetn: *syntax.node = exprtype(c, lhsn, nil); if (basetn != nil) { - let bu: *node = resolvealias(c, unwrapbang(basetn)); - if (bu != nil) { if (bu.kind == nkind.N_TPTR) { + let bu: *syntax.node = resolvealias(c, unwrapbang(basetn)); + if (bu != nil) { if (bu.kind == syntax.nkind.N_TPTR) { bu = resolvealias(c, unwrapbang(bu.lhs)); }; }; - if (bu != nil) { if (bu.kind == nkind.N_TENUM) { + if (bu != nil) { if (bu.kind == syntax.nkind.N_TENUM) { let prev: u64 = (-1i64): u64; - let m: *node = bu.list; + let m: *syntax.node = bu.list; for (m != nil) { let val: u64 = 0u64; if (m.lhs == nil) { @@ -14358,7 +14358,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { if (!enumvalfold(bu, m, m.lhs, &val)) { return nil; }; }; prev = val; - if (streq(m.str, e.str)) { + if (syntax.streq(m.str, e.str)) { foldtointlit(c, e, val: i64); e.type_ = tinfofornode(c, basetn): *void; return basetn; @@ -14374,10 +14374,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // L833-842. `str` lives as N_TNAME("str") in wwstage — no // dedicated N_TSTR kind — so test the trio shape here. if (bu != nil) { - let isstr: bool = (bu.kind == nkind.N_TNAME) && streq(bu.str, "str"); - if (bu.kind == nkind.N_TSLICE || bu.kind == nkind.N_TARRAY || isstr) { - if (streq(e.str, "len")) { - let tn: *node = mktname(c, "i32"); + let isstr: bool = (bu.kind == syntax.nkind.N_TNAME) && syntax.streq(bu.str, "str"); + if (bu.kind == syntax.nkind.N_TSLICE || bu.kind == syntax.nkind.N_TARRAY || isstr) { + if (syntax.streq(e.str, "len")) { + let tn: *syntax.node = mktname(c, "i32"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14385,13 +14385,13 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // invalid (drew ruling). cstage check.c errs // symmetrically. c.errs>0 gates cgen off → build // fails (the #11 inferarraylen idiom). - if (bu.kind == nkind.N_TARRAY && streq(e.str, "cap")) { + if (bu.kind == syntax.nkind.N_TARRAY && syntax.streq(e.str, "cap")) { cerr("error: no field 'cap' on a fixed-size array (arrays have no capacity; use .len)\n"); c.errs += 1; return nil; }; - if (streq(e.str, "cap")) { - let tn: *node = mktname(c, "i32"); + if (syntax.streq(e.str, "cap")) { + let tn: *syntax.node = mktname(c, "i32"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14399,10 +14399,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // &A[0], a sanctioned ww spelling / faithful Hare // desugaring (14 live consumers). KEEP — .ptr valid. // See .ai/drew-gapa-ptr-ruling.md. - if (streq(e.str, "ptr")) { - let elem: *node = bu.lhs; + if (syntax.streq(e.str, "ptr")) { + let elem: *syntax.node = bu.lhs; if (isstr) { elem = mktname(c, "u8"); }; - let pp: *node = newnode(nkind.N_TPTR, "", 0, 0); + let pp: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, "", 0, 0); pp.lhs = elem; e.type_ = tinfofornode(c, pp): *void; return pp; @@ -14410,10 +14410,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; }; // Struct field walk. Cstage L843-849 errors on missing field. - if (bu != nil) { if (bu.kind == nkind.N_TSTRUCT) { - let f: *node = bu.list; + if (bu != nil) { if (bu.kind == syntax.nkind.N_TSTRUCT) { + let f: *syntax.node = bu.list; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { if (streq(f.str, e.str)) { + if (f.kind == syntax.nkind.N_TFIELD) { if (syntax.streq(f.str, e.str)) { e.type_ = tinfofornode(c, f.lhs): *void; return f.lhs; }; }; @@ -14423,16 +14423,16 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Tuple positional access `t.0`, `t.1`, …. Cstage L850-866 // errors on non-numeric / out-of-range; wwstage falls // through. fldnumidx (cgenutil) returns -1 on non-digit. - if (bu != nil) { if (bu.kind == nkind.N_TTUPLE) { + if (bu != nil) { if (bu.kind == syntax.nkind.N_TTUPLE) { let idx: i32 = fldnumidx(e.str); if (idx >= 0) { - let p: *node = bu.list; + let p: *syntax.node = bu.list; for (idx > 0 && p != nil) { p = p.next; idx -= 1; }; if (p != nil) { - let pt: *node = p.lhs; + let pt: *syntax.node = p.lhs; e.type_ = tinfofornode(c, pt): *void; return pt; }; @@ -14441,7 +14441,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; return nil; }; - if (k == nkind.N_STRUCTLIT) { + if (k == syntax.nkind.N_STRUCTLIT) { // A.6.1.6 — head-only stamp of the struct-lit's overall type. // Mirror cstage cmd/wcc/check.c:1161-1197; field-level walk // (cstage L1178-1194) parked behind #23 / Phase 2 — field @@ -14452,10 +14452,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // TYPE_IDENT in e.lhs; e.lhs == nil would be a future Hare- // style anonymous struct lit we don't yet parse — bail. if (e.lhs == nil) { return nil; }; - if (e.lhs.kind == nkind.N_IDENT) { - let ms: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); - if (ms != nil) { if (ms.skind == skind.SK_TYPE) { if (ms.decl != nil) { - let tn: *node = ms.decl.lhs; + if (e.lhs.kind == syntax.nkind.N_IDENT) { + let ms: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.lhs.str); + if (ms != nil) { if (ms.skind == syntax.skind.SK_TYPE) { if (ms.decl != nil) { + let tn: *syntax.node = ms.decl.lhs; if (tn != nil) { // #66 Phase-N step 3: stamp e.type_ to the NOMINAL // per-decl NAMED, not the flattened body. `overflow{}` @@ -14473,8 +14473,8 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Return the body node tn unchanged: byte-id rides // e.type_ (cgen), while the checker's AST-level // assign/return checks keep their prior input. - let tnm: *node = mktname(c, e.lhs.str); - let nti: *tinfo = tinfofornode(c, tnm); + let tnm: *syntax.node = mktname(c, e.lhs.str); + let nti: *syntax.tinfo = tinfofornode(c, tnm); if (nti != nil) { e.type_ = nti: *void; } else { e.type_ = tinfofornode(c, tn): *void; }; // #251: range-check array-typed field inits @@ -14487,18 +14487,18 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // and closes the rule-7 silent out-of-range truncate // at this site (cstage check.c:1546 range-checks via // arrlit_init_fits). - let stn: *node = resolvealias(c, tn); - if (stn != nil && stn.kind == nkind.N_TSTRUCT) { - let fi: *node = e.list; + let stn: *syntax.node = resolvealias(c, tn); + if (stn != nil && stn.kind == syntax.nkind.N_TSTRUCT) { + let fi: *syntax.node = e.list; for (fi != nil) { - if (fi.kind == nkind.N_FIELD + if (fi.kind == syntax.nkind.N_FIELD && fi.lhs != nil - && fi.lhs.kind == nkind.N_ARRLIT) { - let ftn: *node = nil; - let tf: *node = stn.list; + && fi.lhs.kind == syntax.nkind.N_ARRLIT) { + let ftn: *syntax.node = nil; + let tf: *syntax.node = stn.list; for (tf != nil) { - if (tf.kind == nkind.N_TFIELD) { - if (streq(tf.str, fi.str)) { ftn = tf.lhs; }; + if (tf.kind == syntax.nkind.N_TFIELD) { + if (syntax.streq(tf.str, fi.str)) { ftn = tf.lhs; }; }; tf = tf.next; }; @@ -14521,7 +14521,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, e.lhs): *void; return e.lhs; }; - if (k == nkind.N_ARRLIT) { + if (k == syntax.nkind.N_ARRLIT) { // A.6.1.7 — head-only stamp of the array-lit's overall type. // Mirror cstage cmd/wcc/check.c:1198-1211: walk elements, // skip the `...` repeat sentinel (parse/expr.ww:101-105), @@ -14538,16 +14538,16 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // precedent at L1509. Consumers default-type via the declared // `let` slot until A.6.3 lands. Mixed-type elements follow // cstage first-element-wins; no unify check (future scope). - let elt: *node = nil; + let elt: *syntax.node = nil; let count: u64 = 0u64; - let it: *node = e.list; + let it: *syntax.node = e.list; for (it != nil) { let skip: bool = false; - if (it.kind == nkind.N_FIELD) { - if (streq(it.str, "...")) { skip = true; }; + if (it.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(it.str, "...")) { skip = true; }; }; if (!skip) { - let t: *node = exprtype(c, it, nil); + let t: *syntax.node = exprtype(c, it, nil); if (elt == nil) { // #19: N_STRUCTLIT exprtype returns the struct BODY // (N_TSTRUCT) per #66, but the array->slice @@ -14559,9 +14559,9 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // is the same N_TNAME shape (typeeqast is already // streq-keyed for TNAME). Non-named elements keep the // existing first-element shape. - if (it.kind == nkind.N_STRUCTLIT + if (it.kind == syntax.nkind.N_STRUCTLIT && it.lhs != nil - && it.lhs.kind == nkind.N_IDENT) { + && it.lhs.kind == syntax.nkind.N_IDENT) { elt = mktname(c, it.lhs.str); } else { elt = t; @@ -14583,23 +14583,23 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Hare-fidelity: harec lower_flexible defaults a flexible iconst // to `int` (ref/harec/src/types.c:835). int = machine word (8B); // the old i32 truncated values >2^31 (#263 trap). - if (elt != nil && elt.kind == nkind.N_TNAME) { - if (streq(elt.str, "untyped_int")) { + if (elt != nil && elt.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(elt.str, "untyped_int")) { elt = mktname(c, "int"); - } else { if (streq(elt.str, "untyped_float")) { + } else { if (syntax.streq(elt.str, "untyped_float")) { elt = mktname(c, "f64"); - } else { if (streq(elt.str, "untyped_str")) { + } else { if (syntax.streq(elt.str, "untyped_str")) { elt = mktname(c, "str"); - } else { if (streq(elt.str, "untyped_rune")) { + } else { if (syntax.streq(elt.str, "untyped_rune")) { elt = mktname(c, "rune"); - } else { if (streq(elt.str, "untyped_bool")) { + } else { if (syntax.streq(elt.str, "untyped_bool")) { elt = mktname(c, "bool"); }; }; }; }; }; }; // Empty inferred arrlit: default to int, symmetric with cstage // check.c:1859 empty-fallback ty_int (#103). Was "i32". if (elt == nil) { elt = mktname(c, "int"); }; - let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0); + let arr: *syntax.node = syntax.newnode(syntax.nkind.N_TARRAY, "", 0, 0); // #6(niche): stamp the SYNTHESIZED element TNAME so the inferred // array's cgen is IDENTICAL to an explicit [N]T's (whose element is // resolvewalk-stamped). For a scalar element (int/u8) cgen's @@ -14611,7 +14611,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // real exprtype result whose type_ is already set. if (elt.type_ == nil) { elt.type_ = tinfofornode(c, elt): *void; }; arr.lhs = elt; - let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let cn: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); cn.uval = count; // #6(niche): stamp the SYNTHESIZED count literal. When this arr is // planted on an inferred array global's n.lhs (the array twin of @@ -14632,7 +14632,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { arr.type_ = e.type_; return arr; }; - if (k == nkind.N_SLICE) { + if (k == syntax.nkind.N_SLICE) { // A.6.2.0a — head-only stamp of the slice expression's overall // type. Mirrors cstage cmd/wcc/check.c:1214-1228 N_SLICE: peel // alias on the base; [N]T → []T, []T → []T (return base), str @@ -14643,22 +14643,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // Documented cstage divergence: cstage L1227 errors on a // non-sliceable base; wwstage returns nil (lenient on miss), // matching scruttype L656 / A.6.1.5b N_DOT precedent. - let basetn: *node = exprtype(c, e.lhs, nil); - let bu: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, e.lhs, nil); + let bu: *syntax.node = resolvealias(c, unwrapbang(basetn)); if (bu == nil) { return nil; }; - if (bu.kind == nkind.N_TARRAY) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + if (bu.kind == syntax.nkind.N_TARRAY) { + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = bu.lhs; e.type_ = tinfofornode(c, sl): *void; return sl; }; - if (bu.kind == nkind.N_TSLICE) { + if (bu.kind == syntax.nkind.N_TSLICE) { e.type_ = tinfofornode(c, basetn): *void; return basetn; }; - if (bu.kind == nkind.N_TNAME) { - if (streq(bu.str, "str")) { - let tn: *node = mktname(c, "str"); + if (bu.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(bu.str, "str")) { + let tn: *syntax.node = mktname(c, "str"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14668,15 +14668,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // the index route (idxeffti) and unlike Hare. Loud on the // usual []T annotation; for-range likewise. Team task #18 // (#61-residual A). - if (bu.kind == nkind.N_TPTR && bu.lhs != nil) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + if (bu.kind == syntax.nkind.N_TPTR && bu.lhs != nil) { + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = bu.lhs; e.type_ = tinfofornode(c, sl): *void; return sl; }; return nil; }; - if (k == nkind.N_TUPLE) { + if (k == syntax.nkind.N_TUPLE) { // A.6.2.0b — head-only stamp of the tuple expression's // overall type. Mirrors cstage cmd/wcc/check.c:1437-1451 // N_TUPLE: walk e.list, type each element via exprtype, and @@ -14692,47 +14692,47 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // expression), so empty is unreachable and yields nil here // (matches scruttype L656 / A.6.1.5b N_DOT lenient-on-miss). if (e.list == nil) { return nil; }; - let head: *node = nil; - let tail: *node = nil; - let it: *node = e.list; + let head: *syntax.node = nil; + let tail: *syntax.node = nil; + let it: *syntax.node = e.list; for (it != nil) { - let elemt: *node = exprtype(c, it, nil); - let w: *node = newnode(nkind.N_TPARAM, "", 0, 0); + let elemt: *syntax.node = exprtype(c, it, nil); + let w: *syntax.node = syntax.newnode(syntax.nkind.N_TPARAM, "", 0, 0); w.lhs = elemt; if (head == nil) { head = w; } else { tail.next = w; }; tail = w; it = it.next; }; - let tt: *node = newnode(nkind.N_TTUPLE, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTUPLE, "", 0, 0); tt.list = head; e.type_ = tinfofornode(c, tt): *void; return tt; }; - if (k == nkind.N_RECV) { + if (k == syntax.nkind.N_RECV) { // A.6.2.0d — head-only stamp of the receive expression's // overall type. Mirrors cstage cmd/wcc/check.c:1230-1236 // N_RECV: peel alias on the channel base; chan T → T. // Documented cstage divergence: cstage L1234 errors on a // non-chan base; wwstage returns nil (lenient on miss), // matching scruttype L656 / A.6.1.5b N_DOT precedent. - let basetn: *node = exprtype(c, e.lhs, nil); - let bu: *node = resolvealias(c, unwrapbang(basetn)); + let basetn: *syntax.node = exprtype(c, e.lhs, nil); + let bu: *syntax.node = resolvealias(c, unwrapbang(basetn)); if (bu == nil) { return nil; }; - if (bu.kind == nkind.N_TCHAN) { + if (bu.kind == syntax.nkind.N_TCHAN) { e.type_ = tinfofornode(c, bu.lhs): *void; return bu.lhs; }; return nil; }; - if (k == nkind.N_SPREAD) { + if (k == syntax.nkind.N_SPREAD) { // A.6.2.0e — pass-through stamp. Mirrors cstage check.c:1212-1213. // The spread expression `xs...` carries the operand's type. - let t: *node = exprtype(c, e.lhs, nil); + let t: *syntax.node = exprtype(c, e.lhs, nil); if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; return t; }; - if (k == nkind.N_MATCH) { + if (k == syntax.nkind.N_MATCH) { // A.6.2.0g — port of cstage cmd/wcc/check.c:1316-1330 match-as- // expression stamp. The match's type is the first arm's yield // operand type; void if no arm yields. Wwstage skips cstage's @@ -14747,15 +14747,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // node (nil on the post-walk cached read) for the assignability // node the consumers (checkletassign/checkretassign) read off this // arm's *node return; see matchyieldtype's docstring + #279. - let yt: *tinfo = nil; - let retn: *node = nil; - let cs: *node = e.list; + let yt: *syntax.tinfo = nil; + let retn: *syntax.node = nil; + let cs: *syntax.node = e.list; for (cs != nil) { // cs.str/cs.lhs = the arm's case-binding name + declared // type (the N_MCASE binder); fed to matchyieldtype's #241 // scope-popped `yield ` fallback. - let armn: *node = nil; - let t: *tinfo = matchyieldtype(c, cs.body, cs.str, cs.lhs, &armn); + let armn: *syntax.node = nil; + let t: *syntax.tinfo = matchyieldtype(c, cs.body, cs.str, cs.lhs, &armn); if (t != nil) { if (yt == nil) { // First yielding arm: it is the match's type; @@ -14782,7 +14782,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // untyped_float) - a precision gap, not a silent // miscompile of the catA repro; closeable only with a // real tinfo type_assignable. - if (!typeeq(yt, t)) { + if (!syntax.typeeq(yt, t)) { let ca: i32 = yieldclass(yt); let cb: i32 = yieldclass(t); if (ca != 0i32 && cb != 0i32 && ca != cb) { @@ -14799,7 +14799,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = yt: *void; return retn; }; - if (k == nkind.N_YIELD) { + if (k == syntax.nkind.N_YIELD) { // A.6.2.0f — pass-through stamp; cstage check.c:1708 does NOT // stamp N_YIELD (statement-shaped). Wwstage's A.6.2 invariant // requires every post-dispatch kind have type_ set. Yield's @@ -14808,25 +14808,25 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // expression with a type). Bare `yield;` (no operand) stamps // void. if (e.lhs == nil) { - let v: *node = mktname(c, "void"); + let v: *syntax.node = mktname(c, "void"); e.type_ = tinfofornode(c, v): *void; return v; }; - let t: *node = exprtype(c, e.lhs, nil); + let t: *syntax.node = exprtype(c, e.lhs, nil); if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; return t; }; - if (k == nkind.N_TRYPROP) { + if (k == syntax.nkind.N_TRYPROP) { // success unwrap: the success-variant type of operand's // tagged union. - let opt: *node = exprtype(c, e.lhs, nil); - let ou: *node = resolvealias(c, unwrapbang(opt)); + let opt: *syntax.node = exprtype(c, e.lhs, nil); + let ou: *syntax.node = resolvealias(c, unwrapbang(opt)); if (ou == nil) { return nil; }; - if (ou.kind != nkind.N_TTAGGED) { return nil; }; + if (ou.kind != syntax.nkind.N_TTAGGED) { return nil; }; // Hare semantics: success = first non-error variant if // any !-flag is present; else first variant. if (taggedhaserr(c, ou)) { - let v: *node = ou.list; + let v: *syntax.node = ou.list; for (v != nil) { if (!iserrvariant(c, ou, v)) { e.type_ = tinfofornode(c, v): *void; @@ -14839,16 +14839,16 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, ou.list): *void; return ou.list; }; - if (k == nkind.N_TRYUNW) { + if (k == syntax.nkind.N_TRYUNW) { // `e!` abort-on-error unwrap; success variant is what the // receiver gets, identical to `?` shape modulo control flow. // #31: required so `let p: *T = alloc(v)!;` resolves to *T. - let opt: *node = exprtype(c, e.lhs, nil); - let ou: *node = resolvealias(c, unwrapbang(opt)); + let opt: *syntax.node = exprtype(c, e.lhs, nil); + let ou: *syntax.node = resolvealias(c, unwrapbang(opt)); if (ou == nil) { return nil; }; - if (ou.kind != nkind.N_TTAGGED) { return nil; }; + if (ou.kind != syntax.nkind.N_TTAGGED) { return nil; }; if (taggedhaserr(c, ou)) { - let v: *node = ou.list; + let v: *syntax.node = ou.list; for (v != nil) { if (!iserrvariant(c, ou, v)) { e.type_ = tinfofornode(c, v): *void; @@ -14861,15 +14861,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, ou.list): *void; return ou.list; }; - if (k == nkind.N_TYPEASSERT) { + if (k == syntax.nkind.N_TYPEASSERT) { // `e as T` → T. Mirrors cstage cmd/wcc/check.c TYPEASSERT // `n->type = resolve_type(c, n->rhs)`. e.type_ = tinfofornode(c, e.rhs): *void; return e.rhs; }; - if (k == nkind.N_TYPETEST) { + if (k == syntax.nkind.N_TYPETEST) { // `e is T` → bool - let tn: *node = mktname(c, "bool"); + let tn: *syntax.node = mktname(c, "bool"); e.type_ = tinfofornode(c, tn): *void; return tn; }; @@ -14879,22 +14879,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { // isuntypedint / is_str_like / is_bool_like — helpers used // by the assignability check below to allow common AST shapes // through without needing real type inference. -fn isuntypedint(t: *node) bool = { +fn isuntypedint(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "untyped_int"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "untyped_int"); }; -fn isuntypedfloat(t: *node) bool = { +fn isuntypedfloat(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "untyped_float"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "untyped_float"); }; -fn isuntypednil(t: *node) bool = { +fn isuntypednil(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "untyped_nil"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "untyped_nil"); }; // isinttypeast — int-typed AST node. Either a primitive int name @@ -14902,24 +14902,24 @@ fn isuntypednil(t: *node) bool = { // excluded so the enum↔int reinterpret in checkisas (#52) refuses a // surprise `enum as f64` shape. Mirrors cstage's type_isint // (cmd/wcc/type.c) restricted to the kinds reachable from AST. -fn isinttypeast(t: *node) bool = { +fn isinttypeast(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind == nkind.N_TENUM) { return true; }; - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind == syntax.nkind.N_TENUM) { return true; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let s: str = t.str; - if (streq(s, "i8")) { return true; }; - if (streq(s, "i16")) { return true; }; - if (streq(s, "i32")) { return true; }; - if (streq(s, "i64")) { return true; }; - if (streq(s, "u8")) { return true; }; - if (streq(s, "u16")) { return true; }; - if (streq(s, "u32")) { return true; }; - if (streq(s, "u64")) { return true; }; - if (streq(s, "int")) { return true; }; - if (streq(s, "uint")) { return true; }; - if (streq(s, "uintptr")) { return true; }; - if (streq(s, "size")) { return true; }; - if (streq(s, "rune")) { return true; }; + if (syntax.streq(s, "i8")) { return true; }; + if (syntax.streq(s, "i16")) { return true; }; + if (syntax.streq(s, "i32")) { return true; }; + if (syntax.streq(s, "i64")) { return true; }; + if (syntax.streq(s, "u8")) { return true; }; + if (syntax.streq(s, "u16")) { return true; }; + if (syntax.streq(s, "u32")) { return true; }; + if (syntax.streq(s, "u64")) { return true; }; + if (syntax.streq(s, "int")) { return true; }; + if (syntax.streq(s, "uint")) { return true; }; + if (syntax.streq(s, "uintptr")) { return true; }; + if (syntax.streq(s, "size")) { return true; }; + if (syntax.streq(s, "rune")) { return true; }; return false; }; @@ -14933,64 +14933,64 @@ fn isinttypeast(t: *node) bool = { // (chasing) accepts. nil operands are treated as already-errored upstream // (the unifyarith nil-bail shapes) and NOT re-rejected — the cstage twin's // `l == ty_err` escape. -fn intkindast(c: *checker, t: *node) bool = { +fn intkindast(c: *checker, t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (isinttypeast(u)) { return true; }; // int family + enum + rune if (isuntypedint(u)) { return true; }; - if (u != nil && u.kind == nkind.N_TNAME && streq(u.str, "untyped_rune")) { + if (u != nil && u.kind == syntax.nkind.N_TNAME && syntax.streq(u.str, "untyped_rune")) { return true; }; return false; }; -fn numkindast(c: *checker, t: *node) bool = { +fn numkindast(c: *checker, t: *syntax.node) bool = { if (intkindast(c, t)) { return true; }; if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return false; }; - if (u.kind != nkind.N_TNAME) { return false; }; + if (u.kind != syntax.nkind.N_TNAME) { return false; }; let s: str = u.str; - if (streq(s, "f32")) { return true; }; - if (streq(s, "f64")) { return true; }; - if (streq(s, "untyped_float")) { return true; }; + if (syntax.streq(s, "f32")) { return true; }; + if (syntax.streq(s, "f64")) { return true; }; + if (syntax.streq(s, "untyped_float")) { return true; }; return false; }; -fn boolkindast(c: *checker, t: *node) bool = { +fn boolkindast(c: *checker, t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *node = resolvealias(c, unwrapbang(t)); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return false; }; - if (u.kind != nkind.N_TNAME) { return false; }; - return streq(u.str, "bool") || streq(u.str, "untyped_bool"); + if (u.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(u.str, "bool") || syntax.streq(u.str, "untyped_bool"); }; -fn isnumerictname(t: *node) bool = { +fn isnumerictname(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let s: str = t.str; - if (streq(s, "i8")) { return true; }; - if (streq(s, "i16")) { return true; }; - if (streq(s, "i32")) { return true; }; - if (streq(s, "i64")) { return true; }; - if (streq(s, "u8")) { return true; }; - if (streq(s, "u16")) { return true; }; - if (streq(s, "u32")) { return true; }; - if (streq(s, "u64")) { return true; }; - if (streq(s, "int")) { return true; }; - if (streq(s, "uint")) { return true; }; - if (streq(s, "uintptr")) { return true; }; - if (streq(s, "size")) { return true; }; - if (streq(s, "rune")) { return true; }; - if (streq(s, "f32")) { return true; }; - if (streq(s, "f64")) { return true; }; + if (syntax.streq(s, "i8")) { return true; }; + if (syntax.streq(s, "i16")) { return true; }; + if (syntax.streq(s, "i32")) { return true; }; + if (syntax.streq(s, "i64")) { return true; }; + if (syntax.streq(s, "u8")) { return true; }; + if (syntax.streq(s, "u16")) { return true; }; + if (syntax.streq(s, "u32")) { return true; }; + if (syntax.streq(s, "u64")) { return true; }; + if (syntax.streq(s, "int")) { return true; }; + if (syntax.streq(s, "uint")) { return true; }; + if (syntax.streq(s, "uintptr")) { return true; }; + if (syntax.streq(s, "size")) { return true; }; + if (syntax.streq(s, "rune")) { return true; }; + if (syntax.streq(s, "f32")) { return true; }; + if (syntax.streq(s, "f64")) { return true; }; return false; }; -fn isstrtname(t: *node) bool = { +fn isstrtname(t: *syntax.node) bool = { if (t == nil) { return false; }; - if (t.kind != nkind.N_TNAME) { return false; }; - return streq(t.str, "str"); + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + return syntax.streq(t.str, "str"); }; // tagshape — #24/#37: the coarse variant-shape bucket of a (resolved) type @@ -15001,9 +15001,9 @@ fn isstrtname(t: *node) bool = { // aggregate-shape-lenient leg to keep a tagged accept lenient ONLY against a // shape-compatible variant — same classifier cgen boxes with, so the checker // accept and the cgen box agree (rule-12: reuse the in-tree classifier). -fn tagshape(t: *node) i32 = { +fn tagshape(t: *syntax.node) i32 = { if (t == nil) { return 0i32; }; - if (t.kind == nkind.N_TSLICE) { return 2i32; }; + if (t.kind == syntax.nkind.N_TSLICE) { return 2i32; }; if (isstrtname(t)) { return 1i32; }; return 0i32; }; @@ -15014,14 +15014,14 @@ fn tagshape(t: *node) i32 = { // Mirror of cstage addrfn_ptr_matches (cmd/wcc/check.c, project #206); // reuses typeeqast — the same structural-fn comparator cstage uses via // type_eq(TY_FN,TY_FN) — for symmetry. -fn addrfnptrmatches(c: *checker, ptr: *node, synth: *node) bool = { +fn addrfnptrmatches(c: *checker, ptr: *syntax.node, synth: *syntax.node) bool = { if (ptr == nil) { return false; }; - let pu: *node = resolvealias(c, unwrapbang(ptr)); + let pu: *syntax.node = resolvealias(c, unwrapbang(ptr)); if (pu == nil) { return false; }; - if (pu.kind != nkind.N_TPTR) { return false; }; - let ref: *node = resolvealias(c, unwrapbang(pu.lhs)); + if (pu.kind != syntax.nkind.N_TPTR) { return false; }; + let ref: *syntax.node = resolvealias(c, unwrapbang(pu.lhs)); if (ref == nil) { return false; }; - if (ref.kind != nkind.N_TFN) { return false; }; + if (ref.kind != syntax.nkind.N_TFN) { return false; }; return typeeqast(c, synth, ref); }; @@ -15040,35 +15040,35 @@ fn addrfnptrmatches(c: *checker, ptr: *node, synth: *node) bool = { // the rhs node. N_FNDECL and N_TFN share parseparams' param-node shape // (lib/ww/parse/decl.ww + parse.ww), so a synthetic N_TFN over the fn // decl's lhs/list compares correctly under typeeqast. -fn assignableaddrfn(c: *checker, dst: *node, rhs: *node) bool = { +fn assignableaddrfn(c: *checker, dst: *syntax.node, rhs: *syntax.node) bool = { if (dst == nil) { return false; }; if (rhs == nil) { return false; }; - if (rhs.kind != nkind.N_UN) { return false; }; - if (rhs.op != tkind.TK_AMP) { return false; }; - let id: *node = rhs.lhs; + if (rhs.kind != syntax.nkind.N_UN) { return false; }; + if (rhs.op != syntax.tkind.TK_AMP) { return false; }; + let id: *syntax.node = rhs.lhs; if (id == nil) { return false; }; - if (id.kind != nkind.N_IDENT) { return false; }; + if (id.kind != syntax.nkind.N_IDENT) { return false; }; // #4: curmod preference. Without it a `&handler` whose leaf also // names a fn in a later module misbinds the foreign fn's signature // here (scopedefineinmodule prepends → chain-first = last module), // silently admitting a *fn into a foreign-sig slot or rejecting a // valid same-module &fn. cstage uses scope_lookup_prefer with // cur_mod (cmd/wcc/check.c:410, assignable_addrfn). - let s: *sym = scopelookupprefer(c.cur, c.curmod, id.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, id.str); if (s == nil) { return false; }; - if (s.skind != skind.SK_FN) { return false; }; + if (s.skind != syntax.skind.SK_FN) { return false; }; if (s.decl == nil) { return false; }; - let d: *node = s.decl; - if (d.kind != nkind.N_FNDECL) { return false; }; - let synth: *node = newnode(nkind.N_TFN, "", 0, 0); + let d: *syntax.node = s.decl; + if (d.kind != syntax.nkind.N_FNDECL) { return false; }; + let synth: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, "", 0, 0); synth.lhs = d.lhs; synth.list = d.list; - let du: *node = resolvealias(c, unwrapbang(dst)); + let du: *syntax.node = resolvealias(c, unwrapbang(dst)); if (du == nil) { return false; }; - if (du.kind == nkind.N_TPTR) { return addrfnptrmatches(c, du, synth); }; - if (du.kind == nkind.N_TTAGGED) { + if (du.kind == syntax.nkind.N_TPTR) { return addrfnptrmatches(c, du, synth); }; + if (du.kind == syntax.nkind.N_TTAGGED) { let nmatch: i32 = 0; - let v: *node = du.list; + let v: *syntax.node = du.list; for (v != nil) { if (addrfnptrmatches(c, v, synth)) { nmatch = nmatch + 1; }; v = v.next; @@ -15085,13 +15085,13 @@ fn assignableaddrfn(c: *checker, dst: *node, rhs: *node) bool = { // `confident` lets the caller decide whether to emit an error // when the result is false: if !confident, the caller should not // flag it. -fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { +fn isassignable(c: *checker, dst: *syntax.node, src: *syntax.node, confident: *bool) bool = { *confident = false; if (dst == nil) { return true; }; // no declared target if (src == nil) { return true; }; // unknown src type *confident = true; - let du: *node = resolvealias(c, unwrapbang(dst)); - let su: *node = resolvealias(c, unwrapbang(src)); + let du: *syntax.node = resolvealias(c, unwrapbang(dst)); + let su: *syntax.node = resolvealias(c, unwrapbang(src)); if (du == nil) { *confident = false; return true; }; if (su == nil) { *confident = false; return true; }; if (typeeqast(c, du, su)) { return true; }; @@ -15102,8 +15102,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // reject (mirror cstage type.c type_assignable's #258 arm + fallthrough // to 0). The acceptance sites then desugar the array expr to an // explicit full slice via desugararrayslice; cgen is untouched. - if (du.kind == nkind.N_TSLICE) { - if (su.kind == nkind.N_TARRAY) { + if (du.kind == syntax.nkind.N_TSLICE) { + if (su.kind == syntax.nkind.N_TARRAY) { if (typeeqast(c, du.lhs, su.lhs)) { return true; }; return false; }; @@ -15112,10 +15112,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { if (isuntypedint(su)) { if (isnumerictname(du)) { return true; }; // (T | ...) tagged: only OK if some variant accepts untyped_int. - if (du.kind == nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { if (isnumerictname(vu)) { return true; }; // mirror cstage type_isnum(enum)=true (type.c:201 -> @@ -15123,7 +15123,7 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // accept an untyped int. Without this the #23 fix would // flip an enum-variant union to reject while cstage // accepts = a NEW divergence (A3 trap). - if (vu.kind == nkind.N_TENUM) { return true; }; + if (vu.kind == syntax.nkind.N_TENUM) { return true; }; }; v = v.next; }; @@ -15136,8 +15136,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // general call-arg check made this path reachable). Mirror the // tagged→tagged spread escape (:4117). Spread decl-form flatten // is #199b, deferred. - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { *confident = false; return true; }; @@ -15156,10 +15156,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { return false; }; // Known non-numeric primitive: confidently wrong. - if (du.kind == nkind.N_TNAME) { - if (streq(du.str, "bool")) { return false; }; - if (streq(du.str, "void")) { return false; }; - if (streq(du.str, "str")) { return false; }; + if (du.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(du.str, "bool")) { return false; }; + if (syntax.streq(du.str, "void")) { return false; }; + if (syntax.streq(du.str, "str")) { return false; }; }; // #24: untyped int into a known AGGREGATE (slice/array/ptr/fn/chan/ // tuple/struct) — confident reject. `let xs: []int = 5` read the int @@ -15167,10 +15167,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // left it unconfident → silent accept). cstage type_assignable // rejects untyped_int into a non-numeric aggregate (cmd/wcc/type.c). // The TTAGGED case is handled above; this is the bare aggregate. - if (du.kind == nkind.N_TSLICE || du.kind == nkind.N_TARRAY - || du.kind == nkind.N_TPTR || du.kind == nkind.N_TFN - || du.kind == nkind.N_TCHAN || du.kind == nkind.N_TTUPLE - || du.kind == nkind.N_TSTRUCT) { + if (du.kind == syntax.nkind.N_TSLICE || du.kind == syntax.nkind.N_TARRAY + || du.kind == syntax.nkind.N_TPTR || du.kind == syntax.nkind.N_TFN + || du.kind == syntax.nkind.N_TCHAN || du.kind == syntax.nkind.N_TTUPLE + || du.kind == syntax.nkind.N_TSTRUCT) { return false; }; // Unknown shapes: stay quiet. @@ -15179,10 +15179,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { }; if (isuntypedfloat(su)) { if (isnumerictname(du)) { return true; }; - if (du.kind == nkind.N_TNAME) { - if (streq(du.str, "bool")) { return false; }; - if (streq(du.str, "void")) { return false; }; - if (streq(du.str, "str")) { return false; }; + if (du.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(du.str, "bool")) { return false; }; + if (syntax.streq(du.str, "void")) { return false; }; + if (syntax.streq(du.str, "str")) { return false; }; }; // A4 (#23 float-twin): (T | ...) tagged dst — accept iff a DIRECT // variant is a float type. cstage type_assignable for an @@ -15194,22 +15194,22 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // true (:3777). Without it the catch-all (:3972) over-accepts an // untyped float into ANY tagged (silent tag=0). Faithful // flatten+rebox deferred post-CSP (nominal id, #23/#40). - if (du.kind == nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { - if (vu.kind == nkind.N_TNAME) { - if (streq(vu.str, "f32")) { return true; }; - if (streq(vu.str, "f64")) { return true; }; + if (vu.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(vu.str, "f32")) { return true; }; + if (syntax.streq(vu.str, "f64")) { return true; }; }; }; v = v.next; }; // #24: spread variant keeps the lenient escape (cstage flattens; // wwstage can't) — same rationale as the untyped-int arm above. - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { *confident = false; return true; }; @@ -15218,10 +15218,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { }; // #24: untyped float into a known AGGREGATE — confident reject (twin // of the untyped-int aggregate arm above; `let xs: []f64 = 1.5`). - if (du.kind == nkind.N_TSLICE || du.kind == nkind.N_TARRAY - || du.kind == nkind.N_TPTR || du.kind == nkind.N_TFN - || du.kind == nkind.N_TCHAN || du.kind == nkind.N_TTUPLE - || du.kind == nkind.N_TSTRUCT) { + if (du.kind == syntax.nkind.N_TSLICE || du.kind == syntax.nkind.N_TARRAY + || du.kind == syntax.nkind.N_TPTR || du.kind == syntax.nkind.N_TFN + || du.kind == syntax.nkind.N_TCHAN || du.kind == syntax.nkind.N_TTUPLE + || du.kind == syntax.nkind.N_TSTRUCT) { return false; }; *confident = false; @@ -15229,25 +15229,25 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { }; if (isuntypednil(su)) { // nil → ptr/slice/chan/fn/nullable - if (du.kind == nkind.N_TPTR) { return true; }; - if (du.kind == nkind.N_TSLICE) { return true; }; - if (du.kind == nkind.N_TCHAN) { return true; }; - if (du.kind == nkind.N_TFN) { return true; }; + if (du.kind == syntax.nkind.N_TPTR) { return true; }; + if (du.kind == syntax.nkind.N_TSLICE) { return true; }; + if (du.kind == syntax.nkind.N_TCHAN) { return true; }; + if (du.kind == syntax.nkind.N_TFN) { return true; }; // nullable `(*T | void)` — already accepted by typeeqast // when matched whole; nil is OK there too. - if (du.kind == nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { - if (v.kind == nkind.N_TPTR) { return true; }; - if (v.kind == nkind.N_TSLICE) { return true; }; - if (v.kind == nkind.N_TCHAN) { return true; }; - if (v.kind == nkind.N_TFN) { return true; }; + if (v.kind == syntax.nkind.N_TPTR) { return true; }; + if (v.kind == syntax.nkind.N_TSLICE) { return true; }; + if (v.kind == syntax.nkind.N_TCHAN) { return true; }; + if (v.kind == syntax.nkind.N_TFN) { return true; }; v = v.next; }; // #24: spread variant keeps the lenient escape (cstage flattens; // wwstage can't) — same rationale as the untyped-int arm above. - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { *confident = false; return true; }; @@ -15272,8 +15272,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // harec keeps the drill at types.c:702-739 (#199b deferred port). // Restores SSoT with `is`/`as` non-recursive lookup (#198 sibling). // Callers compose `let inner: Wrapper = sub; let r: parent = inner;`. - if (du.kind == nkind.N_TTAGGED && su.kind != nkind.N_TTAGGED) { - let v: *node = du.list; + if (du.kind == syntax.nkind.N_TTAGGED && su.kind != syntax.nkind.N_TTAGGED) { + let v: *syntax.node = du.list; for (v != nil) { // Spread `...wrapper` keeps the recursive drill: the // wrapper's flat variants are intentionally inlined into @@ -15281,10 +15281,10 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // expanded yet (cstage flattens at resolve_type; wwstage // stays AST-keyed). Plain wrapper variant gets the // direct-only gate. - let vspread: bool = (v.op == tkind.TK_ELLIPSIS); - let vu: *node = resolvealias(c, unwrapbang(v)); + let vspread: bool = (v.op == syntax.tkind.TK_ELLIPSIS); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); let vtagged: bool = false; - if (vu != nil) { if (vu.kind == nkind.N_TTAGGED) { vtagged = true; }; }; + if (vu != nil) { if (vu.kind == syntax.nkind.N_TTAGGED) { vtagged = true; }; }; if (vtagged && !vspread) { if (typeeqast(c, v, src)) { return true; }; } else { @@ -15341,11 +15341,11 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // qualleaf bridge). Pre-c3 the collision was ALSO accepted (call-arg // ran no check; let/return short-circuited on the scalar variant) — c3 // is NEUTRAL on it. - if (su.kind != nkind.N_TNAME) { + if (su.kind != syntax.nkind.N_TNAME) { let ss: i32 = tagshape(su); - let sp: *node = du.list; + let sp: *syntax.node = du.list; for (sp != nil) { - let svu: *node = resolvealias(c, unwrapbang(sp)); + let svu: *syntax.node = resolvealias(c, unwrapbang(sp)); if (svu != nil) { if (tagshape(svu) == ss) { *confident = false; @@ -15363,7 +15363,7 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // (don't be confident) — common when forwarding a fallible // return through another fn with the same shape but possibly // a different surface spelling. - if (du.kind == nkind.N_TTAGGED && su.kind == nkind.N_TTAGGED) { + if (du.kind == syntax.nkind.N_TTAGGED && su.kind == syntax.nkind.N_TTAGGED) { // #205: NAMED-variant nominal compare BEFORE permissive // fallthrough. Mirror of cstage type.c type_assignable // tagged→tagged arm (#199 α concrete→tagged sibling). @@ -15372,11 +15372,11 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // identity — wrapper's leaves are NOT direct variants of // dst, so a structural subset walk would reject. SSoT // with `is`/`as` variant lookup (#198 family). - let v: *node = du.list; + let v: *syntax.node = du.list; for (v != nil) { - let vu: *node = resolvealias(c, unwrapbang(v)); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); if (vu != nil) { - if (vu.kind == nkind.N_TTAGGED) { + if (vu.kind == syntax.nkind.N_TTAGGED) { if (typeeqast(c, v, src)) { return true; }; }; }; @@ -15390,11 +15390,11 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // spread-widen cstage accepts → new cs≠ww divergence. Spread // decl-form layout is #199b, deferred. let hasspread: bool = false; - for (let p: *node = du.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { hasspread = true; }; + for (let p: *syntax.node = du.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { hasspread = true; }; }; - for (let p: *node = su.list; p != nil; p = p.next) { - if (p.op == tkind.TK_ELLIPSIS) { hasspread = true; }; + for (let p: *syntax.node = su.list; p != nil; p = p.next) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { hasspread = true; }; }; if (hasspread) { *confident = false; @@ -15419,15 +15419,15 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // gap. Sound for the bootstrap — no two of its variants share a leaf // (drew); the cross-module same-leaf collision (a.foo vs b.foo) is a // known over-accept deferred to #10 / filed in the #4 census. - for (let sp: *node = su.list; sp != nil; sp = sp.next) { + for (let sp: *syntax.node = su.list; sp != nil; sp = sp.next) { let ok: bool = false; - for (let dp: *node = du.list; dp != nil; dp = dp.next) { + for (let dp: *syntax.node = du.list; dp != nil; dp = dp.next) { if (typeeqast(c, dp, sp)) { ok = true; break; }; - let su2: *node = unwrapbang(sp); - let du2: *node = unwrapbang(dp); + let su2: *syntax.node = unwrapbang(sp); + let du2: *syntax.node = unwrapbang(dp); if (su2 != nil && du2 != nil && - su2.kind == nkind.N_TNAME && du2.kind == nkind.N_TNAME && - streq(qualleaf(su2.str), qualleaf(du2.str))) { + su2.kind == syntax.nkind.N_TNAME && du2.kind == syntax.nkind.N_TNAME && + syntax.streq(qualleaf(su2.str), qualleaf(du2.str))) { ok = true; break; }; }; @@ -15438,18 +15438,18 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // tagged → non-tagged: requires `?` / `!` / match to project a // variant. #31: this is what traps `let p: *T = alloc(v);` // where the builtin returns `(*T | nomem)` and the LHS is bare. - if (su.kind == nkind.N_TTAGGED && du.kind != nkind.N_TTAGGED) { + if (su.kind == syntax.nkind.N_TTAGGED && du.kind != syntax.nkind.N_TTAGGED) { return false; }; // Two known primitives with different names are confidently // incompatible. `i32 ↔ bool`, `str ↔ i32`, etc. - if (du.kind == nkind.N_TNAME && su.kind == nkind.N_TNAME) { + if (du.kind == syntax.nkind.N_TNAME && su.kind == syntax.nkind.N_TNAME) { let known_d: bool = isnumerictname(du) || isstrtname(du); - if (!known_d) { if (streq(du.str, "bool")) { known_d = true; }; }; - if (!known_d) { if (streq(du.str, "void")) { known_d = true; }; }; + if (!known_d) { if (syntax.streq(du.str, "bool")) { known_d = true; }; }; + if (!known_d) { if (syntax.streq(du.str, "void")) { known_d = true; }; }; let known_s: bool = isnumerictname(su) || isstrtname(su); - if (!known_s) { if (streq(su.str, "bool")) { known_s = true; }; }; - if (!known_s) { if (streq(su.str, "void")) { known_s = true; }; }; + if (!known_s) { if (syntax.streq(su.str, "bool")) { known_s = true; }; }; + if (!known_s) { if (syntax.streq(su.str, "void")) { known_s = true; }; }; if (known_d) { if (known_s) { // Both primitives, different names → no. @@ -15467,14 +15467,14 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // handled at the assignment caller sites via assignableaddrfn, NOT // here. Without this the lenient catch-all below silently accepted // the laundering shape. - if (du.kind == nkind.N_TPTR) { - if (su.kind == nkind.N_TPTR) { - let dref: *node = resolvealias(c, unwrapbang(du.lhs)); - let sref: *node = resolvealias(c, unwrapbang(su.lhs)); + if (du.kind == syntax.nkind.N_TPTR) { + if (su.kind == syntax.nkind.N_TPTR) { + let dref: *syntax.node = resolvealias(c, unwrapbang(du.lhs)); + let sref: *syntax.node = resolvealias(c, unwrapbang(su.lhs)); if (dref != nil) { if (sref != nil) { - if (dref.kind == nkind.N_TFN) { - if (sref.kind == nkind.N_TFN) { + if (dref.kind == syntax.nkind.N_TFN) { + if (sref.kind == syntax.nkind.N_TFN) { return false; }; }; @@ -15492,8 +15492,8 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // The matched-sig case already returned true via typeeqast at the top. // The `&fn` (*fn) vs bare-fn KIND mismatch (du N_TFN, su N_TPTR) is a // different shape, closed by c3's aggregate-kind reject, not here. - if (du.kind == nkind.N_TFN) { - if (su.kind == nkind.N_TFN) { + if (du.kind == syntax.nkind.N_TFN) { + if (su.kind == syntax.nkind.N_TFN) { return false; }; }; @@ -15515,20 +15515,20 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // rejects via structural type_assignable, a filed residual under-reject, // NOT a new over-reject. A NAMED struct/alias dst that does NOT resolve // to a known kind stays N_TNAME-non-prim → neither set → lenient. - let dprim: bool = du.kind == nkind.N_TNAME + let dprim: bool = du.kind == syntax.nkind.N_TNAME && (isnumerictname(du) || isstrtname(du) - || streq(du.str, "bool") || streq(du.str, "void")); - let sprim: bool = su.kind == nkind.N_TNAME + || syntax.streq(du.str, "bool") || syntax.streq(du.str, "void")); + let sprim: bool = su.kind == syntax.nkind.N_TNAME && (isnumerictname(su) || isstrtname(su) - || streq(su.str, "bool") || streq(su.str, "void")); - let daggr: bool = du.kind == nkind.N_TSLICE || du.kind == nkind.N_TARRAY - || du.kind == nkind.N_TPTR || du.kind == nkind.N_TFN - || du.kind == nkind.N_TCHAN || du.kind == nkind.N_TTUPLE - || du.kind == nkind.N_TSTRUCT; - let saggr: bool = su.kind == nkind.N_TSLICE || su.kind == nkind.N_TARRAY - || su.kind == nkind.N_TPTR || su.kind == nkind.N_TFN - || su.kind == nkind.N_TCHAN || su.kind == nkind.N_TTUPLE - || su.kind == nkind.N_TSTRUCT; + || syntax.streq(su.str, "bool") || syntax.streq(su.str, "void")); + let daggr: bool = du.kind == syntax.nkind.N_TSLICE || du.kind == syntax.nkind.N_TARRAY + || du.kind == syntax.nkind.N_TPTR || du.kind == syntax.nkind.N_TFN + || du.kind == syntax.nkind.N_TCHAN || du.kind == syntax.nkind.N_TTUPLE + || du.kind == syntax.nkind.N_TSTRUCT; + let saggr: bool = su.kind == syntax.nkind.N_TSLICE || su.kind == syntax.nkind.N_TARRAY + || su.kind == syntax.nkind.N_TPTR || su.kind == syntax.nkind.N_TFN + || su.kind == syntax.nkind.N_TCHAN || su.kind == syntax.nkind.N_TTUPLE + || su.kind == syntax.nkind.N_TSTRUCT; if (sprim && daggr) { return false; }; if (dprim && saggr) { return false; }; // #24: two aggregates of DIFFERENT kinds → confident reject (array/slice @@ -15542,7 +15542,7 @@ fn isassignable(c: *checker, dst: *node, src: *node, confident: *bool) bool = { // principle as the concrete→tagged aggregate-lenient arm above; the // struct-into-ptr genuine mismatch stays a filed #224/#10 under-reject. if (daggr && saggr && du.kind != su.kind - && du.kind != nkind.N_TSTRUCT && su.kind != nkind.N_TSTRUCT) { + && du.kind != syntax.nkind.N_TSTRUCT && su.kind != syntax.nkind.N_TSTRUCT) { return false; }; // Anything else: don't claim confidence. @@ -15602,15 +15602,15 @@ fn qualmod(nm: str, defmod: str) str = { // precise Type-identity form is #10 (tinfo SSoT). typeeqast handles the // exact-string cases first, so this fires only on the qualified-vs-bare // mix. -fn casevariantpairmatch(v: *node, pat: *node, unionmod: str) bool = { - let vv: *node = unwrapbang(v); - let pp: *node = unwrapbang(pat); +fn casevariantpairmatch(v: *syntax.node, pat: *syntax.node, unionmod: str) bool = { + let vv: *syntax.node = unwrapbang(v); + let pp: *syntax.node = unwrapbang(pat); if (vv == nil) { return false; }; if (pp == nil) { return false; }; - if (vv.kind != nkind.N_TNAME) { return false; }; - if (pp.kind != nkind.N_TNAME) { return false; }; - if (!streq(qualleaf(vv.str), qualleaf(pp.str))) { return false; }; - return streq(qualmod(vv.str, unionmod), qualmod(pp.str, unionmod)); + if (vv.kind != syntax.nkind.N_TNAME) { return false; }; + if (pp.kind != syntax.nkind.N_TNAME) { return false; }; + if (!syntax.streq(qualleaf(vv.str), qualleaf(pp.str))) { return false; }; + return syntax.streq(qualmod(vv.str, unionmod), qualmod(pp.str, unionmod)); }; // taggeddefmod — defining module of the typedecl whose body IS the @@ -15618,29 +15618,29 @@ fn casevariantpairmatch(v: *node, pat: *node, unionmod: str) bool = { // Bare variants in that body are defined here: io.error = // !(errors.error | underread | nomem) (module io) -> "io"; errors.error // -> "errors". Falls back to c.curmod when the chain can't resolve. -fn taggeddefmod(c: *checker, st: *node) str = { +fn taggeddefmod(c: *checker, st: *syntax.node) str = { let defmod: str = c.curmod; - let cur: *node = unwrapbang(st); + let cur: *syntax.node = unwrapbang(st); for (cur != nil) { - if (cur.kind != nkind.N_TNAME) { return defmod; }; - let s: *sym = aliassym(c, cur); + if (cur.kind != syntax.nkind.N_TNAME) { return defmod; }; + let s: *syntax.sym = aliassym(c, cur); if (s == nil) { return defmod; }; if (s.decl == nil) { return defmod; }; if (s.decl.nmod.len > 0) { defmod = s.decl.nmod; }; - let body: *node = unwrapbang(s.decl.lhs); + let body: *syntax.node = unwrapbang(s.decl.lhs); if (body == nil) { return defmod; }; - if (body.kind == nkind.N_TTAGGED) { return defmod; }; + if (body.kind == syntax.nkind.N_TTAGGED) { return defmod; }; cur = body; }; return defmod; }; -fn casecovers(c: *checker, cs: *node, want: *node, unionmod: str) bool = { +fn casecovers(c: *checker, cs: *syntax.node, want: *syntax.node, unionmod: str) bool = { if (cs.lhs != nil) { if (typeeqast(c, cs.lhs, want)) { return true; }; if (casevariantpairmatch(want, cs.lhs, unionmod)) { return true; }; }; - let alt: *node = cs.list; + let alt: *syntax.node = cs.list; for (alt != nil) { if (typeeqast(c, alt, want)) { return true; }; if (casevariantpairmatch(want, alt, unionmod)) { return true; }; @@ -15649,10 +15649,10 @@ fn casecovers(c: *checker, cs: *node, want: *node, unionmod: str) bool = { return false; }; -fn errmatchvariant(c: *checker, n: *node, vname: *node) void = { +fn errmatchvariant(c: *checker, n: *syntax.node, vname: *syntax.node) void = { cerr("match: variant not handled"); if (vname != nil) { - if (vname.kind == nkind.N_TNAME) { + if (vname.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(vname.str); cerr(")"); @@ -15673,13 +15673,13 @@ fn errmatchvariant(c: *checker, n: *node, vname: *node) void = { // attributing them the inner union's defining module. Mirrors cstage's // resolve_type flatten (cmd/wcc/check.c:651-674) at the AST layer; the // cgen side already dispatches off the flattened tinfo.params (#61a). -fn casevariantin(c: *checker, tagged: *node, pat: *node, unionmod: str) bool = { - let v: *node = tagged.list; +fn casevariantin(c: *checker, tagged: *syntax.node, pat: *syntax.node, unionmod: str) bool = { + let v: *syntax.node = tagged.list; for (v != nil) { - if (v.op == tkind.TK_ELLIPSIS) { - let inner: *node = resolvealias(c, unwrapbang(v)); + if (v.op == syntax.tkind.TK_ELLIPSIS) { + let inner: *syntax.node = resolvealias(c, unwrapbang(v)); if (inner != nil) { - if (inner.kind == nkind.N_TTAGGED) { + if (inner.kind == syntax.nkind.N_TTAGGED) { if (casevariantin(c, inner, pat, taggeddefmod(c, v))) { return true; @@ -15696,10 +15696,10 @@ fn casevariantin(c: *checker, tagged: *node, pat: *node, unionmod: str) bool = { return false; }; -fn errbadcase(c: *checker, pat: *node) void = { +fn errbadcase(c: *checker, pat: *syntax.node) void = { cerr("case: not a variant of scrutinee"); if (pat != nil) { - if (pat.kind == nkind.N_TNAME) { + if (pat.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(pat.str); cerr(")"); @@ -15709,10 +15709,10 @@ fn errbadcase(c: *checker, pat: *node) void = { c.errs += 1; }; -fn checkmatchexhaust(c: *checker, n: *node) void = { +fn checkmatchexhaust(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { return; }; - let st: *node = scruttype(c, n.lhs); + let st: *syntax.node = scruttype(c, n.lhs); // F9 (task #12): direct `match (expr?)` / `match (expr!)` — cstage // types the try-result as the success variant and rejects when it // is not itself a tagged union (check.c "match on non-tagged- @@ -15723,14 +15723,14 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { // normal exhaustiveness walk, matching cstage's accept. let istry: bool = false; if (st == nil) { - if (n.lhs.kind == nkind.N_TRYPROP || n.lhs.kind == nkind.N_TRYUNW) { + if (n.lhs.kind == syntax.nkind.N_TRYPROP || n.lhs.kind == syntax.nkind.N_TRYUNW) { istry = true; st = exprtype(c, n.lhs, nil); }; }; - let u: *node = resolvealias(c, unwrapbang(st)); + let u: *syntax.node = resolvealias(c, unwrapbang(st)); if (u == nil) { return; }; - if (u.kind != nkind.N_TTAGGED) { + if (u.kind != syntax.nkind.N_TTAGGED) { if (istry) { cerr("match on non-tagged-union try-result\n"); c.errs += 1; @@ -15745,13 +15745,13 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { // Validity: every `case T` pattern (and multi-pattern alts) // must name a variant of u. Catches typos and dead arms that // the dispatch would never reach. - let cs0: *node = n.list; + let cs0: *syntax.node = n.list; for (cs0 != nil) { if (cs0.lhs != nil) { if (!casevariantin(c, u, cs0.lhs, unionmod)) { errbadcase(c, cs0.lhs); }; - let alt: *node = cs0.list; + let alt: *syntax.node = cs0.list; for (alt != nil) { if (!casevariantin(c, u, alt, unionmod)) { errbadcase(c, alt); @@ -15762,13 +15762,13 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { cs0 = cs0.next; }; // Default arm absorbs anything; skip exhaustiveness. - let cs: *node = n.list; + let cs: *syntax.node = n.list; for (cs != nil) { if (cs.lhs == nil) { return; }; // default cs = cs.next; }; // For each variant of u, look for a covering case. - let v: *node = u.list; + let v: *syntax.node = u.list; for (v != nil) { checkvariantcovered(c, n, v, unionmod); v = v.next; @@ -15782,13 +15782,13 @@ fn checkmatchexhaust(c: *checker, n: *node) void = { // members are checked instead. Mirrors the casevariantin spread recursion // + cstage's flattened u->params exhaustiveness walk (cmd/wcc/check.c: // 1648-1669). Leaf variants keep their NODE so errmatchvariant names them. -fn checkvariantcovered(c: *checker, n: *node, v: *node, unionmod: str) void = { - if (v.op == tkind.TK_ELLIPSIS) { - let inner: *node = resolvealias(c, unwrapbang(v)); +fn checkvariantcovered(c: *checker, n: *syntax.node, v: *syntax.node, unionmod: str) void = { + if (v.op == syntax.tkind.TK_ELLIPSIS) { + let inner: *syntax.node = resolvealias(c, unwrapbang(v)); if (inner != nil) { - if (inner.kind == nkind.N_TTAGGED) { + if (inner.kind == syntax.nkind.N_TTAGGED) { let im: str = taggeddefmod(c, v); - let m: *node = inner.list; + let m: *syntax.node = inner.list; for (m != nil) { checkvariantcovered(c, n, m, im); m = m.next; @@ -15798,7 +15798,7 @@ fn checkvariantcovered(c: *checker, n: *node, v: *node, unionmod: str) void = { }; }; let covered: bool = false; - let cs2: *node = n.list; + let cs2: *syntax.node = n.list; for (cs2 != nil) { if (casecovers(c, cs2, v, unionmod)) { covered = true; @@ -15818,16 +15818,16 @@ fn checkvariantcovered(c: *checker, n: *node, v: *node, unionmod: str) void = { // (binary ops, complex exprs we don't infer), we stay quiet — full // type inference lives only on the C side. -fn errnotassign(c: *checker, dst: *node, src: *node, where: str) void = { +fn errnotassign(c: *checker, dst: *syntax.node, src: *syntax.node, where: str) void = { cerr(where); cerr(": not assignable"); if (src != nil) { - if (src.kind == nkind.N_TNAME) { + if (src.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(src.str); cerr(" → "); if (dst != nil) { - if (dst.kind == nkind.N_TNAME) { + if (dst.kind == syntax.nkind.N_TNAME) { cerr(dst.str); }; }; @@ -15849,26 +15849,26 @@ fn errnotassign(c: *checker, dst: *node, src: *node, where: str) void = { // the array-variant box is refused. Mirrors the concrete→tagged variant // select in isassignable (:3859) and cstage tagged_array_variant so the // variant chosen here is the one the box would materialize. -fn taggedarrayvariantctor(c: *checker, dst: *node, src: *node) bool = { +fn taggedarrayvariantctor(c: *checker, dst: *syntax.node, src: *syntax.node) bool = { if (dst == nil) { return false; }; if (src == nil) { return false; }; - let du: *node = resolvealias(c, unwrapbang(dst)); - let su: *node = resolvealias(c, unwrapbang(src)); + let du: *syntax.node = resolvealias(c, unwrapbang(dst)); + let su: *syntax.node = resolvealias(c, unwrapbang(src)); if (du == nil) { return false; }; - if (du.kind != nkind.N_TTAGGED) { return false; }; - if (su != nil) { if (su.kind == nkind.N_TTAGGED) { return false; }; }; - let v: *node = du.list; + if (du.kind != syntax.nkind.N_TTAGGED) { return false; }; + if (su != nil) { if (su.kind == syntax.nkind.N_TTAGGED) { return false; }; }; + let v: *syntax.node = du.list; for (v != nil) { - let vspread: bool = (v.op == tkind.TK_ELLIPSIS); - let vu: *node = resolvealias(c, unwrapbang(v)); + let vspread: bool = (v.op == syntax.tkind.TK_ELLIPSIS); + let vu: *syntax.node = resolvealias(c, unwrapbang(v)); let vtagged: bool = false; - if (vu != nil) { if (vu.kind == nkind.N_TTAGGED) { vtagged = true; }; }; + if (vu != nil) { if (vu.kind == syntax.nkind.N_TTAGGED) { vtagged = true; }; }; if (vtagged && !vspread) { if (typeeqast(c, v, src)) { return false; }; } else { let innerconf: bool = false; if (isassignable(c, v, src, &innerconf)) { - if (vu != nil) { if (vu.kind == nkind.N_TARRAY) { return true; }; }; + if (vu != nil) { if (vu.kind == syntax.nkind.N_TARRAY) { return true; }; }; return false; }; }; @@ -15887,7 +15887,7 @@ fn taggedarrayvariantctor(c: *checker, dst: *node, src: *node) bool = { // declared type at cgen, so no element-type restamp is needed — #251 // proved coerce_floatlit's restamp shape does NOT transfer (cgen reads // the declared type's element size, not the literal node's stamp). -fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { +fn checkarrlitfits(c: *checker, arrtn: *syntax.node, rhs: *syntax.node) void = { if (arrtn == nil) { return; }; if (rhs == nil) { return; }; // #106: chase a TY_NAMED alias (`type A=[2]int`) to the underlying @@ -15898,8 +15898,8 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // struct/return/call-arg) alias-aware by construction. arrtn = resolvealias(c, unwrapbang(arrtn)); if (arrtn == nil) { return; }; - if (arrtn.kind != nkind.N_TARRAY) { return; }; - if (rhs.kind != nkind.N_ARRLIT) { return; }; + if (arrtn.kind != syntax.nkind.N_TARRAY) { return; }; + if (rhs.kind != syntax.nkind.N_ARRLIT) { return; }; // #71: more elements than the declared [N] passed every per-element // check below and then smashed the frame at cgen (each element is // stored at its natural offset — the overflow clobbered neighbours @@ -15922,11 +15922,11 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // the wwstage twin of cstage's dropped `alen > 0`. if (arrtn.rhs != nil) { let cnt: u64 = 0u64; - let ce: *node = rhs.list; + let ce: *syntax.node = rhs.list; for (ce != nil) { let cskip: bool = false; - if (ce.kind == nkind.N_FIELD) { - if (streq(ce.str, "...")) { cskip = true; }; + if (ce.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(ce.str, "...")) { cskip = true; }; }; if (!cskip) { cnt += 1u64; }; ce = ce.next; @@ -15941,20 +15941,20 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { return; }; }; - let elemtn: *node = arrtn.lhs; - let at: *tinfo = tinfofornode(c, arrtn); - let et: *tinfo = nil; + let elemtn: *syntax.node = arrtn.lhs; + let at: *syntax.tinfo = tinfofornode(c, arrtn); + let et: *syntax.tinfo = nil; if (at != nil) { et = at.sub; }; et = tichase(et); - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { let skip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { skip = true; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { skip = true; }; }; if (!skip) { - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; // #71: a NESTED array-literal element must run the same // count check against the inner [N] — cstage catches the // nested shape through its typed-literal assignability net @@ -15969,9 +15969,9 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // the segv). resolvealias is transitive, so alias spellings // of any depth take the same recursion; a direct N_TARRAY // passes through unchanged. - let eltr: *node = resolvealias(c, elemtn); - if (eltr != nil && eltr.kind == nkind.N_TARRAY - && ev != nil && ev.kind == nkind.N_ARRLIT) { + let eltr: *syntax.node = resolvealias(c, elemtn); + if (eltr != nil && eltr.kind == syntax.nkind.N_TARRAY + && ev != nil && ev.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, eltr, ev); e = e.next; continue; @@ -15979,7 +15979,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { let v: u64 = 0u64; let folded: bool = false; if (et != nil) { - if (typeisint(et)) { + if (syntax.typeisint(et)) { if (ev != nil) { folded = foldintliteral(ev, &v); }; @@ -15993,7 +15993,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { return; }; } else { - let est: *node = exprtype(c, ev, elemtn); + let est: *syntax.node = exprtype(c, ev, elemtn); let conf2: bool = false; if (est != nil) { if (!isassignable(c, elemtn, est, &conf2)) { @@ -16020,7 +16020,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { // N_TUPLE) recurses. Shared by checkletassign (let) and // checkretassign (return). Mirrors cstage's element-wise // type_assignable count-reject; no-ops on scalar elements. -fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { +fn checktuplearrfits(c: *checker, ttn: *syntax.node, tup: *syntax.node) void = { if (ttn == nil) { return; }; if (tup == nil) { return; }; // #38/F2 (review item 10): a tuple literal whose arity differs from the @@ -16034,10 +16034,10 @@ fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { // reject a mismatch before the per-element fits walk. Recursion through // this one choke point gates every nesting depth. let dn: u64 = 0u64; - let dc: *node = ttn.list; + let dc: *syntax.node = ttn.list; for (dc != nil) { dn += 1u64; dc = dc.next; }; let vn: u64 = 0u64; - let vc: *node = tup.list; + let vc: *syntax.node = tup.list; for (vc != nil) { vn += 1u64; vc = vc.next; }; if (dn != vn) { cerr("tuple literal has "); @@ -16048,15 +16048,15 @@ fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { c.errs += 1; return; }; - let dt: *node = ttn.list; - let vt: *node = tup.list; + let dt: *syntax.node = ttn.list; + let vt: *syntax.node = tup.list; for (dt != nil && vt != nil) { - if (vt.kind == nkind.N_ARRLIT) { + if (vt.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, dt.lhs, vt); } else { - if (vt.kind == nkind.N_TUPLE) { - let drt: *node = resolvealias(c, unwrapbang(dt.lhs)); - if (drt != nil && drt.kind == nkind.N_TTUPLE) { + if (vt.kind == syntax.nkind.N_TUPLE) { + let drt: *syntax.node = resolvealias(c, unwrapbang(dt.lhs)); + if (drt != nil && drt.kind == syntax.nkind.N_TTUPLE) { checktuplearrfits(c, drt, vt); }; }; @@ -16087,32 +16087,32 @@ fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = { // position there is no addressable backing — loud-reject so the gap is a // compile error, not a dangling-ptr miscompile. Both stages reject here // (rule-10, byte-id-trivial: no asm). Full non-let support is #33. -fn rejectarrlitborrow(c: *checker, dsttn: *node, val: *node) bool = { +fn rejectarrlitborrow(c: *checker, dsttn: *syntax.node, val: *syntax.node) bool = { if (val == nil) { return false; }; - if (val.kind != nkind.N_ARRLIT) { return false; }; - let du: *node = resolvealias(c, unwrapbang(dsttn)); + if (val.kind != syntax.nkind.N_ARRLIT) { return false; }; + let du: *syntax.node = resolvealias(c, unwrapbang(dsttn)); if (du == nil) { return false; }; - if (du.kind != nkind.N_TSLICE) { return false; }; + if (du.kind != syntax.nkind.N_TSLICE) { return false; }; let m: str = "array literal cannot borrow as a slice here; bind it to a `let` first\n"; cerr(m); c.errs += 1; return true; }; -fn desugararrayslice(c: *checker, dsttn: *node, srctn: *node, val: *node) *node = { +fn desugararrayslice(c: *checker, dsttn: *syntax.node, srctn: *syntax.node, val: *syntax.node) *syntax.node = { if (dsttn == nil) { return val; }; if (srctn == nil) { return val; }; if (val == nil) { return val; }; - let du: *node = resolvealias(c, unwrapbang(dsttn)); - let su: *node = resolvealias(c, unwrapbang(srctn)); + let du: *syntax.node = resolvealias(c, unwrapbang(dsttn)); + let su: *syntax.node = resolvealias(c, unwrapbang(srctn)); if (du == nil) { return val; }; if (su == nil) { return val; }; - if (du.kind != nkind.N_TSLICE) { return val; }; - if (su.kind != nkind.N_TARRAY) { return val; }; + if (du.kind != syntax.nkind.N_TSLICE) { return val; }; + if (su.kind != syntax.nkind.N_TARRAY) { return val; }; if (!typeeqast(c, du.lhs, su.lhs)) { return val; }; - let sl: *node = newnode(nkind.N_SLICE, val.file, val.line, val.col); + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_SLICE, val.file, val.line, val.col); sl.lhs = val; // sliced base; lo (.rhs) / hi (.cond) nil → 0 : len(arr) - let slt: *node = newnode(nkind.N_TSLICE, "", 0, 0); + let slt: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); slt.lhs = su.lhs; sl.type_ = tinfofornode(c, slt): *void; sl.next = val.next; @@ -16126,28 +16126,28 @@ fn desugararrayslice(c: *checker, dsttn: *node, srctn: *node, val: *node) *node // module-qualified via the SK_USE receiver). nil for builtins / fn-value // callees — they have no declared param list to drive the #258 desugar, // and the selfhost corpus has no array→slice arg there anyway. -fn calleefndecl(c: *checker, callee: *node) *node = { +fn calleefndecl(c: *checker, callee: *syntax.node) *syntax.node = { if (callee == nil) { return nil; }; - if (callee.kind == nkind.N_IDENT) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, callee.str); + if (callee.kind == syntax.nkind.N_IDENT) { + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, callee.str); if (s != nil) { - if (s.skind == skind.SK_FN) { return s.decl; }; + if (s.skind == syntax.skind.SK_FN) { return s.decl; }; }; return nil; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { - let ms: *sym = scopelookupprefer(c.cur, c.curmod, callee.lhs.str); - if (ms != nil && ms.skind != skind.SK_USE) { - let mu: *sym = scopelookupuselocal(ms.scope, callee.lhs.str); + if (callee.lhs.kind == syntax.nkind.N_IDENT) { + let ms: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, callee.lhs.str); + if (ms != nil && ms.skind != syntax.skind.SK_USE) { + let mu: *syntax.sym = syntax.scopelookupuselocal(ms.scope, callee.lhs.str); if (mu != nil) { ms = mu; }; }; if (ms != nil) { - if (ms.skind == skind.SK_USE || ms.use_alias != 0i32) { - let fs: *sym = scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), callee.str); + if (ms.skind == syntax.skind.SK_USE || ms.use_alias != 0i32) { + let fs: *syntax.sym = syntax.scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), callee.str); if (fs != nil) { - if (fs.skind == skind.SK_FN) { return fs.decl; }; + if (fs.skind == syntax.skind.SK_FN) { return fs.decl; }; }; }; }; @@ -16162,7 +16162,7 @@ fn calleefndecl(c: *checker, callee: *node) *node = { // passed where a []T param is expected. Mirrors cstage cmd/wcc/check.c's // non-variadic call-arg arm. Variadic (`T...`) slots are skipped (the // arg flows into the gather as an element, not the slice itself). -fn desugarcallargs(c: *checker, n: *node) void = { +fn desugarcallargs(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; // #24: a 1-arg `free(x)` is the Hare no-op pseudo-builtin (#27), NOT the // rt 2-arg `free(p: *void, n: u64)` that calleefndecl resolves to in the @@ -16174,12 +16174,12 @@ fn desugarcallargs(c: *checker, n: *node) void = { // `free(slice)` (regex finish #27) isn't checked against rt_free's *void // param. `free` is the only builtin name with a colliding real decl // (len/alloc/append/delete/insert keep nil decls → calleefndecl bails). - if (n.lhs != nil) { if (n.lhs.kind == nkind.N_IDENT) { - if (streq(n.lhs.str, "free")) { + if (n.lhs != nil) { if (n.lhs.kind == syntax.nkind.N_IDENT) { + if (syntax.streq(n.lhs.str, "free")) { if (n.list != nil) { if (n.list.next == nil) { return; }; }; }; }; }; - let decl: *node = calleefndecl(c, n.lhs); + let decl: *syntax.node = calleefndecl(c, n.lhs); // task #51: calleefndecl nils every fn-VALUE callee — a deref `(*fp)(...)` // (N_UN), an SK_VAR fn-ptr ident, a struct-field fn call — so this bail // skips the #258 array→slice desugar AND the general arg typecheck for @@ -16188,22 +16188,22 @@ fn desugarcallargs(c: *checker, n: *node) void = { // (cmd/wcc/check.c:1828 type_chase_named(cexpr(callee))). The type-keyed // callee path is MECHANISM (not a checker gate) — filed as task #51. if (decl == nil) { return; }; - let param: *node = decl.list; - let prev: *node = nil; - let a: *node = n.list; + let param: *syntax.node = decl.list; + let prev: *syntax.node = nil; + let a: *syntax.node = n.list; for (a != nil) { - let nexta: *node = a.next; + let nexta: *syntax.node = a.next; if (param != nil) { - if (param.kind == nkind.N_PARAM) { - if (param.op != tkind.TK_ELLIPSIS) { - let atype: *node = exprtype(c, a, nil); + if (param.kind == syntax.nkind.N_PARAM) { + if (param.op != syntax.tkind.TK_ELLIPSIS) { + let atype: *syntax.node = exprtype(c, a, nil); // #29: a rune literal narrowing into an integer param // (`take('b')` where take(b: u8)). Override atype to the // integer target so c3's general isassignable accepts, // mirroring cstage's coarse untyped_rune rule. See // coercerunelit. cgen is byte-id-neutral (narrows by the // param/destination width). - let runet: *node = coercerunelit(c, a, param.lhs); + let runet: *syntax.node = coercerunelit(c, a, param.lhs); if (runet != nil) { atype = runet; }; // #24: GENERAL per-arg assignability — align UP to // cstage check.c:1867-1870, which type_assignables @@ -16229,20 +16229,20 @@ fn desugarcallargs(c: *checker, n: *node) void = { // of falling to cgen #271's late aggregate-arg loud. // param.lhs is the declared param type (alias-aware // via the resolvealias chase in checkarrlitfits). - if (a.kind == nkind.N_ARRLIT) { + if (a.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, param.lhs, a); }; // #31/#33: bare array-literal arg has no backing // — loud-reject (supported only at a `let`). if (!rejectarrlitborrow(c, param.lhs, a)) { - let rep: *node = desugararrayslice(c, param.lhs, atype, a); + let rep: *syntax.node = desugararrayslice(c, param.lhs, atype, a); if (rep != a) { if (prev == nil) { n.list = rep; } else { prev.next = rep; }; a = rep; }; }; }; - if (param.op != tkind.TK_ELLIPSIS) { param = param.next; }; + if (param.op != syntax.tkind.TK_ELLIPSIS) { param = param.next; }; }; }; prev = a; @@ -16255,7 +16255,7 @@ fn desugarcallargs(c: *checker, n: *node) void = { // route an array→slice rhs through the shared desugar so w6c_ww emits // the same borrow as w6c (rule-10). No error diagnostics — cstage gates // the shape. -fn checkassign(c: *checker, n: *node) void = { +fn checkassign(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { return; }; if (n.rhs == nil) { return; }; @@ -16263,9 +16263,9 @@ fn checkassign(c: *checker, n: *node) void = { // is_const bit set at the let-install above). A bare `_` discard // lvalue carries an empty str and is skipped. Mirror cstage // cmd/wcc/check.c:1889-1896. - if (n.lhs.kind == nkind.N_IDENT) { + if (n.lhs.kind == syntax.nkind.N_IDENT) { if (n.lhs.str.len > 0) { - let s: *sym = scopelookupprefer(c.cur, c.curmod, n.lhs.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, n.lhs.str); if (s != nil) { if (s.is_const != 0i32) { cerr("error: cannot assign to const binding\n"); @@ -16274,14 +16274,14 @@ fn checkassign(c: *checker, n: *node) void = { }; }; }; - let ltn: *node = exprtype(c, n.lhs, nil); - let rtn: *node = exprtype(c, n.rhs, nil); + let ltn: *syntax.node = exprtype(c, n.lhs, nil); + let rtn: *syntax.node = exprtype(c, n.rhs, nil); // #29: a rune literal narrowing into an integer assign/index-store // target (`buf[i] = 'F'`). Override rtn to the integer target so a // general assign typecheck accepts, mirroring cstage's coarse // untyped_rune rule. See coercerunelit. cgen narrows by the destination // width (byte-id-neutral). Removes the getopt `'X': u8` index casts. - let runet: *node = coercerunelit(c, n.rhs, ltn); + let runet: *syntax.node = coercerunelit(c, n.rhs, ltn); if (runet != nil) { rtn = runet; }; // #24/#36 (rule-7 deferred-divergence, NEVER silent): the ASSIGN seam // does NOT yet route the general conf-gated UNION (isassignable || @@ -16318,35 +16318,35 @@ fn checkassign(c: *checker, n: *node) void = { // never a silent zero-length array (rule 7). Idempotent (skips once the // length child is set), so the module-level double-call (checkfile's // pre-resolvewalk call + checkletassign here) raises at most one error. -fn inferarraylen(c: *checker, n: *node) void = { +fn inferarraylen(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { return; }; - if (n.lhs.kind != nkind.N_TARRAY) { return; }; + if (n.lhs.kind != syntax.nkind.N_TARRAY) { return; }; if (n.lhs.rhs != nil) { return; }; // explicit [N] or already inferred - if (n.rhs == nil || n.rhs.kind != nkind.N_ARRLIT) { + if (n.rhs == nil || n.rhs.kind != syntax.nkind.N_ARRLIT) { cerr("error: [_]T needs an array-literal initialiser\n"); c.errs += 1; - let z: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let z: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); z.uval = 0u64; n.lhs.rhs = z; // sentinel: idempotent, error already raised return; }; let cnt: u64 = 0u64; - let it: *node = n.rhs.list; + let it: *syntax.node = n.rhs.list; for (it != nil) { let skip: bool = false; - if (it.kind == nkind.N_FIELD) { - if (streq(it.str, "...")) { skip = true; }; + if (it.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(it.str, "...")) { skip = true; }; }; if (!skip) { cnt += 1u64; }; it = it.next; }; - let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let cn: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); cn.uval = cnt; n.lhs.rhs = cn; }; -fn checkletassign(c: *checker, n: *node) void = { +fn checkletassign(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; inferarraylen(c, n); // #7: must run before the n.rhs==nil bail if (n.rhs == nil) { return; }; // no init @@ -16357,34 +16357,34 @@ fn checkletassign(c: *checker, n: *node) void = { // exprtype, so flag the exact call node up front; exprtype errors on // any empty alloc that isn't this one). Peel the same ?/! wrapper #45 // peels so the flagged node matches. - let octx: *node = nil; - if (n.lhs != nil && n.lhs.kind == nkind.N_TSLICE) { - let inner: *node = n.rhs; - if (inner.kind == nkind.N_TRYPROP) { + let octx: *syntax.node = nil; + if (n.lhs != nil && n.lhs.kind == syntax.nkind.N_TSLICE) { + let inner: *syntax.node = n.rhs; + if (inner.kind == syntax.nkind.N_TRYPROP) { inner = inner.lhs; - } else { if (inner.kind == nkind.N_TRYUNW) { + } else { if (inner.kind == syntax.nkind.N_TRYUNW) { inner = inner.lhs; }; }; - if (inner != nil && inner.kind == nkind.N_CALL) { - let callee: *node = inner.lhs; - let a0: *node = inner.list; - let a1: *node = nil; - let a2: *node = nil; + if (inner != nil && inner.kind == syntax.nkind.N_CALL) { + let callee: *syntax.node = inner.lhs; + let a0: *syntax.node = inner.list; + let a1: *syntax.node = nil; + let a2: *syntax.node = nil; if (a0 != nil) { a1 = a0.next; }; if (a1 != nil) { a2 = a1.next; }; if (callee != nil - && callee.kind == nkind.N_IDENT - && streq(callee.str, "alloc") - && a0 != nil && a0.kind == nkind.N_ARRLIT + && callee.kind == syntax.nkind.N_IDENT + && syntax.streq(callee.str, "alloc") + && a0 != nil && a0.kind == syntax.nkind.N_ARRLIT && a0.list == nil && a1 != nil && a2 == nil) { octx = inner; }; }; }; - let savedoctx: *node = c.allococtx; + let savedoctx: *syntax.node = c.allococtx; c.allococtx = octx; - let src: *node = exprtype(c, n.rhs, nil); + let src: *syntax.node = exprtype(c, n.rhs, nil); c.allococtx = savedoctx; // Inferred binding (`let r = expr;`, no type annotation). Mirror // cstage cmd/wcc/check.c:1477 clet `if (t == NULL && initt) t = @@ -16405,10 +16405,10 @@ fn checkletassign(c: *checker, n: *node) void = { // one downstream. cstage needs no twin: check.c:1477 clet carries // Sym.type (tinfo), and its emission is annotation-invariant // (probed identical asm annotated vs not). - if (src != nil && src.kind == nkind.N_TSTRUCT - && n.rhs.kind == nkind.N_STRUCTLIT - && n.rhs.lhs != nil && n.rhs.lhs.kind == nkind.N_IDENT) { - let ltn: *node = mktname(c, n.rhs.lhs.str); + if (src != nil && src.kind == syntax.nkind.N_TSTRUCT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT + && n.rhs.lhs != nil && n.rhs.lhs.kind == syntax.nkind.N_IDENT) { + let ltn: *syntax.node = mktname(c, n.rhs.lhs.str); ltn.type_ = tinfofornode(c, ltn): *void; n.lhs = ltn; return; @@ -16424,44 +16424,44 @@ fn checkletassign(c: *checker, n: *node) void = { // so isassignable sees exact equality. cgenstmt cglet drives the // element size from n.lhs already (cmd/wcc/cgenstmt.ww), so this // stays symmetric with cstage check.c clet's parallel retype. - if (n.lhs.kind == nkind.N_TSLICE) { + if (n.lhs.kind == syntax.nkind.N_TSLICE) { let wrapped: bool = false; - let inner: *node = n.rhs; - if (inner.kind == nkind.N_TRYPROP) { + let inner: *syntax.node = n.rhs; + if (inner.kind == syntax.nkind.N_TRYPROP) { wrapped = true; inner = inner.lhs; - } else { if (inner.kind == nkind.N_TRYUNW) { + } else { if (inner.kind == syntax.nkind.N_TRYUNW) { wrapped = true; inner = inner.lhs; }; }; - if (inner != nil && inner.kind == nkind.N_CALL) { - let callee: *node = inner.lhs; - let a0: *node = inner.list; - let a1: *node = nil; - let a2: *node = nil; + if (inner != nil && inner.kind == syntax.nkind.N_CALL) { + let callee: *syntax.node = inner.lhs; + let a0: *syntax.node = inner.list; + let a1: *syntax.node = nil; + let a2: *syntax.node = nil; if (a0 != nil) { a1 = a0.next; }; if (a1 != nil) { a2 = a1.next; }; if (callee != nil - && callee.kind == nkind.N_IDENT - && streq(callee.str, "alloc") - && a0 != nil && a0.kind == nkind.N_ARRLIT + && callee.kind == syntax.nkind.N_IDENT + && syntax.streq(callee.str, "alloc") + && a0 != nil && a0.kind == syntax.nkind.N_ARRLIT && a0.list == nil && a1 != nil && a2 == nil) { let shadowed: bool = false; if (c.curmod.len > 0) { - if (scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { + if (syntax.scopelookupinmodule(c.cur, c.curmod, "alloc") != nil) { shadowed = true; }; }; if (!shadowed) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = n.lhs.lhs; if (wrapped) { src = sl; } else { - let nome: *node = mktname(c, "nomem"); + let nome: *syntax.node = mktname(c, "nomem"); sl.next = nome; - let tt: *node = newnode(nkind.N_TTAGGED, "", 0, 0); + let tt: *syntax.node = syntax.newnode(syntax.nkind.N_TTAGGED, "", 0, 0); tt.list = sl; src = tt; }; @@ -16487,8 +16487,8 @@ fn checkletassign(c: *checker, n: *node) void = { // here too so an alias-of-array routes through the same over-fill. A // direct N_TARRAY is unchanged (resolvealias is idempotent), and the // early return matches the direct-array branch's pre-existing return. - let llhs: *node = resolvealias(c, unwrapbang(n.lhs)); - if (llhs != nil && llhs.kind == nkind.N_TARRAY && n.rhs.kind == nkind.N_ARRLIT) { + let llhs: *syntax.node = resolvealias(c, unwrapbang(n.lhs)); + if (llhs != nil && llhs.kind == syntax.nkind.N_TARRAY && n.rhs.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, n.lhs, n.rhs); return; }; @@ -16502,8 +16502,8 @@ fn checkletassign(c: *checker, n: *node) void = { // early return — the rest of checkletassign still runs for the tuple. // N_TTUPLE elements wrap their type on .lhs (N_TPARAM chain, // stamptuplebinds:311); the N_TUPLE rhs values chain directly on .list. - if (llhs != nil && llhs.kind == nkind.N_TTUPLE - && n.rhs.kind == nkind.N_TUPLE) { + if (llhs != nil && llhs.kind == syntax.nkind.N_TTUPLE + && n.rhs.kind == syntax.nkind.N_TUPLE) { checktuplearrfits(c, llhs, n.rhs); }; // #25/#31: an array literal initialising a SLICE local. Re-stamp the @@ -16514,21 +16514,21 @@ fn checkletassign(c: *checker, n: *node) void = { // [count]T), then drive isassignable + the borrow off [count]T. Twin of // cstage arrlit_init_fits' slice arm. Local-only (c.cur != c.top): the // borrow runs at runtime; module-level slice-from-arrlit stays #32. - if (c.cur != c.top && n.lhs.kind == nkind.N_TSLICE - && n.rhs.kind == nkind.N_ARRLIT) { + if (c.cur != c.top && n.lhs.kind == syntax.nkind.N_TSLICE + && n.rhs.kind == syntax.nkind.N_ARRLIT) { let cnt: u64 = 0u64; - let e0: *node = n.rhs.list; + let e0: *syntax.node = n.rhs.list; for (e0 != nil) { let skip: bool = false; - if (e0.kind == nkind.N_FIELD) { - if (streq(e0.str, "...")) { skip = true; }; + if (e0.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e0.str, "...")) { skip = true; }; }; if (!skip) { cnt += 1u64; }; e0 = e0.next; }; - let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + let cn: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, "", 0, 0); cn.uval = cnt; - let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0); + let arr: *syntax.node = syntax.newnode(syntax.nkind.N_TARRAY, "", 0, 0); arr.lhs = n.lhs.lhs; // declared slice element type arr.rhs = cn; checkarrlitfits(c, arr, n.rhs); @@ -16544,7 +16544,7 @@ fn checkletassign(c: *checker, n: *node) void = { // #29: an un-suffixed rune literal narrowing into an integer let target // (`let b: u8 = 'a'`). Override src to the integer target so isassignable // accepts, mirroring cstage's coarse untyped_rune rule. See coercerunelit. - let runet: *node = coercerunelit(c, n.rhs, n.lhs); + let runet: *syntax.node = coercerunelit(c, n.rhs, n.lhs); if (runet != nil) { src = runet; }; let conf: bool = false; let ok: bool = isassignable(c, n.lhs, src, &conf); @@ -16577,7 +16577,7 @@ fn checkletassign(c: *checker, n: *node) void = { }; }; -fn checkretassign(c: *checker, n: *node) void = { +fn checkretassign(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; if (n.lhs == nil) { // bare `return;` — mirror cstage cmd/wcc/check.c:2428-2439: @@ -16588,7 +16588,7 @@ fn checkretassign(c: *checker, n: *node) void = { // reaches the same verdict (void→void typeeqast; void→tagged via // the void variant; void→i32 a confident primitive mismatch). if (c.fnret == nil) { return; }; - let vt: *node = mktname(c, "void"); + let vt: *syntax.node = mktname(c, "void"); let vconf: bool = false; let vok: bool = isassignable(c, c.fnret, vt, &vconf); if (vconf) { if (!vok) { errnotassign(c, c.fnret, vt, "return"); }; }; @@ -16602,7 +16602,7 @@ fn checkretassign(c: *checker, n: *node) void = { // would short-circuit the check (the alias path set conf=true, so neg3 // caught it but the direct neg0 slipped). Alias-aware via the // resolvealias chase at the top of checkarrlitfits. - if (n.lhs.kind == nkind.N_ARRLIT) { + if (n.lhs.kind == syntax.nkind.N_ARRLIT) { checkarrlitfits(c, c.fnret, n.lhs); }; // #25: array-typed element of a TUPLE RETURN with an overlong array @@ -16613,18 +16613,18 @@ fn checkretassign(c: *checker, n: *node) void = { // BEFORE the isassignable/conf guards (a tuple return drives // conf=false → short-circuit), same reason as the #12 array arm // above. Alias/!-aware on the fnret tuple type. - let rrt: *node = resolvealias(c, unwrapbang(c.fnret)); - if (rrt != nil && rrt.kind == nkind.N_TTUPLE - && n.lhs.kind == nkind.N_TUPLE) { + let rrt: *syntax.node = resolvealias(c, unwrapbang(c.fnret)); + if (rrt != nil && rrt.kind == syntax.nkind.N_TTUPLE + && n.lhs.kind == syntax.nkind.N_TUPLE) { checktuplearrfits(c, rrt, n.lhs); }; - let src: *node = exprtype(c, n.lhs, nil); + let src: *syntax.node = exprtype(c, n.lhs, nil); if (src == nil) { return; }; // #29: a rune literal returned into an integer (or integer-variant) // fnret (`return '\\';` into u8 or (u8 | star | ...)). Override src so // isassignable accepts; cgen boxes via the shape fallback. See // coercerunelit. Removes the fnmatch.ww:126 `'\\': u8` workaround cast. - let runet: *node = coercerunelit(c, n.lhs, c.fnret); + let runet: *syntax.node = coercerunelit(c, n.lhs, c.fnret); if (runet != nil) { src = runet; }; let conf: bool = false; let ok: bool = isassignable(c, c.fnret, src, &conf); @@ -16653,10 +16653,10 @@ fn checkretassign(c: *checker, n: *node) void = { // union and that T name one of its variants. Operates on AST type // expressions; falls back silently when we can't determine e's // type (matches the case-variant rule for match). -fn checkisas(c: *checker, n: *node) void = { +fn checkisas(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; // e is in n.lhs (value), T is in n.rhs (type expr). - let st: *node = scruttype(c, n.lhs); + let st: *syntax.node = scruttype(c, n.lhs); // F9 (task #12): direct `expr? is T` / `expr! is T` — cstage cexpr // types the ?/! result as the success variant and the non-tagged // gate below then rejects (check.c "is on non-tagged-union"). @@ -16666,11 +16666,11 @@ fn checkisas(c: *checker, n: *node) void = { // union variant) flows on into the variant checks, matching // cstage's accept. if (st == nil && n.lhs != nil) { - if (n.lhs.kind == nkind.N_TRYPROP || n.lhs.kind == nkind.N_TRYUNW) { + if (n.lhs.kind == syntax.nkind.N_TRYPROP || n.lhs.kind == syntax.nkind.N_TRYUNW) { st = exprtype(c, n.lhs, nil); }; }; - let u: *node = resolvealias(c, unwrapbang(st)); + let u: *syntax.node = resolvealias(c, unwrapbang(st)); if (u == nil) { return; }; // #52: enum ↔ int reinterpret (`enum as intT` / `intT as enum`). // Mirrors cstage cmd/wcc/check.c:1346-1357 — N_TYPEASSERT with an @@ -16680,22 +16680,22 @@ fn checkisas(c: *checker, n: *node) void = { // the lib/os syscall casts stop false-positiving. `is` (TYPETEST) // stays rejected on non-tagged operands — cstage cmd/wcc/check.c // gates the bypass on N_TYPEASSERT only. - if (n.kind == nkind.N_TYPEASSERT) { - let v: *node = resolvealias(c, unwrapbang(n.rhs)); + if (n.kind == syntax.nkind.N_TYPEASSERT) { + let v: *syntax.node = resolvealias(c, unwrapbang(n.rhs)); let lhsenum: bool = false; let rhsenum: bool = false; - if (u != nil) { if (u.kind == nkind.N_TENUM) { lhsenum = true; }; }; - if (v != nil) { if (v.kind == nkind.N_TENUM) { rhsenum = true; }; }; + if (u != nil) { if (u.kind == syntax.nkind.N_TENUM) { lhsenum = true; }; }; + if (v != nil) { if (v.kind == syntax.nkind.N_TENUM) { rhsenum = true; }; }; if (lhsenum || rhsenum) { if (isinttypeast(u)) { if (isinttypeast(v)) { return; }; }; }; }; - if (u.kind != nkind.N_TTAGGED) { + if (u.kind != syntax.nkind.N_TTAGGED) { cerr("is/as: operand is not a tagged union\n"); c.errs += 1; return; }; - let want: *node = n.rhs; + let want: *syntax.node = n.rhs; if (want == nil) { return; }; // #198: route through tinfo.params (the #61a-flattened chain built // at L1789-1845 N_TTAGGED) — the prior AST u.list walk via @@ -16706,8 +16706,8 @@ fn checkisas(c: *checker, n: *node) void = { // keys off at cgenexpr.ww:155). project_tinfo_lossy_nominal: name- // keying was the pre-Phase-N workaround for tinfo lossy on nominal // identity; typeeq inside flatvariantidxt now handles NAMED ptr-id. - let utinfo: *tinfo = tinfofornode(c, u); - let wanttinfo: *tinfo = tinfofornode(c, want); + let utinfo: *syntax.tinfo = tinfofornode(c, u); + let wanttinfo: *syntax.tinfo = tinfofornode(c, want); if (utinfo != nil) { if (wanttinfo != nil) { // exact-only (#95-c3): is/as acceptance is nominal variant // membership; the cgen tag-synthesis chain/structural arms must @@ -16718,7 +16718,7 @@ fn checkisas(c: *checker, n: *node) void = { }; }; if (casevariantin(c, u, want, taggeddefmod(c, st))) { return; }; cerr("is/as: not a variant of operand"); - if (want.kind == nkind.N_TNAME) { + if (want.kind == syntax.nkind.N_TNAME) { cerr(" ("); cerr(want.str); cerr(")"); @@ -16736,35 +16736,35 @@ fn checkisas(c: *checker, n: *node) void = { // we look at the expr's *declared* type for nkind.N_IDENT/nkind.N_CALL // cases. -fn exprtypeoftry(c: *checker, e: *node) *node = { +fn exprtypeoftry(c: *checker, e: *syntax.node) *syntax.node = { if (e == nil) { return nil; }; - if (e.kind == nkind.N_IDENT) { + if (e.kind == syntax.nkind.N_IDENT) { // #11a: curmod preference (the #53/#55 family). A bare ident // whose leaf also names a global in a later module otherwise // binds the foreign decl's type, mis-typing the try operand and // either spuriously rejecting valid `?` code or skipping the F8 // reject. Mirrors exprtype's own N_IDENT arm (scopelookupprefer // at :2897); cstage types the operand via cexpr with cur_mod. - let s: *sym = scopelookupprefer(c.cur, c.curmod, e.str); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, e.str); if (s == nil) { return nil; }; if (s.decl == nil) { return nil; }; return s.decl.lhs; }; - if (e.kind == nkind.N_CALL) { + if (e.kind == syntax.nkind.N_CALL) { // callee return type lookup: callee is e.lhs (nkind.N_IDENT or // nkind.N_DOT). We need the fn-decl's lhs (return-type AST). - let callee: *node = e.lhs; + let callee: *syntax.node = e.lhs; if (callee == nil) { return nil; }; let nm: str; nm.ptr = nil; nm.len = 0; - if (callee.kind == nkind.N_IDENT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_IDENT) { nm = callee.str; }; // #11b/task #51: an N_DOT callee `mod.f()?` is looked up by BARE // LEAF here, NOT via the module qualifier (callee.lhs) the way // exprtype's own N_CALL arm does (:3095 scopelookupinmodule) — a // cross-module same-leaf `f` misbinds. The mechanism fix (module- // keyed callee resolution + the deref-callee `(*fp)()?` shape that // returns nil below) rides task #51 with the fn-ptr-callee desugar. - if (callee.kind == nkind.N_DOT) { nm = callee.str; }; + if (callee.kind == syntax.nkind.N_DOT) { nm = callee.str; }; if (nm.len == 0) { return nil; }; // #11a: curmod preference for the bare-leaf callee. A same-leaf // `op()?` declared in a later module otherwise binds the foreign @@ -16773,9 +16773,9 @@ fn exprtypeoftry(c: *checker, e: *node) *node = { // N_CALL arm (scopelookupprefer at :3336). The N_DOT-callee leaf // (callee.str above) still resolves bare-leaf, not via the module // qualifier callee.lhs.str — that module-keyed fix rides task #51. - let s: *sym = scopelookupprefer(c.cur, c.curmod, nm); + let s: *syntax.sym = syntax.scopelookupprefer(c.cur, c.curmod, nm); if (s == nil) { return nil; }; - if (s.skind != skind.SK_FN) { return nil; }; + if (s.skind != syntax.skind.SK_FN) { return nil; }; if (s.decl == nil) { return nil; }; return s.decl.lhs; }; @@ -16799,12 +16799,12 @@ fn exprtypeoftry(c: *checker, e: *node) *node = { // or a spliced member carries the error, so each flattened member routes // through varianterr, matching cstage's per-param iserror. Mirrors the #209 // spread recursion tinfofornode already runs over vu.params (check.ww:2275). -fn trycountvariants(c: *checker, outer: *node, v: *node, nsuccp: *int, +fn trycountvariants(c: *checker, outer: *syntax.node, v: *syntax.node, nsuccp: *int, haserrp: *bool, depth: i32) void = { for (v != nil) { - if (v.op == tkind.TK_ELLIPSIS && depth < 8i32) { - let inner: *node = resolvealias(c, unwrapbang(v)); - if (inner != nil && inner.kind == nkind.N_TTAGGED) { + if (v.op == syntax.tkind.TK_ELLIPSIS && depth < 8i32) { + let inner: *syntax.node = resolvealias(c, unwrapbang(v)); + if (inner != nil && inner.kind == syntax.nkind.N_TTAGGED) { trycountvariants(c, outer, inner.list, nsuccp, haserrp, depth + 1i32); v = v.next; @@ -16817,12 +16817,12 @@ fn trycountvariants(c: *checker, outer: *node, v: *node, nsuccp: *int, }; }; -fn checktryprop(c: *checker, n: *node) void = { +fn checktryprop(c: *checker, n: *syntax.node) void = { if (n == nil) { return; }; - let t: *node = exprtypeoftry(c, n.lhs); - let u: *node = resolvealias(c, unwrapbang(t)); + let t: *syntax.node = exprtypeoftry(c, n.lhs); + let u: *syntax.node = resolvealias(c, unwrapbang(t)); if (u == nil) { return; }; - if (u.kind != nkind.N_TTAGGED) { return; }; + if (u.kind != syntax.nkind.N_TTAGGED) { return; }; // F8 interim gate (task #5): try-propagation assumes ONE success // member end-to-end — exprtype collapses to the first non-error // variant and cgen emits a single tag compare, so any OTHER @@ -16837,33 +16837,33 @@ fn checktryprop(c: *checker, n: *node) void = { // multi-success gate counts the spliced members, not the spread alias. trycountvariants(c, u, u.list, &nsucc, &haserr, 0i32); if (nsucc > 1) { - if (n.kind == nkind.N_TRYPROP) { cerr("?"); } else { cerr("!"); }; + if (n.kind == syntax.nkind.N_TRYPROP) { cerr("?"); } else { cerr("!"); }; cerr(": multi-success union unwired (task #14): bind and match instead\n"); c.errs += 1; return; }; // `!` has no propagation, so no error-subset check (mirrors // cstage's N_TRYPROP-only guard on the subset walk). - if (n.kind != nkind.N_TRYPROP) { return; }; + if (n.kind != syntax.nkind.N_TRYPROP) { return; }; if (!haserr) { return; }; // Enclosing fn must return a tagged union with each operand // error variant present. - let r: *node = resolvealias(c, unwrapbang(c.fnret)); + let r: *syntax.node = resolvealias(c, unwrapbang(c.fnret)); if (r == nil) { cerr("?: enclosing fn has no tagged-union return\n"); c.errs += 1; return; }; - if (r.kind != nkind.N_TTAGGED) { + if (r.kind != syntax.nkind.N_TTAGGED) { cerr("?: enclosing fn return is not tagged\n"); c.errs += 1; return; }; - let ev: *node = u.list; + let ev: *syntax.node = u.list; for (ev != nil) { if (iserrvariant(c, u, ev)) { let found: bool = false; - let rv: *node = r.list; + let rv: *syntax.node = r.list; for (rv != nil) { if (typeeqast(c, rv, ev)) { found = true; @@ -16889,10 +16889,10 @@ fn checktryprop(c: *checker, n: *node) void = { // into w6c_ww so the diagnostic class lands as a single coordinated // step rather than dribbling in. Matches the cstage-only neg-case // precedent at test/wcc/708 + test/wcc/696. -fn installparams(c: *checker, params: *node) void = { - let p: *node = params; +fn installparams(c: *checker, params: *syntax.node) void = { + let p: *syntax.node = params; for (p != nil) { - if (p.kind == nkind.N_PARAM) { + if (p.kind == syntax.nkind.N_PARAM) { // Hare-style variadic `T...`: normalize p.lhs to []T so // downstream consumers (N_IDENT exprtype lookups via // s.decl.lhs, cgen's variadic-slot synthesis) see the @@ -16900,9 +16900,9 @@ fn installparams(c: *checker, params: *node) void = { // `tp->type = type_slice(c->a, pt)` and harec // check_func_type. Surface-fidelity preserved: wwdump // -a runs parser only and never reaches this mutation. - if (p.op == tkind.TK_ELLIPSIS) { - if (p.lhs != nil && p.lhs.kind != nkind.N_TSLICE) { - let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0); + if (p.op == syntax.tkind.TK_ELLIPSIS) { + if (p.lhs != nil && p.lhs.kind != syntax.nkind.N_TSLICE) { + let sl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); sl.lhs = p.lhs; p.lhs = sl; }; @@ -16910,7 +16910,7 @@ fn installparams(c: *checker, params: *node) void = { let nm: str = p.str; if (nm.len > 0) { checkmoduleshadow(c, nm, "param"); - scopedefine(c.cur, nm, skind.SK_PARAM, nil, p); + syntax.scopedefine(c.cur, nm, syntax.skind.SK_PARAM, nil, p); }; }; p = p.next; @@ -16921,22 +16921,22 @@ fn installparams(c: *checker, params: *node) void = { // then walk the body. Local lets installed by walk_stmt (a future // extension); for the current pass we just resolve-walk without // per-statement scopes. -fn resolvefnbody(c: *checker, fnnode: *node) void = { - let outer: *scope = c.cur; - c.cur = newscope(c.cur); +fn resolvefnbody(c: *checker, fnnode: *syntax.node) void = { + let outer: *syntax.scope = c.cur; + c.cur = syntax.newscope(c.cur); installparams(c, fnnode.list); // #61 audit §1.8 — A.2: walk each param's declared type-expr so // tinfofornode stamps n.type_ on it. installparams binds the name // but never recurses into the type; without this, cgen's slotsize // fast-path hits the fallback for every param load/store. - let p: *node = fnnode.list; + let p: *syntax.node = fnnode.list; for (p != nil) { - if (p.kind == nkind.N_PARAM) { + if (p.kind == syntax.nkind.N_PARAM) { if (p.lhs != nil) { resolvewalk(c, p.lhs); }; }; p = p.next; }; - let prevret: *node = c.fnret; + let prevret: *syntax.node = c.fnret; c.fnret = fnnode.lhs; // return type AST, used by `?` check if (fnnode.body != nil) { resolvewalk(c, fnnode.body); @@ -16954,13 +16954,13 @@ fn resolvefnbody(c: *checker, fnnode: *node) void = { // callee carry no type by design. Recognized exactly as the cstage // builtin intercept (cmd/wcc/check.c:1314,1328): the reserved name // with no shadowing user symbol. -fn isassertfam(c: *checker, id: *node) bool = { +fn isassertfam(c: *checker, id: *syntax.node) bool = { if (id == nil) { return false; }; - if (id.kind != nkind.N_IDENT) { return false; }; - if (!streq(id.str, "abort") && !streq(id.str, "assert")) { + if (id.kind != syntax.nkind.N_IDENT) { return false; }; + if (!syntax.streq(id.str, "abort") && !syntax.streq(id.str, "assert")) { return false; }; - return scopelookupprefer(c.cur, c.curmod, id.str) == nil; + return syntax.scopelookupprefer(c.cur, c.curmod, id.str) == nil; }; // asserttyped — post-checker invariant gate (#15, A.6.2.1e). Walks the @@ -16999,43 +16999,43 @@ fn isassertfam(c: *checker, id: *node) bool = { // // `indot` tracks gate 3: true only when the immediate caller is an // N_DOT recursing into its .lhs. -fn asserttyped(c: *checker, n: *node, indot: bool) void = { +fn asserttyped(c: *checker, n: *syntax.node, indot: bool) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; let isexpr: bool = - k == nkind.N_INTLIT || k == nkind.N_FLOATLIT || - k == nkind.N_STRLIT || k == nkind.N_RUNELIT || - k == nkind.N_TRUE || k == nkind.N_FALSE || - k == nkind.N_NIL || k == nkind.N_VOIDLIT || - k == nkind.N_IDENT || k == nkind.N_BIN || - k == nkind.N_UN || k == nkind.N_CALL || - k == nkind.N_INDEX || k == nkind.N_CAST || - k == nkind.N_STRUCTLIT || k == nkind.N_ARRLIT || - k == nkind.N_RECV || k == nkind.N_DOT || - k == nkind.N_SLICE || k == nkind.N_SPREAD || - k == nkind.N_TUPLE || k == nkind.N_TRYPROP || - k == nkind.N_TRYUNW || k == nkind.N_TYPETEST || - k == nkind.N_TYPEASSERT || k == nkind.N_YIELD || - k == nkind.N_MATCH; + k == syntax.nkind.N_INTLIT || k == syntax.nkind.N_FLOATLIT || + k == syntax.nkind.N_STRLIT || k == syntax.nkind.N_RUNELIT || + k == syntax.nkind.N_TRUE || k == syntax.nkind.N_FALSE || + k == syntax.nkind.N_NIL || k == syntax.nkind.N_VOIDLIT || + k == syntax.nkind.N_IDENT || k == syntax.nkind.N_BIN || + k == syntax.nkind.N_UN || k == syntax.nkind.N_CALL || + k == syntax.nkind.N_INDEX || k == syntax.nkind.N_CAST || + k == syntax.nkind.N_STRUCTLIT || k == syntax.nkind.N_ARRLIT || + k == syntax.nkind.N_RECV || k == syntax.nkind.N_DOT || + k == syntax.nkind.N_SLICE || k == syntax.nkind.N_SPREAD || + k == syntax.nkind.N_TUPLE || k == syntax.nkind.N_TRYPROP || + k == syntax.nkind.N_TRYUNW || k == syntax.nkind.N_TYPETEST || + k == syntax.nkind.N_TYPEASSERT || k == syntax.nkind.N_YIELD || + k == syntax.nkind.N_MATCH; let skip: bool = false; - if (isexpr && k == nkind.N_IDENT) { + if (isexpr && k == syntax.nkind.N_IDENT) { if (indot) { skip = true; }; if (!skip) { - let s: *sym = scopelookup(c.cur, n.str); + let s: *syntax.sym = syntax.scopelookup(c.cur, n.str); if (s != nil) { - if (s.skind == skind.SK_USE) { skip = true; }; + if (s.skind == syntax.skind.SK_USE) { skip = true; }; if (s.decl == nil) { skip = true; }; }; }; if (!skip) { if (isassertfam(c, n)) { skip = true; }; }; }; - if (isexpr && k == nkind.N_CALL) { + if (isexpr && k == syntax.nkind.N_CALL) { if (isassertfam(c, n.lhs)) { skip = true; }; }; if (isexpr && !skip) { if (n.type_ == nil) { cerr("asserttyped: "); - let kn: str = nkname(k); + let kn: str = syntax.nkname(k); cerr(kn); cerr(" "); if (n.file.len > 0) { @@ -17053,7 +17053,7 @@ fn asserttyped(c: *checker, n: *node, indot: bool) void = { os.exit(1); }; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { if (n.lhs != nil) { asserttyped(c, n.lhs, true); }; return; }; @@ -17063,16 +17063,16 @@ fn asserttyped(c: *checker, n: *node, indot: bool) void = { if (n.cond != nil) { asserttyped(c, n.cond, false); }; if (n.body != nil) { asserttyped(c, n.body, false); }; if (n.els != nil) { asserttyped(c, n.els, false); }; - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { asserttyped(c, m, false); m = m.next; }; }; -export fn checkinit(c: *checker, tc: *tctx) void = { +export fn checkinit(c: *checker, tc: *syntax.tctx) void = { c.tc = tc; - c.top = newscope(nil); + c.top = syntax.newscope(nil); c.cur = c.top; c.nresolved = 0; c.nunresolved = 0; @@ -17087,13 +17087,13 @@ export fn checkinit(c: *checker, tc: *tctx) void = { seedprimitives(c); }; -export fn checkfile(c: *checker, file: *node) void = { +export fn checkfile(c: *checker, file: *syntax.node) void = { if (file == nil) { return; }; - if (file.kind != nkind.N_FILE) { return; }; + if (file.kind != syntax.nkind.N_FILE) { return; }; c.file = file; // Pass 1: install all top-level names. - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { installdecl(c, file, d); d = d.next; @@ -17106,12 +17106,12 @@ export fn checkfile(c: *checker, file: *node) void = { // collision by construction (#31). Two ROOT entries still collide on // the bare symbol → reject loud (rule 7). Walks USER decls only — runs // before the -T synth main is appended below. Twin of cmd/wcc/check.c. - let firstmain: *node = nil; - let mm: *node = file.list; + let firstmain: *syntax.node = nil; + let mm: *syntax.node = file.list; for (mm != nil) { - let ismain: bool = (mm.kind == nkind.N_FNDECL - || mm.kind == nkind.N_LET || mm.kind == nkind.N_DEF - || mm.kind == nkind.N_TYPEDECL) && streq(mm.str, "main"); + let ismain: bool = (mm.kind == syntax.nkind.N_FNDECL + || mm.kind == syntax.nkind.N_LET || mm.kind == syntax.nkind.N_DEF + || mm.kind == syntax.nkind.N_TYPEDECL) && syntax.streq(mm.str, "main"); if (ismain && mm.imported == 0) { if (firstmain == nil) { firstmain = mm; @@ -17153,10 +17153,10 @@ export fn checkfile(c: *checker, file: *node) void = { let pl: i32 = file.line; let pc: i32 = file.col; // (b) the synth entry OWNS `main` — loud-reject a user one. - let u: *node = file.list; + let u: *syntax.node = file.list; for (u != nil) { - if (u.kind == nkind.N_FNDECL && u.body != nil - && streq(u.str, "main")) { + if (u.kind == syntax.nkind.N_FNDECL && u.body != nil + && syntax.streq(u.str, "main")) { cerr(u.file); cerr(": error: test mode: main is synthesized by -T; remove the explicit main\n"); c.errs += 1; @@ -17169,7 +17169,7 @@ export fn checkfile(c: *checker, file: *node) void = { // so the synth `run(__wwtests)` iterates the user's table, not // the collected @tests — reserve the NAME so the collision is // loud regardless of type. Any decl kind (const/let/fn). - if (streq(u.str, "__wwtests")) { + if (syntax.streq(u.str, "__wwtests")) { cerr(u.file); cerr(": error: test mode: __wwtests is reserved by -T; rename the declaration\n"); c.errs += 1; @@ -17178,17 +17178,17 @@ export fn checkfile(c: *checker, file: *node) void = { }; // (c) collect @test fns in file.list order; build one table row // `("", &)` per validated @test fn. - let rhead: *node = nil; - let rtail: *node = nil; + let rhead: *syntax.node = nil; + let rtail: *syntax.node = nil; let ntest: i32 = 0; - let t: *node = file.list; + let t: *syntax.node = file.list; for (t != nil) { - if (t.kind == nkind.N_FNDECL) { + if (t.kind == syntax.nkind.N_FNDECL) { let istest: bool = false; - let at: *node = t.attr; + let at: *syntax.node = t.attr; for (at != nil) { - if (at.kind == nkind.N_ATTR - && streq(at.str, "test")) { + if (at.kind == syntax.nkind.N_ATTR + && syntax.streq(at.str, "test")) { istest = true; }; at = at.next; @@ -17198,8 +17198,8 @@ export fn checkfile(c: *checker, file: *node) void = { // into t.lhs, so void-returning is lhs==nil // OR an N_TNAME "void". let retvoid: bool = t.lhs == nil - || (t.lhs.kind == nkind.N_TNAME - && streq(t.lhs.str, "void")); + || (t.lhs.kind == syntax.nkind.N_TNAME + && syntax.streq(t.lhs.str, "void")); if (t.list != nil || !retvoid) { cerr(t.file); cerr(": error: @test fn '"); @@ -17207,14 +17207,14 @@ export fn checkfile(c: *checker, file: *node) void = { cerr("' must be fn() void\n"); c.errs += 1; } else { - let nm: *node = newnode(nkind.N_STRLIT, pf, pl, pc); + let nm: *syntax.node = syntax.newnode(syntax.nkind.N_STRLIT, pf, pl, pc); nm.str = t.str; - let id: *node = newnode(nkind.N_IDENT, pf, pl, pc); + let id: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc); id.str = t.str; - let amp: *node = newnode(nkind.N_UN, pf, pl, pc); - amp.op = tkind.TK_AMP; + let amp: *syntax.node = syntax.newnode(syntax.nkind.N_UN, pf, pl, pc); + amp.op = syntax.tkind.TK_AMP; amp.lhs = id; - let row: *node = newnode(nkind.N_TUPLE, pf, pl, pc); + let row: *syntax.node = syntax.newnode(syntax.nkind.N_TUPLE, pf, pl, pc); row.list = nm; nm.next = amp; if (rhead == nil) { rhead = row; } @@ -17227,39 +17227,39 @@ export fn checkfile(c: *checker, file: *node) void = { t = t.next; }; - let body: *node = newnode(nkind.N_BLOCK, pf, pl, pc); - let tab: *node = nil; + let body: *syntax.node = syntax.newnode(syntax.nkind.N_BLOCK, pf, pl, pc); + let tab: *syntax.node = nil; if (ntest == 0i32) { // no @test fns in this unit — exit 0, nothing to run. - let ret: *node = newnode(nkind.N_RETURN, pf, pl, pc); - let zero: *node = newnode(nkind.N_INTLIT, pf, pl, pc); + let ret: *syntax.node = syntax.newnode(syntax.nkind.N_RETURN, pf, pl, pc); + let zero: *syntax.node = syntax.newnode(syntax.nkind.N_INTLIT, pf, pl, pc); zero.uval = 0u64; ret.lhs = zero; body.list = ret; } else { // const __wwtests: [](str, *fn() void) = [rows...]; // wwstage tuple-type elements wrap in N_TPARAM (parse.ww:308). - let e0: *node = newnode(nkind.N_TNAME, pf, pl, pc); + let e0: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, pf, pl, pc); e0.str = "str"; - let p0: *node = newnode(nkind.N_TPARAM, pf, pl, pc); + let p0: *syntax.node = syntax.newnode(syntax.nkind.N_TPARAM, pf, pl, pc); p0.lhs = e0; - let vret: *node = newnode(nkind.N_TNAME, pf, pl, pc); + let vret: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, pf, pl, pc); vret.str = "void"; - let vfn: *node = newnode(nkind.N_TFN, pf, pl, pc); + let vfn: *syntax.node = syntax.newnode(syntax.nkind.N_TFN, pf, pl, pc); vfn.lhs = vret; - let e1: *node = newnode(nkind.N_TPTR, pf, pl, pc); + let e1: *syntax.node = syntax.newnode(syntax.nkind.N_TPTR, pf, pl, pc); e1.lhs = vfn; - let p1: *node = newnode(nkind.N_TPARAM, pf, pl, pc); + let p1: *syntax.node = syntax.newnode(syntax.nkind.N_TPARAM, pf, pl, pc); p1.lhs = e1; - let tup: *node = newnode(nkind.N_TTUPLE, pf, pl, pc); + let tup: *syntax.node = syntax.newnode(syntax.nkind.N_TTUPLE, pf, pl, pc); tup.list = p0; p0.next = p1; - let tsl: *node = newnode(nkind.N_TSLICE, pf, pl, pc); + let tsl: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, pf, pl, pc); tsl.lhs = tup; - let arr: *node = newnode(nkind.N_ARRLIT, pf, pl, pc); + let arr: *syntax.node = syntax.newnode(syntax.nkind.N_ARRLIT, pf, pl, pc); arr.list = rhead; - tab = newnode(nkind.N_LET, pf, pl, pc); - tab.op = tkind.TK_CONST; + tab = syntax.newnode(syntax.nkind.N_LET, pf, pl, pc); + tab.op = syntax.tkind.TK_CONST; tab.str = "__wwtests"; tab.lhs = tsl; tab.rhs = arr; @@ -17270,23 +17270,23 @@ export fn checkfile(c: *checker, file: *node) void = { // duplicate-decl reject (#23) the same way, so a pathological // user `const __wwtests` stays a downstream type error in // both stages rather than a dup-diagnostic in only one. - scopedefineinmodule(c.top, tab.str, "", skind.SK_VAR, nil, tab); + syntax.scopedefineinmodule(c.top, tab.str, "", syntax.skind.SK_VAR, nil, tab); - let arg: *node = newnode(nkind.N_IDENT, pf, pl, pc); + let arg: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc); arg.str = "__wwtests"; - let call: *node = newnode(nkind.N_CALL, pf, pl, pc); - let cid: *node = newnode(nkind.N_IDENT, pf, pl, pc); + let call: *syntax.node = syntax.newnode(syntax.nkind.N_CALL, pf, pl, pc); + let cid: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc); cid.str = "run"; call.lhs = cid; call.list = arg; - let ret: *node = newnode(nkind.N_RETURN, pf, pl, pc); + let ret: *syntax.node = syntax.newnode(syntax.nkind.N_RETURN, pf, pl, pc); ret.lhs = call; body.list = ret; }; - let m: *node = newnode(nkind.N_FNDECL, pf, pl, pc); + let m: *syntax.node = syntax.newnode(syntax.nkind.N_FNDECL, pf, pl, pc); m.str = "main"; m.exported = 1i32; - let rety: *node = newnode(nkind.N_TNAME, pf, pl, pc); + let rety: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, pf, pl, pc); rety.str = "i32"; m.lhs = rety; m.body = body; @@ -17294,7 +17294,7 @@ export fn checkfile(c: *checker, file: *node) void = { // type_ pre-set on main: installdecl never stamps a fn's type_ on // the ww side — cgfn reads lhs/list on demand. Pass-2 below // resolve-walks the appended bodies. - let tl: *node = file.list; + let tl: *syntax.node = file.list; if (tl == nil) { if (tab != nil) { file.list = tab; tab.next = m; } else { file.list = m; }; @@ -17318,12 +17318,12 @@ export fn checkfile(c: *checker, file: *node) void = { // dispatch. Mirror resolvewalk L405 which descends n.attr on // inner nodes. if (d.attr != nil) { resolvewalk(c, d.attr); }; - let k: nkind = d.kind; + let k: syntax.nkind = d.kind; switch (k) { - case nkind.N_FNDECL: + case syntax.nkind.N_FNDECL: if (d.lhs != nil) { resolvewalk(c, d.lhs); }; // return type resolvefnbody(c, d); - case nkind.N_DEF: + case syntax.nkind.N_DEF: // #11: a module-level `def xs: [_]T = arrlit;` must infer // its length BEFORE resolvewalk stamps d.lhs's tinfo, the // def twin of the N_LET arm below. #7 wired only the let @@ -17356,9 +17356,9 @@ export fn checkfile(c: *checker, file: *node) void = { }; }; }; - case nkind.N_TYPEDECL: + case syntax.nkind.N_TYPEDECL: if (d.lhs != nil) { resolvewalk(c, d.lhs); }; - case nkind.N_LET: + case syntax.nkind.N_LET: // #7: a module-level `let xs: [_]T = arrlit;` must infer // its length BEFORE resolvewalk stamps d.lhs's tinfo — // otherwise the array tinfo caches the alen=0 sentinel and @@ -17417,21 +17417,21 @@ export fn checkfile(c: *checker, file: *node) void = { // untouched: its synth main calls the @test fns, so they must remain. // Twin: cmd/wcc/check.c. if (c.istest == 0) { - let prev: *node = nil; - let e: *node = file.list; + let prev: *syntax.node = nil; + let e: *syntax.node = file.list; for (e != nil) { let istest: bool = false; - if (e.kind == nkind.N_FNDECL) { - let at: *node = e.attr; + if (e.kind == syntax.nkind.N_FNDECL) { + let at: *syntax.node = e.attr; for (at != nil) { - if (at.kind == nkind.N_ATTR - && streq(at.str, "test")) { + if (at.kind == syntax.nkind.N_ATTR + && syntax.streq(at.str, "test")) { istest = true; }; at = at.next; }; }; - let nx: *node = e.next; + let nx: *syntax.node = e.next; if (istest) { if (prev == nil) { file.list = nx; } else { prev.next = nx; }; @@ -18256,8 +18256,8 @@ import strconv; // for the param (callee side) and the call-site slice descriptor // (caller side) both advertise their effective type as []ELEM — // every isslicetype / nodeisslice check then succeeds naturally. -fn slicewrap(c: *cgen, elem: *node) *node = { - let s: *node = newnode(nkind.N_TSLICE, "", 0, 0); +fn slicewrap(c: *cgen, elem: *syntax.node) *syntax.node = { + let s: *syntax.node = syntax.newnode(syntax.nkind.N_TSLICE, "", 0, 0); s.lhs = elem; return s; }; @@ -18266,12 +18266,12 @@ fn slicewrap(c: *cgen, elem: *node) *node = { // param node (the one with op == TK_ELLIPSIS) plus the count of // non-variadic params before it. Returns nil/0 when no variadic. // nfixed_out cannot be nil. -fn findvariadicparam(ps: *node, nfixed_out: *i32) *node = { +fn findvariadicparam(ps: *syntax.node, nfixed_out: *i32) *syntax.node = { *nfixed_out = 0; - let p: *node = ps; + let p: *syntax.node = ps; for (p != nil) { - if (p.kind == nkind.N_PARAM) { - if (p.op == tkind.TK_ELLIPSIS) { + if (p.kind == syntax.nkind.N_PARAM) { + if (p.op == syntax.tkind.TK_ELLIPSIS) { return p; }; *nfixed_out += 1; @@ -18293,19 +18293,19 @@ fn findvariadicparam(ps: *node, nfixed_out: *i32) *node = { // strings.contains gained a variadic shape and a caller's // bytes.contains call site picked strings.contains' variadic // params for arg-prep while emitting CALL bytes.contains. -fn callee_variadic_param(c: *cgen, callee: *node, nfixed_out: *i32) *node = { +fn callee_variadic_param(c: *cgen, callee: *syntax.node, nfixed_out: *i32) *syntax.node = { *nfixed_out = 0; if (callee == nil) { return nil; }; - let ps: *node = nil; - if (callee.kind == nkind.N_IDENT) { + let ps: *syntax.node = nil; + if (callee.kind == syntax.nkind.N_IDENT) { if (callee.str.len == 0) { return nil; }; ps = fnparamslookup(c, callee.str); - } else { if (callee.kind == nkind.N_DOT) { + } else { if (callee.kind == syntax.nkind.N_DOT) { if (callee.str.len == 0) { return nil; }; let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; @@ -18347,21 +18347,21 @@ fn callee_variadic_param(c: *cgen, callee: *node, nfixed_out: *i32) *node = { // payload word) or the float-source box was misclassified as a float arg // (#48: MOVSD ate the tag word into X0). Mirrors cstage's precomputed // widen[i]/widen_sz[i] (cmd/w6c/cgen.c cgcall). -fn argtaggedwidensz(c: *cgen, arg0: *node, param: *node) i32 = { +fn argtaggedwidensz(c: *cgen, arg0: *syntax.node, param: *syntax.node) i32 = { if (param == nil) { return 0; }; - if (param.kind != nkind.N_PARAM) { return 0; }; - if (param.op == tkind.TK_ELLIPSIS) { return 0; }; - let ptype: *node = param.lhs; + if (param.kind != syntax.nkind.N_PARAM) { return 0; }; + if (param.op == syntax.tkind.TK_ELLIPSIS) { return 0; }; + let ptype: *syntax.node = param.lhs; if (ptype == nil) { return 0; }; if (!istaggedtype(c, ptype)) { return 0; }; // >48B slot is memory-class: pushargsrev stages it below the register // words and the drain skips it (dmemsz) — never a register widen. - if (taggedmemargsize(ptype.type_: *tinfo) > 0) { return 0; }; - let arg: *node = taggedcastpeel(c, arg0); + if (taggedmemargsize(ptype.type_: *syntax.tinfo) > 0) { return 0; }; + let arg: *syntax.node = taggedcastpeel(c, arg0); let pslot: i32 = slotsize(c, ptype); // Already a matching-slot tagged source → natural push, no widen // (mirrors pushargsrev's aistagged gates: ident/call/index/dot/deref). - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, arg.str); if (lc != nil) { if (istaggedtype(c, lc.tnode)) { @@ -18370,13 +18370,13 @@ fn argtaggedwidensz(c: *cgen, arg0: *node, param: *node) i32 = { }; }; if (taggedcallslot(c, arg) == pslot) { return 0; }; - if (arg.kind == nkind.N_INDEX) { + if (arg.kind == syntax.nkind.N_INDEX) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == pslot) { return 0; }; }; }; - if (arg.kind == nkind.N_DOT) { + if (arg.kind == syntax.nkind.N_DOT) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == pslot) { return 0; }; }; }; - if (arg.kind == nkind.N_UN && arg.op == tkind.TK_STAR) { + if (arg.kind == syntax.nkind.N_UN && arg.op == syntax.tkind.TK_STAR) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == pslot) { return 0; }; }; }; // The 8B nullable fold pushes one pointer word the scalar drain path @@ -18386,9 +18386,9 @@ fn argtaggedwidensz(c: *cgen, arg0: *node, param: *node) i32 = { return pslot; }; -fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { +fn pushargsrev(c: *cgen, arg: *syntax.node, param: *syntax.node, memphase: bool) i32 = { if (arg == nil) { return 0; }; - let nextparam: *node = nil; + let nextparam: *syntax.node = nil; if (param != nil) { nextparam = param.next; }; let rest: i32 = pushargsrev(c, arg.next, nextparam, memphase); // Family C (#35): peel tagged→tagged casts FIRST so every gate @@ -18404,33 +18404,33 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // type (so widening into a >48B slot is caught), else the arg's // own stamped type (fn-ptr callee carries no param nodes). let memsz: i32 = 0; - let memptype: *node = nil; - if (param != nil) { if (param.kind == nkind.N_PARAM) { - if (param.op != tkind.TK_ELLIPSIS) { + let memptype: *syntax.node = nil; + if (param != nil) { if (param.kind == syntax.nkind.N_PARAM) { + if (param.op != syntax.tkind.TK_ELLIPSIS) { memptype = param.lhs; if (memptype != nil) { - memsz = taggedmemargsize(memptype.type_: *tinfo); + memsz = taggedmemargsize(memptype.type_: *syntax.tinfo); }; }; }; }; if (memsz == 0) { - memsz = taggedmemargsize(arg.type_: *tinfo); + memsz = taggedmemargsize(arg.type_: *syntax.tinfo); }; if (memphase != (memsz > 0)) { return rest; }; if (memsz > 0) { // same-type check — mirror cstage's `(pu == au) || // type_eq(p->type, at)` widen detection. let same: bool = false; - let at: *tinfo = arg.type_: *tinfo; + let at: *syntax.tinfo = arg.type_: *syntax.tinfo; if (memptype != nil) { - let pt: *tinfo = memptype.type_: *tinfo; - let pu: *tinfo = pt; + let pt: *syntax.tinfo = memptype.type_: *syntax.tinfo; + let pu: *syntax.tinfo = pt; pu = tichase(pu); - let au: *tinfo = at; + let au: *syntax.tinfo = at; au = tichase(au); if (pu != nil && pu == au) { same = true; }; if (!same && pt != nil && at != nil) { - if (typeeq(pt, at)) { same = true; }; + if (syntax.typeeq(pt, at)) { same = true; }; }; } else { same = true; @@ -18450,7 +18450,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, memptype.type_: *tinfo, arg, + cgwidentaggedstore(c, memptype.type_: *syntax.tinfo, arg, "BP", scroff, memsz); let pp: i32 = memsz - 8; for (pp >= 0) { @@ -18469,12 +18469,12 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // return) — its result is in memory behind a dest pointer, // not a register cursor; receive-then-push is the // #40-family follow-up. - if (arg.kind == nkind.N_CALL) { + if (arg.kind == syntax.nkind.N_CALL) { let mc: str = "#38b: sret-class tagged call result as a >48B by-value arg unwired (#40-family follow-up)\n"; os.write(2, mc.ptr, mc.len: u64); os.exit(1); }; - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, arg.str); if (lc != nil) { let w: i32 = memsz / 8 - 1; @@ -18525,20 +18525,20 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { let widensz: i32 = 0; let widentag: i32 = 0; if (param != nil) { - if (param.kind == nkind.N_PARAM) { + if (param.kind == syntax.nkind.N_PARAM) { // Hare-style variadic `T...`: effective param type is // []T (slice). The arg here is the synthesised slice // descriptor (or a forwarded `xs...` slice), not a // value of T being widened into a tagged slot — skip // the widening detection so the slice-ident fast path // at the bottom of pushargsrev gets the push. - if (param.op == tkind.TK_ELLIPSIS) { + if (param.op == syntax.tkind.TK_ELLIPSIS) { widensz = 0; } else { - let ptype: *node = param.lhs; + let ptype: *syntax.node = param.lhs; if (istaggedtype(c, ptype)) { let aistagged: bool = false; - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, arg.str); if (lc != nil) { // #55: only treat a tagged ident as @@ -18582,7 +18582,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // slotsize read .type_, so feed the N_INDEX node // directly. cstage reads the element via // base->type->sub (cmd/w6c/cgen.c:3518). - if (arg.kind == nkind.N_INDEX) { + if (arg.kind == syntax.nkind.N_INDEX) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == slotsize(c, ptype)) { aistagged = true; @@ -18598,7 +18598,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // twin of the N_INDEX arm above; cstage // needs no kind gate (its widen[i] `same` // check is type-keyed on args[i]->type). - if (arg.kind == nkind.N_DOT) { + if (arg.kind == syntax.nkind.N_DOT) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == slotsize(c, ptype)) { aistagged = true; @@ -18611,7 +18611,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // scalar branch boxed the box. Same // slotsize key as the N_INDEX/N_DOT // stamped-carrier arms above. - if (arg.kind == nkind.N_UN && arg.op == tkind.TK_STAR) { + if (arg.kind == syntax.nkind.N_UN && arg.op == syntax.tkind.TK_STAR) { if (istaggedtype(c, arg)) { if (slotsize(c, arg) == slotsize(c, ptype)) { aistagged = true; @@ -18620,7 +18620,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { }; if (!aistagged) { widensz = slotsize(c, ptype); - let tagged: *node = resolvetagged(c, ptype); + let tagged: *syntax.node = resolvetagged(c, ptype); let t: i32 = taggedvariantindex(c, tagged, arg); if (t < 0) { t = 0; }; widentag = t; @@ -18648,7 +18648,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // the scratch store, whose #242/#66 tuple arm handles the // literal/cast forms and loud-stops the rest (#72). Mirrors // cstage cg_widen_tagged_push src_is_tuple. - let argtup: *tinfo = arg.type_: *tinfo; + let argtup: *syntax.tinfo = arg.type_: *syntax.tinfo; argtup = tichase(argtup); let argistuple: bool = false; // #55: a tagged SOURCE widened into a wider/reordered tagged param @@ -18662,16 +18662,16 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // routing (cmd/w6c/cgen.c:2982). let argistagged: bool = false; if (argtup != nil) { - if (argtup.kind == tykind.TY_TUPLE) { + if (argtup.kind == syntax.tykind.TY_TUPLE) { argistuple = true; }; - if (argtup.kind == tykind.TY_TAGGED) { + if (argtup.kind == syntax.tykind.TY_TAGGED) { argistagged = true; }; }; let pname: str = rhsstructpayload(c, arg); if (pname.len > 0 || argistuple || argistagged) { - let ptype: *node = param.lhs; + let ptype: *syntax.node = param.lhs; let scroff: i32 = tagscradd(c, widensz); emitline("\tXORQ\tAX, AX\n"); let zz: i32 = 0; @@ -18681,7 +18681,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, ptype.type_: *tinfo, arg, "BP", scroff, widensz); + cgwidentaggedstore(c, ptype.type_: *syntax.tinfo, arg, "BP", scroff, widensz); let pp: i32 = widensz - 8; for (pp >= 0) { emitline("\tMOVQ\t"); @@ -18757,20 +18757,20 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // nkind.N_SLICE expression as arg: `buf[lo:hi]` builds a slice header // on the stack matching C cgen's sequence — push base, push hi, // compute lo, pop into BX/CX, derive len/ptr, push (cap, len, ptr). - if (arg.kind == nkind.N_SLICE) { - let base: *node = arg.lhs; - let lo: *node = arg.rhs; - let hi: *node = arg.cond; + if (arg.kind == syntax.nkind.N_SLICE) { + let base: *syntax.node = arg.lhs; + let lo: *syntax.node = arg.rhs; + let hi: *syntax.node = arg.cond; let baselocal: *local = nil; - let globaltn: *node = nil; + let globaltn: *syntax.node = nil; let globalname: str; globalname.ptr = nil; globalname.len = 0; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal == nil) { - let gt: *node = letvartnode(c, bn); + let gt: *syntax.node = letvartnode(c, bn); if (gt != nil) { globaltn = gt; globalname = bn; @@ -18783,9 +18783,9 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // checker-stamped element tinfo on base.type_ instead. Cstage // twin reads base->type (cgen.c pushargs N_SLICE esz). Mirror // of the cgslice #252 site. - let dotbu: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_DOT) { - dotbu = base.type_: *tinfo; + let dotbu: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_DOT) { + dotbu = base.type_: *syntax.tinfo; dotbu = tichase(dotbu); };}; // #60 (alias arc #5): alias-NAMED N_IDENT base — the tnode @@ -18794,10 +18794,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // pusharg twin of the cgslice fix (cstage pushargs N_SLICE // reads bu = type_chase_named(base->type) uniformly). let basealias: bool = false; - let bu60: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; - if (bt60 != nil) { if (bt60.kind == tykind.TY_NAMED) { + let bu60: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt60 != nil) { if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; bu60 = tichase(bt60); };}; @@ -18817,18 +18817,18 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { esz = dotbu.sub.size: i32; };};}; if (bu60 != nil) { - let es60: *tinfo = tichase(bu60.sub); + let es60: *syntax.tinfo = tichase(bu60.sub); if (es60 != nil) { esz = es60.size: i32; }; }; // base address → push if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarr60: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { isarr60 = true; }; + if (tn.kind == syntax.nkind.N_TARRAY) { isarr60 = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). - if (bu60 != nil) { isarr60 = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { isarr60 = bu60.kind == syntax.tykind.TY_ARRAY; }; if (isarr60) { emitline("\tLEAQ\t"); emitoff(baselocal.off: i64); @@ -18839,10 +18839,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("(BP), AX\n"); }; } else { if (globaltn != nil) { - let gisarr60: bool = globaltn.kind == nkind.N_TARRAY; + let gisarr60: bool = globaltn.kind == syntax.nkind.N_TARRAY; // #60: alias-NAMED base — chased kind; runtime- // unreachable until #77/#78 global DATA. - if (bu60 != nil) { gisarr60 = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { gisarr60 = bu60.kind == syntax.tykind.TY_ARRAY; }; if (gisarr60) { emitline("\tLEAQ\t"); emitsymname(c, globalname); @@ -18865,11 +18865,11 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { if (hi != nil) { cgexpr(c, hi); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { - let lenn: *node = tn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (tn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = tn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -18880,19 +18880,19 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // N_TNAME); a plain `[MAX]u8` base reaches here // with a non-N_INTLIT dim and dropped the // default-hi entirely. cstage reads bu->alen. - let abt: *tinfo = tichase(tn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(tn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); }; }; - } else { if (tn.kind == nkind.N_TSLICE) { + } else { if (tn.kind == syntax.nkind.N_TSLICE) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); - } else { if (tn.kind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { + } else { if (tn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); @@ -18902,21 +18902,21 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // #60: alias-NAMED base default-hi — chased kind // (see the cgslice twin). if (bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); };}; }; } else { if (globaltn != nil) { - if (globaltn.kind == nkind.N_TARRAY) { - let lenn: *node = globaltn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (globaltn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = globaltn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -18924,20 +18924,20 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // #56: def/const dim on a global array base — // resolve from the stamped array tinfo (rule-13), // twin of the local arg-push arm above. - let abt: *tinfo = tichase(globaltn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(globaltn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); }; }; - } else { if (globaltn.kind == nkind.N_TSLICE) { + } else { if (globaltn.kind == syntax.nkind.N_TSLICE) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); emitline("\tMOVQ\t8(CX), AX\n"); - } else { if (globaltn.kind == nkind.N_TNAME) { - if (streq(globaltn.str, "str")) { + } else { if (globaltn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(globaltn.str, "str")) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -18947,12 +18947,12 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // #60: alias-NAMED global base default-hi — chased // kind; runtime-unreachable until #77/#78 global DATA. if (bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -18998,7 +18998,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // into argregs lands the canonical (ptr/tag, len/v0, cap/v1). // For tagged ident with a >24B slot (slice-payload variant), // push a fourth word from off+24. - if (arg.kind == nkind.N_IDENT) { + if (arg.kind == syntax.nkind.N_IDENT) { let nm: str = arg.str; let lc: *local = localfindnode(c, nm); if (lc != nil) { @@ -19058,9 +19058,9 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // from dotchainaddr). The slot-word count is the stamped tinfo // size (the type table, byte-id with cstage struct_arg_size). if (lc == nil) { - let gst: *tinfo = arg.type_: *tinfo; + let gst: *syntax.tinfo = arg.type_: *syntax.tinfo; gst = tichase(gst); - if (gst != nil) { if (gst.kind == tykind.TY_STRUCT) { + if (gst != nil) { if (gst.kind == syntax.tykind.TY_STRUCT) { let gsz: i32 = gst.size: i32; if (gsz > 0 && gsz <= 16 && (isletvar(c, nm) || deflookup(c, nm))) { @@ -19097,7 +19097,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // would LEAQ an undefined main.(SB) (w6l fails); a // def must fall through to the const-fold path instead. if (gst != nil && isletvar(c, nm)) { - if (gst.kind == tykind.TY_SLICE) { + if (gst.kind == syntax.tykind.TY_SLICE) { emitline("\tLEAQ\t"); emitsymname(c, nm); emitline("(SB), BX\n"); @@ -19109,7 +19109,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { emitline("\tPUSHQ\tAX\n"); return rest + 3; }; - if (gst.kind == tykind.TY_STR) { + if (gst.kind == syntax.tykind.TY_STR) { emitline("\tLEAQ\t"); emitsymname(c, nm); emitline("(SB), CX\n"); @@ -19134,7 +19134,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // >24B sret'd into @aggargscr then pushed from there. Pre-fix every // such source fell to the scalar default (one PUSHQ for a multi-word // aggregate) and stack-imbalanced against the type-based drain. - let aggsz: i32 = aggargsizetn(arg.type_: *tinfo); + let aggsz: i32 = aggargsizetn(arg.type_: *syntax.tinfo); if (aggsz > 0) { // Exclude a ≤16B-struct IDENT — it owns the structparamsize // fast path above (or, when a cross-module same-leaf collision @@ -19145,10 +19145,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // args[i]->type) — a name-keyed gate here re-opens the #211/#13 // name-keyed divergence the cstage type gate doesn't have. let structident: bool = false; - if (arg.kind == nkind.N_IDENT) { - let st: *tinfo = arg.type_: *tinfo; + if (arg.kind == syntax.nkind.N_IDENT) { + let st: *syntax.tinfo = arg.type_: *syntax.tinfo; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { if (st.size: i32 <= 16) { structident = true; }; }; }; }; @@ -19159,7 +19159,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { os.exit(1); }; let nwords: i32 = (aggsz + 7) / 8; - if (arg.kind == nkind.N_CALL) { + if (arg.kind == syntax.nkind.N_CALL) { if (callsretsize(c, arg) > 0) { let scr: i32 = localadd(c, "@aggargscr", aggsz, nil); @@ -19215,9 +19215,9 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // the MOVSS load on the pop side touches only the low 4. let fk: i32 = 0; if (arg != nil) { - let at: *tinfo = arg.type_: *tinfo; - if (typeisf32(at)) { fk = 1; } - else { if (typeisfloat(at)) { fk = 2; }; }; + let at: *syntax.tinfo = arg.type_: *syntax.tinfo; + if (syntax.typeisf32(at)) { fk = 1; } + else { if (syntax.typeisfloat(at)) { fk = 2; }; }; }; if (fk != 0) { cgexpr(c, arg); @@ -19235,14 +19235,14 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // the box cursor; the restage + push then key on the param tuple type // node (declared element widths), not the literal's element- // constructed types. Mirrors cstage cgcall paramtup. - let paramtt: *node = nil; - if (arg.kind == nkind.N_TUPLE) { if (param != nil) { - if (param.kind == nkind.N_PARAM && param.lhs != nil) { - let ptn: *node = param.lhs; - for (ptn != nil && ptn.kind == nkind.N_TNAME) { + let paramtt: *syntax.node = nil; + if (arg.kind == syntax.nkind.N_TUPLE) { if (param != nil) { + if (param.kind == syntax.nkind.N_PARAM && param.lhs != nil) { + let ptn: *syntax.node = param.lhs; + for (ptn != nil && ptn.kind == syntax.nkind.N_TNAME) { ptn = aliaslookup(c, ptn.str); }; - if (ptn != nil) { if (ptn.kind == nkind.N_TTUPLE) { paramtt = ptn; }; }; + if (ptn != nil) { if (ptn.kind == syntax.nkind.N_TTUPLE) { paramtt = ptn; }; }; }; }; }; if (paramtt != nil) { cgtuplelittocursor(c, arg, paramtt); } @@ -19258,17 +19258,17 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // arg-class regs. When the PARAM tuple type is known (#68), walk its // declared element type nodes (p.lhs); else an N_TUPLE literal's // elements are VALUE exprs classified the way cgtuplelittocursor does. - let tuparg: *node = paramtt; + let tuparg: *syntax.node = paramtt; if (tuparg == nil) { tuparg = nodetuplearg(c, arg); }; if (tuparg != nil) { let tuplit: bool = false; - if (paramtt == nil) { if (tuparg.kind == nkind.N_TUPLE) { tuplit = true; }; }; + if (paramtt == nil) { if (tuparg.kind == syntax.nkind.N_TUPLE) { tuplit = true; }; }; let gptot: i32 = 0; let sstot: i32 = 0; let tsz: i32 = 0; - let p: *node = tuparg.list; + let p: *syntax.node = tuparg.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (tuplit) { et = p; }; // C-t2 (ken demand 1, rule 7): a COMPOSITE element // (nested tuple/struct/array/tagged) occupies more @@ -19278,19 +19278,19 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // skewed). The stamped tinfo classifies both type // nodes and literal value exprs. Mirrors the cstage // restage guard. - let eti: *tinfo = et.type_: *tinfo; + let eti: *syntax.tinfo = et.type_: *syntax.tinfo; eti = tichase(eti); if (eti != nil) { - let bad: bool = eti.kind == tykind.TY_TUPLE - || eti.kind == tykind.TY_STRUCT - || eti.kind == tykind.TY_ARRAY; + let bad: bool = eti.kind == syntax.tykind.TY_TUPLE + || eti.kind == syntax.tykind.TY_STRUCT + || eti.kind == syntax.tykind.TY_ARRAY; // #68: a declared-tagged element graduates to a real // widen — the decl-aware send (cgtuplelittocursor over // the param tuple type) left the box words in the // cursor, so tupstore below carries them. A tagged // element with no param decl stays rule-7 loud (the // cursor was filled stamped-keyed). - if (eti.kind == tykind.TY_TAGGED && paramtt == nil) { bad = true; }; + if (eti.kind == syntax.tykind.TY_TAGGED && paramtt == nil) { bad = true; }; if (bad) { let mne: str = "#32: tuple arg element kind unsupported (nested tuple/struct/array/tagged; rule 7)\n"; os.write(2, mne.ptr, mne.len: u64); @@ -19327,7 +19327,7 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { let eoff: i32 = 0; p = tuparg.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (tuplit) { et = p; }; let eslot: i32 = 8; if (tuplit) { @@ -19358,10 +19358,10 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // single-PUSHQ default and silently skewed every later arg // register. Mirrors the cstage cgcall guard. { - let ati: *tinfo = arg.type_: *tinfo; + let ati: *syntax.tinfo = arg.type_: *syntax.tinfo; ati = tichase(ati); if (ati != nil) { - if (ati.kind == tykind.TY_TUPLE) { + if (ati.kind == syntax.tykind.TY_TUPLE) { let m32: str = "#32: tuple arg from unsupported source shape (call/ident/literal/unwrap only; rule 7)\n"; os.write(2, m32.ptr, m32.len: u64); os.exit(1); @@ -19416,8 +19416,8 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // keeps the stamped-carrier kind gate (#67 pattern) — the // remaining kinds (deref/cast/unwrap) are word0-only reads today, // filed residual. - if (arg.kind == nkind.N_INDEX || arg.kind == nkind.N_DOT - || (arg.kind == nkind.N_UN && arg.op == tkind.TK_STAR)) { + if (arg.kind == syntax.nkind.N_INDEX || arg.kind == syntax.nkind.N_DOT + || (arg.kind == syntax.nkind.N_UN && arg.op == syntax.tkind.TK_STAR)) { if (istaggedtype(c, arg)) { let isz: i32 = slotsize(c, arg); // #35 (Family C): a mem-based read left the box @@ -19454,21 +19454,21 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node, memphase: bool) i32 = { // route a tagged-return call result through the AX/DX/CX/R8 high→low // push convention rather than the concrete-variant widening path // (which drops DX/CX/R8). See task #21. -export fn taggedcallslot(c: *cgen, n: *node) i32 = { +export fn taggedcallslot(c: *cgen, n: *syntax.node) i32 = { if (n == nil) { return 0; }; - if (n.kind != nkind.N_CALL) { return 0; }; - let callee: *node = n.lhs; + if (n.kind != syntax.nkind.N_CALL) { return 0; }; + let callee: *syntax.node = n.lhs; if (callee == nil) { return 0; }; - if (callee.kind != nkind.N_IDENT) { return 0; }; - let rtyp: *node = fnretlookup(c, callee.str); + if (callee.kind != syntax.nkind.N_IDENT) { return 0; }; + let rtyp: *syntax.node = fnretlookup(c, callee.str); if (!istaggedtype(c, rtyp)) { return 0; }; return slotsize(c, rtyp); }; -fn nodeisslice(c: *cgen, n: *node) bool = { +fn nodeisslice(c: *cgen, n: *syntax.node) bool = { if (n == nil) { return false; }; - let k: nkind = n.kind; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_IDENT) { let nm: str = n.str; let lc: *local = localfindnode(c, nm); // F7-c1: the local read collapses onto the checker-stamped @@ -19479,7 +19479,7 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // decl localfindnode keys on); the localfindnode gate stays to // keep the global-var-not-def case routing to false (out of F7 // scope), so this is a zero-delta mechanic validation. - if (lc != nil) { return typeisslice(n.type_: *tinfo); }; + if (lc != nil) { return syntax.typeisslice(n.type_: *syntax.tinfo); }; // #21: a module-level `def g: []T` ident is not a frame // slot (localfindnode→nil), so the local arm above misses // it and it would fall to the scalar single-PUSHQ default, @@ -19491,12 +19491,12 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // const-fold, so the push site and cgcall's pop sizer flip // together on this shared recognizer (load-bearing). if (deflookup(c, nm)) { - return typeisslice(n.type_: *tinfo); + return syntax.typeisslice(n.type_: *syntax.tinfo); }; return false; }; - if (k == nkind.N_SLICE) { return true; }; - if (k == nkind.N_CAST) { return isslicetype(c, n.rhs); }; + if (k == syntax.nkind.N_SLICE) { return true; }; + if (k == syntax.nkind.N_CAST) { return isslicetype(c, n.rhs); }; // #24: N_CALL returning a slice — cgexpr leaves (AX=ptr, // BX=len, CX=cap); pushargsrev's slice arm pushes CX/BX/AX // and cgcall pops 3 words. Without this arm the natural-push @@ -19508,22 +19508,22 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // doesn't shadow the explicit `mod.f()` qualifier — surfaced by // strings.slice returning `frombytes(utf8.slice(...))` // where strings.slice itself returns str. - if (k == nkind.N_CALL) { - let callee: *node = n.lhs; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = n.lhs; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { - let rtyp: *node = fnretlookupmod(c, callee.str, c.curmod); + if (callee.kind == syntax.nkind.N_IDENT) { + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, c.curmod); return isslicetype(c, rtyp); }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; - let rtyp: *node = fnretlookupmod(c, callee.str, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, cmod); return isslicetype(c, rtyp); }; }; @@ -19534,8 +19534,8 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // resolve to the right tinfo via check.ww:1947-1978 (pseudo-field // + struct-field stamps). Cstage cgen.c:182-184 node_isslice = // type_isslice(n->type) — same shape. Collapsed per A.6.3h (#56). - if (k == nkind.N_DOT) { - return typeisslice(n.type_: *tinfo); + if (k == syntax.nkind.N_DOT) { + return syntax.typeisslice(n.type_: *syntax.tinfo); }; // #45 (F7-c2): `arr[i]` whose element is a slice. cgindex leaves // (AX=ptr, BX=len, CX=cap) for a 24B element, but with no N_INDEX @@ -19545,8 +19545,8 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // type (exprtype N_INDEX stamps n.type_, check.ww:2777), mirroring // cstage node_isslice = type_isslice(n->type) and the N_INDEX arms of // nodeisstr (below) + nodeisunsigned (:1798). - if (k == nkind.N_INDEX) { - return typeisslice(n.type_: *tinfo); + if (k == syntax.nkind.N_INDEX) { + return syntax.typeisslice(n.type_: *syntax.tinfo); }; return false; }; @@ -19567,11 +19567,11 @@ fn nodeisslice(c: *cgen, n: *node) bool = { // - N_UN(TK_STAR) of `*str` — cgun itself emits only `MOVQ (AX), AX` // and never loads .len into BX; fixing the recognizer alone won't // help. Tracked alongside the broader cgun-load-shape gap. -fn nodeisstr(c: *cgen, n: *node) bool = { +fn nodeisstr(c: *cgen, n: *syntax.node) bool = { if (n == nil) { return false; }; - let k: nkind = n.kind; - if (k == nkind.N_STRLIT) { return true; }; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_STRLIT) { return true; }; + if (k == syntax.nkind.N_IDENT) { let nm: str = n.str; let lc: *local = localfindnode(c, nm); // F7-c1: the local read collapses onto the checker-stamped @@ -19584,7 +19584,7 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // localfindnode keys on). The localfindnode gate stays to keep // the global-var-not-def case routing to false (out of F7 // scope), so this is a zero-delta mechanic validation. - if (lc != nil) { return typeisstr(n.type_: *tinfo); }; + if (lc != nil) { return syntax.typeisstr(n.type_: *syntax.tinfo); }; // #21: a module-level `def s: str` ident is not a frame slot // (localfindnode→nil), so the local arm above misses it and // it would fall to the scalar single-PUSHQ default, dropping @@ -19596,29 +19596,29 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // $len), so the push site and cgcall's pop sizer flip together // on this shared recognizer (load-bearing). if (deflookup(c, nm)) { - return typeisstr(n.type_: *tinfo); + return syntax.typeisstr(n.type_: *syntax.tinfo); }; return false; }; - if (k == nkind.N_CALL) { - let callee: *node = n.lhs; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = n.lhs; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { - let rtyp: *node = fnretlookupmod(c, callee.str, c.curmod); + if (callee.kind == syntax.nkind.N_IDENT) { + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, c.curmod); return isstrtype(c, rtyp); }; // #34: cross-module N_DOT — route through fnretlookupmod // so a same-leaf caller-module fn (different return shape) // doesn't shadow the explicit qualifier. - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; - let rtyp: *node = fnretlookupmod(c, callee.str, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, callee.str, cmod); return isstrtype(c, rtyp); }; }; @@ -19633,18 +19633,18 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // = type_isstr(n->type) and nodeisunsigned's N_INDEX arm (:1798). The // base-kind whitelist is gone — every base shape routes through the // one stamp read. - if (k == nkind.N_INDEX) { - return typeisstr(n.type_: *tinfo); + if (k == syntax.nkind.N_INDEX) { + return syntax.typeisstr(n.type_: *syntax.tinfo); }; // N_DOT: read the checker-stamped n.type_. Struct field, nested // dot, value-struct hops, and pseudo-fields (.ptr/.len/.cap) all // resolve to the right tinfo via check.ww:1947-1978. Cstage // cgen.c:168-170 node_isstr = type_isstr(n->type) — same shape. // Collapsed per A.6.3h (#56). - if (k == nkind.N_DOT) { - return typeisstr(n.type_: *tinfo); + if (k == syntax.nkind.N_DOT) { + return syntax.typeisstr(n.type_: *syntax.tinfo); }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { return isstrtype(c, n.rhs); }; return false; @@ -19655,9 +19655,9 @@ fn nodeisstr(c: *cgen, n: *node) bool = { // (cstage N_LET sz==8 ladder SSoT). t.type_ is stamped at check.ww // L426-436 for every type-AST kind callers reach. Collapsed onto the // tinfo helper per A.6.3b (#46). -fn typeis8byteprimitive(c: *cgen, t: *node) bool = { +fn typeis8byteprimitive(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeis8byteprim(t.type_: *tinfo); + return syntax.typeis8byteprim(t.type_: *syntax.tinfo); }; // elemissignedc — given an indexable type-AST (`*T`, `[]T`, `[N]T`), @@ -19665,7 +19665,7 @@ fn typeis8byteprimitive(c: *cgen, t: *node) bool = { // MOVSXD vs MOVL at esz=4 (and MOVSBQ/MOVSWQ at esz=1/2). Mirrors // cstage's `signed_elem` (cmd/w6c/cgen.c idx_eff path). Reads through // the stamped tinfo so alias/enum recursion lives in lib/ww/typ.ww. -fn elemissignedc(c: *cgen, t: *node) bool = { +fn elemissignedc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; // #65 Phase-N step-2 cleanup: peel TY_NAMED before the .sub read. // #64 now flows per-decl NAMED wrappers, so a NAMED-of-(`*T`/`[]T`/ @@ -19677,9 +19677,9 @@ fn elemissignedc(c: *cgen, t: *node) bool = { // idxeffti additionally drills `*[N]T` to the pointee array (#61) // so a signed-narrow element behind a pointer-to-array still // sign-extends on load. - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti == nil) { return false; }; - return typeissigned(ti.sub); + return syntax.typeissigned(ti.sub); }; // elemisfloatc — given an indexable type-AST (`*T`, `[]T`, `[N]T`), is @@ -19690,22 +19690,22 @@ fn elemissignedc(c: *cgen, t: *node) bool = { // .sub read exactly as elemissignedc does (#64/#65). Float-ness comes // from the SAME tinfo the esz already reads — never a fresh node-stamp // (the unstamped-base trap that broke the exprfloatkind collapse, #121). -fn elemisfloatc(c: *cgen, t: *node) bool = { +fn elemisfloatc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; // idxeffti = TY_NAMED peel + the `*[N]T` drill (#61). - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti == nil) { return false; }; - return typeisfloat(ti.sub); + return syntax.typeisfloat(ti.sub); }; // elemisf32c — narrower elemisfloatc: true only when the element is f32, // so cgindex picks MOVSS over MOVSD at the #119 element load. -fn elemisf32c(c: *cgen, t: *node) bool = { +fn elemisf32c(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; // idxeffti = TY_NAMED peel + the `*[N]T` drill (#61). - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti == nil) { return false; }; - return typeisf32(ti.sub); + return syntax.typeisf32(ti.sub); }; // elemisarrayc — given an indexable type-AST (`*T` / `[]T` / `[N]T`), is @@ -19717,20 +19717,20 @@ fn elemisf32c(c: *cgen, t: *node) bool = { // elemsizeof (:920-948) so elem-is-array aligns with the esz this same // tnode feeds. cstage twin: idx_eff(bt)->sub unwrapped == TY_ARRAY // (cmd/w6c/cgen.c). `c` kept for signature symmetry with elemisfloatc. -fn elemisarrayc(c: *cgen, t: *node) bool = { +fn elemisarrayc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - let k: nkind = t.kind; - let elem: *node = nil; - if (k == nkind.N_TPTR) { elem = t.lhs; }; - if (k == nkind.N_TSLICE) { elem = t.lhs; }; - if (k == nkind.N_TARRAY) { elem = t.lhs; }; + let k: syntax.nkind = t.kind; + let elem: *syntax.node = nil; + if (k == syntax.nkind.N_TPTR) { elem = t.lhs; }; + if (k == syntax.nkind.N_TSLICE) { elem = t.lhs; }; + if (k == syntax.nkind.N_TARRAY) { elem = t.lhs; }; if (elem == nil) { return false; }; - if (k == nkind.N_TPTR) { - if (elem.kind == nkind.N_TARRAY) { + if (k == syntax.nkind.N_TPTR) { + if (elem.kind == syntax.nkind.N_TARRAY) { if (elem.lhs != nil) { elem = elem.lhs; }; }; }; - return elem.kind == nkind.N_TARRAY; + return elem.kind == syntax.nkind.N_TARRAY; }; // tichase — transitive TY_NAMED peel, nil-passthrough. Exact wwstage @@ -19740,10 +19740,10 @@ fn elemisarrayc(c: *cgen, t: *node) bool = { // scalar shape (#60's esz=1/pointer-base SEGV family). One chased // accessor is the only spelled way to dealias; raw `.under` reads // outside it are the lint target (rob F2 ruling). -fn tichase(t0: *tinfo) *tinfo = { - let t: *tinfo = t0; +fn tichase(t0: *syntax.tinfo) *syntax.tinfo = { + let t: *syntax.tinfo = t0; // peel-ok: chase body - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + for (t != nil && t.kind == syntax.tykind.TY_NAMED) { t = t.under; }; return t; }; @@ -19752,11 +19752,11 @@ fn tichase(t0: *tinfo) *tinfo = { // element type comes from n.type_ (stamped tinfo) not a tnode. Same // role as typeisslice/typeisstr in lib/ww/typ.ww; kept cgen-local to // avoid widening the frontend surface for one #156 read-half check. -fn tinfoisarray(t: *tinfo) bool = { - let u: *tinfo = t; +fn tinfoisarray(t: *syntax.tinfo) bool = { + let u: *syntax.tinfo = t; u = tichase(u); if (u == nil) { return false; }; - return u.kind == tykind.TY_ARRAY; + return u.kind == syntax.tykind.TY_ARRAY; }; // fieldissignedc — does this field/element type-AST need sign- @@ -19764,9 +19764,9 @@ fn tinfoisarray(t: *tinfo) bool = { // cgen.c:240 `fld_issigned` SSoT). t.type_ is stamped at check.ww // L426-436 for every type-AST kind we see here (TNAME / TPTR / // TBANG / TENUM / TARRAY / TSLICE — see resolvewalk). -fn fieldissignedc(c: *cgen, t: *node) bool = { +fn fieldissignedc(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeissigned(t.type_: *tinfo); + return syntax.typeissigned(t.type_: *syntax.tinfo); }; // fieldloadop — pick the load instruction for a non-str struct @@ -19801,7 +19801,7 @@ fn fieldstoreop(c: *cgen, f: *fieldinfo) str = { // pointer-target, slice-element, etc.) rather than a struct fieldinfo. // Used at the index / tuple / pointer-deref sites where there's no // fieldinfo entry but the type-node + size are both known. -fn tnodeloadop(c: *cgen, t: *node, sz: i32) str = { +fn tnodeloadop(c: *cgen, t: *syntax.node, sz: i32) str = { let sigd: bool = fieldissignedc(c, t); if (sz == 1) { if (sigd) { return "MOVSBQ"; }; return "MOVZBQ"; }; if (sz == 2) { if (sigd) { return "MOVSWQ"; }; return "MOVZWQ"; }; @@ -19809,7 +19809,7 @@ fn tnodeloadop(c: *cgen, t: *node, sz: i32) str = { return "MOVQ"; }; -fn tnodestoreop(c: *cgen, t: *node, sz: i32) str = { +fn tnodestoreop(c: *cgen, t: *syntax.node, sz: i32) str = { if (sz == 1) { return "MOVB"; }; if (sz == 2) { return "MOVW"; }; if (sz == 4) { return "MOVL"; }; @@ -19841,13 +19841,13 @@ fn loadopsz(sigd: bool, sz: i32) str = { // reports, with TBANG / TENUM / TNAME-alias chains pre-folded by // tinfofornode (check.ww:1102-1153 TNAME, 1154-1161 TBANG, // 1196-1208 TENUM). -export fn localloadop(c: *cgen, tnode: *node) str = { +export fn localloadop(c: *cgen, tnode: *syntax.node) str = { if (tnode == nil) { return "MOVQ"; }; - let ti: *tinfo = tnode.type_: *tinfo; + let ti: *syntax.tinfo = tnode.type_: *syntax.tinfo; if (ti == nil) { return "MOVQ"; }; let sz: i32 = ti.size: i32; if (sz != 1) { if (sz != 2) { if (sz != 4) { return "MOVQ"; }; }; }; - let sigd: bool = typeissigned(ti); + let sigd: bool = syntax.typeissigned(ti); return loadopsz(sigd, sz); }; @@ -19858,13 +19858,13 @@ export fn localloadop(c: *cgen, tnode: *node) str = { // step). One peel choke-point: every tinfo-keyed index-element answer // (elemsizeofc / elemissignedc / elemisfloatc / elemisf32c) routes // through here. Mirrors cstage idx_eff (cmd/w6c/cgen.c:1163). -fn idxeffti(t0: *tinfo) *tinfo = { - let t: *tinfo = t0; +fn idxeffti(t0: *syntax.tinfo) *syntax.tinfo = { + let t: *syntax.tinfo = t0; t = tichase(t); - if (t != nil && t.kind == tykind.TY_PTR) { - let p: *tinfo = t.sub; + if (t != nil && t.kind == syntax.tykind.TY_PTR) { + let p: *syntax.tinfo = t.sub; p = tichase(p); - if (p != nil && p.kind == tykind.TY_ARRAY) { return p; }; + if (p != nil && p.kind == syntax.tykind.TY_ARRAY) { return p; }; }; return t; }; @@ -19878,14 +19878,14 @@ fn idxeffti(t0: *tinfo) *tinfo = { // N*8-byte aggregate copy from an 8B source: caller-frame smash). // nil for non-indexable kinds (str N_TNAME: callers want nil so // tnodestoreop falls to the u8 byte store). -fn idxelemtn(tn: *node) *node = { +fn idxelemtn(tn: *syntax.node) *syntax.node = { if (tn == nil) { return nil; }; - let k: nkind = tn.kind; - if (k != nkind.N_TARRAY && k != nkind.N_TSLICE - && k != nkind.N_TPTR) { return nil; }; - let elem: *node = tn.lhs; - if (k == nkind.N_TPTR && elem != nil - && elem.kind == nkind.N_TARRAY) { + let k: syntax.nkind = tn.kind; + if (k != syntax.nkind.N_TARRAY && k != syntax.nkind.N_TSLICE + && k != syntax.nkind.N_TPTR) { return nil; }; + let elem: *syntax.node = tn.lhs; + if (k == syntax.nkind.N_TPTR && elem != nil + && elem.kind == syntax.nkind.N_TARRAY) { return elem.lhs; }; return elem; @@ -19897,14 +19897,14 @@ fn idxelemtn(tn: *node) *node = { // For aliased element types (e.g. `[N]formattable`), callers that // need the resolved slot size should use elemsizeofc(c, t) which // follows aliases via slotsize. -fn elemsizeof(t: *node) i32 = { +fn elemsizeof(t: *syntax.node) i32 = { if (t == nil) { return 1; }; - let k: nkind = t.kind; - let elem: *node = nil; - if (k == nkind.N_TPTR) { elem = t.lhs; }; - if (k == nkind.N_TSLICE) { elem = t.lhs; }; - if (k == nkind.N_TARRAY) { elem = t.lhs; }; - if (k == nkind.N_TNAME) { + let k: syntax.nkind = t.kind; + let elem: *syntax.node = nil; + if (k == syntax.nkind.N_TPTR) { elem = t.lhs; }; + if (k == syntax.nkind.N_TSLICE) { elem = t.lhs; }; + if (k == syntax.nkind.N_TARRAY) { elem = t.lhs; }; + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; // str's element is u8 (F1: tystr.sub = tyu8), named directly // rather than read off str.sub because elemsizeof gets a raw @@ -19914,7 +19914,7 @@ fn elemsizeof(t: *node) i32 = { // str.sub-equivalent; the structural collapse onto str.sub is // blocked on tinfo-stamping here, not intent (#24). cstage twin // reads eff->sub->size (cmd/w6c/cgen.c N_INDEX). - if (streq(nm, "str")) { return primtypesize("u8"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("u8"): i32; }; // Indexing a primitive name (rare): element size = the prim. // primsize-ok (#101/#109): elemsizeof is the STRUCTURAL (non- // chasing) sizer by design — its alias-resolving twin elemsizeofc @@ -19933,17 +19933,17 @@ fn elemsizeof(t: *node) i32 = { // double-index (cgindex) needs the sub-array stride — call // elemsizeofc, the 2D-correct entry, which recovers slotsize([M]T) // when elemsizeof returns 8. Never call elemsizeof for a 2D stride. - if (elem.kind == nkind.N_TARRAY) { + if (elem.kind == syntax.nkind.N_TARRAY) { if (elem.lhs != nil) { elem = elem.lhs; }; }; // `*[]T`: stride is the slice header (24B). Hare-faithful — a // pointer-to-slice is a 1D array of slices, not of T. Mirrors the // cstage check.c default `*U → U` path for U=[]T (slice element). - if (elem.kind == nkind.N_TSLICE) { return tyslicesize(): i32; }; - if (elem.kind == nkind.N_TNAME) { + if (elem.kind == syntax.nkind.N_TSLICE) { return tyslicesize(): i32; }; + if (elem.kind == syntax.nkind.N_TNAME) { let nm: str = elem.str; // str element is 16B (ptr+len). primsize returns 0 for it. - if (streq(nm, "str")) { return primtypesize("str"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("str"): i32; }; // primsize-ok (#101/#109): structural sizer — the chase lives // in elemsizeofc (:1579), not here. See the :1475 leg. let ps: i32 = primsize(nm); @@ -19956,7 +19956,7 @@ fn elemsizeof(t: *node) i32 = { // (struct / tagged / `type foo = bar;`) via slotsize. Used where // cgindex / cgassign need a correct stride for `[N]Alias` arrays // whose Alias resolves to a tagged union (e.g. `[N]formattable`). -fn elemsizeofc(c: *cgen, t: *node) i32 = { +fn elemsizeofc(c: *cgen, t: *syntax.node) i32 = { if (t == nil) { return 1; }; // #270-2: a NESTED-array element ([N][M]T) — the OUTER index stride // is the WHOLE sub-array [M]T, not the scalar T that elemsizeof @@ -19973,12 +19973,12 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // every index by N*size(T) — the siphash round() corruption. The // `*[N][M]T` outer stride still resolves below via idxeffti // (pointee array's .sub = [M]T, its natural size). - let nk: nkind = t.kind; - let nest: *node = nil; - if (nk == nkind.N_TSLICE) { nest = t.lhs; }; - if (nk == nkind.N_TARRAY) { nest = t.lhs; }; - if (nest != nil && nest.kind == nkind.N_TARRAY) { - let eti: *tinfo = nest.type_: *tinfo; + let nk: syntax.nkind = t.kind; + let nest: *syntax.node = nil; + if (nk == syntax.nkind.N_TSLICE) { nest = t.lhs; }; + if (nk == syntax.nkind.N_TARRAY) { nest = t.lhs; }; + if (nest != nil && nest.kind == syntax.nkind.N_TARRAY) { + let eti: *syntax.tinfo = nest.type_: *syntax.tinfo; eti = tichase(eti); if (eti != nil) { return eti.size: i32; }; }; @@ -19991,12 +19991,12 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // element chased like the #8 leg below. Non-indexable names // (struct/prim/str aliases) fall through to the old paths — // byte-id preserved there. - if (nk == nkind.N_TNAME) { - let eff: *tinfo = idxeffti(t.type_: *tinfo); + if (nk == syntax.nkind.N_TNAME) { + let eff: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (eff != nil) { - if (eff.kind == tykind.TY_ARRAY - || eff.kind == tykind.TY_SLICE) { - let aes: *tinfo = tichase(eff.sub); + if (eff.kind == syntax.tykind.TY_ARRAY + || eff.kind == syntax.tykind.TY_SLICE) { + let aes: *syntax.tinfo = tichase(eff.sub); if (aes != nil) { return aes.size: i32; }; }; }; @@ -20017,15 +20017,15 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // idxeffti folds that peel together with the `*[N]T` TY_PTR→ // TY_ARRAY drill (#61) so .sub is the array's element, never the // whole pointee array. - let ti: *tinfo = idxeffti(t.type_: *tinfo); + let ti: *syntax.tinfo = idxeffti(t.type_: *syntax.tinfo); if (ti != nil) { - let esub: *tinfo = ti.sub; + let esub: *syntax.tinfo = ti.sub; esub = tichase(esub); if (esub != nil) { return esub.size: i32; }; }; - let elem: *node = idxelemtn(t); + let elem: *syntax.node = idxelemtn(t); if (elem == nil) { return direct; }; - if (elem.kind == nkind.N_TNAME) { + if (elem.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, elem.str); if (ps > 0) { return ps; }; }; @@ -20042,9 +20042,9 @@ fn elemsizeofc(c: *cgen, t: *node) i32 = { // // Conservative: if we can't tell, return false (signed). The cost of // being wrong here is byte-different asm vs C, not bad runtime. -fn nodeisunsigned(c: *cgen, n: *node) bool = { +fn nodeisunsigned(c: *cgen, n: *syntax.node) bool = { if (n == nil) { return false; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; // #25 (F7-c5): collapse the whole N_IDENT arm onto the checker-stamped // n.type_, dropping the localfindnode special-case. The prior arm read // the local's declared tnode and returned `false` (signed) for a @@ -20056,21 +20056,21 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // the corpus HAS module-global unsigned counters on the divide/shift // path, so the self-compile .s MOVES — every move is toward cstage // (IDIV→DIV where the global's stamp is unsigned) and runtime-correct. - if (k == nkind.N_IDENT) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_IDENT) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; - if (k == nkind.N_DOT) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_DOT) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { if (n.rhs == nil) { return false; }; - return typeisunsigned(n.rhs.type_: *tinfo); + return syntax.typeisunsigned(n.rhs.type_: *syntax.tinfo); }; - if (k == nkind.N_BIN) { + if (k == syntax.nkind.N_BIN) { if (nodeisunsigned(c, n.lhs)) { return true; }; return nodeisunsigned(c, n.rhs); }; - if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); }; + if (k == syntax.nkind.N_UN) { return nodeisunsigned(c, n.lhs); }; // nkind.N_INDEX: `p[i]` is unsigned iff its element type is // unsigned. Read the checker-stamped result type directly, // mirroring the N_DOT arm above and cstage cgen.c:2541 @@ -20081,8 +20081,8 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // `d.digits[nd] >= 5u8` pick signed JGE instead of unsigned JAE. // Embodies the #121 principle (collapse structural onto stamp). // #134. - if (k == nkind.N_INDEX) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_INDEX) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; // nkind.N_CALL: a call returning an unsigned type (e.g. `fn f() u64`) // is unsigned. Read the checker-stamped result type directly — the @@ -20091,8 +20091,8 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // `n->type = u->ret`; without this arm the wwstage fell through to // `return false`, picking signed IDIV/SAR over unsigned DIV/SHR on a // call-result div/mod/shift operand. #168. - if (k == nkind.N_CALL) { - return typeisunsigned(n.type_: *tinfo); + if (k == syntax.nkind.N_CALL) { + return syntax.typeisunsigned(n.type_: *syntax.tinfo); }; return false; }; @@ -20101,27 +20101,27 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { // statically determinable. Mirrors nodeisunsigned's structural walk. // Used by cgun TK_TILDE to clamp narrow unsigned ~ results to type // width (NOTQ inverts the full 64-bit register). -fn nodeprimwidth(c: *cgen, n: *node) i32 = { +fn nodeprimwidth(c: *cgen, n: *syntax.node) i32 = { if (n == nil) { return 0; }; - let k: nkind = n.kind; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; + if (tn.kind == syntax.nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; }; }; return 0; }; - if (k == nkind.N_CAST) { - let tn: *node = n.rhs; + if (k == syntax.nkind.N_CAST) { + let tn: *syntax.node = n.rhs; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; + if (tn.kind == syntax.nkind.N_TNAME) { return aliasprimsize(c, tn.str); }; }; return 0; }; - if (k == nkind.N_UN) { return nodeprimwidth(c, n.lhs); }; + if (k == syntax.nkind.N_UN) { return nodeprimwidth(c, n.lhs); }; return 0; }; @@ -20178,7 +20178,7 @@ fn structabisize(si: *structinfo) i32 = { let end: i32 = fi.foff + fi.fsz; if (end > n) { n = end; }; if (fi.tnode != nil) { - let ti: *tinfo = fi.tnode.type_: *tinfo; + let ti: *syntax.tinfo = fi.tnode.type_: *syntax.tinfo; ti = tichase(ti); if (ti != nil) { let aln: i32 = ti.align: i32; @@ -20211,7 +20211,7 @@ fn structabisize(si: *structinfo) i32 = { // cgdot / cgassign at every "field-walk on a struct-typed local" // site so a transitively-aliased struct name resolves to its // fieldinfo list regardless of chain depth. -export fn structlookupchain(c: *cgen, tn: *node) *structinfo = { +export fn structlookupchain(c: *cgen, tn: *syntax.node) *structinfo = { if (tn == nil) { return nil; }; // #92: a struct LITERAL's type ref parses as N_IDENT (expression // position, lib/ww/parse/expr.ww) where type specs parse N_TNAME @@ -20219,17 +20219,17 @@ export fn structlookupchain(c: *cgen, tn: *node) *structinfo = { // iterations past the first walk aliaslookup results, which are // N_TNAME by the loop's own reassignment gate. Consumer census // (commit body): no existing caller can pass N_IDENT. - if (tn.kind != nkind.N_TNAME && tn.kind != nkind.N_IDENT) { return nil; }; + if (tn.kind != syntax.nkind.N_TNAME && tn.kind != syntax.nkind.N_IDENT) { return nil; }; let si: *structinfo = structlookup(c, tn.str); if (si != nil) { return si; }; - let cur: *node = tn; + let cur: *syntax.node = tn; for (cur != nil - && (cur.kind == nkind.N_TNAME || cur.kind == nkind.N_IDENT) + && (cur.kind == syntax.nkind.N_TNAME || cur.kind == syntax.nkind.N_IDENT) && si == nil) { - let aliased: *node = aliaslookup(c, cur.str); + let aliased: *syntax.node = aliaslookup(c, cur.str); if (aliased == nil) { cur = nil; } else { - if (aliased.kind == nkind.N_TNAME) { + if (aliased.kind == syntax.nkind.N_TNAME) { si = structlookup(c, aliased.str); cur = aliased; } else { cur = nil; }; @@ -20238,10 +20238,10 @@ export fn structlookupchain(c: *cgen, tn: *node) *structinfo = { return si; }; -export fn sretretsize(c: *cgen, t: *node) i32 = { +export fn sretretsize(c: *cgen, t: *syntax.node) i32 = { if (t == nil) { return 0; }; - let r: *node = t; - if (r.kind == nkind.N_TBANG) { + let r: *syntax.node = t; + if (r.kind == syntax.nkind.N_TBANG) { r = r.lhs; if (r == nil) { return 0; }; }; @@ -20257,7 +20257,7 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { if (tsz38 <= TUPLE_GPCAP * 8) { return 0; }; return tsz38; }; - if (r.kind == nkind.N_TTUPLE) { + if (r.kind == syntax.nkind.N_TTUPLE) { // #10: over-cap tuple → sret. Walk the element TYPE nodes // (pt.lhs) over the SAME caps the SEND/receive use; a float = // 1 SSE eightbyte, a slice/str its 3-word header, a scalar 1 @@ -20268,9 +20268,9 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { let ssecap: i32 = TUPLE_SSECAP; let gptotal: i32 = 0; let ssecount: i32 = 0; - let pt: *node = r.list; + let pt: *syntax.node = r.list; for (pt != nil) { - let et: *node = pt.lhs; + let et: *syntax.node = pt.lhs; if (isfloattype(c, et)) { ssecount = ssecount + 1; } else { @@ -20279,7 +20279,7 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { pt = pt.next; }; if (gptotal > TUPLE_GPCAP || ssecount > ssecap) { - let rti: *tinfo = r.type_: *tinfo; + let rti: *syntax.tinfo = r.type_: *syntax.tinfo; if (rti != nil) { return rti.size: i32; }; }; return 0; @@ -20288,24 +20288,24 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { // (sub.size*len, the type table) gates ≤24 reg / >24 sret, mirroring // cstage cg_sret_retsize TY_ARRAY arm. Pure-int element arrays only; // no float-array-return consumer (structfloatclass stays struct-only). - if (r.kind == nkind.N_TARRAY) { - let ati: *tinfo = r.type_: *tinfo; + if (r.kind == syntax.nkind.N_TARRAY) { + let ati: *syntax.tinfo = r.type_: *syntax.tinfo; ati = tichase(ati); if (ati == nil) { return 0; }; let asz: i32 = ati.size: i32; if (asz <= 24) { return 0; }; return asz; }; - if (r.kind != nkind.N_TNAME) { return 0; }; + if (r.kind != syntax.nkind.N_TNAME) { return 0; }; // Primitives / aliased-to-primitives are never sret. if (aliasprimsize(c, r.str) > 0) { return 0; }; - if (streq(r.str, "str")) { return 0; }; + if (syntax.streq(r.str, "str")) { return 0; }; // #129: same-module alias wins over any-module struct hit. Without // this, `type stream = *vtable` (io) loses to memio.stream (56B // struct) via structlookup's any-module fallback → spurious sret. // Mirrors cstage cg_sret_retsize, which sees TY_PTR, not a name. if (c != nil) { - let al: *node = aliassamemod(c, r.str); + let al: *syntax.node = aliassamemod(c, r.str); if (al != nil) { return sretretsize(c, al); }; @@ -20313,7 +20313,7 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { let si: *structinfo = structlookup(c, r.str); if (si == nil) { if (c != nil) { - let aliased: *node = aliaslookup(c, r.str); + let aliased: *syntax.node = aliaslookup(c, r.str); if (aliased != nil) { return sretretsize(c, aliased); }; @@ -20329,29 +20329,29 @@ export fn sretretsize(c: *cgen, t: *node) i32 = { // > 24B, return its natural size; else 0. Wraps sretretsize over the // callee's resolved return type, used by cglet / cgassign receive // sites and cgcall to detect sret at the receive / emit boundaries. -export fn callsretsize(c: *cgen, n: *node) i32 = { +export fn callsretsize(c: *cgen, n: *syntax.node) i32 = { if (n == nil) { return 0; }; - if (n.kind != nkind.N_CALL) { return 0; }; - let callee: *node = n.lhs; + if (n.kind != syntax.nkind.N_CALL) { return 0; }; + let callee: *syntax.node = n.lhs; if (callee == nil) { return 0; }; let cn: str; cn.ptr = nil; cn.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { cn = callee.str; cmod = c.curmod; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { cn = callee.str; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cn.len == 0) { return 0; }; - let rtyp: *node = fnretlookupmod(c, cn, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cn, cmod); // #129: sretretsize must see the CALLEE's module context so // aliassamemod resolves aliases from the callee's module (not the // caller's). Mirrors cstage operating on resolved Type* objects @@ -20372,15 +20372,15 @@ fn structlookup(c: *cgen, name: str) *structinfo = { // wrong totsize / field offsets. let s: *structinfo = c.structs; for (s != nil) { - if (streq(s.sname, name)) { - if (streq(s.smod, c.curmod)) { return s; }; + if (syntax.streq(s.sname, name)) { + if (syntax.streq(s.smod, c.curmod)) { return s; }; }; s = s.sinext; }; s = c.structs; for (s != nil) { let sn: str = s.sname; - if (streq(sn, name)) { return s; }; + if (syntax.streq(sn, name)) { return s; }; s = s.sinext; }; // Module-qualified form embedded in name (`pkg.S`): scope the @@ -20401,8 +20401,8 @@ fn structlookup(c: *cgen, name: str) *structinfo = { let pkgmod: str = usehint(c, pkg); let b: *structinfo = c.structs; for (b != nil) { - if (streq(b.sname, leaf)) { - if (streq(b.smod, pkgmod)) { + if (syntax.streq(b.sname, leaf)) { + if (syntax.streq(b.smod, pkgmod)) { return b; }; }; @@ -20424,8 +20424,8 @@ fn structlookup(c: *cgen, name: str) *structinfo = { fn structsamemod(c: *cgen, name: str) *structinfo = { let s: *structinfo = c.structs; for (s != nil) { - if (streq(s.sname, name)) { - if (streq(s.smod, c.curmod)) { return s; }; + if (syntax.streq(s.sname, name)) { + if (syntax.streq(s.smod, c.curmod)) { return s; }; }; s = s.sinext; }; @@ -20455,23 +20455,23 @@ fn fldnumidx(s: str) i32 = { // IS the SSoT table aliasprimsize wraps; there is nothing below it to // chase. fn primsize(name: str) i32 = { - if (streq(name, "u8")) { return 1; }; - if (streq(name, "i8")) { return 1; }; - if (streq(name, "bool")) { return 1; }; - if (streq(name, "u16")) { return 2; }; - if (streq(name, "i16")) { return 2; }; - if (streq(name, "u32")) { return 4; }; - if (streq(name, "i32")) { return 4; }; - if (streq(name, "f32")) { return 4; }; - if (streq(name, "u64")) { return 8; }; - if (streq(name, "i64")) { return 8; }; - if (streq(name, "uint")) { return 8; }; - if (streq(name, "int")) { return 8; }; - if (streq(name, "uintptr")) { return 8; }; - if (streq(name, "size")) { return 8; }; - if (streq(name, "f64")) { return 8; }; - if (streq(name, "rune")) { return 4; }; - if (streq(name, "void")) { return 0; }; + if (syntax.streq(name, "u8")) { return 1; }; + if (syntax.streq(name, "i8")) { return 1; }; + if (syntax.streq(name, "bool")) { return 1; }; + if (syntax.streq(name, "u16")) { return 2; }; + if (syntax.streq(name, "i16")) { return 2; }; + if (syntax.streq(name, "u32")) { return 4; }; + if (syntax.streq(name, "i32")) { return 4; }; + if (syntax.streq(name, "f32")) { return 4; }; + if (syntax.streq(name, "u64")) { return 8; }; + if (syntax.streq(name, "i64")) { return 8; }; + if (syntax.streq(name, "uint")) { return 8; }; + if (syntax.streq(name, "int")) { return 8; }; + if (syntax.streq(name, "uintptr")) { return 8; }; + if (syntax.streq(name, "size")) { return 8; }; + if (syntax.streq(name, "f64")) { return 8; }; + if (syntax.streq(name, "rune")) { return 4; }; + if (syntax.streq(name, "void")) { return 0; }; return 0; }; @@ -20492,9 +20492,9 @@ fn primsize(name: str) i32 = { fn aliasprimsize(c: *cgen, nm: str) i32 = { let ps: i32 = primsize(nm); if (ps > 0) { return ps; }; - let cur: *node = aliaslookup(c, nm); + let cur: *syntax.node = aliaslookup(c, nm); for (cur != nil) { - if (cur.kind != nkind.N_TNAME) { return 0; }; + if (cur.kind != syntax.nkind.N_TNAME) { return 0; }; let p: i32 = primsize(cur.str); if (p > 0) { return p; }; cur = aliaslookup(c, cur.str); @@ -20509,16 +20509,16 @@ fn aliasprimsize(c: *cgen, nm: str) i32 = { // enum, etc.). Mirrors cstage's `type_isint(t) ? t->size : 0` / // `type_isunsigned` recursion through TY_NAMED and TY_ENUM. Used by // cgcast's identity-width identity-sign clamp-skip predicate (#33). -export fn typenodeprimresolved(c: *cgen, t: *node, +export fn typenodeprimresolved(c: *cgen, t: *syntax.node, sz_out: *i32, unsigned_out: *bool) void = { *sz_out = 0; *unsigned_out = false; - let cur: *node = t; + let cur: *syntax.node = t; for (cur != nil) { - let k: nkind = cur.kind; - if (k == nkind.N_TBANG) { cur = cur.lhs; } - else { if (k == nkind.N_TENUM) { cur = cur.lhs; } - else { if (k == nkind.N_TNAME) { + let k: syntax.nkind = cur.kind; + if (k == syntax.nkind.N_TBANG) { cur = cur.lhs; } + else { if (k == syntax.nkind.N_TENUM) { cur = cur.lhs; } + else { if (k == syntax.nkind.N_TNAME) { let nm: str = cur.str; // bool is excluded from the int-prim contract: cstage's // `type_isint(TY_BOOL)` is false, so its identity check @@ -20529,17 +20529,17 @@ export fn typenodeprimresolved(c: *cgen, t: *node, // primsize("bool")=1, so the exclusion stays local. The // dedicated `is_bool` path in cgcast owns bool→bool's // ANDQ $255 on both stages. - if (streq(nm, "bool")) { return; }; + if (syntax.streq(nm, "bool")) { return; }; // primsize-ok (#101/#109): this fn IS a prim-resolver // chaser (#33) — primsize is the leaf-primitive probe; // aliaslookup below advances the walk on a miss. let ps: i32 = primsize(nm); if (ps > 0) { *sz_out = ps; - *unsigned_out = typeisunsigned(cur.type_: *tinfo); + *unsigned_out = syntax.typeisunsigned(cur.type_: *syntax.tinfo); return; }; - let al: *node = aliaslookup(c, nm); + let al: *syntax.node = aliaslookup(c, nm); if (al == nil) { return; }; cur = al; } @@ -20555,13 +20555,13 @@ export fn typenodeprimresolved(c: *cgen, t: *node, // caller treats sz=0 as "not identity", which conservatively keeps // the clamp. Mirror of cstage's `n->lhs->type` lookup with the same // TY_NAMED / TY_ENUM recursion through type_isint / type_isunsigned. -export fn exprprimresolved(c: *cgen, n: *node, +export fn exprprimresolved(c: *cgen, n: *syntax.node, sz_out: *i32, unsigned_out: *bool) void = { *sz_out = 0; *unsigned_out = false; if (n == nil) { return; }; - let k: nkind = n.kind; - if (k == nkind.N_INTLIT) { + let k: syntax.nkind = n.kind; + if (k == syntax.nkind.N_INTLIT) { // Typed-int literal: `7u32` has tsuffix = "u32". Mirrors // cstage's `cexpr` which assigns `lookup_builtin(tsuffix)` // as the node's type — without this, wwstage misses the @@ -20576,12 +20576,12 @@ export fn exprprimresolved(c: *cgen, n: *node, let ps: i32 = primsize(s); if (ps > 0) { *sz_out = ps; - *unsigned_out = typeisunsigned(n.type_: *tinfo); + *unsigned_out = syntax.typeisunsigned(n.type_: *syntax.tinfo); }; }; return; }; - if (k == nkind.N_IDENT) { + if (k == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { typenodeprimresolved(c, lc.tnode, @@ -20589,15 +20589,15 @@ export fn exprprimresolved(c: *cgen, n: *node, }; return; }; - if (k == nkind.N_CAST) { + if (k == syntax.nkind.N_CAST) { typenodeprimresolved(c, n.rhs, sz_out, unsigned_out); return; }; - if (k == nkind.N_UN) { + if (k == syntax.nkind.N_UN) { exprprimresolved(c, n.lhs, sz_out, unsigned_out); return; }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // #59: read the checker-stamped tinfo instead of re-deriving the // field type via dotfieldtnode's structinfo walk. Mirrors cstage // castsrcprim N_DOT (cmd/w6c/cgen.c:323-344): the base must @@ -20618,16 +20618,16 @@ export fn exprprimresolved(c: *cgen, n: *node, // there, sound through type_isint's NAMED recursion + the // NAMED tinfo carrying its underlying's size (probe // b1c_fld2lvl byte-id). - let bu: *tinfo = nil; - if (n.lhs != nil) { bu = n.lhs.type_: *tinfo; }; + let bu: *syntax.tinfo = nil; + if (n.lhs != nil) { bu = n.lhs.type_: *syntax.tinfo; }; bu = tichase(bu); - if (bu != nil && bu.kind == tykind.TY_PTR) { bu = tichase(bu.sub); }; - if (bu != nil && bu.kind == tykind.TY_STRUCT) { - let u: *tinfo = n.type_: *tinfo; + if (bu != nil && bu.kind == syntax.tykind.TY_PTR) { bu = tichase(bu.sub); }; + if (bu != nil && bu.kind == syntax.tykind.TY_STRUCT) { + let u: *syntax.tinfo = n.type_: *syntax.tinfo; u = tichase(u); - if (typeisint(u)) { + if (syntax.typeisint(u)) { *sz_out = u.size: i32; - *unsigned_out = typeisunsigned(u); + *unsigned_out = syntax.typeisunsigned(u); }; }; return; @@ -20642,7 +20642,7 @@ export fn exprprimresolved(c: *cgen, n: *node, // accept exact match plus suffix-after-`.` on either side. Mirrors // the C cgen's type_eq, which goes through resolved Type pointers. fn variantnamematch(vname: str, pname: str) bool = { - if (streq(vname, pname)) { return true; }; + if (syntax.streq(vname, pname)) { return true; }; // `pname` is qualified, `vname` is bare: drop module prefix. let i: i32 = 0; for (i < pname.len) { @@ -20650,7 +20650,7 @@ fn variantnamematch(vname: str, pname: str) bool = { let tail: str; tail.ptr = pname.ptr + i + 1; tail.len = pname.len - i - 1; - if (streq(tail, vname)) { return true; }; + if (syntax.streq(tail, vname)) { return true; }; }; i += 1; }; @@ -20661,7 +20661,7 @@ fn variantnamematch(vname: str, pname: str) bool = { let tail: str; tail.ptr = vname.ptr + j + 1; tail.len = vname.len - j - 1; - if (streq(tail, pname)) { return true; }; + if (syntax.streq(tail, pname)) { return true; }; }; j += 1; }; @@ -20675,42 +20675,42 @@ fn variantnamematch(vname: str, pname: str) bool = { // the SB-symbol fallback (linker reports `undefined reference to // `). We don't infer for plain `let x = f()` yet — // non-tagged returns don't carry their type back the same way. -fn inferletcalltype(c: *cgen, rhs: *node) *node = { +fn inferletcalltype(c: *cgen, rhs: *syntax.node) *syntax.node = { if (rhs == nil) { return nil; }; // `?` (N_TRYPROP) and `!` (N_TRYUNW) both unwrap a tagged // return to its success variant; the rhs we want the type of // is the inner call expression. let unwrap: bool = false; - let call: *node = rhs; - if (rhs.kind == nkind.N_TRYPROP) { call = rhs.lhs; unwrap = true; }; - if (rhs.kind == nkind.N_TRYUNW) { call = rhs.lhs; unwrap = true; }; + let call: *syntax.node = rhs; + if (rhs.kind == syntax.nkind.N_TRYPROP) { call = rhs.lhs; unwrap = true; }; + if (rhs.kind == syntax.nkind.N_TRYUNW) { call = rhs.lhs; unwrap = true; }; if (call == nil) { return nil; }; - if (call.kind != nkind.N_CALL) { return nil; }; - let callee: *node = call.lhs; + if (call.kind != syntax.nkind.N_CALL) { return nil; }; + let callee: *syntax.node = call.lhs; if (callee == nil) { return nil; }; let cname: str; cname.ptr = nil; cname.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { cname = callee.str; cmod = c.curmod; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { cname = callee.str; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cname.len == 0) { return nil; }; - let rtyp: *node = fnretlookupmod(c, cname, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cname, cmod); if (rtyp == nil) { return nil; }; if (unwrap) { // Strip error variants — success type is the first // variant of the tagged return. - if (rtyp.kind != nkind.N_TTAGGED) { return nil; }; + if (rtyp.kind != syntax.nkind.N_TTAGGED) { return nil; }; return rtyp.list; }; // Plain call: declared return type is the local's type. @@ -20728,7 +20728,7 @@ fn inferletcalltype(c: *cgen, rhs: *node) *node = { // not the default 8B. Without this, the AX:DX:CX spill in cglet's // tagged-init branch writes past the local and tramples the next // slot. -export fn letslotsize(c: *cgen, n: *node) i32 = { +export fn letslotsize(c: *cgen, n: *syntax.node) i32 = { // `[_]T = arrlit;` inferred-length arrays no longer need a slot-size // intercept here: the checker (inferarraylen, check.ww) stamps the // real element count onto the array type's length child before cgen @@ -20736,7 +20736,7 @@ export fn letslotsize(c: *cgen, n: *node) i32 = { // Annotation-less init: defer to the call's return type if we can // infer it. Tagged-union returns need 24B; everything else matches // slotsize on the inferred type. - let tn: *node = n.lhs; + let tn: *syntax.node = n.lhs; if (tn == nil) { tn = inferletcalltype(c, n.rhs); }; if (tn == nil) { return 8; }; let s: i32 = slotsize(c, tn); @@ -20748,9 +20748,9 @@ export fn letslotsize(c: *cgen, n: *node) i32 = { // instead, else its zero width collides with the next local. A // genuine empty struct or [0]T array (also slotsize 0) keeps its 0. if (s == 0) { - let ti: *tinfo = tn.type_: *tinfo; + let ti: *syntax.tinfo = tn.type_: *syntax.tinfo; if (ti != nil) { ti = tichase(ti); }; - if (ti != nil && ti.kind == tykind.TY_VOID) { return 8; }; + if (ti != nil && ti.kind == syntax.tykind.TY_VOID) { return 8; }; }; return s; }; @@ -20774,9 +20774,9 @@ export fn letslotsize(c: *cgen, n: *node) i32 = { // // `c: *cgen` retained unused for callsite stability (localloadop // precedent, 68219a1). -fn slotsize(c: *cgen, typn: *node) i32 = { +fn slotsize(c: *cgen, typn: *syntax.node) i32 = { if (typn == nil) { return 8; }; - let ti: *tinfo = typn.type_: *tinfo; + let ti: *syntax.tinfo = typn.type_: *syntax.tinfo; if (ti == nil) { return 8; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel @@ -20784,11 +20784,11 @@ fn slotsize(c: *cgen, typn: *node) i32 = { // NAMED to the alias-invariant underlying this read consumes. ti = tichase(ti); if (ti == nil) { return 8; }; - let kk: tykind = ti.kind; - if (kk == tykind.TY_VOID) { return 0; }; - if (kk == tykind.TY_PTR || kk == tykind.TY_SLICE || - kk == tykind.TY_CHAN || kk == tykind.TY_FN || - kk == tykind.TY_STR || kk == tykind.TY_TAGGED) { + let kk: syntax.tykind = ti.kind; + if (kk == syntax.tykind.TY_VOID) { return 0; }; + if (kk == syntax.tykind.TY_PTR || kk == syntax.tykind.TY_SLICE || + kk == syntax.tykind.TY_CHAN || kk == syntax.tykind.TY_FN || + kk == syntax.tykind.TY_STR || kk == syntax.tykind.TY_TAGGED) { return ti.size: i32; }; // #75: a struct LOCAL's stack slot is the struct's NATURAL size @@ -20800,10 +20800,10 @@ fn slotsize(c: *cgen, typn: *node) i32 = { // dual-SSoT leak as #44 (field-offset) / #55, one notion over. The // TUPLE arm (8B/elem slot, user ruling #60) and ARRAY arm (element // stride, #48 [N]Alias 24B) keep ti.slotsize — deliberate divergences. - if (kk == tykind.TY_STRUCT) { + if (kk == syntax.tykind.TY_STRUCT) { return ((ti.size + 7u64) & ~7u64): i32; }; - if (kk == tykind.TY_TUPLE || kk == tykind.TY_ARRAY) { + if (kk == syntax.tykind.TY_TUPLE || kk == syntax.tykind.TY_ARRAY) { return ti.slotsize: i32; }; return 8; @@ -20823,9 +20823,9 @@ fn slotsize(c: *cgen, typn: *node) i32 = { // // `c: *cgen` retained unused for callsite stability (slotsize / // localloadop precedent, a828c03 / 68219a1). -fn fieldsize(c: *cgen, tnode: *node) i32 = { +fn fieldsize(c: *cgen, tnode: *syntax.node) i32 = { if (tnode == nil) { return 8; }; - let ti: *tinfo = tnode.type_: *tinfo; + let ti: *syntax.tinfo = tnode.type_: *syntax.tinfo; if (ti == nil) { return 8; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel @@ -20833,14 +20833,14 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = { // NAMED to the alias-invariant underlying this read consumes. ti = tichase(ti); if (ti == nil) { return 8; }; - let k: tykind = ti.kind; - if (k == tykind.TY_STRUCT) { return ti.slotsize: i32; }; - if (k == tykind.TY_ARRAY) { return ti.slotsize: i32; }; - if (k == tykind.TY_TAGGED) { return ti.size: i32; }; - if (k == tykind.TY_SLICE) { return ti.size: i32; }; - if (k == tykind.TY_PTR || k == tykind.TY_FN || - k == tykind.TY_CHAN) { return 8; }; - if (k == tykind.TY_STR) { return ti.size: i32; }; + let k: syntax.tykind = ti.kind; + if (k == syntax.tykind.TY_STRUCT) { return ti.slotsize: i32; }; + if (k == syntax.tykind.TY_ARRAY) { return ti.slotsize: i32; }; + if (k == syntax.tykind.TY_TAGGED) { return ti.size: i32; }; + if (k == syntax.tykind.TY_SLICE) { return ti.size: i32; }; + if (k == syntax.tykind.TY_PTR || k == syntax.tykind.TY_FN || + k == syntax.tykind.TY_CHAN) { return 8; }; + if (k == syntax.tykind.TY_STR) { return ti.size: i32; }; // Primitives + TY_ENUM keep natural width inside structs // (cstage parity: cgen.c reads f->type->size directly). TY_TUPLE // flows here too — pre-collapse fallback was 8, the populated @@ -20864,7 +20864,7 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = { // non-TFIELD identically), so they advance in exact step. si.totsize keeps // the slot-padded total (stack-slot allocator's number) from ti.slotsize, // already 8-rounded at check.ww:2259-2261. -fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { +fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *syntax.node) void = { let si: *structinfo = alloc(structinfo{ sname = name, smod = srcmod, @@ -20874,7 +20874,7 @@ fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { os.write(2, msg.ptr, msg.len: u64); os.exit(1); }; - let ti: *tinfo = tichase(tstruct.type_: *tinfo); + let ti: *syntax.tinfo = tichase(tstruct.type_: *syntax.tinfo); if (ti == nil) { let msg: str = "#44/#55: registerstruct: tichase yielded nil tinfo\n"; os.write(2, msg.ptr, msg.len: u64); @@ -20882,10 +20882,10 @@ fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { }; let head: *fieldinfo = nil; let tail: *fieldinfo = nil; - let f: *node = tstruct.list; - let tf: *tfield = ti.fields; + let f: *syntax.node = tstruct.list; + let tf: *syntax.tfield = ti.fields; for (f != nil) { - if (f.kind == nkind.N_TFIELD) { + if (f.kind == syntax.nkind.N_TFIELD) { if (tf == nil) { let msg: str = "#44/#55: registerstruct: AST/tfield walk desync (more TFIELDs than tinfo.fields)\n"; os.write(2, msg.ptr, msg.len: u64); @@ -20909,13 +20909,13 @@ fn registerstruct(c: *cgen, name: str, srcmod: str, tstruct: *node) void = { c.structs = si; }; -fn collectstructs(c: *cgen, file: *node) void = { +fn collectstructs(c: *cgen, file: *syntax.node) void = { c.structs = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_TYPEDECL) { - let body: *node = d.lhs; + if (d.kind == syntax.nkind.N_TYPEDECL) { + let body: *syntax.node = d.lhs; // #9: an error-struct (`type X = !struct{...}`) carries an // N_TBANG-wrapped body; peel it so X registers like any // struct. cstage is tinfo-based and needs no table, but @@ -20927,11 +20927,11 @@ fn collectstructs(c: *cgen, file: *node) void = { // cutover, which deletes this name-keyed dispatch outright; // until then the table must be complete (errors.opaque_ is // the first such type). #10 tracks retiring the table. - if (body != nil && body.kind == nkind.N_TBANG) { + if (body != nil && body.kind == syntax.nkind.N_TBANG) { body = body.lhs; }; if (body != nil) { - if (body.kind == nkind.N_TSTRUCT) { + if (body.kind == syntax.nkind.N_TSTRUCT) { registerstruct(c, d.str, d.nmod, body); }; }; @@ -20946,14 +20946,14 @@ fn collectstructs(c: *cgen, file: *node) void = { // Collapsed onto typeisstr per A.6.3b (#46); the prior AST walker is // reconstituted by typeisstr's TY_NAMED chase + tinfofornode's // TBANG-unwrap (check.ww:1145). -fn isstrtype(c: *cgen, t: *node) bool = { +fn isstrtype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisstr(t.type_: *tinfo); + return syntax.typeisstr(t.type_: *syntax.tinfo); }; -fn isslicetype(c: *cgen, t: *node) bool = { +fn isslicetype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisslice(t.type_: *tinfo); + return syntax.typeisslice(t.type_: *syntax.tinfo); }; // resolvetagged — return the underlying N_TTAGGED node for `t`, or nil @@ -20963,16 +20963,16 @@ fn isslicetype(c: *cgen, t: *node) bool = { // `(invalid | overflow)` node. Use at sites that read variant lists // or detect nullable folding off a scrutinee — cgmatch, cgtypetest, // cgtypeassert — so aliased `!(A|B)` shapes still dispatch. -export fn resolvetagged(c: *cgen, t: *node) *node = { - let r: *node = resolvetype(c, t); +export fn resolvetagged(c: *cgen, t: *syntax.node) *syntax.node = { + let r: *syntax.node = resolvetype(c, t); if (r == nil) { return nil; }; - if (r.kind == nkind.N_TBANG) { - let inner: *node = r.lhs; + if (r.kind == syntax.nkind.N_TBANG) { + let inner: *syntax.node = r.lhs; if (inner == nil) { return nil; }; r = resolvetype(c, inner); if (r == nil) { return nil; }; }; - if (r.kind == nkind.N_TTAGGED) { return r; }; + if (r.kind == syntax.nkind.N_TTAGGED) { return r; }; return nil; }; @@ -20981,41 +20981,41 @@ export fn resolvetagged(c: *cgen, t: *node) *node = { // @match_spill slot at first use (#15 first-use+fail-loud convergence). // IDENT scrutinees use a different lookup path (read off the local // directly, no spill) so this returns nil for them too. -fn matchscrutt(c: *cgen, scrut: *node) *node = { +fn matchscrutt(c: *cgen, scrut: *syntax.node) *syntax.node = { if (scrut == nil) { return nil; }; - let k: nkind = scrut.kind; - if (k == nkind.N_IDENT) { return nil; }; - if (k == nkind.N_CALL) { - let callee: *node = scrut.lhs; + let k: syntax.nkind = scrut.kind; + if (k == syntax.nkind.N_IDENT) { return nil; }; + if (k == syntax.nkind.N_CALL) { + let callee: *syntax.node = scrut.lhs; if (callee != nil) { let cnm: str; cnm.ptr = nil; cnm.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { cnm = callee.str; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_IDENT) { cnm = callee.str; }; + if (callee.kind == syntax.nkind.N_DOT) { cnm = callee.str; // Same-module-first disambiguation: a leaf collision // on `next` (utf8.next + caller-side next) otherwise // returns the last-declared (caller) rtype and the // 4-arm match collapses arms 2+ to tag 0. Task #31. if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cnm.len > 0) { - let rtyp: *node = fnretlookupmod(c, cnm, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cnm, cmod); if (rtyp != nil) { return resolvetagged(c, rtyp); }; }; }; return nil; }; - if (k == nkind.N_INDEX) { - let ibase: *node = scrut.lhs; + if (k == syntax.nkind.N_INDEX) { + let ibase: *syntax.node = scrut.lhs; if (ibase == nil) { return nil; }; - if (ibase.kind != nkind.N_IDENT) { + if (ibase.kind != syntax.nkind.N_IDENT) { // #48: non-ident index base (s.field[i], call()[i], // nested). Only idents carry a declared tnode to walk, // so resolve from the checker-stamped element tinfo @@ -21028,16 +21028,16 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { return nil; }; let bl: *local = localfindnode(c, ibase.str); - let btn: *node = nil; + let btn: *syntax.node = nil; if (bl != nil) { btn = bl.tnode; } else { btn = letvartnode(c, ibase.str); }; if (btn == nil) { return nil; }; // idxelemtn: `*[N]T` drills to the pointee array's element (#61). - let etn: *node = idxelemtn(btn); + let etn: *syntax.node = idxelemtn(btn); if (etn == nil) { return nil; }; return resolvetagged(c, etn); }; - if (k == nkind.N_DOT) { + if (k == syntax.nkind.N_DOT) { // #67: read the field's stamped tinfo off the N_DOT node // (post-#66 N_DOT carries the field type) instead of the // dotfieldtnode AST walk. cgmatch's gate reads scrutt.type_ @@ -21052,7 +21052,7 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { // non-ident N_INDEX/N_DOT arms (`match (*p)` spill size + variant // indices key off scrut.type_; pre-#46 nil here clamped the // variant to 0 and mis-sized @match_spill). - if (k == nkind.N_UN && scrut.op == tkind.TK_STAR) { + if (k == syntax.nkind.N_UN && scrut.op == syntax.tkind.TK_STAR) { if (!istaggedtype(c, scrut)) { return nil; }; return scrut; }; @@ -21065,7 +21065,7 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { // when the scrutinee type can't be resolved keeps the historical // alloc for non-tagged / unresolved cases. Called by cgmatch at first // use; #15 first-use+fail-loud pins this size per fn. -fn matchspillsz(c: *cgen, scrutt: *node) i32 = { +fn matchspillsz(c: *cgen, scrutt: *syntax.node) i32 = { if (scrutt == nil) { return 16; }; let sz: i32 = slotsize(c, scrutt); if (sz <= 0) { return 16; }; @@ -21081,13 +21081,13 @@ fn matchspillsz(c: *cgen, scrutt: *node) i32 = { // scalar catch-all, the second-half value registers (DX/CX) were // never spilled, and field reads from the under-allocated slot // trailed into the saved-BP word. -fn structparamsize(c: *cgen, t: *node) i32 = { +fn structparamsize(c: *cgen, t: *syntax.node) i32 = { if (c == nil) { return 0; }; - let r: *node = resolvetype(c, t); + let r: *syntax.node = resolvetype(c, t); if (r == nil) { return 0; }; - if (r.kind != nkind.N_TNAME) { return 0; }; + if (r.kind != syntax.nkind.N_TNAME) { return 0; }; let nm: str = r.str; - if (streq(nm, "str")) { return 0; }; + if (syntax.streq(nm, "str")) { return 0; }; if (aliasprimsize(c, nm) > 0) { return 0; }; let si: *structinfo = structlookup(c, nm); if (si == nil) { return 0; }; @@ -21101,12 +21101,12 @@ fn structparamsize(c: *cgen, t: *node) i32 = { // ≤16B-struct structparamsize carve-out doesn't cover: arrays of any // size and structs > 16B. Reads the stamped tinfo size (the type table, // byte-id with cstage Type.size). -fn aggargsizetn(t: *tinfo) i32 = { +fn aggargsizetn(t: *syntax.tinfo) i32 = { if (t == nil) { return 0; }; - let u: *tinfo = t; + let u: *syntax.tinfo = t; u = tichase(u); if (u == nil) { return 0; }; - if (u.kind == tykind.TY_STRUCT || u.kind == tykind.TY_ARRAY) { + if (u.kind == syntax.tykind.TY_STRUCT || u.kind == syntax.tykind.TY_ARRAY) { return u.size: i32; }; return 0; @@ -21119,12 +21119,12 @@ fn aggargsizetn(t: *tinfo) i32 = { // positive BP offsets. Mirror of cstage tagged_memarg_size; ABI shape // per ref/qbe/amd64/sysv.c:80-85 (inmem) / :411-426 (stack blit). The // ≤48B register convention is pinned in-tree (test/926 boundary rows). -fn taggedmemargsize(t: *tinfo) i32 = { +fn taggedmemargsize(t: *syntax.tinfo) i32 = { if (t == nil) { return 0; }; - let u: *tinfo = t; + let u: *syntax.tinfo = t; u = tichase(u); if (u == nil) { return 0; }; - if (u.kind != tykind.TY_TAGGED) { return 0; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return 0; }; if (u.nullable != 0) { return 0; }; // sizelint-ok: 6 SysV int arg regs (DI..R9) x 8B words — the // same register-capacity constant as cstage tagged_arg_size. @@ -21132,9 +21132,9 @@ fn taggedmemargsize(t: *tinfo) i32 = { return u.size: i32; }; -fn nodeisaggarg(n: *node) bool = { +fn nodeisaggarg(n: *syntax.node) bool = { if (n == nil) { return false; }; - return aggargsizetn(n.type_: *tinfo) > 0; + return aggargsizetn(n.type_: *syntax.tinfo) > 0; }; // aggargfloatstop — true iff the arg is a ≤16B struct with any float @@ -21142,16 +21142,16 @@ fn nodeisaggarg(n: *node) bool = { // the SSE eightbyte transport the GP aggregate push/drain can't model; // both stages loud-stop on it. Same predicate as the cstage Tfield // fld_isfloat walk (cmd/w6c/cgen.c #271 push arm). -fn aggargfloatstop(n: *node) bool = { +fn aggargfloatstop(n: *syntax.node) bool = { if (n == nil) { return false; }; - let st: *tinfo = n.type_: *tinfo; + let st: *syntax.tinfo = n.type_: *syntax.tinfo; st = tichase(st); if (st == nil) { return false; }; - if (st.kind != tykind.TY_STRUCT) { return false; }; + if (st.kind != syntax.tykind.TY_STRUCT) { return false; }; if (st.size: i32 > 16) { return false; }; - let f: *tfield = st.fields; + let f: *syntax.tfield = st.fields; for (f != nil) { - if (typeisfloat(f.type_)) { return true; }; + if (syntax.typeisfloat(f.type_)) { return true; }; f = f.tnext; }; return false; @@ -21170,13 +21170,13 @@ fn aggargfloatstop(n: *node) bool = { // eightbyte is pure-INT or a lone f64 AND at least one is f64. f32 / // sub-eightbyte packing deferred (#165b). Mirrors cstage // struct_float_class (cmd/w6c/cgen.c). -fn structfloatclass(c: *cgen, t: *node) i32 = { +fn structfloatclass(c: *cgen, t: *syntax.node) i32 = { if (c == nil) { return 0; }; - let r: *node = resolvetype(c, t); + let r: *syntax.node = resolvetype(c, t); if (r == nil) { return 0; }; - if (r.kind != nkind.N_TNAME) { return 0; }; + if (r.kind != syntax.nkind.N_TNAME) { return 0; }; let nm: str = r.str; - if (streq(nm, "str")) { return 0; }; + if (syntax.streq(nm, "str")) { return 0; }; if (aliasprimsize(c, nm) > 0) { return 0; }; let si: *structinfo = structlookup(c, nm); if (si == nil) { return 0; }; @@ -21211,10 +21211,10 @@ fn structfloatclass(c: *cgen, t: *node) i32 = { // and every tuple field; the fsz>8 guard below also lets a // <=8B one slip, so such a struct would wrongly SSE-route on // this stage but stay GP on cstage (a #165b leak). - let rf: *node = resolvetype(c, fi.tnode); + let rf: *syntax.node = resolvetype(c, fi.tnode); if (rf != nil) { - if (rf.kind == nkind.N_TARRAY) { return 0; }; - if (rf.kind == nkind.N_TTUPLE) { return 0; }; + if (rf.kind == syntax.nkind.N_TARRAY) { return 0; }; + if (rf.kind == syntax.nkind.N_TTUPLE) { return 0; }; }; if (fsz > 8) { return 0; }; if ((foff + fsz - 1) / 8 != e) { return 0; }; @@ -21239,49 +21239,49 @@ fn structfloatclass(c: *cgen, t: *node) i32 = { // resolve to TY_TAGGED — tinfofornode handles the N_TBANG unwrap // (check.ww:1145) so we don't re-walk it here. Cite cstage cgen.c // (`type_chase_named` + TY_TAGGED). Collapsed per A.6.3b (#46). -fn istaggedtype(c: *cgen, t: *node) bool = { +fn istaggedtype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeistagged(t.type_: *tinfo); + return syntax.typeistagged(t.type_: *syntax.tinfo); }; // tnodeisagg — struct/array/tuple kind off the checker-STAMPED tinfo // (the #49 funnel predicate; #209/#211 discipline — never tnode // names). Mirror of cstage's chase-then-kind test at the fill / // assign aggregate arms. -fn tnodeisagg(t: *node) bool = { +fn tnodeisagg(t: *syntax.node) bool = { if (t == nil) { return false; }; - let u: *tinfo = t.type_: *tinfo; + let u: *syntax.tinfo = t.type_: *syntax.tinfo; u = tichase(u); if (u == nil) { return false; }; - if (u.kind == tykind.TY_STRUCT) { return true; }; - if (u.kind == tykind.TY_ARRAY) { return true; }; - return u.kind == tykind.TY_TUPLE; + if (u.kind == syntax.tykind.TY_STRUCT) { return true; }; + if (u.kind == syntax.tykind.TY_ARRAY) { return true; }; + return u.kind == syntax.tykind.TY_TUPLE; }; // isfloattype — f32 / f64 / untyped_float (alias-aware). Cite cstage // cgen.c:117 `cg_isfloat`. Dispatches MOVSS/MOVSD-shaped paths across // cglet, cgident, cgassign, cgbin, cgcast, cgcall, cgreturn, fn- // prologue. Collapsed per A.6.3b (#46). -export fn isfloattype(c: *cgen, t: *node) bool = { +export fn isfloattype(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisfloat(t.type_: *tinfo); + return syntax.typeisfloat(t.type_: *syntax.tinfo); }; // isf32type — narrower: true only for f32 (after alias chase). Cite // cstage cgen.c:188 `type_isf32`. Picks MOVSS vs MOVSD and the SS- // variant arithmetic / cast opcodes. Collapsed per A.6.3b (#46). -export fn isf32type(c: *cgen, t: *node) bool = { +export fn isf32type(c: *cgen, t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisf32(t.type_: *tinfo); + return syntax.typeisf32(t.type_: *syntax.tinfo); }; // isnullabletype — `(*T | void)` one-word fold per Hare's // `(*T | null)` semantics. Cite cstage cgen.c:396 `type_isnullable`; // the .nullable flag lands on tinfo at check.ww:1309-1318 when the // two-variant shape matches. Collapsed per A.6.3b (#46). -export fn isnullabletype(t: *node) bool = { +export fn isnullabletype(t: *syntax.node) bool = { if (t == nil) { return false; }; - return typeisnullable(t.type_: *tinfo); + return syntax.typeisnullable(t.type_: *syntax.tinfo); }; // nullableptrtag — 0-based index of the *T variant in a nullable @@ -21289,9 +21289,9 @@ export fn isnullabletype(t: *node) bool = { // scan ti.params, strip TY_NAMED on each variant, return idx of first // TY_PTR. Phase 1 (26724fe) populated the chain in tinfofornode's // TTAGGED arm so this walk could retire the AST-keyed predecessor. -export fn nullableptrtag(t: *node) i32 = { +export fn nullableptrtag(t: *syntax.node) i32 = { if (t == nil) { return 0; }; - let ti: *tinfo = t.type_: *tinfo; + let ti: *syntax.tinfo = t.type_: *syntax.tinfo; if (ti == nil) { return 0; }; // #63 Phase-N step 1: peel TY_NAMED before this structural query. // #64 builds per-decl NAMED wrappers (tinfofornode), so the peel @@ -21299,19 +21299,19 @@ export fn nullableptrtag(t: *node) i32 = { // NAMED to the alias-invariant underlying this read consumes. ti = tichase(ti); if (ti == nil) { return 0; }; - if (ti.kind != tykind.TY_TAGGED) { return 0; }; - let p: *tparam = ti.params; + if (ti.kind != syntax.tykind.TY_TAGGED) { return 0; }; + let p: *syntax.tparam = ti.params; let i: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; + let vt: *syntax.tinfo = p.type_; if (vt != nil) { // peel-ok: single peel PROBE-CLEARED (batch-2 c3-B2, // 018ef66) — constructible variant params never carry // 2+-level NAMED at this scan; cs twin nullable_ptr_tag // (cmd/w6c/cgen.c:747) keeps the identical single peel. - if (vt.kind == tykind.TY_NAMED) { vt = vt.under; }; + if (vt.kind == syntax.tykind.TY_NAMED) { vt = vt.under; }; if (vt != nil) { - if (vt.kind == tykind.TY_PTR) { return i; }; + if (vt.kind == syntax.tykind.TY_PTR) { return i; }; }; }; p = p.tnext; @@ -21332,18 +21332,18 @@ export fn nullableptrtag(t: *node) i32 = { // Mirrors cstage cg_tag_for_variant(rt, ty_void) (cmd/w6c/cgen.c:900-911): // chase NAMED, scan params, match bare TY_VOID (not `!void`, carried by the // tparam iserror flag). -fn voidvariantindex(tagged: *node) i32 = { +fn voidvariantindex(tagged: *syntax.node) i32 = { if (tagged == nil) { return -1; }; - let ti: *tinfo = tagged.type_: *tinfo; + let ti: *syntax.tinfo = tagged.type_: *syntax.tinfo; if (ti == nil) { return -1; }; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; - let p: *tparam = ti.params; + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; - if (vt != nil && vt.kind == tykind.TY_VOID && !p.iserror) { + let vt: *syntax.tinfo = p.type_; + if (vt != nil && vt.kind == syntax.tykind.TY_VOID && !p.iserror) { return idx; }; p = p.tnext; @@ -21356,9 +21356,9 @@ fn voidvariantindex(tagged: *node) i32 = { // returned value's surface type, find the matching variant's 0-based // index. Compare by exact type name first; if no match, fall back to // "any str-shape variant matches an str-typed value". -fn taggedvariantindex(c: *cgen, tagged: *node, rhs: *node) i32 = { +fn taggedvariantindex(c: *cgen, tagged: *syntax.node, rhs: *syntax.node) i32 = { if (tagged == nil) { return -1; }; - return taggedvariantindext(c, tagged.type_: *tinfo, rhs); + return taggedvariantindext(c, tagged.type_: *syntax.tinfo, rhs); }; // taggedvariantindext — tinfo-keyed core of taggedvariantindex. Given @@ -21373,14 +21373,14 @@ fn taggedvariantindex(c: *cgen, tagged: *node, rhs: *node) i32 = { // pass 1 (cgvariantmatch's tyassignableuntyped arm, the cg_variant_match // :801 mirror); the str/slice shape scan below covers the remaining // LOOSE sources (concrete types that typeeq no variant). -fn taggedvariantindext(c: *cgen, du: *tinfo, rhs: *node) i32 = { +fn taggedvariantindext(c: *cgen, du: *syntax.tinfo, rhs: *syntax.node) i32 = { if (du == nil) { return -1; }; if (rhs == nil) { return -1; }; - let ti: *tinfo = du; + let ti: *syntax.tinfo = du; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; - let r: i32 = flatvariantidxt(ti, rhs.type_: *tinfo, false); + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; + let r: i32 = flatvariantidxt(ti, rhs.type_: *syntax.tinfo, false); if (r >= 0) { return r; }; // Shape fallback: classify rhs as (str, slice, scalar/other) and // pick the first variant of matching shape. Covers LOOSE concrete @@ -21392,12 +21392,12 @@ fn taggedvariantindext(c: *cgen, du: *tinfo, rhs: *node) i32 = { // walk collapses to a flat scan over p.type_. let wantstr: bool = nodeisstr(c, rhs); let wantslice: bool = nodeisslice(c, rhs); - let p: *tparam = ti.params; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; - let visstr: bool = typeisstr(vt); - let visslice: bool = typeisslice(vt); + let vt: *syntax.tinfo = p.type_; + let visstr: bool = syntax.typeisstr(vt); + let visslice: bool = syntax.typeisslice(vt); if (visstr == wantstr && visslice == wantslice) { return idx; }; p = p.tnext; idx += 1; @@ -21419,10 +21419,10 @@ fn taggedvariantindext(c: *cgen, du: *tinfo, rhs: *node) i32 = { // ptr-id (typeeq, typ.ww:514), one-NAMED → kind mismatch → false. ww has // no type_assignable, so the untyped/loose arm (cg_variant_match's first // branch) lives in the caller's str/slice shape fallback, not here. -fn flatvariantidx(c: *cgen, tagged: *node, pat: *node) i32 = { +fn flatvariantidx(c: *cgen, tagged: *syntax.node, pat: *syntax.node) i32 = { if (tagged == nil) { return -1; }; if (pat == nil) { return -1; }; - return flatvariantidxt(tagged.type_: *tinfo, pat.type_: *tinfo, false); + return flatvariantidxt(tagged.type_: *syntax.tinfo, pat.type_: *syntax.tinfo, false); }; // flatvariantidxt — tinfo-keyed core of flatvariantidx: flat 0-based @@ -21442,16 +21442,16 @@ fn flatvariantidx(c: *cgen, tagged: *node, pat: *node) i32 = { // consumers, two modes — not a wrapper. cstage has no twin: its is/as // gate (check.c:2036) never calls cg_tag_for_variant, so cg_tag_for_variant // stays full-only there. -fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { +fn flatvariantidxt(tagged: *syntax.tinfo, want: *syntax.tinfo, exactonly: bool) i32 = { if (want == nil) { return -1; }; - let ti: *tinfo = tagged; + let ti: *syntax.tinfo = tagged; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; // Pass 1: exact match (NAMED-vs-NAMED typeeq, tagged-vs-tagged, bare // typeeq). Exact matches take precedence and need no guard — distinct // variants don't exact-match the same source. - let p: *tparam = ti.params; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { if (cgvariantmatch(p.type_, want)) { return idx; }; @@ -21473,10 +21473,10 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // disambiguated once the nominal-lossy model collapses the chain — // hard-error (drew's ambiguity proviso extended to the chained // set). cs twin cg_tag_for_variant fused in this commit. - if (want.kind == tykind.TY_NAMED) { - let sb: *tinfo = tichase(want); + if (want.kind == syntax.tykind.TY_NAMED) { + let sb: *syntax.tinfo = tichase(want); if (sb == nil) { return -1; }; - let q: *tparam = ti.params; + let q: *syntax.tparam = ti.params; let qi: i32 = 0; let found: i32 = -1; let n: i32 = 0; @@ -21512,7 +21512,7 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { q = ti.params; qi = 0; for (q != nil) { - if (q.type_ != nil && typeeq(tichase(q.type_), sb)) { + if (q.type_ != nil && syntax.typeeq(tichase(q.type_), sb)) { if (found < 0) { found = qi; }; n += 1; }; @@ -21536,8 +21536,8 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // exact `i64`. drew's proviso: guard the structural fallback like the // #218 nested-widen site — a bare source matching >=2 NAMED variants // needs nominal layout to disambiguate, so hard-error. - if (want.kind != tykind.TY_NAMED) { - let q: *tparam = ti.params; + if (want.kind != syntax.tykind.TY_NAMED) { + let q: *syntax.tparam = ti.params; let qi: i32 = 0; let found: i32 = -1; let n: i32 = 0; @@ -21551,9 +21551,9 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // below now guards the CHASED match set. cs twin // cg_tag_for_variant fused in this commit (probe: // both-wrong-identical pre-fix). - let pu: *tinfo = q.type_; - if (pu != nil && pu.kind == tykind.TY_NAMED - && typeeq(tichase(pu), want)) { + let pu: *syntax.tinfo = q.type_; + if (pu != nil && pu.kind == syntax.tykind.TY_NAMED + && syntax.typeeq(tichase(pu), want)) { if (found < 0) { found = qi; }; n += 1; }; @@ -21576,7 +21576,7 @@ fn flatvariantidxt(tagged: *tinfo, want: *tinfo, exactonly: bool) i32 = { // (type.c:316-324) for a variant that is itself a union. ww's checker // isassignable is node-keyed (AST type exprs), so the tinfo-keyed // widen/match funnel needs this focused mirror (#33). -fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { +fn tyassignableuntyped(dst: *syntax.tinfo, want: *syntax.tinfo) bool = { if (dst == nil) { return false; }; if (want == nil) { return false; }; // c4 (rob RE-RULE 2026-06-05): FULL chase, not the one-level unwrap @@ -21587,8 +21587,8 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // alias variant silently mis-tagged 0 (the str twin was masked by // taggedvariantindext's shape fallback). Aligns ww UP to the cs // twin cmd/wcc/type.c:369-385, harec-shaped since F1 9bd0d8b. - let du: *tinfo = tichase(dst); - if (du != nil && du.kind == tykind.TY_TAGGED) { + let du: *syntax.tinfo = tichase(dst); + if (du != nil && du.kind == syntax.tykind.TY_TAGGED) { // concrete→tagged drill (type.c:316-324): a NESTED tagged // variant compares by type_eq there — never equal to an // untyped source — so only non-tagged variants recurse, on @@ -21596,12 +21596,12 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // detected via the full chase (was one-level: a 2-level // alias-tagged variant slipped INTO the recursion, diverging // from cs's checker-level #199α reject — see the c4 finding). - let p: *tparam = du.params; + let p: *syntax.tparam = du.params; for (p != nil) { - let pu: *tinfo = tichase(p.type_); + let pu: *syntax.tinfo = tichase(p.type_); let nestedtagged: bool = false; if (pu != nil) { - if (pu.kind == tykind.TY_TAGGED) { nestedtagged = true; }; + if (pu.kind == syntax.tykind.TY_TAGGED) { nestedtagged = true; }; }; if (!nestedtagged) { if (tyassignableuntyped(p.type_, want)) { return true; }; @@ -21613,26 +21613,26 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // type.c:369-385 — INT/FLOAT/RUNE run on the UNPEELED dst exactly // like cs (typeisnum/typeisfloat/typeisint self-recurse TY_NAMED); // STR/BOOL/NIL read the chased du like cs reads its chased du. - if (want.kind == tykind.TY_UNTYPED_INT) { return typeisnum(dst); }; - if (want.kind == tykind.TY_UNTYPED_FLOAT) { return typeisfloat(dst); }; - if (want.kind == tykind.TY_UNTYPED_STR) { + if (want.kind == syntax.tykind.TY_UNTYPED_INT) { return syntax.typeisnum(dst); }; + if (want.kind == syntax.tykind.TY_UNTYPED_FLOAT) { return syntax.typeisfloat(dst); }; + if (want.kind == syntax.tykind.TY_UNTYPED_STR) { if (du == nil) { return false; }; - return du.kind == tykind.TY_STR; + return du.kind == syntax.tykind.TY_STR; }; - if (want.kind == tykind.TY_UNTYPED_RUNE) { - if (typeisint(dst)) { return true; }; - return dst.kind == tykind.TY_RUNE; + if (want.kind == syntax.tykind.TY_UNTYPED_RUNE) { + if (syntax.typeisint(dst)) { return true; }; + return dst.kind == syntax.tykind.TY_RUNE; }; - if (want.kind == tykind.TY_UNTYPED_BOOL) { + if (want.kind == syntax.tykind.TY_UNTYPED_BOOL) { if (du == nil) { return false; }; - return du.kind == tykind.TY_BOOL; + return du.kind == syntax.tykind.TY_BOOL; }; - if (want.kind == tykind.TY_UNTYPED_NIL) { + if (want.kind == syntax.tykind.TY_UNTYPED_NIL) { if (du == nil) { return false; }; - if (du.kind == tykind.TY_PTR) { return true; }; - if (du.kind == tykind.TY_SLICE) { return true; }; - if (du.kind == tykind.TY_CHAN) { return true; }; - return du.kind == tykind.TY_FN; + if (du.kind == syntax.tykind.TY_PTR) { return true; }; + if (du.kind == syntax.tykind.TY_SLICE) { return true; }; + if (du.kind == syntax.tykind.TY_CHAN) { return true; }; + return du.kind == syntax.tykind.TY_FN; }; return false; }; @@ -21650,7 +21650,7 @@ fn tyassignableuntyped(dst: *tinfo, want: *tinfo) bool = { // nominal-lossy; the collision guard in cgwidentaggedstorebp enforces // the invariant for when #199b/B-full lands true nominal layout. // - neither NAMED → structural typeeq -fn cgvariantmatch(vt: *tinfo, want: *tinfo) bool = { +fn cgvariantmatch(vt: *syntax.tinfo, want: *syntax.tinfo) bool = { if (vt == nil) { return false; }; if (want == nil) { return false; }; // #33: pre-fix an untyped scalar fell past the typeeq passes to @@ -21658,23 +21658,23 @@ fn cgvariantmatch(vt: *tinfo, want: *tinfo) bool = { // non-str/slice variant can be `void` — a bare // `let e: (void | size) = 5` stored tag 0 while the is/as side // resolved `size` to 1 (wwstage-only; cstage resolves here). - if (typeisuntyped(want)) { return tyassignableuntyped(vt, want); }; - if (vt.kind == tykind.TY_NAMED && want.kind == tykind.TY_NAMED) { - return typeeq(vt, want); + if (syntax.typeisuntyped(want)) { return tyassignableuntyped(vt, want); }; + if (vt.kind == syntax.tykind.TY_NAMED && want.kind == syntax.tykind.TY_NAMED) { + return syntax.typeeq(vt, want); }; - if (vt.kind == tykind.TY_NAMED || want.kind == tykind.TY_NAMED) { - let vu: *tinfo = vt; + if (vt.kind == syntax.tykind.TY_NAMED || want.kind == syntax.tykind.TY_NAMED) { + let vu: *syntax.tinfo = vt; vu = tichase(vu); - let wu: *tinfo = want; + let wu: *syntax.tinfo = want; wu = tichase(wu); if (vu != nil && wu != nil - && vu.kind == tykind.TY_TAGGED - && wu.kind == tykind.TY_TAGGED) { - return typeeq(vu, wu); + && vu.kind == syntax.tykind.TY_TAGGED + && wu.kind == syntax.tykind.TY_TAGGED) { + return syntax.typeeq(vu, wu); }; return false; }; - return typeeq(vt, want); + return syntax.typeeq(vt, want); }; // cgvariantstructmatch — structural equality ignoring nominal identity @@ -21682,14 +21682,14 @@ fn cgvariantmatch(vt: *tinfo, want: *tinfo) bool = { // variants share the source's *shape*; ≥2 means the structural fallback // could not disambiguate them once nominal identity is lost. Mirrors // cstage cg_variant_struct_match (cmd/w6c/cgen.c). -fn cgvariantstructmatch(vt: *tinfo, want: *tinfo) bool = { - let vu: *tinfo = vt; +fn cgvariantstructmatch(vt: *syntax.tinfo, want: *syntax.tinfo) bool = { + let vu: *syntax.tinfo = vt; vu = tichase(vu); - let wu: *tinfo = want; + let wu: *syntax.tinfo = want; wu = tichase(wu); if (vu == nil) { return false; }; if (wu == nil) { return false; }; - return typeeq(vu, wu); + return syntax.typeeq(vu, wu); }; // flatslicevariantidx — flat 0-based index of a slice-shape variant in @@ -21703,27 +21703,27 @@ fn cgvariantstructmatch(vt: *tinfo, want: *tinfo) bool = { // #66 Phase-N step 3: element compare flips from surface-name to // typeeq(p.type_.sub, elem.type_). Mirrors cstage cg_tag_for_variant // over Type->params. Returns -1 when no slice variant exists. -fn flatslicevariantidx(c: *cgen, tagged: *node, elem: *node) i32 = { +fn flatslicevariantidx(c: *cgen, tagged: *syntax.node, elem: *syntax.node) i32 = { if (tagged == nil) { return -1; }; - let ti: *tinfo = tagged.type_: *tinfo; + let ti: *syntax.tinfo = tagged.type_: *syntax.tinfo; ti = tichase(ti); if (ti == nil) { return -1; }; - if (ti.kind != tykind.TY_TAGGED) { return -1; }; - let want: *tinfo = nil; - if (elem != nil) { want = elem.type_: *tinfo; }; + if (ti.kind != syntax.tykind.TY_TAGGED) { return -1; }; + let want: *syntax.tinfo = nil; + if (elem != nil) { want = elem.type_: *syntax.tinfo; }; let fallback: i32 = -1; - let p: *tparam = ti.params; + let p: *syntax.tparam = ti.params; let idx: i32 = 0; for (p != nil) { - let vt: *tinfo = p.type_; + let vt: *syntax.tinfo = p.type_; if (vt != nil) { - if (typeisslice(vt)) { + if (syntax.typeisslice(vt)) { if (fallback < 0) { fallback = idx; }; if (want != nil) { - let su: *tinfo = vt; + let su: *syntax.tinfo = vt; su = tichase(su); if (su != nil) { - if (typeeq(su.sub, want)) { return idx; }; + if (syntax.typeeq(su.sub, want)) { return idx; }; }; }; }; @@ -21742,17 +21742,17 @@ fn flatslicevariantidx(c: *cgen, tagged: *node, elem: *node) i32 = { // TY_NAMED then walk su.params, mapping each source variant to its dst // index by typeeq (flatvariantidxt). Mirrors cg_widen_tag_remap // (cmd/w6c/cgen.c:1177) over su->params + cg_tag_for_variant (:503). -fn cgwidentagremap(c: *cgen, du: *tinfo, su: *tinfo, slot_off: i32) void = { - let dt: *tinfo = du; +fn cgwidentagremap(c: *cgen, du: *syntax.tinfo, su: *syntax.tinfo, slot_off: i32) void = { + let dt: *syntax.tinfo = du; dt = tichase(dt); if (dt == nil) { return; }; - if (dt.kind != tykind.TY_TAGGED) { return; }; - let st: *tinfo = su; + if (dt.kind != syntax.tykind.TY_TAGGED) { return; }; + let st: *syntax.tinfo = su; st = tichase(st); if (st == nil) { return; }; - if (st.kind != tykind.TY_TAGGED) { return; }; + if (st.kind != syntax.tykind.TY_TAGGED) { return; }; let identity: bool = true; - let p: *tparam = st.params; + let p: *syntax.tparam = st.params; let idx: i32 = 0; for (p != nil) { let di: i32 = flatvariantidxt(dt, p.type_, false); @@ -21799,12 +21799,12 @@ fn cgwidentagremap(c: *cgen, du: *tinfo, su: *tinfo, slot_off: i32) void = { // when the name is registered in c.structs — `!void` / `!i32` aliases // share the N_STRUCTLIT / N_TNAME shape but aren't structs, and must // fall through to the scalar/str/tagged-source paths instead. -fn rhsstructpayload(c: *cgen, src: *node) str = { +fn rhsstructpayload(c: *cgen, src: *syntax.node) str = { let empty: str; empty.ptr = nil; empty.len = 0; if (src == nil) { return empty; }; - if (src.kind == nkind.N_STRUCTLIT) { - let trefn: *node = src.lhs; + if (src.kind == syntax.nkind.N_STRUCTLIT) { + let trefn: *syntax.node = src.lhs; if (trefn != nil) { // #92: bare structlookup missed an alias-named literal // — `ali{...}` into a union fell to the scalar widen @@ -21819,12 +21819,12 @@ fn rhsstructpayload(c: *cgen, src: *node) str = { }; return empty; }; - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, src.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { + if (tn.kind == syntax.nkind.N_TNAME) { // #62 Layer-2 (F2 ww half): bare structlookup // missed an alias name (ali->base), so the // struct value fell to the SCALAR widen arm — @@ -21849,12 +21849,12 @@ fn rhsstructpayload(c: *cgen, src: *node) str = { // rhstaggedsource — return the tagged-type node for `src` when src is a // tagged-typed local ident; nil otherwise. The slot-copy path uses this // to walk variants for tag remap. -fn rhstaggedident(c: *cgen, src: *node) *node = { +fn rhstaggedident(c: *cgen, src: *syntax.node) *syntax.node = { if (src == nil) { return nil; }; - if (src.kind != nkind.N_IDENT) { return nil; }; + if (src.kind != syntax.nkind.N_IDENT) { return nil; }; let lc: *local = localfindnode(c, src.str); if (lc == nil) { return nil; }; - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (!istaggedtype(c, tn)) { return nil; }; return resolvetagged(c, tn); }; @@ -21865,9 +21865,9 @@ fn rhstaggedident(c: *cgen, src: *node) *node = { // #28's cgdot fix loads AX/DX/CX/R8 from the field's slot). Used to // decide whether cgexpr/spill works for the tagged-source branch of // cgwidentaggedstore. -fn rhstaggedabicall(c: *cgen, src: *node) bool = { +fn rhstaggedabicall(c: *cgen, src: *syntax.node) bool = { if (src == nil) { return false; }; - if (src.kind == nkind.N_CALL) { + if (src.kind == syntax.nkind.N_CALL) { // #211: a call's result type is the CALLEE's fn-type ret, which // the checker stamps onto this N_CALL node (check.ww N_CALL: both // the SK_FN path and the fn-VALUE/field path set e.type_ = the @@ -21878,10 +21878,10 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // sister reads u->ret off the callee type (cmd/wcc/check.c:1433, // :1490); harec selects by interned type id, not name (ref/harec/ // src/types.c:714). Mirrors the N_DOT branch below. - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; return false; }; - if (src.kind == nkind.N_INDEX) { + if (src.kind == syntax.nkind.N_INDEX) { // The checker stamps every N_INDEX node's type_ to the element // tinfo (check.ww:2334-2337 indexresult) for ANY base shape — // N_IDENT, N_DOT (`x.o[i]`), or chained N_INDEX (`m[i][j]`). Read @@ -21891,7 +21891,7 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // so a tagged element materialized via `x.o[i]` (correct AX/DX // slot from cgindex) was then spilled by the scalar-widen arm, // dropping the tag/payload-high word — silent cs≠ww. - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; return false; }; // N_DOT of a tagged-typed struct field — cgdot loads @@ -21901,19 +21901,19 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // stamp) instead of re-deriving via dotfieldtnode — matches // cstage cg_widen_tagged_store reading src->type directly // (cmd/w6c/cgen.c:1302-1305). typeistagged(nil) is false. - if (src.kind == nkind.N_DOT) { - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (src.kind == syntax.nkind.N_DOT) { + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; }; // Family C (#35/#46): a DEREF source is mem-based (taggedmemread, // any size) — the widen-store's memread arm copies the box from // the address cgexpr leaves in AX. An unwrap (`?`/`!`) source // fills the cursor after the tagged-success payload shift (the // cgtryprop/cgtryunw twin of cstage's kind-blind su-tagged arm). - if (src.kind == nkind.N_UN && src.op == tkind.TK_STAR) { - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (src.kind == syntax.nkind.N_UN && src.op == syntax.tkind.TK_STAR) { + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; }; - if (src.kind == nkind.N_TRYPROP || src.kind == nkind.N_TRYUNW) { - if (typeistagged(src.type_: *tinfo)) { return true; }; + if (src.kind == syntax.nkind.N_TRYPROP || src.kind == syntax.nkind.N_TRYUNW) { + if (syntax.typeistagged(src.type_: *syntax.tinfo)) { return true; }; }; return false; }; @@ -21930,21 +21930,21 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { // (which carried only the tag) and consumers copy from memory. ≤32B // INDEX/DOT keep the cursor byte-for-byte (the #37 no-drift bar); // the nullable one-word fold stays a scalar deref. -fn taggedmemread(c: *cgen, e: *node) bool = { +fn taggedmemread(c: *cgen, e: *syntax.node) bool = { if (e == nil) { return false; }; - if (e.kind == nkind.N_UN && e.op == tkind.TK_STAR) { - let du: *tinfo = e.type_: *tinfo; + if (e.kind == syntax.nkind.N_UN && e.op == syntax.tkind.TK_STAR) { + let du: *syntax.tinfo = e.type_: *syntax.tinfo; du = tichase(du); if (du == nil) { return false; }; - if (du.kind != tykind.TY_TAGGED) { return false; }; + if (du.kind != syntax.tykind.TY_TAGGED) { return false; }; if (du.nullable != 0) { return false; }; return du.size: i32 > 8; }; - if (e.kind != nkind.N_INDEX && e.kind != nkind.N_DOT) { return false; }; - let u: *tinfo = e.type_: *tinfo; + if (e.kind != syntax.nkind.N_INDEX && e.kind != syntax.nkind.N_DOT) { return false; }; + let u: *syntax.tinfo = e.type_: *syntax.tinfo; u = tichase(u); if (u == nil) { return false; }; - if (u.kind != tykind.TY_TAGGED) { return false; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return false; }; return u.size: i32 > TUPLE_GPCAP * 8; }; @@ -21956,17 +21956,17 @@ fn taggedmemread(c: *cgen, e: *node) bool = { // variant casts (`7: size`) keep their node for variant-tag lookup; // the nullable one-word fold never spills a cursor — excluded. // Mirrors cstage cg_tagged_castpeel. -fn taggedcastpeel(c: *cgen, e: *node) *node = { - for (e != nil && e.kind == nkind.N_CAST && e.lhs != nil) { - let cu: *tinfo = e.type_: *tinfo; +fn taggedcastpeel(c: *cgen, e: *syntax.node) *syntax.node = { + for (e != nil && e.kind == syntax.nkind.N_CAST && e.lhs != nil) { + let cu: *syntax.tinfo = e.type_: *syntax.tinfo; cu = tichase(cu); if (cu == nil) { return e; }; - if (cu.kind != tykind.TY_TAGGED) { return e; }; + if (cu.kind != syntax.tykind.TY_TAGGED) { return e; }; if (cu.nullable != 0) { return e; }; - let iu: *tinfo = e.lhs.type_: *tinfo; + let iu: *syntax.tinfo = e.lhs.type_: *syntax.tinfo; iu = tichase(iu); if (iu == nil) { return e; }; - if (iu.kind != tykind.TY_TAGGED) { return e; }; + if (iu.kind != syntax.tykind.TY_TAGGED) { return e; }; if (iu.nullable != 0) { return e; }; e = e.lhs; }; @@ -21979,13 +21979,13 @@ fn taggedcastpeel(c: *cgen, e: *node) *node = { // cast changes the tag numbering and must NOT be peeled — those die // loud at the consumer's cast catch-all instead. Mirrors cstage // cg_tagged_idcastpeel. -fn taggedidcastpeel(c: *cgen, e: *node) *node = { - for (e != nil && e.kind == nkind.N_CAST && e.lhs != nil) { - if (!typeeq(e.type_: *tinfo, e.lhs.type_: *tinfo)) { return e; }; - let cu: *tinfo = e.type_: *tinfo; +fn taggedidcastpeel(c: *cgen, e: *syntax.node) *syntax.node = { + for (e != nil && e.kind == syntax.nkind.N_CAST && e.lhs != nil) { + if (!syntax.typeeq(e.type_: *syntax.tinfo, e.lhs.type_: *syntax.tinfo)) { return e; }; + let cu: *syntax.tinfo = e.type_: *syntax.tinfo; cu = tichase(cu); if (cu == nil) { return e; }; - if (cu.kind != tykind.TY_TAGGED) { return e; }; + if (cu.kind != syntax.tykind.TY_TAGGED) { return e; }; e = e.lhs; }; return e; @@ -22062,9 +22062,9 @@ fn cgloadtaggedfield(c: *cgen, basereg: str, foff: i32, slot_sz: i32) void = { // tag last. // - str src: tag@+0, ptr@+8, len@+16, cap@+24 (str IS []u8, #1/Phase 3). // - scalar src: tag@+0, value@+8. -fn cgwidentaggedstore(c: *cgen, dst: *tinfo, src: *node, +fn cgwidentaggedstore(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, basereg: str, slot_off: i32, slot_sz: i32) void = { - if (streq(basereg, "BP")) { + if (syntax.streq(basereg, "BP")) { cgwidentaggedstorebp(c, dst, src, slot_off, slot_sz); return; }; @@ -22111,16 +22111,16 @@ fn cgwidentaggedstore(c: *cgen, dst: *tinfo, src: *node, // for the natural "BP" case and via the wrapper's scratch path for // pointer-rooted dst. Direct callers exist only in case of future // inlined uses inside this file; new code should call the wrapper. -fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_sz: i32) void = { +fn cgwidentaggedstorebp(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, slot_off: i32, slot_sz: i32) void = { // #68: dst is the tagged tinfo. Peel TY_NAMED → du and gate // TY_TAGGED, mirroring cstage cg_widen_tagged_store's // `du = (dst->kind==TY_NAMED)?dst->under:dst` + TY_TAGGED guard // (cmd/w6c/cgen.c:1273). resolvetagged's N_TBANG unwrap is already // handled upstream by tinfofornode (check.ww:1203-1210). - let dt: *tinfo = dst; + let dt: *syntax.tinfo = dst; dt = tichase(dt); if (dt == nil) { return; }; - if (dt.kind != tykind.TY_TAGGED) { return; }; + if (dt.kind != syntax.tykind.TY_TAGGED) { return; }; // Nullable fold: one 8B word holding the pointer (or 0 for void). if (dt.nullable != 0) { cgexpr(c, src); @@ -22143,11 +22143,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // a concrete variant (`7: i32`) is left intact so the existing // scalar / str / slice branches pick the right variant tag. if (src != nil) { - if (src.kind == nkind.N_CAST) { + if (src.kind == syntax.nkind.N_CAST) { if (src.lhs != nil) { - let inner: *node = src.lhs; + let inner: *syntax.node = src.lhs; let inneristagged: bool = false; - if (inner.kind == nkind.N_IDENT) { + if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { inneristagged = istaggedtype(c, lc.tnode); @@ -22170,16 +22170,16 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // the a==b fast path. let castisdst: bool = false; let castsubset: bool = false; - let castrhs: *node = src.rhs; + let castrhs: *syntax.node = src.rhs; if (castrhs != nil) { - let castt: *tinfo = castrhs.type_: *tinfo; - let castu: *tinfo = castt; + let castt: *syntax.tinfo = castrhs.type_: *syntax.tinfo; + let castu: *syntax.tinfo = castt; castu = tichase(castu); if (castu != nil) { if (castu == dt) { castisdst = true; - } else { if (castu.kind == tykind.TY_TAGGED) { - if (typeeq(castt, dst)) { + } else { if (castu.kind == syntax.tykind.TY_TAGGED) { + if (syntax.typeeq(castt, dst)) { castisdst = true; } else { castsubset = true; @@ -22216,7 +22216,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // chased the same src.type_. Mirrors cstage cg_widen_tagged_store's // `su = type_chase_named(st)` position (c138605). Tag lookups keep // the un-chased src.type_ (nominal identity is the alias). - let su: *tinfo = src.type_: *tinfo; + let su: *syntax.tinfo = src.type_: *syntax.tinfo; su = tichase(su); // #218: is the source itself a single NESTED variant of dt (its // whole tagged type matches one dt variant), rather than a flattened @@ -22232,14 +22232,14 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s || rhstaggedabicall(c, src); // #51 (#263): a module-global tagged ident is also a tagged source // (no local slot — handled by the global branch in the nested copy). - if (!srctagged) { if (src.kind == nkind.N_IDENT) { + if (!srctagged) { if (src.kind == syntax.nkind.N_IDENT) { if (localfindnode(c, src.str) == nil) { - let gtn51: *node = letvartnode(c, src.str); + let gtn51: *syntax.node = letvartnode(c, src.str); if (gtn51 != nil) { if (istaggedtype(c, gtn51)) { srctagged = true; }; }; }; }; }; if (srctagged) { - let nested: i32 = flatvariantidxt(dt, src.type_: *tinfo, false); + let nested: i32 = flatvariantidxt(dt, src.type_: *syntax.tinfo, false); if (nested >= 0) { // drew collision guard: the structural fallback over- // matches if ≥2 nominally-distinct dt variants share the @@ -22248,10 +22248,10 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // layer — hard-error NOW so a future collision STOPS the // compiler instead of silently mis-tagging. let nmatch: i32 = 0; - let gp: *tparam = dt.params; + let gp: *syntax.tparam = dt.params; for (gp != nil) { if (cgvariantstructmatch(gp.type_, - src.type_: *tinfo)) { + src.type_: *syntax.tinfo)) { nmatch += 1; }; gp = gp.tnext; @@ -22270,7 +22270,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s emitline("(BP)\n"); zk += 8; }; - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, src.str); if (lc != nil) { let soff: i32 = lc.off; @@ -22312,7 +22312,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // memory (AX = dest pointer), not the cursor — // the spill below would store the pointer as // the payload. Mem-to-mem widen is #40. - if (src.kind == nkind.N_CALL) { + if (src.kind == syntax.nkind.N_CALL) { if (callsretsize(c, src) > 0) { let m40a: str = "#40: sret-class call result cannot be cursor-widened into a tagged slot (mem-to-mem widen unwired)\n"; os.write(2, m40a.ptr, m40a.len: u64); @@ -22346,7 +22346,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // surviving taggedcastpeel (cast to a THIRD // union) has no cursor — loud, not word0 // garbage. Mirrors cstage. - if (src.kind == nkind.N_CAST) { + if (src.kind == syntax.nkind.N_CAST) { let m35a: str = "#35: tagged cast source shape unwired at the widen nested arm (rule 7)\n"; os.write(2, m35a.ptr, m35a.len: u64); os.exit(1); @@ -22383,7 +22383,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // Tagged source ident: byte-copy slot words then tag-remap. // rhstaggedident gates "src is a tagged-typed local ident"; the // remap reads the source tagged tinfo off the local's tnode (#68). - let st: *node = rhstaggedident(c, src); + let st: *syntax.node = rhstaggedident(c, src); if (st != nil) { let lc: *local = localfindnode(c, src.str); let ssz: i32 = slotsize(c, lc.tnode); @@ -22408,7 +22408,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s p += 8; }; }; - cgwidentagremap(c, dt, lc.tnode.type_: *tinfo, slot_off); + cgwidentagremap(c, dt, lc.tnode.type_: *syntax.tinfo, slot_off); return; }; // Tagged source via AX/DX/CX/R8 register ABI (N_CALL, N_INDEX @@ -22417,7 +22417,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s if (rhstaggedabicall(c, src)) { // #38b: an sret-classified call result is in memory (AX = // dest pointer), not the cursor. #40. - if (src.kind == nkind.N_CALL) { + if (src.kind == syntax.nkind.N_CALL) { if (callsretsize(c, src) > 0) { let m40b: str = "#40: sret-class call result cannot be cursor-widened into a tagged slot (mem-to-mem widen unwired)\n"; os.write(2, m40b.ptr, m40b.len: u64); @@ -22451,7 +22451,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s pp37 += 8; }; }; - cgwidentagremap(c, dt, src.type_: *tinfo, slot_off); + cgwidentagremap(c, dt, src.type_: *syntax.tinfo, slot_off); return; }; // #55: spill the AX/DX/CX/R8 cursor by the SOURCE box width @@ -22495,7 +22495,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s pp += 8; }; }; - cgwidentagremap(c, dt, src.type_: *tinfo, slot_off); + cgwidentagremap(c, dt, src.type_: *syntax.tinfo, slot_off); return; }; // #37 (rule 7): a >32B TAGGED source of a kind the resolver arms @@ -22505,7 +22505,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // cg_widen_tagged_store's generic-else bound. Surfaced by // reviewer-37's `let w = *p` probe on a 56B box: cstage loud, // wwstage silent (rule-10 break). - if (su != nil && su.kind == tykind.TY_TAGGED + if (su != nil && su.kind == syntax.tykind.TY_TAGGED && su.size: i32 > TUPLE_GPCAP * 8) { let m37f: str = "#37: >32B tagged source of a non-mem-based kind unwired (rule 7)\n"; os.write(2, m37f.ptr, m37f.len: u64); @@ -22515,8 +22515,8 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // taggedcastpeel (cast to a THIRD union) would fall to the // scalar arm below and silently truncate — loud. Mirrors // cstage's widen subset-arm cast bound. - if (src.kind == nkind.N_CAST && su != nil - && su.kind == tykind.TY_TAGGED && su.nullable == 0) { + if (src.kind == syntax.nkind.N_CAST && su != nil + && su.kind == syntax.tykind.TY_TAGGED && su.nullable == 0) { let m35b: str = "#35: tagged cast source shape unwired at the widen subset arm (rule 7)\n"; os.write(2, m35b.ptr, m35b.len: u64); os.exit(1); @@ -22535,13 +22535,13 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // slot 1+. Peel to the inner tuple here; src.type_ stays the CAST's // type, which resolves the variant tag by exact named match, so the // #241 untyped-element un-matchability does not arise for this form. - let tupsrc: *node = nil; + let tupsrc: *syntax.node = nil; let tupcast: bool = false; if (src != nil) { - if (src.kind == nkind.N_TUPLE) { tupsrc = src; }; - if (src.kind == nkind.N_CAST) { + if (src.kind == syntax.nkind.N_TUPLE) { tupsrc = src; }; + if (src.kind == syntax.nkind.N_CAST) { if (src.lhs != nil) { - if (src.lhs.kind == nkind.N_TUPLE) { + if (src.lhs.kind == syntax.nkind.N_TUPLE) { tupsrc = src.lhs; tupcast = true; }; @@ -22553,7 +22553,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // Mirrors cstage cg_widen_tagged_store. }; if (tupsrc != nil) { - if (su != nil) { if (su.kind == tykind.TY_TUPLE) { + if (su != nil) { if (su.kind == syntax.tykind.TY_TUPLE) { // #242/#241: mirror cstage's loud-stop CONDITION, not its // -1 mechanism (rule 10, align the RICHER side DOWN). // wwstage types `true`/`false` as bool and a suffix-less `7` @@ -22567,15 +22567,15 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // literal typing -> symmetric accept. BARE form only (#66): // the cast form resolves its tag from the cast's type on // BOTH stages, so bare elements are fine there. - let bl: *node = tupsrc.list; + let bl: *syntax.node = tupsrc.list; for (bl != nil && !tupcast) { let bare: bool = false; - if (bl.kind == nkind.N_TRUE) { bare = true; }; - if (bl.kind == nkind.N_FALSE) { bare = true; }; - if (bl.kind == nkind.N_INTLIT && bl.tsuffix.len == 0) { + if (bl.kind == syntax.nkind.N_TRUE) { bare = true; }; + if (bl.kind == syntax.nkind.N_FALSE) { bare = true; }; + if (bl.kind == syntax.nkind.N_INTLIT && bl.tsuffix.len == 0) { bare = true; }; - if (bl.kind == nkind.N_FLOATLIT && bl.tsuffix.len == 0) { + if (bl.kind == syntax.nkind.N_FLOATLIT && bl.tsuffix.len == 0) { bare = true; }; if (bare) { @@ -22590,7 +22590,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // str/slice shape fallback would silently pick tag 0 for an // unmatched tuple, diverging from cstage cg_tag_for_variant // (which returns -1) and masking the loud-stop below. - let ttag: i32 = flatvariantidxt(dt, src.type_: *tinfo, false); + let ttag: i32 = flatvariantidxt(dt, src.type_: *syntax.tinfo, false); // #242: an untyped/literal tuple element (`(true,7)`) leaves // the src tuple un-matchable, so the variant tag can't // resolve — the supported shape is a tuple of TYPED exprs @@ -22608,7 +22608,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // SysV eightbyte tuple classification is a deferred // follow-up. Symmetric with cstage cg_widen_tagged_store. let ttotal: i32 = 0; - let ce: *node = tupsrc.list; + let ce: *syntax.node = tupsrc.list; for (ce != nil) { // #47 gap-A: a tagged element rides its OWN // box (tag + payload, roundup8) per tuple slot @@ -22616,9 +22616,9 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // N_TTUPLE accumulation (check.ww:1640-1646); // the store loop below boxes it recursively // (two-level widen). Symmetric with cstage. - let ceti: *tinfo = ce.type_: *tinfo; + let ceti: *syntax.tinfo = ce.type_: *syntax.tinfo; ceti = tichase(ceti); - if (ceti != nil && ceti.kind == tykind.TY_TAGGED) { + if (ceti != nil && ceti.kind == syntax.tykind.TY_TAGGED) { ttotal += (ceti.size: i32 + 7) & ~7; } else { if (nodeisstr(c, ce) || nodeisslice(c, ce)) { ttotal += 24; @@ -22639,7 +22639,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s tzk += 8; }; let tfoff: i32 = 0; - let te: *node = tupsrc.list; + let te: *syntax.node = tupsrc.list; for (te != nil) { // #47 gap-A: a tagged element is its own // tag+payload box. Recurse so the inner box @@ -22649,11 +22649,11 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // (inner boxes here, outer tuple tag stamped // below). slot stride = roundup8(box). Symmetric // with cstage cg_widen_tagged_store. - let teti: *tinfo = te.type_: *tinfo; + let teti: *syntax.tinfo = te.type_: *syntax.tinfo; teti = tichase(teti); - if (teti != nil && teti.kind == tykind.TY_TAGGED) { + if (teti != nil && teti.kind == syntax.tykind.TY_TAGGED) { let ebox: i32 = (teti.size: i32 + 7) & ~7; - cgwidentaggedstore(c, te.type_: *tinfo, te, + cgwidentaggedstore(c, te.type_: *syntax.tinfo, te, "BP", slot_off + 8 + tfoff, ebox); tfoff += ebox; te = te.next; @@ -22662,7 +22662,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s let isflt: bool = isfloattype(c, te); let wide: bool = nodeisstr(c, te) || nodeisslice(c, te); let esz: i32 = 8; - let eti: *tinfo = te.type_: *tinfo; + let eti: *syntax.tinfo = te.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; cgexpr(c, te); if (isflt) { @@ -22715,23 +22715,23 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // A cast wrapping a concrete-variant tuple (`(tbl[i]: ci)`) // survived the widen-cast peel above; its operand is the // addressable expr. Mirror of cstage cg_widen_tagged_store. - if (su != nil) { if (su.kind == tykind.TY_TUPLE) { - let addrsrc: *node = src; - if (addrsrc.kind == nkind.N_CAST) { + if (su != nil) { if (su.kind == syntax.tykind.TY_TUPLE) { + let addrsrc: *syntax.node = src; + if (addrsrc.kind == syntax.nkind.N_CAST) { if (addrsrc.lhs != nil) { addrsrc = addrsrc.lhs; }; }; let okkind: bool = false; - if (addrsrc.kind == nkind.N_IDENT) { okkind = true; }; - if (addrsrc.kind == nkind.N_INDEX) { okkind = true; }; - if (addrsrc.kind == nkind.N_UN) { - if (addrsrc.op == tkind.TK_STAR) { okkind = true; }; + if (addrsrc.kind == syntax.nkind.N_IDENT) { okkind = true; }; + if (addrsrc.kind == syntax.nkind.N_INDEX) { okkind = true; }; + if (addrsrc.kind == syntax.nkind.N_UN) { + if (addrsrc.op == syntax.tkind.TK_STAR) { okkind = true; }; }; if (!okkind) { let mk: str = "cgwidentaggedstore: tuple-typed source shape unwired (only the bare/cast tuple literal and the addressable ident/index/deref trio carry a full payload; see #116)\n"; os.write(2, mk.ptr, mk.len: u64); os.exit(1); }; - let ntag: i32 = flatvariantidxt(dt, src.type_: *tinfo, false); + let ntag: i32 = flatvariantidxt(dt, src.type_: *syntax.tinfo, false); if (ntag < 0) { let mt: str = "cgwidentaggedstore: tuple-in-union variant tag unresolved (untyped/literal tuple element; see #242 / #241)\n"; os.write(2, mt.ptr, mt.len: u64); @@ -22784,10 +22784,10 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // fell to the scalar word0 arm — payload truncated. Land g(SB) in SI and // byte-copy the struct words into slot+8; cstage zero-fills the payload // (cstage half #43). Local/literal sources keep the existing arms (byte-id). - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { if (localfindnode(c, src.str) == nil) { - let gtn: *node = letvartnode(c, src.str); - if (gtn != nil) { if (gtn.kind == nkind.N_TNAME) { + let gtn: *syntax.node = letvartnode(c, src.str); + if (gtn != nil) { if (gtn.kind == syntax.nkind.N_TNAME) { let gsi: *structinfo = structlookupchain(c, gtn); if (gsi != nil) { emitline("\tXORQ\tAX, AX\n"); @@ -22848,7 +22848,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s }; let tag: i32 = taggedvariantindext(c, dt, src); if (tag < 0) { tag = 0; }; - if (src.kind == nkind.N_STRUCTLIT) { + if (src.kind == syntax.nkind.N_STRUCTLIT) { // #23: delegate to the single fill path. The // inline field loop this replaces was a // parallel fill that drifted: it lacked the @@ -22949,9 +22949,9 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // value" is dead and removed. let fkind: i32 = 0; if (src != nil) { - let srct: *tinfo = src.type_: *tinfo; - if (typeisf32(srct)) { fkind = 1; } - else { if (typeisfloat(srct)) { fkind = 2; }; }; + let srct: *syntax.tinfo = src.type_: *syntax.tinfo; + if (syntax.typeisf32(srct)) { fkind = 1; } + else { if (syntax.typeisfloat(srct)) { fkind = 2; }; }; }; if (fkind != 0) { let fmov: str = "MOVSD"; @@ -22983,17 +22983,17 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // like the slice axis, not nominal identity. let wantf32: bool = (fkind == 1); let ftag: i32 = -1; - let fti: *tinfo = dt; + let fti: *syntax.tinfo = dt; fti = tichase(fti); - if (fti != nil) { if (fti.kind == tykind.TY_TAGGED) { - let fp: *tparam = fti.params; + if (fti != nil) { if (fti.kind == syntax.tykind.TY_TAGGED) { + let fp: *syntax.tparam = fti.params; let fidx: i32 = 0; for (fp != nil) { - let fvt: *tinfo = fp.type_; + let fvt: *syntax.tinfo = fp.type_; fvt = tichase(fvt); if (fvt != nil) { - if (typeisfloat(fvt)) { - if (typeisf32(fvt) == wantf32) { ftag = fidx; break; }; + if (syntax.typeisfloat(fvt)) { + if (syntax.typeisf32(fvt) == wantf32) { ftag = fidx; break; }; }; }; fp = fp.tnext; @@ -23068,9 +23068,9 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s // offset), so this is offset-preserving. Leaf out-param is the field's // stamped *tinfo (was *fieldinfo); the str/slice pseudo-leaf leaves it // nil and the callers gate on slicedelta>=0 first. -export fn dotchainresolve(c: *cgen, n: *node, +export fn dotchainresolve(c: *cgen, n: *syntax.node, outrootname: *str, outrootoff: *i32, outtotaloff: *i32, - outleaftype: **tinfo, outslicedelta: *i32, + outleaftype: **syntax.tinfo, outslicedelta: *i32, outisglobal: *bool, outptrroot: *bool) bool = { *outrootname = ""; *outrootoff = 0; @@ -23080,12 +23080,12 @@ export fn dotchainresolve(c: *cgen, n: *node, *outleaftype = nil; *outslicedelta = -1; if (n == nil) { return false; }; - if (n.kind != nkind.N_DOT) { return false; }; - let stk: [16]*node; + if (n.kind != syntax.nkind.N_DOT) { return false; }; + let stk: [16]*syntax.node; let nsteps: i32 = 0; - let cur: *node = n; + let cur: *syntax.node = n; for (cur != nil) { - if (cur.kind != nkind.N_DOT) { break; }; + if (cur.kind != syntax.nkind.N_DOT) { break; }; if (nsteps >= 16) { return false; }; stk[nsteps] = cur; nsteps += 1; @@ -23093,13 +23093,13 @@ export fn dotchainresolve(c: *cgen, n: *node, }; if (nsteps < 2) { return false; }; if (cur == nil) { return false; }; - if (cur.kind != nkind.N_IDENT) { return false; }; + if (cur.kind != syntax.nkind.N_IDENT) { return false; }; *outrootname = cur.str; let resolved: bool = false; let lc: *local = localfindnode(c, cur.str); if (lc != nil) { if (lc.tnode != nil) { - if (lc.tnode.kind == nkind.N_TNAME) { + if (lc.tnode.kind == syntax.nkind.N_TNAME) { *outrootoff = lc.off; resolved = true; }; @@ -23107,10 +23107,10 @@ export fn dotchainresolve(c: *cgen, n: *node, // pointee struct supplies the field layout. Callers // that opt in via *outptrroot emit a MOVQ load of the // slot before indexing. - if (lc.tnode.kind == nkind.N_TPTR) { - let pe: *node = lc.tnode.lhs; + if (lc.tnode.kind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = lc.tnode.lhs; if (pe != nil) { - if (pe.kind == nkind.N_TNAME) { + if (pe.kind == syntax.nkind.N_TNAME) { *outrootoff = lc.off; *outptrroot = true; resolved = true; @@ -23130,24 +23130,24 @@ export fn dotchainresolve(c: *cgen, n: *node, // Root struct layout = the stamped root-ident type_, peeled NAMED // (plus one TY_PTR hop for a `*struct` root). tfield.type_ then // supplies each nested struct directly, so no name re-lookup. - let curstruct: *tinfo = cur.type_: *tinfo; + let curstruct: *syntax.tinfo = cur.type_: *syntax.tinfo; curstruct = tichase(curstruct); if (*outptrroot) { if (curstruct == nil) { return false; }; - if (curstruct.kind != tykind.TY_PTR) { return false; }; + if (curstruct.kind != syntax.tykind.TY_PTR) { return false; }; curstruct = curstruct.sub; curstruct = tichase(curstruct); }; let i: i32 = nsteps - 1; for (i >= 0) { if (curstruct == nil) { return false; }; - if (curstruct.kind != tykind.TY_STRUCT) { return false; }; + if (curstruct.kind != syntax.tykind.TY_STRUCT) { return false; }; if (stk[i] == nil) { return false; }; let stepnm: str = stk[i].str; - let tf: *tfield = curstruct.fields; - let found: *tfield = nil; + let tf: *syntax.tfield = curstruct.fields; + let found: *syntax.tfield = nil; for (tf != nil) { - if (streq(tf.name, stepnm)) { found = tf; break; }; + if (syntax.streq(tf.name, stepnm)) { found = tf; break; }; tf = tf.tnext; }; if (found == nil) { return false; }; @@ -23157,37 +23157,37 @@ export fn dotchainresolve(c: *cgen, n: *node, *outleaftype = found.type_; return true; }; - let ft: *tinfo = found.type_; + let ft: *syntax.tinfo = found.type_; ft = tichase(ft); if (ft == nil) { return false; }; - if (ft.kind == tykind.TY_STR) { + if (ft.kind == syntax.tykind.TY_STR) { // str IS []u8: .cap is the third header word, same as // the TY_SLICE leaf below — cstage treats str≡slice for // .ptr/.len/.cap (cmd/w6c/cgen.c:2478) (#1/Phase 3, #11). if (i != 1) { return false; }; let pseudo: str = stk[0].str; let delta: i32 = -1; - if (streq(pseudo, "ptr")) { delta = 0; } - else { if (streq(pseudo, "len")) { delta = 8; } - else { if (streq(pseudo, "cap")) { delta = 16; }; }; }; + if (syntax.streq(pseudo, "ptr")) { delta = 0; } + else { if (syntax.streq(pseudo, "len")) { delta = 8; } + else { if (syntax.streq(pseudo, "cap")) { delta = 16; }; }; }; if (delta < 0) { return false; }; *outtotaloff = *outtotaloff + foff; *outslicedelta = delta; return true; }; - if (ft.kind == tykind.TY_SLICE) { + if (ft.kind == syntax.tykind.TY_SLICE) { if (i != 1) { return false; }; let pseudo: str = stk[0].str; let delta: i32 = -1; - if (streq(pseudo, "ptr")) { delta = 0; } - else { if (streq(pseudo, "len")) { delta = 8; } - else { if (streq(pseudo, "cap")) { delta = 16; }; }; }; + if (syntax.streq(pseudo, "ptr")) { delta = 0; } + else { if (syntax.streq(pseudo, "len")) { delta = 8; } + else { if (syntax.streq(pseudo, "cap")) { delta = 16; }; }; }; if (delta < 0) { return false; }; *outtotaloff = *outtotaloff + foff; *outslicedelta = delta; return true; }; - if (ft.kind != tykind.TY_STRUCT) { return false; }; + if (ft.kind != syntax.tykind.TY_STRUCT) { return false; }; *outtotaloff = *outtotaloff + foff; curstruct = ft; i -= 1; @@ -23253,14 +23253,14 @@ export fn dotchainresolve(c: *cgen, n: *node, // byte-identically — cstage hasn't yet learned MOVW for fsz==2. Once // #13 aligns both stages, the dispatch can switch to fieldstoreop // which already returns MOVW where appropriate. -fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, +fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *syntax.node, mode: i32, srcoff: i32, srcname: str, disp: i32) void = { if (si == nil) { return; }; let basereg: str = "BP"; if (mode != 0) { basereg = "BX"; }; let totsize: i32 = structabisize(si); - if (lit.op == tkind.TK_ELLIPSIS) { + if (lit.op == syntax.tkind.TK_ELLIPSIS) { // `..., ...` autofill — zero the entire slot first so // unmentioned fields read as 0. Sized stores: 8/4/1. For // non-BP modes, reload BX once before the loop (cgexpr-free @@ -23311,14 +23311,14 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, zi += 1; }; }; - let fieldnode: *node = lit.list; + let fieldnode: *syntax.node = lit.list; for (fieldnode != nil) { - if (fieldnode.kind == nkind.N_FIELD) { + if (fieldnode.kind == syntax.nkind.N_FIELD) { let fname: str = fieldnode.str; let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fname)) { + if (syntax.streq(fn_, fname)) { // Tagged-union field: delegate to the shared // widening writer (handles str/scalar/struct // literal/ident payload + tagged-subset tag @@ -23335,7 +23335,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, emitsymname(c, srcname); emitline("(SB), BX\n"); }; - cgwidentaggedstore(c, fi.tnode.type_: *tinfo, + cgwidentaggedstore(c, fi.tnode.type_: *syntax.tinfo, fieldnode.lhs, basereg, disp + fi.foff, fi.fsz); fi = nil; @@ -23347,9 +23347,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // the rest silently stayed zero. let nested: bool = false; if (fieldnode.lhs != nil) { - if (fieldnode.lhs.kind == nkind.N_STRUCTLIT) { + if (fieldnode.lhs.kind == syntax.nkind.N_STRUCTLIT) { if (fi.tnode != nil) { - if (fi.tnode.kind == nkind.N_TNAME) { + if (fi.tnode.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, fi.tnode.str) == 0) { let isi: *structinfo = structlookup(c, fi.tnode.str); if (isi != nil) { @@ -23393,9 +23393,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, let callwhole: bool = false; if (!nested) { if (fieldnode.lhs != nil) { - if (fieldnode.lhs.kind == nkind.N_CALL) { + if (fieldnode.lhs.kind == syntax.nkind.N_CALL) { if (fi.tnode != nil) { - if (fi.tnode.kind == nkind.N_TNAME) { + if (fi.tnode.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, fi.tnode.str) == 0) { let csi: *structinfo = structlookup(c, fi.tnode.str); if (csi != nil) { @@ -23524,9 +23524,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, }; fi = nil; } else if (fi.tnode != nil - && fi.tnode.kind == nkind.N_TARRAY + && fi.tnode.kind == syntax.nkind.N_TARRAY && fieldnode.lhs != nil - && fieldnode.lhs.kind == nkind.N_ARRLIT) { + && fieldnode.lhs.kind == syntax.nkind.N_ARRLIT) { // #249: array field from an N_ARRLIT. Without this // the generic tail below cgexprs the N_ARRLIT (→ AX) // and stores one sized word, silently DROPPING every @@ -23536,7 +23536,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // str/slice/struct/tagged elements are the N_LET // multi-word gap — loud rule-7 error (cstage // cg_structlit_fill twin). - let elemn: *node = fi.tnode.lhs; + let elemn: *syntax.node = fi.tnode.lhs; let isstrel: bool = isstrtype(c, elemn); let istagel: bool = istaggedtype(c, elemn); let issliceel: bool = isslicetype(c, elemn); @@ -23550,9 +23550,9 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // type_chase_named key (cgen.c:3179, B5-c1). let isstructel: bool = false; if (elemn != nil) { - let eu: *tinfo = tichase(elemn.type_: *tinfo); + let eu: *syntax.tinfo = tichase(elemn.type_: *syntax.tinfo); if (eu != nil) { - if (eu.kind == tykind.TY_STRUCT) { + if (eu.kind == syntax.tykind.TY_STRUCT) { isstructel = true; }; }; @@ -23567,7 +23567,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, }; let esz: i32 = 8; if (elemn != nil) { - if (elemn.kind == nkind.N_TNAME) { + if (elemn.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, elemn.str); if (ps > 0) { esz = ps; }; }; @@ -23578,11 +23578,11 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, if (isf32type(c, elemn)) { fmov = "MOVSS"; }; let idx: i32 = 0; let repeat: bool = false; - let e: *node = fieldnode.lhs.list; + let e: *syntax.node = fieldnode.lhs.list; for (e != nil) { let isellip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; isellip = true; }; @@ -23625,7 +23625,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, if (repeat) { let total: i32 = idx; if (fi.tnode.rhs != nil) { - if (fi.tnode.rhs.kind == nkind.N_INTLIT) { + if (fi.tnode.rhs.kind == syntax.nkind.N_INTLIT) { total = fi.tnode.rhs.uval: i32; }; }; @@ -23706,7 +23706,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, }; let agsz49: i32 = 0; if (fi.tnode != nil) { - let agti49: *tinfo = fi.tnode.type_: *tinfo; + let agti49: *syntax.tinfo = fi.tnode.type_: *syntax.tinfo; agti49 = tichase(agti49); if (agti49 != nil) { agsz49 = agti49.size: i32; }; }; @@ -23777,7 +23777,7 @@ fn cgstructlitfill(c: *cgen, si: *structinfo, lit: *node, // Thin wrapper preserving the BP-rel call shape used by cglet, // cgreturn, cgassign N_IDENT-lhs N_STRUCTLIT, and the C1.25 // @placescr materialise (cg_structlit_fill_bp's named twin). -fn cgstructlitfillbp(c: *cgen, si: *structinfo, lit: *node, bpoff: i32) void = { +fn cgstructlitfillbp(c: *cgen, si: *structinfo, lit: *syntax.node, bpoff: i32) void = { if (si == nil) { return; }; cgstructlitfill(c, si, lit, 0, 0, "", bpoff); }; @@ -23816,12 +23816,12 @@ fn cgfloatbits(c: *cgen, bits: u64) void = { emitline("\tADDQ\t$8, SP\n"); }; -fn cgexpr(c: *cgen, n: *node) void = { +fn cgexpr(c: *cgen, n: *syntax.node) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; switch (k) { - case nkind.N_INTLIT: + case syntax.nkind.N_INTLIT: // A no-decimal `0f64`/`8f64` is an N_INTLIT carrying float // TYPE; it must reach X0 like a true float literal, not the // integer-immediate path (which strands it in AX and an SSE @@ -23849,7 +23849,7 @@ fn cgexpr(c: *cgen, n: *node) void = { emitint(n.uval: i64); emitline(", AX\n"); return; - case nkind.N_FLOATLIT: + case syntax.nkind.N_FLOATLIT: // The bits come from n.uval — the parser populates it from // the lexer's bitcast of t.fval. cgfloatbits(c, n.uval); @@ -23858,41 +23858,41 @@ fn cgexpr(c: *cgen, n: *node) void = { emitline("\tCVTSD2SS\tX0, X0\n"); }; return; - case nkind.N_RUNELIT: + case syntax.nkind.N_RUNELIT: emitline("\tMOVQ\t$"); emitint(n.uval: i64); emitline(", AX\n"); return; - case nkind.N_STRLIT: cgstrlit(c, n); return; - case nkind.N_TRUE: + case syntax.nkind.N_STRLIT: cgstrlit(c, n); return; + case syntax.nkind.N_TRUE: emitline("\tMOVQ\t$1, AX\n"); return; - case nkind.N_FALSE: + case syntax.nkind.N_FALSE: emitline("\tMOVQ\t$0, AX\n"); return; - case nkind.N_NIL: + case syntax.nkind.N_NIL: emitline("\tMOVQ\t$0, AX\n"); return; - case nkind.N_VOIDLIT: + case syntax.nkind.N_VOIDLIT: // void value: zero-size, but the consumer's ABI expects a // deterministic AX. Emit 0 like nil/false do. emitline("\tMOVQ\t$0, AX\n"); return; - case nkind.N_IDENT: cgident(c, n); return; - case nkind.N_INDEX: cgindex(c, n); return; - case nkind.N_SLICE: cgslice(c, n); return; - case nkind.N_MATCH: cgmatch(c, n); return; - case nkind.N_CAST: cgcast(c, n); return; - case nkind.N_DOT: cgdot(c, n); return; - case nkind.N_UN: cgun(c, n); return; - case nkind.N_BIN: cgbin(c, n); return; - case nkind.N_CALL: cgcall(c, n); return; - case nkind.N_ASSIGN: cgassign(c, n); return; - case nkind.N_TRYPROP: cgtryprop(c, n); return; - case nkind.N_TRYUNW: cgtryunw(c, n); return; - case nkind.N_TYPETEST: cgtypetest(c, n); return; - case nkind.N_TYPEASSERT: cgtypeassert(c, n); return; - case nkind.N_TUPLE: + case syntax.nkind.N_IDENT: cgident(c, n); return; + case syntax.nkind.N_INDEX: cgindex(c, n); return; + case syntax.nkind.N_SLICE: cgslice(c, n); return; + case syntax.nkind.N_MATCH: cgmatch(c, n); return; + case syntax.nkind.N_CAST: cgcast(c, n); return; + case syntax.nkind.N_DOT: cgdot(c, n); return; + case syntax.nkind.N_UN: cgun(c, n); return; + case syntax.nkind.N_BIN: cgbin(c, n); return; + case syntax.nkind.N_CALL: cgcall(c, n); return; + case syntax.nkind.N_ASSIGN: cgassign(c, n); return; + case syntax.nkind.N_TRYPROP: cgtryprop(c, n); return; + case syntax.nkind.N_TRYUNW: cgtryunw(c, n); return; + case syntax.nkind.N_TYPETEST: cgtypetest(c, n); return; + case syntax.nkind.N_TYPEASSERT: cgtypeassert(c, n); return; + case syntax.nkind.N_TUPLE: // #241: a literal tuple rvalue `(a, b)` is a value — pack its // elements into the register cursor (mirror cgreturn's N_TUPLE // arm) so a let-bind / destructure consumer reads every element, @@ -23913,10 +23913,10 @@ fn cgexpr(c: *cgen, n: *node) void = { // tagged-union type expression `tagged`. -1 if `tagged` isn't an // nkind.N_TTAGGED or no variant matches. Mirrors the lookup that cgmatch // does inline; pulled out so `is` / `as` can reuse it. -fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { +fn cgtagvariantidx(c: *cgen, tagged: *syntax.node, vt: *syntax.node) i32 = { if (tagged == nil) { return -1; }; if (vt == nil) { return -1; }; - if (tagged.kind != nkind.N_TTAGGED) { + if (tagged.kind != syntax.nkind.N_TTAGGED) { // #22a: a STAMPED-CARRIER scrutinee (the #67 matchscrutt // shape — is/as on a tuple element t.N, a struct field, an // indexed element) is not an N_TTAGGED type-AST node; its @@ -23925,10 +23925,10 @@ fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { // cstage cg_tag_for_variant is type-based for every // scrutinee shape, so the AST-keyed -1 here was a silent // tag-0 clamp on wwstage (cs CMPQ $1 vs ww CMPQ $0). - let sti: *tinfo = tagged.type_: *tinfo; + let sti: *syntax.tinfo = tagged.type_: *syntax.tinfo; sti = tichase(sti); - if (sti != nil && sti.kind == tykind.TY_TAGGED && vt.type_ != nil) { - return flatvariantidxt(sti, vt.type_: *tinfo, false); + if (sti != nil && sti.kind == syntax.tykind.TY_TAGGED && vt.type_ != nil) { + return flatvariantidxt(sti, vt.type_: *syntax.tinfo, false); }; return -1; }; @@ -23936,7 +23936,7 @@ fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { // element-aware helper, which carries the loose first-slice-shape // fallback (cstage type_assignable stand-in) that flatvariantidx's // strict typeeq below doesn't. Task #19; #66 refresh. - if (vt.kind == nkind.N_TSLICE) { + if (vt.kind == syntax.nkind.N_TSLICE) { return flatslicevariantidx(c, tagged, vt.lhs); }; // #66 Phase-N step 3: match by typeeq on vt's stamped tinfo @@ -23949,12 +23949,12 @@ fn cgtagvariantidx(c: *cgen, tagged: *node, vt: *node) i32 = { // error (`!T`), the success tag is the first NON-error variant's index; // else 0 (legacy/no-error). Drives the `?`/`!` success-tag CMPQ + the // payload-shift variant lookup (#52/#216 — replaces the hardcoded tag-0). -fn successtag(ou: *tinfo) i64 = { - let u: *tinfo = tichase(ou); +fn successtag(ou: *syntax.tinfo) i64 = { + let u: *syntax.tinfo = tichase(ou); if (u == nil) { return 0i64; }; - if (u.kind != tykind.TY_TAGGED) { return 0i64; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return 0i64; }; let haserr: bool = false; - let p: *tparam = u.params; + let p: *syntax.tparam = u.params; for (p != nil) { if (p.iserror) { haserr = true; }; p = p.tnext; }; if (!haserr) { return 0i64; }; let idx: i64 = 0i64; @@ -23970,13 +23970,13 @@ fn successtag(ou: *tinfo) i64 = { // successvariant — the success variant's type_ (the param at successtag). // Lets the #241 tuple/tagged payload-shift sites inspect the SUCCESS // variant's shape, not the (error-first) first param. -fn successvariant(ou: *tinfo) *tinfo = { - let u: *tinfo = tichase(ou); +fn successvariant(ou: *syntax.tinfo) *syntax.tinfo = { + let u: *syntax.tinfo = tichase(ou); if (u == nil) { return nil; }; - if (u.kind != tykind.TY_TAGGED) { return nil; }; + if (u.kind != syntax.tykind.TY_TAGGED) { return nil; }; let st: i64 = successtag(ou); let idx: i64 = 0i64; - let p: *tparam = u.params; + let p: *syntax.tparam = u.params; for (p != nil) { if (idx == st) { return p.type_; }; idx += 1i64; @@ -23992,17 +23992,17 @@ fn successvariant(ou: *tinfo) *tinfo = { // stamped tagged result tinfo (n.lhs.type_); the success variant is the // param at successtag (dynamic, #52 — not the hardcoded first param), // matching the dynamic CMPQ $successtag success-tag convention. -fn cgtrytupleshift(c: *cgen, n: *node) bool = { +fn cgtrytupleshift(c: *cgen, n: *syntax.node) bool = { if (n.lhs == nil) { return false; }; - let ou: *tinfo = n.lhs.type_: *tinfo; + let ou: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; ou = tichase(ou); if (ou == nil) { return false; }; - if (ou.kind != tykind.TY_TAGGED) { return false; }; + if (ou.kind != syntax.tykind.TY_TAGGED) { return false; }; if (ou.params == nil) { return false; }; - let sv: *tinfo = successvariant(ou); + let sv: *syntax.tinfo = successvariant(ou); sv = tichase(sv); if (sv == nil) { return false; }; - if (sv.kind != tykind.TY_TUPLE) { return false; }; + if (sv.kind != syntax.tykind.TY_TUPLE) { return false; }; cgtaggedtuplepayloadshift(c, sv); return true; }; @@ -24015,17 +24015,17 @@ fn cgtrytupleshift(c: *cgen, n: *node) bool = { // MOVQ DX,AX tail carried only the inner tag and dropped the payload // (ken unw16). Nullable folds to one word and stays on the scalar // move. Twin of cgtrytupleshift; mirrors cstage N_TRYPROP/N_TRYUNW. -fn cgtrytaggedshift(c: *cgen, n: *node) bool = { +fn cgtrytaggedshift(c: *cgen, n: *syntax.node) bool = { if (n.lhs == nil) { return false; }; - let ou: *tinfo = n.lhs.type_: *tinfo; + let ou: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; ou = tichase(ou); if (ou == nil) { return false; }; - if (ou.kind != tykind.TY_TAGGED) { return false; }; + if (ou.kind != syntax.tykind.TY_TAGGED) { return false; }; if (ou.params == nil) { return false; }; - let sv: *tinfo = successvariant(ou); + let sv: *syntax.tinfo = successvariant(ou); sv = tichase(sv); if (sv == nil) { return false; }; - if (sv.kind != tykind.TY_TAGGED) { return false; }; + if (sv.kind != syntax.tykind.TY_TAGGED) { return false; }; if (sv.nullable != 0) { return false; }; emitline("\tMOVQ\tDX, AX\n"); if (sv.size: i32 > 8) { emitline("\tMOVQ\tCX, DX\n"); }; @@ -24048,25 +24048,25 @@ fn cgtrytaggedshift(c: *cgen, n: *node) bool = { // need the lhs in AX and the divisor/count in CX, so swap (rhs AX→CX, // old BX→AX) first. Signed RSHIFTEQ uses SARQ, unsigned SHRQ (#136). // Mirrors cstage cg_dotfield_combine — both stages emit identical asm. -fn cgdotfieldcombine(c: *cgen, op: tkind, unsignd: bool) void = { - if (op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tBX, AX\n"); return; }; - if (op == tkind.TK_MINUSEQ) { +fn cgdotfieldcombine(c: *cgen, op: syntax.tkind, unsignd: bool) void = { + if (op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); emitline("\tMOVQ\tBX, AX\n"); return; }; - if (op == tkind.TK_STAREQ) { emitline("\tIMULQ\tBX, AX\n"); return; }; - if (op == tkind.TK_AMPEQ) { emitline("\tANDQ\tBX, AX\n"); return; }; - if (op == tkind.TK_PIPEEQ) { emitline("\tORQ\tBX, AX\n"); return; }; - if (op == tkind.TK_CARETEQ) { emitline("\tXORQ\tBX, AX\n"); return; }; - if (op == tkind.TK_SLASHEQ) { + if (op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tBX, AX\n"); return; }; + if (op == syntax.tkind.TK_SLASHEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; return; }; - if (op == tkind.TK_PERCENTEQ) { + if (op == syntax.tkind.TK_PERCENTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } @@ -24074,13 +24074,13 @@ fn cgdotfieldcombine(c: *cgen, op: tkind, unsignd: bool) void = { emitline("\tMOVQ\tDX, AX\n"); return; }; - if (op == tkind.TK_LSHIFTEQ) { + if (op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); emitline("\tSHLQ\tCX, AX\n"); return; }; - if (op == tkind.TK_RSHIFTEQ) { + if (op == syntax.tkind.TK_RSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tMOVQ\tBX, AX\n"); if (unsignd) { emitline("\tSHRQ\tCX, AX\n"); } @@ -24096,7 +24096,7 @@ fn cgdotfieldcombine(c: *cgen, op: tkind, unsignd: bool) void = { // non-integer field (float/str/slice/tagged): the combine arm only // speaks integer ABI; pre-#34 these silently became `s.f = rhs`. // Mirrors the cstage cg_dotfield_hardstop gate. (#34/rule-7) -fn cgdotfieldhardstop(c: *cgen, ftn: *node) void = { +fn cgdotfieldhardstop(c: *cgen, ftn: *syntax.node) void = { if (istaggedtype(c, ftn)) { let m: str = "single-dot field compound on tagged field not wired (#34/rule-7)\n"; os.write(2, m.ptr, m.len: u64); @@ -24119,18 +24119,18 @@ fn cgdotfieldhardstop(c: *cgen, ftn: *node) void = { }; }; -fn cgtryunwcursor(c: *cgen, n: *node, opname: str) void = { - let u: *tinfo = nil; - if (n.lhs != nil) { u = n.lhs.type_: *tinfo; }; +fn cgtryunwcursor(c: *cgen, n: *syntax.node, opname: str) void = { + let u: *syntax.tinfo = nil; + if (n.lhs != nil) { u = n.lhs.type_: *syntax.tinfo; }; u = tichase(u); let utag: bool = false; if (u != nil) { - if (u.kind == tykind.TY_TAGGED && u.nullable == 0) { + if (u.kind == syntax.tykind.TY_TAGGED && u.nullable == 0) { utag = true; }; }; if (utag && u.size: i32 > TUPLE_GPCAP * 8 - && n.lhs.kind != nkind.N_CALL) { + && n.lhs.kind != syntax.nkind.N_CALL) { let p37: str = "#37: `"; os.write(2, p37.ptr, p37.len: u64); os.write(2, opname.ptr, opname.len: u64); @@ -24138,7 +24138,7 @@ fn cgtryunwcursor(c: *cgen, n: *node, opname: str) void = { os.write(2, m37t.ptr, m37t.len: u64); os.exit(1); }; - if (utag && n.lhs.kind == nkind.N_IDENT) { + if (utag && n.lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.lhs.str); if (lc == nil) { let p35: str = "#35: `"; @@ -24186,14 +24186,14 @@ fn cgtryunwcursor(c: *cgen, n: *node, opname: str) void = { // cgtryprop — `e?` propagates the error variant up the stack. // Success tag is dynamic via successtag (#52/#216): the first non-error // variant's index (cstage cg_tagged_success_tag parity), 0 when success-first. -fn cgtryprop(c: *cgen, n: *node) void = { +fn cgtryprop(c: *cgen, n: *syntax.node) void = { // #38b residuals (rule 7): the cursor read below cannot see an // sret-classified call result (AX = dest pointer), and the // propagate-RET cannot speak an sret-classified enclosing return // (the caller reads memory, not the cursor). #40-family follow-ups. // Mirrors cstage cgen.c N_TRYPROP gates. if (n.lhs != nil) { - if (n.lhs.kind == nkind.N_CALL) { + if (n.lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, n.lhs) > 0) { let m38p: str = "#38b: `?` on an sret-class call result unwired (mem-based unwrap is a #40-family follow-up)\n"; os.write(2, m38p.ptr, m38p.len: u64); @@ -24231,8 +24231,8 @@ fn cgtryprop(c: *cgen, n: *node) void = { // parity, #52): 0 for success-first, the first non-error index for an // error-first union. let cl: str = mklabel(c, "tryprop_ok"); - let propu: *tinfo = nil; - if (n.lhs != nil) { propu = n.lhs.type_: *tinfo; }; + let propu: *syntax.tinfo = nil; + if (n.lhs != nil) { propu = n.lhs.type_: *syntax.tinfo; }; emitline("\tCMPQ\t$"); emitint(successtag(propu)); emitline(", AX\n"); @@ -24247,17 +24247,17 @@ fn cgtryprop(c: *cgen, n: *node) void = { // Payload words DX/CX/R8 ride the RET untouched; only AX (the // tag) is rewritten. Same-order unions map every error variant to // itself → zero instructions, byte-id with the pre-#173 emit. - let u: *tinfo = nil; - if (n.lhs != nil) { u = n.lhs.type_: *tinfo; }; + let u: *syntax.tinfo = nil; + if (n.lhs != nil) { u = n.lhs.type_: *syntax.tinfo; }; u = tichase(u); - let r: *tinfo = nil; - if (c.fnret != nil) { r = c.fnret.type_: *tinfo; }; + let r: *syntax.tinfo = nil; + if (c.fnret != nil) { r = c.fnret.type_: *syntax.tinfo; }; r = tichase(r); - if (u != nil && r != nil && r.kind == tykind.TY_TAGGED && u.params != nil) { + if (u != nil && r != nil && r.kind == syntax.tykind.TY_TAGGED && u.params != nil) { let propret: str; propret.ptr = nil; propret.len = 0; let haveret: bool = false; - let p: *tparam = u.params; + let p: *syntax.tparam = u.params; let i: i32 = 0; for (p != nil) { if (p.iserror) { @@ -24306,7 +24306,7 @@ fn cgtryprop(c: *cgen, n: *node) void = { // (success_is_str = type_isstr(succ_t at cg_tagged_success_tag)). let succisstr: bool = false; if (n.lhs != nil) { - succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo)); + succisstr = syntax.typeisstr(successvariant(n.lhs.type_: *syntax.tinfo)); }; if (succisstr) { // str IS []u8: success arrives DX=ptr, CX=len, R8=cap @@ -24322,10 +24322,10 @@ fn cgtryprop(c: *cgen, n: *node) void = { // cgtryunw — `e!` aborts on the error variant via exit(1). Success tag // is dynamic via successtag (#52): the first non-error variant's index // (cstage cg_tagged_success_tag parity), 0 when success-first. -fn cgtryunw(c: *cgen, n: *node) void = { +fn cgtryunw(c: *cgen, n: *syntax.node) void = { // #38b residual (rule 7): see the cgtryprop twin. if (n.lhs != nil) { - if (n.lhs.kind == nkind.N_CALL) { + if (n.lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, n.lhs) > 0) { let m38u: str = "#38b: `!` on an sret-class call result unwired (mem-based unwrap is a #40-family follow-up)\n"; os.write(2, m38u.ptr, m38u.len: u64); @@ -24354,8 +24354,8 @@ fn cgtryunw(c: *cgen, n: *node) void = { // Success tag is dynamic (successtag / cstage cg_tagged_success_tag // parity, #52): 0 for success-first, the first non-error index for an // error-first union. - let unwu: *tinfo = nil; - if (n.lhs != nil) { unwu = n.lhs.type_: *tinfo; }; + let unwu: *syntax.tinfo = nil; + if (n.lhs != nil) { unwu = n.lhs.type_: *syntax.tinfo; }; emitline("\tCMPQ\t$"); emitint(successtag(unwu)); emitline(", AX\n"); @@ -24373,7 +24373,7 @@ fn cgtryunw(c: *cgen, n: *node) void = { // cgtryprop; cstage cgen.c:10595-10602). let succisstr: bool = false; if (n.lhs != nil) { - succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo)); + succisstr = syntax.typeisstr(successvariant(n.lhs.type_: *syntax.tinfo)); }; if (succisstr) { // str IS []u8: success arrives DX=ptr, CX=len, R8=cap @@ -24386,7 +24386,7 @@ fn cgtryunw(c: *cgen, n: *node) void = { return; }; -fn cgtypetest(c: *cgen, n: *node) void = { +fn cgtypetest(c: *cgen, n: *syntax.node) void = { // `e is T` — load the lhs's tag, compare against T's variant // index, set AX = (tag == idx). Result type is bool. // @@ -24398,12 +24398,12 @@ fn cgtypetest(c: *cgen, n: *node) void = { // the ident emission carries; a WIDENING tagged cast renumbers // the tag the compare keys on and has no wired source arm — // loud below, not a mis-keyed test. Mirrors cstage N_TYPETEST. - let lhs: *node = taggedidcastpeel(c, n.lhs); + let lhs: *syntax.node = taggedidcastpeel(c, n.lhs); // #38b residual (rule 7): an sret-class call result leaves AX = // dest pointer, not the tag — mem-based test is a #40-family // follow-up. Mirrors cstage cgen.c N_TYPETEST gate. if (lhs != nil) { - if (lhs.kind == nkind.N_CALL) { + if (lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, lhs) > 0) { let m38t: str = "#38b: `is` on an sret-class call result unwired (#40-family follow-up)\n"; os.write(2, m38t.ptr, m38t.len: u64); @@ -24412,11 +24412,11 @@ fn cgtypetest(c: *cgen, n: *node) void = { }; }; let scrutoff: i32 = 0; - let scrutt: *node = nil; + let scrutt: *syntax.node = nil; let nonident: bool = false; let globalident: bool = false; if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, lhs.str); if (lc != nil) { scrutoff = lc.off; @@ -24425,7 +24425,7 @@ fn cgtypetest(c: *cgen, n: *node) void = { // #18 is-half (align-UP): global tagged ident — tag word at // g(SB)+0, no BP slot. cstage N_TYPETEST is uniformly cgexpr // (MOVQ g(SB),AX); pre-fix the !nonident emit read 0(BP)=saved BP. - let gt: *node = letvartnode(c, lhs.str); + let gt: *syntax.node = letvartnode(c, lhs.str); scrutt = resolvetagged(c, gt); globalident = true; }; @@ -24444,10 +24444,10 @@ fn cgtypetest(c: *cgen, n: *node) void = { // Family C catch-all (rule 7): a widening tagged // cast source — loud. Mirrors cstage. { - let icu: *tinfo = lhs.type_: *tinfo; + let icu: *syntax.tinfo = lhs.type_: *syntax.tinfo; icu = tichase(icu); - if (lhs.kind == nkind.N_CAST && icu != nil - && icu.kind == tykind.TY_TAGGED + if (lhs.kind == syntax.nkind.N_CAST && icu != nil + && icu.kind == syntax.tykind.TY_TAGGED && icu.nullable == 0) { let m35i: str = "#35: tagged cast source shape unwired at `is` (rule 7)\n"; os.write(2, m35i.ptr, m35i.len: u64); @@ -24464,7 +24464,7 @@ fn cgtypetest(c: *cgen, n: *node) void = { }; }; let want: i32 = 0; - let nullcarrier: *node = scrutt; + let nullcarrier: *syntax.node = scrutt; if (nonident) { // Variant index from the STAMPED scrutinee type (cstage: // u = n->lhs->type) — matchscrutt's node-shape walk can't @@ -24473,7 +24473,7 @@ fn cgtypetest(c: *cgen, n: *node) void = { // flatslicevariantidx read .type_ off any stamped carrier. nullcarrier = lhs; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_TSLICE) { + if (n.rhs.kind == syntax.nkind.N_TSLICE) { want = flatslicevariantidx(c, lhs, n.rhs.lhs); } else { want = flatvariantidx(c, lhs, n.rhs); @@ -24524,13 +24524,13 @@ fn cgtypetest(c: *cgen, n: *node) void = { return; }; -fn cgtypeassert(c: *cgen, n: *node) void = { +fn cgtypeassert(c: *cgen, n: *syntax.node) void = { // `e as T` — load tag, abort (exit 1) if tag != T's variant // index, otherwise unwrap to T's ABI: scalar/ptr → AX, 16B // str → (AX, BX). Mirrors cgmatch's slot-based value load. // Slot resolution inlined; see cgtypetest comment. // Family C (#35): identity-cast peel — see the cgtypetest twin. - let lhs: *node = taggedidcastpeel(c, n.lhs); + let lhs: *syntax.node = taggedidcastpeel(c, n.lhs); // Enum ↔ integer: reinterpret-only — the value already occupies AX // (or AX:BX for str variants, irrelevant here); no tag/unwrap. Gate // on the stamped operand / result TYPE, not node shape: a constant- @@ -24539,13 +24539,13 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // spurious tagged-assertion + exit(1) (#27b). Mirrors cstage // cmd/w6c/cgen.c N_TYPEASSERT (type_chase_named on operand + result). { - let su: *tinfo = nil; - if (lhs != nil) { su = tichase(lhs.type_: *tinfo); }; - let vu: *tinfo = tichase(n.type_: *tinfo); + let su: *syntax.tinfo = nil; + if (lhs != nil) { su = tichase(lhs.type_: *syntax.tinfo); }; + let vu: *syntax.tinfo = tichase(n.type_: *syntax.tinfo); let lenum: bool = false; let renum: bool = false; - if (su != nil) { if (su.kind == tykind.TY_ENUM) { lenum = true; }; }; - if (vu != nil) { if (vu.kind == tykind.TY_ENUM) { renum = true; }; }; + if (su != nil) { if (su.kind == syntax.tykind.TY_ENUM) { lenum = true; }; }; + if (vu != nil) { if (vu.kind == syntax.tykind.TY_ENUM) { renum = true; }; }; if (lenum || renum) { cgexpr(c, lhs); return; @@ -24555,7 +24555,7 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // an sret-class call result never fills. Mirrors cstage cgen.c // N_TYPEASSERT gate. if (lhs != nil) { - if (lhs.kind == nkind.N_CALL) { + if (lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, lhs) > 0) { let m38a: str = "#38b: `as` on an sret-class call result unwired (#40-family follow-up)\n"; os.write(2, m38a.ptr, m38a.len: u64); @@ -24564,9 +24564,9 @@ fn cgtypeassert(c: *cgen, n: *node) void = { }; }; let scrutoff: i32 = 0; - let scrutt: *node = nil; + let scrutt: *syntax.node = nil; if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, lhs.str); if (lc != nil) { scrutoff = lc.off; @@ -24577,7 +24577,7 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // task #46). No BP slot: copy the box words from g(SB) into a // fresh @asrt_spill so the tag-check + payload load below index // off memory like a local. cs!=ww residual until #46 lands. - let gt: *node = letvartnode(c, lhs.str); + let gt: *syntax.node = letvartnode(c, lhs.str); scrutt = resolvetagged(c, gt); let gsz: i32 = matchspillsz(c, scrutt); scrutoff = localalloc(c, "@asrt_spill", gsz, nil); @@ -24634,10 +24634,10 @@ fn cgtypeassert(c: *cgen, n: *node) void = { // Family C catch-all (rule 7): a widening tagged // cast source — loud. Mirrors cstage. { - let acu: *tinfo = lhs.type_: *tinfo; + let acu: *syntax.tinfo = lhs.type_: *syntax.tinfo; acu = tichase(acu); - if (lhs.kind == nkind.N_CAST && acu != nil - && acu.kind == tykind.TY_TAGGED + if (lhs.kind == syntax.nkind.N_CAST && acu != nil + && acu.kind == syntax.tykind.TY_TAGGED && acu.nullable == 0) { let m35s: str = "#35: tagged cast source shape unwired at `as` (rule 7)\n"; os.write(2, m35s.ptr, m35s.len: u64); @@ -24716,12 +24716,12 @@ fn cgtypeassert(c: *cgen, n: *node) void = { return; }; -fn cgcast(c: *cgen, n: *node) void = { +fn cgcast(c: *cgen, n: *syntax.node) void = { let srcfk: i32 = 0; if (n.lhs != nil) { - let st: *tinfo = n.lhs.type_: *tinfo; - if (typeisf32(st)) { srcfk = 1; } - else { if (typeisfloat(st)) { srcfk = 2; }; }; + let st: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; + if (syntax.typeisf32(st)) { srcfk = 1; } + else { if (syntax.typeisfloat(st)) { srcfk = 2; }; }; }; let dstf64: bool = isfloattype(c, n.rhs); let dstf32: bool = isf32type(c, n.rhs); @@ -24774,18 +24774,18 @@ fn cgcast(c: *cgen, n: *node) void = { // Detect bool dst by walking n.rhs to the leaf TNAME. bool // keeps its dedicated ANDQ $255 contract regardless of // upstream shape; it stays off the identity path. - let leaf_tn: *node = n.rhs; + let leaf_tn: *syntax.node = n.rhs; for (leaf_tn != nil) { - let lk: nkind = leaf_tn.kind; - if (lk == nkind.N_TBANG) { leaf_tn = leaf_tn.lhs; } - else { if (lk == nkind.N_TENUM) { leaf_tn = leaf_tn.lhs; } - else { if (lk == nkind.N_TNAME) { + let lk: syntax.nkind = leaf_tn.kind; + if (lk == syntax.nkind.N_TBANG) { leaf_tn = leaf_tn.lhs; } + else { if (lk == syntax.nkind.N_TENUM) { leaf_tn = leaf_tn.lhs; } + else { if (lk == syntax.nkind.N_TNAME) { let lnm: str = leaf_tn.str; // primsize-ok (#101/#109): this IS an alias chase loop // — primsize is the leaf-primitive break test the loop // wraps (aliaslookup advances the cursor on a miss). if (primsize(lnm) > 0) { break; }; - let lal: *node = aliaslookup(c, lnm); + let lal: *syntax.node = aliaslookup(c, lnm); if (lal == nil) { leaf_tn = nil; } else { leaf_tn = lal; }; } @@ -24793,8 +24793,8 @@ fn cgcast(c: *cgen, n: *node) void = { }; let is_bool: bool = false; if (leaf_tn != nil) { - if (leaf_tn.kind == nkind.N_TNAME) { - is_bool = streq(leaf_tn.str, "bool"); + if (leaf_tn.kind == syntax.nkind.N_TNAME) { + is_bool = syntax.streq(leaf_tn.str, "bool"); }; }; // Symmetric narrow on signed vs unsigned (task #5): @@ -24852,7 +24852,7 @@ fn cgcast(c: *cgen, n: *node) void = { // Same-kind float→float: nothing to emit. }; -fn cgstrlit(c: *cgen, n: *node) void = { +fn cgstrlit(c: *cgen, n: *syntax.node) void = { // str IS []u8: the (ptr, len, cap) triple — ptr in AX, len in BX, // cap in CX. A static literal has no spare storage, so cap = len // (#1/Phase 3). Call sites that expect a str arg pick these up. @@ -24870,7 +24870,7 @@ fn cgstrlit(c: *cgen, n: *node) void = { return; }; -fn cgident(c: *cgen, n: *node) void = { +fn cgident(c: *cgen, n: *syntax.node) void = { let nm: str = n.str; let lc: *local = localfindnode(c, nm); if (lc != nil) { @@ -24878,10 +24878,10 @@ fn cgident(c: *cgen, n: *node) void = { // #241: a tuple ident is a value — leave the whole tuple in the // register cursor (`yield t` / `return t` / `let q = t`), not // just word0 in AX. Mirror of cstage cgexpr N_IDENT tuple arm. - let itu: *tinfo = nil; - if (lc.tnode != nil) { itu = lc.tnode.type_: *tinfo; }; + let itu: *syntax.tinfo = nil; + if (lc.tnode != nil) { itu = lc.tnode.type_: *syntax.tinfo; }; itu = tichase(itu); - if (itu != nil) { if (itu.kind == tykind.TY_TUPLE) { + if (itu != nil) { if (itu.kind == syntax.tykind.TY_TUPLE) { cgtupleslottocursor(c, off, itu); return; }; }; @@ -24938,9 +24938,9 @@ fn cgident(c: *cgen, n: *node) void = { // the (LEAQ ptr, MOVQ $len) pair instead, mirroring cstage // Sdef walk #1 N_IDENT bare-load (cmd/w6c/cgen.c). Filed #12. if (deflookup(c, nm)) { - let drhs: *node = deflookuprhs(c, nm); + let drhs: *syntax.node = deflookuprhs(c, nm); if (drhs != nil) { - if (drhs.kind == nkind.N_STRLIT) { + if (drhs.kind == syntax.nkind.N_STRLIT) { let bytes: str = drhs.str; let lab: str = internstrlit(c, bytes); emitline("\tLEAQ\t"); @@ -24984,7 +24984,7 @@ fn cgident(c: *cgen, n: *node) void = { // in one go, so a body-less FFI binding emits the C symbol // it was declared with via @symbol(), not the ww-side ident. // Bare ident → same-module by ww's resolver, hint with c.curmod. - let rtyp: *node = fnretlookup(c, nm); + let rtyp: *syntax.node = fnretlookup(c, nm); if (rtyp != nil) { emitline("\tLEAQ\t"); emitfnname(c, nm, c.curmod); @@ -25005,12 +25005,12 @@ fn cgident(c: *cgen, n: *node) void = { // receive read a STALE cursor for words 1+. Element reads // (g.N) are the supported surface. Mirrors the cstage cgexpr // non-local ident guard. - let gtt: *node = letvartnode(c, nm); - for (gtt != nil && gtt.kind == nkind.N_TNAME) { + let gtt: *syntax.node = letvartnode(c, nm); + for (gtt != nil && gtt.kind == syntax.nkind.N_TNAME) { gtt = aliaslookup(c, gtt.str); }; if (gtt != nil) { - if (gtt.kind == nkind.N_TTUPLE) { + if (gtt.kind == syntax.nkind.N_TTUPLE) { let mgt: str = "#48: global tuple as a first-class value unwired (element reads only; rule 7)\n"; os.write(2, mgt.ptr, mgt.len: u64); os.exit(1); @@ -25035,10 +25035,10 @@ fn cgident(c: *cgen, n: *node) void = { // MOVSD have no D_EXTERN operand form in w6a. Signed-narrow // scalar globals route through the same LEAQ scratch since // MOVSXD/MOVSWQ/MOVSBQ also have no D_EXTERN form. - let lvtnode: *node = nil; + let lvtnode: *syntax.node = nil; let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, nm)) { + if (syntax.streq(lv.name, nm)) { // #135: an inferred-float global's tnode is the // defaultinferredlets-renamed "f64"/"f32" N_TNAME whose // .type_ is unstamped (cgen can't build tinfo), so the @@ -25048,7 +25048,7 @@ fn cgident(c: *cgen, n: *node) void = { let isf: bool = isfloattype(c, lv.tnode); let is32: bool = isf32type(c, lv.tnode); if (!isf && lv.tnode != nil - && lv.tnode.kind == nkind.N_TNAME) { + && lv.tnode.kind == syntax.nkind.N_TNAME) { let fsz: i32 = letfloatprim(lv.tnode.str); if (fsz > 0) { isf = true; }; if (fsz == 4) { is32 = true; }; @@ -25071,7 +25071,7 @@ fn cgident(c: *cgen, n: *node) void = { }; }; let glop: str = localloadop(c, lvtnode); - if (streq(glop, "MOVQ")) { + if (syntax.streq(glop, "MOVQ")) { emitline("\tMOVQ\t"); emitfnname(c, nm, c.curmod); emitline("(SB), AX\n"); @@ -25096,12 +25096,12 @@ fn cgident(c: *cgen, n: *node) void = { // and, later, the typeassert str-variant leaf (#9). c retained unused // for callsite symmetry with cstage cgslicehdr. fn cgslicehdr(c: *cgen, base: str) void = { - if (!streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; - if (!streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; - if (!streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; - if (streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; - if (streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; - if (streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; + if (!syntax.streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; + if (!syntax.streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; + if (!syntax.streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; + if (syntax.streq(base, "BX")) { emitmovqload(8i64, base, "BX"); }; + if (syntax.streq(base, "CX")) { emitmovqload(16i64, base, "CX"); }; + if (syntax.streq(base, "AX")) { emitmovqload(0i64, base, "AX"); }; }; // dotchainaddr — emit the ADDRESS of a dot/ident lvalue chain into @@ -25113,9 +25113,9 @@ fn cgslicehdr(c: *cgen, base: str) void = { // spill contract as dotbaseaddr. The chained-base arm of dotbaseaddr // (#253) is its sole caller. Cstage twin: cmd/w6c/cgen.c // `cg_dotchain_addr`. -fn dotchainaddr(c: *cgen, n: *node, dstreg: str) bool = { +fn dotchainaddr(c: *cgen, n: *syntax.node, dstreg: str) bool = { if (n == nil) { return false; }; - if (n.kind == nkind.N_IDENT) { + if (n.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -25142,29 +25142,29 @@ fn dotchainaddr(c: *cgen, n: *node, dstreg: str) bool = { }; return false; }; - if (n.kind != nkind.N_DOT) { return false; }; - let x: *node = n.lhs; + if (n.kind != syntax.nkind.N_DOT) { return false; }; + let x: *syntax.node = n.lhs; if (x == nil) { return false; }; - let xu: *tinfo = x.type_: *tinfo; + let xu: *syntax.tinfo = x.type_: *syntax.tinfo; xu = tichase(xu); if (xu == nil) { return false; }; let xviaptr: bool = false; - let st: *tinfo = nil; - if (xu.kind == tykind.TY_PTR) { - let p: *tinfo = xu.sub; + let st: *syntax.tinfo = nil; + if (xu.kind == syntax.tykind.TY_PTR) { + let p: *syntax.tinfo = xu.sub; p = tichase(p); - if (p != nil) { if (p.kind == tykind.TY_STRUCT) { + if (p != nil) { if (p.kind == syntax.tykind.TY_STRUCT) { st = p; xviaptr = true; }; }; - } else { if (xu.kind == tykind.TY_STRUCT) { + } else { if (xu.kind == syntax.tykind.TY_STRUCT) { st = xu; }; }; if (st == nil) { return false; }; - let f: *tfield = st.fields; + let f: *syntax.tfield = st.fields; let foff: i64 = -1; for (f != nil) { - if (streq(f.name, n.str)) { + if (syntax.streq(f.name, n.str)) { foff = f.offset: i64; break; }; @@ -25207,13 +25207,13 @@ fn dotchainaddr(c: *cgen, n: *node, dstreg: str) bool = { // inner when inner is a *struct (viaptr), else the ADDRESS of inner — // then adds the field offset. Closes the array-field-base-address // family across every op (index r/w, addr-of, slice, compound). -fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { +fn dotbaseaddr(c: *cgen, base: *syntax.node, dstreg: str) bool = { if (base == nil) { return false; }; - if (base.kind != nkind.N_DOT) { return false; }; - let inner: *node = base.lhs; + if (base.kind != syntax.nkind.N_DOT) { return false; }; + let inner: *syntax.node = base.lhs; if (inner == nil) { return false; }; - let chained: bool = (inner.kind == nkind.N_DOT); - if (inner.kind != nkind.N_IDENT && !chained) { return false; }; + let chained: bool = (inner.kind == syntax.nkind.N_DOT); + if (inner.kind != syntax.nkind.N_IDENT && !chained) { return false; }; // #128b: module-qualified `mod.arr` where arr is an imported // top-level `let X: [N]T`. The checker leaves SK_USE module- // idents without a localfindnode entry; detect via letvartnode @@ -25232,10 +25232,10 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { // (cgen.c:2109). Without the gate a typed-struct global inner whose // FIELD shares a name with an unrelated global array hijacks it // (gs.fld -> LEAQ fld(SB)) — #20. A typed inner falls to #249 below. - let ibu: *tinfo = tichase(inner.type_: *tinfo); - if (ibu == nil || ibu.kind == tykind.TY_ERR) { - let gt: *node = letvartnode(c, base.str); - if (gt != nil && gt.kind == nkind.N_TARRAY) { + let ibu: *syntax.tinfo = tichase(inner.type_: *syntax.tinfo); + if (ibu == nil || ibu.kind == syntax.tykind.TY_ERR) { + let gt: *syntax.node = letvartnode(c, base.str); + if (gt != nil && gt.kind == syntax.nkind.N_TARRAY) { emitline("\tLEAQ\t"); emitsymname(c, base.str); emitline("(SB), "); @@ -25252,27 +25252,27 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { isglobal = true; }; }; - let bu: *tinfo = inner.type_: *tinfo; + let bu: *syntax.tinfo = inner.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; let viaptr: bool = false; - let structt: *tinfo = nil; - if (bu.kind == tykind.TY_PTR) { - let st: *tinfo = bu.sub; + let structt: *syntax.tinfo = nil; + if (bu.kind == syntax.tykind.TY_PTR) { + let st: *syntax.tinfo = bu.sub; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { structt = st; viaptr = true; }; }; - } else { if (bu.kind == tykind.TY_STRUCT) { + } else { if (bu.kind == syntax.tykind.TY_STRUCT) { structt = bu; }; }; if (structt == nil) { return false; }; - let f: *tfield = structt.fields; + let f: *syntax.tfield = structt.fields; let foff: i64 = -1; - let ft: *tinfo = nil; + let ft: *syntax.tinfo = nil; for (f != nil) { - if (streq(f.name, base.str)) { + if (syntax.streq(f.name, base.str)) { foff = f.offset: i64; ft = f.type_; break; @@ -25286,7 +25286,7 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { // twin gate at cg_dotbase_addr. ft = tichase(ft); if (ft == nil) { return false; }; - if (ft.kind != tykind.TY_ARRAY) { return false; }; + if (ft.kind != syntax.tykind.TY_ARRAY) { return false; }; // #253: chained inner — compute the container base via the dot-chain // spine (pointer VALUE of inner when viaptr, else its ADDRESS), then // add the field offset. dotchainaddr keeps the spill contract. @@ -25356,11 +25356,11 @@ fn dotbaseaddr(c: *cgen, base: *node, dstreg: str) bool = { // #253), N_INDEX element of an N_IDENT array base (the &base[i] spine, // #252/#270). Returns false for an uncovered source kind (caller loud- // stops, rule 7). The CALL source is handled at the push site. -fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { - if (src.kind == nkind.N_UN) { - if (src.op == tkind.TK_STAR) { +fn aggargsrcaddr(c: *cgen, src: *syntax.node, dst: str) bool = { + if (src.kind == syntax.nkind.N_UN) { + if (src.op == syntax.tkind.TK_STAR) { cgexpr(c, src.lhs); - if (!streq(dst, "AX")) { + if (!syntax.streq(dst, "AX")) { emitline("\tMOVQ\tAX, "); emitline(dst); emitline("\n"); @@ -25368,7 +25368,7 @@ fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { return true; }; }; - if (src.kind == nkind.N_IDENT) { + if (src.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, src.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -25392,18 +25392,18 @@ fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { }; return false; }; - if (src.kind == nkind.N_DOT) { + if (src.kind == syntax.nkind.N_DOT) { return dotchainaddr(c, src, dst); }; - if (src.kind == nkind.N_INDEX) { - let base: *node = src.lhs; - let idx: *node = src.rhs; + if (src.kind == syntax.nkind.N_INDEX) { + let base: *syntax.node = src.lhs; + let idx: *syntax.node = src.rhs; if (base == nil) { return false; }; - if (base.kind != nkind.N_IDENT) { return false; }; - let bu: *tinfo = base.type_: *tinfo; + if (base.kind != syntax.nkind.N_IDENT) { return false; }; + let bu: *syntax.tinfo = base.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; - if (bu.kind != tykind.TY_ARRAY) { return false; }; + if (bu.kind != syntax.tykind.TY_ARRAY) { return false; }; let esz: i32 = 1; if (bu.sub != nil) { esz = bu.sub.size: i32; }; cgexpr(c, idx); @@ -25424,7 +25424,7 @@ fn aggargsrcaddr(c: *cgen, src: *node, dst: str) bool = { emitline("(SB), BX\n"); }; emitline("\tADDQ\tBX, AX\n"); - if (!streq(dst, "AX")) { + if (!syntax.streq(dst, "AX")) { emitline("\tMOVQ\tAX, "); emitline(dst); emitline("\n"); @@ -25494,13 +25494,13 @@ fn aggcopy(c: *cgen, sz: i32) void = { // #44-coupled source). The ragged-tail completeness shared by both stages' // field copies is a separate class, tracked under #73 / the aggcopy // emitter choke-point. -fn copysrcnatsize(c: *cgen, src: *node) i32 = { +fn copysrcnatsize(c: *cgen, src: *syntax.node) i32 = { if (src == nil || src.type_ == nil) { let msg: str = "#71: whole-struct copy source has no stamped tinfo\n"; os.write(2, msg.ptr, msg.len: u64); os.exit(1); }; - let ti: *tinfo = tichase(src.type_: *tinfo); + let ti: *syntax.tinfo = tichase(src.type_: *syntax.tinfo); if (ti == nil) { let msg: str = "#71: whole-struct copy source tinfo chase yielded nil\n"; os.write(2, msg.ptr, msg.len: u64); @@ -25524,9 +25524,9 @@ fn copysrcnatsize(c: *cgen, src: *node) i32 = { // keeps its own load/store/copy emission. Clobbers AX/CX (cgexpr on // index / pointer operands) and balances its own PUSHQ/POPQ; dstreg // must not be AX or CX. -fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { +fn cgplaceaddr(c: *cgen, n: *syntax.node, dstreg: str) bool = { if (n == nil) { return false; }; - if (n.kind == nkind.N_IDENT) { + if (n.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, n.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -25541,9 +25541,9 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { if (defvarstructinfo(c, n.str) != nil) { gok = true; }; }; if (!gok) { - let dtn: *node = defvartnode(c, n.str); + let dtn: *syntax.node = defvartnode(c, n.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { gok = true; }; + if (dtn.kind == syntax.nkind.N_TARRAY) { gok = true; }; }; }; if (gok) { @@ -25556,8 +25556,8 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { }; return false; }; - if (n.kind == nkind.N_UN) { - if (n.op != tkind.TK_STAR) { return false; }; + if (n.kind == syntax.nkind.N_UN) { + if (n.op != syntax.tkind.TK_STAR) { return false; }; // &(*e) is e's value — no load. cgexpr(c, n.lhs); emitline("\tMOVQ\tAX, "); @@ -25565,21 +25565,21 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { emitline("\n"); return true; }; - if (n.kind == nkind.N_INDEX) { - let base: *node = n.lhs; - let idx: *node = n.rhs; + if (n.kind == syntax.nkind.N_INDEX) { + let base: *syntax.node = n.lhs; + let idx: *syntax.node = n.rhs; if (base == nil || idx == nil) { return false; }; // C2: any addressable base — recursion decides (deref / // ident / dot / index spine). Ident-rooted shapes with // enumerated arms never reach the resolver (those arms // dispatch first), so their asm is untouched. - let bu: *tinfo = base.type_: *tinfo; + let bu: *syntax.tinfo = base.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; - if (bu.kind != tykind.TY_SLICE && bu.kind != tykind.TY_ARRAY) { + if (bu.kind != syntax.tykind.TY_SLICE && bu.kind != syntax.tykind.TY_ARRAY) { return false; }; - let et: *tinfo = n.type_: *tinfo; + let et: *syntax.tinfo = n.type_: *syntax.tinfo; et = tichase(et); if (et == nil) { return false; }; let esz: i32 = et.size: i32; @@ -25595,7 +25595,7 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { // A slice place holds the {ptr,len,cap} header — the // element base is its .ptr word; an array place IS the // element storage. - if (bu.kind == tykind.TY_SLICE) { + if (bu.kind == syntax.tykind.TY_SLICE) { emitline("\tMOVQ\t("); emitline(dstreg); emitline("), "); @@ -25608,29 +25608,29 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { emitline("\n"); return true; }; - if (n.kind == nkind.N_DOT) { - let base: *node = n.lhs; + if (n.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = n.lhs; if (base == nil) { return false; }; - let bu: *tinfo = base.type_: *tinfo; + let bu: *syntax.tinfo = base.type_: *syntax.tinfo; bu = tichase(bu); if (bu == nil) { return false; }; let viaptr: bool = false; - let st: *tinfo = nil; - if (bu.kind == tykind.TY_PTR) { - let p: *tinfo = bu.sub; + let st: *syntax.tinfo = nil; + if (bu.kind == syntax.tykind.TY_PTR) { + let p: *syntax.tinfo = bu.sub; p = tichase(p); - if (p != nil) { if (p.kind == tykind.TY_STRUCT) { + if (p != nil) { if (p.kind == syntax.tykind.TY_STRUCT) { st = p; viaptr = true; }; }; - } else { if (bu.kind == tykind.TY_STRUCT) { + } else { if (bu.kind == syntax.tykind.TY_STRUCT) { st = bu; }; }; if (st == nil) { return false; }; - let f: *tfield = st.fields; + let f: *syntax.tfield = st.fields; let foff: i64 = -1; for (f != nil) { - if (streq(f.name, n.str)) { + if (syntax.streq(f.name, n.str)) { foff = f.offset: i64; break; }; @@ -25657,12 +25657,12 @@ fn cgplaceaddr(c: *cgen, n: *node, dstreg: str) bool = { return false; }; -fn cgindex(c: *cgen, n: *node) void = { +fn cgindex(c: *cgen, n: *syntax.node) void = { // Element-size-aware load: u8 → MOVZBQ, i32 → MOVSXD, u32 → MOVL, // str → (ptr, len) into (AX, BX), everything else → MOVQ. Fast // path when the base is a bare ident (mem.ww shape). - let base: *node = n.lhs; - let idx: *node = n.rhs; + let base: *syntax.node = n.lhs; + let idx: *syntax.node = n.rhs; // Direct non-ident index bases that match none of the typed arms // below (e.g. a cast-expression base) keep this 8B default — // cs!=ww for narrow elements. Team task #19 (#61-residual B). @@ -25707,7 +25707,7 @@ fn cgindex(c: *cgen, n: *node) void = { let globalname: str; globalname.ptr = nil; globalname.len = 0; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal != nil) { @@ -25717,7 +25717,7 @@ fn cgindex(c: *cgen, n: *node) void = { f32_elem = elemisf32c(c, baselocal.tnode); elem_isarray = elemisarrayc(c, baselocal.tnode); } else { - let tn: *node = letvartnode(c, bn); + let tn: *syntax.node = letvartnode(c, bn); // #129 A.3: array-typed defs now have DATA storage; // resolve their base via the same N_TARRAY path as // lets. defvartnode is the def-side sister of @@ -25750,7 +25750,7 @@ fn cgindex(c: *cgen, n: *node) void = { float_elem = elemisfloatc(c, tn); f32_elem = elemisf32c(c, tn); elem_isarray = elemisarrayc(c, tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; @@ -25760,17 +25760,17 @@ fn cgindex(c: *cgen, n: *node) void = { // #60: element facts off the chased checker-stamped // tinfos — cstage reads them via type_chase_named/ // idx_eff uniformly (cmd/w6c/cgen.c N_INDEX). - let bt60: *tinfo = base.type_: *tinfo; + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; if (bt60 != nil) { - if (bt60.kind == tykind.TY_NAMED) { basealias = true; }; + if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; }; }; if (basealias) { - let et60: *tinfo = tichase(n.type_: *tinfo); + let et60: *syntax.tinfo = tichase(n.type_: *syntax.tinfo); if (et60 != nil) { esz = et60.size: i32; - signed_elem = typeissigned(et60); - float_elem = typeisfloat(et60); - f32_elem = typeisf32(et60); + signed_elem = syntax.typeissigned(et60); + float_elem = syntax.typeisfloat(et60); + f32_elem = syntax.typeisf32(et60); }; // global base: array-vs-pointer re-keyed off the // chased BASE kind (cstage isglobal && u->kind == @@ -25778,9 +25778,9 @@ fn cgindex(c: *cgen, n: *node) void = { // alias-typed global DATA emit lands (#77/#78); // kept so the read leg is already cs-aligned. if (isglobalarr || isglobalptr) { - let bu60: *tinfo = tichase(bt60); + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - isglobalarr = bu60.kind == tykind.TY_ARRAY; + isglobalarr = bu60.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; @@ -25791,9 +25791,9 @@ fn cgindex(c: *cgen, n: *node) void = { // element tinfo is the authority (cstage gates on // esubu = type_chase_named(esub) == TY_ARRAY). if (!elem_isarray) { - elem_isarray = tinfoisarray(n.type_: *tinfo); + elem_isarray = tinfoisarray(n.type_: *syntax.tinfo); }; - } else { if (base.kind == nkind.N_INDEX) { + } else { if (base.kind == syntax.nkind.N_INDEX) { // #60: chained `names[i][k]` — n.type_ is the checker- // stamped outer element tinfo (indexresult over the inner // index's value type). cstage reads base->type->sub->size @@ -25809,14 +25809,14 @@ fn cgindex(c: *cgen, n: *node) void = { // reading the SAME stamp the esz read above uses. CLASS-N: // the corpus has no chained str/slice element, so the prior // byte-id is preserved (this only fires on the missed shape). - let et: *tinfo = n.type_: *tinfo; + let et: *syntax.tinfo = n.type_: *syntax.tinfo; if (et != nil) { esz = et.size: i32; - signed_elem = typeissigned(et); - elemisstr = typeisstr(et); - elemisslice = typeisslice(et); - float_elem = typeisfloat(et); - f32_elem = typeisf32(et); + signed_elem = syntax.typeissigned(et); + elemisstr = syntax.typeisstr(et); + elemisslice = syntax.typeisslice(et); + float_elem = syntax.typeisfloat(et); + f32_elem = syntax.typeisf32(et); elem_isarray = tinfoisarray(et); }; } else { @@ -25838,8 +25838,8 @@ fn cgindex(c: *cgen, n: *node) void = { // on (signed,sz); cstage's fldloadop reads it from the element // type — align ww up, #255). The base ADDRESS materialization // below is unchanged; only the stride/load-width was wrong. - let dt: *tinfo = n.type_: *tinfo; - if (dt != nil) { esz = dt.size: i32; signed_elem = typeissigned(dt); elemisstr = typeisstr(dt); elemisslice = typeisslice(dt); float_elem = typeisfloat(dt); f32_elem = typeisf32(dt); }; + let dt: *syntax.tinfo = n.type_: *syntax.tinfo; + if (dt != nil) { esz = dt.size: i32; signed_elem = syntax.typeissigned(dt); elemisstr = syntax.typeisstr(dt); elemisslice = syntax.typeisslice(dt); float_elem = syntax.typeisfloat(dt); f32_elem = syntax.typeisf32(dt); }; elem_isarray = tinfoisarray(dt); };}; }; @@ -25851,9 +25851,9 @@ fn cgindex(c: *cgen, n: *node) void = { let elem_tagged: bool = false; let elem_slot_sz: i32 = esz; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bl: *local = baselocal; - let etn: *node = nil; + let etn: *syntax.node = nil; // idxelemtn drills `*[N]T` to the pointee array's own // element (#61) — an undrilled etn classified the whole // array, missing tagged/str/slice elements behind a @@ -25904,10 +25904,10 @@ fn cgindex(c: *cgen, n: *node) void = { // `MOVQ (AX),AX` (tag only) vs cstage's full 4-word cursor // (cs rc=50 / ww rc=40). Dropping the whitelist for the stamp read // closes the base-kind class by construction. - if (base.kind != nkind.N_IDENT) { - let dt: *tinfo = n.type_: *tinfo; + if (base.kind != syntax.nkind.N_IDENT) { + let dt: *syntax.tinfo = n.type_: *syntax.tinfo; if (dt != nil) { - if (typeistagged(dt)) { + if (syntax.typeistagged(dt)) { elem_tagged = true; elem_slot_sz = dt.size: i32; esz = elem_slot_sz; @@ -25923,11 +25923,11 @@ fn cgindex(c: *cgen, n: *node) void = { let elem_tuple: bool = false; let tuple_nwords: i32 = 0; { - let eti: *tinfo = tichase(n.type_: *tinfo); - if (eti != nil) { if (eti.kind == tykind.TY_TUPLE) { + let eti: *syntax.tinfo = tichase(n.type_: *syntax.tinfo); + if (eti != nil) { if (eti.kind == syntax.tykind.TY_TUPLE) { elem_tuple = true; // ww tuples store elements in .tupleelems, not .params. - let tpw: *ttupleelem = eti.tupleelems; + let tpw: *syntax.ttupleelem = eti.tupleelems; for (tpw != nil) { tuple_nwords += tupeslot(tpw.type_) / 8; tpw = tpw.tnext; @@ -26024,14 +26024,14 @@ fn cgindex(c: *cgen, n: *node) void = { return; }; if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; - if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; }; + if (tn != nil) { if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — LEAQ-vs-MOVQ off the chased stamped // kind (cstage u->kind == TY_ARRAY, cmd/w6c/cgen.c N_INDEX). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarray) { emitline("\tLEAQ\t"); @@ -26204,16 +26204,16 @@ fn cgindex(c: *cgen, n: *node) void = { // a GLOBAL str base (no +16 load here, #73 -- matching the cstage // carve-out keeps both stages byte-identical). cstage twin: // cmd/w6c/cgen.c cg_base_cap. -fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { +fn cgbasecap(c: *cgen, base: *syntax.node, dst: str) bool = { if (base == nil) { return false; }; - if (base.kind != nkind.N_IDENT) { return false; }; + if (base.kind != syntax.nkind.N_IDENT) { return false; }; let baselocal: *local = localfindnode(c, base.str); if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; if (tn == nil) { return false; }; - if (tn.kind == nkind.N_TARRAY) { - let lenn: *node = tn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (tn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = tn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", "); @@ -26225,8 +26225,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { // from the stamped array tinfo (rule-13), the cap twin of the // default-hi fix; pre-fix cgbasecap returned false here and the // caller fell to cap=len (cs computes base_cap-lo from bu->alen). - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", "); @@ -26236,7 +26236,7 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { }; return false; }; - if (tn.kind == nkind.N_TSLICE) { + if (tn.kind == syntax.nkind.N_TSLICE) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 16): i64); emitline("(BP), "); @@ -26244,8 +26244,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { emitline("\n"); return true; }; - if (tn.kind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { + if (tn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 16): i64); emitline("(BP), "); @@ -26256,11 +26256,11 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { }; // #60: alias-NAMED base — chased kind (cstage cg_base_cap // receives bu pre-chased by the N_SLICE arm, cgen.c:1888). - let bt60: *tinfo = base.type_: *tinfo; - if (bt60 != nil) { if (bt60.kind == tykind.TY_NAMED) { - let bu60: *tinfo = tichase(bt60); + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt60 != nil) { if (bt60.kind == syntax.tykind.TY_NAMED) { + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", "); @@ -26268,8 +26268,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { emitline("\n"); return true; }; - if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 16): i64); emitline("(BP), "); @@ -26281,11 +26281,11 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { };}; return false; }; - let gt: *node = letvartnode(c, base.str); + let gt: *syntax.node = letvartnode(c, base.str); if (gt == nil) { return false; }; - if (gt.kind == nkind.N_TARRAY) { - let lenn: *node = gt.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (gt.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = gt.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", "); @@ -26294,8 +26294,8 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { return true; }; // #21: def/const global array dim cap — twin of the local arm. - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", "); @@ -26305,7 +26305,7 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { }; return false; }; - if (gt.kind == nkind.N_TSLICE) { + if (gt.kind == syntax.nkind.N_TSLICE) { emitline("\tLEAQ\t"); emitsymname(c, base.str); emitline("(SB), "); @@ -26321,11 +26321,11 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { // #60: alias-NAMED global base — chased kind; global STR keeps // the #73 cap=len carve-out (cstage isglobal && TY_STR → 0). // Runtime-unreachable until #77/#78 global DATA. - let gbt60: *tinfo = base.type_: *tinfo; - if (gbt60 != nil) { if (gbt60.kind == tykind.TY_NAMED) { - let gbu60: *tinfo = tichase(gbt60); + let gbt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (gbt60 != nil) { if (gbt60.kind == syntax.tykind.TY_NAMED) { + let gbu60: *syntax.tinfo = tichase(gbt60); if (gbu60 != nil) { - if (gbu60.kind == tykind.TY_ARRAY) { + if (gbu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(gbu60.alen: i64); emitline(", "); @@ -26333,7 +26333,7 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { emitline("\n"); return true; }; - if (gbu60.kind == tykind.TY_SLICE) { + if (gbu60.kind == syntax.tykind.TY_SLICE) { emitline("\tLEAQ\t"); emitsymname(c, base.str); emitline("(SB), "); @@ -26364,45 +26364,45 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = { // the COUNT by this same width, so it MUST match cgslice's ptr scaling // byte-for-byte (cgslice supplies the dst ptr). Cstage twin: the N_SLICE-LHS // arm in cgen.c N_ASSIGN reuses the read-path one-liner directly. -fn slicebaseesz(c: *cgen, base: *node) i32 = { +fn slicebaseesz(c: *cgen, base: *syntax.node) i32 = { if (base == nil) { return 1; }; let esz: i32 = 1; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bl: *local = localfindnode(c, base.str); if (bl != nil) { esz = elemsizeofc(c, bl.tnode); } else { - let gt: *node = letvartnode(c, base.str); + let gt: *syntax.node = letvartnode(c, base.str); if (gt != nil) { esz = elemsizeofc(c, gt); }; }; - let bt: *tinfo = base.type_: *tinfo; - if (bt != nil) { if (bt.kind == tykind.TY_NAMED) { - let bu60: *tinfo = tichase(bt); - let es60: *tinfo = tichase(bu60.sub); + let bt: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt != nil) { if (bt.kind == syntax.tykind.TY_NAMED) { + let bu60: *syntax.tinfo = tichase(bt); + let es60: *syntax.tinfo = tichase(bu60.sub); if (es60 != nil) { esz = es60.size: i32; }; };}; - } else { if (base.kind == nkind.N_DOT) { - let db: *tinfo = tichase(base.type_: *tinfo); + } else { if (base.kind == syntax.nkind.N_DOT) { + let db: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); if (db != nil) { if (db.sub != nil) { esz = db.sub.size: i32; }; }; - } else { if (base.kind == nkind.N_ARRLIT) { + } else { if (base.kind == syntax.nkind.N_ARRLIT) { esz = elemsizeofc(c, base.lhs); };};}; return esz; }; -fn cgslice(c: *cgen, n: *node) void = { - let base: *node = n.lhs; - let lo: *node = n.rhs; - let hi: *node = n.cond; +fn cgslice(c: *cgen, n: *syntax.node) void = { + let base: *syntax.node = n.lhs; + let lo: *syntax.node = n.rhs; + let hi: *syntax.node = n.cond; let baselocal: *local = nil; - let globaltn: *node = nil; + let globaltn: *syntax.node = nil; let globalname: str; globalname.ptr = nil; globalname.len = 0; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { baselocal = localfindnode(c, base.str); if (baselocal == nil) { - let gt: *node = letvartnode(c, base.str); + let gt: *syntax.node = letvartnode(c, base.str); if (gt != nil) { globaltn = gt; globalname = base.str; @@ -26414,9 +26414,9 @@ fn cgslice(c: *cgen, n: *node) void = { // tnode — resolve esz / default-hi / base-address from the checker- // stamped element tinfo on base.type_ instead. Cstage twin reads // base->type (cgen.c N_SLICE esz + bu->kind==TY_ARRAY default-hi). - let dotbu: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_DOT) { - dotbu = base.type_: *tinfo; + let dotbu: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_DOT) { + dotbu = base.type_: *syntax.tinfo; dotbu = tichase(dotbu); };}; // #31: an N_ARRLIT base (the desugared one-step `let xs:[]T=[..]` @@ -26426,8 +26426,8 @@ fn cgslice(c: *cgen, n: *node) void = { // count come NODE-wise (elemsizeofc / .rhs intlit), because wwstage // narrow-primitive tinfos are unsized (#8). Cstage twin reads base->type // (its Type IS sized). - let arrlittn: *node = nil; - if (base != nil) { if (base.kind == nkind.N_ARRLIT) { + let arrlittn: *syntax.node = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_ARRLIT) { arrlittn = base.lhs; };}; // #60 (alias arc #5): alias-NAMED N_IDENT base — the tnode reads @@ -26436,10 +26436,10 @@ fn cgslice(c: *cgen, n: *node) void = { // stamped tinfo, mirroring cstage N_SLICE's single // bu = type_chase_named(base->type) source (cmd/w6c/cgen.c). let basealias: bool = false; - let bu60: *tinfo = nil; - if (base != nil) { if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; - if (bt60 != nil) { if (bt60.kind == tykind.TY_NAMED) { + let bu60: *syntax.tinfo = nil; + if (base != nil) { if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; + if (bt60 != nil) { if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; bu60 = tichase(bt60); };}; @@ -26459,18 +26459,18 @@ fn cgslice(c: *cgen, n: *node) void = { esz = elemsizeofc(c, arrlittn); };};};}; if (bu60 != nil) { - let es60: *tinfo = tichase(bu60.sub); + let es60: *syntax.tinfo = tichase(bu60.sub); if (es60 != nil) { esz = es60.size: i32; }; }; // base address if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { isarray = true; }; + if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; if (isarray) { emitline("\tLEAQ\t"); emitoff(baselocal.off: i64); @@ -26484,10 +26484,10 @@ fn cgslice(c: *cgen, n: *node) void = { // Top-level let: [N]T → LEAQ name(SB); pointer/slice/str // → MOVQ name(SB) (the symbol holds the {ptr,len,cap} or // {ptr,len} or pointer value). - let gisarr: bool = globaltn.kind == nkind.N_TARRAY; + let gisarr: bool = globaltn.kind == syntax.nkind.N_TARRAY; // #60: alias-NAMED base — chased kind; runtime-unreachable // until #77/#78 global DATA (see cgindex twin). - if (bu60 != nil) { gisarr = bu60.kind == tykind.TY_ARRAY; }; + if (bu60 != nil) { gisarr = bu60.kind == syntax.tykind.TY_ARRAY; }; if (gisarr) { emitline("\tLEAQ\t"); emitsymname(c, globalname); @@ -26497,7 +26497,7 @@ fn cgslice(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), AX\n"); }; - } else { if (base != nil && base.kind == nkind.N_ARRLIT + } else { if (base != nil && base.kind == syntax.nkind.N_ARRLIT && arrlittn != nil) { // #31: materialise the array literal into a FRESH per-borrow // @slicescr stack slot (distinct slot per borrow — a borrow's @@ -26512,7 +26512,7 @@ fn cgslice(c: *cgen, n: *node) void = { // local borrowed past its frame is a footgun, not promoted). let cnt: i32 = 0; if (arrlittn.rhs != nil) { - if (arrlittn.rhs.kind == nkind.N_INTLIT) { + if (arrlittn.rhs.kind == syntax.nkind.N_INTLIT) { cnt = arrlittn.rhs.uval: i32; }; }; @@ -26540,12 +26540,12 @@ fn cgslice(c: *cgen, n: *node) void = { if (hi != nil) { cgexpr(c, hi); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let handled: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { - let lenn: *node = tn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (tn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = tn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -26556,21 +26556,21 @@ fn cgslice(c: *cgen, n: *node) void = { // (MOVQ $0 default-hi -> len 0 / underflow, exit 255). // Read the resolved length from the stamped array // tinfo (rule-13), mirroring cstage's bu->alen. - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); handled = true; }; }; - } else { if (tn.kind == nkind.N_TSLICE) { + } else { if (tn.kind == syntax.nkind.N_TSLICE) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); handled = true; - } else { if (tn.kind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { + } else { if (tn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); @@ -26582,13 +26582,13 @@ fn cgslice(c: *cgen, n: *node) void = { // N_SLICE hi-default reads bu uniformly: TY_ARRAY → $alen, // TY_SLICE/TY_STR → len word at +8). if (!handled && bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); handled = true; - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tMOVQ\t"); emitoff((baselocal.off + 8): i64); emitline("(BP), AX\n"); @@ -26598,9 +26598,9 @@ fn cgslice(c: *cgen, n: *node) void = { if (!handled) { emitline("\tMOVQ\t$0, AX\n"); }; } else { if (globaltn != nil) { let handled: bool = false; - if (globaltn.kind == nkind.N_TARRAY) { - let lenn: *node = globaltn.rhs; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (globaltn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = globaltn.rhs; + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { emitline("\tMOVQ\t$"); emituint(lenn.uval); emitline(", AX\n"); @@ -26609,15 +26609,15 @@ fn cgslice(c: *cgen, n: *node) void = { // #21: a def/const global array dim — non-N_INTLIT, read the // resolved length off the stamped array tinfo (rule-13), the // twin of the local arm above (cstage's bu->alen). - let abt: *tinfo = tichase(base.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(abt.alen: i64); emitline(", AX\n"); handled = true; }; }; - } else { if (globaltn.kind == nkind.N_TSLICE) { + } else { if (globaltn.kind == syntax.nkind.N_TSLICE) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -26628,13 +26628,13 @@ fn cgslice(c: *cgen, n: *node) void = { // runtime-unreachable until #77/#78 global DATA (cstage // emits LEAQ+8 for global SLICE/STR alike). if (!handled && bu60 != nil) { - if (bu60.kind == tykind.TY_ARRAY) { + if (bu60.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(bu60.alen: i64); emitline(", AX\n"); handled = true; - } else { if (bu60.kind == tykind.TY_SLICE - || bu60.kind == tykind.TY_STR) { + } else { if (bu60.kind == syntax.tykind.TY_SLICE + || bu60.kind == syntax.tykind.TY_STR) { emitline("\tLEAQ\t"); emitsymname(c, globalname); emitline("(SB), CX\n"); @@ -26643,7 +26643,7 @@ fn cgslice(c: *cgen, n: *node) void = { };}; }; if (!handled) { emitline("\tMOVQ\t$0, AX\n"); }; - } else { if (dotbu != nil && dotbu.kind == tykind.TY_ARRAY) { + } else { if (dotbu != nil && dotbu.kind == syntax.tykind.TY_ARRAY) { // #252: default-hi `s.obuf[lo:]` on a struct array-field → // element count from the field's array tinfo. Cstage twin // cgexpr_int(bu->alen) (cgen.c N_SLICE default-hi). @@ -26655,7 +26655,7 @@ fn cgslice(c: *cgen, n: *node) void = { // stashed [count]T tnode's .rhs intlit). let hc: i64 = 0i64; if (arrlittn.rhs != nil) { - if (arrlittn.rhs.kind == nkind.N_INTLIT) { + if (arrlittn.rhs.kind == syntax.nkind.N_INTLIT) { hc = arrlittn.rhs.uval: i64; }; }; @@ -26689,7 +26689,7 @@ fn cgslice(c: *cgen, n: *node) void = { }; }; -fn cgmatch(c: *cgen, n: *node) void = { +fn cgmatch(c: *cgen, n: *syntax.node) void = { // match (e) { case let v: T => stmt; ... } // // Read the tagged-union slot and dispatch by tag. Slot @@ -26697,11 +26697,11 @@ fn cgmatch(c: *cgen, n: *node) void = { // (`case let v: T =>`) get a fresh local slot loaded from // slot+8 (and slot+16 for str-typed payload). // Family C (#35): identity-cast peel — see the cgtypetest twin. - let scrut: *node = taggedidcastpeel(c, n.lhs); + let scrut: *syntax.node = taggedidcastpeel(c, n.lhs); let scrutoff: i32 = 0; - let scrutt: *node = nil; + let scrutt: *syntax.node = nil; if (scrut != nil) { - if (scrut.kind == nkind.N_IDENT) { + if (scrut.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, scrut.str); if (lc != nil) { scrutoff = lc.off; @@ -26713,7 +26713,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // saved BP as the tag (garbage). The PLAIN-tagged twin // of cstage #78 SB-resolution: LEAQ the address, copy // the box into an @match_spill slot indexed off BP. - let gtt: *node = resolvetagged(c, letvartnode(c, scrut.str)); + let gtt: *syntax.node = resolvetagged(c, letvartnode(c, scrut.str)); if (gtt != nil && !isnullabletype(gtt)) { scrutt = gtt; let gspill: i32 = matchspillsz(c, gtt); @@ -26754,15 +26754,15 @@ fn cgmatch(c: *cgen, n: *node) void = { // spill `else`, which resolves g(SB). align-DOWN to cstage // (rule 10): both stages emit TEXT $32 on the local-field // case and the same g(SB) spill on the global-field case. - let mfld: *tfield = nil; - if (scrut.kind == nkind.N_DOT && scrut.lhs != nil - && scrut.lhs.kind == nkind.N_IDENT + let mfld: *syntax.tfield = nil; + if (scrut.kind == syntax.nkind.N_DOT && scrut.lhs != nil + && scrut.lhs.kind == syntax.nkind.N_IDENT && scrut.lhs.type_ != nil) { - let bu: *tinfo = tichase(scrut.lhs.type_: *tinfo); - if (bu != nil && bu.kind == tykind.TY_STRUCT) { - let fl: *tfield = bu.fields; + let bu: *syntax.tinfo = tichase(scrut.lhs.type_: *syntax.tinfo); + if (bu != nil && bu.kind == syntax.tykind.TY_STRUCT) { + let fl: *syntax.tfield = bu.fields; for (fl != nil) { - if (streq(fl.name, scrut.str)) { + if (syntax.streq(fl.name, scrut.str)) { mfld = fl; break; }; @@ -26799,7 +26799,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // binds already read the slot from memory. Mirrors // cstage cgen.c N_MATCH. let msret: i32 = 0; - if (scrut.kind == nkind.N_CALL) { + if (scrut.kind == syntax.nkind.N_CALL) { msret = callsretsize(c, scrut); }; if (msret > 0) { @@ -26837,9 +26837,9 @@ fn cgmatch(c: *cgen, n: *node) void = { // stamped s->type, so it louds — key on scrut.type_ // to match. Surfaced by reviewer-37's `match (*p)` // probe on a 56B box. - let ms37: *tinfo = scrut.type_: *tinfo; + let ms37: *syntax.tinfo = scrut.type_: *syntax.tinfo; ms37 = tichase(ms37); - if (ms37 != nil && ms37.kind == tykind.TY_TAGGED + if (ms37 != nil && ms37.kind == syntax.tykind.TY_TAGGED && ms37.size: i32 > TUPLE_GPCAP * 8) { let m37n: str = "#37: >32B tagged match scrutinee from a non-mem-based source unwired (rule 7)\n"; os.write(2, m37n.ptr, m37n.len: u64); @@ -26848,8 +26848,8 @@ fn cgmatch(c: *cgen, n: *node) void = { // Family C catch-all (rule 7): a widening tagged // cast scrutinee has no cursor — loud. Mirrors // cstage cgmatch. - if (scrut.kind == nkind.N_CAST && ms37 != nil - && ms37.kind == tykind.TY_TAGGED + if (scrut.kind == syntax.nkind.N_CAST && ms37 != nil + && ms37.kind == syntax.tykind.TY_TAGGED && ms37.nullable == 0) { let m35m: str = "#35: tagged cast source shape unwired at match (rule 7)\n"; os.write(2, m35m.ptr, m35m.len: u64); @@ -26889,10 +26889,10 @@ fn cgmatch(c: *cgen, n: *node) void = { c.yieldbuf[c.yieldtop] = endl; c.yieldtop += 1; }; - let cs: *node = n.list; + let cs: *syntax.node = n.list; for (cs != nil) { let nxt: str = mklabel(c, "match_next"); - let pat: *node = cs.lhs; + let pat: *syntax.node = cs.lhs; let nullable: bool = isnullabletype(scrutt); // Per-arm scope: save c.locals before allocating the bind // and restore after the body runs, so the arm's bind (and @@ -26911,7 +26911,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // void arm: skip if ptr != 0. let ptr_tag: i32 = nullableptrtag(scrutt); let cur_tag: i32 = 0; - if (pat.kind == nkind.N_TPTR) { cur_tag = ptr_tag; } + if (pat.kind == syntax.nkind.N_TPTR) { cur_tag = ptr_tag; } else { if (ptr_tag == 0) { cur_tag = 1; }; }; emitline("\tMOVQ\t"); emitoff(scrutoff: i64); @@ -26933,7 +26933,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // rather than the resolved N_TTAGGED node. if (istaggedtype(c, scrutt)) { let r: i32 = -1; - let pattype: *tinfo = pat.type_: *tinfo; + let pattype: *syntax.tinfo = pat.type_: *syntax.tinfo; if (pattype != nil) { // #179: kind-agnostic dispatch on the resolved // tinfo. Cstage cg_tag_for_variant works on @@ -26943,10 +26943,10 @@ fn cgmatch(c: *cgen, n: *node) void = { // Slice arm still goes through flatslicevariantidx // (task #19 untyped-elem fallback when typeeq // can't match a (scalar | []T) shape). - if (typeisslice(pattype)) { + if (syntax.typeisslice(pattype)) { r = flatslicevariantidx(c, scrutt, pat.lhs); } else { - r = flatvariantidxt(scrutt.type_: *tinfo, pattype, false); + r = flatvariantidxt(scrutt.type_: *syntax.tinfo, pattype, false); }; }; if (r >= 0) { want = r; }; @@ -26971,7 +26971,7 @@ fn cgmatch(c: *cgen, n: *node) void = { // Bind the pointer (or skip for the // void arm, which has zero-size). The // value IS slot+0. - if (pat.kind == nkind.N_TPTR) { + if (pat.kind == syntax.nkind.N_TPTR) { let voff: i32 = localalloc(c, bn, 8, pat); emitline("\tMOVQ\t"); emitoff(scrutoff: i64); @@ -27033,8 +27033,8 @@ fn cgmatch(c: *cgen, n: *node) void = { return; }; -fn cgdot(c: *cgen, n: *node) void = { - let lhs: *node = n.lhs; +fn cgdot(c: *cgen, n: *syntax.node) void = { + let lhs: *syntax.node = n.lhs; let fld: str = n.str; // `(*p).f` read retarget: parser produces n.lhs = N_UN(STAR, // IDENT(p)). Substitute the inner IDENT as dotlhs so the @@ -27044,12 +27044,12 @@ fn cgdot(c: *cgen, n: *node) void = { // (*expr).f follow-up task pending. Enum-leaf lookup above and // chained-N_DOT branches below keep checking raw lhs since // (*p) is neither shape. - let dotlhs: *node = lhs; + let dotlhs: *syntax.node = lhs; if (dotlhs != nil) { - if (dotlhs.kind == nkind.N_UN) { - if (dotlhs.op == tkind.TK_STAR) { + if (dotlhs.kind == syntax.nkind.N_UN) { + if (dotlhs.op == syntax.tkind.TK_STAR) { if (dotlhs.lhs != nil) { - if (dotlhs.lhs.kind == nkind.N_IDENT) { + if (dotlhs.lhs.kind == syntax.nkind.N_IDENT) { dotlhs = dotlhs.lhs; }; }; @@ -27066,12 +27066,12 @@ fn cgdot(c: *cgen, n: *node) void = { let etmod: str; etname.ptr = nil; etname.len = 0; etmod.ptr = nil; etmod.len = 0; - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { etname = lhs.str; }; - if (lhs.kind == nkind.N_DOT) { + if (lhs.kind == syntax.nkind.N_DOT) { if (lhs.lhs != nil) { - if (lhs.lhs.kind == nkind.N_IDENT) { + if (lhs.lhs.kind == syntax.nkind.N_IDENT) { etname = lhs.str; etmod = lhs.lhs.str; }; @@ -27091,11 +27091,11 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (dotlhs != nil) { - if (dotlhs.kind == nkind.N_IDENT) { + if (dotlhs.kind == syntax.nkind.N_IDENT) { let nm: str = dotlhs.str; let lc: *local = localfindnode(c, nm); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; // Receiver is a NAMED alias chain — peel via aliaslookup // until tn exposes a non-N_TNAME kind (or a struct alias). // Without this, `type vs = *vt` leaves lkind == N_TNAME and @@ -27122,9 +27122,9 @@ fn cgdot(c: *cgen, n: *node) void = { // any-module heuristic. The broader cross-module same-leaf // STRUCT name-keying at the direct-struct arm below is // filed separately as #224 (not FLIP-triggered). - for (tn != nil && tn.kind == nkind.N_TNAME) { + for (tn != nil && tn.kind == syntax.nkind.N_TNAME) { if (structsamemod(c, tn.str) != nil) { break; }; - let nx: *node = aliassamemod(c, tn.str); + let nx: *syntax.node = aliassamemod(c, tn.str); if (nx == nil) { if (structlookup(c, tn.str) != nil) { break; }; nx = aliaslookup(c, tn.str); @@ -27133,14 +27133,14 @@ fn cgdot(c: *cgen, n: *node) void = { tn = nx; }; if (tn == nil) { return; }; - let lkind: nkind = tn.kind; + let lkind: syntax.nkind = tn.kind; // Pointer-to-struct: deref then field load. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; let sname: str; sname.ptr = nil; sname.len = 0; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; @@ -27154,7 +27154,7 @@ fn cgdot(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // tagged-union field via *struct: stage // the *struct in BX, then load the four // payload regs via cgloadtaggedfield. @@ -27223,7 +27223,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; // Direct struct local: field load at off+foff. - if (lkind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { // structlookupchain walks the alias chain on // miss so a transitively-aliased struct (`type // b = a; a = struct`) still resolves to the @@ -27233,7 +27233,7 @@ fn cgdot(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // tagged-union field: emit the AX=tag, // DX=word0, CX=word1[, R8=word2] load // sequence so the match / let-init / @@ -27291,17 +27291,17 @@ fn cgdot(c: *cgen, n: *node) void = { // Array pseudo-fields: `.ptr` is the array's // address (LEAQ); `.len` is the static element // count (immediate). - if (lkind == nkind.N_TARRAY) { - if (streq(fld, "ptr")) { + if (lkind == syntax.nkind.N_TARRAY) { + if (syntax.streq(fld, "ptr")) { emitline("\tLEAQ\t"); emitoff(lc.off: i64); emitline("(BP), AX\n"); return; }; - if (streq(fld, "len")) { - let lenn: *node = tn.rhs; + if (syntax.streq(fld, "len")) { + let lenn: *syntax.node = tn.rhs; let alen: i64 = 0i64; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i64; } else { // #56: def/const dim — resolve from the @@ -27310,8 +27310,8 @@ fn cgdot(c: *cgen, n: *node) void = { // node is an N_IDENT(def), not N_INTLIT, so // the literal read above defaults 0; cstage // reads the resolved bu->alen. - let abt: *tinfo = tichase(tn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(tn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i64; }; }; @@ -27330,10 +27330,10 @@ fn cgdot(c: *cgen, n: *node) void = { // sibling here, so the triple is hand-authored; base is // BP (frame, not a target reg) so ptr/len/cap order has // no clobber risk. - if (lkind == nkind.N_TTUPLE) { + if (lkind == syntax.nkind.N_TTUPLE) { let idx: i32 = fldnumidx(fld); if (idx >= 0) { - let tp: *node = tn.list; + let tp: *syntax.node = tn.list; let foff: i32 = 0; let i: i32 = 0; for (i < idx) { @@ -27347,7 +27347,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (tp != nil) { - let tpt: *node = tp.lhs; + let tpt: *syntax.node = tp.lhs; // str IS []u8, and a slice is the same 24B // {ptr,len,cap} header — load all three words // into (AX, BX, CX). #28: pre-fix the gate was @@ -27420,7 +27420,7 @@ fn cgdot(c: *cgen, n: *node) void = { // byte-id twin of cstage's fldloadop // in the N_DOT TY_TUPLE arm. let nsz: i32 = 8; - let tpti: *tinfo = tpt.type_: *tinfo; + let tpti: *syntax.tinfo = tpt.type_: *syntax.tinfo; if (tpti != nil) { nsz = tpti.size: i32; }; let op: str = tnodeloadop(c, tpt, nsz); emitline("\t"); @@ -27435,22 +27435,22 @@ fn cgdot(c: *cgen, n: *node) void = { // str/slice pseudo-fields .ptr/.len/.cap on a // direct local: load at slot+delta. let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { // Pointer to str/slice (`*[]u8`, `*str`): // deref, then load at delta within the // pointed-to header. C cgen does the same. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; - let innerkind: nkind = nkind.N_NONE; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; + let innerkind: syntax.nkind = syntax.nkind.N_NONE; if (inner != nil) { innerkind = inner.kind; }; let innerstr: bool = false; - if (innerkind == nkind.N_TNAME) { - if (streq(inner.str, "str")) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TNAME) { + if (syntax.streq(inner.str, "str")) { innerstr = true; }; }; - if (innerkind == nkind.N_TSLICE) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TSLICE) { innerstr = true; }; if (innerstr) { emitline("\tMOVQ\t"); emitoff(lc.off: i64); @@ -27475,19 +27475,19 @@ fn cgdot(c: *cgen, n: *node) void = { // `MOVQ (SB), AX` (looking up the field name as a // symbol). Mirrors cmd/w6c/cgen.c nkind.N_DOT off==0 / Sdef branch. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - let drhs: *node = deflookuprhs(c, lhs.str); + if (lhs.kind == syntax.nkind.N_IDENT) { + let drhs: *syntax.node = deflookuprhs(c, lhs.str); if (drhs != nil) { - if (drhs.kind == nkind.N_STRLIT) { + if (drhs.kind == syntax.nkind.N_STRLIT) { let bytes: str = drhs.str; - if (streq(fld, "ptr")) { + if (syntax.streq(fld, "ptr")) { let lab: str = internstrlit(c, bytes); emitline("\tLEAQ\t"); emitbytes( lab.ptr, lab.len: u64); emitline("(SB), AX\n"); return; }; - if (streq(fld, "len")) { + if (syntax.streq(fld, "len")) { emitline("\tMOVQ\t$"); emitint(bytes.len: i64); emitline(", AX\n"); @@ -27502,17 +27502,17 @@ fn cgdot(c: *cgen, n: *node) void = { // delta(CX), AX. Without this the module-qualified fallback // below would mis-emit `MOVQ (SB), AX`. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { if (isletvar(c, lhs.str)) { let isstr: bool = letvarisstr(c, lhs.str); let issl: bool = letvarisslice(c, lhs.str); if (isstr || issl) { let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; // str IS []u8: .cap is valid on a str global too, // not slice-only — mirrors cstage (#1/Phase 3, #11). - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); @@ -27534,27 +27534,27 @@ fn cgdot(c: *cgen, n: *node) void = { // reference to len). Mirror of the local-array arm above and cstage // cg_base_cap's `aimm(bu->alen)` immediate (cgen.c:1692). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - let gtn: *node = letvartnode(c, lhs.str); + if (lhs.kind == syntax.nkind.N_IDENT) { + let gtn: *syntax.node = letvartnode(c, lhs.str); if (gtn != nil) { - if (gtn.kind == nkind.N_TARRAY) { - if (streq(fld, "ptr")) { + if (gtn.kind == syntax.nkind.N_TARRAY) { + if (syntax.streq(fld, "ptr")) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), AX\n"); return; }; - if (streq(fld, "len")) { - let lenn: *node = gtn.rhs; + if (syntax.streq(fld, "len")) { + let lenn: *syntax.node = gtn.rhs; let alen: i64 = 0i64; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i64; } else { // #56: def/const dim on a let-global array — // resolve from the stamped array tinfo // (rule-13), twin of the local arm above. - let abt: *tinfo = tichase(gtn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(gtn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i64; }; }; @@ -27579,11 +27579,11 @@ fn cgdot(c: *cgen, n: *node) void = { // so both stages byte-id). `.cap` stays unmirrored — arrays have no // .cap (both checkers reject, task GAP-A.cap). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - if (streq(fld, "ptr")) { - let dtn: *node = defvartnode(c, lhs.str); + if (lhs.kind == syntax.nkind.N_IDENT) { + if (syntax.streq(fld, "ptr")) { + let dtn: *syntax.node = defvartnode(c, lhs.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { + if (dtn.kind == syntax.nkind.N_TARRAY) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), AX\n"); @@ -27591,20 +27591,20 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; }; - if (streq(fld, "len")) { - let dtn: *node = defvartnode(c, lhs.str); + if (syntax.streq(fld, "len")) { + let dtn: *syntax.node = defvartnode(c, lhs.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { - let lenn: *node = dtn.rhs; + if (dtn.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = dtn.rhs; let alen: i64 = 0i64; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i64; } else { // #56: def/const dim on a def array — // resolve from the stamped array tinfo // (rule-13), twin of the let-global arm above. - let abt: *tinfo = tichase(dtn.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(dtn.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i64; }; }; @@ -27625,16 +27625,16 @@ fn cgdot(c: *cgen, n: *node) void = { // DATA) and the module-leaf fallback mis-emitted the field index // as a symbol (`MOVQ 0(SB), AX`). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - let gtt: *node = letvartnode(c, lhs.str); - for (gtt != nil && gtt.kind == nkind.N_TNAME) { + if (lhs.kind == syntax.nkind.N_IDENT) { + let gtt: *syntax.node = letvartnode(c, lhs.str); + for (gtt != nil && gtt.kind == syntax.nkind.N_TNAME) { gtt = aliaslookup(c, gtt.str); }; if (gtt != nil) { - if (gtt.kind == nkind.N_TTUPLE) { + if (gtt.kind == syntax.nkind.N_TTUPLE) { let gidx: i32 = fldnumidx(fld); if (gidx >= 0) { - let gtp: *node = gtt.list; + let gtp: *syntax.node = gtt.list; let gfoff: i32 = 0; let gi: i32 = 0; for (gi < gidx) { @@ -27648,7 +27648,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (gtp != nil) { - let gpt: *node = gtp.lhs; + let gpt: *syntax.node = gtp.lhs; emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), CX\n"); @@ -27677,7 +27677,7 @@ fn cgdot(c: *cgen, n: *node) void = { return; }; let gnsz: i32 = 8; - let gpti: *tinfo = gpt.type_: *tinfo; + let gpti: *syntax.tinfo = gpt.type_: *syntax.tinfo; if (gpti != nil) { gnsz = gpti.size: i32; }; let gop: str = tnodeloadop(c, gpt, gnsz); emitline("\t"); @@ -27702,13 +27702,13 @@ fn cgdot(c: *cgen, n: *node) void = { // fell through to the integer-let MOVQ catch-all (reading garbage // from the wrong offset). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let si: *structinfo = letvarstructinfo(c, lhs.str); if (si == nil) { si = defvarstructinfo(c, lhs.str); }; if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), CX\n"); @@ -27780,41 +27780,41 @@ fn cgdot(c: *cgen, n: *node) void = { // Mirrors cstage cgen.c case N_DOT N_INDEX-lhs arm 1:1; #209/#211 // name-keyed→tinfo-SSoT cluster. if (lhs != nil) { - if (lhs.kind == nkind.N_INDEX) { - let idxbase: *node = lhs.lhs; - if (idxbase != nil) { if (idxbase.kind == nkind.N_IDENT) { - let elemt: *tinfo = lhs.type_: *tinfo; - let elemu: *tinfo = elemt; + if (lhs.kind == syntax.nkind.N_INDEX) { + let idxbase: *syntax.node = lhs.lhs; + if (idxbase != nil) { if (idxbase.kind == syntax.nkind.N_IDENT) { + let elemt: *syntax.tinfo = lhs.type_: *syntax.tinfo; + let elemu: *syntax.tinfo = elemt; elemu = tichase(elemu); - let st: *tinfo = nil; + let st: *syntax.tinfo = nil; let viaptr: bool = false; if (elemu != nil) { - if (elemu.kind == tykind.TY_PTR) { - let pin: *tinfo = elemu.sub; + if (elemu.kind == syntax.tykind.TY_PTR) { + let pin: *syntax.tinfo = elemu.sub; pin = tichase(pin); - if (pin != nil) { if (pin.kind == tykind.TY_STRUCT) { + if (pin != nil) { if (pin.kind == syntax.tykind.TY_STRUCT) { st = pin; viaptr = true; };}; - } else { if (elemu.kind == tykind.TY_STRUCT) { + } else { if (elemu.kind == syntax.tykind.TY_STRUCT) { st = elemu; };}; }; if (st != nil) { - let fnd: *tfield = nil; - let fwalk: *tfield = st.fields; + let fnd: *syntax.tfield = nil; + let fwalk: *syntax.tfield = st.fields; for (fwalk != nil) { - if (streq(fwalk.name, fld)) { fnd = fwalk; break; }; + if (syntax.streq(fwalk.name, fld)) { fnd = fwalk; break; }; fwalk = fwalk.tnext; }; - let bu: *tinfo = idxbase.type_: *tinfo; + let bu: *syntax.tinfo = idxbase.type_: *syntax.tinfo; bu = tichase(bu); let baseisarray: bool = false; let baseok: bool = false; if (bu != nil) { - if (bu.kind == tykind.TY_ARRAY) { baseisarray = true; baseok = true; }; - if (bu.kind == tykind.TY_SLICE) { baseok = true; }; - if (bu.kind == tykind.TY_PTR) { baseok = true; }; + if (bu.kind == syntax.tykind.TY_ARRAY) { baseisarray = true; baseok = true; }; + if (bu.kind == syntax.tykind.TY_SLICE) { baseok = true; }; + if (bu.kind == syntax.tykind.TY_PTR) { baseok = true; }; }; let lc: *local = localfindnode(c, idxbase.str); // #21 (READ twin of #11): a module-GLOBAL base makes @@ -27832,9 +27832,9 @@ fn cgdot(c: *cgen, n: *node) void = { if (isletvar(c, idxbase.str)) { isglobal = true; } else { - let dtn: *node = defvartnode(c, idxbase.str); + let dtn: *syntax.node = defvartnode(c, idxbase.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { isglobal = true; }; + if (dtn.kind == syntax.nkind.N_TARRAY) { isglobal = true; }; }; }; }; @@ -27875,8 +27875,8 @@ fn cgdot(c: *cgen, n: *node) void = { emitline("\tMOVQ\tBX, AX\n"); }; let foff: i64 = fnd.offset: i64; - let ft: *tinfo = fnd.type_; - let fu: *tinfo = ft; + let ft: *syntax.tinfo = fnd.type_; + let fu: *syntax.tinfo = ft; fu = tichase(fu); // #270-1a: an `[N]T`-typed field of an // array element (`a[i].m[j]`) — leave the @@ -27888,7 +27888,7 @@ fn cgdot(c: *cgen, n: *node) void = { // field fell to the scalar load below and loaded // its first 8 bytes as a value → garbage // base → SEGFAULT in the outer index. - if (fu != nil && fu.kind == tykind.TY_ARRAY) { + if (fu != nil && fu.kind == syntax.tykind.TY_ARRAY) { if (foff != 0) { emitline("\tADDQ\t$"); emitint(foff); @@ -27896,8 +27896,8 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - if (fu != nil && (fu.kind == tykind.TY_STR - || fu.kind == tykind.TY_SLICE)) { + if (fu != nil && (fu.kind == syntax.tykind.TY_STR + || fu.kind == syntax.tykind.TY_SLICE)) { // str/slice: the 3-word {ptr,len,cap} // slice header (#1). AX holds the // element base, so load .ptr (which @@ -27915,9 +27915,9 @@ fn cgdot(c: *cgen, n: *node) void = { emitline(", AX\n"); return; }; - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); @@ -27947,7 +27947,7 @@ fn cgdot(c: *cgen, n: *node) void = { // #114 wires it, that commit replaces this with // the LEAQ box-address emission + a >32B value // pin row. Mirrors cstage cgen.c. - if (fu != nil && fu.kind == tykind.TY_TAGGED) { + if (fu != nil && fu.kind == syntax.tykind.TY_TAGGED) { let bsz: i32 = fu.size: i32; if (bsz > TUPLE_GPCAP * 8) { let m58r: str = "#58: >32B tagged-field indexed read unreachable until #114\n"; @@ -27976,7 +27976,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; let fsz: i32 = 8; if (ft != nil) { fsz = ft.size: i32; }; - let lop: str = loadopsz(typeissigned(ft), fsz); + let lop: str = loadopsz(syntax.typeissigned(ft), fsz); emitline("\t"); emitline(lop); emitline("\t"); @@ -27998,16 +27998,16 @@ fn cgdot(c: *cgen, n: *node) void = { // scalar loadopsz. Narrow (rob Q3): tagged / nested-aggregate // fields stay LOUD. Mirrors cstage cgen.c leg-(a) arm 1:1. if (lhs != nil) { - if (lhs.kind == nkind.N_INDEX) { - let eu: *tinfo = tichase(lhs.type_: *tinfo); - if (eu != nil) { if (eu.kind == tykind.TY_TUPLE) { + if (lhs.kind == syntax.nkind.N_INDEX) { + let eu: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); + if (eu != nil) { if (eu.kind == syntax.tykind.TY_TUPLE) { let idx: i32 = fldnumidx(fld); if (idx >= 0) { // ww tuples store elements in .tupleelems // (ttupleelem chain), NOT .params (that is // fn-only). foff via tupeslot accumulation = // cstage tuple_eslot, byte-id. - let tp: *ttupleelem = eu.tupleelems; + let tp: *syntax.ttupleelem = eu.tupleelems; let foff: i32 = 0; let i: i32 = 0; for (i < idx) { @@ -28019,12 +28019,12 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; if (tp != nil) { - let ft: *tinfo = tp.type_; - let fu: *tinfo = tichase(ft); - if (fu != nil && (fu.kind == tykind.TY_TAGGED - || fu.kind == tykind.TY_STRUCT - || fu.kind == tykind.TY_TUPLE - || fu.kind == tykind.TY_ARRAY)) { + let ft: *syntax.tinfo = tp.type_; + let fu: *syntax.tinfo = tichase(ft); + if (fu != nil && (fu.kind == syntax.tykind.TY_TAGGED + || fu.kind == syntax.tykind.TY_STRUCT + || fu.kind == syntax.tykind.TY_TUPLE + || fu.kind == syntax.tykind.TY_ARRAY)) { let mt: str = "#121: aggregate/tagged tuple-element field read off an indexed base unwired\n"; os.write(2, mt.ptr, mt.len: u64); os.exit(1); @@ -28035,9 +28035,9 @@ fn cgdot(c: *cgen, n: *node) void = { os.exit(1); }; emitline("\tMOVQ\tBX, AX\n"); - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); @@ -28045,8 +28045,8 @@ fn cgdot(c: *cgen, n: *node) void = { emitline(", X0\n"); return; }; - if (fu != nil && (fu.kind == tykind.TY_STR - || fu.kind == tykind.TY_SLICE)) { + if (fu != nil && (fu.kind == syntax.tykind.TY_STR + || fu.kind == syntax.tykind.TY_SLICE)) { emitline("\tMOVQ\t"); emitdispreg((foff + 8): i64, "AX"); emitline(", BX\n"); @@ -28060,7 +28060,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; let fsz: i32 = 8; if (ft != nil) { fsz = ft.size: i32; }; - let lop: str = loadopsz(typeissigned(ft), fsz); + let lop: str = loadopsz(syntax.typeissigned(ft), fsz); emitline("\t"); emitline(lop); emitline("\t"); @@ -28079,7 +28079,7 @@ fn cgdot(c: *cgen, n: *node) void = { // prior narrow deref-store doesn't leave stale upper bytes. Same // fallback the C cgen takes when bt is NULL/tyerr. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { // `let p = mod.fn` — fn rvalue via N_DOT. Mirror of // cstage cgdot's TY_FN branch (mafn with module hint). // Without this the MOVQ leaf(SB) fallback below would @@ -28088,7 +28088,7 @@ fn cgdot(c: *cgen, n: *node) void = { // lhs.str is the explicit module hint so a same-leaf // def in another module (head of c.fnrets) can't shadow // the explicit qualifier (#17 N_DOT-arm omission audit). - let frt: *node = fnretlookupmod(c, fld, usehint(c, lhs.str)); + let frt: *syntax.node = fnretlookupmod(c, fld, usehint(c, lhs.str)); if (frt != nil) { emitline("\tLEAQ\t"); emitfnname(c, fld, usehint(c, lhs.str)); @@ -28103,9 +28103,9 @@ fn cgdot(c: *cgen, n: *node) void = { // the explicit module hint — a 3rd-module qualifier // `alpha.MSG` from gamma needs alpha (not c.curmod) // to beat a head-of-c.defs beta.MSG collision (#11). - let drhs: *node = deflookuprhsmod(c, fld, usehint(c, lhs.str)); + let drhs: *syntax.node = deflookuprhsmod(c, fld, usehint(c, lhs.str)); if (drhs != nil) { - if (drhs.kind == nkind.N_STRLIT) { + if (drhs.kind == syntax.nkind.N_STRLIT) { let bytes: str = drhs.str; let lab: str = internstrlit(c, bytes); emitline("\tLEAQ\t"); @@ -28122,7 +28122,7 @@ fn cgdot(c: *cgen, n: *node) void = { // — the non-preferring emitsymname mis-mangled `aa.v` onto // a same-leaf global. The TY_FN branch above already // threads lhs.str via emitfnname. - if (streq(mqop, "MOVQ")) { + if (syntax.streq(mqop, "MOVQ")) { emitline("\tMOVQ\t"); emitfnname(c, fld, usehint(c, lhs.str)); emitline("(SB), AX\n"); @@ -28148,11 +28148,11 @@ fn cgdot(c: *cgen, n: *node) void = { // (loading only .ptr into AX) and shuffle stale BX into AX. // Placed BEFORE the .ptr/.len fast paths so the chain wins. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { + if (lhs.kind == syntax.nkind.N_DOT) { let rootname: str = ""; let rootoff: i32 = 0; let totaloff: i32 = 0; - let leaftype: *tinfo = nil; + let leaftype: *syntax.tinfo = nil; let slicedelta: i32 = -1; let isglobal: bool = false; let ptrroot: bool = false; @@ -28195,8 +28195,8 @@ fn cgdot(c: *cgen, n: *node) void = { // ONE word (the tag): is-tests passed by tag-luck // while as/match/let consumers read stale payload // registers (ken x5c: o.r.min as size added DX). - if (typeistagged(leaftype)) { - let tlu: *tinfo = leaftype; + if (syntax.typeistagged(leaftype)) { + let tlu: *syntax.tinfo = leaftype; tlu = tichase(tlu); let ttsz: i32 = tlu.size: i32; if (viacx) { @@ -28216,7 +28216,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - if (typeisstr(leaftype) || typeisslice(leaftype)) { + if (syntax.typeisstr(leaftype) || syntax.typeisslice(leaftype)) { // str/slice leaf: load all three header words into // (AX=ptr, BX=len, CX=cap). str IS []u8 — the same 24B // {ptr,len,cap} header. #29: the str leaf used to load @@ -28259,9 +28259,9 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - if (typeisfloat(leaftype)) { + if (syntax.typeisfloat(leaftype)) { let mov: str = "MOVSD"; - if (typeisf32(leaftype)) { mov = "MOVSS"; }; + if (syntax.typeisf32(leaftype)) { mov = "MOVSS"; }; if (viacx) { if (ptrroot) { emitline("\tMOVQ\t"); @@ -28286,7 +28286,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; return; }; - let lop: str = loadopsz(typeissigned(leaftype), + let lop: str = loadopsz(syntax.typeissigned(leaftype), leaftype.slotsize: i32); if (viacx) { if (ptrroot) { @@ -28326,21 +28326,21 @@ fn cgdot(c: *cgen, n: *node) void = { // NAME behind a non-ident spine took the offset-blind cgexpr path // while cstage (type-gated) routes it to the read-resolver. { - let pbu: *tinfo = nil; - if (lhs != nil) { pbu = lhs.type_: *tinfo; }; + let pbu: *syntax.tinfo = nil; + if (lhs != nil) { pbu = lhs.type_: *syntax.tinfo; }; pbu = tichase(pbu); let pbok: bool = false; if (pbu != nil) { - if (pbu.kind == tykind.TY_SLICE - || pbu.kind == tykind.TY_STR - || pbu.kind == tykind.TY_UNTYPED_STR) { pbok = true; }; + if (pbu.kind == syntax.tykind.TY_SLICE + || pbu.kind == syntax.tykind.TY_STR + || pbu.kind == syntax.tykind.TY_UNTYPED_STR) { pbok = true; }; }; if (lhs != nil) { - if (lhs.kind == nkind.N_STRLIT) { pbok = true; }; + if (lhs.kind == syntax.nkind.N_STRLIT) { pbok = true; }; }; if (pbok) { - if (streq(fld, "ptr")) { cgexpr(c, lhs); return; }; - if (streq(fld, "len")) { + if (syntax.streq(fld, "ptr")) { cgexpr(c, lhs); return; }; + if (syntax.streq(fld, "len")) { cgexpr(c, lhs); emitline("\tMOVQ\tBX, AX\n"); return; @@ -28360,11 +28360,11 @@ fn cgdot(c: *cgen, n: *node) void = { // alone would wrongly fire. The N_STRLIT exclusion keeps // this byte-identical with cstage. #13 read-fix, sibling // of the #20 store. - if (streq(fld, "cap")) { + if (syntax.streq(fld, "cap")) { cgexpr(c, lhs); - if (lhs != nil && lhs.kind != nkind.N_STRLIT) { - if (pbu != nil && (pbu.kind == tykind.TY_SLICE - || pbu.kind == tykind.TY_STR)) { + if (lhs != nil && lhs.kind != syntax.nkind.N_STRLIT) { + if (pbu != nil && (pbu.kind == syntax.tykind.TY_SLICE + || pbu.kind == syntax.tykind.TY_STR)) { emitline("\tMOVQ\tCX, AX\n"); }; }; @@ -28381,7 +28381,7 @@ fn cgdot(c: *cgen, n: *node) void = { // itself, so reads silently get the pointer value instead of // the field. (Showed up porting w6l/pass.ww.) if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { + if (lhs.kind == syntax.nkind.N_DOT) { // #70 (#12): inner-struct layout via the stamped lhs.type_ // (peel *→struct) + tinfo.fields, replacing dotinnerstructptr's // structinfo walk. Gate is strict-equal to the deleted helper: @@ -28393,34 +28393,34 @@ fn cgdot(c: *cgen, n: *node) void = { // wanted, is a future task with its own probe. Global-root // chains stay in their pre-existing shared base-eval breakage // (filed #27), untouched here. - let croot: *node = lhs; + let croot: *syntax.node = lhs; let allptr: bool = true; - for (croot != nil && croot.kind == nkind.N_DOT) { - let ct: *tinfo = croot.type_: *tinfo; + for (croot != nil && croot.kind == syntax.nkind.N_DOT) { + let ct: *syntax.tinfo = croot.type_: *syntax.tinfo; ct = tichase(ct); let okp: bool = false; - if (ct != nil) { if (ct.kind == tykind.TY_PTR) { - let cs: *tinfo = ct.sub; + if (ct != nil) { if (ct.kind == syntax.tykind.TY_PTR) { + let cs: *syntax.tinfo = ct.sub; cs = tichase(cs); - if (cs != nil) { if (cs.kind == tykind.TY_STRUCT) { okp = true; }; }; + if (cs != nil) { if (cs.kind == syntax.tykind.TY_STRUCT) { okp = true; }; }; }; }; if (!okp) { allptr = false; }; croot = croot.lhs; }; - let it: *tinfo = nil; - if (allptr && croot != nil && croot.kind == nkind.N_IDENT && + let it: *syntax.tinfo = nil; + if (allptr && croot != nil && croot.kind == syntax.nkind.N_IDENT && localfindnode(c, croot.str) != nil) { - it = lhs.type_: *tinfo; + it = lhs.type_: *syntax.tinfo; }; it = tichase(it); - if (it != nil) { if (it.kind == tykind.TY_PTR) { - let st: *tinfo = it.sub; + if (it != nil) { if (it.kind == syntax.tykind.TY_PTR) { + let st: *syntax.tinfo = it.sub; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { - let tf: *tfield = st.fields; + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { + let tf: *syntax.tfield = st.fields; for (tf != nil) { - if (streq(tf.name, fld)) { - let ft: *tinfo = tf.type_; + if (syntax.streq(tf.name, fld)) { + let ft: *syntax.tinfo = tf.type_; cgexpr(c, lhs); // AX = ptr to inner struct // tagged leaf (#38a): AX holds the // *struct base and the tagged cursor @@ -28428,8 +28428,8 @@ fn cgdot(c: *cgen, n: *node) void = { // BX, then cgloadtaggedfield (cstage // chained-*struct twin; ken b8: the // scalar tail read stale DX as payload). - if (typeistagged(ft)) { - let plu: *tinfo = ft; + if (syntax.typeistagged(ft)) { + let plu: *syntax.tinfo = ft; plu = tichase(plu); emitline("\tMOVQ\tAX, BX\n"); cgloadtaggedfield(c, "BX", @@ -28444,7 +28444,7 @@ fn cgdot(c: *cgen, n: *node) void = { // AX) LAST. str folds onto the slice // arm (#1/Phase 3 collapse; cite cstage // cgen.c N_DOT chained *struct caseB). - if (typeisstr(ft) || typeisslice(ft)) { + if (syntax.typeisstr(ft) || syntax.typeisslice(ft)) { emitline("\tMOVQ\t"); emitdispreg((tf.offset + 8u64): i64, "AX"); emitline(", BX\n"); @@ -28457,9 +28457,9 @@ fn cgdot(c: *cgen, n: *node) void = { return; }; // f64/f32 chained field: route through X0. - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); @@ -28467,7 +28467,7 @@ fn cgdot(c: *cgen, n: *node) void = { emitline(", X0\n"); return; }; - let lop: str = loadopsz(typeissigned(ft), ft.slotsize: i32); + let lop: str = loadopsz(syntax.typeissigned(ft), ft.slotsize: i32); emitline("\t"); emitline(lop); emitline("\t"); @@ -28489,21 +28489,21 @@ fn cgdot(c: *cgen, n: *node) void = { // earlier in cgdot) to preserve byte-identical output on shapes // it already handles. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let inner: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let inner: *syntax.node = lhs.lhs; let innerfld: str = lhs.str; - if (inner != nil) { if (inner.kind == nkind.N_IDENT) { + if (inner != nil) { if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { if (lc.tnode != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = tn.kind; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = tn.kind; let outname: str; outname.ptr = nil; outname.len = 0; let isptr: bool = false; - if (lkind == nkind.N_TNAME) { outname = tn.str; }; - if (lkind == nkind.N_TPTR) { - let pe: *node = tn.lhs; - if (pe != nil) { if (pe.kind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { outname = tn.str; }; + if (lkind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = tn.lhs; + if (pe != nil) { if (pe.kind == syntax.nkind.N_TNAME) { outname = pe.str; isptr = true; };}; @@ -28513,15 +28513,15 @@ fn cgdot(c: *cgen, n: *node) void = { if (osi != nil) { let ofi: *fieldinfo = osi.fields; for (ofi != nil) { - if (streq(ofi.fname, innerfld)) { - let oft: *node = ofi.tnode; - if (oft != nil) { if (oft.kind == nkind.N_TNAME) { + if (syntax.streq(ofi.fname, innerfld)) { + let oft: *syntax.node = ofi.tnode; + if (oft != nil) { if (oft.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, oft.str) == 0) { let isi: *structinfo = structlookup(c, oft.str); if (isi != nil) { let ffi: *fieldinfo = isi.fields; for (ffi != nil) { - if (streq(ffi.fname, fld)) { + if (syntax.streq(ffi.fname, fld)) { let totoff: i32 = ofi.foff + ffi.foff; if (isstrtype(c, ffi.tnode)) { if (isptr) { @@ -28608,9 +28608,9 @@ fn cgdot(c: *cgen, n: *node) void = { // chain, turning a TYPED depth-2 read behind an index/deref spine // into a silent global read of a colliding leaf symbol. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let sbt: *tinfo = lhs.type_: *tinfo; - if (sbt == nil || sbt.kind == tykind.TY_ERR) { + if (lhs.kind == syntax.nkind.N_DOT) { + let sbt: *syntax.tinfo = lhs.type_: *syntax.tinfo; + if (sbt == nil || sbt.kind == syntax.tykind.TY_ERR) { emitline("\tMOVQ\t"); emitsymname(c, fld); emitline("(SB), AX\n"); @@ -28625,11 +28625,11 @@ fn cgdot(c: *cgen, n: *node) void = { // arm → cs≠ww). Loud; the wwstage alignment is filed as task // #37. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let pgu: *tinfo = lhs.type_: *tinfo; + if (lhs.kind == syntax.nkind.N_DOT) { + let pgu: *syntax.tinfo = lhs.type_: *syntax.tinfo; pgu = tichase(pgu); if (pgu != nil) { - if (pgu.kind == tykind.TY_PTR) { + if (pgu.kind == syntax.tykind.TY_PTR) { let mp: str = "cgdot: ptr-chained field read unwired in wwstage (task #37)\n"; os.write(2, mp.ptr, mp.len: u64); os.exit(1); @@ -28646,11 +28646,11 @@ fn cgdot(c: *cgen, n: *node) void = { // silently emitted NOTHING. Mirror of cstage cgen.c case N_DOT // read-resolver tail. { - let rdt: *tinfo = n.type_: *tinfo; - let rdu: *tinfo = rdt; + let rdt: *syntax.tinfo = n.type_: *syntax.tinfo; + let rdu: *syntax.tinfo = rdt; rdu = tichase(rdu); if (rdu != nil) { - if (rdu.kind == tykind.TY_TAGGED) { + if (rdu.kind == syntax.tykind.TY_TAGGED) { let mt: str = "read-resolver: tagged field read not wired (rule-7)\n"; os.write(2, mt.ptr, mt.len: u64); os.exit(1); @@ -28660,8 +28660,8 @@ fn cgdot(c: *cgen, n: *node) void = { // them; this loud guards the remaining non-let expr // positions (no register convention for a >8B leaf), // symmetric with cstage's read-resolver tail. - if (rdu.kind == tykind.TY_STRUCT - || rdu.kind == tykind.TY_TUPLE) { + if (rdu.kind == syntax.tykind.TY_STRUCT + || rdu.kind == syntax.tykind.TY_TUPLE) { let ma: str = "read-resolver: aggregate field read not wired (rule-7)\n"; os.write(2, ma.ptr, ma.len: u64); os.exit(1); @@ -28672,22 +28672,22 @@ fn cgdot(c: *cgen, n: *node) void = { os.write(2, mu.ptr, mu.len: u64); os.exit(1); }; - if (typeisfloat(rdt)) { + if (syntax.typeisfloat(rdt)) { let mov: str = "MOVSD"; - if (typeisf32(rdt)) { mov = "MOVSS"; }; + if (syntax.typeisf32(rdt)) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t(BX), X0\n"); return; }; - if (rdu != nil && rdu.kind == tykind.TY_ARRAY) { + if (rdu != nil && rdu.kind == syntax.tykind.TY_ARRAY) { // `[N]T` leaf: leave the field ADDRESS — a base for // an outer index, never a value (#270-1a semantics). emitline("\tMOVQ\tBX, AX\n"); return; }; - if (rdu != nil && (rdu.kind == tykind.TY_STR - || rdu.kind == tykind.TY_SLICE)) { + if (rdu != nil && (rdu.kind == syntax.tykind.TY_STR + || rdu.kind == syntax.tykind.TY_SLICE)) { // str IS []u8 — 3-word {ptr,len,cap} into (AX, BX, // CX). BX is the place base, so load .len (which // targets BX) LAST. @@ -28698,7 +28698,7 @@ fn cgdot(c: *cgen, n: *node) void = { }; let lop: str = "MOVQ"; if (rdt != nil) { - lop = loadopsz(typeissigned(rdt), rdt.slotsize: i32); + lop = loadopsz(syntax.typeissigned(rdt), rdt.slotsize: i32); }; emitline("\t"); emitline(lop); @@ -28707,18 +28707,18 @@ fn cgdot(c: *cgen, n: *node) void = { }; }; -fn cgun(c: *cgen, n: *node) void = { +fn cgun(c: *cgen, n: *syntax.node) void = { // Match C cgen ordering: evaluate operand first (load into AX), // then apply the unary op. AMP / STAR override AX with the // address / deref. The wasted load before AMP keeps our asm // byte-identical to the C version. let fk: i32 = 0; if (n.lhs != nil) { - let lt: *tinfo = n.lhs.type_: *tinfo; - if (typeisf32(lt)) { fk = 1; } - else { if (typeisfloat(lt)) { fk = 2; }; }; + let lt: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; + if (syntax.typeisf32(lt)) { fk = 1; } + else { if (syntax.typeisfloat(lt)) { fk = 2; }; }; }; - if (n.op == tkind.TK_MINUS && fk != 0) { + if (n.op == syntax.tkind.TK_MINUS && fk != 0) { // Float negate: X0 = 0 - X0. Stash orig, load 0.0, subtract. // Zero bit pattern equals 0.0 for both f32 and f64 so we // reuse the integer-zero materialisation. @@ -28740,10 +28740,10 @@ fn cgun(c: *cgen, n: *node) void = { // Address-of has its own evaluation strategy — we want the address // of the operand, not its value. Special-case here so `&arr[i]` // doesn't compile the value load and then discard it. - if (n.op == tkind.TK_AMP) { - let opnd: *node = n.lhs; + if (n.op == syntax.tkind.TK_AMP) { + let opnd: *syntax.node = n.lhs; if (opnd != nil) { - if (opnd.kind == nkind.N_IDENT) { + if (opnd.kind == syntax.nkind.N_IDENT) { let nm: str = opnd.str; let off: i32 = localfind(c, nm); if (off != 0) { @@ -28809,16 +28809,16 @@ fn cgun(c: *cgen, n: *node) void = { // only; spine walker aborts on the *T base. Load // p into AX, then LEAQ field_off(AX), AX. Mirror // of the read at cgdot 1144. - if (opnd.kind == nkind.N_DOT) { + if (opnd.kind == syntax.nkind.N_DOT) { // Shape 1 chained: depth-≥2 via dotchainresolve. // `opnd.lhs.kind == N_DOT` gates the helper at // nsteps ≥ 2 (matches the read path's gate). if (opnd.lhs != nil) { - if (opnd.lhs.kind == nkind.N_DOT) { + if (opnd.lhs.kind == syntax.nkind.N_DOT) { let rootname: str = ""; let rootoff: i32 = 0; let totaloff: i32 = 0; - let leaftype: *tinfo = nil; + let leaftype: *syntax.tinfo = nil; let slicedelta: i32 = -1; let isglobal: bool = false; let ptrroot: bool = false; @@ -28854,13 +28854,13 @@ fn cgun(c: *cgen, n: *node) void = { // the base's tnode to pick value-struct vs slice/ // str pseudo vs pointer-field. if (opnd.lhs != nil) { - if (opnd.lhs.kind == nkind.N_IDENT) { + if (opnd.lhs.kind == syntax.nkind.N_IDENT) { let basenm: str = opnd.lhs.str; let fld: str = opnd.str; let lc: *local = localfindnode(c, basenm); if (lc != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = nkind.N_NONE; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = syntax.nkind.N_NONE; if (tn != nil) { lkind = tn.kind; }; // Pointer-field: &p.f where p:*T. // #102 (ken B6-c3 re-attribution): an @@ -28873,19 +28873,19 @@ fn cgun(c: *cgen, n: *node) void = { // chain; plain rows short-circuit at its // structlookup head, byte-id by // construction. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; let sname: str; sname.ptr = nil; sname.len = 0; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; if (sname.len > 0) { let si: *structinfo = structlookupchain(c, inner); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tMOVQ\t"); emitoff(lc.off: i64); emitline("(BP), AX\n"); @@ -28905,12 +28905,12 @@ fn cgun(c: *cgen, n: *node) void = { // &p.f gate — an alias-NAMED value // struct fell to the generic route. // Same chase, same construction. - if (lkind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { let si: *structinfo = structlookupchain(c, tn); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tLEAQ\t"); emitoff((lc.off + fi.foff): i64); emitline("(BP), AX\n"); @@ -28924,14 +28924,14 @@ fn cgun(c: *cgen, n: *node) void = { // &s.ptr / &s.len / &s.cap. Delta is // 0/8/16 — matches the spine walker. let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { let isslor: bool = false; - if (lkind == nkind.N_TSLICE) { isslor = true; }; - if (lkind == nkind.N_TNAME) { - if (streq(tn.str, "str")) { isslor = true; }; + if (lkind == syntax.nkind.N_TSLICE) { isslor = true; }; + if (lkind == syntax.nkind.N_TNAME) { + if (syntax.streq(tn.str, "str")) { isslor = true; }; }; if (isslor) { emitline("\tLEAQ\t"); @@ -28948,7 +28948,7 @@ fn cgun(c: *cgen, n: *node) void = { if (gsi != nil) { let fi: *fieldinfo = gsi.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { emitline("\tLEAQ\t"); emitsymname(c, basenm); emitline("(SB), CX\n"); @@ -28964,11 +28964,11 @@ fn cgun(c: *cgen, n: *node) void = { let issl: bool = letvarisslice(c, basenm); if (isstr || issl) { let gdelta: i32 = -1; - if (streq(fld, "ptr")) { gdelta = 0; }; - if (streq(fld, "len")) { gdelta = 8; }; + if (syntax.streq(fld, "ptr")) { gdelta = 0; }; + if (syntax.streq(fld, "len")) { gdelta = 8; }; // str IS []u8: &str.cap is valid too, not slice-only // — mirrors cstage (#1/Phase 3, #11). - if (streq(fld, "cap")) { gdelta = 16; }; + if (syntax.streq(fld, "cap")) { gdelta = 16; }; if (gdelta >= 0) { emitline("\tLEAQ\t"); emitsymname(c, basenm); @@ -28992,7 +28992,7 @@ fn cgun(c: *cgen, n: *node) void = { // via emitfnname (fn address), mirroring that read // path's TY_FN branch. if (opnd.lhs != nil) { - if (opnd.lhs.kind == nkind.N_IDENT) { + if (opnd.lhs.kind == syntax.nkind.N_IDENT) { let basenm: str = opnd.lhs.str; if (localfindnode(c, basenm) == nil) { // A def base (`&Pdef.field`) is NOT a module @@ -29008,7 +29008,7 @@ fn cgun(c: *cgen, n: *node) void = { // pre-#149 gap (file as #150-family). if (!isletvar(c, basenm) && !deflookup(c, basenm)) { let fld: str = opnd.str; - let frt: *node = fnretlookupmod(c, fld, usehint(c, basenm)); + let frt: *syntax.node = fnretlookupmod(c, fld, usehint(c, basenm)); if (frt != nil) { emitline("\tLEAQ\t"); emitfnname(c, fld, usehint(c, basenm)); @@ -29043,10 +29043,10 @@ fn cgun(c: *cgen, n: *node) void = { os.write(2, mam.ptr, mam.len: u64); os.exit(1); }; - if (opnd.kind == nkind.N_INDEX) { + if (opnd.kind == syntax.nkind.N_INDEX) { // &base[i] = base + i*esz, no dereference. - let base: *node = opnd.lhs; - let idx: *node = opnd.rhs; + let base: *syntax.node = opnd.lhs; + let idx: *syntax.node = opnd.rhs; let esz: i32 = 8; let isglobalarr: bool = false; let isglobalptr: bool = false; @@ -29055,13 +29055,13 @@ fn cgun(c: *cgen, n: *node) void = { let baselocal: *local = nil; let isarr: bool = false; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { baselocal = localfindnode(c, base.str); if (baselocal != nil) { esz = elemsizeofc(c, baselocal.tnode); - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { isarr = true; }; + if (tn.kind == syntax.nkind.N_TARRAY) { isarr = true; }; }; } else { // #11: addr-of twin of the #10 cgindex read @@ -29076,7 +29076,7 @@ fn cgun(c: *cgen, n: *node) void = { // esz=bu->sub->size, base is_arr?LEAQ:MOVQ // name(SB) (a str/slice's .ptr IS the symbol's // first word). Align UP, mirroring cgindex. - let tn: *node = letvartnode(c, base.str); + let tn: *syntax.node = letvartnode(c, base.str); // #94: a def-array base resolves via // defvartnode (the def-side sister), the same // fallback cgindex's read-side already takes @@ -29090,7 +29090,7 @@ fn cgun(c: *cgen, n: *node) void = { if (tn != nil) { globalname = base.str; esz = elemsizeofc(c, tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; @@ -29106,26 +29106,26 @@ fn cgun(c: *cgen, n: *node) void = { // classifies off type_chase_named uniformly // (cmd/w6c/cgen.c:4172-4188). TY_NAMED gate // keeps non-alias rows byte-id by construction. - let bt82: *tinfo = base.type_: *tinfo; + let bt82: *syntax.tinfo = base.type_: *syntax.tinfo; let basealias82: bool = false; if (bt82 != nil) { - if (bt82.kind == tykind.TY_NAMED) { basealias82 = true; }; + if (bt82.kind == syntax.tykind.TY_NAMED) { basealias82 = true; }; }; if (basealias82) { - let bu82: *tinfo = tichase(bt82); + let bu82: *syntax.tinfo = tichase(bt82); if (bu82 != nil) { if (baselocal != nil) { - isarr = bu82.kind == tykind.TY_ARRAY; + isarr = bu82.kind == syntax.tykind.TY_ARRAY; }; if (isglobalarr || isglobalptr) { - isglobalarr = bu82.kind == tykind.TY_ARRAY; + isglobalarr = bu82.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; }; - } else { if (base.kind == nkind.N_DOT - || (base.kind == nkind.N_UN - && base.op == tkind.TK_STAR)) { + } else { if (base.kind == syntax.nkind.N_DOT + || (base.kind == syntax.nkind.N_UN + && base.op == syntax.tkind.TK_STAR)) { // `&p.ptr[i]`: stride is the checker-stamped // element tinfo's natural size, mirroring // cgindex's N_DOT arm so &p.ptr[i] and @@ -29134,7 +29134,7 @@ fn cgun(c: *cgen, n: *node) void = { // N_UN deref base (`&(*p)[i]`, #61 C): same // stamped source; cstage reads base->type // uniformly. - let dt: *tinfo = opnd.type_: *tinfo; + let dt: *syntax.tinfo = opnd.type_: *syntax.tinfo; if (dt != nil) { esz = dt.size: i32; }; };}; }; @@ -29200,8 +29200,8 @@ fn cgun(c: *cgen, n: *node) void = { return; }; cgexpr(c, n.lhs); - if (n.op == tkind.TK_MINUS) { emitline("\tNEGQ\tAX\n"); return; }; - if (n.op == tkind.TK_TILDE) { + if (n.op == syntax.tkind.TK_MINUS) { emitline("\tNEGQ\tAX\n"); return; }; + if (n.op == syntax.tkind.TK_TILDE) { emitline("\tNOTQ\tAX\n"); // NOTQ inverts the whole 64-bit register; clamp narrow // unsigned results to type width so subsequent 64-bit @@ -29216,7 +29216,7 @@ fn cgun(c: *cgen, n: *node) void = { }; return; }; - if (n.op == tkind.TK_STAR) { + if (n.op == syntax.tkind.TK_STAR) { // #185: deref of *fn — the pointer value IS the fn address. // cgexpr(n.lhs) left AX = fn-addr; a generic MOVQ (AX),AX // would load the first instruction word and a subsequent @@ -29227,10 +29227,10 @@ fn cgun(c: *cgen, n: *node) void = { // `*[N]T` leaves AX = p's value. The scalar load below // pulled a[0]'s VALUE and `(*p)[i]` then dereferenced it as // the index base — a wild pointer, SIGSEGV on both stages. - let rti: *tinfo = n.type_: *tinfo; + let rti: *syntax.tinfo = n.type_: *syntax.tinfo; rti = tichase(rti); - if (rti != nil && rti.kind == tykind.TY_FN) { return; }; - if (rti != nil && rti.kind == tykind.TY_ARRAY) { return; }; + if (rti != nil && rti.kind == syntax.tykind.TY_FN) { return; }; + if (rti != nil && rti.kind == syntax.tykind.TY_ARRAY) { return; }; // Family C (#35/#46): a tagged box behind *p joins the // mem-based class at ANY size (taggedmemread) — AX = p's // value IS the box address. The scalar load below pulled @@ -29238,7 +29238,7 @@ fn cgun(c: *cgen, n: *node) void = { // garbage payload words — silent-wrong both stages (ken // f35/D3a/D3b). The nullable one-word fold stays a scalar // deref. Mirrors cstage N_UN TK_STAR. - if (rti != nil && rti.kind == tykind.TY_TAGGED) { + if (rti != nil && rti.kind == syntax.tykind.TY_TAGGED) { if (rti.nullable == 0 && rti.size: i32 > 8) { return; }; }; // f64/f32 result rides X0 (SSE), not AX — an integer MOVQ @@ -29271,7 +29271,7 @@ fn cgun(c: *cgen, n: *node) void = { }; return; }; - if (n.op == tkind.TK_NOT) { + if (n.op == syntax.tkind.TK_NOT) { let t: str = mklabel(c, "tt"); let e: str = mklabel(c, "te"); emitline("\tCMPQ\t$0, AX\n"); @@ -29292,8 +29292,8 @@ fn cgun(c: *cgen, n: *node) void = { // module-global str (#154 let_islet branch) or BP+off for a local; a // non-ident evals via cgexpr (AX=ptr, BX=len) and pushes BX then AX. Push // order is len then ptr so the matching POPQ pops ptr first. -fn cgstreqpush(c: *cgen, op: *node) void = { - if (op.kind == nkind.N_IDENT) { +fn cgstreqpush(c: *cgen, op: *syntax.node) void = { + if (op.kind == syntax.nkind.N_IDENT) { let nm: str = op.str; let lc: *local = localfindnode(c, nm); if (lc == nil && isletvar(c, nm)) { @@ -29323,17 +29323,17 @@ fn cgstreqpush(c: *cgen, op: *node) void = { emitline("\tPUSHQ\tAX\n"); }; -fn cgbin(c: *cgen, n: *node) void = { +fn cgbin(c: *cgen, n: *syntax.node) void = { // Short-circuit `&&` / `||`. Operands are bool (0/1); the type // checker enforces it. Eval LHS into AX, branch over RHS on the // short-circuit polarity, otherwise eval RHS into AX. The // surviving AX is the result. Must precede any eager-eval path // below — `if (p != nil && p.x > 0)` would segfault on a nil // deref otherwise. Byte-identical to cmd/w6c/cgen.c N_BIN. - if (n.op == tkind.TK_AND || n.op == tkind.TK_OR) { + if (n.op == syntax.tkind.TK_AND || n.op == syntax.tkind.TK_OR) { let prefix: str = "andend"; let jshrt: str = "JE"; - if (n.op == tkind.TK_OR) { prefix = "orend"; jshrt = "JNE"; }; + if (n.op == syntax.tkind.TK_OR) { prefix = "orend"; jshrt = "JNE"; }; let end: str = mklabel(c, prefix); cgexpr(c, n.lhs); emitline("\tCMPQ\t$0, AX\n"); @@ -29352,15 +29352,15 @@ fn cgbin(c: *cgen, n: *node) void = { // for !=. The gate reads the checker stamp (typeisstr) exactly like // cstage node_isstr. Byte-identical to cstage cbinop (cmd/w6c/ // cgen.c:4564-4623). cstage was fixed by #154; this is its mirror. - if ((n.op == tkind.TK_EQ || n.op == tkind.TK_NEQ) + if ((n.op == syntax.tkind.TK_EQ || n.op == syntax.tkind.TK_NEQ) && n.lhs != nil && n.rhs != nil - && typeisstr(n.lhs.type_: *tinfo) - && typeisstr(n.rhs.type_: *tinfo)) { + && syntax.typeisstr(n.lhs.type_: *syntax.tinfo) + && syntax.typeisstr(n.rhs.type_: *syntax.tinfo)) { cgstreqpush(c, n.rhs); cgstreqpush(c, n.lhs); emitline("\tPOPQ\tDI\n\tPOPQ\tSI\n\tPOPQ\tDX\n\tPOPQ\tCX\n"); emitline("\tCALL\trt_streq(SB)\n"); - if (n.op == tkind.TK_NEQ) { emitline("\tXORQ\t$1, AX\n"); }; + if (n.op == syntax.tkind.TK_NEQ) { emitline("\tXORQ\t$1, AX\n"); }; return; }; @@ -29380,25 +29380,25 @@ fn cgbin(c: *cgen, n: *node) void = { // are therefore dead and removed. let lfk: i32 = 0; if (n.lhs != nil) { - let llt: *tinfo = n.lhs.type_: *tinfo; - if (typeisf32(llt)) { lfk = 1; } - else { if (typeisfloat(llt)) { lfk = 2; }; }; + let llt: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; + if (syntax.typeisf32(llt)) { lfk = 1; } + else { if (syntax.typeisfloat(llt)) { lfk = 2; }; }; }; let rfk: i32 = 0; if (n.rhs != nil) { - let rrt: *tinfo = n.rhs.type_: *tinfo; - if (typeisf32(rrt)) { rfk = 1; } - else { if (typeisfloat(rrt)) { rfk = 2; }; }; + let rrt: *syntax.tinfo = n.rhs.type_: *syntax.tinfo; + if (syntax.typeisf32(rrt)) { rfk = 1; } + else { if (syntax.typeisfloat(rrt)) { rfk = 2; }; }; }; let fk: i32 = lfk; if (fk == 0) { fk = rfk; }; if (fk != 0) { let mov: str = "MOVSD"; if (fk == 1) { mov = "MOVSS"; }; - if (n.op == tkind.TK_PLUS || - n.op == tkind.TK_MINUS || - n.op == tkind.TK_STAR || - n.op == tkind.TK_SLASH) { + if (n.op == syntax.tkind.TK_PLUS || + n.op == syntax.tkind.TK_MINUS || + n.op == syntax.tkind.TK_STAR || + n.op == syntax.tkind.TK_SLASH) { cgexpr(c, n.rhs); emitline("\tSUBQ\t$8, SP\n"); emitline("\t"); emitline(mov); emitline("\tX0, (SP)\n"); @@ -29406,25 +29406,25 @@ fn cgbin(c: *cgen, n: *node) void = { emitline("\t"); emitline(mov); emitline("\t(SP), X1\n"); emitline("\tADDQ\t$8, SP\n"); let op: str = "ADDSD"; - if (n.op == tkind.TK_MINUS) { op = "SUBSD"; }; - if (n.op == tkind.TK_STAR) { op = "MULSD"; }; - if (n.op == tkind.TK_SLASH) { op = "DIVSD"; }; + if (n.op == syntax.tkind.TK_MINUS) { op = "SUBSD"; }; + if (n.op == syntax.tkind.TK_STAR) { op = "MULSD"; }; + if (n.op == syntax.tkind.TK_SLASH) { op = "DIVSD"; }; if (fk == 1) { - if (n.op == tkind.TK_PLUS) { op = "ADDSS"; }; - if (n.op == tkind.TK_MINUS) { op = "SUBSS"; }; - if (n.op == tkind.TK_STAR) { op = "MULSS"; }; - if (n.op == tkind.TK_SLASH) { op = "DIVSS"; }; + if (n.op == syntax.tkind.TK_PLUS) { op = "ADDSS"; }; + if (n.op == syntax.tkind.TK_MINUS) { op = "SUBSS"; }; + if (n.op == syntax.tkind.TK_STAR) { op = "MULSS"; }; + if (n.op == syntax.tkind.TK_SLASH) { op = "DIVSS"; }; }; emitline("\t"); emitline(op); emitline("\tX1, X0\n"); return; }; let isfcmp: bool = false; - if (n.op == tkind.TK_EQ) { isfcmp = true; }; - if (n.op == tkind.TK_NEQ) { isfcmp = true; }; - if (n.op == tkind.TK_LT) { isfcmp = true; }; - if (n.op == tkind.TK_LE) { isfcmp = true; }; - if (n.op == tkind.TK_GT) { isfcmp = true; }; - if (n.op == tkind.TK_GE) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_EQ) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_NEQ) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_LT) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_LE) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_GT) { isfcmp = true; }; + if (n.op == syntax.tkind.TK_GE) { isfcmp = true; }; if (isfcmp) { cgexpr(c, n.rhs); emitline("\tSUBQ\t$8, SP\n"); @@ -29444,7 +29444,7 @@ fn cgbin(c: *cgen, n: *node) void = { // unordered never gives, so they are ALREADY NaN-correct // and stay byte-identical to the pre-#97 single-template // arm — no redundant PF guard. - if (n.op == tkind.TK_NEQ) { + if (n.op == syntax.tkind.TK_NEQ) { // not-equal OR unordered -> true let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); @@ -29457,12 +29457,12 @@ fn cgbin(c: *cgen, n: *node) void = { emitlabel(e); return; }; - if (n.op == tkind.TK_EQ || n.op == tkind.TK_LT || - n.op == tkind.TK_LE) { + if (n.op == syntax.tkind.TK_EQ || n.op == syntax.tkind.TK_LT || + n.op == syntax.tkind.TK_LE) { // unordered -> false; otherwise the ordered Jcc decides. let jcc: str = "JE"; - if (n.op == tkind.TK_LT) { jcc = "JB"; }; - if (n.op == tkind.TK_LE) { jcc = "JBE"; }; + if (n.op == syntax.tkind.TK_LT) { jcc = "JB"; }; + if (n.op == syntax.tkind.TK_LE) { jcc = "JBE"; }; let fl: str = mklabel(c, "cf"); let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); @@ -29479,7 +29479,7 @@ fn cgbin(c: *cgen, n: *node) void = { // `>`/`>=`: JA/JAE already reject unordered (CF=1), so // keep the pre-#97 single-template shape verbatim. let jcc: str = "JA"; - if (n.op == tkind.TK_GE) { jcc = "JAE"; }; + if (n.op == syntax.tkind.TK_GE) { jcc = "JAE"; }; let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); emitline("\t"); emitline(jcc); emitline("\t"); emitline(t); emitline("\n"); @@ -29497,10 +29497,10 @@ fn cgbin(c: *cgen, n: *node) void = { emitline("\tPUSHQ\tAX\n"); cgexpr(c, n.lhs); emitline("\tPOPQ\tBX\n"); - if (n.op == tkind.TK_PLUS) { emitline("\tADDQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_MINUS) { emitline("\tSUBQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_STAR) { emitline("\tIMULQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_SLASH) { + if (n.op == syntax.tkind.TK_PLUS) { emitline("\tADDQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_MINUS) { emitline("\tSUBQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_STAR) { emitline("\tIMULQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_SLASH) { // Signed IDIV reads dividend from RDX:RAX; CQO sign-extends // RAX. Zero-filling DX would treat a negative RAX as a huge // positive 128-bit value. Unsigned DIV needs RDX zero. @@ -29513,7 +29513,7 @@ fn cgbin(c: *cgen, n: *node) void = { }; return; }; - if (n.op == tkind.TK_PERCENT) { + if (n.op == syntax.tkind.TK_PERCENT) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tBX\n"); @@ -29524,15 +29524,15 @@ fn cgbin(c: *cgen, n: *node) void = { emitline("\tMOVQ\tDX, AX\n"); return; }; - if (n.op == tkind.TK_AMP) { emitline("\tANDQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_PIPE) { emitline("\tORQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_CARET) { emitline("\tXORQ\tBX, AX\n"); return; }; - if (n.op == tkind.TK_LSHIFT) { + if (n.op == syntax.tkind.TK_AMP) { emitline("\tANDQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_PIPE) { emitline("\tORQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_CARET) { emitline("\tXORQ\tBX, AX\n"); return; }; + if (n.op == syntax.tkind.TK_LSHIFT) { emitline("\tMOVQ\tBX, CX\n"); emitline("\tSHLQ\tCX, AX\n"); return; }; - if (n.op == tkind.TK_RSHIFT) { + if (n.op == syntax.tkind.TK_RSHIFT) { // #136: signed RSHIFT → SAR (arithmetic, sign-extends MSB); // unsigned → SHR (logical, zero-fill). `unsignd` derived above // at cgbin head from nodeisunsigned(lhs) || nodeisunsigned(rhs). @@ -29548,12 +29548,12 @@ fn cgbin(c: *cgen, n: *node) void = { // materialise 0/1 in AX. Same shape as the C cgen. let iscmp: bool = false; let jcc: str = ""; - if (n.op == tkind.TK_EQ) { iscmp = true; jcc = "JE"; }; - if (n.op == tkind.TK_NEQ) { iscmp = true; jcc = "JNE"; }; - if (n.op == tkind.TK_LT) { iscmp = true; if (unsignd) { jcc = "JB"; } else { jcc = "JL"; }; }; - if (n.op == tkind.TK_LE) { iscmp = true; if (unsignd) { jcc = "JBE"; } else { jcc = "JLE"; }; }; - if (n.op == tkind.TK_GT) { iscmp = true; if (unsignd) { jcc = "JA"; } else { jcc = "JG"; }; }; - if (n.op == tkind.TK_GE) { iscmp = true; if (unsignd) { jcc = "JAE"; } else { jcc = "JGE"; }; }; + if (n.op == syntax.tkind.TK_EQ) { iscmp = true; jcc = "JE"; }; + if (n.op == syntax.tkind.TK_NEQ) { iscmp = true; jcc = "JNE"; }; + if (n.op == syntax.tkind.TK_LT) { iscmp = true; if (unsignd) { jcc = "JB"; } else { jcc = "JL"; }; }; + if (n.op == syntax.tkind.TK_LE) { iscmp = true; if (unsignd) { jcc = "JBE"; } else { jcc = "JLE"; }; }; + if (n.op == syntax.tkind.TK_GT) { iscmp = true; if (unsignd) { jcc = "JA"; } else { jcc = "JG"; }; }; + if (n.op == syntax.tkind.TK_GE) { iscmp = true; if (unsignd) { jcc = "JAE"; } else { jcc = "JGE"; }; }; if (iscmp) { let t: str = mklabel(c, "ct"); let e: str = mklabel(c, "ce"); @@ -29582,11 +29582,11 @@ fn cgbin(c: *cgen, n: *node) void = { // DX=0) or the success variant (tag=0, DX=ptr) after the // value-init stores complete. Callers wrap with `!` / `?` to // consume the union. -fn cgalloc(c: *cgen, n: *node) void = { - let v: *node = n.list; +fn cgalloc(c: *cgen, n: *syntax.node) void = { + let v: *syntax.node = n.list; let sz: i32 = 8; let si: *structinfo = nil; - if (v.kind == nkind.N_STRUCTLIT) { + if (v.kind == syntax.nkind.N_STRUCTLIT) { // #26: chase the alias chain on the literal's type ref so an // alias head (`type pt = point; alloc(pt{...})`) resolves to // the underlying struct's layout — name-keyed structlookup on @@ -29612,16 +29612,16 @@ fn cgalloc(c: *cgen, n: *node) void = { emitline("\tJMP\t"); emitline(donel); emitline("\n"); emitlabel(okl); emitline("\tPUSHQ\tAX\n"); - if (v.kind == nkind.N_STRUCTLIT) { + if (v.kind == syntax.nkind.N_STRUCTLIT) { if (si != nil) { - let f: *node = v.list; + let f: *syntax.node = v.list; for (f != nil) { - if (f.kind == nkind.N_FIELD) { + if (f.kind == syntax.nkind.N_FIELD) { let fname: str = f.str; let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fname)) { + if (syntax.streq(fn_, fname)) { cgexpr(c, f.lhs); // alloc(T{ fval = v }) for f64/f32 field: cgexpr left // the value in X0, not AX — route the store via MOVSD/MOVSS. @@ -29776,8 +29776,8 @@ fn cgappendslot(c: *cgen, direct: bool, off: i32, scr: i32, esz: i32, dst: str) // ; POPQ AX // ; MOV* AX, (BX) ; store (MOVB / MOVQ) // nkind.N_SPREAD wraps the same body in a counted loop over items.len. -fn cgappend(c: *cgen, n: *node) void = { - let sn: *node = n.list; +fn cgappend(c: *cgen, n: *syntax.node) void = { + let sn: *syntax.node = n.list; if (sn == nil) { return; }; // FA1 (#15): the old `sn.kind != N_IDENT → return` and // `snlocal == nil → return` gates were SILENT zero-emission @@ -29788,7 +29788,7 @@ fn cgappend(c: *cgen, n: *node) void = { let sndirect: bool = false; let sn_off: i32 = 0; let snlocal: *local = nil; - if (sn.kind == nkind.N_IDENT) { + if (sn.kind == syntax.nkind.N_IDENT) { snlocal = localfindnode(c, sn.str); if (snlocal != nil) { sndirect = true; @@ -29796,8 +29796,8 @@ fn cgappend(c: *cgen, n: *node) void = { }; }; let esz: i32 = 0; - let etnode: *node = nil; - let sti: *tinfo = nil; + let etnode: *syntax.node = nil; + let sti: *syntax.tinfo = nil; if (sndirect) { // #34: esz off the DECLARED slice local's stamped tnode via // elemsizeofc — bare elemsizeof returns the 8 sentinel for a @@ -29806,18 +29806,18 @@ fn cgappend(c: *cgen, n: *node) void = { // the slot index vs cstage's su->sub->size. esz = elemsizeofc(c, snlocal.tnode); if (snlocal.tnode != nil) { - let stk: nkind = snlocal.tnode.kind; - if (stk == nkind.N_TSLICE) { etnode = snlocal.tnode.lhs; }; - if (stk == nkind.N_TARRAY) { etnode = snlocal.tnode.lhs; }; - if (stk == nkind.N_TPTR) { etnode = snlocal.tnode.lhs; }; - sti = snlocal.tnode.type_: *tinfo; + let stk: syntax.nkind = snlocal.tnode.kind; + if (stk == syntax.nkind.N_TSLICE) { etnode = snlocal.tnode.lhs; }; + if (stk == syntax.nkind.N_TARRAY) { etnode = snlocal.tnode.lhs; }; + if (stk == syntax.nkind.N_TPTR) { etnode = snlocal.tnode.lhs; }; + sti = snlocal.tnode.type_: *syntax.tinfo; }; } else { // FA1: `*p` has no declared tnode — key esz/element kind off // the checker-STAMPED target tinfo (#209/#211 discipline), the // same source cstage reads (sn->type → su->sub->size). - sti = sn.type_: *tinfo; - let fsti: *tinfo = sti; + sti = sn.type_: *syntax.tinfo; + let fsti: *syntax.tinfo = sti; fsti = tichase(fsti); if (fsti != nil && fsti.sub != nil) { esz = fsti.sub.size: i32; }; if (esz <= 0) { @@ -29834,17 +29834,17 @@ fn cgappend(c: *cgen, n: *node) void = { // Mirrors cstage cgen.c's append arm + the #270/#12/#20 // array-literal element dispatch (cgarrlitfillbp). sti = tichase(sti); - let esubti: *tinfo = nil; + let esubti: *syntax.tinfo = nil; if (sti != nil) { esubti = sti.sub; }; // FA1: pre-peel handle — the indirect struct-lit fill keys its // structinfo off the NAMED element tinfo's name (the same leaf // structlookupchain resolves from the declared tnode). - let esubnamed: *tinfo = esubti; + let esubnamed: *syntax.tinfo = esubti; esubti = tichase(esubti); - let elstr: bool = esubti != nil && esubti.kind == tykind.TY_STR; - let elslice: bool = esubti != nil && esubti.kind == tykind.TY_SLICE; - let eltagged: bool = esubti != nil && esubti.kind == tykind.TY_TAGGED; - let elstruct: bool = esubti != nil && esubti.kind == tykind.TY_STRUCT; + let elstr: bool = esubti != nil && esubti.kind == syntax.tykind.TY_STR; + let elslice: bool = esubti != nil && esubti.kind == syntax.tykind.TY_SLICE; + let eltagged: bool = esubti != nil && esubti.kind == syntax.tykind.TY_TAGGED; + let elstruct: bool = esubti != nil && esubti.kind == syntax.tykind.TY_STRUCT; let elwide: bool = elstr || elslice || eltagged || elstruct; if (!elwide && esz > 8) { let m34k: str = "#34: append() element kind unsupported (rule-7)\n"; @@ -29872,31 +29872,31 @@ fn cgappend(c: *cgen, n: *node) void = { emitline("(BP)\n"); }; - let vn: *node = sn.next; + let vn: *syntax.node = sn.next; for (vn != nil) { - if (vn.kind == nkind.N_SPREAD) { + if (vn.kind == syntax.nkind.N_SPREAD) { // #34 review: a non-ident/non-local spread source used // to be silently SKIPPED here while cstage fell past // its spread arm into the single-value stores with the // N_SPREAD node (garbage store) — divergent. - let it: *node = vn.lhs; + let it: *syntax.node = vn.lhs; // #35: only a {ptr,len,cap}-headered source reads as a // header below; a [N]T array place IS its storage — the // ident path used to read its first 16 data bytes as // ptr/len, silently. Loud until wired (task #27); str // shares the slice header layout. - let itu: *tinfo = nil; - if (it != nil) { itu = it.type_: *tinfo; }; + let itu: *syntax.tinfo = nil; + if (it != nil) { itu = it.type_: *syntax.tinfo; }; itu = tichase(itu); - if (itu == nil || (itu.kind != tykind.TY_SLICE - && itu.kind != tykind.TY_STR)) { + if (itu == nil || (itu.kind != syntax.tykind.TY_SLICE + && itu.kind != syntax.tykind.TY_STR)) { let m35p: str = "#35: append() spread source shape unsupported (rule-7)\n"; os.write(2, m35p.ptr, m35p.len: u64); os.exit(1); }; let it_off: i32 = 0; let itscr: i32 = 0; - if (it.kind == nkind.N_IDENT) { + if (it.kind == syntax.nkind.N_IDENT) { let itlocal: *local = localfindnode(c, it.str); if (itlocal != nil) { it_off = itlocal.off; }; }; @@ -29930,7 +29930,7 @@ fn cgappend(c: *cgen, n: *node) void = { // FA1: no etnode behind `*p` — signedness off the // stamped element tinfo, the predicate cstage's // fldloadop applies to su->sub. - load_op = loadopsz(typeissigned(esubti), esz); + load_op = loadopsz(syntax.typeissigned(esubti), esz); }; emitline("\tSUBQ\t$8, SP\n"); emitline("\tMOVQ\t$0, (SP)\n"); @@ -30112,21 +30112,21 @@ fn cgappend(c: *cgen, n: *node) void = { let arootoff: i32 = 0; let asroot: i32 = 0; let asoff: i32 = 0; - let aroot: *node = nil; - let aidx: *node = nil; - if (elstruct && vn.kind != nkind.N_STRUCTLIT && vn.kind != nkind.N_IDENT) { - let ch: *node = vn; + let aroot: *syntax.node = nil; + let aidx: *syntax.node = nil; + if (elstruct && vn.kind != syntax.nkind.N_STRUCTLIT && vn.kind != syntax.nkind.N_IDENT) { + let ch: *syntax.node = vn; let aok: bool = true; - for (aok && ch.kind == nkind.N_DOT) { - let ab: *node = ch.lhs; - let af: *tfield = nil; + for (aok && ch.kind == syntax.nkind.N_DOT) { + let ab: *syntax.node = ch.lhs; + let af: *syntax.tfield = nil; if (ab != nil) { - let abu: *tinfo = ab.type_: *tinfo; + let abu: *syntax.tinfo = ab.type_: *syntax.tinfo; abu = tichase(abu); - if (abu != nil && abu.kind == tykind.TY_STRUCT) { - let fl: *tfield = abu.fields; + if (abu != nil && abu.kind == syntax.tykind.TY_STRUCT) { + let fl: *syntax.tfield = abu.fields; for (fl != nil) { - if (streq(fl.name, ch.str)) { af = fl; break; }; + if (syntax.streq(fl.name, ch.str)) { af = fl; break; }; fl = fl.tnext; }; }; @@ -30135,27 +30135,27 @@ fn cgappend(c: *cgen, n: *node) void = { afld += af.offset: i32; ch = ab; }; - if (aok && ch.kind == nkind.N_INDEX) { - let ab: *node = ch.lhs; - let aet: *tinfo = ch.type_: *tinfo; + if (aok && ch.kind == syntax.nkind.N_INDEX) { + let ab: *syntax.node = ch.lhs; + let aet: *syntax.tinfo = ch.type_: *syntax.tinfo; aet = tichase(aet); - let abu: *tinfo = nil; + let abu: *syntax.tinfo = nil; if (ab != nil) { - abu = ab.type_: *tinfo; + abu = ab.type_: *syntax.tinfo; abu = tichase(abu); }; if (ab == nil || abu == nil || aet == nil - || (abu.kind != tykind.TY_SLICE && abu.kind != tykind.TY_ARRAY)) { + || (abu.kind != syntax.tykind.TY_SLICE && abu.kind != syntax.tykind.TY_ARRAY)) { aok = false; } else { - abaseslice = abu.kind == tykind.TY_SLICE; + abaseslice = abu.kind == syntax.tykind.TY_SLICE; aidxesz = aet.size: i32; aidx = ch.rhs; ch = ab; }; }; if (aok) { - if (ch.kind == nkind.N_IDENT) { + if (ch.kind == syntax.nkind.N_IDENT) { let rl: *local = localfindnode(c, ch.str); if (rl != nil) { arootoff = rl.off; @@ -30165,15 +30165,15 @@ fn cgappend(c: *cgen, n: *node) void = { if (defvarstructinfo(c, ch.str) != nil) { gok = true; }; }; if (!gok) { - let dtn: *node = defvartnode(c, ch.str); + let dtn: *syntax.node = defvartnode(c, ch.str); if (dtn != nil) { - if (dtn.kind == nkind.N_TARRAY) { gok = true; }; + if (dtn.kind == syntax.nkind.N_TARRAY) { gok = true; }; }; }; if (!gok) { aok = false; }; }; } else { - if (ch.kind != nkind.N_UN || ch.op != tkind.TK_STAR) { + if (ch.kind != syntax.nkind.N_UN || ch.op != syntax.tkind.TK_STAR) { aok = false; }; }; @@ -30184,7 +30184,7 @@ fn cgappend(c: *cgen, n: *node) void = { os.exit(1); }; aroot = ch; - if (aroot.kind == nkind.N_UN) { + if (aroot.kind == syntax.nkind.N_UN) { asroot = localadd(c, "@appendsroot", 8, nil); cgexpr(c, aroot.lhs); emitline("\tMOVQ\tAX, "); @@ -30237,7 +30237,7 @@ fn cgappend(c: *cgen, n: *node) void = { vn = vn.next; continue; }; - if (vn.kind == nkind.N_STRUCTLIT) { + if (vn.kind == syntax.nkind.N_STRUCTLIT) { // #59 (#50's eval-order kin): resolve the struct // info, then fill the literal into a fresh // per-SITE scratch (must stay live across @@ -30252,7 +30252,7 @@ fn cgappend(c: *cgen, n: *node) void = { // FA1: no declared tnode to chain through — // the stamped NAMED element tinfo carries the // same leaf structlookupchain would resolve. - if (esubnamed.kind == tykind.TY_NAMED) { + if (esubnamed.kind == syntax.tykind.TY_NAMED) { esi = structlookup(c, esubnamed.name); }; }; @@ -30315,7 +30315,7 @@ fn cgappend(c: *cgen, n: *node) void = { }; cgappendgrow(c, sndirect, sn_off, snscr, esz); cgappendslot(c, sndirect, sn_off, snscr, esz, "BX"); - if (vn.kind == nkind.N_IDENT) { + if (vn.kind == syntax.nkind.N_IDENT) { let sl: *local = localfindnode(c, vn.str); if (sl == nil) { let m34i: str = "#34: append() struct element source ident is not a local (rule-7)\n"; @@ -30371,7 +30371,7 @@ fn cgappend(c: *cgen, n: *node) void = { emitline("\tMOVQ\tBX, "); emitoff(pscroff: i64); emitline("(BP)\n"); - if (aroot.kind == nkind.N_IDENT) { + if (aroot.kind == syntax.nkind.N_IDENT) { if (arootoff != 0) { emitline("\tLEAQ\t"); emitoff(arootoff: i64); @@ -30468,15 +30468,15 @@ fn cgappend(c: *cgen, n: *node) void = { // src (j+1) ahead of dst (j), the safe memmove-down direction. Mirrors // cmd/w6c/cgen.c's N_CALL delete arm instruction-for-instruction // (rule-10 byte-id). -fn cgdelete(c: *cgen, n: *node) void = { - let d: *node = n.list; // N_INDEX, checker-validated - let base: *node = d.lhs; +fn cgdelete(c: *cgen, n: *syntax.node) void = { + let d: *syntax.node = n.list; // N_INDEX, checker-validated + let base: *syntax.node = d.lhs; // esz off the STAMPED base tinfo (#34/#48 discipline — never the // value node). Peel TY_NAMED on indexable AND element, mirroring // cstage's type_chase_named on both (#8 family). - let sti: *tinfo = base.type_: *tinfo; + let sti: *syntax.tinfo = base.type_: *syntax.tinfo; sti = tichase(sti); - let esub: *tinfo = nil; + let esub: *syntax.tinfo = nil; if (sti != nil) { esub = sti.sub; }; esub = tichase(esub); let esz: i32 = 0; @@ -30489,7 +30489,7 @@ fn cgdelete(c: *cgen, n: *node) void = { let hdr_lea: bool = false; let hdr_off: i32 = 0; let hdr_ok: bool = false; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, base.str); if (lc != nil) { hdr_lea = true; @@ -30499,9 +30499,9 @@ fn cgdelete(c: *cgen, n: *node) void = { }; // (*p)[i]: the header lives behind a local ptr-to-slice — the // regex fold-2b delete_thread shape (threads: *[]thread). - if (!hdr_ok && base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR && base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (!hdr_ok && base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR && base.lhs != nil) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let pc: *local = localfindnode(c, base.lhs.str); if (pc != nil) { hdr_off = pc.off; @@ -30600,15 +30600,15 @@ fn cgdelete(c: *cgen, n: *node) void = { // Bounds are implicit (no range check, matching cgdelete and the rest // of cgen). Mirrors cmd/w6c/cgen.c's N_CALL delete range arm // instruction-for-instruction (rule-10 byte-id). -fn cgdeleterange(c: *cgen, n: *node) void = { - let d: *node = n.list; // N_SLICE, checker-validated - let base: *node = d.lhs; +fn cgdeleterange(c: *cgen, n: *syntax.node) void = { + let d: *syntax.node = n.list; // N_SLICE, checker-validated + let base: *syntax.node = d.lhs; // esz off the STAMPED base tinfo (#34/#48 discipline — never the // value node). Peel TY_NAMED on indexable AND element, mirroring // cstage's type_chase_named on both (#8 family). - let sti: *tinfo = base.type_: *tinfo; + let sti: *syntax.tinfo = base.type_: *syntax.tinfo; sti = tichase(sti); - let esub: *tinfo = nil; + let esub: *syntax.tinfo = nil; if (sti != nil) { esub = sti.sub; }; esub = tichase(esub); let esz: i32 = 0; @@ -30623,7 +30623,7 @@ fn cgdeleterange(c: *cgen, n: *node) void = { let hdr_ok: bool = false; let hdr_idx: bool = false; let osz: i32 = 0; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, base.str); if (lc != nil) { hdr_lea = true; @@ -30633,9 +30633,9 @@ fn cgdeleterange(c: *cgen, n: *node) void = { }; // (*p)[lo:hi]: header behind a local ptr-to-slice — cgdelete's // regex_shape twin. - if (!hdr_ok && base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR && base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (!hdr_ok && base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR && base.lhs != nil) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let pc: *local = localfindnode(c, base.lhs.str); if (pc != nil) { hdr_off = pc.off; @@ -30648,9 +30648,9 @@ fn cgdeleterange(c: *cgen, n: *node) void = { // the fold-5a consumer shape (ref/hare/regex/regex.ha:333 // delete(jump_idxs[group_level][..])). Outer stride = the inner // header type's own table size (sti). - if (!hdr_ok && base.kind == nkind.N_INDEX) { + if (!hdr_ok && base.kind == syntax.nkind.N_INDEX) { if (base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let oc: *local = localfindnode(c, base.lhs.str); if (oc != nil) { hdr_idx = true; @@ -30798,16 +30798,16 @@ fn cgdeleterange(c: *cgen, n: *node) void = { // are implicit (no index check, matching delete). Mirrors cmd/w6c/ // cgen.c's N_CALL insert arm instruction-for-instruction (rule-10 // byte-id). -fn cginsert(c: *cgen, n: *node) void = { - let d: *node = n.list; // N_INDEX, checker-validated - let base: *node = d.lhs; - let v: *node = d.next; +fn cginsert(c: *cgen, n: *syntax.node) void = { + let d: *syntax.node = n.list; // N_INDEX, checker-validated + let base: *syntax.node = d.lhs; + let v: *syntax.node = d.next; // esz off the STAMPED base tinfo (#34/#48 discipline — never the // value node). Peel TY_NAMED on indexable AND element, mirroring // cstage's type_chase_named on both (#8 family). - let sti: *tinfo = base.type_: *tinfo; + let sti: *syntax.tinfo = base.type_: *syntax.tinfo; sti = tichase(sti); - let esub: *tinfo = nil; + let esub: *syntax.tinfo = nil; if (sti != nil) { esub = sti.sub; }; esub = tichase(esub); let esz: i32 = 0; @@ -30820,7 +30820,7 @@ fn cginsert(c: *cgen, n: *node) void = { let hdr_lea: bool = false; let hdr_off: i32 = 0; let hdr_ok: bool = false; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, base.str); if (lc != nil) { hdr_lea = true; @@ -30830,9 +30830,9 @@ fn cginsert(c: *cgen, n: *node) void = { }; // (*p)[i]: the header lives behind a local ptr-to-slice — // delete's regex_shape twin. - if (!hdr_ok && base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR && base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (!hdr_ok && base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR && base.lhs != nil) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { let pc: *local = localfindnode(c, base.lhs.str); if (pc != nil) { hdr_off = pc.off; @@ -31026,21 +31026,21 @@ fn cginsert(c: *cgen, n: *node) void = { emitline("\tADDQ\t$24, SP\n"); }; -fn cgcall(c: *cgen, n: *node) void = { +fn cgcall(c: *cgen, n: *syntax.node) void = { // Hare-style `append(s, v)` / `append(s, items...)` builtin — // special-cased before pushargsrev so the spread variant can run // a counted loop over the items slice instead of a normal call. - let callee: *node = n.lhs; + let callee: *syntax.node = n.lhs; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { // abort([msg]) / assert(cond[, msg]) — checker-tagged // builtins (callee TY_ERR is the routing key, cstage's // `lhs->type == ty_err` at cmd/w6c/cgen.c:6618,6645); // lower to rt_abort. A user-shadowed abort/assert is // untagged and stays on the regular call path (#58). - let bti: *tinfo = callee.type_: *tinfo; - if (bti != nil && bti.kind == tykind.TY_ERR) { - if (streq(callee.str, "abort")) { + let bti: *syntax.tinfo = callee.type_: *syntax.tinfo; + if (bti != nil && bti.kind == syntax.tykind.TY_ERR) { + if (syntax.streq(callee.str, "abort")) { if (n.list != nil) { cgexpr(c, n.list); emitline("\tMOVQ\tAX, DI\n"); @@ -31052,14 +31052,14 @@ fn cgcall(c: *cgen, n: *node) void = { emitline("\tCALL\trt_abort(SB)\n"); return; }; - if (streq(callee.str, "assert") && n.list != nil) { + if (syntax.streq(callee.str, "assert") && n.list != nil) { cgexpr(c, n.list); let skip: str = mklabel(c, "as"); emitline("\tCMPQ\t$0, AX\n"); emitline("\tJNE\t"); emitline(skip); emitline("\n"); - let msg: *node = n.list.next; + let msg: *syntax.node = n.list.next; if (msg != nil) { cgexpr(c, msg); emitline("\tMOVQ\tAX, DI\n"); @@ -31073,7 +31073,7 @@ fn cgcall(c: *cgen, n: *node) void = { return; }; }; - if (streq(callee.str, "append")) { + if (syntax.streq(callee.str, "append")) { if (n.list != nil) { if (n.list.next != nil) { cgappend(c, n); @@ -31092,7 +31092,7 @@ fn cgcall(c: *cgen, n: *node) void = { // scope_lookup_prefer gating on the `abort` precedent; // without it, the bare same-module call lands in the // typed-builtin path and shadows the user decl. Task #23. - if (streq(callee.str, "alloc")) { + if (syntax.streq(callee.str, "alloc")) { if (n.list != nil) { if (!samemodfn(c, "alloc")) { cgalloc(c, n); @@ -31118,20 +31118,20 @@ fn cgcall(c: *cgen, n: *node) void = { // DATA POINTER as the length. Non-place operands (call // result, slicing expr, string literal — previously the same // silent ptr-garbage) die LOUD per rule 7. - if (streq(callee.str, "len")) { + if (syntax.streq(callee.str, "len")) { if (n.list != nil) { - let a: *node = n.list; - let at: *tinfo = a.type_: *tinfo; - let u: *tinfo = at; + let a: *syntax.node = n.list; + let at: *syntax.tinfo = a.type_: *syntax.tinfo; + let u: *syntax.tinfo = at; u = tichase(u); let hdrish: bool = false; if (u != nil) { - if (u.kind == tykind.TY_SLICE - || u.kind == tykind.TY_STR) { + if (u.kind == syntax.tykind.TY_SLICE + || u.kind == syntax.tykind.TY_STR) { hdrish = true; }; }; - if (hdrish && a.kind == nkind.N_IDENT) { + if (hdrish && a.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.str); if (lc != nil) { emitline("\tMOVQ\t"); @@ -31168,20 +31168,20 @@ fn cgcall(c: *cgen, n: *node) void = { // directly at BP + element_off + 8, mirroring // the N_IDENT slice arm above and the // tuple-field-offset walk (cgenexpr.ww N_TTUPLE). - if (hdrish && a.kind == nkind.N_DOT + if (hdrish && a.kind == syntax.nkind.N_DOT && a.lhs != nil - && a.lhs.kind == nkind.N_IDENT) { + && a.lhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.lhs.str); if (lc != nil) { - let tn: *node = lc.tnode; - for (tn != nil && tn.kind == nkind.N_TNAME) { + let tn: *syntax.node = lc.tnode; + for (tn != nil && tn.kind == syntax.nkind.N_TNAME) { tn = aliaslookup(c, tn.str); }; if (tn != nil) { - if (tn.kind == nkind.N_TTUPLE) { + if (tn.kind == syntax.nkind.N_TTUPLE) { let idx: i32 = fldnumidx(a.str); if (idx >= 0) { - let tp: *node = tn.list; + let tp: *syntax.node = tn.list; let foff: i32 = 0; let i: i32 = 0; for (i < idx) { @@ -31211,15 +31211,15 @@ fn cgcall(c: *cgen, n: *node) void = { // hit; twin of the cgdot global-tuple // arm and cstage's #235 global base. if (lc == nil) { - let gtn: *node = letvartnode(c, a.lhs.str); - for (gtn != nil && gtn.kind == nkind.N_TNAME) { + let gtn: *syntax.node = letvartnode(c, a.lhs.str); + for (gtn != nil && gtn.kind == syntax.nkind.N_TNAME) { gtn = aliaslookup(c, gtn.str); }; if (gtn != nil) { - if (gtn.kind == nkind.N_TTUPLE) { + if (gtn.kind == syntax.nkind.N_TTUPLE) { let gidx: i32 = fldnumidx(a.str); if (gidx >= 0) { - let gtp: *node = gtn.list; + let gtp: *syntax.node = gtn.list; let gfoff: i32 = 0; let gi: i32 = 0; for (gi < gidx) { @@ -31257,13 +31257,13 @@ fn cgcall(c: *cgen, n: *node) void = { // the same MOVQ BX,AX shape as the #14 .len // pseudo-field fix. Same family as #18 (shared // cstage==wwstage gap, not rule-10). - if (hdrish && a.kind == nkind.N_INDEX) { + if (hdrish && a.kind == syntax.nkind.N_INDEX) { cgexpr(c, a); emitline("\tMOVQ\tBX, AX\n"); return; }; if (u != nil) { - if (u.kind == tykind.TY_ARRAY) { + if (u.kind == syntax.tykind.TY_ARRAY) { emitline("\tMOVQ\t$"); emitint(u.alen: i64); emitline(", AX\n"); @@ -31294,7 +31294,7 @@ fn cgcall(c: *cgen, n: *node) void = { // so Hare code ports verbatim with its side effects // intact. Pre-#27 wwstage fell through to a generic // CALL free → undefined reference at link. - if (streq(callee.str, "free")) { + if (syntax.streq(callee.str, "free")) { if (n.list != nil) { if (n.list.next == nil) { cgexpr(c, n.list); @@ -31306,10 +31306,10 @@ fn cgcall(c: *cgen, n: *node) void = { // delete-half + fold-5a P2 range form; mirror of // cstage cgen.c's N_CALL delete arm (which branches // on d->kind == N_SLICE internally). - if (streq(callee.str, "delete")) { + if (syntax.streq(callee.str, "delete")) { if (n.list != nil) { if (n.list.next == nil) { - if (n.list.kind == nkind.N_SLICE) { + if (n.list.kind == syntax.nkind.N_SLICE) { cgdeleterange(c, n); return; }; @@ -31320,7 +31320,7 @@ fn cgcall(c: *cgen, n: *node) void = { }; // insert(xs[idx], v) — #35 insert-half; mirror of // cstage cgen.c's N_CALL insert arm. - if (streq(callee.str, "insert")) { + if (syntax.streq(callee.str, "insert")) { if (n.list != nil) { if (n.list.next != nil) { if (n.list.next.next == nil) { @@ -31343,15 +31343,15 @@ fn cgcall(c: *cgen, n: *node) void = { // fast path and dropped the variant tag word on widened slice args. // Cstage finds params via the checker-set `n->lhs->type`, sidestepping // the name-driven registry entirely (cmd/w6c/cgen.c:4161-4165). - let calleeparams: *node = nil; + let calleeparams: *syntax.node = nil; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { calleeparams = fnparamslookup(c, callee.str); - } else { if (callee.kind == nkind.N_DOT) { + } else { if (callee.kind == syntax.nkind.N_DOT) { let cmod: str; cmod.ptr = nil; cmod.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; @@ -31371,37 +31371,37 @@ fn cgcall(c: *cgen, n: *node) void = { // nvar>0, vararg_sl always — keeping later match labels aligned. { let nfixed_v: i32 = 0; - let varp: *node = callee_variadic_param(c, callee, &nfixed_v); + let varp: *syntax.node = callee_variadic_param(c, callee, &nfixed_v); if (varp != nil) { let nargs0: i32 = 0; - let aw: *node = n.list; + let aw: *syntax.node = n.list; for (aw != nil) { nargs0 += 1; aw = aw.next; }; let nvar: i32 = nargs0 - nfixed_v; if (nvar < 0) { nvar = 0; }; let forwarding: bool = false; if (nvar == 1) { - let aaf: *node = n.list; + let aaf: *syntax.node = n.list; let kk: i32 = 0; for (kk < nfixed_v) { aaf = aaf.next; kk += 1; }; if (aaf != nil) { - if (aaf.kind == nkind.N_SPREAD) { + if (aaf.kind == syntax.nkind.N_SPREAD) { forwarding = true; }; }; }; if (forwarding) { - let prev: *node = nil; - let cur2: *node = n.list; + let prev: *syntax.node = nil; + let cur2: *syntax.node = n.list; let kk2: i32 = 0; for (kk2 < nfixed_v) { prev = cur2; cur2 = cur2.next; kk2 += 1; }; - let inner: *node = cur2.lhs; + let inner: *syntax.node = cur2.lhs; if (inner != nil) { inner.next = nil; }; if (prev == nil) { n.list = inner; } else { prev.next = inner; }; @@ -31421,14 +31421,14 @@ fn cgcall(c: *cgen, n: *node) void = { // .lhs; Ken's gate: only deref when the wrap // shape is confirmed N_TSLICE (mirrors cstage // cgen.c:4352 `vsu->kind == TY_SLICE` guard). - let velem: *node = varp.lhs; + let velem: *syntax.node = varp.lhs; if (varp.lhs != nil - && varp.lhs.kind == nkind.N_TSLICE) { + && varp.lhs.kind == syntax.nkind.N_TSLICE) { velem = varp.lhs.lhs; }; let esz: i32 = 8; if (velem != nil) { - if (velem.kind == nkind.N_TNAME) { + if (velem.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, velem.str); if (ps > 0) { esz = ps; } else { esz = slotsize(c, velem); }; @@ -31442,7 +31442,7 @@ fn cgcall(c: *cgen, n: *node) void = { // gather buffer — unwired (rule 7). cstage twin // guards before its v_is_tagged gather. if (velem != nil) { - if (taggedmemargsize(velem.type_: *tinfo) > 0) { + if (taggedmemargsize(velem.type_: *syntax.tinfo) > 0) { let mv: str = "#38b: >48B tagged variadic element unwired\n"; os.write(2, mv.ptr, mv.len: u64); os.exit(1); @@ -31470,14 +31470,14 @@ fn cgcall(c: *cgen, n: *node) void = { let sname: str = mklabel(c, "vararg_sl"); let soff: i32 = localadd(c, sname, tyslicesize(): i32, varp.lhs); - let aa2: *node = n.list; + let aa2: *syntax.node = n.list; let kk3: i32 = 0; for (kk3 < nfixed_v) { aa2 = aa2.next; kk3 += 1; }; let j: i32 = 0; - let prevarg: *node = n.list; + let prevarg: *syntax.node = n.list; if (nfixed_v == 0) { prevarg = nil; } else { let kk4: i32 = 0; @@ -31492,7 +31492,7 @@ fn cgcall(c: *cgen, n: *node) void = { // dst is the per-element tagged type; // pass velem (cstage cgen.c:4382 passes // velem, not the slice wrap vsu). - cgwidentaggedstore(c, velem.type_: *tinfo, + cgwidentaggedstore(c, velem.type_: *syntax.tinfo, aa2, "BP", slot, esz); } else { if (velemstr) { cgexpr(c, aa2); @@ -31544,7 +31544,7 @@ fn cgcall(c: *cgen, n: *node) void = { emitline("\tMOVQ\tAX, "); emitoff((soff + 16): i64); emitline("(BP)\n"); - let sn: *node = newnode(nkind.N_IDENT, + let sn: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, "", 0, 0); sn.str = sname; // Synthesised after the checker has run, so the @@ -31576,7 +31576,7 @@ fn cgcall(c: *cgen, n: *node) void = { let sretcalloff: i32 = 0; // #220: GLOBAL dest — RDI gets `LEAQ name(SB)` below; no @sretscr // slot (the callee writes the struct straight into g's storage). - let sretdestn: *node = nil; + let sretdestn: *syntax.node = nil; if (sretcs > 0) { if (c.sretdestnode != nil) { sretdestn = c.sretdestnode; @@ -31599,8 +31599,8 @@ fn cgcall(c: *cgen, n: *node) void = { let intidx: i32 = 0; if (sretcs > 0) { intidx = 1; }; let fpidx: i32 = 0; - let a: *node = n.list; - let dparam: *node = calleeparams; + let a: *syntax.node = n.list; + let dparam: *syntax.node = calleeparams; let popped: i32 = 0; let stackslots: i32 = 0; for (a != nil) { @@ -31610,15 +31610,15 @@ fn cgcall(c: *cgen, n: *node) void = { // pushargsrev (a widened concrete arg is mem-class only // via its param). let dmemsz: i32 = 0; - if (dparam != nil) { if (dparam.kind == nkind.N_PARAM) { - if (dparam.op != tkind.TK_ELLIPSIS) { + if (dparam != nil) { if (dparam.kind == syntax.nkind.N_PARAM) { + if (dparam.op != syntax.tkind.TK_ELLIPSIS) { if (dparam.lhs != nil) { - dmemsz = taggedmemargsize(dparam.lhs.type_: *tinfo); + dmemsz = taggedmemargsize(dparam.lhs.type_: *syntax.tinfo); }; }; }; }; if (dmemsz == 0) { - dmemsz = taggedmemargsize(a.type_: *tinfo); + dmemsz = taggedmemargsize(a.type_: *syntax.tinfo); }; if (dmemsz > 0) { if (dparam != nil) { dparam = dparam.next; }; @@ -31657,9 +31657,9 @@ fn cgcall(c: *cgen, n: *node) void = { }; let fk: i32 = 0; if (a != nil) { - let at: *tinfo = a.type_: *tinfo; - if (typeisf32(at)) { fk = 1; } - else { if (typeisfloat(at)) { fk = 2; }; }; + let at: *syntax.tinfo = a.type_: *syntax.tinfo; + if (syntax.typeisf32(at)) { fk = 1; } + else { if (syntax.typeisfloat(at)) { fk = 2; }; }; }; if (fk != 0) { let mov: str = "MOVSD"; @@ -31681,17 +31681,17 @@ fn cgcall(c: *cgen, n: *node) void = { // tuple LITERAL arg (the declared-tagged box words pop // together with the i64 that follows), mirroring the // param-aware send; else the source tuple type. - let dptt: *node = nil; - if (a.kind == nkind.N_TUPLE) { if (dparam != nil) { - if (dparam.kind == nkind.N_PARAM && dparam.lhs != nil) { - let dtn2: *node = dparam.lhs; - for (dtn2 != nil && dtn2.kind == nkind.N_TNAME) { + let dptt: *syntax.node = nil; + if (a.kind == syntax.nkind.N_TUPLE) { if (dparam != nil) { + if (dparam.kind == syntax.nkind.N_PARAM && dparam.lhs != nil) { + let dtn2: *syntax.node = dparam.lhs; + for (dtn2 != nil && dtn2.kind == syntax.nkind.N_TNAME) { dtn2 = aliaslookup(c, dtn2.str); }; - if (dtn2 != nil) { if (dtn2.kind == nkind.N_TTUPLE) { dptt = dtn2; }; }; + if (dtn2 != nil) { if (dtn2.kind == syntax.nkind.N_TTUPLE) { dptt = dtn2; }; }; }; }; }; - let tuparg: *node = dptt; + let tuparg: *syntax.node = dptt; if (tuparg == nil) { tuparg = nodetuplearg(c, a); }; if (tuparg != nil) { // #163/#32: drain the tuple's staged words (slot+0 @@ -31707,10 +31707,10 @@ fn cgcall(c: *cgen, n: *node) void = { // them (kind-discriminated twin walk). The param-aware // path (dptt) walks declared element TYPE nodes. let tuplit: bool = false; - if (dptt == nil) { if (tuparg.kind == nkind.N_TUPLE) { tuplit = true; }; }; - let p: *node = tuparg.list; + if (dptt == nil) { if (tuparg.kind == syntax.nkind.N_TUPLE) { tuplit = true; }; }; + let p: *syntax.node = tuparg.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (tuplit) { et = p; }; if (isfloattype(c, et)) { if (fpidx >= 8) { @@ -31759,7 +31759,7 @@ fn cgcall(c: *cgen, n: *node) void = { }; } else { let stfc: i32 = 0; - if (a.kind == nkind.N_IDENT) { + if (a.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.str); if (lc != nil) { stfc = structfloatclass(c, lc.tnode); } else { @@ -31769,7 +31769,7 @@ fn cgcall(c: *cgen, n: *node) void = { // class off the global's declared tnode (letvartnode), the same // SysV classification the local path uses. cstage keys // structfloatclass off the operand TYPE, not a local slot. - let gtn: *node = letvartnode(c, a.str); + let gtn: *syntax.node = letvartnode(c, a.str); if (gtn != nil) { stfc = structfloatclass(c, gtn); }; }; }; @@ -31829,7 +31829,7 @@ fn cgcall(c: *cgen, n: *node) void = { // drain exactly that many so intidx tracks per-arg // (the ≤16B struct IDENT case is the stfc branch // above). Mirror of cstage node_isaggarg drain arm. - let aggsz: i32 = aggargsizetn(a.type_: *tinfo); + let aggsz: i32 = aggargsizetn(a.type_: *syntax.tinfo); if (aggsz > 0) { extra = (aggsz + 7) / 8 - 1; }; let words: i32 = 1 + extra; let w: i32 = 0; @@ -31892,7 +31892,7 @@ fn cgcall(c: *cgen, n: *node) void = { // the linker rightly fails. let isfnptrcall: bool = false; if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { let cn: str = callee.str; if (localfindnode(c, cn) != nil) { isfnptrcall = true; @@ -31907,28 +31907,28 @@ fn cgcall(c: *cgen, n: *node) void = { // `CALL (SB)` (empty symbol) for the N_UN-callee shape — the // IDENT/DOT name-emit branches missed and isfnptrcall stayed // false. - if (callee.kind != nkind.N_IDENT - && callee.kind != nkind.N_DOT) { + if (callee.kind != syntax.nkind.N_IDENT + && callee.kind != syntax.nkind.N_DOT) { isfnptrcall = true; }; - if (callee.kind == nkind.N_DOT) { - let base: *node = callee.lhs; + if (callee.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = callee.lhs; let fld: str = callee.str; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; let lc: *local = localfindnode(c, bn); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - let lkind: nkind = tn.kind; + let lkind: syntax.nkind = tn.kind; let sname: str; sname.ptr = nil; sname.len = 0; - if (lkind == nkind.N_TNAME) { sname = tn.str; }; - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TNAME) { sname = tn.str; }; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; }; if (sname.len > 0) { @@ -31937,10 +31937,10 @@ fn cgcall(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { - let ft: *node = fi.tnode; + if (syntax.streq(fn_, fld)) { + let ft: *syntax.node = fi.tnode; if (ft != nil) { - if (ft.kind == nkind.N_TFN) { + if (ft.kind == syntax.nkind.N_TFN) { isfnptrcall = true; }; }; @@ -31995,12 +31995,12 @@ fn cgcall(c: *cgen, n: *node) void = { } else { emitline("\tCALL\t"); if (callee != nil) { - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { // Bare `f()` — same-module by ww's resolver, // so c.curmod is the disambiguation hint. calleename = callee.str; emitfnname(c, calleename, c.curmod); - } else { if (callee.kind == nkind.N_DOT) { + } else { if (callee.kind == syntax.nkind.N_DOT) { // `m.f()` — pass the explicit module bareword // so cross-module same-leaf exports resolve. calleename = callee.str; @@ -32008,7 +32008,7 @@ fn cgcall(c: *cgen, n: *node) void = { hint.ptr = nil; hint.len = 0; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { hint = usehint(c, callee.lhs.str); }; }; @@ -32031,8 +32031,8 @@ fn cgcall(c: *cgen, n: *node) void = { return; }; -fn cgassign(c: *cgen, n: *node) void = { - let lhs: *node = n.lhs; +fn cgassign(c: *cgen, n: *syntax.node) void = { + let lhs: *syntax.node = n.lhs; // #145 (c1.5a): bulk slice-copy-assign `s.arr[lo:hi] = bs` (LHS is // N_SLICE). No legacy cgassign arm catches N_SLICE — the statement // silently emitted nothing (both stages, byte-id-green, #263-class). @@ -32044,8 +32044,8 @@ fn cgassign(c: *cgen, n: *node) void = { // the length is RUNTIME (w6a has no REP/MOVSB). Only plain `=`. The // Hare len(bs)==hi-lo assert is task #149 (rule-7: documented, not a // c2 blocker — appendlit's lengths are equal by construction). - if (lhs != nil) { if (lhs.kind == nkind.N_SLICE - && n.op == tkind.TK_ASSIGN) { + if (lhs != nil) { if (lhs.kind == syntax.nkind.N_SLICE + && n.op == syntax.tkind.TK_ASSIGN) { let esz: i32 = slicebaseesz(c, lhs.lhs); cgexpr(c, lhs); if (esz > 1) { @@ -32088,20 +32088,20 @@ fn cgassign(c: *cgen, n: *node) void = { let placeslit: bool = false; let placedotidx: bool = false; if (lhs != nil) { - if (lhs.kind == nkind.N_DOT && lhs.lhs != nil) { - if (lhs.lhs.kind == nkind.N_INDEX) { + if (lhs.kind == syntax.nkind.N_DOT && lhs.lhs != nil) { + if (lhs.lhs.kind == syntax.nkind.N_INDEX) { placedotidx = true; }; }; - if ((lhs.kind == nkind.N_INDEX - || (lhs.kind == nkind.N_UN && lhs.op == tkind.TK_STAR) + if ((lhs.kind == syntax.nkind.N_INDEX + || (lhs.kind == syntax.nkind.N_UN && lhs.op == syntax.tkind.TK_STAR) || placedotidx) - && n.op == tkind.TK_ASSIGN && n.rhs != nil) { - if (n.rhs.kind == nkind.N_STRUCTLIT) { - let iet: *tinfo = lhs.type_: *tinfo; + && n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil) { + if (n.rhs.kind == syntax.nkind.N_STRUCTLIT) { + let iet: *syntax.tinfo = lhs.type_: *syntax.tinfo; iet = tichase(iet); if (iet != nil) { - if (iet.kind == tykind.TY_STRUCT) { + if (iet.kind == syntax.tykind.TY_STRUCT) { placeslit = true; }; }; @@ -32116,14 +32116,14 @@ fn cgassign(c: *cgen, n: *node) void = { // (byte-id-pinned). Mirror of cstage deref_agg. let derefagg: bool = false; if (lhs != nil) { - if (lhs.kind == nkind.N_UN && lhs.op == tkind.TK_STAR - && n.op == tkind.TK_ASSIGN) { - let du: *tinfo = lhs.type_: *tinfo; + if (lhs.kind == syntax.nkind.N_UN && lhs.op == syntax.tkind.TK_STAR + && n.op == syntax.tkind.TK_ASSIGN) { + let du: *syntax.tinfo = lhs.type_: *syntax.tinfo; du = tichase(du); if (du != nil) { - if (du.kind == tykind.TY_STRUCT - || du.kind == tykind.TY_ARRAY - || du.kind == tykind.TY_TUPLE) { + if (du.kind == syntax.tykind.TY_STRUCT + || du.kind == syntax.tykind.TY_ARRAY + || du.kind == syntax.tykind.TY_TUPLE) { derefagg = true; }; }; @@ -32133,9 +32133,9 @@ fn cgassign(c: *cgen, n: *node) void = { // write nothing. Detected by lhs being an nkind.N_IDENT with empty str // (planted by parseprimary on the tkind.TK_UNDER token). if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { if (lhs.str.len == 0) { - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { cgexpr(c, n.rhs); return; }; @@ -32147,12 +32147,12 @@ fn cgassign(c: *cgen, n: *node) void = { // decl-init fills. Pre-#32 the same scalar tail zeroed one // word silently; die loud until the fill lands. Slice-typed // places are already loud in the checker. - if (n.op == tkind.TK_ASSIGN && lhs != nil && n.rhs != nil) { - if (n.rhs.kind == nkind.N_ARRLIT) { - let alt: *tinfo = lhs.type_: *tinfo; + if (n.op == syntax.tkind.TK_ASSIGN && lhs != nil && n.rhs != nil) { + if (n.rhs.kind == syntax.nkind.N_ARRLIT) { + let alt: *syntax.tinfo = lhs.type_: *syntax.tinfo; alt = tichase(alt); if (alt != nil) { - if (alt.kind == tykind.TY_ARRAY) { + if (alt.kind == syntax.tykind.TY_ARRAY) { let mal: str = "array-literal store at assignment unwired (task #32)\n"; os.write(2, mal.ptr, mal.len: u64); os.exit(1); @@ -32168,10 +32168,10 @@ fn cgassign(c: *cgen, n: *node) void = { // guard. Plain `=` (the tagged-ident reassign arm just below) is // untouched. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT && n.op != tkind.TK_ASSIGN) { - let itu: *tinfo = tichase(lhs.type_: *tinfo); + if (lhs.kind == syntax.nkind.N_IDENT && n.op != syntax.tkind.TK_ASSIGN) { + let itu: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); if (itu != nil) { - if (itu.kind == tykind.TY_TAGGED) { + if (itu.kind == syntax.tykind.TY_TAGGED) { let m21: str = "ident compound on tagged not wired (#21/rule-7)\n"; os.write(2, m21.ptr, m21.len: u64); os.exit(1); @@ -32184,8 +32184,8 @@ fn cgassign(c: *cgen, n: *node) void = { // as cglet's tagged-init). Covers nullable fold, tagged source, // struct payload, str payload, scalar payload, with tag remap. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { - if (n.op == tkind.TK_ASSIGN) { + if (lhs.kind == syntax.nkind.N_IDENT) { + if (n.op == syntax.tkind.TK_ASSIGN) { let lc: *local = localfindnode(c, lhs.str); if (lc != nil) { if (istaggedtype(c, lc.tnode)) { @@ -32198,20 +32198,20 @@ fn cgassign(c: *cgen, n: *node) void = { // arm + the generic sret receive. let asret: i32 = 0; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { + if (n.rhs.kind == syntax.nkind.N_CALL) { asret = callsretsize(c, n.rhs); }; }; if (asret > 0) { - let aru: *tinfo = n.rhs.type_: *tinfo; + let aru: *syntax.tinfo = n.rhs.type_: *syntax.tinfo; aru = tichase(aru); - let alu: *tinfo = lc.tnode.type_: *tinfo; + let alu: *syntax.tinfo = lc.tnode.type_: *syntax.tinfo; alu = tichase(alu); let aexact: bool = false; if (aru != nil && aru == alu) { aexact = true; } else { - if (typeeq(n.rhs.type_: *tinfo, - lc.tnode.type_: *tinfo)) { + if (syntax.typeeq(n.rhs.type_: *syntax.tinfo, + lc.tnode.type_: *syntax.tinfo)) { aexact = true; }; }; @@ -32226,7 +32226,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; let lsz: i32 = slotsize(c, lc.tnode); - cgwidentaggedstore(c, lc.tnode.type_: *tinfo, + cgwidentaggedstore(c, lc.tnode.type_: *syntax.tinfo, n.rhs, "BP", lc.off, lsz); return; }; @@ -32234,10 +32234,10 @@ fn cgassign(c: *cgen, n: *node) void = { // #38b: sret receive into a tagged GLOBAL // lvalue unwired (rule 7; cstage twin fatals). if (lc == nil && n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { - let gru: *tinfo = lhs.type_: *tinfo; + if (n.rhs.kind == syntax.nkind.N_CALL) { + let gru: *syntax.tinfo = lhs.type_: *syntax.tinfo; gru = tichase(gru); - if (gru != nil && gru.kind == tykind.TY_TAGGED + if (gru != nil && gru.kind == syntax.tykind.TY_TAGGED && callsretsize(c, n.rhs) > 0) { let m38g: str = "#38b: sret receive into a tagged GLOBAL lvalue unwired\n"; os.write(2, m38g.ptr, m38g.len: u64); @@ -32252,14 +32252,14 @@ fn cgassign(c: *cgen, n: *node) void = { // scalar store below clobbered the tag word. cstage drops the // store entirely — cs!=ww residual until the cstage half (#41). if (lc == nil) { - let gtn: *node = letvartnode(c, lhs.str); + let gtn: *syntax.node = letvartnode(c, lhs.str); if (gtn != nil) { if (istaggedtype(c, gtn)) { let gsz: i32 = slotsize(c, gtn); emitline("\tLEAQ\t"); emitsymname(c, lhs.str); emitline("(SB), BX\n"); - cgwidentaggedstore(c, gtn.type_: *tinfo, n.rhs, "BX", 0, gsz); + cgwidentaggedstore(c, gtn.type_: *syntax.tinfo, n.rhs, "BX", 0, gsz); return; }; }; @@ -32276,11 +32276,11 @@ fn cgassign(c: *cgen, n: *node) void = { // truncates to one word here — task #31 A/E/G; struct-lit // diverts at the placeslit gate, array-lit dies loud (#32). if (lhs != nil) { - if (lhs.kind == nkind.N_UN) { - if (lhs.op == tkind.TK_STAR) { - if (n.op == tkind.TK_ASSIGN && !placeslit + if (lhs.kind == syntax.nkind.N_UN) { + if (lhs.op == syntax.tkind.TK_STAR) { + if (n.op == syntax.tkind.TK_ASSIGN && !placeslit && !derefagg) { - let inner: *node = lhs.lhs; + let inner: *syntax.node = lhs.lhs; // #17: tagged-union pointee. The single-store // tail below writes rhs into the tag word only, // dropping the payload and corrupting the union. @@ -32290,8 +32290,8 @@ fn cgassign(c: *cgen, n: *node) void = { // word-copy scratch -> *p. Mirror of the runtime- // index tagged element arm (cgenexpr.ww:8768) and // the cstage twin (cmd/w6c/cgen.c #17 deref arm). - let du: *tinfo = tichase(lhs.type_: *tinfo); - if (du != nil && du.kind == tykind.TY_TAGGED) { + let du: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); + if (du != nil && du.kind == syntax.tykind.TY_TAGGED) { let ssz: i32 = du.size: i32; let scr: i32 = tagscradd(c, ssz); emitline("\tXORQ\tAX, AX\n"); @@ -32322,18 +32322,18 @@ fn cgassign(c: *cgen, n: *node) void = { let elemf32: bool = false; let storeop: str = "MOVQ"; if (inner != nil) { - if (inner.kind == nkind.N_IDENT) { + if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TPTR) { - let pe: *node = tn.lhs; + if (tn.kind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = tn.lhs; if (pe != nil) { - if (pe.kind == nkind.N_TNAME) { - if (streq(pe.str, "str")) { elemstr = true; } - else { if (streq(pe.str, "f64")) { elemfloat = true; } - else { if (streq(pe.str, "f32")) { elemfloat = true; elemf32 = true; } + if (pe.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(pe.str, "str")) { elemstr = true; } + else { if (syntax.streq(pe.str, "f64")) { elemfloat = true; } + else { if (syntax.streq(pe.str, "f32")) { elemfloat = true; elemf32 = true; } else { // primsize-ok (#101/#109): this site OWNS its own ps==0 // typenodeprimresolved chase below — routing through @@ -32366,7 +32366,7 @@ fn cgassign(c: *cgen, n: *node) void = { // deref-store stays 1-word, the SAME divergence // str carries; resolved-vs-syntactic detection // is unified UP in #80, not patched here. - if (pe.kind == nkind.N_TSLICE) { elemstr = true; }; + if (pe.kind == syntax.nkind.N_TSLICE) { elemstr = true; }; }; }; }; @@ -32431,8 +32431,8 @@ fn cgassign(c: *cgen, n: *node) void = { // no-op — exactly the trap that broke fmt.println). Mirror of // cmd/w6c/cgen.c's N_UN/TK_STAR compound branch. if (lhs != nil) { - if (lhs.kind == nkind.N_UN) { - if (lhs.op == tkind.TK_STAR) { + if (lhs.kind == syntax.nkind.N_UN) { + if (lhs.op == syntax.tkind.TK_STAR) { // Size gate (mirror cstage cgen.c handled=sz∈{1,2,4,8}): // a tagged (or any non-scalar) pointee is not a // meaningful compound target — skip this single-word @@ -32441,24 +32441,24 @@ fn cgassign(c: *cgen, n: *node) void = { // (#18). Without it the MOVQ default below clobbers the // tag word and returns: a silent miscompile. let psz: i32 = 8; - let lt: *tinfo = lhs.type_: *tinfo; + let lt: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (lt != nil) { psz = lt.size: i32; }; let scalarpointee: bool = (psz == 1 || psz == 2 || psz == 4 || psz == 8); - if (n.op != tkind.TK_ASSIGN && scalarpointee) { - let inner: *node = lhs.lhs; + if (n.op != syntax.tkind.TK_ASSIGN && scalarpointee) { + let inner: *syntax.node = lhs.lhs; let loadop: str = "MOVQ"; let storeop: str = "MOVQ"; // Pointee node for the lhs-sign side of the /= // and %= dispatch. Mirror of cstage's `vt` at // cmd/w6c/cgen.c's TK_STAR-compound branch. - let pe: *node = nil; + let pe: *syntax.node = nil; if (inner != nil) { - if (inner.kind == nkind.N_IDENT) { + if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; if (tn != nil) { - if (tn.kind == nkind.N_TPTR) { + if (tn.kind == syntax.nkind.N_TPTR) { pe = tn.lhs; if (pe != nil) { let ps: i32 = fieldsize(c, pe); @@ -32488,12 +32488,12 @@ fn cgassign(c: *cgen, n: *node) void = { // RSHIFTEQ can route SHRQ vs SARQ on the same key. let unsignd: bool = false; if (pe != nil) { - unsignd = typeisunsigned(pe.type_: *tinfo); + unsignd = syntax.typeisunsigned(pe.type_: *syntax.tinfo); }; if (!unsignd) { unsignd = nodeisunsigned(c, n.rhs); }; - if (n.op == tkind.TK_SLASHEQ || n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ || n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); @@ -32501,7 +32501,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { emitline("\tMOVQ\tDX, AX\n"); }; emitline("\t"); @@ -32510,14 +32510,14 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; let combineop: str = "MOVQ"; - if (n.op == tkind.TK_PLUSEQ) { combineop = "ADDQ"; } - else { if (n.op == tkind.TK_MINUSEQ) { combineop = "SUBQ"; } - else { if (n.op == tkind.TK_STAREQ) { combineop = "IMULQ"; } - else { if (n.op == tkind.TK_AMPEQ) { combineop = "ANDQ"; } - else { if (n.op == tkind.TK_PIPEEQ) { combineop = "ORQ"; } - else { if (n.op == tkind.TK_CARETEQ) { combineop = "XORQ"; } - else { if (n.op == tkind.TK_LSHIFTEQ) { combineop = "SHLQ"; } - else { if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { combineop = "ADDQ"; } + else { if (n.op == syntax.tkind.TK_MINUSEQ) { combineop = "SUBQ"; } + else { if (n.op == syntax.tkind.TK_STAREQ) { combineop = "IMULQ"; } + else { if (n.op == syntax.tkind.TK_AMPEQ) { combineop = "ANDQ"; } + else { if (n.op == syntax.tkind.TK_PIPEEQ) { combineop = "ORQ"; } + else { if (n.op == syntax.tkind.TK_CARETEQ) { combineop = "XORQ"; } + else { if (n.op == syntax.tkind.TK_LSHIFTEQ) { combineop = "SHLQ"; } + else { if (n.op == syntax.tkind.TK_RSHIFTEQ) { // #136: signed RSHIFTEQ → SARQ. if (unsignd) { combineop = "SHRQ"; } else { combineop = "SARQ"; }; @@ -32537,20 +32537,20 @@ fn cgassign(c: *cgen, n: *node) void = { // Array/slice/ptr index store: `arr[i] = v;`. Element size // from base.tnode picks MOVB vs MOVQ. if (lhs != nil) { - if (lhs.kind == nkind.N_INDEX && !placeslit) { - if (n.op == tkind.TK_ASSIGN) { - let base: *node = lhs.lhs; - let idx: *node = lhs.rhs; + if (lhs.kind == syntax.nkind.N_INDEX && !placeslit) { + if (n.op == syntax.tkind.TK_ASSIGN) { + let base: *syntax.node = lhs.lhs; + let idx: *syntax.node = lhs.rhs; let esz: i32 = 8; let baselocal: *local = nil; let isglobalarr: bool = false; let isglobalptr: bool = false; let globalname: str; globalname.ptr = nil; globalname.len = 0; - let elemtn: *node = nil; + let elemtn: *syntax.node = nil; let basealias: bool = false; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal != nil) { @@ -32578,23 +32578,23 @@ fn cgassign(c: *cgen, n: *node) void = { // picks MOVB on the store arm, and the compound // arm's str/slice hard-error still fires on a // []str element). - let tn: *node = letvartnode(c, bn); + let tn: *syntax.node = letvartnode(c, bn); if (tn != nil) { globalname = bn; esz = elemsizeofc(c, tn); // idxelemtn: `*[N]T` drill, see the // local branch above (#61). elemtn = idxelemtn(tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; }; }; }; - } else { if (base.kind == nkind.N_DOT - || (base.kind == nkind.N_UN - && base.op == tkind.TK_STAR)) { + } else { if (base.kind == syntax.nkind.N_DOT + || (base.kind == syntax.nkind.N_UN + && base.op == syntax.tkind.TK_STAR)) { // lhs.type_ is the checker-stamped element tinfo // of the N_INDEX: esz is its natural size and the // tagged-element gate (below) reads the same @@ -32602,9 +32602,9 @@ fn cgassign(c: *cgen, n: *node) void = { // (#60/#72). cstage idx_eff(base->type)->sub->size // (cmd/w6c/cgen.c:3517-18). N_UN deref base // (`(*p)[i] = v`, #61 C): same stamped source. - let dt: *tinfo = lhs.type_: *tinfo; + let dt: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (dt != nil) { esz = dt.size: i32; elemtn = lhs; }; - } else { if (base.kind == nkind.N_INDEX) { + } else { if (base.kind == syntax.nkind.N_INDEX) { // Chained-write write-side parallel of the // cgindex N_INDEX-base arm (#24): `names[i][k] // = v` (names: **u8) — outer element is u8 so @@ -32615,7 +32615,7 @@ fn cgassign(c: *cgen, n: *node) void = { // (#69/#61d, mirror #60). cstage: esz = // idx_eff(base->type)->sub->size // (cmd/w6c/cgen.c:3517-3518). - let et: *tinfo = lhs.type_: *tinfo; + let et: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (et != nil) { esz = et.size: i32; elemtn = lhs; @@ -32630,13 +32630,13 @@ fn cgassign(c: *cgen, n: *node) void = { // cstage N_INDEX store reads idx_eff(base->type)->sub // uniformly (cmd/w6c/cgen.c:3517-3518). if (base != nil) { - if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; + if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; if (bt60 != nil) { - if (bt60.kind == tykind.TY_NAMED) { basealias = true; }; + if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; }; }; if (basealias) { - let et60: *tinfo = tichase(lhs.type_: *tinfo); + let et60: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); if (et60 != nil) { esz = et60.size: i32; elemtn = lhs; @@ -32644,9 +32644,9 @@ fn cgassign(c: *cgen, n: *node) void = { // see cgindex twin: cs-aligned, runtime- // unreachable until #77/#78 global DATA. if (isglobalarr || isglobalptr) { - let bu60: *tinfo = tichase(bt60); + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - isglobalarr = bu60.kind == tykind.TY_ARRAY; + isglobalarr = bu60.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; @@ -32673,7 +32673,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, elemtn.type_: *tinfo, n.rhs, + cgwidentaggedstore(c, elemtn.type_: *syntax.tinfo, n.rhs, "BP", scroff, slot_sz); cgexpr(c, idx); if (slot_sz > 1) { @@ -32691,18 +32691,18 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarr: bool = false; if (tn != nil) { - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isarr = true; }; }; // #60: alias-NAMED base — chased kind // (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarr = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarr = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarr) { emitline("\tLEAQ\t"); @@ -32760,19 +32760,19 @@ fn cgassign(c: *cgen, n: *node) void = { // so the verdict is byte-identical to cstage's cg_sret_retsize. // The base-shape split below then loud-stops every non-local- // array form, base-kind-independent. - if (n.rhs != nil && n.rhs.kind == nkind.N_CALL + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL && callsretsize(c, n.rhs) > 0) { let islocalarr: bool = false; if (baselocal != nil) { - let btn: *node = baselocal.tnode; + let btn: *syntax.node = baselocal.tnode; if (btn != nil) { - if (btn.kind == nkind.N_TARRAY) { islocalarr = true; }; + if (btn.kind == syntax.nkind.N_TARRAY) { islocalarr = true; }; }; }; let constidx: bool = false; let cidx: i32 = 0; if (idx != nil) { - if (idx.kind == nkind.N_INTLIT) { + if (idx.kind == syntax.nkind.N_INTLIT) { constidx = true; cidx = idx.uval: i32; }; @@ -32799,18 +32799,18 @@ fn cgassign(c: *cgen, n: *node) void = { // element N_TTUPLE), in-cap. Mirror of cstage cgen.c #121 // store arm; the materialise + base-resolve are the // cglet / #270-1b byte-id twins. - if (n.rhs.kind == nkind.N_TUPLE && esz > 8 - && base != nil && base.kind == nkind.N_IDENT - && elemtn != nil && elemtn.kind == nkind.N_TTUPLE + if (n.rhs.kind == syntax.nkind.N_TUPLE && esz > 8 + && base != nil && base.kind == syntax.nkind.N_IDENT + && elemtn != nil && elemtn.kind == syntax.nkind.N_TTUPLE && sretretsize(c, elemtn) == 0) { let scr121: i32 = tagscradd(c, esz); cgtuplelittocursor(c, n.rhs, elemtn); let gpc: i32 = 0; let ssc: i32 = 0; let eo: i32 = 0; - let q121: *node = elemtn.list; + let q121: *syntax.node = elemtn.list; for (q121 != nil) { - let qt: *node = q121.lhs; + let qt: *syntax.node = q121.lhs; let isflt: bool = isfloattype(c, qt); let es: i32 = tupeslotn(qt); tupstore(c, gpc, ssc, scr121 + eo, es, qt); @@ -32837,12 +32837,12 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn2: *node = baselocal.tnode; + let tn2: *syntax.node = baselocal.tnode; let isarr2: bool = false; - if (tn2 != nil) { if (tn2.kind == nkind.N_TARRAY) { isarr2 = true; }; }; + if (tn2 != nil) { if (tn2.kind == syntax.nkind.N_TARRAY) { isarr2 = true; }; }; if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarr2 = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarr2 = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarr2) { emitline("\tLEAQ\t"); @@ -32885,10 +32885,10 @@ fn cgassign(c: *cgen, n: *node) void = { // — RAX-only store, task #31-G. esz>8 // non-str/non-slice IS a struct/array/tuple here (the // tagged element already returned above; floats are ≤8). - let aggsrc: bool = (n.rhs.kind == nkind.N_IDENT) - || (n.rhs.kind == nkind.N_DOT) - || (n.rhs.kind == nkind.N_UN - && n.rhs.op == tkind.TK_STAR); + let aggsrc: bool = (n.rhs.kind == syntax.nkind.N_IDENT) + || (n.rhs.kind == syntax.nkind.N_DOT) + || (n.rhs.kind == syntax.nkind.N_UN + && n.rhs.op == syntax.tkind.TK_STAR); if (esz > 8 && !isstrtype(c, elemtn) && !isslicetype(c, elemtn) && aggsrc) { cgexpr(c, idx); // idx → AX @@ -32908,13 +32908,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn2: *node = baselocal.tnode; + let tn2: *syntax.node = baselocal.tnode; let isarr2: bool = false; - if (tn2 != nil) { if (tn2.kind == nkind.N_TARRAY) { isarr2 = true; }; }; + if (tn2 != nil) { if (tn2.kind == syntax.nkind.N_TARRAY) { isarr2 = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarr2 = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarr2 = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarr2) { emitline("\tLEAQ\t"); @@ -32935,11 +32935,11 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tADDQ\tAX, BX\n"); emitline("\tPUSHQ\tBX\n"); // spill dest // rhs source address → SI - if (n.rhs.kind == nkind.N_UN - && n.rhs.op == tkind.TK_STAR) { + if (n.rhs.kind == syntax.nkind.N_UN + && n.rhs.op == syntax.tkind.TK_STAR) { cgexpr(c, n.rhs.lhs); emitline("\tMOVQ\tAX, SI\n"); - } else { if (n.rhs.kind == nkind.N_IDENT) { + } else { if (n.rhs.kind == syntax.nkind.N_IDENT) { let sl: *local = localfindnode(c, n.rhs.str); if (sl != nil) { emitline("\tLEAQ\t"); @@ -33040,13 +33040,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; - if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; }; + if (tn != nil) { if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarray) { emitline("\tLEAQ\t"); @@ -33121,18 +33121,18 @@ fn cgassign(c: *cgen, n: *node) void = { // unwired — cstage's compound template never carried // those payload kinds. Same shape gate as the cstage // branch (cgen.c #133). - if (n.op != tkind.TK_ASSIGN) { - let base: *node = lhs.lhs; - let idx: *node = lhs.rhs; + if (n.op != syntax.tkind.TK_ASSIGN) { + let base: *syntax.node = lhs.lhs; + let idx: *syntax.node = lhs.rhs; let esz: i32 = 8; let baselocal: *local = nil; let isglobalarr: bool = false; let isglobalptr: bool = false; let globalname: str; globalname.ptr = nil; globalname.len = 0; - let elemtn: *node = nil; + let elemtn: *syntax.node = nil; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; baselocal = localfindnode(c, bn); if (baselocal != nil) { @@ -33160,29 +33160,29 @@ fn cgassign(c: *cgen, n: *node) void = { // picks MOVB on the store arm, and the compound // arm's str/slice hard-error still fires on a // []str element). - let tn: *node = letvartnode(c, bn); + let tn: *syntax.node = letvartnode(c, bn); if (tn != nil) { globalname = bn; esz = elemsizeofc(c, tn); // idxelemtn: `*[N]T` drill, see the // local branch above (#61). elemtn = idxelemtn(tn); - if (tn.kind == nkind.N_TARRAY) { + if (tn.kind == syntax.nkind.N_TARRAY) { isglobalarr = true; } else { isglobalptr = true; }; }; }; - } else { if (base.kind == nkind.N_DOT - || (base.kind == nkind.N_UN - && base.op == tkind.TK_STAR)) { + } else { if (base.kind == syntax.nkind.N_DOT + || (base.kind == syntax.nkind.N_UN + && base.op == syntax.tkind.TK_STAR)) { // N_UN deref base (`(*p)[i] OP= v`, #61 C): // same stamped source as the store arm. - let dt: *tinfo = lhs.type_: *tinfo; + let dt: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (dt != nil) { esz = dt.size: i32; elemtn = lhs; }; - } else { if (base.kind == nkind.N_INDEX) { - let et: *tinfo = lhs.type_: *tinfo; + } else { if (base.kind == syntax.nkind.N_INDEX) { + let et: *syntax.tinfo = lhs.type_: *syntax.tinfo; if (et != nil) { esz = et.size: i32; elemtn = lhs; @@ -33193,21 +33193,21 @@ fn cgassign(c: *cgen, n: *node) void = { // same stamped-element adoption as the store arm. let basealias: bool = false; if (base != nil) { - if (base.kind == nkind.N_IDENT) { - let bt60: *tinfo = base.type_: *tinfo; + if (base.kind == syntax.nkind.N_IDENT) { + let bt60: *syntax.tinfo = base.type_: *syntax.tinfo; if (bt60 != nil) { - if (bt60.kind == tykind.TY_NAMED) { basealias = true; }; + if (bt60.kind == syntax.tykind.TY_NAMED) { basealias = true; }; }; if (basealias) { - let et60: *tinfo = tichase(lhs.type_: *tinfo); + let et60: *syntax.tinfo = tichase(lhs.type_: *syntax.tinfo); if (et60 != nil) { esz = et60.size: i32; elemtn = lhs; }; if (isglobalarr || isglobalptr) { - let bu60: *tinfo = tichase(bt60); + let bu60: *syntax.tinfo = tichase(bt60); if (bu60 != nil) { - isglobalarr = bu60.kind == tykind.TY_ARRAY; + isglobalarr = bu60.kind == syntax.tykind.TY_ARRAY; isglobalptr = !isglobalarr; }; }; @@ -33257,13 +33257,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitsymname(c, globalname); emitline("(SB), BX\n"); } else { if (baselocal != nil) { - let tn: *node = baselocal.tnode; + let tn: *syntax.node = baselocal.tnode; let isarray: bool = false; - if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; }; + if (tn != nil) { if (tn.kind == syntax.nkind.N_TARRAY) { isarray = true; }; }; // #60: alias-NAMED base — chased kind (see cgindex twin). if (basealias) { - let bu60: *tinfo = tichase(base.type_: *tinfo); - if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; }; + let bu60: *syntax.tinfo = tichase(base.type_: *syntax.tinfo); + if (bu60 != nil) { isarray = bu60.kind == syntax.tykind.TY_ARRAY; }; }; if (isarray) { emitline("\tLEAQ\t"); @@ -33295,29 +33295,29 @@ fn cgassign(c: *cgen, n: *node) void = { let unsignd_c: bool = false; if (elemtn != nil) { if (elemtn.type_ != nil) { - unsignd_c = typeisunsigned(elemtn.type_: *tinfo); + unsignd_c = syntax.typeisunsigned(elemtn.type_: *syntax.tinfo); }; }; let wired: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd_c) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd_c) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd_c) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired = true; @@ -33345,30 +33345,30 @@ fn cgassign(c: *cgen, n: *node) void = { // N_INDEX-lhs branch above handles bare `arr[i] = v`, not the // field write). if (lhs != nil) { - if (lhs.kind == nkind.N_DOT && lhs.lhs != nil - && lhs.lhs.kind == nkind.N_INDEX && !placeslit) { - let idxbase: *node = lhs.lhs.lhs; - let idx: *node = lhs.lhs.rhs; + if (lhs.kind == syntax.nkind.N_DOT && lhs.lhs != nil + && lhs.lhs.kind == syntax.nkind.N_INDEX && !placeslit) { + let idxbase: *syntax.node = lhs.lhs.lhs; + let idx: *syntax.node = lhs.lhs.rhs; let fld2: str = lhs.str; - if (idxbase != nil) { if (idxbase.kind == nkind.N_IDENT) { + if (idxbase != nil) { if (idxbase.kind == syntax.nkind.N_IDENT) { if (idx != nil) { let lc: *local = localfindnode(c, idxbase.str); if (lc != nil) { if (lc.tnode != nil) { - let tn: *node = lc.tnode; + let tn: *syntax.node = lc.tnode; // idxelemtn: `*[N]T` drills to the pointee // array's element (#61). - let elemt: *node = idxelemtn(tn); - let baseisarray: bool = tn.kind == nkind.N_TARRAY; - let snode: *node = nil; + let elemt: *syntax.node = idxelemtn(tn); + let baseisarray: bool = tn.kind == syntax.nkind.N_TARRAY; + let snode: *syntax.node = nil; let viaptr: bool = false; if (elemt != nil) { - if (elemt.kind == nkind.N_TPTR) { - let inner: *node = elemt.lhs; - if (inner != nil) { if (inner.kind == nkind.N_TNAME) { + if (elemt.kind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = elemt.lhs; + if (inner != nil) { if (inner.kind == syntax.nkind.N_TNAME) { snode = inner; viaptr = true; };}; - } else { if (elemt.kind == nkind.N_TNAME) { + } else { if (elemt.kind == syntax.nkind.N_TNAME) { snode = elemt; };}; }; @@ -33387,12 +33387,12 @@ fn cgassign(c: *cgen, n: *node) void = { if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld2)) { + if (syntax.streq(fi.fname, fld2)) { let esz: i32 = elemsizeofc(c, tn); // f64/f32: rhs in X0. Spill to stack, // compute &arr[i] in BX (deref if *T), // then reload X0 and MOVSD/MOVSS. - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { if (isfloattype(c, fi.tnode)) { let mov: str = "MOVSD"; if (isf32type(c, fi.tnode)) { mov = "MOVSS"; }; @@ -33520,7 +33520,7 @@ fn cgassign(c: *cgen, n: *node) void = { os.write(2, m58m.ptr, m58m.len: u64); os.exit(1); }; - if (typeisfloat(n.rhs.type_: *tinfo)) { + if (syntax.typeisfloat(n.rhs.type_: *syntax.tinfo)) { let m58f: str = "#58: float-payload tagged-field indexed store unreachable until #114\n"; os.write(2, m58f.ptr, m58f.len: u64); os.exit(1); @@ -33546,7 +33546,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tADDQ\tAX, BX\n"); if (viaptr) { emitline("\tMOVQ\t(BX), BX\n"); }; emitline("\tPOPQ\tAX\n"); - let v58tag: i32 = taggedvariantindext(c, fi.tnode.type_: *tinfo, n.rhs); + let v58tag: i32 = taggedvariantindext(c, fi.tnode.type_: *syntax.tinfo, n.rhs); if (v58tag < 0) { v58tag = 0; }; emitline("\tMOVQ\t$"); emitint(v58tag: i64); @@ -33650,29 +33650,29 @@ fn cgassign(c: *cgen, n: *node) void = { let unsignd_x: bool = false; if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { - unsignd_x = typeisunsigned(fi.tnode.type_: *tinfo); + unsignd_x = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; let wired_x: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd_x) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired_x = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd_x) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_x = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_x = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd_x) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired_x = true; @@ -33706,33 +33706,33 @@ fn cgassign(c: *cgen, n: *node) void = { // by retargeting to the inner IDENT so the via_ptr branch fires // the same as auto-deref `p.f = v`. v1 scope: bare-IDENT inner. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; if (base != nil) { - if (base.kind == nkind.N_UN) { - if (base.op == tkind.TK_STAR) { + if (base.kind == syntax.nkind.N_UN) { + if (base.op == syntax.tkind.TK_STAR) { if (base.lhs != nil) { - if (base.lhs.kind == nkind.N_IDENT) { + if (base.lhs.kind == syntax.nkind.N_IDENT) { base = base.lhs; }; }; }; }; - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; let lc: *local = localfindnode(c, bn); if (lc != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = nkind.N_NONE; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = syntax.nkind.N_NONE; if (tn != nil) { lkind = tn.kind; }; // Pointer-to-struct: deref then store. - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; let sname: str; sname.ptr = nil; sname.len = 0; if (inner != nil) { - if (inner.kind == nkind.N_TNAME) { sname = inner.str; }; + if (inner.kind == syntax.nkind.N_TNAME) { sname = inner.str; }; }; if (sname.len > 0) { // structlookupchain (#22) handles the @@ -33743,18 +33743,18 @@ fn cgassign(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // Tagged-union field via *struct base — full slot // rewrite via cgwidentaggedstore basereg="BX". Pre-#26 // fell through to the scalar store and dropped tag // + payload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && istaggedtype(c, fi.tnode)) { let fsz: i32 = slotsize(c, fi.tnode); emitline("\tMOVQ\t"); emitoff(lc.off: i64); emitline("(BP), BX\n"); - cgwidentaggedstore(c, fi.tnode.type_: *tinfo, + cgwidentaggedstore(c, fi.tnode.type_: *syntax.tinfo, n.rhs, "BX", fi.foff, fsz); return; }; @@ -33762,9 +33762,9 @@ fn cgassign(c: *cgen, n: *node) void = { // be a runtime RDI pointer (the BP-relative c.sretdestoff // can't name `p.f`); deferred. HARD-STOP loud, never fall // through to the truncating generic store (rule 7). - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && sretretsize(c, fi.tnode) > 0) { let m234: str = "#234-tail: over-cap tuple sret store to via-ptr field dest unsupported\n"; os.write(2, m234.ptr, m234.len: u64); @@ -33783,11 +33783,11 @@ fn cgassign(c: *cgen, n: *node) void = { // granularity — size via structabisize (cstage // SSoT lu->size, check.c:760; cgen.c:7720 // sz=lu->size at the receive twin). - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -33838,11 +33838,11 @@ fn cgassign(c: *cgen, n: *node) void = { // its trailing bytes. mode=1 (DST_PTR_LOCAL) reloads BX // from lc.off(BP) before zero-fill and before every // field store. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -33851,11 +33851,11 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); let srhs: *local = localfindnode(c, n.rhs.str); @@ -33904,7 +33904,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; };}; }; - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // compound: load current value emitline("\tMOVQ\t"); emitoff(lc.off: i64); @@ -33918,17 +33918,17 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPUSHQ\tBX\n"); }; cgexpr(c, n.rhs); - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { emitline("\tPOPQ\tBX\n"); // PLUSEQ is commutative; MINUSEQ // needs lhs - rhs (BX is old lhs, // AX is rhs). cgdotfieldhardstop(c, fi.tnode); let uns34: bool = false; - if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = typeisunsigned(fi.tnode.type_: *tinfo); }; }; + if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; cgdotfieldcombine(c, n.op, uns34); }; - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { // str/slice field via *struct: str IS []u8, so both // store the full 3-word {ptr,len,cap} from (AX,BX,CX). // CX holds cap, so stage the struct addr in DX and @@ -33981,7 +33981,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; // Direct struct local: store at off+foff. - if (lkind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { // structlookupchain (#22) — same shape // as the cgdot direct-local read site. let si: *structinfo = structlookupchain(c, tn); @@ -33989,15 +33989,15 @@ fn cgassign(c: *cgen, n: *node) void = { let fi: *fieldinfo = si.fields; for (fi != nil) { let fn_: str = fi.fname; - if (streq(fn_, fld)) { + if (syntax.streq(fn_, fld)) { // Tagged-union field in a direct struct local — // full slot rewrite at (lc.off + fi.foff)(BP) // via cgwidentaggedstore basereg="BP". Pre-#26 // fell through and dropped tag + payload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && istaggedtype(c, fi.tnode)) { let fsz: i32 = slotsize(c, fi.tnode); - cgwidentaggedstore(c, fi.tnode.type_: *tinfo, + cgwidentaggedstore(c, fi.tnode.type_: *syntax.tinfo, n.rhs, "BP", lc.off + fi.foff, fsz); return; }; @@ -34009,9 +34009,9 @@ fn cgassign(c: *cgen, n: *node) void = { // (c.sretdestoff = lc.off + fi.foff) so it writes the // WHOLE value there, never the truncating generic store // below. Mirror of cstage cgen.c (#234) field local arm. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && sretretsize(c, fi.tnode) > 0) { c.sretdestoff = lc.off + fi.foff; cgexpr(c, n.rhs); @@ -34027,11 +34027,11 @@ fn cgassign(c: *cgen, n: *node) void = { // N_STRUCTLIT: field-walk; each inner // field stored at +fi.foff+inner_foff(BP). // BP-rel direct, no addr scratch needed. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -34078,11 +34078,11 @@ fn cgassign(c: *cgen, n: *node) void = { // typed structlit value recurses instead of dropping // its trailing bytes. mode=0 (DST_BP) — direct BP-rel, // no BX reload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -34091,11 +34091,11 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); let srhs: *local = localfindnode(c, n.rhs.str); @@ -34141,7 +34141,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; };}; }; - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // Compound on direct struct-local // scalar field: load current → push // → eval rhs → combine → store @@ -34155,13 +34155,13 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPUSHQ\tBX\n"); }; cgexpr(c, n.rhs); - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { emitline("\tPOPQ\tBX\n"); // PLUSEQ commutes; MINUSEQ needs // lhs-rhs (BX old lhs, AX rhs). cgdotfieldhardstop(c, fi.tnode); let uns34: bool = false; - if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = typeisunsigned(fi.tnode.type_: *tinfo); }; }; + if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; cgdotfieldcombine(c, n.op, uns34); }; // str/slice field direct: str IS []u8, so both store the @@ -34205,21 +34205,21 @@ fn cgassign(c: *cgen, n: *node) void = { }; // str/slice pseudo-field assignment. let delta: i32 = -1; - if (streq(fld, "ptr")) { delta = 0; }; - if (streq(fld, "len")) { delta = 8; }; - if (streq(fld, "cap")) { delta = 16; }; + if (syntax.streq(fld, "ptr")) { delta = 0; }; + if (syntax.streq(fld, "len")) { delta = 8; }; + if (syntax.streq(fld, "cap")) { delta = 16; }; if (delta >= 0) { - if (lkind == nkind.N_TPTR) { - let inner: *node = tn.lhs; - let innerkind: nkind = nkind.N_NONE; + if (lkind == syntax.nkind.N_TPTR) { + let inner: *syntax.node = tn.lhs; + let innerkind: syntax.nkind = syntax.nkind.N_NONE; if (inner != nil) { innerkind = inner.kind; }; let innerstr: bool = false; - if (innerkind == nkind.N_TNAME) { - if (streq(inner.str, "str")) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TNAME) { + if (syntax.streq(inner.str, "str")) { innerstr = true; }; }; - if (innerkind == nkind.N_TSLICE) { innerstr = true; }; + if (innerkind == syntax.nkind.N_TSLICE) { innerstr = true; }; if (innerstr) { - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // Compound on `(*str|*slice).field`: load // current → push → eval rhs → combine → store. emitline("\tMOVQ\t"); @@ -34252,7 +34252,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { // Compound on local `str|slice` pseudo-field: // load current → push → eval rhs → combine → // store (mirror cgen.c:3235 local arm). @@ -34287,25 +34287,25 @@ fn cgassign(c: *cgen, n: *node) void = { // follows the same load → push → eval → combine → store shape // as the via-ptr local path. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; if (base != nil) { - if (base.kind == nkind.N_IDENT) { + if (base.kind == syntax.nkind.N_IDENT) { let bn: str = base.str; if (localfindnode(c, bn) == nil) { let si: *structinfo = letvarstructinfo(c, bn); if (si != nil) { let fi: *fieldinfo = si.fields; for (fi != nil) { - if (streq(fi.fname, fld)) { + if (syntax.streq(fi.fname, fld)) { // #234-tail: GLOBAL (`g.f`) sret field STORE. c.sretdestoff is // BP-relative only and can't name a global slot; the runtime // RDI-pointer dest variant is deferred. HARD-STOP loud, never // the truncating generic store (rule 7). - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && sretretsize(c, fi.tnode) > 0) { let m234: str = "#234-tail: over-cap tuple sret store to global field dest unsupported\n"; os.write(2, m234.ptr, m234.len: u64); @@ -34318,11 +34318,11 @@ fn cgassign(c: *cgen, n: *node) void = { // N_CALL: cgexpr → AX/DX/CX; LEAQ base into BX // after call, sized stores per natural size. // N_STRUCTLIT: field-walk; reload BX per store. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -34373,11 +34373,11 @@ fn cgassign(c: *cgen, n: *node) void = { // its trailing bytes. mode=2 (DST_GLOBAL) reloads BX // via LEAQ bn(SB) before zero-fill and before every // field store. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); if (ssi != nil) { @@ -34386,11 +34386,11 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; }; - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && fi.tnode != nil - && fi.tnode.kind == nkind.N_TNAME + && fi.tnode.kind == syntax.nkind.N_TNAME && aliasprimsize(c, fi.tnode.str) == 0) { let ssi: *structinfo = structlookup(c, fi.tnode.str); let srhs: *local = localfindnode(c, n.rhs.str); @@ -34445,18 +34445,18 @@ fn cgassign(c: *cgen, n: *node) void = { // is_global arm. Without this the generic TK_ASSIGN // below truncates to 1 word, silently dropping tag // and payload. - if (n.op == tkind.TK_ASSIGN + if (n.op == syntax.tkind.TK_ASSIGN && istaggedtype(c, fi.tnode)) { let fsz: i32 = slotsize(c, fi.tnode); emitline("\tLEAQ\t"); emitsymname(c, bn); emitline("(SB), BX\n"); cgwidentaggedstore(c, - fi.tnode.type_: *tinfo, + fi.tnode.type_: *syntax.tinfo, n.rhs, "BX", fi.foff, fsz); return; }; - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { cgexpr(c, n.rhs); if (isstrtype(c, fi.tnode) || isslicetype(c, fi.tnode)) { // str OR slice field: str IS []u8, so @@ -34526,7 +34526,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPOPQ\tBX\n"); cgdotfieldhardstop(c, fi.tnode); let uns34: bool = false; - if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = typeisunsigned(fi.tnode.type_: *tinfo); }; }; + if (fi.tnode != nil) { if (fi.tnode.type_ != nil) { uns34 = syntax.typeisunsigned(fi.tnode.type_: *syntax.tinfo); }; }; cgdotfieldcombine(c, n.op, uns34); let sop: str = fieldstoreop(c, fi); emitline("\tLEAQ\t"); @@ -34556,11 +34556,11 @@ fn cgassign(c: *cgen, n: *node) void = { // store. Only plain `=` is wired here; chained compound on a // pointer-field hasn't surfaced. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; if (base != nil) { - if (base.kind == nkind.N_DOT) { + if (base.kind == syntax.nkind.N_DOT) { // #70 (#12): inner-struct layout via the stamped // base.type_ (peel *→struct) + tinfo.fields, // replacing dotinnerstructptr's structinfo walk. @@ -34572,35 +34572,35 @@ fn cgassign(c: *cgen, n: *node) void = { // exactly avoids an untested widening past cstage. // Global-root chains stay in their pre-existing shared // base-eval breakage (filed #27). - let croot: *node = base; + let croot: *syntax.node = base; let allptr: bool = true; - for (croot != nil && croot.kind == nkind.N_DOT) { - let ct: *tinfo = croot.type_: *tinfo; + for (croot != nil && croot.kind == syntax.nkind.N_DOT) { + let ct: *syntax.tinfo = croot.type_: *syntax.tinfo; ct = tichase(ct); let okp: bool = false; - if (ct != nil) { if (ct.kind == tykind.TY_PTR) { - let cs: *tinfo = ct.sub; + if (ct != nil) { if (ct.kind == syntax.tykind.TY_PTR) { + let cs: *syntax.tinfo = ct.sub; cs = tichase(cs); - if (cs != nil) { if (cs.kind == tykind.TY_STRUCT) { okp = true; }; }; + if (cs != nil) { if (cs.kind == syntax.tykind.TY_STRUCT) { okp = true; }; }; }; }; if (!okp) { allptr = false; }; croot = croot.lhs; }; - let it: *tinfo = nil; - if (allptr && croot != nil && croot.kind == nkind.N_IDENT && + let it: *syntax.tinfo = nil; + if (allptr && croot != nil && croot.kind == syntax.nkind.N_IDENT && localfindnode(c, croot.str) != nil) { - it = base.type_: *tinfo; + it = base.type_: *syntax.tinfo; }; it = tichase(it); - if (it != nil) { if (it.kind == tykind.TY_PTR) { - let st: *tinfo = it.sub; + if (it != nil) { if (it.kind == syntax.tykind.TY_PTR) { + let st: *syntax.tinfo = it.sub; st = tichase(st); - if (st != nil) { if (st.kind == tykind.TY_STRUCT) { - let tf: *tfield = st.fields; + if (st != nil) { if (st.kind == syntax.tykind.TY_STRUCT) { + let tf: *syntax.tfield = st.fields; for (tf != nil) { - if (streq(tf.name, fld)) { - let ft: *tinfo = tf.type_; - if (n.op == tkind.TK_ASSIGN) { + if (syntax.streq(tf.name, fld)) { + let ft: *syntax.tinfo = tf.type_; + if (n.op == syntax.tkind.TK_ASSIGN) { // tagged leaf (#38a): eval the *struct // base into BX, then the shared widener // (it spills BX across its internal @@ -34609,8 +34609,8 @@ fn cgassign(c: *cgen, n: *node) void = { // scalar tail below stored ONE sized // word at the field offset: the rhs // landed in the TAG slot (ken b8). - if (typeistagged(ft)) { - let flu: *tinfo = ft; + if (syntax.typeistagged(ft)) { + let flu: *syntax.tinfo = ft; flu = tichase(flu); cgexpr(c, base); emitline("\tMOVQ\tAX, BX\n"); @@ -34619,7 +34619,7 @@ fn cgassign(c: *cgen, n: *node) void = { flu.size: i32); return; }; - if (typeisstr(ft) || typeisslice(ft)) { + if (syntax.typeisstr(ft) || syntax.typeisslice(ft)) { // str/slice: rhs leaves AX=ptr, // BX=len, CX=cap (#1/Phase 3). Spill // all three across the base-expr eval @@ -34651,9 +34651,9 @@ fn cgassign(c: *cgen, n: *node) void = { // f64/f32 chained plain `=`: cgexpr rhs left value in // X0. Spill to stack so cgexpr(base) can use AX, then // reload and MOVSD/MOVSS into the slot. - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mov: str = "MOVSD"; - if (typeisf32(ft)) { mov = "MOVSS"; }; + if (syntax.typeisf32(ft)) { mov = "MOVSS"; }; cgexpr(c, n.rhs); emitline("\tSUBQ\t$8, SP\n"); emitline("\t"); @@ -34698,23 +34698,23 @@ fn cgassign(c: *cgen, n: *node) void = { // float/str/slice/tagged field-type // hard-errors LOUD. Signed RSHIFTEQ uses // SARQ (signed) or SHRQ (unsigned) per #136. - if (n.op != tkind.TK_ASSIGN) { - if (typeisstr(ft)) { + if (n.op != syntax.tkind.TK_ASSIGN) { + if (syntax.typeisstr(ft)) { let m: str = "chained-ptr-field compound on str element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (typeisslice(ft)) { + if (syntax.typeisslice(ft)) { let m: str = "chained-ptr-field compound on slice element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let m: str = "chained-ptr-field compound on float element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (typeistagged(ft)) { + if (syntax.typeistagged(ft)) { let m: str = "chained-ptr-field compound on tagged element not wired (#133/rule-7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -34724,7 +34724,7 @@ fn cgassign(c: *cgen, n: *node) void = { cgexpr(c, base); emitline("\tPUSHQ\tAX\n"); let fsz: i32 = ft.slotsize: i32; - let unsignd_f: bool = typeisunsigned(ft); + let unsignd_f: bool = syntax.typeisunsigned(ft); let lopf: str = loadopsz(!unsignd_f, fsz); emitline("\t"); emitline(lopf); @@ -34734,25 +34734,25 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tPOPQ\tBX\n"); emitline("\tPOPQ\tCX\n"); let wired_f: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd_f) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired_f = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd_f) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_f = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired_f = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd_f) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired_f = true; @@ -34786,13 +34786,13 @@ fn cgassign(c: *cgen, n: *node) void = { // the slice/str pseudo-field write through a value-struct chain // silently emit no store. Only plain `=` is wired. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT && lhs.lhs != nil - && lhs.lhs.kind == nkind.N_DOT - && n.op == tkind.TK_ASSIGN) { + if (lhs.kind == syntax.nkind.N_DOT && lhs.lhs != nil + && lhs.lhs.kind == syntax.nkind.N_DOT + && n.op == syntax.tkind.TK_ASSIGN) { let rootname: str = ""; let rootoff: i32 = 0; let totaloff: i32 = 0; - let leaftype: *tinfo = nil; + let leaftype: *syntax.tinfo = nil; let slicedelta: i32 = -1; let isglobal: bool = false; let ptrroot: bool = false; @@ -34834,8 +34834,8 @@ fn cgassign(c: *cgen, n: *node) void = { // kept its old bytes (ken x5d: `o.r.min = 8: size` left // `is size` false). Only plain `=` reaches this walker // (TK_ASSIGN gate above). - if (typeistagged(leaftype)) { - let wlu: *tinfo = leaftype; + if (syntax.typeistagged(leaftype)) { + let wlu: *syntax.tinfo = leaftype; wlu = tichase(wlu); let wtsz: i32 = wlu.size: i32; if (viacx) { @@ -34856,7 +34856,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; return; }; - if (typeisstr(leaftype) || typeisslice(leaftype)) { + if (syntax.typeisstr(leaftype) || syntax.typeisslice(leaftype)) { // str/slice: store ptr/len/cap. cgexpr leaves // CX=cap, so the viacx base goes in DX (not CX) to // avoid clobbering it — same as the single-dot str @@ -34921,17 +34921,17 @@ fn cgassign(c: *cgen, n: *node) void = { let leafstruct: bool = false; let leafname: str = ""; if (leaftype != nil) { - let lp: *tinfo = leaftype; + let lp: *syntax.tinfo = leaftype; lp = tichase(lp); if (lp != nil) { - if (lp.kind == tykind.TY_STRUCT) { leafstruct = true; }; + if (lp.kind == syntax.tykind.TY_STRUCT) { leafstruct = true; }; }; - if (leaftype.kind == tykind.TY_NAMED) { + if (leaftype.kind == syntax.tykind.TY_NAMED) { leafname = leaftype.name; }; }; if (n.rhs != nil - && n.rhs.kind == nkind.N_CALL + && n.rhs.kind == syntax.nkind.N_CALL && leafstruct) { let lsi: *structinfo = structlookup(c, leafname); if (lsi != nil) { @@ -35015,7 +35015,7 @@ fn cgassign(c: *cgen, n: *node) void = { // LEAQ rootname(SB). // else → mode=0 (DST_BP), direct BP-rel, no reload. if (n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT + && n.rhs.kind == syntax.nkind.N_STRUCTLIT && leafstruct) { let lsi: *structinfo = structlookup(c, leafname); if (lsi != nil) { @@ -35036,7 +35036,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; if (n.rhs != nil - && n.rhs.kind == nkind.N_IDENT + && n.rhs.kind == syntax.nkind.N_IDENT && leafstruct) { let ssi: *structinfo = structlookup(c, leafname); let srhs: *local = localfindnode(c, n.rhs.str); @@ -35117,9 +35117,9 @@ fn cgassign(c: *cgen, n: *node) void = { return; };}; }; - if (typeisfloat(leaftype)) { + if (syntax.typeisfloat(leaftype)) { let mov: str = "MOVSD"; - if (typeisf32(leaftype)) { mov = "MOVSS"; }; + if (syntax.typeisf32(leaftype)) { mov = "MOVSS"; }; cgexpr(c, n.rhs); if (viacx) { if (ptrroot) { @@ -35192,24 +35192,24 @@ fn cgassign(c: *cgen, n: *node) void = { // Kept as fallback below the generalized walker for any shape // the walker doesn't recognize. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT) { - let base: *node = lhs.lhs; + if (lhs.kind == syntax.nkind.N_DOT) { + let base: *syntax.node = lhs.lhs; let fld: str = lhs.str; - if (base != nil) { if (base.kind == nkind.N_DOT) { - let inner: *node = base.lhs; + if (base != nil) { if (base.kind == syntax.nkind.N_DOT) { + let inner: *syntax.node = base.lhs; let innerfld: str = base.str; - if (inner != nil) { if (inner.kind == nkind.N_IDENT) { + if (inner != nil) { if (inner.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, inner.str); if (lc != nil) { if (lc.tnode != nil) { - let tn: *node = lc.tnode; - let lkind: nkind = tn.kind; + let tn: *syntax.node = lc.tnode; + let lkind: syntax.nkind = tn.kind; let outname: str; outname.ptr = nil; outname.len = 0; let isptr: bool = false; - if (lkind == nkind.N_TNAME) { outname = tn.str; }; - if (lkind == nkind.N_TPTR) { - let pe: *node = tn.lhs; - if (pe != nil) { if (pe.kind == nkind.N_TNAME) { + if (lkind == syntax.nkind.N_TNAME) { outname = tn.str; }; + if (lkind == syntax.nkind.N_TPTR) { + let pe: *syntax.node = tn.lhs; + if (pe != nil) { if (pe.kind == syntax.nkind.N_TNAME) { outname = pe.str; isptr = true; };}; @@ -35219,16 +35219,16 @@ fn cgassign(c: *cgen, n: *node) void = { if (osi != nil) { let ofi: *fieldinfo = osi.fields; for (ofi != nil) { - if (streq(ofi.fname, innerfld)) { - let oft: *node = ofi.tnode; - if (oft != nil) { if (oft.kind == nkind.N_TNAME) { + if (syntax.streq(ofi.fname, innerfld)) { + let oft: *syntax.node = ofi.tnode; + if (oft != nil) { if (oft.kind == syntax.nkind.N_TNAME) { if (aliasprimsize(c, oft.str) == 0) { let isi: *structinfo = structlookup(c, oft.str); if (isi != nil) { let ffi: *fieldinfo = isi.fields; for (ffi != nil) { - if (streq(ffi.fname, fld)) { - if (n.op == tkind.TK_ASSIGN) { + if (syntax.streq(ffi.fname, fld)) { + if (n.op == syntax.tkind.TK_ASSIGN) { let totoff: i32 = ofi.foff + ffi.foff; cgexpr(c, n.rhs); if (isstrtype(c, ffi.tnode)) { @@ -35312,7 +35312,7 @@ fn cgassign(c: *cgen, n: *node) void = { // forms (+= -= *= /=); other compounds fall back to // "evaluate rhs, replace". Mirrors C cgen's IDENT-assign path. if (lhs != nil) { - if (lhs.kind == nkind.N_IDENT) { + if (lhs.kind == syntax.nkind.N_IDENT) { let nm: str = lhs.str; let off: i32 = localfind(c, nm); if (off == 0) { @@ -35341,9 +35341,9 @@ fn cgassign(c: *cgen, n: *node) void = { let lvf: *letvar = c.lets; let isfg: bool = false; let isf32g: bool = false; - let lvftn: *node = nil; + let lvftn: *syntax.node = nil; for (lvf != nil) { - if (streq(lvf.name, nm)) { + if (syntax.streq(lvf.name, nm)) { isfg = isfloattype(c, lvf.tnode); isf32g = isf32type(c, lvf.tnode); lvftn = lvf.tnode; @@ -35369,7 +35369,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tLEAQ\t"); emitsymname(c, nm); emitline("(SB), CX\n"); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { emitline("\t"); emitline(mov); emitline("\tX0, (CX)\n"); @@ -35380,10 +35380,10 @@ fn cgassign(c: *cgen, n: *node) void = { // only, so we can't combine direct to memory. let fop: str; fop.ptr = nil; fop.len = 0; - if (n.op == tkind.TK_PLUSEQ) { fop = addf; }; - if (n.op == tkind.TK_MINUSEQ) { fop = subf; }; - if (n.op == tkind.TK_STAREQ) { fop = mulf; }; - if (n.op == tkind.TK_SLASHEQ) { fop = divf; }; + if (n.op == syntax.tkind.TK_PLUSEQ) { fop = addf; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { fop = subf; }; + if (n.op == syntax.tkind.TK_STAREQ) { fop = mulf; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { fop = divf; }; if (fop.len == 0) { // Unsupported (e.g., %= on float): // fall back to plain store of rhs. @@ -35409,15 +35409,15 @@ fn cgassign(c: *cgen, n: *node) void = { // into g's storage. The scalar store below would emit a // truncated `MOVQ AX, g(SB)` and drop the body. Mirror // of the C cgen N_ASSIGN global arm (cmd/w6c/cgen.c). - if (n.op == tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL && lvftn != nil) { + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil + && n.rhs.kind == syntax.nkind.N_CALL && lvftn != nil) { let gsz: i32 = 0; - if (lvftn.kind == nkind.N_TNAME) { + if (lvftn.kind == syntax.nkind.N_TNAME) { let gsi: *structinfo = structlookup(c, lvftn.str); if (gsi != nil) { gsz = structabisize(gsi); }; }; - if (lvftn.kind == nkind.N_TARRAY) { - let gat: *tinfo = lvftn.type_: *tinfo; + if (lvftn.kind == syntax.nkind.N_TARRAY) { + let gat: *syntax.tinfo = lvftn.type_: *syntax.tinfo; gat = tichase(gat); if (gat != nil) { gsz = gat.size: i32; }; }; @@ -35442,11 +35442,11 @@ fn cgassign(c: *cgen, n: *node) void = { // behaviour — no consumer (rule-10 aligned with cstage; // note non-float struct globals also truncate symmetrically // here, byte-id-clean — #276 covers both). - if (n.op == tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL && lvftn != nil - && lvftn.kind == nkind.N_TARRAY) { + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil + && n.rhs.kind == syntax.nkind.N_CALL && lvftn != nil + && lvftn.kind == syntax.nkind.N_TARRAY) { let aggsz: i32 = 0; - let aat: *tinfo = lvftn.type_: *tinfo; + let aat: *syntax.tinfo = lvftn.type_: *syntax.tinfo; aat = tichase(aat); if (aat != nil) { aggsz = aat.size: i32; }; if (aggsz > 0 && aggsz <= 24) { @@ -35488,16 +35488,16 @@ fn cgassign(c: *cgen, n: *node) void = { // addressable rhs → aggargsrcaddr + LEAQ g(SB), BX // + aggcopy. Pre-#49 every shape fell to the scalar // tail below: one MOVQ AX, g(SB). - if (n.op == tkind.TK_ASSIGN && lvftn != nil) { - let gau: *tinfo = lvftn.type_: *tinfo; + if (n.op == syntax.tkind.TK_ASSIGN && lvftn != nil) { + let gau: *syntax.tinfo = lvftn.type_: *syntax.tinfo; gau = tichase(gau); if (gau != nil) { - if (gau.kind == tykind.TY_STRUCT - || gau.kind == tykind.TY_ARRAY - || gau.kind == tykind.TY_TUPLE) { - if (n.rhs != nil && n.rhs.kind == nkind.N_STRUCTLIT) { + if (gau.kind == syntax.tykind.TY_STRUCT + || gau.kind == syntax.tykind.TY_ARRAY + || gau.kind == syntax.tykind.TY_TUPLE) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_STRUCTLIT) { let gsi49: *structinfo = nil; - if (lvftn.kind == nkind.N_TNAME) { + if (lvftn.kind == syntax.nkind.N_TNAME) { gsi49 = structlookup(c, lvftn.str); }; if (gsi49 == nil) { @@ -35510,7 +35510,7 @@ fn cgassign(c: *cgen, n: *node) void = { cgstructlitfill(c, gsi49, n.rhs, 2, 0, nm, 0); return; }; - if (n.rhs != nil && n.rhs.kind == nkind.N_CALL) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL) { let m49e: str = "assign: aggregate call receive shape unwired (task #49/#276/rule-7)\n"; os.write(2, m49e.ptr, m49e.len: u64); os.exit(1); @@ -35529,7 +35529,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; cgexpr(c, n.rhs); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { // str/slice top-level let: str IS []u8, so both store the // full 3-word {ptr,len,cap}. Stash cap in DI before LEAQ // overwrites CX, then store ptr/len/cap via &name(SB) @@ -35554,7 +35554,7 @@ fn cgassign(c: *cgen, n: *node) void = { // a prior `*(&letname): *iN` deref-store doesn't // leave stale upper bytes feeding the combine. let glop: str = localloadop(c, lvftn); - if (streq(glop, "MOVQ")) { + if (syntax.streq(glop, "MOVQ")) { emitline("\tMOVQ\t"); emitsymname(c, nm); emitline("(SB), BX\n"); @@ -35567,22 +35567,22 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\t(CX), BX\n"); }; let didcompound: bool = true; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); } - else { if (n.op == tkind.TK_LSHIFTEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); } + else { if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tSHLQ\tCX, BX\n"); } - else { if (n.op == tkind.TK_RSHIFTEQ) { + else { if (n.op == syntax.tkind.TK_RSHIFTEQ) { // #136: signed RSHIFTEQ → SARQ. let unsignd_r: bool = false; if (lvftn != nil) { if (lvftn.type_ != nil) { - unsignd_r = typeisunsigned(lvftn.type_: *tinfo); + unsignd_r = syntax.typeisunsigned(lvftn.type_: *syntax.tinfo); }; }; if (!unsignd_r) { @@ -35598,10 +35598,10 @@ fn cgassign(c: *cgen, n: *node) void = { // CQO (or zero DX), IDIVQ (or DIVQ) CX, // ferry AX or DX back to BX for the shared // store-BX tail below. - else { if (n.op == tkind.TK_SLASHEQ || n.op == tkind.TK_PERCENTEQ) { + else { if (n.op == syntax.tkind.TK_SLASHEQ || n.op == syntax.tkind.TK_PERCENTEQ) { let unsignd: bool = false; if (lvftn != nil) { - unsignd = typeisunsigned(lvftn.type_: *tinfo); + unsignd = syntax.typeisunsigned(lvftn.type_: *syntax.tinfo); }; if (!unsignd) { unsignd = nodeisunsigned(c, n.rhs); @@ -35615,7 +35615,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ) { emitline("\tMOVQ\tAX, BX\n"); } else { emitline("\tMOVQ\tDX, BX\n"); @@ -35644,9 +35644,9 @@ fn cgassign(c: *cgen, n: *node) void = { // returning call — rettupleof distinguishes it from a // >24B struct, which keeps its own size-aware recv // below. Mirrors the cstage N_ASSIGN-ident over-cap arm. - if (n.op == tkind.TK_ASSIGN && n.rhs != nil - && n.rhs.kind == nkind.N_CALL) { - let rtup: *node = rettupleof(c, n.rhs); + if (n.op == syntax.tkind.TK_ASSIGN && n.rhs != nil + && n.rhs.kind == syntax.nkind.N_CALL) { + let rtup: *syntax.node = rettupleof(c, n.rhs); if (rtup != nil) { let rscs: i32 = callsretsize(c, n.rhs); if (rscs > 0) { @@ -35693,11 +35693,11 @@ fn cgassign(c: *cgen, n: *node) void = { // doesn't emit (tracked separately as the cstage/ // wwstage MOVW divergence task). if (lcn != nil) { - let lctn: *node = lcn.tnode; + let lctn: *syntax.node = lcn.tnode; let lcsname: str; lcsname.ptr = nil; lcsname.len = 0; if (lctn != nil) { - if (lctn.kind == nkind.N_TNAME) { + if (lctn.kind == syntax.nkind.N_TNAME) { lcsname = lctn.str; }; }; @@ -35712,9 +35712,9 @@ fn cgassign(c: *cgen, n: *node) void = { // (natural 12, ABI 16) to MOVQ+MOVL where // cstage writes MOVQ+MOVQ. let lcnsz: i32 = structabisize(lcsi); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { if (n.rhs != nil - && n.rhs.kind == nkind.N_STRUCTLIT) { + && n.rhs.kind == syntax.nkind.N_STRUCTLIT) { // Delegate to the shared BP-relative // structlit fill helper. Handles // TK_ELLIPSIS autofill + per-field @@ -35730,7 +35730,7 @@ fn cgassign(c: *cgen, n: *node) void = { return; }; if (n.rhs != nil - && n.rhs.kind == nkind.N_CALL) { + && n.rhs.kind == syntax.nkind.N_CALL) { // sret receive (#23): plain // TY_STRUCT > 24B from a CALL. // `s` is the prealloc dest; the @@ -35795,12 +35795,12 @@ fn cgassign(c: *cgen, n: *node) void = { // stores. Array natural size (tinfo.size = sub.size*len) // mirrors cstage lu->size. No structfloatclass (pure-int // element arrays). - if (lcn != nil && n.op == tkind.TK_ASSIGN - && n.rhs != nil && n.rhs.kind == nkind.N_CALL) { - let acati: *tinfo = nil; - if (lcn.tnode != nil) { acati = lcn.tnode.type_: *tinfo; }; + if (lcn != nil && n.op == syntax.tkind.TK_ASSIGN + && n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL) { + let acati: *syntax.tinfo = nil; + if (lcn.tnode != nil) { acati = lcn.tnode.type_: *syntax.tinfo; }; acati = tichase(acati); - if (acati != nil && acati.kind == tykind.TY_ARRAY) { + if (acati != nil && acati.kind == syntax.tykind.TY_ARRAY) { let lcsz: i32 = acati.size: i32; if (lcsz > 24) { let rscs: i32 = callsretsize(c, n.rhs); @@ -35867,7 +35867,7 @@ fn cgassign(c: *cgen, n: *node) void = { mulf = "MULSS"; divf = "DIVSS"; }; - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { emitline("\t"); emitline(mov); emitline("\tX0, "); @@ -35877,10 +35877,10 @@ fn cgassign(c: *cgen, n: *node) void = { }; let fop: str; fop.ptr = nil; fop.len = 0; - if (n.op == tkind.TK_PLUSEQ) { fop = addf; }; - if (n.op == tkind.TK_MINUSEQ) { fop = subf; }; - if (n.op == tkind.TK_STAREQ) { fop = mulf; }; - if (n.op == tkind.TK_SLASHEQ) { fop = divf; }; + if (n.op == syntax.tkind.TK_PLUSEQ) { fop = addf; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { fop = subf; }; + if (n.op == syntax.tkind.TK_STAREQ) { fop = mulf; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { fop = divf; }; if (fop.len == 0) { emitline("\t"); emitline(mov); @@ -35913,19 +35913,19 @@ fn cgassign(c: *cgen, n: *node) void = { // below and word0-copied `b = a` (cstage cgen.c // N_ASSIGN aggregate-ident twin). Kind keys off the // checker-STAMPED tinfo (#209/#211 discipline). - if (n.op == tkind.TK_ASSIGN) { - let agu: *tinfo = nil; + if (n.op == syntax.tkind.TK_ASSIGN) { + let agu: *syntax.tinfo = nil; if (lcn != nil) { if (lcn.tnode != nil) { - agu = lcn.tnode.type_: *tinfo; + agu = lcn.tnode.type_: *syntax.tinfo; }; }; agu = tichase(agu); if (agu != nil) { - if (agu.kind == tykind.TY_STRUCT - || agu.kind == tykind.TY_ARRAY - || agu.kind == tykind.TY_TUPLE) { - if (n.rhs != nil && n.rhs.kind == nkind.N_STRUCTLIT) { + if (agu.kind == syntax.tykind.TY_STRUCT + || agu.kind == syntax.tykind.TY_ARRAY + || agu.kind == syntax.tykind.TY_TUPLE) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_STRUCTLIT) { // wwstage-only bail: the fill is // structinfo-keyed; a literal // reaching past the name-keyed arm @@ -35938,7 +35938,7 @@ fn cgassign(c: *cgen, n: *node) void = { os.write(2, m49a.ptr, m49a.len: u64); os.exit(1); }; - if (n.rhs != nil && n.rhs.kind == nkind.N_CALL) { + if (n.rhs != nil && n.rhs.kind == syntax.nkind.N_CALL) { let m49b: str = "assign: aggregate call receive shape unwired (task #49/#276/rule-7)\n"; os.write(2, m49b.ptr, m49b.len: u64); os.exit(1); @@ -35957,7 +35957,7 @@ fn cgassign(c: *cgen, n: *node) void = { }; }; cgexpr(c, n.rhs); - if (n.op == tkind.TK_ASSIGN) { + if (n.op == syntax.tkind.TK_ASSIGN) { emitline("\tMOVQ\tAX, "); emitoff(off: i64); emitline("(BP)\n"); @@ -35981,14 +35981,14 @@ fn cgassign(c: *cgen, n: *node) void = { // after a 4B deref-store leaves the upper bytes stale. let llop: str = "MOVQ"; if (lcn != nil) { llop = localloadop(c, lcn.tnode); }; - if (streq(llop, "MOVQ")) { - if (n.op == tkind.TK_PLUSEQ) { + if (syntax.streq(llop, "MOVQ")) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, "); emitoff(off: i64); emitline("(BP)\n"); return; }; - if (n.op == tkind.TK_MINUSEQ) { + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, "); emitoff(off: i64); emitline("(BP)\n"); @@ -36001,23 +36001,23 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\t"); emitoff(off: i64); emitline("(BP), BX\n"); - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); }; - if (n.op == tkind.TK_LSHIFTEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tAX, BX\n"); }; + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tMOVQ\tAX, CX\n"); emitline("\tSHLQ\tCX, BX\n"); }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_RSHIFTEQ) { // #136: signed RSHIFTEQ → SARQ. let unsignd_r: bool = false; if (lcn != nil) { if (lcn.tnode != nil) { if (lcn.tnode.type_ != nil) { - unsignd_r = typeisunsigned(lcn.tnode.type_: *tinfo); + unsignd_r = syntax.typeisunsigned(lcn.tnode.type_: *syntax.tinfo); }; }; }; @@ -36035,11 +36035,11 @@ fn cgassign(c: *cgen, n: *node) void = { // shape the global/deref siblings took. Park rhs in // CX, slot value (BX) into AX, CQO/IDIVQ, ferry AX // (quotient) or DX (remainder) back to BX. - if (n.op == tkind.TK_SLASHEQ || n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ || n.op == syntax.tkind.TK_PERCENTEQ) { let unsignd: bool = false; if (lcn != nil) { if (lcn.tnode != nil) { - unsignd = typeisunsigned(lcn.tnode.type_: *tinfo); + unsignd = syntax.typeisunsigned(lcn.tnode.type_: *syntax.tinfo); }; }; if (!unsignd) { @@ -36054,7 +36054,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_SLASHEQ) { emitline("\tMOVQ\tAX, BX\n"); } else { emitline("\tMOVQ\tDX, BX\n"); @@ -36078,20 +36078,20 @@ fn cgassign(c: *cgen, n: *node) void = { // indexed/deref shape returned from its legacy arm), and the // C1.25 aggregate branch fills via @placescr. if (lhs != nil) { - if (lhs.kind == nkind.N_DOT || lhs.kind == nkind.N_INDEX - || (lhs.kind == nkind.N_UN && lhs.op == tkind.TK_STAR)) { - let ft: *tinfo = lhs.type_: *tinfo; - let fu: *tinfo = ft; + if (lhs.kind == syntax.nkind.N_DOT || lhs.kind == syntax.nkind.N_INDEX + || (lhs.kind == syntax.nkind.N_UN && lhs.op == syntax.tkind.TK_STAR)) { + let ft: *syntax.tinfo = lhs.type_: *syntax.tinfo; + let fu: *syntax.tinfo = ft; fu = tichase(fu); let fsz: i32 = 8; if (ft != nil) { fsz = ft.size: i32; }; - if (typeisfloat(ft)) { + if (syntax.typeisfloat(ft)) { let mf: str = "assign-resolver: float field not wired (rule-7)\n"; os.write(2, mf.ptr, mf.len: u64); os.exit(1); }; if (fu != nil) { - if (fu.kind == tykind.TY_TAGGED) { + if (fu.kind == syntax.tykind.TY_TAGGED) { let mt: str = "assign-resolver: tagged field not wired (rule-7)\n"; os.write(2, mt.ptr, mt.len: u64); os.exit(1); @@ -36106,16 +36106,16 @@ fn cgassign(c: *cgen, n: *node) void = { // (loud-first, wire-next). Compound on an // aggregate is meaningless and stays loud. // Mirror of the cstage cgen.c C1.25 arm. - if (fu.kind == tykind.TY_STRUCT - || fu.kind == tykind.TY_ARRAY - || fu.kind == tykind.TY_TUPLE) { - if (n.op != tkind.TK_ASSIGN) { + if (fu.kind == syntax.tykind.TY_STRUCT + || fu.kind == syntax.tykind.TY_ARRAY + || fu.kind == syntax.tykind.TY_TUPLE) { + if (n.op != syntax.tkind.TK_ASSIGN) { let mac: str = "assign-resolver: compound on aggregate field not wired (rule-7)\n"; os.write(2, mac.ptr, mac.len: u64); os.exit(1); }; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { + if (n.rhs.kind == syntax.nkind.N_CALL) { // sret-class needs a runtime-RDI dest // (the #234-tail deferral); the ≤24B // reg-return receive is task #24. The @@ -36136,8 +36136,8 @@ fn cgassign(c: *cgen, n: *node) void = { let placed: bool = false; let isslit: bool = false; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_STRUCTLIT - && fu.kind == tykind.TY_STRUCT) { + if (n.rhs.kind == syntax.nkind.N_STRUCTLIT + && fu.kind == syntax.tykind.TY_STRUCT) { isslit = true; }; }; @@ -36155,7 +36155,7 @@ fn cgassign(c: *cgen, n: *node) void = { // below may clobber AX/CX freely. let sname: str; sname.ptr = nil; sname.len = 0; - if (ft.kind == tykind.TY_NAMED) { + if (ft.kind == syntax.tykind.TY_NAMED) { sname = ft.name; }; let si: *structinfo = nil; @@ -36210,13 +36210,13 @@ fn cgassign(c: *cgen, n: *node) void = { }; let fstrsl: bool = false; if (fu != nil) { - if (fu.kind == tykind.TY_STR - || fu.kind == tykind.TY_SLICE) { + if (fu.kind == syntax.tykind.TY_STR + || fu.kind == syntax.tykind.TY_SLICE) { fstrsl = true; }; }; if (fstrsl) { - if (n.op != tkind.TK_ASSIGN) { + if (n.op != syntax.tkind.TK_ASSIGN) { let ms: str = "assign-resolver: compound on str/slice field not wired (rule-7)\n"; os.write(2, ms.ptr, ms.len: u64); os.exit(1); @@ -36238,7 +36238,7 @@ fn cgassign(c: *cgen, n: *node) void = { emitline("\tMOVQ\tCX, 16(DX)\n"); return; }; - } else { if (n.op == tkind.TK_ASSIGN) { + } else { if (n.op == syntax.tkind.TK_ASSIGN) { cgexpr(c, n.rhs); emitline("\tPUSHQ\tAX\n"); if (cgplaceaddr(c, lhs, "BX")) { @@ -36259,32 +36259,32 @@ fn cgassign(c: *cgen, n: *node) void = { cgexpr(c, n.rhs); emitline("\tPUSHQ\tAX\n"); if (cgplaceaddr(c, lhs, "BX")) { - let lop: str = loadopsz(typeissigned(ft), fsz); + let lop: str = loadopsz(syntax.typeissigned(ft), fsz); emitline("\t"); emitline(lop); emitline("\t(BX), AX\n"); emitline("\tPOPQ\tCX\n"); - let unsignd: bool = typeisunsigned(ft); + let unsignd: bool = syntax.typeisunsigned(ft); let wired: bool = false; - if (n.op == tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_SLASHEQ) { + if (n.op == syntax.tkind.TK_PLUSEQ) { emitline("\tADDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_MINUSEQ) { emitline("\tSUBQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_STAREQ) { emitline("\tIMULQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_AMPEQ) { emitline("\tANDQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_PIPEEQ) { emitline("\tORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_CARETEQ) { emitline("\tXORQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_SLASHEQ) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; wired = true; }; - if (n.op == tkind.TK_PERCENTEQ) { + if (n.op == syntax.tkind.TK_PERCENTEQ) { if (unsignd) { emitline("\tMOVQ\t$0, DX\n"); emitline("\tDIVQ\tCX\n"); } else { emitline("\tCQO\n"); emitline("\tIDIVQ\tCX\n"); }; emitline("\tMOVQ\tDX, AX\n"); wired = true; }; - if (n.op == tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; - if (n.op == tkind.TK_RSHIFTEQ) { + if (n.op == syntax.tkind.TK_LSHIFTEQ) { emitline("\tSHLQ\tCX, AX\n"); wired = true; }; + if (n.op == syntax.tkind.TK_RSHIFTEQ) { if (unsignd) { emitline("\tSHRQ\tCX, AX\n"); } else { emitline("\tSARQ\tCX, AX\n"); }; wired = true; @@ -36338,36 +36338,36 @@ import strconv; // ---- statement cgen -------------------------------------------------- -fn cgstmt(c: *cgen, n: *node) void = { +fn cgstmt(c: *cgen, n: *syntax.node) void = { if (n == nil) { return; }; - let k: nkind = n.kind; + let k: syntax.nkind = n.kind; - if (k == nkind.N_BLOCK) { cgblock(c, n); return; }; + if (k == syntax.nkind.N_BLOCK) { cgblock(c, n); return; }; - if (k == nkind.N_RETURN) { cgreturn(c, n); return; }; + if (k == syntax.nkind.N_RETURN) { cgreturn(c, n); return; }; - if (k == nkind.N_EXPRSTMT) { cgexprstmt(c, n); return; }; + if (k == syntax.nkind.N_EXPRSTMT) { cgexprstmt(c, n); return; }; - if (k == nkind.N_LET) { cglet(c, n); return; }; + if (k == syntax.nkind.N_LET) { cglet(c, n); return; }; - if (k == nkind.N_IF) { cgif(c, n); return; }; + if (k == syntax.nkind.N_IF) { cgif(c, n); return; }; - if (k == nkind.N_FOR) { cgfor(c, n); return; }; + if (k == syntax.nkind.N_FOR) { cgfor(c, n); return; }; - if (k == nkind.N_FORRANGE) { cgforrange(c, n); return; }; + if (k == syntax.nkind.N_FORRANGE) { cgforrange(c, n); return; }; - if (k == nkind.N_SWITCH) { cgswitch(c, n); return; }; + if (k == syntax.nkind.N_SWITCH) { cgswitch(c, n); return; }; - if (k == nkind.N_MASSIGN) { cgmassign(c, n); return; }; + if (k == syntax.nkind.N_MASSIGN) { cgmassign(c, n); return; }; - if (k == nkind.N_MLET) { cgmlet(c, n); return; }; + if (k == syntax.nkind.N_MLET) { cgmlet(c, n); return; }; - if (k == nkind.N_BREAK) { cgbreak(c, n); return; }; - if (k == nkind.N_CONTINUE) { cgcontinue(c, n); return; }; + if (k == syntax.nkind.N_BREAK) { cgbreak(c, n); return; }; + if (k == syntax.nkind.N_CONTINUE) { cgcontinue(c, n); return; }; - if (k == nkind.N_YIELD) { cgyield(c, n); return; }; + if (k == syntax.nkind.N_YIELD) { cgyield(c, n); return; }; - if (k == nkind.N_DEFER) { + if (k == syntax.nkind.N_DEFER) { // #40: at the cap, fail loud in BOTH stages rather than // silently drop the deferred call. cstage's DEFER_MAX was 32 // and also dropped silently past it; the runtime-correct target @@ -36385,7 +36385,7 @@ fn cgstmt(c: *cgen, n: *node) void = { c.lastwasreturn = 0; }; -fn cgyield(c: *cgen, n: *node) void = { +fn cgyield(c: *cgen, n: *syntax.node) void = { // Evaluate the value into AX (and BX for str), then JMP to the // enclosing match's end label. Falls through silently if there // is no active match — should be a checker error eventually. @@ -36400,7 +36400,7 @@ fn cgyield(c: *cgen, n: *node) void = { return; }; -fn cgblock(c: *cgen, n: *node) void = { +fn cgblock(c: *cgen, n: *syntax.node) void = { // Save/restore the locals head across the block (post-#27). // Inner-scope `let` bindings prepend to c.locals via localadd; // without this restore, the prepended stubs leak into sibling @@ -36413,7 +36413,7 @@ fn cgblock(c: *cgen, n: *node) void = { // restore at the function's outermost block — defers (and the // implicit-return epilogue) need locals intact. let saved: *local = c.locals; - let s: *node = n.list; + let s: *syntax.node = n.list; for (s != nil) { cgstmt(c, s); s = s.next; @@ -36470,55 +36470,55 @@ fn tupsse(i: i32) str = { // predicates this absorbs were the #22 neighbor-slot/zeros miscompile. // Checker twin: check.ww tupleelemslot / check.c N_TTUPLE; cstage twin: // tuple_eslot (cmd/w6c/cgen.c). -export fn tupeslot(ti: *tinfo) i32 = { - let t: *tinfo = ti; +export fn tupeslot(ti: *syntax.tinfo) i32 = { + let t: *syntax.tinfo = ti; t = tichase(t); if (t == nil) { return 8; }; - if (t.kind == tykind.TY_VOID) { return 0; }; + if (t.kind == syntax.tykind.TY_VOID) { return 0; }; // a literal tuple's stamped element can be untyped_str (size 0) — // it occupies the str header slot (the C-t2 type_isstr lesson). - if (t.kind == tykind.TY_UNTYPED_STR) { return tyslicesize(): i32; }; - if (t.kind == tykind.TY_STR || t.kind == tykind.TY_SLICE || - t.kind == tykind.TY_TAGGED) { + if (t.kind == syntax.tykind.TY_UNTYPED_STR) { return tyslicesize(): i32; }; + if (t.kind == syntax.tykind.TY_STR || t.kind == syntax.tykind.TY_SLICE || + t.kind == syntax.tykind.TY_TAGGED) { return ((t.size + 7u64) & ~7u64): i32; }; return 8; }; -export fn tupeslotn(n: *node) i32 = { +export fn tupeslotn(n: *syntax.node) i32 = { if (n == nil) { return 8; }; - return tupeslot(n.type_: *tinfo); + return tupeslot(n.type_: *syntax.tinfo); }; // rettupleof — the N_TTUPLE return-type node of an N_CALL rhs (else nil). // wwstage has no checker, so the receive sites read each tuple element's // width from the called fn's declared return type. Mirrors the callee // resolution shared by cgmlet/cgmassign. -fn rettupleof(c: *cgen, rhs: *node) *node = { +fn rettupleof(c: *cgen, rhs: *syntax.node) *syntax.node = { if (rhs == nil) { return nil; }; - if (rhs.kind != nkind.N_CALL) { return nil; }; - let callee: *node = rhs.lhs; + if (rhs.kind != syntax.nkind.N_CALL) { return nil; }; + let callee: *syntax.node = rhs.lhs; if (callee == nil) { return nil; }; let cnm: str; cnm.ptr = nil; cnm.len = 0; let cmod: str; cmod.ptr = nil; cmod.len = 0; - if (callee.kind == nkind.N_IDENT) { + if (callee.kind == syntax.nkind.N_IDENT) { cnm = callee.str; cmod = c.curmod; }; - if (callee.kind == nkind.N_DOT) { + if (callee.kind == syntax.nkind.N_DOT) { cnm = callee.str; if (callee.lhs != nil) { - if (callee.lhs.kind == nkind.N_IDENT) { + if (callee.lhs.kind == syntax.nkind.N_IDENT) { cmod = callee.lhs.str; }; }; }; if (cnm.len == 0) { return nil; }; - let rtyp: *node = fnretlookupmod(c, cnm, cmod); + let rtyp: *syntax.node = fnretlookupmod(c, cnm, cmod); if (rtyp == nil) { return nil; }; - if (rtyp.kind != nkind.N_TTUPLE) { return nil; }; + if (rtyp.kind != syntax.nkind.N_TTUPLE) { return nil; }; return rtyp; }; @@ -36531,24 +36531,24 @@ fn rettupleof(c: *cgen, rhs: *node) *node = { // nodes). Mirror of cstage node_tuplearg; the cgcall push site // loud-stops any other tuple-typed source shape (rule 7). rettupleof // stays N_CALL-scoped for the destructure/reassign receive sites. -fn nodetuplearg(c: *cgen, a: *node) *node = { +fn nodetuplearg(c: *cgen, a: *syntax.node) *syntax.node = { if (a == nil) { return nil; }; - if (a.kind == nkind.N_TUPLE) { return a; }; - if (a.kind == nkind.N_IDENT) { + if (a.kind == syntax.nkind.N_TUPLE) { return a; }; + if (a.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, a.str); if (lc == nil) { return nil; }; - let tn: *node = lc.tnode; - for (tn != nil && tn.kind == nkind.N_TNAME) { + let tn: *syntax.node = lc.tnode; + for (tn != nil && tn.kind == syntax.nkind.N_TNAME) { tn = aliaslookup(c, tn.str); }; if (tn != nil) { - if (tn.kind == nkind.N_TTUPLE) { return tn; }; + if (tn.kind == syntax.nkind.N_TTUPLE) { return tn; }; }; return nil; }; - let t: *node = inferletcalltype(c, a); + let t: *syntax.node = inferletcalltype(c, a); if (t != nil) { - if (t.kind == nkind.N_TTUPLE) { return t; }; + if (t.kind == syntax.nkind.N_TTUPLE) { return t; }; }; return nil; }; @@ -36560,7 +36560,7 @@ fn nodetuplearg(c: *cgen, a: *node) *node = { // registers; a float rides the SSE cursor (X0,X1); a scalar stores 1 // INTEGER word. The caller owns the dual cursor (validated + // advanced). Byte-identical to the cstage tuple_store (cmd/w6c/cgen.c). -fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *node) void = { +fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *syntax.node) void = { if (eslot == 0) { return; }; // void element: the checker's 0-slot if (eslot > 8) { let k: i32 = 0; @@ -36602,7 +36602,7 @@ fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *node) os.write(2, ls.ptr, ls.len: u64); os.write(2, " ".ptr, 1u64); }; - let kn: str = nkname(tn.kind); + let kn: str = syntax.nkname(tn.kind); os.write(2, kn.ptr, kn.len: u64); os.write(2, "\n".ptr, 1u64); os.exit(1); @@ -36639,7 +36639,7 @@ fn tupstore(c: *cgen, gpcur: i32, ssecur: i32, off: i32, eslot: i32, tn: *node) // declared-TAGGED slot counted ONE word here while the receive walks // the declared eslot — the cursor shifted and every later element // read garbage. Declared-tagged keys the count on the DECLARED box. -fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { +fn tuplitgpwords(c: *cgen, e: *syntax.node, dtn: *syntax.node) i32 = { if (dtn != nil) { if (istaggedtype(c, dtn)) { return tupeslotn(dtn) / 8; }; }; @@ -36647,10 +36647,10 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { if (nodeisstr(c, e) || nodeisslice(c, e)) { return (tyslicesize() / 8i64): i32; }; - let t: *tinfo = e.type_: *tinfo; + let t: *syntax.tinfo = e.type_: *syntax.tinfo; t = tichase(t); - if (t != nil && (t.kind == tykind.TY_TAGGED || - t.kind == tykind.TY_VOID)) { + if (t != nil && (t.kind == syntax.tykind.TY_TAGGED || + t.kind == syntax.tykind.TY_VOID)) { return tupeslotn(e) / 8; }; return 1; @@ -36673,11 +36673,11 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { // tagged-@retscr shape) and pushes the box words. A tagged->tagged // SUBSET element (eslot mismatch) needs a tag remap on the way into // the slot — loud (rule 7, the #23/#40 widening family). -fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { - let t: *tinfo = e.type_: *tinfo; +fn tuplitpushelem(c: *cgen, e: *syntax.node, dtn: *syntax.node) void = { + let t: *syntax.tinfo = e.type_: *syntax.tinfo; t = tichase(t); let etagged: bool = false; - if (t != nil) { if (t.kind == tykind.TY_TAGGED) { etagged = true; }; }; + if (t != nil) { if (t.kind == syntax.tykind.TY_TAGGED) { etagged = true; }; }; if (dtn != nil) { if (istaggedtype(c, dtn) && !etagged) { let eslot: i32 = tupeslotn(dtn); @@ -36690,7 +36690,7 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { emitline("(BP)\n"); z += 8; }; - cgwidentaggedstore(c, dtn.type_: *tinfo, e, + cgwidentaggedstore(c, dtn.type_: *syntax.tinfo, e, "BP", scr, eslot); let pk: i32 = 0; for (pk < eslot / 8) { @@ -36712,7 +36712,7 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { if (etagged) { let eslot: i32 = tupeslotn(e); let eoff: i32 = 0; - if (e.kind == nkind.N_IDENT) { eoff = localfind(c, e.str); }; + if (e.kind == syntax.nkind.N_IDENT) { eoff = localfind(c, e.str); }; if (eoff == 0) { let m22: str = "#22a: tagged tuple element from a non-local source shape unwired (ident locals only; rule 7; call-source is task #41, widening #23, deref/cast #35)\n"; os.write(2, m22.ptr, m22.len: u64); @@ -36729,7 +36729,7 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { return; }; cgexpr(c, e); - if (t != nil && t.kind == tykind.TY_VOID) { return; }; + if (t != nil && t.kind == syntax.tykind.TY_VOID) { return; }; emitline("\tPUSHQ\tAX\n"); if (nodeisstr(c, e) || nodeisslice(c, e)) { emitline("\tPUSHQ\tBX\n"); @@ -36755,18 +36755,18 @@ fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { // declared eslot — see tuplitgpwords / tuplitpushelem. Mirrors cstage // cg_tuple_lit_to_cursor's decl walk; decl.list nodes wrap the elem // type in .lhs (the c.fnret.list shape the over-cap arm walks). -fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { - let dp0: *node = nil; +fn cgtuplelittocursor(c: *cgen, tuple: *syntax.node, decl: *syntax.node) void = { + let dp0: *syntax.node = nil; if (decl != nil) { - if (decl.kind == nkind.N_TTUPLE) { dp0 = decl.list; }; + if (decl.kind == syntax.nkind.N_TTUPLE) { dp0 = decl.list; }; }; let ssecap: i32 = TUPLE_SSECAP; let gptotal: i32 = 0; let ssecount: i32 = 0; - let dp: *node = dp0; - let e: *node = tuple.list; + let dp: *syntax.node = dp0; + let e: *syntax.node = tuple.list; for (e != nil) { - let dtn: *node = nil; + let dtn: *syntax.node = nil; if (dp != nil) { dtn = dp.lhs; }; let dtagged: bool = false; if (dtn != nil) { dtagged = istaggedtype(c, dtn); }; @@ -36791,7 +36791,7 @@ fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { dp = dp0; e = tuple.list; for (e != nil) { - let dtn: *node = nil; + let dtn: *syntax.node = nil; if (dp != nil) { dtn = dp.lhs; }; let dtagged: bool = false; if (dtn != nil) { dtagged = istaggedtype(c, dtn); }; @@ -36821,7 +36821,7 @@ fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { dp = dp0; e = tuple.list; for (e != nil) { - let dtn: *node = nil; + let dtn: *syntax.node = nil; if (dp != nil) { dtn = dp.lhs; }; let dtagged: bool = false; if (dtn != nil) { dtagged = istaggedtype(c, dtn); }; @@ -36849,14 +36849,14 @@ fn cgtuplelittocursor(c: *cgen, tuple: *node, decl: *node) void = { // / `return t` / `let q = t` over a tuple ident leave the whole tuple in the // cursor, not just word0 in AX. Over-cap loud-stops (rule 7; #10). Mirror of // cstage cg_tuple_slot_to_cursor. -fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { +fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *syntax.tinfo) void = { let gptotal: i32 = 0; let ssecount: i32 = 0; - let el: *ttupleelem = tu.tupleelems; + let el: *syntax.ttupleelem = tu.tupleelems; for (el != nil) { - let et: *tinfo = el.type_; + let et: *syntax.tinfo = el.type_; et = tichase(et); - if (et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64)) { + if (et != nil && (et.kind == syntax.tykind.TY_F32 || et.kind == syntax.tykind.TY_F64)) { ssecount = ssecount + 1; } else { gptotal = gptotal + tupeslot(el.type_) / 8; @@ -36873,13 +36873,13 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { let foff: i32 = 0; el = tu.tupleelems; for (el != nil) { - let et: *tinfo = el.type_; + let et: *syntax.tinfo = el.type_; et = tichase(et); - let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); + let isflt: bool = et != nil && (et.kind == syntax.tykind.TY_F32 || et.kind == syntax.tykind.TY_F64); let eslot: i32 = tupeslot(el.type_); if (isflt) { let mov: str = "MOVSD"; - if (et.kind == tykind.TY_F32) { mov = "MOVSS"; }; + if (et.kind == syntax.tykind.TY_F32) { mov = "MOVSS"; }; emitline("\t"); emitline(mov); emitline("\t"); emitoff((srcoff + foff): i64); emitline("(BP), "); @@ -36912,13 +36912,13 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { // elements ride a different SysV class — loud-stop (rule 7; the per- // eightbyte tagged-tuple-payload classification is the #243 follow-up). // Mirror of cstage cg_tagged_tuple_payload_shift. -fn cgtaggedtuplepayloadshift(c: *cgen, tup: *tinfo) void = { +fn cgtaggedtuplepayloadshift(c: *cgen, tup: *syntax.tinfo) void = { let words: i32 = 0; - let el: *ttupleelem = tup.tupleelems; + let el: *syntax.ttupleelem = tup.tupleelems; for (el != nil) { - let et: *tinfo = el.type_; + let et: *syntax.tinfo = el.type_; et = tichase(et); - let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); + let isflt: bool = et != nil && (et.kind == syntax.tykind.TY_F32 || et.kind == syntax.tykind.TY_F64); if (isflt || tupeslot(el.type_) != 8) { let msg: str = "tuple-in-union ? unwrap: float/slice/str/tagged payload element needs SysV per-eightbyte classification (see #243); only integer tuple payloads supported\n"; os.write(2, msg.ptr, msg.len: u64); @@ -36943,9 +36943,9 @@ fn cgtaggedtuplepayloadshift(c: *cgen, tup: *tinfo) void = { }; }; -fn cgreturn(c: *cgen, n: *node) void = { +fn cgreturn(c: *cgen, n: *syntax.node) void = { rundefers(c); - let rhs: *node = n.lhs; + let rhs: *syntax.node = n.lhs; if (rhs != nil) { // #83 / #164 (#107): positional register-return over a SysV // dual class cursor (harec create_unpack_bindings, ref/harec/src/ @@ -36968,7 +36968,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // below, which routes it via cgwidentaggedstore. Without this // guard the bare-tuple arm fired first and dropped the tag, // returning (AX=word0, DX=word1) with no tag word. - if (rhs.kind == nkind.N_TUPLE && !istaggedtype(c, c.fnret)) { + if (rhs.kind == syntax.nkind.N_TUPLE && !istaggedtype(c, c.fnret)) { let ssecap: i32 = TUPLE_SSECAP; // X0,X1 per SysV let gptotal: i32 = 0; let ssecount: i32 = 0; @@ -36980,16 +36980,16 @@ fn cgreturn(c: *cgen, n: *node) void = { // declared eslot (2 words sent for a 3-word shape; // ken /tmp/ken57 p8/p9). Same pt walk the over-cap arm // already does (#240/#22b). Mirrors cstage cgreturn. - let rp0: *node = nil; + let rp0: *syntax.node = nil; if (c.fnret != nil) { - if (c.fnret.kind == nkind.N_TTUPLE) { + if (c.fnret.kind == syntax.nkind.N_TTUPLE) { rp0 = c.fnret.list; }; }; - let rp: *node = rp0; - let e: *node = rhs.list; + let rp: *syntax.node = rp0; + let e: *syntax.node = rhs.list; for (e != nil) { - let rdtn: *node = nil; + let rdtn: *syntax.node = nil; if (rp != nil) { rdtn = rp.lhs; }; let rdtag: bool = false; if (rdtn != nil) { rdtag = istaggedtype(c, rdtn); }; @@ -37031,15 +37031,15 @@ fn cgreturn(c: *cgen, n: *node) void = { // (#10 Fold B). Byte-identical to cstage cgen.c // N_RETURN over-cap tuple arm. let saoff: i32 = localfind(c, "@sretarg"); - let pt: *node = nil; + let pt: *syntax.node = nil; if (c.fnret != nil) { pt = c.fnret.list; }; - let we: *node = rhs.list; + let we: *syntax.node = rhs.list; let foff: i32 = 0; for (we != nil) { - let dt: *tinfo = nil; - if (pt != nil) { dt = pt.lhs.type_: *tinfo; }; + let dt: *syntax.tinfo = nil; + if (pt != nil) { dt = pt.lhs.type_: *syntax.tinfo; }; dt = tichase(dt); - if (dt != nil && dt.kind == tykind.TY_TAGGED) { + if (dt != nil && dt.kind == syntax.tykind.TY_TAGGED) { // #22b (task #28): MEMORY-class tagged // element — the whole box copies through // the sret pointer mem-to-mem from the @@ -37054,11 +37054,11 @@ fn cgreturn(c: *cgen, n: *node) void = { // follow-ups). Mirror of cstage cgen.c // N_RETURN over-cap tagged arm. let eslot: i32 = tupeslotn(pt.lhs); - let eu: *tinfo = we.type_: *tinfo; + let eu: *syntax.tinfo = we.type_: *syntax.tinfo; eu = tichase(eu); let eoff: i32 = 0; - if (we.kind == nkind.N_IDENT && eu != nil) { - if (eu.kind == tykind.TY_TAGGED && tupeslotn(we) == eslot) { + if (we.kind == syntax.nkind.N_IDENT && eu != nil) { + if (eu.kind == syntax.tykind.TY_TAGGED && tupeslotn(we) == eslot) { eoff = localfind(c, we.str); }; }; @@ -37089,7 +37089,7 @@ fn cgreturn(c: *cgen, n: *node) void = { let wide: bool = nodeisstr(c, we) || nodeisslice(c, we); let esz: i32 = 8; if (pt != nil) { - let eti: *tinfo = pt.lhs.type_: *tinfo; + let eti: *syntax.tinfo = pt.lhs.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; }; cgexpr(c, we); @@ -37165,7 +37165,7 @@ fn cgreturn(c: *cgen, n: *node) void = { rp = rp0; e = rhs.list; for (e != nil) { - let rdtn: *node = nil; + let rdtn: *syntax.node = nil; if (rp != nil) { rdtn = rp.lhs; }; let rdtag: bool = false; if (rdtn != nil) { rdtag = istaggedtype(c, rdtn); }; @@ -37200,7 +37200,7 @@ fn cgreturn(c: *cgen, n: *node) void = { rp = rp0; e = rhs.list; for (e != nil) { - let rdtn: *node = nil; + let rdtn: *syntax.node = nil; if (rp != nil) { rdtn = rp.lhs; }; let rdtag: bool = false; if (rdtn != nil) { rdtag = istaggedtype(c, rdtn); }; @@ -37259,17 +37259,17 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_INDEX tagged-element return fell to the scalar-variant // shuffle (MOVQ AX,DX; MOVQ $0,AX), dropping the payload. let forwardtagged: bool = false; - if ((rhs.kind == nkind.N_CALL || rhs.kind == nkind.N_INDEX || rhs.kind == nkind.N_DOT) && rhs.type_ != nil && c.fnret != nil && c.fnret.type_ != nil) { - let ru: *tinfo = rhs.type_: *tinfo; + if ((rhs.kind == syntax.nkind.N_CALL || rhs.kind == syntax.nkind.N_INDEX || rhs.kind == syntax.nkind.N_DOT) && rhs.type_ != nil && c.fnret != nil && c.fnret.type_ != nil) { + let ru: *syntax.tinfo = rhs.type_: *syntax.tinfo; ru = tichase(ru); - let fu: *tinfo = c.fnret.type_: *tinfo; + let fu: *syntax.tinfo = c.fnret.type_: *syntax.tinfo; fu = tichase(fu); - if (ru != nil && fu != nil && ru.kind == tykind.TY_TAGGED && fu.kind == tykind.TY_TAGGED) { + if (ru != nil && fu != nil && ru.kind == syntax.tykind.TY_TAGGED && fu.kind == syntax.tykind.TY_TAGGED) { if (ru == fu) { forwardtagged = true; } else if (ru.nullable == fu.nullable) { - let pa: *tparam = ru.params; - let pb: *tparam = fu.params; + let pa: *syntax.tparam = ru.params; + let pb: *syntax.tparam = fu.params; let same: bool = true; for (pa != nil && pb != nil) { if (pa.type_ != pb.type_) { same = false; }; @@ -37291,7 +37291,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // cgwidentaggedstore's non-BP base. if (sretretsize(c, c.fnret) > 0) { let sa38v: i32 = localfind(c, "@sretarg"); - if (forwardtagged && rhs.kind == nkind.N_CALL) { + if (forwardtagged && rhs.kind == syntax.nkind.N_CALL) { // exact-type N_CALL forward: inner sret's // into outer's dest; an N_INDEX/N_DOT // source routes through the widener's @@ -37307,14 +37307,14 @@ fn cgreturn(c: *cgen, n: *node) void = { c.lastwasreturn = 1; return; }; - let ru38: *tinfo = rhs.type_: *tinfo; + let ru38: *syntax.tinfo = rhs.type_: *syntax.tinfo; ru38 = tichase(ru38); if (ru38 != nil) { // #37 wired the N_INDEX/N_DOT mem-read into // the widener; the remaining >32B kinds stay // loud. - if (ru38.kind == tykind.TY_TAGGED - && rhs.kind != nkind.N_IDENT + if (ru38.kind == syntax.tykind.TY_TAGGED + && rhs.kind != syntax.nkind.N_IDENT && ru38.size: i32 > TUPLE_GPCAP * 8 && !taggedmemread(c, rhs)) { let m38e: str = "#40: widening tagged return-forward of a >32B source needs mem-to-mem tag-remap (unwired)\n"; @@ -37325,7 +37325,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("\tMOVQ\t"); emitoff(sa38v: i64); emitline("(BP), BX\n"); - cgwidentaggedstore(c, c.fnret.type_: *tinfo, rhs, + cgwidentaggedstore(c, c.fnret.type_: *syntax.tinfo, rhs, "BX", 0, slotsize(c, c.fnret)); emitline("\tMOVQ\t"); emitoff(sa38v: i64); @@ -37350,7 +37350,7 @@ fn cgreturn(c: *cgen, n: *node) void = { }; // #242: a tuple variant packs into the union // payload via cgwidentaggedstore's TY_TUPLE arm. - if (rhs.kind == nkind.N_TUPLE) { + if (rhs.kind == syntax.nkind.N_TUPLE) { needswiden = true; }; // Family C (#35/#46): a mem-based tagged @@ -37374,15 +37374,15 @@ fn cgreturn(c: *cgen, n: *node) void = { // EXACT-type tagged casts on cstage's passthrough // (forwardtagged's own ru==fu equality) so byte-id // holds. - let ru1: *tinfo = rhs.type_: *tinfo; + let ru1: *syntax.tinfo = rhs.type_: *syntax.tinfo; ru1 = tichase(ru1); - let fu1: *tinfo = nil; + let fu1: *syntax.tinfo = nil; if (c.fnret != nil) { - fu1 = c.fnret.type_: *tinfo; + fu1 = c.fnret.type_: *syntax.tinfo; fu1 = tichase(fu1); }; if (ru1 != nil && fu1 != nil) { - if (ru1.kind == tykind.TY_TAGGED && ru1 != fu1) { + if (ru1.kind == syntax.tykind.TY_TAGGED && ru1 != fu1) { needswiden = true; }; // S3/#35: a SAME-TYPE tagged CAST (ru1 == fu1, @@ -37400,7 +37400,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // "N_CAST defeats srcreg"; peeling here instead // would reroute a call/dot source to passthrough // and break byte-id. - if (rhs.kind == nkind.N_CAST && ru1.kind == tykind.TY_TAGGED && ru1 == fu1) { + if (rhs.kind == syntax.nkind.N_CAST && ru1.kind == syntax.tykind.TY_TAGGED && ru1 == fu1) { needswiden = true; }; }; @@ -37429,7 +37429,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("(BP)\n"); zz += 8; }; - cgwidentaggedstore(c, c.fnret.type_: *tinfo, rhs, "BP", + cgwidentaggedstore(c, c.fnret.type_: *syntax.tinfo, rhs, "BP", scroff, rsz); // Tagged-return ABI loads at most 4 eightbytes // (AX/DX/CX/R8). A union whose slot exceeds 32B @@ -37494,9 +37494,9 @@ fn cgreturn(c: *cgen, n: *node) void = { // the SSoT cstage reads via node_isfloat / type_isf32. let rfk: i32 = 0; if (rhs != nil) { - let rety: *tinfo = rhs.type_: *tinfo; - if (typeisf32(rety)) { rfk = 1; } - else { if (typeisfloat(rety)) { rfk = 2; }; }; + let rety: *syntax.tinfo = rhs.type_: *syntax.tinfo; + if (syntax.typeisf32(rety)) { rfk = 1; } + else { if (syntax.typeisfloat(rety)) { rfk = 2; }; }; }; if (nodeisslice(c, rhs)) { // cgexpr leaves (AX=ptr, BX=len, CX=cap). @@ -37579,7 +37579,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // @sretarg(BP), AX is redundant after inner's // RET but kept for byte-id symmetry with the // N_IDENT / N_STRUCTLIT arms below. - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { c.sretforward = 1; cgexpr(c, rhs); emitline("\tMOVQ\t"); @@ -37598,15 +37598,15 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_RETURN sret arm. N_ARRLIT >24B has no consumer // (loud-stops in cstage); not wired here. let addrsrc: bool = false; - if (rhs.kind == nkind.N_IDENT) { okrhs = true; }; - if (rhs.kind == nkind.N_STRUCTLIT) { okrhs = true; }; - if (rhs.kind == nkind.N_DOT) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_INDEX) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_IDENT) { okrhs = true; }; + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { okrhs = true; }; + if (rhs.kind == syntax.nkind.N_DOT) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_INDEX) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { okrhs = true; addrsrc = true; }; }; if (okrhs) { - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { // #63: the >24B sret RETURN twin of the :2421 // let-init fix. sretretsize chases the alias for // the size GATE (so this sret arm fires for a >24B @@ -37619,7 +37619,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // (SILENT wrong, runtime-0). structlookupchain chases // to the base struct; cs fills via the resolved // Type*, runtime-correct. - let trefn: *node = rhs.lhs; + let trefn: *syntax.node = rhs.lhs; let sret_si: *structinfo = structlookupchain(c, trefn); if (sret_si != nil) { let emptys: str; @@ -37728,7 +37728,7 @@ fn cgreturn(c: *cgen, n: *node) void = { let rname: str; rname.ptr = nil; rname.len = 0; if (c.fnret != nil) { - if (c.fnret.kind == nkind.N_TNAME) { + if (c.fnret.kind == syntax.nkind.N_TNAME) { rname = c.fnret.str; }; }; @@ -37745,7 +37745,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_DOT/N_INDEX/deref memcpy into @retscr before the // shared structfloatclass tail (mirror cstage cgen.c). let addrsrc: bool = false; - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { okrhs = true; // #41 (#263 ww-runtime-correct): a module-global struct // source has no BP slot — route it through the addrsrc @@ -37756,13 +37756,13 @@ fn cgreturn(c: *cgen, n: *node) void = { addrsrc = true; }; }; - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { okrhs = true; }; - if (rhs.kind == nkind.N_DOT) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_INDEX) { okrhs = true; addrsrc = true; }; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_DOT) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_INDEX) { okrhs = true; addrsrc = true; }; + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { okrhs = true; addrsrc = true; }; }; if (okrhs) { let scroff: i32 = localadd(c, @@ -37777,7 +37777,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("\tMOVQ\tAX, "); emitoff((scroff + 16): i64); emitline("(BP)\n"); - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { // Delegate to the shared BP-relative // structlit fill helper. Same store // sequence the inline pre-#17 walk @@ -37937,7 +37937,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // (tinfo.size = sub.size*len) mirrors cstage rt->size. No // structfloatclass (pure-int arrays); N_CALL forward at reg- // class falls to the default cgexpr passthrough below. - if (c.fnret != nil && c.fnret.kind == nkind.N_TARRAY) { + if (c.fnret != nil && c.fnret.kind == syntax.nkind.N_TARRAY) { // #272: array return-by-value source-shape closure. // Beyond the #267 N_IDENT word-copy, route N_ARRLIT // (literal fill), N_DOT/N_INDEX/deref (aggargsrcaddr + @@ -37945,14 +37945,14 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_RETURN ≤24B arm. N_CALL stays on the cgexpr tail (the // callee already left AX/DX/CX). let arrok: bool = false; - if (rhs.kind == nkind.N_IDENT) { arrok = true; }; - if (rhs.kind == nkind.N_ARRLIT) { arrok = true; }; - if (rhs.kind == nkind.N_DOT) { arrok = true; }; - if (rhs.kind == nkind.N_INDEX) { arrok = true; }; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_IDENT) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_ARRLIT) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_DOT) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_INDEX) { arrok = true; }; + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { arrok = true; }; }; - let ati: *tinfo = c.fnret.type_: *tinfo; + let ati: *syntax.tinfo = c.fnret.type_: *syntax.tinfo; ati = tichase(ati); if (arrok && ati != nil) { let rsz: i32 = ati.size: i32; @@ -37968,7 +37968,7 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("\tMOVQ\tAX, "); emitoff((scroff + 16): i64); emitline("(BP)\n"); - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { let rl: *local = localfindnode(c, rhs.str); let roff: i32 = 0; if (rl != nil) { roff = rl.off; }; @@ -38000,28 +38000,28 @@ fn cgreturn(c: *cgen, n: *node) void = { emitline("(BP)\n"); k += 1; }; - } else { if (rhs.kind == nkind.N_ARRLIT) { + } else { if (rhs.kind == syntax.nkind.N_ARRLIT) { // scalar/float element fill; non-scalar // elements loud-stop (rule 7, no consumer). - let esubti: *tinfo = nil; + let esubti: *syntax.tinfo = nil; if (ati.sub != nil) { esubti = ati.sub; }; esubti = tichase(esubti); let esz: i32 = 8; if (esubti != nil) { esz = esubti.size: i32; }; let badel: bool = false; if (esubti != nil) { - if (esubti.kind == tykind.TY_STRUCT) { badel = true; }; - if (esubti.kind == tykind.TY_ARRAY) { badel = true; }; - if (esubti.kind == tykind.TY_TUPLE) { badel = true; }; - if (esubti.kind == tykind.TY_SLICE) { badel = true; }; - if (esubti.kind == tykind.TY_STR) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_STRUCT) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_ARRAY) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_TUPLE) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_SLICE) { badel = true; }; + if (esubti.kind == syntax.tykind.TY_STR) { badel = true; }; }; if (badel) { let m2: str = "#272: array-literal return with non-scalar element unsupported (rule 7, no consumer)\n"; os.write(2, m2.ptr, m2.len: u64); os.exit(1); }; - let esub: *node = c.fnret.lhs; + let esub: *syntax.node = c.fnret.lhs; let isfl: bool = isfloattype(c, esub); let fmov: str = "MOVSD"; if (isf32type(c, esub)) { fmov = "MOVSS"; }; @@ -38029,11 +38029,11 @@ fn cgreturn(c: *cgen, n: *node) void = { if (esz == 1) { op = "MOVB"; } else { if (esz == 2) { op = "MOVW"; } else { if (esz == 4) { op = "MOVL"; }; }; }; let idx: i32 = 0; let repeat: bool = false; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { let isellip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; isellip = true; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; isellip = true; }; }; if (isellip) { e = nil; @@ -38157,14 +38157,14 @@ fn cgreturn(c: *cgen, n: *node) void = { // array-literal return (no consumer) also lands here (#276). let aggret: bool = false; if (c.fnret != nil) { - let rti: *tinfo = c.fnret.type_: *tinfo; + let rti: *syntax.tinfo = c.fnret.type_: *syntax.tinfo; rti = tichase(rti); if (rti != nil) { - if (rti.kind == tykind.TY_ARRAY) { aggret = true; }; - if (rti.kind == tykind.TY_STRUCT) { aggret = true; }; + if (rti.kind == syntax.tykind.TY_ARRAY) { aggret = true; }; + if (rti.kind == syntax.tykind.TY_STRUCT) { aggret = true; }; }; }; - if (aggret && rhs.kind != nkind.N_CALL) { + if (aggret && rhs.kind != syntax.nkind.N_CALL) { let m6: str = "#272/#276/#277: aggregate return reaches scalar default — unclosed shape (named-alias aggregate return or >24B array-literal; wwstage tinfo-dispatch deferred #277)\n"; os.write(2, m6.ptr, m6.len: u64); os.exit(1); @@ -38227,7 +38227,7 @@ fn cgreturn(c: *cgen, n: *node) void = { return; }; -fn cgexprstmt(c: *cgen, n: *node) void = { +fn cgexprstmt(c: *cgen, n: *syntax.node) void = { if (n.lhs != nil) { cgexpr(c, n.lhs); }; c.lastwasreturn = 0; return; @@ -38240,8 +38240,8 @@ fn cgexprstmt(c: *cgen, n: *node) void = { // store-op guarantee for rule-10 byte-id (ken). `arrtn` is the [count]T // type NODE (cglet n.lhs; cgslice the re-stamped tnode on arrlit.lhs, // #25); `rhs` the literal. Twin of cstage cg_arrlit_fill_bp. -fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { - let elemn: *node = arrtn.lhs; +fn cgarrlitfillbp(c: *cgen, arrtn: *syntax.node, rhs: *syntax.node, off: i32) void = { + let elemn: *syntax.node = arrtn.lhs; // #79 (#60 rider): alias-NAMED [count]T (`type A = [4]u32; let // a: A = [...]`) — arrtn is the N_TNAME leaf: elemn nil, esz // stayed the 8 sentinel and the per-element store strode MOVQ @@ -38254,12 +38254,12 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // stash alen for the `...` repeat bound (cstage cg_arrlit_fill_bp // receives the pre-chased bu and reads bu->alen). let aliasalen: i32 = -1; - let ati79: *tinfo = arrtn.type_: *tinfo; - if (ati79 != nil) { if (ati79.kind == tykind.TY_NAMED) { - let au79: *tinfo = tichase(ati79); - if (au79 != nil) { if (au79.kind == tykind.TY_ARRAY + let ati79: *syntax.tinfo = arrtn.type_: *syntax.tinfo; + if (ati79 != nil) { if (ati79.kind == syntax.tykind.TY_NAMED) { + let au79: *syntax.tinfo = tichase(ati79); + if (au79 != nil) { if (au79.kind == syntax.tykind.TY_ARRAY && au79.sub != nil) { - let en79: *node = newnode(nkind.N_TNAME, arrtn.file, arrtn.line, arrtn.col); + let en79: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, arrtn.file, arrtn.line, arrtn.col); en79.str = au79.sub.name; en79.type_ = au79.sub: *void; elemn = en79; @@ -38269,8 +38269,8 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { let esz: i32 = 8; let isstrel: bool = false; if (elemn != nil) { - if (elemn.kind == nkind.N_TNAME) { - if (streq(elemn.str, "str")) { + if (elemn.kind == syntax.nkind.N_TNAME) { + if (syntax.streq(elemn.str, "str")) { esz = primtypesize("str"): i32; isstrel = true; } else { @@ -38285,13 +38285,13 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // each element slot from its literal (cgstructlitfillbp) // or source ident (word-copy). esz is the element's // natural size (cstage esub->size). - let esubti: *tinfo = nil; - if (elemn != nil) { esubti = elemn.type_: *tinfo; }; + let esubti: *syntax.tinfo = nil; + if (elemn != nil) { esubti = elemn.type_: *syntax.tinfo; }; esubti = tichase(esubti); let isagg: bool = esubti != nil - && (esubti.kind == tykind.TY_STRUCT - || esubti.kind == tykind.TY_ARRAY - || esubti.kind == tykind.TY_TUPLE); + && (esubti.kind == syntax.tykind.TY_STRUCT + || esubti.kind == syntax.tykind.TY_ARRAY + || esubti.kind == syntax.tykind.TY_TUPLE); if (isagg) { esz = esubti.size: i32; }; // #20/#270 str-slice arm: a slice element (N_TSLICE) is // a 24B {ptr,len,cap} header — it matches no prim/str/agg @@ -38300,7 +38300,7 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // store dropped .len/.cap. Size it from the stamped tinfo // and route it through the 3-word header store below. let isslicel: bool = esubti != nil - && esubti.kind == tykind.TY_SLICE; + && esubti.kind == syntax.tykind.TY_SLICE; if (isslicel) { esz = esubti.size: i32; }; // #12: a tagged-union element. NOT folded into isagg — // isagg's body word-copies/fatals and never boxes the @@ -38311,7 +38311,7 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // 1/2/4, so a tagged 16/24B element keeps the wrong 8 // sentinel stride without this. let istaggedel: bool = esubti != nil - && esubti.kind == tykind.TY_TAGGED; + && esubti.kind == syntax.tykind.TY_TAGGED; if (istaggedel) { esz = esubti.size: i32; }; // #8: a named-narrow element (`[N]tk`, tk = enum i32) is // neither a builtin prim (primsize=0 above, so esz stayed @@ -38338,11 +38338,11 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { if (isf32type(c, elemn)) { fmov = "MOVSS"; }; let idx: i32 = 0; let repeat: bool = false; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { let isellip: bool = false; - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; isellip = true; }; @@ -38351,10 +38351,10 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { e = nil; } else { if (isagg) { - if (e.kind == nkind.N_STRUCTLIT) { + if (e.kind == syntax.nkind.N_STRUCTLIT) { let esi: *structinfo = structlookupchain(c, elemn); cgstructlitfillbp(c, esi, e, off + idx * esz); - } else { if (e.kind == nkind.N_IDENT) { + } else { if (e.kind == syntax.nkind.N_IDENT) { let sl: *local = localfindnode(c, e.str); let soff: i32 = 0; if (sl != nil) { soff = sl.off; }; @@ -38450,9 +38450,9 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { if (repeat) { let total: i32 = idx; if (arrtn != nil) { - if (arrtn.kind == nkind.N_TARRAY) { + if (arrtn.kind == syntax.nkind.N_TARRAY) { if (arrtn.rhs != nil) { - if (arrtn.rhs.kind == nkind.N_INTLIT) { + if (arrtn.rhs.kind == syntax.nkind.N_INTLIT) { total = arrtn.rhs.uval: i32; }; }; @@ -38496,10 +38496,10 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // c.locals while cgletbody runs (Hare evals the init in the outer scope: // harec check.c clet runs cexpr before scope_define). localreserve bumps // the frame now so off + nested-let offsets stay stable. -fn cglet(c: *cgen, n: *node) void = { +fn cglet(c: *cgen, n: *syntax.node) void = { let nm: str = n.str; let sz: i32 = letslotsize(c, n); - let tn: *node = n.lhs; + let tn: *syntax.node = n.lhs; if (tn == nil) { tn = inferletcalltype(c, n.rhs); }; let letloc: *local = localreserve(c, nm, sz, tn); cgletbody(c, n, letloc.off); @@ -38512,16 +38512,16 @@ fn cglet(c: *cgen, n: *node) void = { // binding into c.locals only AFTER, so a self-shadowing init // (`let x = f(x)`) resolves x in the OUTER scope (Hare evals the init in // the outer scope: harec check.c clet runs cexpr before scope_define). -fn cgletbody(c: *cgen, n: *node, off: i32) void = { +fn cgletbody(c: *cgen, n: *syntax.node, off: i32) void = { let nm: str = n.str; let sz: i32 = letslotsize(c, n); // `let x = f()?` has no annotation but the cgen's struct-field // paths need a tnode to dispatch off. Infer from f's tagged // success variant — see inferletcalltype. - let tn: *node = n.lhs; + let tn: *syntax.node = n.lhs; if (tn == nil) { tn = inferletcalltype(c, n.rhs); }; if (n.rhs != nil) { - let rhs: *node = n.rhs; + let rhs: *syntax.node = n.rhs; // `let s: []T = alloc([], n)!;` / `?` shortcut (#32, #45). // Mirror of cstage cgen.c N_LET arrlit-empty branch: allocate // n*esz bytes via rt_malloc, then build the {ptr, 0, n} slice @@ -38532,19 +38532,19 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // land an 8B region and a junk slice header). `?` propagates // nomem via AX = tag of nomem in c.fnret, then epilogue RET. { - let scall: *node = nil; + let scall: *syntax.node = nil; let viatryunw: bool = false; let viatryprop: bool = false; - if (rhs.kind == nkind.N_TRYUNW) { + if (rhs.kind == syntax.nkind.N_TRYUNW) { if (rhs.lhs != nil) { - if (rhs.lhs.kind == nkind.N_CALL) { + if (rhs.lhs.kind == syntax.nkind.N_CALL) { scall = rhs.lhs; viatryunw = true; }; }; - } else { if (rhs.kind == nkind.N_TRYPROP) { + } else { if (rhs.kind == syntax.nkind.N_TRYPROP) { if (rhs.lhs != nil) { - if (rhs.lhs.kind == nkind.N_CALL) { + if (rhs.lhs.kind == syntax.nkind.N_CALL) { scall = rhs.lhs; viatryprop = true; }; @@ -38557,18 +38557,18 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // silently miss after #1 if check.ww's astsize ever // drifted from this dispatch. if (scall != nil && tn != nil - && tn.kind == nkind.N_TSLICE && sz == tyslicesize(): i32) { - let callee: *node = scall.lhs; - let a0: *node = scall.list; - let a1: *node = nil; - let a2: *node = nil; + && tn.kind == syntax.nkind.N_TSLICE && sz == tyslicesize(): i32) { + let callee: *syntax.node = scall.lhs; + let a0: *syntax.node = scall.list; + let a1: *syntax.node = nil; + let a2: *syntax.node = nil; if (a0 != nil) { a1 = a0.next; }; if (a1 != nil) { a2 = a1.next; }; if (callee != nil && a0 != nil && a1 != nil && a2 == nil) { - if (callee.kind == nkind.N_IDENT - && streq(callee.str, "alloc") - && a0.kind == nkind.N_ARRLIT + if (callee.kind == syntax.nkind.N_IDENT + && syntax.streq(callee.str, "alloc") + && a0.kind == syntax.nkind.N_ARRLIT && a0.list == nil) { shapeok = true; }; @@ -38582,7 +38582,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // cstage path byte-identically. A bare primsize/slotsize // fork would silently land esz=1 on `[]point`. let esz: i32 = elemsizeofc(c, tn); - let count: *node = scall.list.next; + let count: *syntax.node = scall.list.next; cgexpr(c, count); emitline("\tPUSHQ\tAX\n"); if (esz > 1) { @@ -38623,14 +38623,14 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // holds no tinfo singleton, so find the nomem // variant by its NAMED name over tinfo.params. let nidx: i32 = -1; - let nti: *tinfo = nil; - if (c.fnret != nil) { nti = c.fnret.type_: *tinfo; }; + let nti: *syntax.tinfo = nil; + if (c.fnret != nil) { nti = c.fnret.type_: *syntax.tinfo; }; nti = tichase(nti); - if (nti != nil) { if (nti.kind == tykind.TY_TAGGED) { - let np: *tparam = nti.params; + if (nti != nil) { if (nti.kind == syntax.tykind.TY_TAGGED) { + let np: *syntax.tparam = nti.params; let nidx2: i32 = 0; for (np != nil) { - let nvt: *tinfo = np.type_; + let nvt: *syntax.tinfo = np.type_; if (nvt != nil) { if (variantnamematch(nvt.name, "nomem")) { nidx = nidx2; break; }; }; @@ -38671,23 +38671,23 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // Mirrors cstage cgen.c N_LET tagged arm. if (istaggedtype(c, tn)) { let letsret: i32 = 0; - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { letsret = callsretsize(c, rhs); }; if (letsret == 0) { - cgwidentaggedstore(c, tn.type_: *tinfo, rhs, + cgwidentaggedstore(c, tn.type_: *syntax.tinfo, rhs, "BP", off, sz); c.lastwasreturn = 0; return; }; - let lru: *tinfo = rhs.type_: *tinfo; + let lru: *syntax.tinfo = rhs.type_: *syntax.tinfo; lru = tichase(lru); - let llu: *tinfo = tn.type_: *tinfo; + let llu: *syntax.tinfo = tn.type_: *syntax.tinfo; llu = tichase(llu); let exact38: bool = false; if (lru != nil && lru == llu) { exact38 = true; } else { - if (typeeq(rhs.type_: *tinfo, tn.type_: *tinfo)) { + if (syntax.typeeq(rhs.type_: *syntax.tinfo, tn.type_: *syntax.tinfo)) { exact38 = true; }; }; @@ -38721,12 +38721,12 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // keying). Alias-peel mirrors cstage's type_chase_named; the // unannotated `let t = f()` shape rides the inferletcalltype // tn above. - let ttup: *node = tn; - for (ttup != nil && ttup.kind == nkind.N_TNAME) { + let ttup: *syntax.node = tn; + for (ttup != nil && ttup.kind == syntax.nkind.N_TNAME) { ttup = aliaslookup(c, ttup.str); }; if (ttup != nil) { - if (ttup.kind == nkind.N_TTUPLE + if (ttup.kind == syntax.nkind.N_TTUPLE && sretretsize(c, ttup) == 0) { // #57: a tuple LITERAL rhs carries the DECLARED // type into the cursor fill — its stamped type @@ -38736,7 +38736,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // (let-twin of the return-position bug; probe // /tmp/p57/q1_let). Same emission as the cgexpr // route for every declared-tagged-free literal. - if (rhs.kind == nkind.N_TUPLE) { + if (rhs.kind == syntax.nkind.N_TUPLE) { cgtuplelittocursor(c, rhs, ttup); } else { cgexpr(c, rhs); @@ -38744,9 +38744,9 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { let gpcur: i32 = 0; let ssecur: i32 = 0; let eoff: i32 = 0; - let q: *node = ttup.list; + let q: *syntax.node = ttup.list; for (q != nil) { - let qt: *node = q.lhs; + let qt: *syntax.node = q.lhs; let isflt: bool = isfloattype(c, qt); let eslot: i32 = tupeslotn(qt); tupstore(c, gpcur, ssecur, @@ -38772,8 +38772,8 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // payload (or a void literal) slip through in-cap // (probe /tmp/i22b/p7) — the let-twin of the #22b // classify/emit skew. Mirrors cstage cgen.c N_LET net. - if (ttup.kind == nkind.N_TTUPLE - && rhs.kind != nkind.N_CALL + if (ttup.kind == syntax.nkind.N_TTUPLE + && rhs.kind != syntax.nkind.N_CALL && sretretsize(c, ttup) > 0) { cgexpr(c, rhs); let mnet: str = "over-cap tuple initialiser from a non-call source unwired (see #10/#22b)\n"; @@ -38798,7 +38798,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // (primsize's default-to-8-on-zero pattern is brittle for // composites generally. The str/slice element now stores all 3 // words; [N]tagged element arrays still hit the gap, task #12.) - if (rhs.kind == nkind.N_ARRLIT) { + if (rhs.kind == syntax.nkind.N_ARRLIT) { cgarrlitfillbp(c, n.lhs, rhs, off); c.lastwasreturn = 0; return; @@ -38809,7 +38809,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // values recursing into the helper instead of landing only AX // (the #17 silent-zero fix). Mirror of cstage cgen.c N_LET // structlit branch. - if (rhs.kind == nkind.N_STRUCTLIT) { + if (rhs.kind == syntax.nkind.N_STRUCTLIT) { // #63: an alias-NAMED struct literal (`type rep2 = rep; // let r = rep2{id=6}`) parses its type ref as N_IDENT/N_TNAME // "rep2", but only the base `rep` is registered — bare @@ -38819,7 +38819,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // alias chain to the base struct, the #92/W2 SSoT already // adopted at cgenstmt:1974/:2687. cs chases via // type_chase_named, runtime-correct. - let trefn: *node = rhs.lhs; + let trefn: *syntax.node = rhs.lhs; let si: *structinfo = structlookupchain(c, trefn); if (si != nil) { cgstructlitfillbp(c, si, rhs, off); @@ -38833,7 +38833,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // before the CALL and the callee writes through it. No // AX/DX/CX shuffle; AX returns the dest pointer per SysV // sret discipline (irrelevant here). - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { let scs: i32 = callsretsize(c, rhs); if (scs > 0) { c.sretdestoff = off; @@ -38873,7 +38873,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // #169 sized tail is unreachable here. structfloatclass gates // to qualifying structs; all-int + f32 fall to the GP recv // below (byte-id / #171b). - if (rhs.kind == nkind.N_CALL && tn != nil) { + if (rhs.kind == syntax.nkind.N_CALL && tn != nil) { let sfc: i32 = structfloatclass(c, tn); if (sfc != 0) { cgexpr(c, rhs); @@ -38904,11 +38904,11 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { return; }; }; - if (rhs.kind == nkind.N_CALL) { + if (rhs.kind == syntax.nkind.N_CALL) { let sname: str; sname.ptr = nil; sname.len = 0; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { + if (tn.kind == syntax.nkind.N_TNAME) { sname = tn.str; }; }; @@ -38966,9 +38966,9 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // above (callsretsize keyed). Array natural size (tinfo.size // = sub.size*len) mirrors cstage lu->size. No structfloatclass // (pure-int element arrays). - if (rhs.kind == nkind.N_CALL && tn != nil - && tn.kind == nkind.N_TARRAY) { - let ati: *tinfo = tn.type_: *tinfo; + if (rhs.kind == syntax.nkind.N_CALL && tn != nil + && tn.kind == syntax.nkind.N_TARRAY) { + let ati: *syntax.tinfo = tn.type_: *syntax.tinfo; ati = tichase(ati); if (ati != nil) { let lsz: i32 = ati.size: i32; @@ -39020,11 +39020,11 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // only the first qword (and a stale BX for sz==16 lets // via the str-init tail) — silent partial copy. Mirrors // cstage cgen.c N_LET struct-ident branch (Task #32). - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { let sname: str; sname.ptr = nil; sname.len = 0; if (tn != nil) { - if (tn.kind == nkind.N_TNAME) { sname = tn.str; }; + if (tn.kind == syntax.nkind.N_TNAME) { sname = tn.str; }; }; if (sname.len > 0) { let lsi: *structinfo = structlookup(c, sname); @@ -39093,25 +39093,25 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { if (aggsi != nil) { aggn = structabisize(aggsi); } else { - let aggti: *tinfo = nil; - if (tn != nil) { aggti = tn.type_: *tinfo; }; + let aggti: *syntax.tinfo = nil; + if (tn != nil) { aggti = tn.type_: *syntax.tinfo; }; aggti = tichase(aggti); if (aggti != nil) { - if (aggti.kind == tykind.TY_ARRAY) { + if (aggti.kind == syntax.tykind.TY_ARRAY) { aggn = aggti.size: i32; }; }; }; if (aggn > 8) { let havesrc: bool = false; - if (rhs.kind == nkind.N_UN) { - if (rhs.op == tkind.TK_STAR) { + if (rhs.kind == syntax.nkind.N_UN) { + if (rhs.op == syntax.tkind.TK_STAR) { cgexpr(c, rhs.lhs); emitline("\tMOVQ\tAX, SI\n"); havesrc = true; }; }; - if (!havesrc) { if (rhs.kind == nkind.N_IDENT) { + if (!havesrc) { if (rhs.kind == syntax.nkind.N_IDENT) { let lc: *local = localfindnode(c, rhs.str); if (lc != nil) { emitline("\tLEAQ\t"); @@ -39127,10 +39127,10 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // over-copies struct-defs on wwstage // only; mirror the defisaddressable // pairing instead. - let aggdtn: *node = defvartnode(c, rhs.str); + let aggdtn: *syntax.node = defvartnode(c, rhs.str); let aggisdef: bool = defvarstructinfo(c, rhs.str) != nil; if (aggdtn != nil) { - if (aggdtn.kind == nkind.N_TARRAY) { aggisdef = true; }; + if (aggdtn.kind == syntax.nkind.N_TARRAY) { aggisdef = true; }; }; if (isletvar(c, rhs.str) || aggisdef) { emitline("\tLEAQ\t"); @@ -39140,19 +39140,19 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { }; }; }; }; - if (!havesrc) { if (rhs.kind == nkind.N_DOT) { + if (!havesrc) { if (rhs.kind == syntax.nkind.N_DOT) { if (dotchainaddr(c, rhs, "SI")) { havesrc = true; }; }; }; - if (!havesrc) { if (rhs.kind == nkind.N_INDEX) { - let base: *node = rhs.lhs; - let idx: *node = rhs.rhs; - let bu: *tinfo = nil; - if (base != nil) { bu = base.type_: *tinfo; }; + if (!havesrc) { if (rhs.kind == syntax.nkind.N_INDEX) { + let base: *syntax.node = rhs.lhs; + let idx: *syntax.node = rhs.rhs; + let bu: *syntax.tinfo = nil; + if (base != nil) { bu = base.type_: *syntax.tinfo; }; bu = tichase(bu); - if (base != nil && base.kind == nkind.N_IDENT - && bu != nil && bu.kind == tykind.TY_ARRAY) { + if (base != nil && base.kind == syntax.nkind.N_IDENT + && bu != nil && bu.kind == syntax.tykind.TY_ARRAY) { let esz: i32 = 1; if (bu.sub != nil) { esz = bu.sub.size: i32; @@ -39188,8 +39188,8 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // address) or the &abase[bidx] spine (nested // N_IDENT-array base), then add. if (!havesrc && base != nil - && (base.kind == nkind.N_DOT - || base.kind == nkind.N_INDEX)) { + && (base.kind == syntax.nkind.N_DOT + || base.kind == syntax.nkind.N_INDEX)) { let esz2: i32 = 1; if (bu != nil && bu.sub != nil) { esz2 = bu.sub.size: i32; @@ -39203,18 +39203,18 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { }; emitline("\tPUSHQ\tAX\n"); let baseok: bool = false; - if (base.kind == nkind.N_DOT) { + if (base.kind == syntax.nkind.N_DOT) { if (dotbaseaddr(c, base, "AX")) { baseok = true; }; } else { - let ab: *node = base.lhs; - let bidx: *node = base.rhs; - let abu: *tinfo = nil; - if (ab != nil) { abu = ab.type_: *tinfo; }; + let ab: *syntax.node = base.lhs; + let bidx: *syntax.node = base.rhs; + let abu: *syntax.tinfo = nil; + if (ab != nil) { abu = ab.type_: *syntax.tinfo; }; abu = tichase(abu); - if (ab != nil && ab.kind == nkind.N_IDENT - && abu != nil && abu.kind == tykind.TY_ARRAY) { + if (ab != nil && ab.kind == syntax.nkind.N_IDENT + && abu != nil && abu.kind == syntax.tykind.TY_ARRAY) { let aesz: i32 = 1; if (abu.sub != nil) { aesz = abu.sub.size: i32; @@ -39307,10 +39307,10 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // cgen.c N_LET; pre-C4 this shape fell through to the // cgtryunw/cgtryprop gates, which the C4 tail below // now pre-empts in let position). - if (rhs.kind == nkind.N_TRYUNW - || rhs.kind == nkind.N_TRYPROP) { + if (rhs.kind == syntax.nkind.N_TRYUNW + || rhs.kind == syntax.nkind.N_TRYPROP) { if (rhs.lhs != nil) { - if (rhs.lhs.kind == nkind.N_CALL) { + if (rhs.lhs.kind == syntax.nkind.N_CALL) { if (callsretsize(c, rhs.lhs) > 0) { let m38f: str = "#38b: `?`/`!` on an sret-class call result unwired (mem-based unwrap is a #40-family follow-up)\n"; os.write(2, m38f.ptr, m38f.len: u64); @@ -39407,14 +39407,14 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { // would over-zero MOVQ-rounded to 24 and diverge from // cstage's exact 20-byte run. Handles direct N_TARRAY and // alias-to-array (N_TNAME chasing through TY_NAMED) alike. - let zti: *tinfo = n.lhs.type_: *tinfo; + let zti: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; zti = tichase(zti); - if (zti != nil && zti.kind == tykind.TY_ARRAY) { + if (zti != nil && zti.kind == syntax.tykind.TY_ARRAY) { zsz = zti.size: i32; - } else { if (n.lhs.kind == nkind.N_TNAME) { + } else { if (n.lhs.kind == syntax.nkind.N_TNAME) { let szi: *structinfo = structlookupchain(c, n.lhs); if (szi != nil) { - let ti: *tinfo = n.lhs.type_: *tinfo; + let ti: *syntax.tinfo = n.lhs.type_: *syntax.tinfo; ti = tichase(ti); if (ti != nil) { zsz = ti.size: i32; }; }; @@ -39472,7 +39472,7 @@ fn cgletbody(c: *cgen, n: *node, off: i32) void = { return; }; -fn cgif(c: *cgen, n: *node) void = { +fn cgif(c: *cgen, n: *syntax.node) void = { let els: str = mklabel(c, "else"); let endl: str = mklabel(c, "end"); cgexpr(c, n.cond); @@ -39492,7 +39492,7 @@ fn cgif(c: *cgen, n: *node) void = { return; }; -fn cgfor(c: *cgen, n: *node) void = { +fn cgfor(c: *cgen, n: *syntax.node) void = { // Match C cgen's label scheme: _loop_N for the top, // _endloop_N for the post-body merge. No separate cont // label when there's no post-expression. @@ -39556,7 +39556,7 @@ fn cgfor(c: *cgen, n: *node) void = { // the first lvalue, then pop DX into the second. Mirrors // cmd/w6c/cgen.c:2424-2440. Lvalues beyond two are dropped (same // as C — no fixture uses >2 today). -fn cgmassign(c: *cgen, n: *node) void = { +fn cgmassign(c: *cgen, n: *syntax.node) void = { // #83: positional per-element destructure REASSIGN. Same cursor as // cgmlet (and cgreturn; harec create_unpack_bindings, // ref/harec/src/check.c:1354-1416), but the slots already exist @@ -39569,7 +39569,7 @@ fn cgmassign(c: *cgen, n: *node) void = { // comma `a, s = f()` multi-assign is a retained ww-EXTENSION beyond // Hare (Hare tuple-unpack is binding-only); ww keeps the Go/rob-pike // multi-assign idiom — rule-9 carve-out. Over-capacity loud-stops. - let rettuple: *node = rettupleof(c, n.rhs); + let rettuple: *syntax.node = rettupleof(c, n.rhs); // #10 Fold B: over-cap tuple destructure REASSIGN. Same sret copy-out // as cgmlet but the slots already exist (localfind); a `_` / missing @@ -39578,7 +39578,7 @@ fn cgmassign(c: *cgen, n: *node) void = { // cstage N_MASSIGN over-cap arm. let sretrecv: i32 = 0; if (n.rhs != nil) { - if (n.rhs.kind == nkind.N_CALL) { + if (n.rhs.kind == syntax.nkind.N_CALL) { sretrecv = callsretsize(c, n.rhs); }; }; @@ -39592,16 +39592,16 @@ fn cgmassign(c: *cgen, n: *node) void = { // fill/receive fall back to the rhs literal element's own stamped type // for the cursor stride (harec `_` advance; pinned by the R3 control). let litrhs: bool = false; - if (n.rhs != nil) { if (n.rhs.kind == nkind.N_TUPLE) { litrhs = true; }; }; - let synthdecl: *node = nil; + if (n.rhs != nil) { if (n.rhs.kind == syntax.nkind.N_TUPLE) { litrhs = true; }; }; + let synthdecl: *syntax.node = nil; if (litrhs) { - synthdecl = newnode(nkind.N_TTUPLE, n.rhs.file, n.rhs.line, n.rhs.col); - let dtail: *node = nil; - let lb0: *node = n.list; + synthdecl = syntax.newnode(syntax.nkind.N_TTUPLE, n.rhs.file, n.rhs.line, n.rhs.col); + let dtail: *syntax.node = nil; + let lb0: *syntax.node = n.list; for (lb0 != nil) { - let w: *node = newnode(nkind.N_TUPLE, n.rhs.file, n.rhs.line, n.rhs.col); + let w: *syntax.node = syntax.newnode(syntax.nkind.N_TUPLE, n.rhs.file, n.rhs.line, n.rhs.col); w.lhs = nil; - if (lb0.kind == nkind.N_IDENT) { + if (lb0.kind == syntax.nkind.N_IDENT) { let lc0: *local = localfindnode(c, lb0.str); if (lc0 != nil) { w.lhs = lc0.tnode; }; }; @@ -39617,12 +39617,12 @@ fn cgmassign(c: *cgen, n: *node) void = { if (sretrecv > 0) { let scr: i32 = localfind(c, "@sretscr"); - let pt2: *node = nil; + let pt2: *syntax.node = nil; if (rettuple != nil) { pt2 = rettuple.list; }; let foff: i32 = 0; - let lb: *node = n.list; + let lb: *syntax.node = n.list; for (lb != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (pt2 != nil) { tn = pt2.lhs; }; let isflt: bool = isfloattype(c, tn); // #22b: the >8B copy-out keys on the ACCESSOR's slot @@ -39635,11 +39635,11 @@ fn cgmassign(c: *cgen, n: *node) void = { let eslot: i32 = tupeslotn(tn); let esz: i32 = 8; if (pt2 != nil) { - let eti: *tinfo = pt2.lhs.type_: *tinfo; + let eti: *syntax.tinfo = pt2.lhs.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; }; let off: i32 = 0; - if (lb.kind == nkind.N_IDENT) { off = localfind(c, lb.str); }; + if (lb.kind == syntax.nkind.N_IDENT) { off = localfind(c, lb.str); }; if (off != 0) { if (isflt) { let mov: str = "MOVSD"; @@ -39689,18 +39689,18 @@ fn cgmassign(c: *cgen, n: *node) void = { let ssecap: i32 = TUPLE_SSECAP; // X0,X1 per SysV let gptotal: i32 = 0; let ssetotal: i32 = 0; - let l: *node = n.list; - let pt: *node = nil; + let l: *syntax.node = n.list; + let pt: *syntax.node = nil; if (rettuple != nil) { pt = rettuple.list; }; // #64: a tuple-LITERAL rhs keys element WIDTH on the DECLARED lvalue // type (synthdecl), not the rettuple (nil for a literal); a `_` slot // (declared type nil) falls back to the rhs literal element's own // stamped type for the cursor stride. - let dp: *node = nil; - let re: *node = nil; + let dp: *syntax.node = nil; + let re: *syntax.node = nil; if (litrhs) { dp = synthdecl.list; re = n.rhs.list; }; for (l != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (litrhs) { if (dp != nil && dp.lhs != nil) { tn = dp.lhs; } else { tn = re; }; } else { @@ -39738,7 +39738,7 @@ fn cgmassign(c: *cgen, n: *node) void = { re = nil; if (litrhs) { dp = synthdecl.list; re = n.rhs.list; }; for (l != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (litrhs) { if (dp != nil && dp.lhs != nil) { tn = dp.lhs; } else { tn = re; }; } else { @@ -39747,7 +39747,7 @@ fn cgmassign(c: *cgen, n: *node) void = { let isflt: bool = isfloattype(c, tn); let eslot: i32 = tupeslotn(tn); let off: i32 = 0; - if (l.kind == nkind.N_IDENT) { off = localfind(c, l.str); }; + if (l.kind == syntax.nkind.N_IDENT) { off = localfind(c, l.str); }; // harec `_` (off==0): skip the store but CONSUME the cursor // slot so the next element stays aligned. if (off != 0) { @@ -39778,8 +39778,8 @@ fn cgmassign(c: *cgen, n: *node) void = { // as (.ptr, .len, .cap). Position-agnostic — the // regs are routed by element type, not by AX/DX. // str IS []u8 (24B): cap rides R8 (#1/Phase 3, task #5). -fn cgmlet(c: *cgen, n: *node) void = { - let rhs: *node = n.rhs; +fn cgmlet(c: *cgen, n: *syntax.node) void = { + let rhs: *syntax.node = n.rhs; if (rhs == nil) { return; }; // #83: positional per-element destructure let-binding. Same cursor @@ -39790,7 +39790,7 @@ fn cgmlet(c: *cgen, n: *node) void = { // walked in lockstep. A slice/str rides its 3-word {ptr,len,cap} // header (ref/hare/rt/ensure.ha:4-8) into a header-sized slot; a // scalar rides 1 word into an 8B slot. Over-capacity loud-stops. - let rettuple: *node = rettupleof(c, rhs); + let rettuple: *syntax.node = rettupleof(c, rhs); // #10 Fold B: over-cap tuple destructure RECEIVE. The callee sret'd // the whole tuple into the @sretscr discard slot (cgcall sees @@ -39799,7 +39799,7 @@ fn cgmlet(c: *cgen, n: *node) void = { // element size — the t.0/t.1 layout), each at its NATURAL width // (#169). Byte-identical to the cstage N_MLET over-cap arm. let sretrecv: i32 = 0; - if (rhs.kind == nkind.N_CALL) { sretrecv = callsretsize(c, rhs); }; + if (rhs.kind == syntax.nkind.N_CALL) { sretrecv = callsretsize(c, rhs); }; // #242: rhs is a tuple already materialised in a local slot (a match- // bound union payload, `let (a,b)=t`), NOT a register-returning call. @@ -39809,22 +39809,22 @@ fn cgmlet(c: *cgen, n: *node) void = { // the SAME layout the tagged construct + match payload-bind write. // Mirror of cstage cgen.c N_MLET tuple-ident arm. The binding element // types ride l.lhs (stamped by the checker's stamptuplebinds). - if (rhs.kind == nkind.N_IDENT) { + if (rhs.kind == syntax.nkind.N_IDENT) { let rl: *local = localfindnode(c, rhs.str); if (rl != nil) { - let rti: *tinfo = rl.tnode.type_: *tinfo; + let rti: *syntax.tinfo = rl.tnode.type_: *syntax.tinfo; rti = tichase(rti); - if (rti != nil) { if (rti.kind == tykind.TY_TUPLE) { + if (rti != nil) { if (rti.kind == syntax.tykind.TY_TUPLE) { let srcoff: i32 = rl.off; let foff: i32 = 0; - let lb: *node = n.list; + let lb: *syntax.node = n.list; for (lb != nil) { - let tn: *node = lb.lhs; + let tn: *syntax.node = lb.lhs; let isflt: bool = isfloattype(c, tn); let eslot: i32 = tupeslotn(tn); let esz: i32 = 8; - let eti: *tinfo = nil; - if (tn != nil) { eti = tn.type_: *tinfo; }; + let eti: *syntax.tinfo = nil; + if (tn != nil) { eti = tn.type_: *syntax.tinfo; }; if (eti != nil) { esz = eti.size: i32; }; let bsz: i32 = 8; if (eslot > 8) { bsz = eslot; }; @@ -39870,18 +39870,18 @@ fn cgmlet(c: *cgen, n: *node) void = { if (sretrecv > 0) { let scr: i32 = localfind(c, "@sretscr"); - let pt2: *node = nil; + let pt2: *syntax.node = nil; if (rettuple != nil) { pt2 = rettuple.list; }; let foff: i32 = 0; - let lb: *node = n.list; + let lb: *syntax.node = n.list; for (lb != nil) { - let tn: *node = nil; + let tn: *syntax.node = nil; if (pt2 != nil) { tn = pt2.lhs; }; let isflt: bool = isfloattype(c, tn); let eslot: i32 = tupeslotn(tn); let esz: i32 = 8; if (pt2 != nil) { - let eti: *tinfo = pt2.lhs.type_: *tinfo; + let eti: *syntax.tinfo = pt2.lhs.type_: *syntax.tinfo; if (eti != nil) { esz = eti.size: i32; }; }; let bsz: i32 = 8; @@ -39929,11 +39929,11 @@ fn cgmlet(c: *cgen, n: *node) void = { let ssecap: i32 = TUPLE_SSECAP; // X0,X1 per SysV let gptotal: i32 = 0; let ssetotal: i32 = 0; - let l: *node = n.list; - let pt: *node = nil; + let l: *syntax.node = n.list; + let pt: *syntax.node = nil; if (rettuple != nil) { pt = rettuple.list; }; for (l != nil) { - let tn: *node = l.lhs; + let tn: *syntax.node = l.lhs; if (tn == nil) { if (pt != nil) { tn = pt.lhs; }; }; @@ -39964,7 +39964,7 @@ fn cgmlet(c: *cgen, n: *node) void = { pt = nil; if (rettuple != nil) { pt = rettuple.list; }; for (l != nil) { - let tn: *node = l.lhs; + let tn: *syntax.node = l.lhs; if (tn == nil) { if (pt != nil) { tn = pt.lhs; }; }; @@ -39990,19 +39990,19 @@ fn cgmlet(c: *cgen, n: *node) void = { // `tp->type->size` read in C cgen N_FORRANGE: 1 for i8/u8/bool, 4 for // i32/u32, 8 for i64/u64/*T/fn, 24 for str/slice (str IS []u8, the slice // header SSoT), tuple → sum of its 8B-floored element slots, default 8. -fn paramfieldsize(t: *node) i32 = { +fn paramfieldsize(t: *syntax.node) i32 = { if (t == nil) { return 8; }; - let k: nkind = t.kind; - if (k == nkind.N_TPTR) { return 8; }; - if (k == nkind.N_TFN) { return 8; }; - if (k == nkind.N_TCHAN) { return 8; }; + let k: syntax.nkind = t.kind; + if (k == syntax.nkind.N_TPTR) { return 8; }; + if (k == syntax.nkind.N_TFN) { return 8; }; + if (k == syntax.nkind.N_TCHAN) { return 8; }; // #43 (F7-c4): a slice tuple-field carries the 24B header (ptr+len+ // cap), not the 8B scalar default. Without this arm the for-range // destructure over `[N]([]T, U)` strode the tuple at 8 not 24 and // read field-2 at the wrong offset (cs=42/ww=8, the cat-A repro). // tyslicesize() is the slice-header SSoT (rule-13); cstage reads the // same width via tp->type->size (cmd/w6c/cgen.c N_FORRANGE). - if (k == nkind.N_TSLICE) { return tyslicesize(): i32; }; + if (k == syntax.nkind.N_TSLICE) { return tyslicesize(): i32; }; // #53: a tagged-union tuple-field carries its full box (tag + widest // payload, slot-padded), NOT the 8B scalar default — a for-range // destructure binding sized 8 loaded only the tag word (cs=56/ww=9, the @@ -40012,10 +40012,10 @@ fn paramfieldsize(t: *node) i32 = { // covers an N_TNAME field naming a tagged union (paramfieldsize's no-`c` // structural contract can't aliaslookup-chase the node). Mirrors the // N_TSLICE arm's type-table SSoT. - let tgi: *tinfo = t.type_: *tinfo; + let tgi: *syntax.tinfo = t.type_: *syntax.tinfo; if (tgi != nil) { tgi = tichase(tgi); - if (tgi != nil && tgi.kind == tykind.TY_TAGGED) { + if (tgi != nil && tgi.kind == syntax.tykind.TY_TAGGED) { return tgi.size: i32; }; }; @@ -40024,9 +40024,9 @@ fn paramfieldsize(t: *node) i32 = { // their 24B header), per the tuple-slot ruling and tupeslot's // roundup8. Recurse structurally so a tuple-of-tuple lands the same // stride cstage's tp->type->size computes. - if (k == nkind.N_TTUPLE) { + if (k == syntax.nkind.N_TTUPLE) { let total: i32 = 0; - let dp: *node = t.list; + let dp: *syntax.node = t.list; for (dp != nil) { let esz: i32 = paramfieldsize(dp.lhs); total = total + (esz + 7) / 8 * 8; @@ -40034,9 +40034,9 @@ fn paramfieldsize(t: *node) i32 = { }; return total; }; - if (k == nkind.N_TNAME) { + if (k == syntax.nkind.N_TNAME) { let nm: str = t.str; - if (streq(nm, "str")) { return primtypesize("str"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("str"): i32; }; // primsize-ok (#101/#109): paramfieldsize is a STRUCTURAL // (no-`c`, no-chase) sizer by design — it takes a *node, not a // *cgen, so it cannot run aliasprimsize's aliaslookup chase @@ -40062,7 +40062,7 @@ fn paramfieldsize(t: *node) i32 = { // paramissigned — does this type need sign-extending on a sub-word // (1/2/4B) load? Mirrors cstage's signed_field check via // fieldissignedc (resolves TBANG / TENUM / alias chains). -fn paramissigned(c: *cgen, t: *node) bool = { +fn paramissigned(c: *cgen, t: *syntax.node) bool = { return fieldissignedc(c, t); }; @@ -40073,22 +40073,22 @@ fn paramissigned(c: *cgen, t: *node) bool = { // either loads the whole element into the named local or pulls each // tuple field into its own local. Mirrors cmd/w6c/cgen.c N_FORRANGE // byte-for-byte (label names + labelseq consumption order). -fn cgforrange(c: *cgen, n: *node) void = { - let slc: *node = n.lhs; +fn cgforrange(c: *cgen, n: *syntax.node) void = { + let slc: *syntax.node = n.lhs; let slclocal: *local = nil; - let slctn: *node = nil; + let slctn: *syntax.node = nil; if (slc != nil) { - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { slclocal = localfindnode(c, slc.str); if (slclocal != nil) { slctn = slclocal.tnode; }; }; }; // Element type — peek through TSLICE/TARRAY for the tuple param walk. - let elemt: *node = nil; + let elemt: *syntax.node = nil; if (slctn != nil) { - let sk: nkind = slctn.kind; - if (sk == nkind.N_TSLICE) { elemt = slctn.lhs; }; - if (sk == nkind.N_TARRAY) { elemt = slctn.lhs; }; + let sk: syntax.nkind = slctn.kind; + if (sk == syntax.nkind.N_TSLICE) { elemt = slctn.lhs; }; + if (sk == syntax.nkind.N_TARRAY) { elemt = slctn.lhs; }; // str IS []u8 (F1: tystr.sub = tyu8). []u8 hands cgen a real // u8 element node (slctn.lhs); a str scrutinee has none, so the // loop var would register tnode=nil and read back as a wide @@ -40097,12 +40097,12 @@ fn cgforrange(c: *cgen, n: *node) void = { // read-back to MOVZBQ on its own — aligning wwstage up to // cstage, whose checker stamps the binding u8. Kind-gated so // str's own type stays nominal. - if (sk == nkind.N_TNAME) { - if (streq(slctn.str, "str")) { - let sti: *tinfo = slctn.type_: *tinfo; + if (sk == syntax.nkind.N_TNAME) { + if (syntax.streq(slctn.str, "str")) { + let sti: *syntax.tinfo = slctn.type_: *syntax.tinfo; if (sti != nil) { if (sti.sub != nil) { - let u8n: *node = newnode(nkind.N_TNAME, slctn.file, slctn.line, slctn.col); + let u8n: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, slctn.file, slctn.line, slctn.col); u8n.str = "u8"; u8n.type_ = sti.sub: *void; elemt = u8n; @@ -40119,18 +40119,18 @@ fn cgforrange(c: *cgen, n: *node) void = { // (slc->type) feeds esz/alen/base classify uniformly) and // synthesise the element node off .sub — the FC0 non-ident // precedent below. - let rti60: *tinfo = nil; + let rti60: *syntax.tinfo = nil; if (slctn != nil) { - if (slctn.kind == nkind.N_TNAME) { - let st60: *tinfo = slctn.type_: *tinfo; + if (slctn.kind == syntax.nkind.N_TNAME) { + let st60: *syntax.tinfo = slctn.type_: *syntax.tinfo; if (st60 != nil) { - if (st60.kind == tykind.TY_NAMED) { rti60 = tichase(st60); }; + if (st60.kind == syntax.tykind.TY_NAMED) { rti60 = tichase(st60); }; }; }; }; if (rti60 != nil && elemt == nil) { if (rti60.sub != nil) { - let en60: *node = newnode(nkind.N_TNAME, slctn.file, slctn.line, slctn.col); + let en60: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, slctn.file, slctn.line, slctn.col); en60.str = rti60.sub.name; en60.type_ = rti60.sub: *void; elemt = en60; @@ -40150,13 +40150,13 @@ fn cgforrange(c: *cgen, n: *node) void = { // #60: alias-NAMED scrutinee — stride off the chased stamped // element (cstage esz = u->sub->size). if (rti60 != nil) { - let es60: *tinfo = tichase(rti60.sub); + let es60: *syntax.tinfo = tichase(rti60.sub); if (es60 != nil) { esz = es60.size: i32; }; }; if (elemt != nil) { - if (elemt.kind == nkind.N_TTUPLE) { + if (elemt.kind == syntax.nkind.N_TTUPLE) { let total: i32 = 0; - let p: *node = elemt.list; + let p: *syntax.node = elemt.list; for (p != nil) { total += paramfieldsize(p.lhs); p = p.next; @@ -40173,15 +40173,15 @@ fn cgforrange(c: *cgen, n: *node) void = { // str/slice/float keys read it like a declared local (the str→u8 // synthesis precedent above). if (slctn == nil && slc != nil) { - let sti2: *tinfo = slc.type_: *tinfo; + let sti2: *syntax.tinfo = slc.type_: *syntax.tinfo; sti2 = tichase(sti2); if (sti2 != nil) { - if (sti2.kind == tykind.TY_SLICE - || sti2.kind == tykind.TY_STR - || sti2.kind == tykind.TY_ARRAY) { + if (sti2.kind == syntax.tykind.TY_SLICE + || sti2.kind == syntax.tykind.TY_STR + || sti2.kind == syntax.tykind.TY_ARRAY) { if (sti2.sub != nil) { esz = sti2.sub.size: i32; - let en: *node = newnode(nkind.N_TNAME, slc.file, slc.line, slc.col); + let en: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, slc.file, slc.line, slc.col); en.str = sti2.sub.name; en.type_ = sti2.sub: *void; elemt = en; @@ -40208,12 +40208,12 @@ fn cgforrange(c: *cgen, n: *node) void = { let loff: i32 = localalloc(c, lname, 8, nil); let baseoff: i32 = 0; if (slc != nil) { - if (slc.kind != nkind.N_IDENT) { - let stu70: *tinfo = slc.type_: *tinfo; + if (slc.kind != syntax.nkind.N_IDENT) { + let stu70: *syntax.tinfo = slc.type_: *syntax.tinfo; stu70 = tichase(stu70); let arr70: bool = false; if (stu70 != nil) { - if (stu70.kind == tykind.TY_ARRAY) { + if (stu70.kind == syntax.tykind.TY_ARRAY) { arr70 = true; }; }; @@ -40226,8 +40226,8 @@ fn cgforrange(c: *cgen, n: *node) void = { // the AX/BX/CX header convention the spill assumes // (the deref-spine load family) — keep it LOUD until // #11 wires the deref load. - if (slc.kind == nkind.N_UN) { - if (slc.op == tkind.TK_STAR) { + if (slc.kind == syntax.nkind.N_UN) { + if (slc.op == syntax.tkind.TK_STAR) { let m11: str = "for-range over a deref base unwired (#11)\n"; os.write(2, m11.ptr, m11.len: u64); os.exit(1); @@ -40246,13 +40246,13 @@ fn cgforrange(c: *cgen, n: *node) void = { // into the for-range spine) is a DISTINCT mechanism — filed as a #121 // sibling, off fold-6's path. if (slc != nil) { - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { if (localfindnode(c, slc.str) == nil) { let isglob: bool = isletvar(c, slc.str); if (!isglob) { - let gdtn: *node = defvartnode(c, slc.str); + let gdtn: *syntax.node = defvartnode(c, slc.str); if (gdtn != nil) { - if (gdtn.kind == nkind.N_TARRAY) { isglob = true; }; + if (gdtn.kind == syntax.nkind.N_TARRAY) { isglob = true; }; }; }; if (isglob) { @@ -40273,12 +40273,12 @@ fn cgforrange(c: *cgen, n: *node) void = { let nbinds: i32 = 0; if (destruct) { - let tp: *node = nil; + let tp: *syntax.node = nil; if (elemt != nil) { - if (elemt.kind == nkind.N_TTUPLE) { tp = elemt.list; }; + if (elemt.kind == syntax.nkind.N_TTUPLE) { tp = elemt.list; }; }; let field_off: i32 = 0; - let m: *node = n.list; + let m: *syntax.node = n.list; for (m != nil) { if (nbinds >= 8) { m = nil; } else { @@ -40286,7 +40286,7 @@ fn cgforrange(c: *cgen, n: *node) void = { let signf: bool = false; // tp walks the N_TPARAM wrapper chain; tpt is the // actual element type AST. - let tpt: *node = nil; + let tpt: *syntax.node = nil; if (tp != nil) { tpt = tp.lhs; }; if (tpt != nil) { fsz = paramfieldsize(tpt); @@ -40340,22 +40340,22 @@ fn cgforrange(c: *cgen, n: *node) void = { let isarr: bool = false; let isslicestr: bool = false; if (slctn != nil) { - let tk: nkind = slctn.kind; - if (tk == nkind.N_TSLICE) { isslicestr = true; }; - if (tk == nkind.N_TARRAY) { isarr = true; }; - if (tk == nkind.N_TNAME) { - if (streq(slctn.str, "str")) { isslicestr = true; }; + let tk: syntax.nkind = slctn.kind; + if (tk == syntax.nkind.N_TSLICE) { isslicestr = true; }; + if (tk == syntax.nkind.N_TARRAY) { isarr = true; }; + if (tk == syntax.nkind.N_TNAME) { + if (syntax.streq(slctn.str, "str")) { isslicestr = true; }; }; }; // #60: alias-NAMED scrutinee — classify off the chased stamped // kind (cstage gates on u->kind TY_SLICE/TY_STR vs TY_ARRAY). if (rti60 != nil) { - if (rti60.kind == tykind.TY_ARRAY) { isarr = true; }; - if (rti60.kind == tykind.TY_SLICE) { isslicestr = true; }; - if (rti60.kind == tykind.TY_STR) { isslicestr = true; }; + if (rti60.kind == syntax.tykind.TY_ARRAY) { isarr = true; }; + if (rti60.kind == syntax.tykind.TY_SLICE) { isslicestr = true; }; + if (rti60.kind == syntax.tykind.TY_STR) { isslicestr = true; }; }; if (isslicestr) { - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { if (slclocal != nil) { emitline("\tMOVQ\t"); emitoff((slclocal.off + 8): i64); @@ -40368,7 +40368,7 @@ fn cgforrange(c: *cgen, n: *node) void = { } else { if (isarr) { let alen: i64 = 0i64; if (slctn.rhs != nil) { - if (slctn.rhs.kind == nkind.N_INTLIT) { alen = slctn.rhs.uval: i64; }; + if (slctn.rhs.kind == syntax.nkind.N_INTLIT) { alen = slctn.rhs.uval: i64; }; }; // #60: alias-NAMED scrutinee has no length tnode — bound off // the chased tinfo (cstage aimm(u->alen)). @@ -40437,7 +40437,7 @@ fn cgforrange(c: *cgen, n: *node) void = { emitline(", CX\n"); emitline("\tIMULQ\tCX, AX\n"); }; - if (slc.kind == nkind.N_IDENT) { + if (slc.kind == syntax.nkind.N_IDENT) { if (slclocal != nil) { if (isarr) { emitline("\tLEAQ\t"); @@ -40594,7 +40594,7 @@ fn cgforrange(c: *cgen, n: *node) void = { // default and runs after all named arms fail. Mirrors cmd/w6c/cgen.c // N_SWITCH: same labelseq consumption order so labels match byte-for- // byte. -fn cgswitch(c: *cgen, n: *node) void = { +fn cgswitch(c: *cgen, n: *syntax.node) void = { let swname: str = mkscratchname(c, "sw"); let sloff: i32 = localalloc(c, swname, 8, nil); @@ -40604,9 +40604,9 @@ fn cgswitch(c: *cgen, n: *node) void = { emitline("(BP)\n"); let endl: str = mklabel(c, "swend"); - let defcase: *node = nil; + let defcase: *syntax.node = nil; - let cs: *node = n.list; + let cs: *syntax.node = n.list; for (cs != nil) { if (cs.list == nil) { defcase = cs; @@ -40615,7 +40615,7 @@ fn cgswitch(c: *cgen, n: *node) void = { }; let body: str = mklabel(c, "swcase"); let nxt: str = mklabel(c, "swnext"); - let e: *node = cs.list; + let e: *syntax.node = cs.list; for (e != nil) { cgexpr(c, e); emitline("\tMOVQ\t"); @@ -40646,7 +40646,7 @@ fn cgswitch(c: *cgen, n: *node) void = { return; }; -fn cgbreak(c: *cgen, n: *node) void = { +fn cgbreak(c: *cgen, n: *syntax.node) void = { if (c.looptop > 0) { let lbl: str = c.loopendbuf[c.looptop - 1]; emitline("\tJMP\t"); emitline(lbl); emitline("\n"); @@ -40655,7 +40655,7 @@ fn cgbreak(c: *cgen, n: *node) void = { return; }; -fn cgcontinue(c: *cgen, n: *node) void = { +fn cgcontinue(c: *cgen, n: *syntax.node) void = { if (c.looptop > 0) { let lbl: str = c.loopcontbuf[c.looptop - 1]; emitline("\tJMP\t"); emitline(lbl); emitline("\n"); @@ -40688,8 +40688,8 @@ import strconv; // ---- function-level cgen --------------------------------------------- -fn cgfnparams(c: *cgen, params: *node) void = { - let p: *node = params; +fn cgfnparams(c: *cgen, params: *syntax.node) void = { + let p: *syntax.node = params; // sret (#23): RDI is consumed by the hidden dest pointer // (already spilled to @sretarg by cgfn); the first user param // lands in SI. @@ -40705,7 +40705,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { // post-walk consistency check against stkcursor. let memwords: i32 = 0; for (p != nil) { - if (p.kind == nkind.N_PARAM) { + if (p.kind == syntax.nkind.N_PARAM) { let nm: str = p.str; // Hare-style variadic `T...`: callee receives a []T // slice (3 register words / 24B). p.lhs is already @@ -40713,8 +40713,8 @@ fn cgfnparams(c: *cgen, params: *node) void = { // (mirrors cstage check.c:455 tp->type promotion), so // we consume it directly — re-wrapping via slicewrap // would yield [][]T. - if (p.op == tkind.TK_ELLIPSIS) { - let tn: *node = p.lhs; + if (p.op == syntax.tkind.TK_ELLIPSIS) { + let tn: *syntax.node = p.lhs; if (idx + 3 <= 6) { let off: i32 = localadd(c, nm, tyslicesize(): i32, tn); emitline("\tMOVQ\t"); @@ -40777,14 +40777,14 @@ fn cgfnparams(c: *cgen, params: *node) void = { // path → 1 slot, SI dropped, t.1 garbage. Slot size + element // walk source the RESOLVED node; localadd keeps the declared // p.lhs so field reads chase identically to cstage (byte-id). - let tt99: *node = nil; + let tt99: *syntax.node = nil; if (p.lhs != nil) { tt99 = p.lhs; - for (tt99 != nil && tt99.kind == nkind.N_TNAME) { + for (tt99 != nil && tt99.kind == syntax.nkind.N_TNAME) { tt99 = aliaslookup(c, tt99.str); }; }; - if (p.lhs != nil) { if (tt99 != nil && tt99.kind == nkind.N_TTUPLE) { + if (p.lhs != nil) { if (tt99 != nil && tt99.kind == syntax.nkind.N_TTUPLE) { // #163: tuple PARAM receive (param twin of #164's // return). Walk the tuple's elements over the SysV // arg cursor — a float reads its XMM (X0..X7), @@ -40796,9 +40796,9 @@ fn cgfnparams(c: *cgen, params: *node) void = { // partial-spill stitch is out of scope (twin of #164). let off: i32 = localadd(c, nm, slotsize(c, p.lhs), p.lhs); let eoff: i32 = 0; - let te: *node = tt99.list; + let te: *syntax.node = tt99.list; for (te != nil) { - let et: *node = te.lhs; + let et: *syntax.node = te.lhs; if (isfloattype(c, et)) { if (fidx >= 8) { let msg: str = "tuple param float element overflows SSE arg regs (X0..X7); stitch out of scope, see #163\n"; @@ -40920,7 +40920,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { // greedy stitch arm below while cstage received // one scalar word (cs≠ww, silent). // ref/qbe/amd64/sysv.c:80-85 / :411-426. - if (taggedmemargsize(p.lhs.type_: *tinfo) > 0) { + if (taggedmemargsize(p.lhs.type_: *syntax.tinfo) > 0) { localaddstack(c, nm, p.lhs, 16 + stkcursor*8); stkcursor += nw; memwords += nw; @@ -41119,7 +41119,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { localaddstack(c, nm, p.lhs, 16 + stkcursor*8); stkcursor += nw; };}; - } else { let aggsz2: i32 = aggargsizetn(p.lhs.type_: *tinfo); + } else { let aggsz2: i32 = aggargsizetn(p.lhs.type_: *syntax.tinfo); if (aggsz2 > 0) { // #271: array / >16B-struct by-value param — // received as ceil(sz/8) GP eightbytes, the @@ -41198,7 +41198,7 @@ fn cgfnparams(c: *cgen, params: *node) void = { }; }; -fn cgfn(c: *cgen, fn_: *node) void = { +fn cgfn(c: *cgen, fn_: *syntax.node) void = { cgeninit(c); c.fnname = fn_.str; c.curmod = fn_.nmod; @@ -41237,8 +41237,8 @@ fn cgfn(c: *cgen, fn_: *node) void = { // resolve identifiers via localfind, so the body's locals must // still be in c.locals when we get there. if (fn_.body != nil) { - if (fn_.body.kind == nkind.N_BLOCK) { - let s: *node = fn_.body.list; + if (fn_.body.kind == syntax.nkind.N_BLOCK) { + let s: *syntax.node = fn_.body.list; for (s != nil) { cgstmt(c, s); s = s.next; @@ -41274,7 +41274,7 @@ fn cgfn(c: *cgen, fn_: *node) void = { // fn_.nmod hint would fall through modlookupforfn's first-leaf match // onto an IMPORTED package's now-registered `pkg.main`. emitline("TEXT "); - if (streq(fn_.str, "main") && fn_.imported == 0) { + if (syntax.streq(fn_.str, "main") && fn_.imported == 0) { emitbytes(fn_.str.ptr, fn_.str.len: u64); } else { emitfnname(c, fn_.str, fn_.nmod); @@ -41294,7 +41294,7 @@ fn cgfn(c: *cgen, fn_: *node) void = { // ---- file-level entry ------------------------------------------------ -export fn cgfile(c: *cgen, file: *node) void = { +export fn cgfile(c: *cgen, file: *syntax.node) void = { if (file == nil) { return; }; c.strlits = nil; c.strlitseq = 0; @@ -41310,9 +41310,9 @@ export fn cgfile(c: *cgen, file: *node) void = { collectmods(c, file); defaultinferredlets(c, file); collectlets(c, file); - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_FNDECL) { + if (d.kind == syntax.nkind.N_FNDECL) { // #22 M3: emit code ONLY for this package's own decls. A // `.wwi` dep fn is a body-less prototype that already skips // (the body != nil gate); the explicit imported gate also @@ -41383,11 +41383,11 @@ import cgendecl; type aliasent = struct { aname: str, amod: str, // originating module (`// MODULE: foo`), or empty - target: *node, // the rhs type expr + target: *syntax.node, // the rhs type expr aanext: *aliasent, }; -fn collectaliases(c: *cgen, file: *node) void = { +fn collectaliases(c: *cgen, file: *syntax.node) void = { c.aliases = nil; // #29: seed `type nomem = !void;` here AS WELL AS in check.ww's // seedprimitives. The two seeds aren't redundant: wwstage's check @@ -41400,18 +41400,18 @@ fn collectaliases(c: *cgen, file: *node) void = { // same-module / any-match passes in aliaslookup then let a local // `type nomem = !void;` shadow this fallback within its module. let empty: str; - let tnvoid: *node = newnode(nkind.N_TNAME, empty, 0, 0); + let tnvoid: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, empty, 0, 0); tnvoid.str = "void"; - let bang: *node = newnode(nkind.N_TBANG, empty, 0, 0); + let bang: *syntax.node = syntax.newnode(syntax.nkind.N_TBANG, empty, 0, 0); bang.lhs = tnvoid; let nomemal: *aliasent = alloc(aliasent{aname="nomem", amod=empty, target=bang, aanext=nil})!; c.aliases = nomemal; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_TYPEDECL) { - let body: *node = d.lhs; + if (d.kind == syntax.nkind.N_TYPEDECL) { + let body: *syntax.node = d.lhs; if (body != nil) { - if (body.kind != nkind.N_TSTRUCT) { + if (body.kind != syntax.nkind.N_TSTRUCT) { let a: *aliasent = alloc(aliasent{aname=d.str, amod=d.nmod, target=body, aanext=c.aliases})!; c.aliases = a; }; @@ -41421,7 +41421,7 @@ fn collectaliases(c: *cgen, file: *node) void = { }; }; -fn aliaslookup(c: *cgen, name: str) *node = { +fn aliaslookup(c: *cgen, name: str) *syntax.node = { // Same-module first, then any. Mirrors cstage's scope_lookup_prefer // (cmd/wcc/check.c:65); without the prefer pass a bare `invalid` // in module M with `type invalid = !void;` can collapse onto a @@ -41431,14 +41431,14 @@ fn aliaslookup(c: *cgen, name: str) *node = { // (task #27 silent-correct-by-zero-init). let a: *aliasent = c.aliases; for (a != nil) { - if (streq(a.aname, name)) { - if (streq(a.amod, c.curmod)) { return a.target; }; + if (syntax.streq(a.aname, name)) { + if (syntax.streq(a.amod, c.curmod)) { return a.target; }; }; a = a.aanext; }; a = c.aliases; for (a != nil) { - if (streq(a.aname, name)) { return a.target; }; + if (syntax.streq(a.aname, name)) { return a.target; }; a = a.aanext; }; // Module-qualified form: `pkg.alias` → match the leaf name @@ -41460,8 +41460,8 @@ fn aliaslookup(c: *cgen, name: str) *node = { let pkgmod: str = usehint(c, pkg); let b: *aliasent = c.aliases; for (b != nil) { - if (streq(b.aname, leaf)) { - if (streq(b.amod, pkgmod)) { + if (syntax.streq(b.aname, leaf)) { + if (syntax.streq(b.amod, pkgmod)) { return b.target; }; }; @@ -41480,11 +41480,11 @@ fn aliaslookup(c: *cgen, name: str) *node = { // cgdot needs to know whether THIS module defines the name as an alias // (so the peel continues) without that cross-module fallback. Returns // the alias target only when an alias of `name` lives in c.curmod. -fn aliassamemod(c: *cgen, name: str) *node = { +fn aliassamemod(c: *cgen, name: str) *syntax.node = { let a: *aliasent = c.aliases; for (a != nil) { - if (streq(a.aname, name)) { - if (streq(a.amod, c.curmod)) { return a.target; }; + if (syntax.streq(a.aname, name)) { + if (syntax.streq(a.amod, c.curmod)) { return a.target; }; }; a = a.aanext; }; @@ -41507,34 +41507,34 @@ fn aliassamemod(c: *cgen, name: str) *node = { // Whitelist kept tight on purpose: anything richer (sibling refs, // arithmetic) belongs in enumevalmember, which calls this for its // literal leaves and handles the rest itself. -fn foldintliteral(e: *node, out: *u64) bool = { +fn foldintliteral(e: *syntax.node, out: *u64) bool = { if (e == nil) { return false; }; - let k: nkind = e.kind; - if (k == nkind.N_INTLIT) { *out = e.uval; return true; }; - if (k == nkind.N_RUNELIT) { *out = e.uval; return true; }; - if (k == nkind.N_TRUE) { *out = 1u64; return true; }; - if (k == nkind.N_FALSE) { *out = 0u64; return true; }; - if (k == nkind.N_NIL) { *out = 0u64; return true; }; - if (k == nkind.N_UN) { + let k: syntax.nkind = e.kind; + if (k == syntax.nkind.N_INTLIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_RUNELIT) { *out = e.uval; return true; }; + if (k == syntax.nkind.N_TRUE) { *out = 1u64; return true; }; + if (k == syntax.nkind.N_FALSE) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_NIL) { *out = 0u64; return true; }; + if (k == syntax.nkind.N_UN) { let v: u64; if (!foldintliteral(e.lhs, &v)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (op == tkind.TK_PLUS) { *out = v; return true; }; + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (op == syntax.tkind.TK_PLUS) { *out = v; return true; }; return false; }; return false; }; -fn enumevalmember(prev: *enummember, e: *node, out: *u64) bool = { +fn enumevalmember(prev: *enummember, e: *syntax.node, out: *u64) bool = { if (e == nil) { return false; }; if (foldintliteral(e, out)) { return true; }; - let k: nkind = e.kind; - if (k == nkind.N_IDENT) { + let k: syntax.nkind = e.kind; + if (k == syntax.nkind.N_IDENT) { let m: *enummember = prev; for (m != nil) { - if (streq(m.mname, e.str)) { + if (syntax.streq(m.mname, e.str)) { *out = m.mval; return true; }; @@ -41542,55 +41542,55 @@ fn enumevalmember(prev: *enummember, e: *node, out: *u64) bool = { }; return false; }; - if (k == nkind.N_BIN) { + if (k == syntax.nkind.N_BIN) { let a: u64; let b: u64; if (!enumevalmember(prev, e.lhs, &a)) { return false; }; if (!enumevalmember(prev, e.rhs, &b)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_PLUS) { *out = a + b; return true; }; - if (op == tkind.TK_MINUS) { *out = a - b; return true; }; - if (op == tkind.TK_STAR) { *out = a * b; return true; }; - if (op == tkind.TK_SLASH) { + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_PLUS) { *out = a + b; return true; }; + if (op == syntax.tkind.TK_MINUS) { *out = a - b; return true; }; + if (op == syntax.tkind.TK_STAR) { *out = a * b; return true; }; + if (op == syntax.tkind.TK_SLASH) { if (b == 0u64) { return false; }; *out = a / b; return true; }; - if (op == tkind.TK_PERCENT) { + if (op == syntax.tkind.TK_PERCENT) { if (b == 0u64) { return false; }; *out = a % b; return true; }; - if (op == tkind.TK_AMP) { *out = a & b; return true; }; - if (op == tkind.TK_PIPE) { *out = a | b; return true; }; - if (op == tkind.TK_CARET) { *out = a ^ b; return true; }; - if (op == tkind.TK_LSHIFT) { *out = a << b; return true; }; - if (op == tkind.TK_RSHIFT) { *out = a >> b; return true; }; + if (op == syntax.tkind.TK_AMP) { *out = a & b; return true; }; + if (op == syntax.tkind.TK_PIPE) { *out = a | b; return true; }; + if (op == syntax.tkind.TK_CARET) { *out = a ^ b; return true; }; + if (op == syntax.tkind.TK_LSHIFT) { *out = a << b; return true; }; + if (op == syntax.tkind.TK_RSHIFT) { *out = a >> b; return true; }; return false; }; - if (k == nkind.N_UN) { + if (k == syntax.nkind.N_UN) { let v: u64; if (!enumevalmember(prev, e.lhs, &v)) { return false; }; - let op: tkind = e.op; - if (op == tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; - if (op == tkind.TK_TILDE) { *out = ~v; return true; }; - if (op == tkind.TK_PLUS) { *out = v; return true; }; + let op: syntax.tkind = e.op; + if (op == syntax.tkind.TK_MINUS) { *out = (-(v: i64)): u64; return true; }; + if (op == syntax.tkind.TK_TILDE) { *out = ~v; return true; }; + if (op == syntax.tkind.TK_PLUS) { *out = v; return true; }; return false; }; return false; }; -fn collectenums(c: *cgen, file: *node) void = { +fn collectenums(c: *cgen, file: *syntax.node) void = { c.enums = nil; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_TYPEDECL) { - let body: *node = d.lhs; + if (d.kind == syntax.nkind.N_TYPEDECL) { + let body: *syntax.node = d.lhs; if (body != nil) { - if (body.kind == nkind.N_TENUM) { + if (body.kind == syntax.nkind.N_TENUM) { let et: *enumtype = alloc(enumtype{ename=d.str, emod=d.nmod, storage=body.lhs, members=nil, etnext=nil})!; let prev: u64 = (-1i64): u64; let mhead: *enummember = nil; let mtail: *enummember = nil; - let m: *node = body.list; + let m: *syntax.node = body.list; for (m != nil) { let val: u64; if (m.lhs == nil) { @@ -41624,14 +41624,14 @@ fn enumlookup(c: *cgen, name: str) *enumtype = { // c.enums, silently folding `Foo.MEMBER` to the wrong constant. let e: *enumtype = c.enums; for (e != nil) { - if (streq(e.ename, name)) { - if (streq(e.emod, c.curmod)) { return e; }; + if (syntax.streq(e.ename, name)) { + if (syntax.streq(e.emod, c.curmod)) { return e; }; }; e = e.etnext; }; e = c.enums; for (e != nil) { - if (streq(e.ename, name)) { return e; }; + if (syntax.streq(e.ename, name)) { return e; }; e = e.etnext; }; // Module-qualified form embedded in name (`pkg.enum`): scope the @@ -41651,8 +41651,8 @@ fn enumlookup(c: *cgen, name: str) *enumtype = { let pkgmod: str = usehint(c, pkg); let b: *enumtype = c.enums; for (b != nil) { - if (streq(b.ename, leaf)) { - if (streq(b.emod, pkgmod)) { + if (syntax.streq(b.ename, leaf)) { + if (syntax.streq(b.emod, pkgmod)) { return b; }; }; @@ -41673,8 +41673,8 @@ fn enumlookupmod(c: *cgen, name: str, mod: str) *enumtype = { if (mod.len > 0) { let e: *enumtype = c.enums; for (e != nil) { - if (streq(e.ename, name)) { - if (streq(e.emod, mod)) { return e; }; + if (syntax.streq(e.ename, name)) { + if (syntax.streq(e.emod, mod)) { return e; }; }; e = e.etnext; }; @@ -41685,7 +41685,7 @@ fn enumlookupmod(c: *cgen, name: str, mod: str) *enumtype = { fn enummemberval(en: *enumtype, mname: str, out: *u64) bool = { let m: *enummember = en.members; for (m != nil) { - if (streq(m.mname, mname)) { + if (syntax.streq(m.mname, mname)) { *out = m.mval; return true; }; @@ -41696,14 +41696,14 @@ fn enummemberval(en: *enumtype, mname: str, out: *u64) bool = { // resolvetype — follow typedef alias chains to a "canonical" type // expr (str/slice/array/struct/...). Stops on cycles via depth limit. -fn resolvetype(c: *cgen, t: *node) *node = { - let cur: *node = t; +fn resolvetype(c: *cgen, t: *syntax.node) *syntax.node = { + let cur: *syntax.node = t; let depth: i32 = 0; for (depth < 16) { if (cur == nil) { return nil; }; - if (cur.kind != nkind.N_TNAME) { return cur; }; + if (cur.kind != syntax.nkind.N_TNAME) { return cur; }; let nm: str = cur.str; - let next: *node = aliaslookup(c, nm); + let next: *syntax.node = aliaslookup(c, nm); if (next == nil) { return cur; }; cur = next; depth += 1; @@ -41722,7 +41722,7 @@ type fieldinfo = struct { fname: str, foff: i32, fsz: i32, - tnode: *node, // the field type expr, for nested struct lookups + tnode: *syntax.node, // the field type expr, for nested struct lookups finext: *fieldinfo, }; @@ -41746,7 +41746,7 @@ type local = struct { // scanlocals pre-pass, so @tagscr/@retscr/@sretscr/ // @tagbase are sized at first-use; subsequent uses // must fit. - tnode: *node, // declared type expr (nkind.N_TNAME / nkind.N_TPTR / ...) or nil + tnode: *syntax.node, // declared type expr (nkind.N_TNAME / nkind.N_TPTR / ...) or nil lnext: *local, }; @@ -41780,7 +41780,7 @@ type enummember = struct { type enumtype = struct { ename: str, emod: str, // originating module (`// MODULE: foo`), or empty - storage: *node, // AST type expr for the storage type (i32 by default) + storage: *syntax.node, // AST type expr for the storage type (i32 by default) members: *enummember, etnext: *enumtype, }; @@ -41834,14 +41834,14 @@ type cgen = struct { // inside lib/foo binds to `foo.frob` even when // other modules also export `frob`. Set in cgfn // before walking the body. - fnret: *node, // declared return type of current fn (or nil) + fnret: *syntax.node, // declared return type of current fn (or nil) looptop: i32, loopendbuf: []str, // stack of end labels for break loopcontbuf: []str, // stack of cont labels for continue yieldtop: i32, yieldbuf: []str, // stack of match end labels for yield defertop: i32, - deferbuf: []*node, // stack of deferred exprs (LIFO at return) + deferbuf: []*syntax.node, // stack of deferred exprs (LIFO at return) // System V AMD64 sret discipline (#23). Plain TY_STRUCT returns // with size > 24B are passed via a hidden first-arg pointer // (RDI) to a caller-prealloc dest; the callee writes through @@ -41869,7 +41869,7 @@ type cgen = struct { // (sretdestoff) can't name a top-level let, so the lhs IDENT node // is carried and emitted as `LEAQ name(SB), DI`. nil means no // global receiver wired; mutually exclusive with sretdestoff. - sretdestnode: *node, + sretdestnode: *syntax.node, sretforward: i32, // #22 M3 `-c`: separate-compile / primary-only codegen. Emit code+ // DATA ONLY for this package's own (imported==0) decls; treat every @@ -41889,7 +41889,7 @@ type cgen = struct { // when picking the load/store sequence. type letvar = struct { name: str, - tnode: *node, + tnode: *syntax.node, lvnext: *letvar, }; @@ -41914,7 +41914,7 @@ fn cgeninit(c: *cgen) void = { let yieldbuf: []str = alloc([], LOOP_MAX: u64)!; c.yieldbuf = yieldbuf; c.defertop = 0; - let deferbuf: []*node = alloc([], DEFER_MAX: u64)!; + let deferbuf: []*syntax.node = alloc([], DEFER_MAX: u64)!; c.deferbuf = deferbuf; }; @@ -41922,7 +41922,7 @@ fn cgeninit(c: *cgen) void = { // match-arm bindings, which cstage allocates via cgexpr's by-value // `locals` list — so two separate matches each get fresh slots even // when their bind names collide. -fn localalloc(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { +fn localalloc(c: *cgen, name: str, sz: i32, tnode: *syntax.node) i32 = { let asz: i32 = sz; if (asz < 8) { asz = 8; }; if ((asz & 7) != 0) { asz = (asz + 7) & ~7; }; @@ -41938,7 +41938,7 @@ fn localalloc(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { // the binding into c.locals only AFTER, so a self-shadowing init // (`let x = f(x)`) resolves x in the OUTER scope (Hare evals the init in // the outer scope: harec check.c clet runs cexpr before scope_define). -fn localreserve(c: *cgen, name: str, sz: i32, tnode: *node) *local = { +fn localreserve(c: *cgen, name: str, sz: i32, tnode: *syntax.node) *local = { // #15: mirror cstage localslot (cmd/w6c/cgen.c:1900) — // `frame = (frame + size + 7) & ~7`, NO sub-8 floor. Identical to // the old `max(8, round8(sz))` accumulation for every sz>0 (frame @@ -41958,12 +41958,12 @@ fn localreserve(c: *cgen, name: str, sz: i32, tnode: *node) *local = { // pushes them in reverse, so each spilled arg lives at 16(BP), 24(BP), // etc. (after the saved RIP+BP). No spill instruction is emitted; the // slot IS the caller's stack slot. -fn localaddstack(c: *cgen, name: str, tnode: *node, off: i32) void = { +fn localaddstack(c: *cgen, name: str, tnode: *syntax.node, off: i32) void = { let l: *local = alloc(local{name=name, off=off, sz=0, tnode=tnode, lnext=c.locals})!; c.locals = l; }; -fn localadd(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { +fn localadd(c: *cgen, name: str, sz: i32, tnode: *syntax.node) i32 = { // User-let path (post-#27): always allocate a fresh slot per // binding. Pre-fix this deduped by name to share one slot // across same-name lets in disjoint scopes — inherited from @@ -41991,7 +41991,7 @@ fn localadd(c: *cgen, name: str, sz: i32, tnode: *node) i32 = { let cur: *local = c.atlocals; for (cur != nil) { let cn: str = cur.name; - if (streq(cn, name)) { + if (syntax.streq(cn, name)) { if (asz > cur.sz) { // rule-7 surface, post-#15: pinned slot // offset can't grow in place. @@ -42054,7 +42054,7 @@ fn localfindnode(c: *cgen, name: str) *local = { let l: *local = c.locals; for (l != nil) { let ln: str = l.name; - if (streq(ln, name)) { return l; }; + if (syntax.streq(ln, name)) { return l; }; l = l.lnext; }; // @-prefix scratch slots survive cgblock save/restore via @@ -42064,7 +42064,7 @@ fn localfindnode(c: *cgen, name: str) *local = { if (name[0] == 64u8) { let a: *local = c.atlocals; for (a != nil) { - if (streq(a.name, name)) { return a; }; + if (syntax.streq(a.name, name)) { return a; }; a = a.lnext; }; }; @@ -42083,7 +42083,7 @@ fn localfind(c: *cgen, name: str) i32 = { if (name[0] == 64u8) { let a: *local = c.atlocals; for (a != nil) { - if (streq(a.name, name)) { return a.off; }; + if (syntax.streq(a.name, name)) { return a.off; }; a = a.lnext; }; }; @@ -42279,7 +42279,7 @@ fn internstrlit(c: *cgen, bytes: str) str = { let s: *strlit = c.strlits; for (s != nil) { let bs: str = s.bytes; - if (streq(bs, bytes)) { + if (syntax.streq(bs, bytes)) { return s.label; }; s = s.slnext; @@ -42318,28 +42318,28 @@ fn internstrlit(c: *cgen, bytes: str) str = { // types are handled separately by letfloatprim — they need MOVSS/MOVSD // and use 4-byte (f32) or 8-byte (f64) slots. fn letscalarprim(nm: str) bool = { - if (streq(nm, "bool")) { return true; }; - if (streq(nm, "rune")) { return true; }; - if (streq(nm, "i8")) { return true; }; - if (streq(nm, "i16")) { return true; }; - if (streq(nm, "i32")) { return true; }; - if (streq(nm, "i64")) { return true; }; - if (streq(nm, "u8")) { return true; }; - if (streq(nm, "u16")) { return true; }; - if (streq(nm, "u32")) { return true; }; - if (streq(nm, "u64")) { return true; }; - if (streq(nm, "int")) { return true; }; - if (streq(nm, "uint")) { return true; }; - if (streq(nm, "uintptr")) { return true; }; - if (streq(nm, "size")) { return true; }; + if (syntax.streq(nm, "bool")) { return true; }; + if (syntax.streq(nm, "rune")) { return true; }; + if (syntax.streq(nm, "i8")) { return true; }; + if (syntax.streq(nm, "i16")) { return true; }; + if (syntax.streq(nm, "i32")) { return true; }; + if (syntax.streq(nm, "i64")) { return true; }; + if (syntax.streq(nm, "u8")) { return true; }; + if (syntax.streq(nm, "u16")) { return true; }; + if (syntax.streq(nm, "u32")) { return true; }; + if (syntax.streq(nm, "u64")) { return true; }; + if (syntax.streq(nm, "int")) { return true; }; + if (syntax.streq(nm, "uint")) { return true; }; + if (syntax.streq(nm, "uintptr")) { return true; }; + if (syntax.streq(nm, "size")) { return true; }; return false; }; // letfloatprim — float type-name keywords. f32 → 4B slot, f64 → 8B. // Returns the slot size or 0 if not a float type. fn letfloatprim(nm: str) i32 = { - if (streq(nm, "f32")) { return 4; }; - if (streq(nm, "f64")) { return 8; }; + if (syntax.streq(nm, "f32")) { return 4; }; + if (syntax.streq(nm, "f64")) { return 8; }; return 0; }; @@ -42351,31 +42351,31 @@ fn letfloatprim(nm: str) i32 = { // 16 → str (only zero-init / nil / "" supported) // 24 → slice (only zero-init supported) // varies → struct (zero-init only; field reads/scalar-field writes) -fn letemitsize(c: *cgen, d: *node) i32 = { +fn letemitsize(c: *cgen, d: *syntax.node) i32 = { if (d == nil) { return 0; }; - let t: *node = d.lhs; + let t: *syntax.node = d.lhs; for (t != nil) { - if (t.kind == nkind.N_TPTR) { return 8; }; - if (t.kind == nkind.N_TSLICE) { return tyslicesize(): i32; }; - if (t.kind == nkind.N_TARRAY) { - let lenn: *node = t.rhs; - let elemn: *node = t.lhs; + if (t.kind == syntax.nkind.N_TPTR) { return 8; }; + if (t.kind == syntax.nkind.N_TSLICE) { return tyslicesize(): i32; }; + if (t.kind == syntax.nkind.N_TARRAY) { + let lenn: *syntax.node = t.rhs; + let elemn: *syntax.node = t.lhs; let alen: i32 = 1; - if (lenn != nil && lenn.kind == nkind.N_INTLIT) { + if (lenn != nil && lenn.kind == syntax.nkind.N_INTLIT) { alen = lenn.uval: i32; } else { // #56: def/const dim — resolve from the stamped array // tinfo (rule-13), the letemitsize twin of the cgdot // .len fix. Pre-fix a non-N_INTLIT dim defaulted alen=1 // → array global mis-sized (one element's worth). - let abt: *tinfo = tichase(t.type_: *tinfo); - if (abt != nil && abt.kind == tykind.TY_ARRAY) { + let abt: *syntax.tinfo = tichase(t.type_: *syntax.tinfo); + if (abt != nil && abt.kind == syntax.tykind.TY_ARRAY) { alen = abt.alen: i32; }; }; let esz: i32 = 8; if (elemn != nil) { - if (elemn.kind == nkind.N_TNAME) { + if (elemn.kind == syntax.nkind.N_TNAME) { let ps: i32 = aliasprimsize(c, elemn.str); if (ps > 0) { esz = ps; }; }; @@ -42389,11 +42389,11 @@ fn letemitsize(c: *cgen, d: *node) i32 = { // globals out of collectlets entirely — no DATA emitted, and // the module-leaf fallback mis-emitted the field index as a // symbol (`MOVQ 0(SB), AX`). - if (t.kind == nkind.N_TTUPLE) { + if (t.kind == syntax.nkind.N_TTUPLE) { let tsum: i32 = 0; - let p: *node = t.list; + let p: *syntax.node = t.list; for (p != nil) { - let et: *node = p.lhs; + let et: *syntax.node = p.lhs; if (isstrtype(c, et) || isslicetype(c, et)) { tsum += (tyslicesize(): i32); } else { @@ -42406,7 +42406,7 @@ fn letemitsize(c: *cgen, d: *node) i32 = { // #87: non-nullable tagged-union global — box size (tag word + // max payload, mirror of the runtime local). Mirrors cstage // let_emit_size TY_TAGGED. - if (t.kind == nkind.N_TTAGGED) { + if (t.kind == syntax.nkind.N_TTAGGED) { // #45 (silent→loud bridge, task #15): a nullable (*T|void) // GLOBAL has no storage path. Returning 0 here made // letcollect + emitletdataw silently skip the decl (no DATA, @@ -42422,15 +42422,15 @@ fn letemitsize(c: *cgen, d: *node) i32 = { }; return slotsize(c, t); }; - if (t.kind != nkind.N_TNAME) { return 0; }; + if (t.kind != syntax.nkind.N_TNAME) { return 0; }; let nm: str = t.str; if (letscalarprim(nm)) { return 8; }; let fsz: i32 = letfloatprim(nm); if (fsz > 0) { return fsz; }; - if (streq(nm, "str")) { return primtypesize("str"): i32; }; + if (syntax.streq(nm, "str")) { return primtypesize("str"): i32; }; let si: *structinfo = structlookup(c, nm); if (si != nil) { return si.totsize; }; - let next: *node = aliaslookup(c, nm); + let next: *syntax.node = aliaslookup(c, nm); if (next == nil) { return 0; }; t = next; }; @@ -42464,23 +42464,23 @@ fn letemitsize(c: *cgen, d: *node) i32 = { // cs≠ww divergence (rule-10) — it ships only WITH the cstage float-use-site fix. // Runs before collectlets in cgfile so the mutated d.lhs is visible to // letpreintern + emitletdataw too. -fn defaultinferredlets(c: *cgen, file: *node) void = { +fn defaultinferredlets(c: *cgen, file: *syntax.node) void = { if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { if (d.lhs != nil && d.rhs != nil - && d.lhs.kind == nkind.N_TNAME - && streq(d.lhs.str, "untyped_int")) { - let opnd: *node = d.rhs; - if (opnd.kind == nkind.N_UN - && (opnd.op == tkind.TK_PLUS - || opnd.op == tkind.TK_MINUS - || opnd.op == tkind.TK_TILDE)) { + && d.lhs.kind == syntax.nkind.N_TNAME + && syntax.streq(d.lhs.str, "untyped_int")) { + let opnd: *syntax.node = d.rhs; + if (opnd.kind == syntax.nkind.N_UN + && (opnd.op == syntax.tkind.TK_PLUS + || opnd.op == syntax.tkind.TK_MINUS + || opnd.op == syntax.tkind.TK_TILDE)) { opnd = opnd.lhs; }; if (opnd != nil - && opnd.kind == nkind.N_INTLIT) { + && opnd.kind == syntax.nkind.N_INTLIT) { d.lhs.str = "int"; }; }; @@ -42495,16 +42495,16 @@ fn defaultinferredlets(c: *cgen, file: *node) void = { // return (X0 untouched). Mirror cstage check.c clet // type_default. if (d.lhs != nil && d.rhs != nil - && d.lhs.kind == nkind.N_TNAME - && streq(d.lhs.str, "untyped_float")) { - let opnd: *node = d.rhs; - if (opnd.kind == nkind.N_UN - && (opnd.op == tkind.TK_PLUS - || opnd.op == tkind.TK_MINUS)) { + && d.lhs.kind == syntax.nkind.N_TNAME + && syntax.streq(d.lhs.str, "untyped_float")) { + let opnd: *syntax.node = d.rhs; + if (opnd.kind == syntax.nkind.N_UN + && (opnd.op == syntax.tkind.TK_PLUS + || opnd.op == syntax.tkind.TK_MINUS)) { opnd = opnd.lhs; }; if (opnd != nil - && opnd.kind == nkind.N_FLOATLIT) { + && opnd.kind == syntax.nkind.N_FLOATLIT) { d.lhs.str = "f64"; }; }; @@ -42513,12 +42513,12 @@ fn defaultinferredlets(c: *cgen, file: *node) void = { }; }; -fn collectlets(c: *cgen, file: *node) void = { +fn collectlets(c: *cgen, file: *syntax.node) void = { c.lets = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { let nm: str = d.str; if (nm.len > 0) { if (letemitsize(c, d) > 0) { @@ -42534,7 +42534,7 @@ fn collectlets(c: *cgen, file: *node) void = { fn isletvar(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { return true; }; + if (syntax.streq(lv.name, name)) { return true; }; lv = lv.lvnext; }; return false; @@ -42548,10 +42548,10 @@ fn isletvar(c: *cgen, name: str) bool = { // cgindex / cgassign to detect global `[N]T` arrays and `*T` // pointers, where the addressing path needs LEAQ name(SB) (array) // or MOVQ name(SB) (pointer) and the element size from T. -fn letvartnode(c: *cgen, name: str) *node = { +fn letvartnode(c: *cgen, name: str) *syntax.node = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { return lv.tnode; }; + if (syntax.streq(lv.name, name)) { return lv.tnode; }; lv = lv.lvnext; }; return nil; @@ -42560,13 +42560,13 @@ fn letvartnode(c: *cgen, name: str) *node = { fn letvarisstr(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let nm: str = t.str; - if (streq(nm, "str")) { return true; }; - let nx: *node = aliaslookup(c, nm); + if (syntax.streq(nm, "str")) { return true; }; + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return false; }; t = nx; }; @@ -42590,12 +42590,12 @@ fn letvarisstr(c: *cgen, name: str) bool = { fn letvarisslice(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind == nkind.N_TSLICE) { return true; }; - if (t.kind != nkind.N_TNAME) { return false; }; - let nx: *node = aliaslookup(c, t.str); + if (t.kind == syntax.nkind.N_TSLICE) { return true; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; + let nx: *syntax.node = aliaslookup(c, t.str); if (nx == nil) { return false; }; t = nx; }; @@ -42612,13 +42612,13 @@ fn letvarisslice(c: *cgen, name: str) bool = { fn letvarisfloat(c: *cgen, name: str) i32 = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return 0; }; + if (t.kind != syntax.nkind.N_TNAME) { return 0; }; let fsz: i32 = letfloatprim(t.str); if (fsz > 0) { return fsz; }; - let nx: *node = aliaslookup(c, t.str); + let nx: *syntax.node = aliaslookup(c, t.str); if (nx == nil) { return 0; }; t = nx; }; @@ -42636,13 +42636,13 @@ fn letvarisfloat(c: *cgen, name: str) i32 = { fn letvarisstruct(c: *cgen, name: str) bool = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return false; }; + if (t.kind != syntax.nkind.N_TNAME) { return false; }; let nm: str = t.str; if (structlookup(c, nm) != nil) { return true; }; - let nx: *node = aliaslookup(c, nm); + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return false; }; t = nx; }; @@ -42659,14 +42659,14 @@ fn letvarisstruct(c: *cgen, name: str) bool = { fn letvarstructinfo(c: *cgen, name: str) *structinfo = { let lv: *letvar = c.lets; for (lv != nil) { - if (streq(lv.name, name)) { - let t: *node = lv.tnode; + if (syntax.streq(lv.name, name)) { + let t: *syntax.node = lv.tnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return nil; }; + if (t.kind != syntax.nkind.N_TNAME) { return nil; }; let nm: str = t.str; let si: *structinfo = structlookup(c, nm); if (si != nil) { return si; }; - let nx: *node = aliaslookup(c, nm); + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return nil; }; t = nx; }; @@ -42689,14 +42689,14 @@ fn letvarstructinfo(c: *cgen, name: str) *structinfo = { fn defvarstructinfo(c: *cgen, name: str) *structinfo = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - let t: *node = e.dtnode; + if (syntax.streq(e.dname, name)) { + let t: *syntax.node = e.dtnode; for (t != nil) { - if (t.kind != nkind.N_TNAME) { return nil; }; + if (t.kind != syntax.nkind.N_TNAME) { return nil; }; let nm: str = t.str; let si: *structinfo = structlookup(c, nm); if (si != nil) { return si; }; - let nx: *node = aliaslookup(c, nm); + let nx: *syntax.node = aliaslookup(c, nm); if (nx == nil) { return nil; }; t = nx; }; @@ -42713,10 +42713,10 @@ fn defvarstructinfo(c: *cgen, name: str) *structinfo = { // resolves through the same N_TARRAY-detect → LEAQ name(SB) shape as // a let array. Parallel to defvarstructinfo (#129 A.2) at the LOAD // side widening. -fn defvartnode(c: *cgen, name: str) *node = { +fn defvartnode(c: *cgen, name: str) *syntax.node = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { return e.dtnode; }; + if (syntax.streq(e.dname, name)) { return e.dtnode; }; e = e.dnext; }; return nil; @@ -42762,25 +42762,25 @@ fn emitdatawbyte(b: u8) void = { // order emitstrarraydata references them by — a divergent order would // mis-pair the DATAR rows with their _S_ rodata. au is the chased // TY_ARRAY tinfo, r the N_ARRLIT rhs; caller verified the element is str. -fn preinternstrarray(c: *cgen, au: *tinfo, r: *node) void = { +fn preinternstrarray(c: *cgen, au: *syntax.tinfo, r: *syntax.node) void = { let alen: i32 = au.alen: i32; let cnt: i32 = 0; - let last_ev: *node = nil; + let last_ev: *syntax.node = nil; let repeat: bool = false; - let e: *node = r.list; + let e: *syntax.node = r.list; for (e != nil && cnt < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { break; }; - if (ev.kind != nkind.N_STRLIT) { break; }; + if (ev.kind != syntax.nkind.N_STRLIT) { break; }; if (ev.str.len > 0) { internstrlit(c, ev.str); }; @@ -42804,7 +42804,7 @@ fn preinternstrarray(c: *cgen, au: *tinfo, r: *node) void = { // emitdatasection emits the DATA row in the same .s file. Running // emitletdataw after emitdatasection would flip the (DATA strlits, // DATAW lets) section order and break byte-identity. -export fn letpreintern(c: *cgen, file: *node) void = { +export fn letpreintern(c: *cgen, file: *syntax.node) void = { if (file == nil) { return; }; // #49: strlit labels allocated here (static-data initialisers) take // the OWNING decl's module prefix, not the stale last-fn curmod. @@ -42812,7 +42812,7 @@ export fn letpreintern(c: *cgen, file: *node) void = { // fn-ptr relocs — see the same value they did before; letpreintern // itself only interns, so driving curmod here has no other effect. let savedmod: str = c.curmod; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { c.curmod = d.nmod; // #22 M3: skip imported deps so the strlit table (and its _S_ @@ -42830,26 +42830,26 @@ export fn letpreintern(c: *cgen, file: *node) void = { // allocated too late (emitdefconstants pass) → dangling _S_. // Str-array ONLY — def tuple/slice/tagged/scalar-str stay out // of scope (#10/#270 / inline-Sdef). - if (d.kind == nkind.N_DEF) { - let dr: *node = d.rhs; - for (dr != nil && dr.kind == nkind.N_CAST) { + if (d.kind == syntax.nkind.N_DEF) { + let dr: *syntax.node = d.rhs; + for (dr != nil && dr.kind == syntax.nkind.N_CAST) { dr = dr.lhs; }; if (d.lhs != nil && dr != nil - && dr.kind == nkind.N_ARRLIT) { - let dau: *tinfo = tichase(d.lhs.type_: *tinfo); - if (dau != nil && dau.kind == tykind.TY_ARRAY) { - let deu: *tinfo = tichase(dau.sub); - if (deu != nil && deu.kind == tykind.TY_STR) { + && dr.kind == syntax.nkind.N_ARRLIT) { + let dau: *syntax.tinfo = tichase(d.lhs.type_: *syntax.tinfo); + if (dau != nil && dau.kind == syntax.tykind.TY_ARRAY) { + let deu: *syntax.tinfo = tichase(dau.sub); + if (deu != nil && deu.kind == syntax.tykind.TY_STR) { preinternstrarray(c, dau, dr); }; }; }; }; - if (d.kind == nkind.N_LET) { - let r: *node = d.rhs; + if (d.kind == syntax.nkind.N_LET) { + let r: *syntax.node = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // #18: `let xs: [N]str = […];` — pre-intern each @@ -42862,11 +42862,11 @@ export fn letpreintern(c: *cgen, file: *node) void = { // globals, desyncing label order vs cstage. let handled: bool = false; if (d.lhs != nil && r != nil) { - let au: *tinfo = tichase(d.lhs.type_: *tinfo); - if (au != nil && au.kind == tykind.TY_ARRAY - && r.kind == nkind.N_ARRLIT) { - let eu: *tinfo = tichase(au.sub); - if (eu != nil && eu.kind == tykind.TY_STR) { + let au: *syntax.tinfo = tichase(d.lhs.type_: *syntax.tinfo); + if (au != nil && au.kind == syntax.tykind.TY_ARRAY + && r.kind == syntax.nkind.N_ARRLIT) { + let eu: *syntax.tinfo = tichase(au.sub); + if (eu != nil && eu.kind == syntax.tykind.TY_STR) { handled = true; preinternstrarray(c, au, r); }; @@ -42877,24 +42877,24 @@ export fn letpreintern(c: *cgen, file: *node) void = { // arm's DATAR rows find their _S_ rodata rows (the // #18 array-arm pattern; cstage let_pre_intern twin). if (!handled && r != nil && d.lhs != nil) { - if (r.kind == nkind.N_TUPLE) { - let tlt: *node = d.lhs; - for (tlt != nil && tlt.kind == nkind.N_TNAME) { + if (r.kind == syntax.nkind.N_TUPLE) { + let tlt: *syntax.node = d.lhs; + for (tlt != nil && tlt.kind == syntax.nkind.N_TNAME) { tlt = aliaslookup(c, tlt.str); }; if (tlt != nil) { - if (tlt.kind == nkind.N_TTUPLE) { + if (tlt.kind == syntax.nkind.N_TTUPLE) { handled = true; - let tp: *node = tlt.list; - let e: *node = r.list; + let tp: *syntax.node = tlt.list; + let e: *syntax.node = r.list; for (e != nil && tp != nil) { - let et: *node = tp.lhs; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { + let et: *syntax.node = tp.lhs; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev != nil) { - if (ev.kind == nkind.N_STRLIT + if (ev.kind == syntax.nkind.N_STRLIT && (isstrtype(c, et) || isslicetype(c, et))) { if (ev.str.len > 0) { internstrlit(c, ev.str); @@ -42917,28 +42917,28 @@ export fn letpreintern(c: *cgen, file: *node) void = { // rodata rows (cstage letpreintern twin). Bounded to // inline N_TTUPLE element types. if (!handled && r != nil && d.lhs != nil) { - if (r.kind == nkind.N_ARRLIT - && d.lhs.kind == nkind.N_TSLICE) { - let tupnode: *node = d.lhs.lhs; - if (tupnode != nil && tupnode.kind == nkind.N_TTUPLE) { + if (r.kind == syntax.nkind.N_ARRLIT + && d.lhs.kind == syntax.nkind.N_TSLICE) { + let tupnode: *syntax.node = d.lhs.lhs; + if (tupnode != nil && tupnode.kind == syntax.nkind.N_TTUPLE) { handled = true; - let row: *node = r.list; + let row: *syntax.node = r.list; for (row != nil) { - let rw: *node = row; - for (rw != nil && rw.kind == nkind.N_CAST) { + let rw: *syntax.node = row; + for (rw != nil && rw.kind == syntax.nkind.N_CAST) { rw = rw.lhs; }; - if (rw != nil && rw.kind == nkind.N_TUPLE) { - let tp: *node = tupnode.list; - let e: *node = rw.list; + if (rw != nil && rw.kind == syntax.nkind.N_TUPLE) { + let tp: *syntax.node = tupnode.list; + let e: *syntax.node = rw.list; for (e != nil && tp != nil) { - let et: *node = tp.lhs; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { + let et: *syntax.node = tp.lhs; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev != nil) { - if (ev.kind == nkind.N_STRLIT + if (ev.kind == syntax.nkind.N_STRLIT && (isstrtype(c, et) || isslicetype(c, et))) { if (ev.str.len > 0) { internstrlit(c, ev.str); @@ -42955,13 +42955,13 @@ export fn letpreintern(c: *cgen, file: *node) void = { }; }; if (!handled && r != nil && d.lhs != nil) { - let tlt: *node = d.lhs; - for (tlt != nil && tlt.kind == nkind.N_TNAME) { + let tlt: *syntax.node = d.lhs; + for (tlt != nil && tlt.kind == syntax.nkind.N_TNAME) { tlt = aliaslookup(c, tlt.str); }; if (tlt != nil) { - if (tlt.kind == nkind.N_TTAGGED && !isnullabletype(tlt)) { - if (r.kind == nkind.N_STRLIT && r.str.len > 0 + if (tlt.kind == syntax.nkind.N_TTAGGED && !isnullabletype(tlt)) { + if (r.kind == syntax.nkind.N_STRLIT && r.str.len > 0 && (nodeisstr(c, r) || nodeisslice(c, r))) { handled = true; internstrlit(c, r.str); @@ -42976,7 +42976,7 @@ export fn letpreintern(c: *cgen, file: *node) void = { // `sz == primtypesize("str"): i32` strlit-init branch. if (sz == primtypesize("str"): i32) { if (r != nil) { - if (r.kind == nkind.N_STRLIT) { + if (r.kind == syntax.nkind.N_STRLIT) { if (r.str.len > 0) { internstrlit(c, r.str); }; @@ -43009,36 +43009,36 @@ export fn letpreintern(c: *cgen, file: *node) void = { // f64/f32 bitcast helpers into cgen. Returns true on emit, false if // rhs doesn't reduce to a foldable float literal. fn emitfloatlitdata(c: *cgen, directive: str, name: str, module: str, - sz: i32, rhs: *node) bool = { + sz: i32, rhs: *syntax.node) bool = { let isf32: bool = (sz == 4); let bits: u64 = 0u64; let neg: bool = false; if (rhs != nil) { - let r: *node = rhs; + let r: *syntax.node = rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; if (r != nil) { - if (r.kind == nkind.N_UN) { - if (r.op == tkind.TK_MINUS) { + if (r.kind == syntax.nkind.N_UN) { + if (r.op == syntax.tkind.TK_MINUS) { neg = true; r = r.lhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; - } else { if (r.op == tkind.TK_PLUS) { + } else { if (r.op == syntax.tkind.TK_PLUS) { r = r.lhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; };}; }; }; if (r == nil) { return false; }; - if (r.kind != nkind.N_FLOATLIT) { return false; }; + if (r.kind != syntax.nkind.N_FLOATLIT) { return false; }; // r.uval holds f64 bits regardless of literal suffix (lexer // stores the pre-narrow bits). f32 needs an explicit // (double→float) narrowing at emit time — mirrors cstage's @@ -43090,25 +43090,25 @@ fn emitfloatlitdata(c: *cgen, directive: str, name: str, module: str, // emit_struct_lit_bytes. `base` offsets the field-start computation // so the recursive call walks an inner struct's fields within its // outer parent's byte stream. -fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, +fn emitstructlitbytes(c: *cgen, structt: *syntax.tinfo, rhs: *syntax.node, base: u64) bool = { - let su: *tinfo = structt; + let su: *syntax.tinfo = structt; su = tichase(su); if (su == nil) { return false; }; - if (su.kind != tykind.TY_STRUCT) { return false; }; + if (su.kind != syntax.tykind.TY_STRUCT) { return false; }; let pos: u64 = base; - let f: *tfield = su.fields; + let f: *syntax.tfield = su.fields; for (f != nil) { let fstart: u64 = base + f.offset; for (pos < fstart) { emitdatawbyte(0u8); pos = pos + 1u64; }; - let v: *node = nil; + let v: *syntax.node = nil; if (rhs != nil) { - let fnod: *node = rhs.list; + let fnod: *syntax.node = rhs.list; for (fnod != nil) { - if (streq(fnod.str, f.name)) { + if (syntax.streq(fnod.str, f.name)) { v = fnod.lhs; break; }; @@ -43126,16 +43126,16 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, f = f.tnext; continue; }; - let vr: *node = v; - for (vr != nil && vr.kind == nkind.N_CAST) { vr = vr.lhs; }; - let fu: *tinfo = f.type_; + let vr: *syntax.node = v; + for (vr != nil && vr.kind == syntax.nkind.N_CAST) { vr = vr.lhs; }; + let fu: *syntax.tinfo = f.type_; fu = tichase(fu); // #19 option A: a non-nullable tagged-union field rides the shared // (tag,payload) core at the field slot size, mirroring the scalar // tagged global — NOT the int emitter. Wide/struct/non-foldable // payload loud-rejects (task #30 sub-item, rule 7). v is non-nil // here (the absent-field zero-fill is handled above). - if (fu != nil && fu.kind == tykind.TY_TAGGED && !typeisnullable(fu)) { + if (fu != nil && fu.kind == syntax.tykind.TY_TAGGED && !syntax.typeisnullable(fu)) { if (!emittaggedbytes(c, f.type_, v, fsz, 1)) { let m: str = "emitstructlitbytes: tagged-union struct-field static-init needs a zero/int payload; wide (str/slice) or struct payload is deferred (task #30, rule 7)\n"; os.write(2, m.ptr, m.len: u64); @@ -43145,13 +43145,13 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, f = f.tnext; continue; }; - if (fu != nil && fu.kind == tykind.TY_STRUCT) { + if (fu != nil && fu.kind == syntax.tykind.TY_STRUCT) { if (vr == nil) { let m: str = "emitstructlitbytes: nested struct field rhs nil (#129 A.2)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (vr.kind != nkind.N_STRUCTLIT) { + if (vr.kind != syntax.nkind.N_STRUCTLIT) { let m: str = "emitstructlitbytes: nested struct rhs not N_STRUCTLIT (#129 A.2)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -43165,13 +43165,13 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, // parked in A.2). Recurses through emitarraylitbytes for // element-kind dispatch. Rule-7 stops loudly if rhs shape // doesn't match. - if (fu != nil && fu.kind == tykind.TY_ARRAY) { + if (fu != nil && fu.kind == syntax.tykind.TY_ARRAY) { if (vr == nil) { let m: str = "emitstructlitbytes: array field rhs nil (#129 A.3)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (vr.kind != nkind.N_ARRLIT) { + if (vr.kind != syntax.nkind.N_ARRLIT) { let m: str = "emitstructlitbytes: array field rhs not N_ARRLIT (#129 A.3)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -43185,18 +43185,18 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, f = f.tnext; continue; }; - if (typeisfloat(f.type_)) { + if (syntax.typeisfloat(f.type_)) { let isf32: bool = (fsz == 4); let neg: bool = false; - let fr: *node = vr; - if (fr != nil) { if (fr.kind == nkind.N_UN) { - if (fr.op == tkind.TK_MINUS) { + let fr: *syntax.node = vr; + if (fr != nil) { if (fr.kind == syntax.nkind.N_UN) { + if (fr.op == syntax.tkind.TK_MINUS) { neg = true; fr = fr.lhs; - for (fr != nil && fr.kind == nkind.N_CAST) { fr = fr.lhs; }; - } else { if (fr.op == tkind.TK_PLUS) { + for (fr != nil && fr.kind == syntax.nkind.N_CAST) { fr = fr.lhs; }; + } else { if (fr.op == syntax.tkind.TK_PLUS) { fr = fr.lhs; - for (fr != nil && fr.kind == nkind.N_CAST) { fr = fr.lhs; }; + for (fr != nil && fr.kind == syntax.nkind.N_CAST) { fr = fr.lhs; }; };}; };}; if (fr == nil) { @@ -43204,7 +43204,7 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, os.write(2, m.ptr, m.len: u64); os.exit(1); }; - if (fr.kind != nkind.N_FLOATLIT) { + if (fr.kind != syntax.nkind.N_FLOATLIT) { let m: str = "emitstructlitbytes: float field rhs not FLOATLIT (#129 A.2)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -43259,11 +43259,11 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, // then delegates to emitstructlitbytes. Shared between emitletdataw // struct arm and emitdefconstants struct arm (#129 A.2). fn emitstructdata(c: *cgen, directive: str, name: str, module: str, - structt: *tinfo, rhs: *node) bool = { - let su: *tinfo = structt; + structt: *syntax.tinfo, rhs: *syntax.node) bool = { + let su: *syntax.tinfo = structt; su = tichase(su); if (su == nil) { return false; }; - if (su.kind != tykind.TY_STRUCT) { return false; }; + if (su.kind != syntax.tykind.TY_STRUCT) { return false; }; emitline(directive); emitline(" "); emitfnname(c, name, module); @@ -43291,15 +43291,15 @@ fn emitstructdata(c: *cgen, directive: str, name: str, module: str, // Two-pass validate-then-emit (`emit_phase=0` validate-only, `=1` // actually emit) keeps emit-on-failure from emitting partial bytes // into an open DATA literal. -fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, +fn emitarraylitbytes(c: *cgen, arrt: *syntax.tinfo, rhs: *syntax.node, emit_phase: i32) bool = { - let au: *tinfo = arrt; + let au: *syntax.tinfo = arrt; au = tichase(au); if (au == nil) { return false; }; - if (au.kind != tykind.TY_ARRAY) { return false; }; + if (au.kind != syntax.tykind.TY_ARRAY) { return false; }; let esz: i32 = au.sub.size: i32; let alen: i32 = au.alen: i32; - let eu: *tinfo = au.sub; + let eu: *syntax.tinfo = au.sub; eu = tichase(eu); // #19 option A: a non-nullable tagged-union element rides the shared @@ -43309,13 +43309,13 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // payload element loud-rejects (task #30 sub-item, rule 7). A nullable // `(*T|void)` element is a 1-word fold, not a tag box — left to the // existing int path (task #15). - if (eu != nil && eu.kind == tykind.TY_TAGGED && !typeisnullable(eu)) { + if (eu != nil && eu.kind == syntax.tykind.TY_TAGGED && !syntax.typeisnullable(eu)) { let idx: i32 = 0; - let last_ev: *node = nil; - let e: *node = rhs.list; + let last_ev: *syntax.node = nil; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; if (!emittaggedbytes(c, au.sub, e, esz, 0)) { let m: str = "emitarraylitbytes: tagged-union array element static-init needs a zero/int payload; wide (str/slice) or struct payload is deferred (task #30, rule 7)\n"; @@ -43331,8 +43331,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, let repeat: bool = false; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; emittaggedbytes(c, au.sub, e, esz, 1); idx += 1; @@ -43350,19 +43350,19 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, return true; }; - if (eu != nil && eu.kind == tykind.TY_STRUCT) { + if (eu != nil && eu.kind == syntax.tykind.TY_STRUCT) { // Validate: every element must be N_STRUCTLIT (after N_CAST). let idx: i32 = 0; - let last_ev: *node = nil; - let e: *node = rhs.list; + let last_ev: *syntax.node = nil; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_STRUCTLIT) { return false; }; + if (ev.kind != syntax.nkind.N_STRUCTLIT) { return false; }; last_ev = ev; idx += 1; e = e.next; @@ -43372,11 +43372,11 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, let repeat: bool = false; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; emitstructlitbytes(c, au.sub, ev, 0u64); idx += 1; e = e.next; @@ -43401,21 +43401,21 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // element stride (rule 13). The `...` repeat marker with nested- // array elements is rejected loud (rule 7): no consumer needs it // (powers_of_ten is fully enumerated). - if (eu != nil && eu.kind == tykind.TY_ARRAY) { + if (eu != nil && eu.kind == syntax.tykind.TY_ARRAY) { let idx: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { let m: str = "emitarraylitbytes: '...' repeat with nested-array elements unsupported (#129 A.3, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_ARRLIT) { return false; }; + if (ev.kind != syntax.nkind.N_ARRLIT) { return false; }; if (!emitarraylitbytes(c, au.sub, ev, 0)) { return false; }; idx += 1; e = e.next; @@ -43424,8 +43424,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, idx = 0; e = rhs.list; for (e != nil && idx < alen) { - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; emitarraylitbytes(c, au.sub, ev, 1); idx += 1; e = e.next; @@ -43438,28 +43438,28 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, return true; }; - if (typeisfloat(au.sub)) { - let isf32: bool = typeisf32(au.sub); + if (syntax.typeisfloat(au.sub)) { + let isf32: bool = syntax.typeisf32(au.sub); // Validate. let idx: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; - if (ev != nil) { if (ev.kind == nkind.N_UN) { - if (ev.op == tkind.TK_MINUS) { + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; + if (ev != nil) { if (ev.kind == syntax.nkind.N_UN) { + if (ev.op == syntax.tkind.TK_MINUS) { ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; - } else { if (ev.op == tkind.TK_PLUS) { + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; + } else { if (ev.op == syntax.tkind.TK_PLUS) { ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; };}; };}; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_FLOATLIT) { return false; }; + if (ev.kind != syntax.nkind.N_FLOATLIT) { return false; }; idx += 1; e = e.next; }; @@ -43470,20 +43470,20 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, let repeat: bool = false; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let neg: bool = false; - if (ev != nil) { if (ev.kind == nkind.N_UN) { - if (ev.op == tkind.TK_MINUS) { + if (ev != nil) { if (ev.kind == syntax.nkind.N_UN) { + if (ev.op == syntax.tkind.TK_MINUS) { neg = true; ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; - } else { if (ev.op == tkind.TK_PLUS) { + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; + } else { if (ev.op == syntax.tkind.TK_PLUS) { ev = ev.lhs; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; };}; };}; let bits: u64 = ev.uval; @@ -43535,16 +43535,16 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // emitletdataw in-place arm so bootstrap consumers (u8/i8/u16 // arrays) don't shift. let idx: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; let last: u64 = 0u64; let repeat: bool = false; // Validate first. for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; if (!foldintliteral(ev, &last)) { return false; }; idx += 1; @@ -43568,8 +43568,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, if (inrepeat) { v = last; } else { if (e != nil) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { inrepeat = true; v = last; } else { @@ -43577,8 +43577,8 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, v = last; }; } else { - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (!foldintliteral(ev, &v)) { v = 0u64; }; last = v; e = e.next; @@ -43609,15 +43609,15 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, // holder constraint, not a mutability grant (def immutability stays // checker-enforced). Returns false when the element type isn't str. fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, - arrt: *tinfo, rhs: *node) bool = { - let au: *tinfo = arrt; + arrt: *syntax.tinfo, rhs: *syntax.node) bool = { + let au: *syntax.tinfo = arrt; au = tichase(au); if (au == nil) { return false; }; - if (au.kind != tykind.TY_ARRAY) { return false; }; - let eu: *tinfo = au.sub; + if (au.kind != syntax.tykind.TY_ARRAY) { return false; }; + let eu: *syntax.tinfo = au.sub; eu = tichase(eu); if (eu == nil) { return false; }; - if (eu.kind != tykind.TY_STR) { return false; }; + if (eu.kind != syntax.tykind.TY_STR) { return false; }; // #8/GAP-B: a str-element array's backing ALWAYS lives in DATAW // (writable section), regardless of the caller's let/def directive — // each element carries an A_DATAR ptr-reloc to its _S_ rodata row, and @@ -43632,18 +43632,18 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, let esz: i32 = au.sub.size: i32; let alen: i32 = au.alen: i32; - let last_ev: *node = nil; + let last_ev: *syntax.node = nil; let repeat: bool = false; let cnt: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil && cnt < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { repeat = true; break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { repeat = true; break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; - if (ev.kind != nkind.N_STRLIT) { return false; }; + if (ev.kind != syntax.nkind.N_STRLIT) { return false; }; last_ev = ev; cnt += 1; e = e.next; @@ -43655,11 +43655,11 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, let idx: i32 = 0; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let i: i32 = 0; for (i < 8) { emitdatawbyte(0u8); i += 1; }; let v: u64 = ev.str.len: u64; @@ -43694,11 +43694,11 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, idx = 0; e = rhs.list; for (e != nil && idx < alen) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { break; }; + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { break; }; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev.str.len > 0) { let lab: str = internstrlit(c, ev.str); emitline("DATAR "); @@ -43737,11 +43737,11 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, // refactor would have skipped emit entirely without this branch, // causing `undefined reference to strconv.f64tos_buf` at link. fn emitarraydata(c: *cgen, directive: str, name: str, module: str, - arrt: *tinfo, rhs: *node) bool = { - let au: *tinfo = arrt; + arrt: *syntax.tinfo, rhs: *syntax.node) bool = { + let au: *syntax.tinfo = arrt; au = tichase(au); if (au == nil) { return false; }; - if (au.kind != tykind.TY_ARRAY) { return false; }; + if (au.kind != syntax.tykind.TY_ARRAY) { return false; }; if (rhs == nil) { let total: u64 = arrt.size; emitline(directive); @@ -43780,25 +43780,25 @@ fn emitarraydata(c: *cgen, directive: str, name: str, module: str, // (w6a asm.c:362); read-only `def`, `...` repeat (no target length), // and slice-of-{str,slice,tagged} elements (per-element relocs / #17) // all loud-stop (rule 7, #10 follow-ups). -fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, - sltnode: *node, rhs: *node) void = { - let su: *tinfo = slt; +fn emitslicedata(c: *cgen, name: str, module: str, slt: *syntax.tinfo, + sltnode: *syntax.node, rhs: *syntax.node) void = { + let su: *syntax.tinfo = slt; su = tichase(su); // Defensive, mirrors cstage emit_slice_data's // `if (u == NULL || u->kind != TY_SLICE) return 0` (rule-10): the // letvarisslice gate already guarantees a slice, so this is // unreachable — it guards the su.sub deref below if the contract // is ever violated rather than nil-derefing. - if (su == nil || su.kind != tykind.TY_SLICE) { return; }; - let etype: *tinfo = su.sub; - let eu: *tinfo = etype; + if (su == nil || su.kind != syntax.tykind.TY_SLICE) { return; }; + let etype: *syntax.tinfo = su.sub; + let eu: *syntax.tinfo = etype; eu = tichase(eu); // Count elements; reject `...` (a slice literal has no target N). let k: i32 = 0; - let e: *node = rhs.list; + let e: *syntax.node = rhs.list; for (e != nil) { - if (e.kind == nkind.N_FIELD) { - if (streq(e.str, "...")) { + if (e.kind == syntax.nkind.N_FIELD) { + if (syntax.streq(e.str, "...")) { let m: str = "emitslicedata: '...' repeat has no target length in a slice literal (#10, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -43812,23 +43812,23 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, // drives the per-element slot classification the node-based // emittuplerow helpers expect; cstage drives the same off the tuple // tinfo's params. Bounded to inline N_TTUPLE element types. - let tupnode: *node = nil; + let tupnode: *syntax.node = nil; if (sltnode != nil) { tupnode = sltnode.lhs; }; let istuprow: bool = false; - if (eu != nil && eu.kind == tykind.TY_TUPLE && tupnode != nil) { - if (tupnode.kind == nkind.N_TTUPLE) { istuprow = true; }; + if (eu != nil && eu.kind == syntax.tykind.TY_TUPLE && tupnode != nil) { + if (tupnode.kind == syntax.nkind.N_TTUPLE) { istuprow = true; }; }; if (istuprow) { let stride: i32 = etype.size: i32; // Validate every row before any bytes (two-pass, partial-row // safe). - let e2: *node = rhs.list; + let e2: *syntax.node = rhs.list; for (e2 != nil) { - let row: *node = e2; - for (row != nil && row.kind == nkind.N_CAST) { row = row.lhs; }; + let row: *syntax.node = e2; + for (row != nil && row.kind == syntax.nkind.N_CAST) { row = row.lhs; }; let bad: bool = false; if (row == nil) { bad = true; } - else if (row.kind != nkind.N_TUPLE) { bad = true; } + else if (row.kind != syntax.nkind.N_TUPLE) { bad = true; } else if (!tuplerowfoldable(c, tupnode, row)) { bad = true; }; if (bad) { let m: str = "emitslicedata: tuple-row element not a foldable constant ((str,*fn) rows only; #117, rule 7)\n"; @@ -43843,8 +43843,8 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, emitline(".d(SB),\""); e2 = rhs.list; for (e2 != nil) { - let row: *node = e2; - for (row != nil && row.kind == nkind.N_CAST) { row = row.lhs; }; + let row: *syntax.node = e2; + for (row != nil && row.kind == syntax.nkind.N_CAST) { row = row.lhs; }; emittuplerowbytes(c, tupnode, row); e2 = e2.next; }; @@ -43852,16 +43852,16 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, let rowoff: i32 = 0; e2 = rhs.list; for (e2 != nil) { - let row: *node = e2; - for (row != nil && row.kind == nkind.N_CAST) { row = row.lhs; }; + let row: *syntax.node = e2; + for (row != nil && row.kind == syntax.nkind.N_CAST) { row = row.lhs; }; emittuplerowrelocs(c, name, module, true, rowoff, tupnode, row); rowoff += stride; e2 = e2.next; }; } else { if (eu != nil) { - if (eu.kind == tykind.TY_STR || eu.kind == tykind.TY_SLICE - || eu.kind == tykind.TY_TAGGED) { + if (eu.kind == syntax.tykind.TY_STR || eu.kind == syntax.tykind.TY_SLICE + || eu.kind == syntax.tykind.TY_TAGGED) { let m: str = "emitslicedata: slice-of-{str,slice,tagged} literal static-init unsupported (#10 follow-up, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -43869,7 +43869,7 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, }; let esz: i32 = etype.size: i32; // Synthesize [k]T to ride the emitarraylitbytes choke-point. - let arrt: *tinfo = newtype(tykind.TY_ARRAY); + let arrt: *syntax.tinfo = syntax.newtype(syntax.tykind.TY_ARRAY); arrt.sub = etype; arrt.alen = k: u64; arrt.size = (k * esz): u64; @@ -43932,7 +43932,7 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, // share this raw core so a nested tagged member rides the SAME // (tag,payload) SSoT as a scalar tagged global. Mirror of cstage // emit_tagged_bytes. -fn emittaggedbytes(c: *cgen, tti: *tinfo, rhs: *node, sz: i32, emit_phase: i32) bool = { +fn emittaggedbytes(c: *cgen, tti: *syntax.tinfo, rhs: *syntax.node, sz: i32, emit_phase: i32) bool = { if (tti == nil) { return false; }; if (rhs == nil) { if (emit_phase == 1) { @@ -43941,10 +43941,10 @@ fn emittaggedbytes(c: *cgen, tti: *tinfo, rhs: *node, sz: i32, emit_phase: i32) }; return true; }; - let r: *node = rhs; - for (r != nil && r.kind == nkind.N_CAST) { r = r.lhs; }; + let r: *syntax.node = rhs; + for (r != nil && r.kind == syntax.nkind.N_CAST) { r = r.lhs; }; if (r == nil) { return false; }; - let tag: i32 = flatvariantidxt(tti, r.type_: *tinfo, false); + let tag: i32 = flatvariantidxt(tti, r.type_: *syntax.tinfo, false); if (tag < 0) { return false; }; if (nodeisstr(c, r) || nodeisslice(c, r)) { return false; }; let v: u64 = 0u64; @@ -43972,18 +43972,18 @@ fn emittaggedbytes(c: *cgen, tti: *tinfo, rhs: *node, sz: i32, emit_phase: i32) // other variant payload returns false and the caller loud-stops (rule 7) — // never the pre-#87 silent no-DATA + garbage read. Mirror of cstage // emit_tagged_data. -fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i32) bool = { +fn emittaggeddata(c: *cgen, name: str, module: str, tt: *syntax.node, rhs: *syntax.node, sz: i32) bool = { if (tt == nil) { return false; }; if (rhs == nil) { emitline("DATAW "); emitfnname(c, name, module); emitline("(SB),\""); - emittaggedbytes(c, tt.type_: *tinfo, rhs, sz, 1); + emittaggedbytes(c, tt.type_: *syntax.tinfo, rhs, sz, 1); emitline("\"\n"); return true; }; - let r: *node = rhs; - for (r != nil && r.kind == nkind.N_CAST) { r = r.lhs; }; + let r: *syntax.node = rhs; + for (r != nil && r.kind == syntax.nkind.N_CAST) { r = r.lhs; }; if (r == nil) { return false; }; // E8/#35: select the variant via flatvariantidx — the EXACT twin of // cstage emit_tagged_data's cg_tag_for_variant (cmd/w6c/cgen.c:15472). @@ -44006,7 +44006,7 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i let i: i32 = 0; let acc: u64 = 0u64; if (wide) { - if (r.kind != nkind.N_STRLIT) { return false; }; + if (r.kind != syntax.nkind.N_STRLIT) { return false; }; let lv: u64 = r.str.len: u64; emitline("DATAW "); emitfnname(c, name, module); @@ -44043,11 +44043,11 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i // int/zero payload via the shared raw core; validate (phase 0) BEFORE // opening the directive so a non-foldable rhs returns false without // leaving a half-written DATAW. - if (!emittaggedbytes(c, tt.type_: *tinfo, rhs, sz, 0)) { return false; }; + if (!emittaggedbytes(c, tt.type_: *syntax.tinfo, rhs, sz, 0)) { return false; }; emitline("DATAW "); emitfnname(c, name, module); emitline("(SB),\""); - emittaggedbytes(c, tt.type_: *tinfo, rhs, sz, 1); + emittaggedbytes(c, tt.type_: *syntax.tinfo, rhs, sz, 1); emitline("\"\n"); return true; }; @@ -44058,11 +44058,11 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i // address-of-fn codegen arm (fnretlookup at the N_UN TK_AMP ident, // cgenexpr.ww). The reloc target symbol is emitted via emitfnname at the // call site (cstage node_fnptr_sym returns the mangled string directly). -fn nodefnptr(c: *cgen, ev: *node) bool = { +fn nodefnptr(c: *cgen, ev: *syntax.node) bool = { if (ev == nil) { return false; }; - if (ev.kind != nkind.N_UN) { return false; }; - if (ev.op != tkind.TK_AMP) { return false; }; - let opnd: *node = ev.lhs; + if (ev.kind != syntax.nkind.N_UN) { return false; }; + if (ev.op != syntax.tkind.TK_AMP) { return false; }; + let opnd: *syntax.node = ev.lhs; if (opnd == nil) { return false; }; // #124: a cross-module `&mod.fn` — opnd is an N_DOT whose base is an // SK_USE module qualifier (not a local / let / def), and whose leaf @@ -44070,9 +44070,9 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { // curmod) at the emit sites so the reloc targets the same TEXT symbol // the runtime `&mod.fn` emits (cgenexpr.ww N_DOT addr-of arm). The // N_DOT arm of the #117/#119 reloc helper. - if (opnd.kind == nkind.N_DOT) { + if (opnd.kind == syntax.nkind.N_DOT) { if (opnd.lhs == nil) { return false; }; - if (opnd.lhs.kind != nkind.N_IDENT) { return false; }; + if (opnd.lhs.kind != syntax.nkind.N_IDENT) { return false; }; let basenm: str = opnd.lhs.str; if (localfindnode(c, basenm) != nil) { return false; }; if (isletvar(c, basenm)) { return false; }; @@ -44080,7 +44080,7 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { if (fnretlookupmod(c, opnd.str, basenm) == nil) { return false; }; return true; }; - if (opnd.kind != nkind.N_IDENT) { return false; }; + if (opnd.kind != syntax.nkind.N_IDENT) { return false; }; // #14 (F7-c7): type-keyed, mirroring cstage node_fnptr_sym // (type_chase_named(opnd->type)->kind == TY_FN, cmd/w6c/cgen.c:15542- // 15543). The prior name-keyed `fnretlookup(opnd.str)` matched a fn @@ -44092,9 +44092,9 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { // #34 fn-rvalue stamp) from a value ident, closing the leaf-name // collision by construction. (F12 name-keyed overlap noted in the F7 // spec — same predicate-to-stamp shape; fixed once here.) - let ou: *tinfo = tichase(opnd.type_: *tinfo); + let ou: *syntax.tinfo = tichase(opnd.type_: *syntax.tinfo); if (ou == nil) { return false; }; - return ou.kind == tykind.TY_FN; + return ou.kind == syntax.tykind.TY_FN; }; // tuplerowfoldable — validate every cast-peeled element of `rhs` (an @@ -44107,26 +44107,26 @@ fn nodefnptr(c: *cgen, ev: *node) bool = { // out of the output (emitarraydata precedent). Factored from emittupledata // so the slice-of-tuple backing (#117) shares it. Mirror of cstage // tuple_row_foldable. -fn tuplerowfoldable(c: *cgen, tt: *node, rhs: *node) bool = { - let tp: *node = tt.list; - let e: *node = rhs.list; +fn tuplerowfoldable(c: *cgen, tt: *syntax.node, rhs: *syntax.node) bool = { + let tp: *syntax.node = tt.list; + let e: *syntax.node = rhs.list; for (e != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (tp != nil) { et = tp.lhs; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; if (ev == nil) { return false; }; { - let eti: *tinfo = nil; - if (et != nil) { eti = et.type_: *tinfo; }; + let eti: *syntax.tinfo = nil; + if (et != nil) { eti = et.type_: *syntax.tinfo; }; eti = tichase(eti); - if (eti != nil && eti.kind == tykind.TY_TAGGED) { + if (eti != nil && eti.kind == syntax.tykind.TY_TAGGED) { return false; }; }; let wide: bool = isstrtype(c, et) || isslicetype(c, et); if (wide) { - if (ev.kind != nkind.N_STRLIT) { return false; }; + if (ev.kind != syntax.nkind.N_STRLIT) { return false; }; } else if (nodefnptr(c, ev)) { // #117: a `&fn` element folds to an 8B reloc slot. } else { @@ -44145,14 +44145,14 @@ fn tuplerowfoldable(c: *cgen, tt: *node, rhs: *node) bool = { // its 24B header slot (8 zero ptr placeholder + LE len + 8 zero cap). // Caller has already proven the row foldable. Mirror of cstage // emit_tuple_row_bytes. -fn emittuplerowbytes(c: *cgen, tt: *node, rhs: *node) void = { - let tp: *node = tt.list; - let e: *node = rhs.list; +fn emittuplerowbytes(c: *cgen, tt: *syntax.node, rhs: *syntax.node) void = { + let tp: *syntax.node = tt.list; + let e: *syntax.node = rhs.list; for (e != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (tp != nil) { et = tp.lhs; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let wide: bool = isstrtype(c, et) || isslicetype(c, et); if (wide) { let i: i32 = 0; @@ -44195,15 +44195,15 @@ fn emittuplerowbytes(c: *cgen, tt: *node, rhs: *node) void = { // backing place k rows contiguously (#117), emittupledata passes 0 (foff // matches the absolute element offset — byte-neutral). Mirror of cstage // emit_tuple_row_relocs. -fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i32, tt: *node, rhs: *node) void = { +fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i32, tt: *syntax.node, rhs: *syntax.node) void = { let foff: i32 = rowoff; - let tp: *node = tt.list; - let e: *node = rhs.list; + let tp: *syntax.node = tt.list; + let e: *syntax.node = rhs.list; for (e != nil) { - let et: *node = nil; + let et: *syntax.node = nil; if (tp != nil) { et = tp.lhs; }; - let ev: *node = e; - for (ev != nil && ev.kind == nkind.N_CAST) { ev = ev.lhs; }; + let ev: *syntax.node = e; + for (ev != nil && ev.kind == syntax.nkind.N_CAST) { ev = ev.lhs; }; let wide: bool = isstrtype(c, et) || isslicetype(c, et); if (wide) { if (ev.str.len > 0) { @@ -44232,7 +44232,7 @@ fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i // #124: a cross-module `&mod.fn` operand mangles // the leaf with the MODULE ident; same-module `&fn` // stays on curmod. - if (ev.lhs.kind == nkind.N_DOT) { + if (ev.lhs.kind == syntax.nkind.N_DOT) { emitfnname(c, ev.lhs.str, usehint(c, ev.lhs.lhs.str)); } else { emitfnname(c, ev.lhs.str, c.curmod); @@ -44255,13 +44255,13 @@ fn emittuplerowrelocs(c: *cgen, name: str, module: str, backing: bool, rowoff: i // zero-inits. Unsupported element inits return false and the caller // loud-stops (rule 7 — pre-C-t3 the whole definition was SILENTLY skipped // and reads saw garbage). Mirror of cstage emit_tuple_data. -fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = { +fn emittupledata(c: *cgen, name: str, module: str, tt: *syntax.node, rhs: *syntax.node) bool = { if (tt == nil) { return false; }; if (rhs == nil) { // #22: slot-sum via the accessor so the zero-fill matches // the checker size (cstage zero-emits u->size). let zsz: i32 = 0; - let p0: *node = tt.list; + let p0: *syntax.node = tt.list; for (p0 != nil) { zsz += tupeslotn(p0.lhs); p0 = p0.next; @@ -44274,7 +44274,7 @@ fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = emitline("\"\n"); return true; }; - if (rhs.kind != nkind.N_TUPLE) { return false; }; + if (rhs.kind != syntax.nkind.N_TUPLE) { return false; }; if (!tuplerowfoldable(c, tt, rhs)) { return false; }; emitline("DATAW "); emitfnname(c, name, module); @@ -44285,8 +44285,8 @@ fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = return true; }; -fn emitletdataw(c: *cgen, file: *node) void = { - let d: *node = file.list; +fn emitletdataw(c: *cgen, file: *syntax.node) void = { + let d: *syntax.node = file.list; for (d != nil) { // #22 M3 THE ONE REAL GUARD: a `.wwi` dep value-global is // initializer-less; emitting a DATAW for it would DUPLICATE the @@ -44295,7 +44295,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // init-less let must still zero-init). Symmetric with M2's // producer imported==0 filter — same predicate both ways. if (c.sepmode != 0 && d.imported != 0) { d = d.next; continue; }; - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { let nm: str = d.str; if (nm.len > 0) { let sz: i32 = letemitsize(c, d); @@ -44308,8 +44308,8 @@ fn emitletdataw(c: *cgen, file: *node) void = { // undefined reference at link. The str/float/ // struct/slice/tuple gates already alias-walk // (letvaris* / the tlt tnode walk) and stay put. - let dti: *tinfo = nil; - if (d.lhs != nil) { dti = tichase(d.lhs.type_: *tinfo); }; + let dti: *syntax.tinfo = nil; + if (d.lhs != nil) { dti = tichase(d.lhs.type_: *syntax.tinfo); }; // C-t3 (#48): tuple global — slot-laid DATAW // row (+ DATAR ptr patches for str elements) // via emittupledata. Unsupported element @@ -44318,20 +44318,20 @@ fn emitletdataw(c: *cgen, file: *node) void = { // and reads saw garbage. The istup gate also // keeps a tuple out of the sz==8 / str-size // arms below (a 24B tuple == str size). - let tlt: *node = d.lhs; - for (tlt != nil && tlt.kind == nkind.N_TNAME) { + let tlt: *syntax.node = d.lhs; + for (tlt != nil && tlt.kind == syntax.nkind.N_TNAME) { tlt = aliaslookup(c, tlt.str); }; let istup: bool = false; if (tlt != nil) { - if (tlt.kind == nkind.N_TTUPLE) { + if (tlt.kind == syntax.nkind.N_TTUPLE) { istup = true; }; }; if (istup) { - let tr: *node = d.rhs; + let tr: *syntax.node = d.rhs; for (tr != nil) { - if (tr.kind != nkind.N_CAST) { break; }; + if (tr.kind != syntax.nkind.N_CAST) { break; }; tr = tr.lhs; }; if (!emittupledata(c, nm, d.nmod, tlt, tr)) { @@ -44347,7 +44347,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // a tagged box (size can equal str/slice size) out of those. let istagged: bool = false; if (tlt != nil) { - if (tlt.kind == nkind.N_TTAGGED) { + if (tlt.kind == syntax.nkind.N_TTAGGED) { if (!isnullabletype(tlt)) { istagged = true; }; }; }; @@ -44374,10 +44374,10 @@ fn emitletdataw(c: *cgen, file: *node) void = { // declaration fell out of the .data section and // the link surfaced an undefined-symbol error. if (issg) { - let r: *node = d.rhs; + let r: *syntax.node = d.rhs; if (r != nil) { - if (r.kind == nkind.N_STRUCTLIT) { - let st: *tinfo = d.lhs.type_: *tinfo; + if (r.kind == syntax.nkind.N_STRUCTLIT) { + let st: *syntax.tinfo = d.lhs.type_: *syntax.tinfo; emitstructdata(c, "DATAW", nm, d.nmod, st, r); }; @@ -44390,17 +44390,17 @@ fn emitletdataw(c: *cgen, file: *node) void = { // otherwise differ across stages on user code. let isarr8: bool = false; if (dti != nil) { - if (dti.kind == tykind.TY_ARRAY) { isarr8 = true; }; + if (dti.kind == syntax.tykind.TY_ARRAY) { isarr8 = true; }; }; if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup && !istagged) { let v: u64 = 0u64; let ok: bool = true; let fnp: bool = false; - let r: *node = nil; + let r: *syntax.node = nil; if (d.rhs != nil) { r = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // Same helper as emitdefconstants (#24) @@ -44426,7 +44426,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // #124: cross-module `&mod.fn` mangles the // leaf with the MODULE ident; same-module `&fn` // stays on curmod. - if (r.lhs.kind == nkind.N_DOT) { + if (r.lhs.kind == syntax.nkind.N_DOT) { emitfnname(c, r.lhs.str, usehint(c, r.lhs.lhs.str)); } else { emitfnname(c, r.lhs.str, c.curmod); @@ -44455,9 +44455,9 @@ fn emitletdataw(c: *cgen, file: *node) void = { // emitarraydata path owns them — mirroring the existing // isarr8 guard on the sz==8 scalar arm. if (sz == primtypesize("str"): i32 && !issg && !istup && !istagged && !isarr8 && !letvarisslice(c, nm)) { - let r: *node = d.rhs; + let r: *syntax.node = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // str-literal init (non-empty): emit @@ -44467,7 +44467,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { // the strlit's runtime VA. let strlitinit: bool = false; if (r != nil) { - if (r.kind == nkind.N_STRLIT) { + if (r.kind == syntax.nkind.N_STRLIT) { if (r.str.len > 0) { strlitinit = true; }; }; }; @@ -44499,8 +44499,8 @@ fn emitletdataw(c: *cgen, file: *node) void = { if (d.rhs != nil) { ok = false; if (r != nil) { - if (r.kind == nkind.N_NIL) { ok = true; }; - if (r.kind == nkind.N_STRLIT) { + if (r.kind == syntax.nkind.N_NIL) { ok = true; }; + if (r.kind == syntax.nkind.N_STRLIT) { if (r.str.len == 0) { ok = true; }; }; }; @@ -44520,9 +44520,9 @@ fn emitletdataw(c: *cgen, file: *node) void = { }; }; if (sz == tyslicesize(): i32 && !issg && !istagged && letvarisslice(c, nm)) { - let r: *node = d.rhs; + let r: *syntax.node = d.rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; // #10 part a: slice-literal static init @@ -44530,9 +44530,9 @@ fn emitletdataw(c: *cgen, file: *node) void = { // writable backing + DATAR). Loud-stops on // the deferred element kinds and the read- // only/`...` shapes (rule 7). - if (r != nil && r.kind == nkind.N_ARRLIT) { + if (r != nil && r.kind == syntax.nkind.N_ARRLIT) { emitslicedata(c, nm, d.nmod, - d.lhs.type_: *tinfo, d.lhs, r); + d.lhs.type_: *syntax.tinfo, d.lhs, r); } else { // zero-init: accept no rhs or nil. // Any other rhs is skipped → @@ -44541,7 +44541,7 @@ fn emitletdataw(c: *cgen, file: *node) void = { if (d.rhs != nil) { ok = false; if (r != nil) { - if (r.kind == nkind.N_NIL) { ok = true; }; + if (r.kind == syntax.nkind.N_NIL) { ok = true; }; }; }; if (ok) { @@ -44596,12 +44596,12 @@ fn emitletdataw(c: *cgen, file: *node) void = { // No-rhs arrays (e.g. `let buf: [N]u8;`) go through // the same helper with rhs=nil → zero-fill branch. if (dti != nil) { - if (dti.kind == tykind.TY_ARRAY) { - let rh: *node = d.rhs; + if (dti.kind == syntax.tykind.TY_ARRAY) { + let rh: *syntax.node = d.rhs; let route: bool = false; if (rh == nil) { route = true; }; if (rh != nil) { - if (rh.kind == nkind.N_ARRLIT) { + if (rh.kind == syntax.nkind.N_ARRLIT) { route = true; }; }; @@ -44630,8 +44630,8 @@ fn emitletdataw(c: *cgen, file: *node) void = { // unary +/-/~ over the same. `def NEG: i32 = -100;` arrives as // N_UN(TK_MINUS, N_INTLIT) — the unary peel is exactly what the // gate is for. -fn emitdefconstants(c: *cgen, file: *node) void = { - let d: *node = file.list; +fn emitdefconstants(c: *cgen, file: *syntax.node) void = { + let d: *syntax.node = file.list; for (d != nil) { // #22 M3: a `.wwi` dep def with DATA storage (int-fold / float / // struct / array) must NOT re-emit — the dep's own .o owns the @@ -44639,8 +44639,8 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // they need no gate; the def registry stays populated for imported // decls so the target's LOAD paths still resolve the extern. if (c.sepmode != 0 && d.imported != 0) { d = d.next; continue; }; - if (d.kind == nkind.N_DEF) { - let r: *node = d.rhs; + if (d.kind == syntax.nkind.N_DEF) { + let r: *syntax.node = d.rhs; let v: u64 = 0u64; let ok: bool = false; if (r != nil) { @@ -44653,12 +44653,12 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // through to no-emit + undef-ref at link. Type-size // walk mirrors letvarisfloat (#129 Phase A.1). let dfsz: i32 = 0; - let dt: *node = d.lhs; + let dt: *syntax.node = d.lhs; for (dt != nil) { - if (dt.kind != nkind.N_TNAME) { dfsz = 0; break; }; + if (dt.kind != syntax.nkind.N_TNAME) { dfsz = 0; break; }; let fsz: i32 = letfloatprim(dt.str); if (fsz > 0) { dfsz = fsz; break; }; - let nx: *node = aliaslookup(c, dt.str); + let nx: *syntax.node = aliaslookup(c, dt.str); if (nx == nil) { dfsz = 0; break; }; dt = nx; }; @@ -44671,12 +44671,12 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // struct's tinfo; helper peels TY_NAMED. Parallel // to emitletdataw struct arm; uses DATA (read- // only) directive. - if (r != nil) { if (r.kind == nkind.N_STRUCTLIT) { - let st: *tinfo = d.lhs.type_: *tinfo; - let su: *tinfo = st; + if (r != nil) { if (r.kind == syntax.nkind.N_STRUCTLIT) { + let st: *syntax.tinfo = d.lhs.type_: *syntax.tinfo; + let su: *syntax.tinfo = st; su = tichase(su); if (su != nil) { - if (su.kind == tykind.TY_STRUCT) { + if (su.kind == syntax.tykind.TY_STRUCT) { emitstructdata(c, "DATA", d.str, d.nmod, st, r); }; @@ -44684,12 +44684,12 @@ fn emitdefconstants(c: *cgen, file: *node) void = { };}; // #129 A.3: array-typed def with N_ARRLIT rhs. // Parallel to emitletdataw array arm; uses DATA. - if (r != nil) { if (r.kind == nkind.N_ARRLIT) { - let at: *tinfo = d.lhs.type_: *tinfo; - let au: *tinfo = at; + if (r != nil) { if (r.kind == syntax.nkind.N_ARRLIT) { + let at: *syntax.tinfo = d.lhs.type_: *syntax.tinfo; + let au: *syntax.tinfo = at; au = tichase(au); if (au != nil) { - if (au.kind == tykind.TY_ARRAY) { + if (au.kind == syntax.tykind.TY_ARRAY) { emitarraydata(c, "DATA", d.str, d.nmod, at, r); }; @@ -44698,7 +44698,7 @@ fn emitdefconstants(c: *cgen, file: *node) void = { // emitslicedata needs (DATAR holder must be // DATAW, w6a asm.c:362). Loud-stop, never // silent no-emit. - if (au.kind == tykind.TY_SLICE) { + if (au.kind == syntax.tykind.TY_SLICE) { let m: str = "emitdefconstants: module-level slice-literal init needs a writable `let` (DATAR holder must be DATAW, w6a asm.c:362); read-only `def` unsupported (#10, rule 7)\n"; os.write(2, m.ptr, m.len: u64); os.exit(1); @@ -44830,16 +44830,16 @@ fn emitdatasection(c: *cgen) void = { type fnret = struct { fname: str, fmod: str, - rtype: *node, - params: *node, + rtype: *syntax.node, + params: *syntax.node, frnext: *fnret, }; -fn collectfnrets(c: *cgen, file: *node) void = { +fn collectfnrets(c: *cgen, file: *syntax.node) void = { c.fnrets = nil; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_FNDECL) { + if (d.kind == syntax.nkind.N_FNDECL) { let f: *fnret = alloc(fnret{fname=d.str, fmod=d.nmod, rtype=d.lhs, params=d.list, frnext=c.fnrets})!; c.fnrets = f; }; @@ -44878,17 +44878,17 @@ fn collectfnrets(c: *cgen, file: *node) void = { // the fix. Masked until #208 landed (the checker rejected the shape // before cgen ran). test/wcc/782 pins the cstage-correct runtime // (cstage-only) and graduates to STAGE_WW on #211 close. -fn fnretlookup(c: *cgen, name: str) *node = { +fn fnretlookup(c: *cgen, name: str) *syntax.node = { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, c.curmod)) { return f.rtype; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, c.curmod)) { return f.rtype; }; }; f = f.frnext; }; f = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { return f.rtype; }; + if (syntax.streq(f.fname, name)) { return f.rtype; }; f = f.frnext; }; return nil; @@ -44903,7 +44903,7 @@ fn fnretlookup(c: *cgen, name: str) *node = { // `match (utf8.next(d))` inside a `fn next() (rune | done)` resolves // the scrutinee tagged type to `(rune | done)` — flatvariantidx then // can't see arms 2/3 and collapses them onto tag 0 (task #31). -fn fnretlookupmod(c: *cgen, name: str, mod: str) *node = { +fn fnretlookupmod(c: *cgen, name: str, mod: str) *syntax.node = { // M1 #22 (#199b): the qualifier may be the import ALIAS the user // wrote (`utf8`); fn decls register f.fmod under the dotted import // PATH (`encoding.utf8`). Map alias->path so a nested-package callee @@ -44920,8 +44920,8 @@ fn fnretlookupmod(c: *cgen, name: str, mod: str) *node = { if (mk.len > 0) { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, mk)) { return f.rtype; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, mk)) { return f.rtype; }; }; f = f.frnext; }; @@ -44939,17 +44939,17 @@ fn fnretlookupmod(c: *cgen, name: str, mod: str) *node = { // detection fires (or doesn't) against the wrong param-type — `foo(7)` // against a same-leaf `(i32 | void)` param re-layouts 7 into a 2-word // tagged slot vs the same-module `i32` param's single push. -fn fnparamslookup(c: *cgen, name: str) *node = { +fn fnparamslookup(c: *cgen, name: str) *syntax.node = { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, c.curmod)) { return f.params; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, c.curmod)) { return f.params; }; }; f = f.frnext; }; f = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { return f.params; }; + if (syntax.streq(f.fname, name)) { return f.params; }; f = f.frnext; }; return nil; @@ -44966,8 +44966,8 @@ fn fnparamslookup(c: *cgen, name: str) *node = { fn samemodfn(c: *cgen, name: str) bool = { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, c.curmod)) { return true; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, c.curmod)) { return true; }; }; f = f.frnext; }; @@ -44980,7 +44980,7 @@ fn samemodfn(c: *cgen, name: str) bool = { // to the explicit module. Falls back to the first leaf match if no // matching module is registered — mirrors aliaslookup's two-pass shape // (cgen.ww:75, fixed in #27). -fn fnparamslookupmod(c: *cgen, name: str, mod: str) *node = { +fn fnparamslookupmod(c: *cgen, name: str, mod: str) *syntax.node = { // M1 #22 (#199b): map import alias -> dotted path, identical to // fnretlookupmod (the param-side twin). usehint is idempotent on a // path / c.curmod so existing callers are unaffected. @@ -44988,8 +44988,8 @@ fn fnparamslookupmod(c: *cgen, name: str, mod: str) *node = { if (mk.len > 0) { let f: *fnret = c.fnrets; for (f != nil) { - if (streq(f.fname, name)) { - if (streq(f.fmod, mk)) { return f.params; }; + if (syntax.streq(f.fname, name)) { + if (syntax.streq(f.fmod, mk)) { return f.params; }; }; f = f.frnext; }; @@ -45006,18 +45006,18 @@ fn fnparamslookupmod(c: *cgen, name: str, mod: str) *node = { type defent = struct { dname: str, dmod: str, // originating module (`// MODULE: foo`), or empty - drhs: *node, - dtnode: *node, // #129 A.2: type-spec node (d.lhs); needed for + drhs: *syntax.node, + dtnode: *syntax.node, // #129 A.2: type-spec node (d.lhs); needed for // struct-def structinfo lookup at the cgdot // LOAD-side widening site. dnext: *defent, }; -fn collectdefs(c: *cgen, file: *node) void = { +fn collectdefs(c: *cgen, file: *syntax.node) void = { c.defs = nil; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_DEF) { + if (d.kind == syntax.nkind.N_DEF) { let e: *defent = alloc(defent{dname=d.str, dmod=d.nmod, drhs=d.rhs, dtnode=d.lhs, dnext=c.defs})!; c.defs = e; }; @@ -45032,14 +45032,14 @@ fn collectdefs(c: *cgen, file: *node) void = { fn deflookup(c: *cgen, name: str) bool = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - if (streq(e.dmod, c.curmod)) { return true; }; + if (syntax.streq(e.dname, name)) { + if (syntax.streq(e.dmod, c.curmod)) { return true; }; }; e = e.dnext; }; e = c.defs; for (e != nil) { - if (streq(e.dname, name)) { return true; }; + if (syntax.streq(e.dname, name)) { return true; }; e = e.dnext; }; return false; @@ -45051,17 +45051,17 @@ fn deflookup(c: *cgen, name: str) bool = { // same-leaf `def MSG: str = ...` sitting at the head of c.defs and // inline the wrong strlit. Used by cgdot to inline `.ptr`/`.len` on // `def NAME: str = "..."` — those aren't laid out in memory. -fn deflookuprhs(c: *cgen, name: str) *node = { +fn deflookuprhs(c: *cgen, name: str) *syntax.node = { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - if (streq(e.dmod, c.curmod)) { return e.drhs; }; + if (syntax.streq(e.dname, name)) { + if (syntax.streq(e.dmod, c.curmod)) { return e.drhs; }; }; e = e.dnext; }; e = c.defs; for (e != nil) { - if (streq(e.dname, name)) { return e.drhs; }; + if (syntax.streq(e.dname, name)) { return e.drhs; }; e = e.dnext; }; return nil; @@ -45077,12 +45077,12 @@ fn deflookuprhs(c: *cgen, name: str) *node = { // str-def value-load routes here so a cross-module N_DOT collision // resolves to the explicit module. Falls back to deflookuprhs's bare- // leaf two-pass when no module matches. -fn deflookuprhsmod(c: *cgen, name: str, mod: str) *node = { +fn deflookuprhsmod(c: *cgen, name: str, mod: str) *syntax.node = { if (mod.len > 0) { let e: *defent = c.defs; for (e != nil) { - if (streq(e.dname, name)) { - if (streq(e.dmod, mod)) { return e.drhs; }; + if (syntax.streq(e.dname, name)) { + if (syntax.streq(e.dmod, mod)) { return e.drhs; }; }; e = e.dnext; }; @@ -45095,25 +45095,25 @@ fn deflookuprhsmod(c: *cgen, name: str, mod: str) *node = { // float address-of gate must equal that emission set, or `&def` LEAQs a // symbol the data pass never wrote. Keep in sync with emitfloatlitdata's // peel. -fn floatlitleaf(rhs: *node) bool = { - let r: *node = rhs; +fn floatlitleaf(rhs: *syntax.node) bool = { + let r: *syntax.node = rhs; for (r != nil) { - if (r.kind != nkind.N_CAST) { break; }; + if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; if (r != nil) { - if (r.kind == nkind.N_UN) { - if (r.op == tkind.TK_MINUS) { + if (r.kind == syntax.nkind.N_UN) { + if (r.op == syntax.tkind.TK_MINUS) { r = r.lhs; - for (r != nil) { if (r.kind != nkind.N_CAST) { break; }; r = r.lhs; }; - } else { if (r.op == tkind.TK_PLUS) { + for (r != nil) { if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; + } else { if (r.op == syntax.tkind.TK_PLUS) { r = r.lhs; - for (r != nil) { if (r.kind != nkind.N_CAST) { break; }; r = r.lhs; }; + for (r != nil) { if (r.kind != syntax.nkind.N_CAST) { break; }; r = r.lhs; }; }; }; }; }; if (r == nil) { return false; }; - return r.kind == nkind.N_FLOATLIT; + return r.kind == syntax.nkind.N_FLOATLIT; }; // #149/#147: a top-level def is addressable for `&def` iff emitdefs emits @@ -45125,7 +45125,7 @@ fn floatlitleaf(rhs: *node) bool = { // loud error, never a LEAQ of a missing symbol. `opnd` is the `&`-operand // N_IDENT; its checker-stamped type_ carries the def's type (same as the // cgident float-def read at cgenexpr.ww). -fn defisaddressable(c: *cgen, opnd: *node) bool = { +fn defisaddressable(c: *cgen, opnd: *syntax.node) bool = { let nm: str = opnd.str; if (defvarstructinfo(c, nm) != nil) { return true; }; // #88: the emission side (emitdefconstants' array arm) peels @@ -45133,12 +45133,12 @@ fn defisaddressable(c: *cgen, opnd: *node) bool = { // array HAS a DATA symbol — keying this gate on the unchased // dtnode kind (N_TARRAY) lied it back to the loud error. Chase // the same stamped tinfo so gate == emission set stays exact. - let dtn: *node = defvartnode(c, nm); + let dtn: *syntax.node = defvartnode(c, nm); if (dtn != nil) { - let du88: *tinfo = tichase(dtn.type_: *tinfo); - if (du88 != nil) { if (du88.kind == tykind.TY_ARRAY) { return true; }; }; + let du88: *syntax.tinfo = tichase(dtn.type_: *syntax.tinfo); + if (du88 != nil) { if (du88.kind == syntax.tykind.TY_ARRAY) { return true; }; }; }; - let drhs: *node = deflookuprhs(c, nm); + let drhs: *syntax.node = deflookuprhs(c, nm); if (drhs == nil) { return false; }; let v: u64 = 0u64; if (foldintliteral(drhs, &v)) { return true; }; @@ -45168,14 +45168,14 @@ type modent = struct { mnext: *modent, }; -fn collectmods(c: *cgen, file: *node) void = { +fn collectmods(c: *cgen, file: *syntax.node) void = { c.mods = nil; c.uses = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { // M1 #22: record alias→path for the qualified-ref hint. - if (d.kind == nkind.N_USE) { + if (d.kind == syntax.nkind.N_USE) { if (d.usepath.len > 0) { let um: *modent = alloc(modent{mname=d.str, nmod=d.usepath, omod=d.nmod, mnext=c.uses})!; c.uses = um; @@ -45184,23 +45184,23 @@ fn collectmods(c: *cgen, file: *node) void = { // Mirror collectfnrets' shape exactly (plain prepend in one // branch). Earlier nested-if/early-return variants tickled a // wwstage cgen bug that dropped most prepends. - if (d.kind == nkind.N_FNDECL) { + if (d.kind == syntax.nkind.N_FNDECL) { // Fns mangle regardless of export status — covers // lib/os.read vs lib/io.read collision. if (d.nmod.len > 0) { let isffi: bool = false; - let a: *node = d.attr; + let a: *syntax.node = d.attr; for (a != nil) { - if (a.kind == nkind.N_ATTR) { + if (a.kind == syntax.nkind.N_ATTR) { let an: str = a.str; - if (streq(an, "symbol")) { isffi = true; }; + if (syntax.streq(an, "symbol")) { isffi = true; }; }; a = a.next; }; if (!isffi) { // M1 #32: the ROOT main (imported==0) stays bare; // an IMPORTED `fn main` mangles on its path. - if (!streq(d.str, "main") || d.imported != 0) { + if (!syntax.streq(d.str, "main") || d.imported != 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; }; @@ -45211,19 +45211,19 @@ fn collectmods(c: *cgen, file: *node) void = { // like fns — `export def MAX` becomes `.MAX`, not a bare // `MAX` two packages could clash on under sep-compile. No export // guard: every decl with a module mangles identically. - if (d.kind == nkind.N_DEF) { + if (d.kind == syntax.nkind.N_DEF) { if (d.nmod.len > 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; }; }; - if (d.kind == nkind.N_TYPEDECL) { + if (d.kind == syntax.nkind.N_TYPEDECL) { if (d.nmod.len > 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; }; }; - if (d.kind == nkind.N_LET) { + if (d.kind == syntax.nkind.N_LET) { if (d.nmod.len > 0) { let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!; c.mods = m; @@ -45236,7 +45236,7 @@ fn collectmods(c: *cgen, file: *node) void = { fn modlookup(c: *cgen, name: str) str = { let m: *modent = c.mods; for (m != nil) { - if (streq(m.mname, name)) { return m.nmod; }; + if (syntax.streq(m.mname, name)) { return m.nmod; }; m = m.mnext; }; let empty: str; @@ -45263,8 +45263,8 @@ fn usehint(c: *cgen, alias: str) str = { any.ptr = nil; any.len = 0; for (m != nil) { - if (streq(m.mname, alias)) { - if (streq(m.omod, c.curmod)) { return m.nmod; }; + if (syntax.streq(m.mname, alias)) { + if (syntax.streq(m.omod, c.curmod)) { return m.nmod; }; if (any.ptr == nil && any.len == 0) { any = m.nmod; }; }; m = m.mnext; @@ -45285,9 +45285,9 @@ fn modlookupforfn(c: *cgen, name: str, hint: str) str = { first.ptr = nil; first.len = 0; for (m != nil) { - if (streq(m.mname, name)) { + if (syntax.streq(m.mname, name)) { if (hint.len > 0 && m.nmod.len > 0 - && streq(m.nmod, hint)) { + && syntax.streq(m.nmod, hint)) { return m.nmod; }; if (first.len == 0 && first.ptr == nil) { @@ -45341,20 +45341,20 @@ fn emitfnname(c: *cgen, ident: str, hint: str) void = { // ---- FFI map --------------------------------------------------------- -fn fficollect(c: *cgen, file: *node) void = { +fn fficollect(c: *cgen, file: *syntax.node) void = { c.ffis = nil; if (file == nil) { return; }; - let d: *node = file.list; + let d: *syntax.node = file.list; for (d != nil) { - if (d.kind == nkind.N_FNDECL) { - let a: *node = d.attr; + if (d.kind == syntax.nkind.N_FNDECL) { + let a: *syntax.node = d.attr; for (a != nil) { - if (a.kind == nkind.N_ATTR) { + if (a.kind == syntax.nkind.N_ATTR) { let aname: str = a.str; - if (streq(aname, "symbol")) { - let symnode: *node = a.list; + if (syntax.streq(aname, "symbol")) { + let symnode: *syntax.node = a.list; if (symnode != nil) { - if (symnode.kind == nkind.N_STRLIT) { + if (symnode.kind == syntax.nkind.N_STRLIT) { let f: *ffi = alloc(ffi{ident=d.str, symbol=symnode.str, fnext=c.ffis})!; c.ffis = f; }; @@ -45372,7 +45372,7 @@ fn ffiresolve(c: *cgen, ident: str) str = { let f: *ffi = c.ffis; for (f != nil) { let id: str = f.ident; - if (streq(id, ident)) { return f.symbol; }; + if (syntax.streq(id, ident)) { return f.symbol; }; f = f.fnext; }; return ident;