Make the type checker recognize enum definitions

This patch makes it such that if you define an enum inside of a scope,
the type checker will remember it. There is currently no support for
field accesses.

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
Slendi 2024-04-30 10:46:00 +03:00
parent 844a906d62
commit 2e38b9dabc
4 changed files with 37 additions and 17 deletions

View File

@ -432,11 +432,12 @@ node_create_struct_or_union :: proc(
return return
} }
node_create_enum :: proc(range: SourceLocation, data: EnumValue) -> (ret: ^Node) { node_create_enum :: proc(range: SourceLocation, data: EnumValue, name: [dynamic]u8) -> (ret: ^Node) {
ret = new(Node) ret = new(Node)
ret^ = { ret^ = {
kind = .Enum, kind = .Enum,
enum_value = data, enum_value = data,
value = name,
} }
return return
} }

View File

@ -46,20 +46,20 @@ main :: proc() {
os.exit(1) os.exit(1)
} }
} }
//clear(&g_message_list) clear(&g_message_list)
//type_check(ast, nil) type_check(ast, nil)
//if len(g_message_list) > 0 { if len(g_message_list) > 0 {
// contains_errors := false contains_errors := false
// for &msg in g_message_list { for &msg in g_message_list {
// message_print(&msg, &data) message_print(&msg, &data)
// if msg.level == .Error || msg.level == .Fatal { if msg.level == .Error || msg.level == .Fatal {
// contains_errors = true contains_errors = true
// } }
// } }
// if contains_errors { if contains_errors {
// os.exit(1) os.exit(1)
// } }
//} }
node_print(ast) node_print(ast)

View File

@ -277,7 +277,7 @@ parser_parse_enum_definition :: proc(parser: ^Parser) -> ^Node {
enum_value.type = type_node enum_value.type = type_node
return node_create_enum(range, enum_value) return node_create_enum(range, enum_value, name)
} }
@(private = "file") @(private = "file")

View File

@ -39,6 +39,7 @@ Scope :: struct {
variable_mutability_definitions: map[int]bool, // A map to a variable's mutability variable_mutability_definitions: map[int]bool, // A map to a variable's mutability
function_return_type: ^Type, function_return_type: ^Type,
structure_definitions: map[int]^Struct, structure_definitions: map[int]^Struct,
enum_definitions: map[int]^EnumValue,
} }
find_struct :: proc(name: [dynamic]u8) -> ^Struct { find_struct :: proc(name: [dynamic]u8) -> ^Struct {
@ -665,7 +666,8 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
} }
} }
scope_leave() scope_leave()
case .Struct: case .Struct: // Nothing
case .Enum: // Nothing
case .StructInitializer: case .StructInitializer:
for child in ast.children { for child in ast.children {
type_check(child, ast) type_check(child, ast)
@ -802,6 +804,23 @@ find_function_definitions :: proc(ast_: ^Node) -> (ret: [dynamic]^FunctionType)
} }
scope_stack[len(scope_stack) - 1].structure_definitions[get_character_sum_of_dyn_arr(&ast.children[0].value.([dynamic]u8))] = scope_stack[len(scope_stack) - 1].structure_definitions[get_character_sum_of_dyn_arr(&ast.children[0].value.([dynamic]u8))] =
struct_ struct_
case .Enum:
if ast.enum_value.type.kind != .Identifier {
append(
&g_message_list,
message_create(.Error, "The type of this struct must be a scalar", ast.enum_value.type.range),
)
}
type_ptr := ast_to_type(ast.enum_value.type)
if type_ptr.kind != .Integer {
append(
&g_message_list,
message_create(.Error, "The type of this struct must be an integer", ast.enum_value.type.range),
)
}
scope_stack[len(scope_stack) - 1].enum_definitions[get_character_sum_of_dyn_arr(&ast.value.([dynamic]u8))] =
&ast.enum_value
case: case:
} }
} }