w6c+selfhost: same-module preference for bare-leaf lookup
This commit is contained in:
@@ -79,6 +79,43 @@ scope_lookup_in_module(Scope *s, const char *mod, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* scope_lookup_prefer — bare-leaf lookup with same-module preference.
|
||||
*
|
||||
* Walks the same FNV bucket + hashnext chain + parent walk scope_lookup
|
||||
* uses. Within each scope's bucket: Pass 1 prefers entries whose
|
||||
* `sym.mod` matches the caller's `mod`; Pass 2 falls back to the first
|
||||
* match regardless of mod (the existing scope_lookup semantics). We
|
||||
* only descend to the parent scope when the current scope has no
|
||||
* matching entry at all — so a local binding in a closer scope still
|
||||
* shadows a same-name fn from a parent scope, even when the parent
|
||||
* entry mod-matches.
|
||||
*
|
||||
* When `mod` is NULL we just call scope_lookup — there's no module
|
||||
* identity to prefer.
|
||||
*
|
||||
* Used at bare-leaf lookup sites inside a known current module so that
|
||||
* a bare `read` inside lib/os resolves to os.read rather than the
|
||||
* io.read that happens to hash earlier into the flat scope.
|
||||
* Qualified-lookup paths (`mod.name`) stay on scope_lookup_in_module.
|
||||
*/
|
||||
Sym *
|
||||
scope_lookup_prefer(Scope *s, const char *mod, const char *name)
|
||||
{
|
||||
if (mod == NULL) return scope_lookup(s, name);
|
||||
for (Scope *p = s; p; p = p->parent) {
|
||||
u64 h = hashstr(name) % p->nbuckets;
|
||||
Sym *fallback = NULL;
|
||||
for (Sym *b = p->buckets[h]; b; b = b->hashnext) {
|
||||
if (strcmp(b->name, name) != 0) continue;
|
||||
if (b->mod && strcmp(b->mod, mod) == 0) return b;
|
||||
if (fallback == NULL) fallback = b;
|
||||
}
|
||||
if (fallback) return fallback;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sym *
|
||||
scope_define(Scope *s, const char *name, Skind k, Type *t, Node *decl)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user