wwi: derive decl-less module's .wwi package leaf from parse-stamped path (#11)
wwi_emit took the .wwi `package` leaf from the first primary decl's module tag;
a fully empty primary module body (zero decls) had none, so the leaf stayed the
literal default "main" and the importer rejected it ("package main does not
match import path <leaf>"). The module identity is only available at parse time
(curmod is overwritten by imported //ww:module sections before emit), so stamp
the primary path onto the N_FILE node (TK_MODULE and TK_MODRESET rp!=NULL sites,
only-if-empty so a bare-reset `package main` root stays "main") and, when the
decl-scan finds no leaf, fall back to that stamped path. Symmetric cstage+
selfhost; both detect scan-miss via the same found-flag so the emitted .wwi
stays byte-identical.
Regression: test/wcc/989_wwileaf_run.c, table-driven over {empty body,
comment-only, nested a.b.c} decl-less shapes, non-vacuity proven.
This commit is contained in:
@@ -587,6 +587,7 @@ export fn wwiemit(c: *checker, file: *syntax.node, path: str) i32 = {
|
||||
|
||||
// package line: leaf of the first primary decl's module tag.
|
||||
let pkg: str = "main";
|
||||
let found: i32 = 0;
|
||||
let pd: *syntax.node = file.list;
|
||||
for (pd != nil) {
|
||||
if (wwiprimary(pd) && pd.nmod.len > 0) {
|
||||
@@ -604,11 +605,35 @@ export fn wwiemit(c: *checker, file: *syntax.node, path: str) i32 = {
|
||||
} else {
|
||||
pkg = pd.nmod;
|
||||
};
|
||||
found = 1;
|
||||
pd = nil;
|
||||
} else {
|
||||
pd = pd.next;
|
||||
};
|
||||
};
|
||||
// #11: a decl-less / export-less primary body carries no
|
||||
// module-tagged decl, so the scan above finds nothing; fall back to
|
||||
// the primary module identity stamped on the N_FILE node at parse
|
||||
// time. A real root `package main` arrives via a bare module-reset
|
||||
// and leaves file.nmod empty, so it stays "main". The detector is
|
||||
// scan-miss (found==0), NOT pkg=="main", to match cstage byte-for-
|
||||
// byte (rule 10) when a tagged decl legitimately leafs to "main".
|
||||
if (found == 0 && file.nmod.len > 0) {
|
||||
let dotidx: i32 = -1;
|
||||
let i: i32 = 0;
|
||||
for (i < file.nmod.len) {
|
||||
if (file.nmod[i] == 46u8) { dotidx = i; };
|
||||
i += 1;
|
||||
};
|
||||
if (dotidx >= 0) {
|
||||
let leaf: str;
|
||||
leaf.ptr = file.nmod.ptr + ((dotidx + 1): u64);
|
||||
leaf.len = file.nmod.len - dotidx - 1;
|
||||
pkg = leaf;
|
||||
} else {
|
||||
pkg = file.nmod;
|
||||
};
|
||||
};
|
||||
wputs(fd, "package ");
|
||||
wputs(fd, pkg);
|
||||
wputs(fd, ";\n");
|
||||
|
||||
Reference in New Issue
Block a user