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:
Mcmd/harehelper/resolve.ha | 121++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
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])!;