diff --git a/test_type_checker.cat b/test_type_checker.cat index 092d335..d4042c2 100644 --- a/test_type_checker.cat +++ b/test_type_checker.cat @@ -1,6 +1,8 @@ let asdf := 123.0 let poop :: 12 as f32 + 2.0 * asdf -fn name(a b: i32) i32 { } +fn name(a b: f32) i32 { + a + b +} -name 123 456 +name 123 as f32 456.0 diff --git a/type_checker.odin b/type_checker.odin index 70ea67c..a8e5d36 100644 --- a/type_checker.odin +++ b/type_checker.odin @@ -79,7 +79,7 @@ scope_leave :: proc() { scope_variable_lookup :: proc(name: [dynamic]u8) -> ^Type { name_ := name - for &scope in scope_stack { + #reverse for &scope in scope_stack { type, ok := scope.variable_definitions[get_character_sum_of_dyn_arr(&name_)] if ok { return type @@ -90,7 +90,7 @@ scope_variable_lookup :: proc(name: [dynamic]u8) -> ^Type { scope_function_lookup :: proc(name: [dynamic]u8) -> ^FunctionType { name_ := name - for &scope in scope_stack { + #reverse for &scope in scope_stack { type, ok := scope.function_definitions[get_character_sum_of_dyn_arr(&name_)] if ok { return type @@ -140,33 +140,43 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) { } scope_leave() case .FunctionCall: - fn := type_check_function_call(ast, parent_ast) - if fn != nil { - if len(fn.parameter_types) != len(ast.children) - 1 { - append(&g_message_list, - message_create( - .Error, - fmt.aprintf("Function call parameter count mismatch for function `%s`: {} and {}", fn.name, len(fn.parameter_types), len(ast.children) - 1), - ast.range, - ), - ) - break - } - - for param, i in fn.parameter_types { - type_check(ast.children[i + 1], ast) - if !compare_types(param, ast.children[i + 1].return_type) { + type := scope_variable_lookup(ast.children[0].value.([dynamic]u8)) + if type != nil { + name := ast.children[0].value.([dynamic]u8) + free(ast.children[0]) + clear(&ast.children) + ast.return_type = type + ast.kind = .Identifier + ast.value = name + } else { + fn := type_check_function_call(ast, parent_ast) + if fn != nil { + if len(fn.parameter_types) != len(ast.children) - 1 { append(&g_message_list, message_create( .Error, - fmt.aprintf("Type mismatch: {} and {}", param, ast.children[i + 1].return_type), + fmt.aprintf("Function call parameter count mismatch for function `%s`: {} and {}", fn.name, len(fn.parameter_types), len(ast.children) - 1), ast.range, ), ) + break } - } - ast.return_type = fn.return_type + for param, i in fn.parameter_types { + type_check(ast.children[i + 1], ast) + if !compare_types(param, ast.children[i + 1].return_type) { + append(&g_message_list, + message_create( + .Error, + fmt.aprintf("Type mismatch: {} and {}", param, ast.children[i + 1].return_type), + ast.range, + ), + ) + } + } + + ast.return_type = fn.return_type + } } case .Identifier: type := scope_variable_lookup(ast.value.([dynamic]u8)) @@ -181,6 +191,9 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) { ), ) } else { + ast.kind = .FunctionCall + append(&ast.children, node_create_value(.Identifier, ast.range, ast.value)) + ast.value = nil ast.return_type = fn.return_type } } @@ -227,23 +240,36 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) { // FIXME: Check if they are both the same bit size ast.return_type = ast_to_type(ast.children[1]) case .VariableDeclaration: - type_check(ast.children[2], ast) - if ast.children[1] == nil { - ast.return_type = ast.children[2].return_type - } - if !compare_types(ast.return_type, ast.children[2].return_type) { - append(&g_message_list, - message_create( - .Error, - fmt.aprintf("Type mismatch: {} and {}", ast.return_type, ast.children[2].return_type), - ast.range, - ), - ) + if ast.children[2] != nil { + type_check(ast.children[2], ast) + if ast.children[1] == nil { + ast.return_type = ast.children[2].return_type + } + if !compare_types(ast.return_type, ast.children[2].return_type) { + append(&g_message_list, + message_create( + .Error, + fmt.aprintf("Type mismatch: {} and {}", ast.return_type, ast.children[2].return_type), + ast.range, + ), + ) + } + } else { + ast.return_type = ast_to_type(ast.children[1]) } scope_stack[len(scope_stack) - 1].variable_definitions[get_character_sum_of_dyn_arr(&ast.children[0].value.([dynamic]u8))] = ast.return_type case .Function: - // FIXME: Declare variables from params + scope_enter() + for child, i in ast.children { + if i < 2 { + continue + } + type_check(child, ast) + scope_stack[len(scope_stack) - 1].variable_definitions[get_character_sum_of_dyn_arr(&child.children[0].value.([dynamic]u8))] = child.return_type + } type_check(ast.children[1], ast) + ast.return_type = ast.children[0].return_type + scope_leave() case: fmt.panicf("Unhandled node kind in type_check: {}", ast.kind) } @@ -279,7 +305,6 @@ find_function_definitions :: proc(ast_: ^Node) -> (ret: [dynamic]^FunctionType) } else { return_type = ast_to_type(ast.children[0]) } - node_print(ast) for decl, i in ast.children { if i < 2 { continue @@ -287,7 +312,6 @@ find_function_definitions :: proc(ast_: ^Node) -> (ret: [dynamic]^FunctionType) type := ast_to_type(decl.children[1]) append(&fn.parameter_types, type) } - fmt.printf("Added: %s\n", fn.name) append(&ret, fn) case: }