Add support for function parameters in scope
Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
parent
a1d74cd2ca
commit
6d94a65649
@ -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
|
||||
|
@ -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:
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user