diff options
Diffstat (limited to 'src/server/analysis.odin')
| -rw-r--r-- | src/server/analysis.odin | 145 |
1 files changed, 139 insertions, 6 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 52a05f0..5e4076c 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -1142,6 +1142,13 @@ internal_resolve_type_expression :: proc( ast_context.field_name, ), true + case ^Matrix_Type: + return make_symbol_matrix_from_ast( + ast_context, + v^, + ast_context.field_name, + ), + true case ^Dynamic_Array_Type: return make_symbol_dynamic_array_from_ast( ast_context, @@ -1174,7 +1181,7 @@ internal_resolve_type_expression :: proc( case ^Basic_Directive: return resolve_basic_directive(ast_context, v^) case ^Binary_Expr: - return resolve_first_symbol_from_binary_expression(ast_context, v) + return resolve_binary_expression(ast_context, v) case ^Ident: delete_key(&ast_context.recursion_map, v) return internal_resolve_type_identifier(ast_context, v^) @@ -1246,6 +1253,13 @@ internal_resolve_type_expression :: proc( symbol, ok := internal_resolve_type_expression(ast_context, v.elem) symbol.pointers += 1 return symbol, ok + case ^Matrix_Index_Expr: + if symbol, ok := internal_resolve_type_expression(ast_context, v.expr); + ok { + if mat, ok := symbol.value.(SymbolMatrixValue); ok { + return internal_resolve_type_expression(ast_context, mat.expr) + } + } case ^Index_Expr: indexed, ok := internal_resolve_type_expression(ast_context, v.expr) @@ -1663,6 +1677,9 @@ internal_resolve_type_identifier :: proc( case ^Dynamic_Array_Type: return_symbol, ok = make_symbol_dynamic_array_from_ast(ast_context, v^, node), true + case ^Matrix_Type: + return_symbol, ok = + make_symbol_matrix_from_ast(ast_context, v^, node), true case ^Map_Type: return_symbol, ok = make_symbol_map_from_ast(ast_context, v^, node), true @@ -1760,6 +1777,9 @@ internal_resolve_type_identifier :: proc( case ^Dynamic_Array_Type: return_symbol, ok = make_symbol_dynamic_array_from_ast(ast_context, v^, node), true + case ^Matrix_Type: + return_symbol, ok = + make_symbol_matrix_from_ast(ast_context, v^, node), true case ^Map_Type: return_symbol, ok = make_symbol_map_from_ast(ast_context, v^, node), true @@ -2113,10 +2133,7 @@ resolve_first_symbol_from_binary_expression :: proc( Symbol, bool, ) { - //Fairly simple function to find the earliest identifier symbol in binary expression. - if binary.left != nil { - if ident, ok := binary.left.derived.(^ast.Ident); ok { if s, ok := resolve_type_identifier(ast_context, ident^); ok { return s, ok @@ -2149,6 +2166,72 @@ resolve_first_symbol_from_binary_expression :: proc( return {}, false } +resolve_binary_expression :: proc( + ast_context: ^AstContext, + binary: ^ast.Binary_Expr, +) -> ( + Symbol, + bool, +) { + if binary.left == nil || binary.right == nil { + return {}, false + } + + symbol_a, symbol_b: Symbol + ok_a, ok_b: bool + + if expr, ok := binary.left.derived.(^ast.Binary_Expr); ok { + symbol_a, ok_a = resolve_binary_expression(ast_context, expr) + } else { + ast_context.use_locals = true + symbol_a, ok_a = resolve_type_expression(ast_context, binary.left) + } + + if expr, ok := binary.right.derived.(^ast.Binary_Expr); ok { + symbol_b, ok_b = resolve_binary_expression(ast_context, expr) + } else { + ast_context.use_locals = true + symbol_b, ok_b = resolve_type_expression(ast_context, binary.right) + } + + if !ok_a || !ok_b { + return {}, false + } + + matrix_value_a, is_matrix_a := symbol_a.value.(SymbolMatrixValue) + matrix_value_b, is_matrix_b := symbol_b.value.(SymbolMatrixValue) + + vector_value_a, is_vector_a := symbol_a.value.(SymbolFixedArrayValue) + vector_value_b, is_vector_b := symbol_b.value.(SymbolFixedArrayValue) + + //Handle matrix multication specially because it can actual change the return type dimension + if is_matrix_a && is_matrix_b && binary.op.kind == .Mul { + symbol_a.value = SymbolMatrixValue { + expr = matrix_value_a.expr, + x = matrix_value_a.x, + y = matrix_value_b.y, + } + return symbol_a, true + } else if is_matrix_a && is_vector_b && binary.op.kind == .Mul { + symbol_a.value = SymbolFixedArrayValue { + expr = matrix_value_a.expr, + len = matrix_value_a.y, + } + return symbol_a, true + + } else if is_vector_a && is_matrix_b && binary.op.kind == .Mul { + symbol_a.value = SymbolFixedArrayValue { + expr = matrix_value_b.expr, + len = matrix_value_b.x, + } + return symbol_a, true + } + + + //Otherwise just choose the first type, we do not handle error cases - that is done with the checker + return symbol_a, ok_a +} + find_position_in_call_param :: proc( ast_context: ^AstContext, call: ast.Call_Expr, @@ -2327,6 +2410,28 @@ make_symbol_dynamic_array_from_ast :: proc( return symbol } +make_symbol_matrix_from_ast :: proc( + ast_context: ^AstContext, + v: ast.Matrix_Type, + name: ast.Ident, +) -> Symbol { + symbol := Symbol { + range = common.get_token_range(v.node, ast_context.file.src), + type = .Constant, + pkg = get_package_from_node(v.node), + name = name.name, + } + + symbol.value = SymbolMatrixValue { + expr = v.elem, + x = v.row_count, + y = v.column_count, + } + + return symbol +} + + make_symbol_multi_pointer_from_ast :: proc( ast_context: ^AstContext, v: ast.Multi_Pointer_Type, @@ -3865,13 +3970,19 @@ get_signature :: proc( return "proc" case SymbolStructValue: if is_variable { - return symbol.name + return strings.concatenate( + {pointer_prefix, symbol.name}, + ast_context.allocator, + ) } else { return "struct" } case SymbolUnionValue: if is_variable { - return symbol.name + return strings.concatenate( + {pointer_prefix, symbol.name}, + ast_context.allocator, + ) } else { return "union" } @@ -3901,6 +4012,20 @@ get_signature :: proc( }, allocator = ast_context.allocator, ) + case SymbolMatrixValue: + return strings.concatenate( + a = { + pointer_prefix, + "matrix", + "[", + common.node_to_string(v.x), + ",", + common.node_to_string(v.y), + "]", + common.node_to_string(v.expr), + }, + allocator = ast_context.allocator, + ) case SymbolPackageValue: return "package" case SymbolUntypedValue: @@ -4553,6 +4678,14 @@ get_document_position_node :: proc( } case ^Undef: case ^Basic_Lit: + case ^Matrix_Index_Expr: + get_document_position(n.expr, position_context) + get_document_position(n.row_index, position_context) + get_document_position(n.column_index, position_context) + case ^Matrix_Type: + get_document_position(n.row_count, position_context) + get_document_position(n.column_count, position_context) + get_document_position(n.elem, position_context) case ^Ellipsis: get_document_position(n.expr, position_context) case ^Proc_Lit: |