selfhost: migrate tool sources to directory packages

Build w6a and w6l from package-main directories and expose the wcc backend through a narrow package API so w6c and wwdump no longer import implementation files. Retarget the remaining load-bearing fixtures and example sources to directory packages; retain the one intentional flat compiler collision as an explicitly composed raw unit.
This commit is contained in:
2026-08-12 17:12:03 +09:00
parent 90f9d60291
commit c7d9dc92de
38 changed files with 197 additions and 252 deletions

View File

@@ -1461,7 +1461,7 @@ fn pushargsrev(c: *cgen, arg: *syntax.node, param: *syntax.node, memphase: bool,
// 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: *syntax.node) i32 = {
fn taggedcallslot(c: *cgen, n: *syntax.node) i32 = {
if (n == nil) { return 0; };
if (n.kind != syntax.nkind.N_CALL) { return 0; };
// Stamped result type, never a callee-name lookup (#209/#211
@@ -1913,7 +1913,7 @@ fn storeopsz(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: *syntax.node) str = {
fn localloadop(c: *cgen, tnode: *syntax.node) str = {
if (tnode == nil) { return "MOVQ"; };
let ti: *syntax.tinfo = tnode.type_: *syntax.tinfo;
if (ti == nil) { return "MOVQ"; };
@@ -2298,7 +2298,7 @@ fn structabisizetn(t: *syntax.tinfo) 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: *syntax.node) *structinfo = {
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
@@ -2325,7 +2325,7 @@ export fn structlookupchain(c: *cgen, tn: *syntax.node) *structinfo = {
return si;
};
export fn sretretsize(c: *cgen, t: *syntax.node) i32 = {
fn sretretsize(c: *cgen, t: *syntax.node) i32 = {
if (t == nil) { return 0; };
let r: *syntax.node = t;
if (r.kind == syntax.nkind.N_TBANG) {
@@ -2490,7 +2490,7 @@ fn sretretsizetn(c: *cgen, t: *syntax.tinfo) 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: *syntax.node) i32 = {
fn callsretsize(c: *cgen, n: *syntax.node) i32 = {
if (n == nil) { return 0; };
if (n.kind != syntax.nkind.N_CALL) { return 0; };
let callee: *syntax.node = n.lhs;
@@ -2666,7 +2666,7 @@ 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: *syntax.node,
fn typenodeprimresolved(c: *cgen, t: *syntax.node,
sz_out: *i32, unsigned_out: *bool) void = {
*sz_out = 0;
*unsigned_out = false;
@@ -2712,7 +2712,7 @@ export fn typenodeprimresolved(c: *cgen, t: *syntax.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: *syntax.node,
fn exprprimresolved(c: *cgen, n: *syntax.node,
sz_out: *i32, unsigned_out: *bool) void = {
*sz_out = 0;
*unsigned_out = false;
@@ -2885,7 +2885,7 @@ fn inferletcalltype(c: *cgen, rhs: *syntax.node) *syntax.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: *syntax.node) i32 = {
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
@@ -3157,7 +3157,7 @@ fn isslicetype(c: *cgen, t: *syntax.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: *syntax.node) *syntax.node = {
fn resolvetagged(c: *cgen, t: *syntax.node) *syntax.node = {
let r: *syntax.node = resolvetype(c, t);
if (r == nil) { return nil; };
if (r.kind == syntax.nkind.N_TBANG) {
@@ -3546,7 +3546,7 @@ fn tnodeisagg(t: *syntax.node) bool = {
// 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: *syntax.node) bool = {
fn isfloattype(c: *cgen, t: *syntax.node) bool = {
if (t == nil) { return false; };
return syntax.typeisfloat(t.type_: *syntax.tinfo);
};
@@ -3554,7 +3554,7 @@ export fn isfloattype(c: *cgen, t: *syntax.node) bool = {
// 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: *syntax.node) bool = {
fn isf32type(c: *cgen, t: *syntax.node) bool = {
if (t == nil) { return false; };
return syntax.typeisf32(t.type_: *syntax.tinfo);
};
@@ -3563,7 +3563,7 @@ export fn isf32type(c: *cgen, t: *syntax.node) bool = {
// `(*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: *syntax.node) bool = {
fn isnullabletype(t: *syntax.node) bool = {
if (t == nil) { return false; };
return syntax.typeisnullable(t.type_: *syntax.tinfo);
};
@@ -3573,7 +3573,7 @@ export fn isnullabletype(t: *syntax.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: *syntax.node) i32 = {
fn nullableptrtag(t: *syntax.node) i32 = {
if (t == nil) { return 0; };
let ti: *syntax.tinfo = t.type_: *syntax.tinfo;
if (ti == nil) { return 0; };
@@ -5394,7 +5394,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *syntax.tinfo, src: *syntax.node, slot_of
// 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: *syntax.node,
fn dotchainresolve(c: *cgen, n: *syntax.node,
outrootname: *str, outrootoff: *i32, outtotaloff: *i32,
outleaftype: **syntax.tinfo, outslicedelta: *i32,
outisglobal: *bool, outptrroot: *bool) bool = {