wcc+ww: //ww:module-reset boundary directive; package-less files keep module "" (#16 PREP-main)

Driver twins emit the line-comment directive only before package-less
files (peekpackage==nil); both lexers tokenize it (TK_MODRESET, appended
=87 so existing token values hold) and both parsers reset curmod — a
package-less file's decls get module "" instead of inheriting the last
bundled package (the sticky-curmod leak, task #11). Withdrawn
alternative: injecting 'package main' flips non-entry symbols
bare->main-prefixed (FFI-visible, broke 764). Codegen-neutral by proof:
bare symbols preserved, both stages emit byte-identical asm for a
directive-bearing combined. Transitional until strict-package rejects
package-less files outright. Includes 737 bad-deep pin for the
PREP-peek >2048 edge + 904/toktest rows for the new token.
This commit is contained in:
2026-06-10 14:07:35 +09:00
parent 2227d698c6
commit 49a5173f3f
17 changed files with 358 additions and 22 deletions

View File

@@ -95,6 +95,23 @@ skipws(Lex *l)
}
if (c == '/' && lpeek(l, 1) == '/') {
lget(l); lget(l); /* consume '//' */
/* #16 option-B: the driver emits `//ww:module-reset`
* before a package-less file's bytes; recognize the
* whole-line directive (without consuming differently)
* and flag it so lexnext emits TK_MODRESET. The body is
* then skipped like any comment. Mirrors the removed
* `// MODULE:` lexer directive. */
{
static const char dir[] = "ww:module-reset";
size_t i = 0;
while (dir[i] && lpeek(l, i) == dir[i])
i++;
if (dir[i] == '\0') {
int nx = lpeek(l, i);
if (nx == '\n' || nx < 0)
l->modreset = 1;
}
}
while ((c = lpeek(l, 0)) >= 0 && c != '\n')
lget(l);
continue;
@@ -381,12 +398,15 @@ lexrune(Lex *l, Pos start)
Tok
lexnext(Lex *l)
{
if (!skipws(l)) {
Pos p = lpos(l);
Tok t = (Tok){ TK_EOF, p, "", 0, {0}, TK_NONE };
int more = skipws(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 (!more) {
Tok t = (Tok){ TK_EOF, start, "", 0, {0}, TK_NONE };
return t;
}
Pos start = lpos(l);
int c = lpeek(l, 0);
if (isidstart(c))