compiler: load imports and enforce package exports

This commit is contained in:
2026-08-11 22:25:59 +09:00
parent 7bc96b4e03
commit db96422f74
14 changed files with 894 additions and 118 deletions

View File

@@ -68,8 +68,10 @@ scope_lookup_in_module(Scope *s, const char *mod, const char *name)
/*
* 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
* matches the caller's `mod`; Pass 2 accepts only a source-visible bare
* entry. For a primary package that means mod==NULL. For an imported
* package it means a lexical local (a child scope) or a decl-less builtin,
* never another package's flattened interface value. 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
@@ -83,14 +85,16 @@ scope_lookup_in_module(Scope *s, const char *mod, const char *name)
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 (mod && b->mod && strcmp(b->mod, mod) == 0)
return b;
if (b->mod == NULL && (mod == NULL || p->parent != NULL
|| b->decl == NULL) && fallback == NULL)
fallback = b;
}
if (fallback) return fallback;
}
@@ -115,7 +119,9 @@ scope_lookup_type(Scope *s, const char *mod, const char *name)
if (b->kind != SK_TYPE) continue;
if (strcmp(b->name, name) != 0) continue;
if (mod && b->mod && strcmp(b->mod, mod) == 0) return b;
if (fallback == NULL) fallback = b;
if (b->mod == NULL && (mod == NULL || b->decl == NULL)
&& fallback == NULL)
fallback = b;
}
if (fallback) return fallback;
}