Add support for function parameters in scope

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
Slendi 2024-02-28 15:07:07 +02:00
parent a1d74cd2ca
commit 6d94a65649
2 changed files with 64 additions and 38 deletions

View File

@ -1,6 +1,8 @@
let asdf := 123.0 let asdf := 123.0
let poop :: 12 as f32 + 2.0 * asdf 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

View File

@ -79,7 +79,7 @@ scope_leave :: proc() {
scope_variable_lookup :: proc(name: [dynamic]u8) -> ^Type { scope_variable_lookup :: proc(name: [dynamic]u8) -> ^Type {
name_ := name 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_)] type, ok := scope.variable_definitions[get_character_sum_of_dyn_arr(&name_)]
if ok { if ok {
return type return type
@ -90,7 +90,7 @@ scope_variable_lookup :: proc(name: [dynamic]u8) -> ^Type {
scope_function_lookup :: proc(name: [dynamic]u8) -> ^FunctionType { scope_function_lookup :: proc(name: [dynamic]u8) -> ^FunctionType {
name_ := name 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_)] type, ok := scope.function_definitions[get_character_sum_of_dyn_arr(&name_)]
if ok { if ok {
return type return type
@ -140,33 +140,43 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
} }
scope_leave() scope_leave()
case .FunctionCall: case .FunctionCall:
fn := type_check_function_call(ast, parent_ast) type := scope_variable_lookup(ast.children[0].value.([dynamic]u8))
if fn != nil { if type != nil {
if len(fn.parameter_types) != len(ast.children) - 1 { name := ast.children[0].value.([dynamic]u8)
append(&g_message_list, free(ast.children[0])
message_create( clear(&ast.children)
.Error, ast.return_type = type
fmt.aprintf("Function call parameter count mismatch for function `%s`: {} and {}", fn.name, len(fn.parameter_types), len(ast.children) - 1), ast.kind = .Identifier
ast.range, ast.value = name
), } else {
) fn := type_check_function_call(ast, parent_ast)
break if fn != nil {
} if len(fn.parameter_types) != len(ast.children) - 1 {
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, append(&g_message_list,
message_create( message_create(
.Error, .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, 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: case .Identifier:
type := scope_variable_lookup(ast.value.([dynamic]u8)) type := scope_variable_lookup(ast.value.([dynamic]u8))
@ -181,6 +191,9 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
), ),
) )
} else { } else {
ast.kind = .FunctionCall
append(&ast.children, node_create_value(.Identifier, ast.range, ast.value))
ast.value = nil
ast.return_type = fn.return_type 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 // FIXME: Check if they are both the same bit size
ast.return_type = ast_to_type(ast.children[1]) ast.return_type = ast_to_type(ast.children[1])
case .VariableDeclaration: case .VariableDeclaration:
type_check(ast.children[2], ast) if ast.children[2] != nil {
if ast.children[1] == nil { type_check(ast.children[2], ast)
ast.return_type = ast.children[2].return_type 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, if !compare_types(ast.return_type, ast.children[2].return_type) {
message_create( append(&g_message_list,
.Error, message_create(
fmt.aprintf("Type mismatch: {} and {}", ast.return_type, ast.children[2].return_type), .Error,
ast.range, 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 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: 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) type_check(ast.children[1], ast)
ast.return_type = ast.children[0].return_type
scope_leave()
case: case:
fmt.panicf("Unhandled node kind in type_check: {}", ast.kind) fmt.panicf("Unhandled node kind in type_check: {}", ast.kind)
} }
@ -279,7 +305,6 @@ find_function_definitions :: proc(ast_: ^Node) -> (ret: [dynamic]^FunctionType)
} else { } else {
return_type = ast_to_type(ast.children[0]) return_type = ast_to_type(ast.children[0])
} }
node_print(ast)
for decl, i in ast.children { for decl, i in ast.children {
if i < 2 { if i < 2 {
continue continue
@ -287,7 +312,6 @@ find_function_definitions :: proc(ast_: ^Node) -> (ret: [dynamic]^FunctionType)
type := ast_to_type(decl.children[1]) type := ast_to_type(decl.children[1])
append(&fn.parameter_types, type) append(&fn.parameter_types, type)
} }
fmt.printf("Added: %s\n", fn.name)
append(&ret, fn) append(&ret, fn)
case: case:
} }