ww+wcc: emit and lex // MODULE: <name> directive in combined.ww

This commit is contained in:
2026-05-11 14:54:56 +09:00
parent 5d91ee778e
commit d7036be0e5
9 changed files with 296 additions and 2 deletions

View File

@@ -113,6 +113,36 @@ locate_import(const char *dirs, const char *name, char *out, size_t outsz)
return 0;
}
/* module_of — pick the source's containing-directory basename.
* lib/os/os.ww -> "os"
* selfhost/cmd/wcc/sym.ww -> "wcc"
* bare "main.ww" -> "main"
* Writes into dst (size ≥ 1); always NUL-terminates. */
static void
module_of(const char *path, char *dst, size_t dstn)
{
if (dstn == 0) return;
dst[0] = '\0';
const char *last = strrchr(path, '/');
if (last == NULL) {
/* bare filename — use the stem (path minus .ww). */
size_t n = strlen(path);
if (n >= 3 && strcmp(path + n - 3, ".ww") == 0) n -= 3;
if (n >= dstn) n = dstn - 1;
memcpy(dst, path, n);
dst[n] = '\0';
return;
}
/* Basename of the parent directory. */
const char *prev = last - 1;
while (prev >= path && *prev != '/') prev--;
prev++;
size_t n = (size_t)(last - prev);
if (n >= dstn) n = dstn - 1;
memcpy(dst, prev, n);
dst[n] = '\0';
}
/* Recursively expand `path`: for each top-level `use IDENT;` we find,
* resolve the import and expand it first, then append our own bytes.
* Already-visited paths are skipped. */
@@ -156,6 +186,15 @@ expand(FILE *out, const char *path, struct ImportSet *visited,
expand(out, ipath, visited, libdir);
}
/* Prefix a `// MODULE: <name>` directive so the ww-side wcc lexer
* can stamp each top-level decl with its originating module. The
* marker is a comment to every other reader (including the C-side
* wcc), so it's safe to emit unconditionally. */
char modname[128];
module_of(path, modname, sizeof modname);
if (modname[0] != '\0')
fprintf(out, "// MODULE: %s\n", modname);
rewind(in);
int ch;
while ((ch = fgetc(in)) != EOF) fputc(ch, out);