diff options
| author | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-06-14 09:56:14 -0400 |
|---|---|---|
| committer | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-06-14 09:56:14 -0400 |
| commit | a4534a5d35f461ef6df6ee77edfa8cdcff2886f2 (patch) | |
| tree | 3c248cc8761d6d2eadf48dfcd250141c9352ea6d /src/server/analysis.odin | |
| parent | 023c8a0fd1d8d8e54b38bf990a74816a31dee68e (diff) | |
Further improvements to procedure overload resolution
Diffstat (limited to 'src/server/analysis.odin')
| -rw-r--r-- | src/server/analysis.odin | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 1a7e4a7..9311328 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -322,45 +322,54 @@ resolve_type_comp_literal :: proc( return current_symbol, current_comp_lit, true } - -is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: Symbol, flags: ast.Field_Flags = {}) -> bool { - //relying on the fact that a is the call argument to avoid checking both sides for untyped. +// NOTE: This function is not commutative +are_symbol_untyped_basic_same_typed :: proc(a, b: Symbol) -> (bool, bool) { if untyped, ok := a.value.(SymbolUntypedValue); ok { if basic, ok := b.value.(SymbolBasicValue); ok { switch untyped.type { case .Integer: switch basic.ident.name { case "int", "uint", "u32", "i32", "u8", "i8", "u64", "u16", "i16": - return true + return true, true case: - return false + return false, true } case .Bool: switch basic.ident.name { case "bool", "b32", "b64": - return true + return true, true case: - return false + return false, true } case .String: switch basic.ident.name { case "string", "cstring": - return true + return true, true case: - return false + return false, true } case .Float: switch basic.ident.name { case "f32", "f64": - return true + return true, true case: - return false + return false, true } } } else if untyped_b, ok := b.value.(SymbolUntypedValue); ok { - return untyped.type == untyped_b.type + return untyped.type == untyped_b.type, true } } + return false, false +} + +is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: Symbol, flags: ast.Field_Flags = {}) -> bool { + // In order to correctly equate the symbols for overloaded functions, we need to check both directions + if same, ok := are_symbol_untyped_basic_same_typed(a, b); ok { + return same + } else if same, ok := are_symbol_untyped_basic_same_typed(b, a); ok { + return same + } a_id := reflect.union_variant_typeid(a.value) b_id := reflect.union_variant_typeid(b.value) @@ -649,7 +658,7 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou //named parameter if field, is_field := call_arg.derived.(^ast.Field_Value); is_field { named = true - call_symbol, ok = resolve_type_expression(ast_context, field.value) + call_symbol, ok = resolve_call_arg_type_expression(ast_context, field.value) if !ok { break next_fn } @@ -667,7 +676,7 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou log.error("Expected name parameter after starting named parmeter phase") return {}, false } - call_symbol, ok = resolve_type_expression(ast_context, call_arg) + call_symbol, ok = resolve_call_arg_type_expression(ast_context, call_arg) } if !ok { @@ -678,7 +687,7 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou if len(p.return_types) != 1 { break next_fn } - if s, ok := resolve_type_expression(ast_context, p.return_types[0].type); ok { + if s, ok := resolve_call_arg_type_expression(ast_context, p.return_types[0].type); ok { call_symbol = s } } @@ -729,6 +738,16 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou return Symbol{}, false } +resolve_call_arg_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (Symbol, bool) { + old_current_package := ast_context.current_package + ast_context.current_package = ast_context.document_package + defer { + ast_context.current_package = old_current_package + } + + return resolve_type_expression(ast_context, node) +} + resolve_basic_lit :: proc(ast_context: ^AstContext, basic_lit: ast.Basic_Lit) -> (Symbol, bool) { symbol := Symbol { type = .Constant, |