w6c+selfhost: cross-module same-leaf type disambiguation via Sym.mod
This commit is contained in:
@@ -53,18 +53,66 @@ scope_lookup(Scope *s, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* scope_lookup_in_module — module-filtered chain walk.
|
||||
*
|
||||
* Same FNV bucket + hashnext chain + parent walk as scope_lookup,
|
||||
* plus a (b->mod != NULL && strcmp(b->mod, mod) == 0) filter. When
|
||||
* `mod` is NULL we fall back to unfiltered scope_lookup semantics,
|
||||
* so callers that don't care about disambiguation get the default.
|
||||
*
|
||||
* Used by resolve_typename and the cexpr N_DOT branch to pick the
|
||||
* right same-leaf-name type when two imports each export it
|
||||
* (`bufio.stream` vs `io.stream`).
|
||||
*/
|
||||
Sym *
|
||||
scope_lookup_in_module(Scope *s, const char *mod, const char *name)
|
||||
{
|
||||
if (mod == NULL) return scope_lookup(s, name);
|
||||
for (; s; s = s->parent) {
|
||||
u64 h = hashstr(name) % s->nbuckets;
|
||||
for (Sym *b = s->buckets[h]; b; b = b->hashnext) {
|
||||
if (strcmp(b->name, name) != 0) continue;
|
||||
if (b->mod && strcmp(b->mod, mod) == 0) return b;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sym *
|
||||
scope_define(Scope *s, const char *name, Skind k, Type *t, Node *decl)
|
||||
{
|
||||
if (scope_lookup_local(s, name) != NULL)
|
||||
return NULL;
|
||||
return scope_define_in_module(s, name, NULL, k, t, decl);
|
||||
}
|
||||
|
||||
/*
|
||||
* scope_define_in_module — bucket insert with per-mod dedup.
|
||||
*
|
||||
* Same insertion as scope_define, but the duplicate-rejection key is
|
||||
* (name, mod) rather than name alone. This lets two imports each
|
||||
* register their own `stream` SK_TYPE in the flat scope, and lets the
|
||||
* primary register `stream` (mod=NULL) alongside imported `stream`s.
|
||||
*
|
||||
* Within a single (name, mod) pair the first registration wins; later
|
||||
* attempts return NULL and the caller emits a duplicate-type error.
|
||||
*/
|
||||
Sym *
|
||||
scope_define_in_module(Scope *s, const char *name, const char *mod,
|
||||
Skind k, Type *t, Node *decl)
|
||||
{
|
||||
u64 h = hashstr(name) % s->nbuckets;
|
||||
for (Sym *b = s->buckets[h]; b; b = b->hashnext) {
|
||||
if (strcmp(b->name, name) != 0) continue;
|
||||
if (b->mod == NULL && mod == NULL) return NULL;
|
||||
if (b->mod && mod && strcmp(b->mod, mod) == 0) return NULL;
|
||||
}
|
||||
Sym *sy = amalloc(s->a, sizeof *sy);
|
||||
sy->name = name;
|
||||
sy->mod = mod;
|
||||
sy->kind = k;
|
||||
sy->type = t;
|
||||
sy->decl = decl;
|
||||
sy->scope = s;
|
||||
u64 h = hashstr(name) % s->nbuckets;
|
||||
sy->hashnext = s->buckets[h];
|
||||
s->buckets[h] = sy;
|
||||
if (s->first == NULL) s->first = sy;
|
||||
|
||||
Reference in New Issue
Block a user