ww: add file-scoped import aliases

This commit is contained in:
2026-08-14 10:56:34 +09:00
parent 351f4a25bc
commit 792b6ecbe5
14 changed files with 587 additions and 430 deletions

View File

@@ -127,8 +127,10 @@ export type node = struct {
type_: *void, // filled in by checker; type.ww treats it as *tinfo
tsuffix: str, // typed numeric literal suffix ("i32", "u64", ...)
nmod: str, // originating module from `// MODULE: foo`; "" if none
usepath: str, // on N_USE: full canonical import path; `str` becomes
// the file-local declared default qualifier; "" otherwise
usesource: str, // N_USE: immutable dotted source spelling
usepath: str, // N_USE: canonical vendor-expanded identity
usealias: str, // N_USE: explicit file-local alias, or empty
usepkgname: str,// N_USE: imported declared package name
pkgname: str, // declared package name; independent of canonical nmod
sourceid: i32, // lexical source-file scope in an owner/export unit
used: i32, // N_USE: checker observed this file-local binding
@@ -140,7 +142,7 @@ export fn newnode(k: nkind, file: str, line: i32, col: i32) *node = {
// fval cast-init: 990's wwdump TK_FLOAT diff requires this file
// to tokenise identically through C and ww (lex.ww:382 has the
// same workaround for the cstage %g-formats vs ww-skips divergence).
let n: *node = alloc(node{kind=k, file=file, line=line, col=col, op=tkind.TK_NONE, str="", uval=0u64, fval=0: f64, lhs=nil, rhs=nil, cond=nil, body=nil, els=nil, list=nil, next=nil, attr=nil, exported=0, packed=0, type_=nil, tsuffix="", nmod="", usepath="", pkgname="", sourceid=0, used=0, imported=0})!;
let n: *node = alloc(node{kind=k, file=file, line=line, col=col, op=tkind.TK_NONE, str="", uval=0u64, fval=0: f64, lhs=nil, rhs=nil, cond=nil, body=nil, els=nil, list=nil, next=nil, attr=nil, exported=0, packed=0, type_=nil, tsuffix="", nmod="", usesource="", usepath="", usealias="", usepkgname="", pkgname="", sourceid=0, used=0, imported=0})!;
return n;
};

View File

@@ -4,11 +4,8 @@ package syntax;
import strings;
// `import encoding.utf8;` — the driver resolves the dotted path to
// a directory; only the leaf (`utf8`) is needed downstream as the
// module bareword for n_use → decl disambiguation, mirroring Hare's
// `use encoding::utf8;` → `utf8::name` (ref/hare/hare/ast/import.ha:7
// stores `[]str` but identifier-resolution uses the last component).
// The optional alias is source-local; the dotted path remains the dependency
// identity supplied to the package driver.
fn parseuse(p: *parser) *node = {
let pf: str = p.curfile;
let pl: i32 = p.curline;
@@ -16,19 +13,31 @@ fn parseuse(p: *parser) *node = {
advance(p);
let n: *node = newnode(nkind.N_USE, pf, pl, pc);
n.nmod = p.curmod;
// M1 #22: accumulate the full dotted import path (n.usepath) for the
// checker's path-keyed module match. n.str is the provisional path leaf;
// direct export metadata later replaces it with the declared default name.
let leaf: str;
expectident(p, &leaf);
let alias: str;
let first: str;
if (p.curkind == tkind.TK_UNDER) {
errmsg(p, "blank import alias _ is not implemented");
alias = "_";
advance(p);
expectident(p, &first);
} else {
expectident(p, &first);
if (p.curkind == tkind.TK_IDENT) {
alias = first;
expectident(p, &first);
};
};
let leaf: str = first;
let path: str = leaf;
for (p.curkind == tkind.TK_DOT) {
advance(p);
expectident(p, &leaf);
path = strings.concat(path, ".", leaf);
};
n.str = leaf;
if (alias.len > 0) { n.str = alias; } else { n.str = leaf; };
n.usesource = path;
n.usepath = path;
n.usealias = alias;
expecttok(p, tkind.TK_SEMI, "expected ';' after use");
return n;
};