commit 48764e73220603294e6214ca38b53c736fec7616
parent d3c29be9ad1ec615021bd61d3504aaa206f894da
Author: Lou Woell <lou.woell@posteo.de>
Date: Tue, 17 Feb 2026 05:16:16 +0100
[resolve] support resolving enum (member) identifiers
Diffstat:
1 file changed, 83 insertions(+), 38 deletions(-)
diff --git a/cmd/harehelper/resolve.ha b/cmd/harehelper/resolve.ha
@@ -113,8 +113,8 @@ fn resolve_uid (
) (void | ast::ident | error) = {
let imports = match (list_imports(path)) {
- case let e: error =>
- fmt::fatalf("Error: {}", strerror(e));
+ case let e: error =>
+ fmt::fatalf("Error: {}", strerror(e));
case let l: []ast::import =>
yield l;
};
@@ -132,52 +132,97 @@ fn resolve_uid (
let found_import = false;
let interned = false;
+
let ns = ident_ns(id);
match :binding (i.bindings) {
- case let a: ast::import_alias =>
- found_import = (ns[0] == a);
- case let members: ast::import_members =>
- // if len(id) > 1 -> id is not an interned
- // symbol.
- if (len(id) > 1) yield :binding;
- for (let s .. members) {
- found_import = (s == id[0]);
- if (found_import) {
- interned = true;
- break;
- };
+ case let a: ast::import_alias =>
+ found_import = (ns[0] == a);
+
+ // handle enums
+ if (found_import && len(id) > 1) {
+ interned = true;
+ id = id[1..];
+ };
+
+ case let members: ast::import_members =>
+
+ // simple case:
+ // id: [ident]
+ // ns: [ident]
+ // ident: [hare, ast]
+ // members [..., ident]
+
+ // complex (enum) case:
+ // id: [builtin_type, bool]
+ // ns: [builtin_type]
+ // ident: [hare, ast]
+ // members [..., builtin_type]
+
+ for (let s .. members) {
+ found_import = (s == id[0]);
+ if (found_import) {
+ interned = true;
+ break;
};
- case ast::import_wildcard =>
- // if len(id) > 1 -> id is not an interned
- // symbol.
- if (len(id) > 1) yield :binding;
- let list = match (list_symbols(ctx, ident)) {
- case let e: error =>
- fmt::errorfln("Error: {}", strerror(e))!;
- // skip module.
- yield :binding;
- case let l: []ast::ident =>
- yield l;
+ };
+ case ast::import_wildcard =>
+
+ // Conceptually the same as in members case.
+
+ let list = match (list_symbols(ctx, ident)) {
+ case let e: error =>
+ fmt::errorfln("Error: {}", strerror(e))!;
+ // skip module.
+ yield :binding;
+ case let l: []ast::ident =>
+ yield l;
+ };
+ defer idents_finish(list);
+
+ for (let s .. list) {
+ found_import = ast::ident_eq(s, [id[0]]);
+ if (found_import) {
+ interned = true;
+ break;
};
- defer idents_finish(list);
-
- for (let s .. list) {
- found_import = ast::ident_eq(s, id);
- if (found_import) {
- interned = true;
- break;
- };
+ };
+ case void =>
+
+ // simple import
+ // id: [ast, ident]
+ // ns: [ast]
+ // ident: [hare, ast]
+ found_import = ast::ident_eq(
+ ns, ident_last(ident),
+ );
+
+ // check for enum
+ // id: [ast, builtin_type, bool]
+ // ns: [ast, builtin_type]
+ // ident: [hare, ast]
+ if (!found_import && len(ns) > 1) {
+
+ let nsns = ident_ns(ns);
+ found_import = ast::ident_eq(nsns, ident_last(ident));
+
+ if (found_import) {
+ interned = true;
+ id = id[len(nsns)..];
};
- case void =>
- found_import = ast::ident_eq(
- ns, ident_last(ident),
- );
+ };
};
if (found_import || found_module) {
+
let result = ast::ident_dup(ident);
- if (found_import && (len(id) > 1 || interned)) {
+
+
+ if (found_import) if (interned) {
+ for (let s .. ast::ident_dup(id)) {
+ append(result, s)!;
+ };
+ } else if (len(id) > 1) {
let end = ident_last(id);
let id_end = ast::ident_dup(end);
append(result, id_end[0])!;