wcc: qualify all references to the syntax package (#75)

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.
This commit is contained in:
2026-06-16 22:45:17 +09:00
parent 01b657a7ff
commit 75a03a7d69
9 changed files with 12912 additions and 12912 deletions

View File

@@ -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 <path>`
// 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;