From 75a03a7d69c4480accbbded2f0983613131bee57 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Tue, 16 Jun 2026 22:45:17 +0900 Subject: [PATCH] wcc: qualify all references to the syntax package (#75) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the frontend consolidated into one syntax package (#74), wcc still referenced syntax symbols unqualified — residue of the old flat combined namespace, where bare refs resolved by accident. Under separate compilation Hare and Go both require the package qualifier, so those bare refs would not sep-resolve. Qualify every wcc reference to a syntax type, function, or enum member as syntax.X across the seven syntax-importing files. Resolution-only: the resolved symbol and emitted code are unchanged, so the two combined.ww regenerate textually but all five _ww binaries hold byte-for-byte. The struct-literal sites resolve via #76. This makes w6c fully separate-compilable. --- selfhost/cmd/w6c/main.combined.ww | 8668 +++++++++++++------------- selfhost/cmd/wcc/cgen.ww | 1076 ++-- selfhost/cmd/wcc/cgendecl.ww | 38 +- selfhost/cmd/wcc/cgenexpr.ww | 2596 ++++---- selfhost/cmd/wcc/cgenstmt.ww | 740 +-- selfhost/cmd/wcc/cgenutil.ww | 1392 ++--- selfhost/cmd/wcc/check.ww | 2646 ++++---- selfhost/cmd/wcc/wwi.ww | 180 +- selfhost/cmd/wwdump/main.combined.ww | 8488 ++++++++++++------------- 9 files changed, 12912 insertions(+), 12912 deletions(-) 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;