wcc/ww: tag sep-built dotted-path packages by full path not leaf (#57)
A separately-compiled package's primary body was emitted under a bare `//ww:module-reset`, so its own `package <leaf>;` clause set curmod to the leaf (e.g. utf8) while the importer spliced the .wwi under the full `//ww:module encoding.utf8` — definer mangled `utf8.X`, importer wanted `encoding.utf8.X`, unresolved. Thread the dotted path through the directive: `//ww:module-reset <path>` sets curmod to the dotted path (imported stays 0, so the root `fn main` stays bare per #32), and the body's package clause is demoted to a leaf==last-component assertion instead of overwriting curmod. Aligns sep-build to the M1 path-mangle model; only the SEP emitter changes (the combined build_one arm is untouched, so all combined byte-id gates hold). Both stages mirrored. Commit-6 broad-soak prerequisite. Gate 989_sepdotpath_run sep-builds a 2-level dotted package and proves definer==importer qualification + single-component non-vacuity, cs==ww.
This commit is contained in:
@@ -115,8 +115,33 @@ skipws(Lex *l)
|
||||
j++;
|
||||
if (rest[j] == '\0') {
|
||||
int af = lpeek(l, i + j);
|
||||
if (af == '\n' || af < 0)
|
||||
if (af == '\n' || af < 0) {
|
||||
l->modreset = 1;
|
||||
} else if (af == ' '
|
||||
|| af == '\t') {
|
||||
/* `//ww:module-reset <path>`
|
||||
* — sep primary body tagged by
|
||||
* its full dotted import path so
|
||||
* definer == importer (#57). */
|
||||
size_t k = i + j;
|
||||
while (lpeek(l, k) == ' '
|
||||
|| lpeek(l, k) == '\t')
|
||||
k++;
|
||||
size_t s = k;
|
||||
int dch;
|
||||
while ((dch = lpeek(l, k)) >= 0
|
||||
&& dch != '\n'
|
||||
&& dch != '\r'
|
||||
&& dch != ' '
|
||||
&& dch != '\t')
|
||||
k++;
|
||||
l->modreset = 1;
|
||||
if (k > s)
|
||||
l->modresetpath =
|
||||
astrndup(l->a,
|
||||
l->src + l->pos + s,
|
||||
k - s);
|
||||
}
|
||||
}
|
||||
} else if (nx == ' ' || nx == '\t') {
|
||||
/* `//ww:module <path>` — M1 import boundary. */
|
||||
@@ -426,7 +451,15 @@ lexnext(Lex *l)
|
||||
Pos start = lpos(l);
|
||||
/* A `//ww:module-reset` seen in the skipped run surfaces as its own
|
||||
* token before the next real one (#16 option-B boundary reset). */
|
||||
if (l->modreset) { l->modreset = 0; EMIT(TK_MODRESET); }
|
||||
if (l->modreset) {
|
||||
l->modreset = 0;
|
||||
const char *rp = l->modresetpath;
|
||||
l->modresetpath = NULL;
|
||||
/* path-carrying reset → text=path (#57); bare reset → text=NULL */
|
||||
Tok _t = (Tok){ TK_MODRESET, start, rp, rp ? strlen(rp) : 0,
|
||||
{0}, TK_NONE };
|
||||
return _t;
|
||||
}
|
||||
if (l->modpath) {
|
||||
const char *mp = l->modpath;
|
||||
l->modpath = NULL;
|
||||
|
||||
Reference in New Issue
Block a user