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:
@@ -1,8 +1,9 @@
|
||||
/*
|
||||
* wwi.c — `.wwi` export-data producer (w6c -I). M2 DEAD-CODE: writes a
|
||||
* re-parseable ww-prototype rendering of a package's EXPORTED surface.
|
||||
* Nothing consumes `.wwi` yet (combined.ww stays the live path); the only
|
||||
* caller is the new -I flag, off on every existing invocation.
|
||||
* wwi.c — `.wwi` export-data producer (w6c -I): a re-parseable ww-prototype
|
||||
* rendering of a package's EXPORTED surface. Since the sep-compile flip
|
||||
* (epic #22) this is the LIVE import path — the driver runs one `w6c -c -I`
|
||||
* per package and feeds each dep's `.wwi` to its importers as import scope;
|
||||
* the combined.ww amalgamator is gone.
|
||||
*
|
||||
* Specs: .ai/rob-M2-spec.md (producer) + .ai/drew-M2-checkexported.md
|
||||
* (check_exported_type). Two load-bearing choices follow them:
|
||||
@@ -492,13 +493,27 @@ wwi_emit(Checker *c, FILE *of, Node *file)
|
||||
|
||||
/* package line: leaf of the first primary decl's module tag. */
|
||||
const char *pkg = "main";
|
||||
int found = 0;
|
||||
for (Node *d = file->list; d; d = d->next) {
|
||||
if (wwi_primary(d) && d->module && d->module[0]) {
|
||||
const char *dot = strrchr(d->module, '.');
|
||||
pkg = dot ? dot + 1 : d->module;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* #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->module NULL, so it stays "main". The detector is
|
||||
* scan-miss (`!found`), NOT pkg=="main": a body whose first tagged
|
||||
* decl legitimately leafs to "main" must keep that, and must match
|
||||
* selfhost's `found` flag byte-for-byte (rule 10). */
|
||||
if (!found && file->module && file->module[0]) {
|
||||
const char *dot = strrchr(file->module, '.');
|
||||
pkg = dot ? dot + 1 : file->module;
|
||||
}
|
||||
fprintf(of, "package %s;\n", pkg);
|
||||
|
||||
/* imports — primary N_USE, byte-sorted by import path. */
|
||||
|
||||
Reference in New Issue
Block a user