Compute the size of structs

This patch makes it such that the size of a struct can be computed by
it's fields.

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
Slendi 2024-05-04 12:57:19 +02:00
parent 137e36b81c
commit a225a5b1fa
3 changed files with 40 additions and 11 deletions

View File

@ -12,15 +12,15 @@ enum MyTypedEnum : i8 {
EnumItem4,
}
\struct Vec2 {
\ x y: f32,
\}
\
struct Vec2 {
x y: f32,
}
\struct Rect {
\ pos size: Vec2,
\}
\
\let CONSTPOS :: .Vec2 {20.0 20.0}
let CONSTPOS :: .Vec2 {20.0 20.0}
\let CONSTSZ :: .Vec2 {100.0 100.0}
\let CONST :: .Rect {(CONSTPOS) (CONSTSZ)}
\

View File

@ -11,7 +11,8 @@ TypeKind :: enum {
}
StructType :: struct {
name: [dynamic]u8,
name: [dynamic]u8,
bit_size: u64,
}
Type :: struct {
@ -25,6 +26,29 @@ Type :: struct {
struct_type: ^StructType,
}
type_get_bit_size :: proc(type: ^Type) -> u64 {
if type == nil {
return 0
}
switch (type.kind) {
case .Integer:
fallthrough
case .Float:
return u64(type.bit_size)
case .Pointer:
return 64
case .Array:
if type.array_size == 0 {
return 64
} else {
return type_get_bit_size(type.array_of) * type.array_size
}
case .Struct:
return type.struct_type.bit_size
}
panic("type_get_bit_size: Invalid type kind, cannot compute bit size")
}
type_to_string :: proc(type: ^Type) -> string {
if type == nil {
return "nil (shouldnt happen lol)"
@ -42,7 +66,7 @@ type_to_string :: proc(type: ^Type) -> string {
} else if type.kind == .Array {
return fmt.aprintf("[{}]{}", type.array_size, type_to_string(type.array_of))
} else if type.kind == .Struct {
return fmt.aprintf("Struct`%s`", type.struct_type.name)
return fmt.aprintf("Struct`%s`(%d)", type.struct_type.name, type.struct_type.bit_size)
}
return "???"
}
@ -145,10 +169,11 @@ type_create_array :: proc(of: ^Type, size: u64) -> (ret: ^Type) {
return
}
type_create_struct :: proc(name: [dynamic]u8) -> (ret: ^Type) {
type_create_struct :: proc(name: [dynamic]u8, bit_size: u64) -> (ret: ^Type) {
ret = new(Type)
ret.kind = .Struct
ret.struct_type = new(StructType)
ret.struct_type.name = name
ret.struct_type.bit_size = bit_size
return
}

View File

@ -14,12 +14,14 @@ struct_field_create :: proc() -> ^StructField {
}
Struct :: struct {
fields: [dynamic]^StructField,
fields: [dynamic]^StructField,
bit_size: u64,
}
struct_create :: proc() -> ^Struct {
s := new(Struct)
s.fields = [dynamic]^StructField{}
s.bit_size = 0
return s
}
@ -106,7 +108,7 @@ ast_to_type :: proc(node: ^Node) -> ^Type {
} else {
res := scope_struct_lookup(value)
if res != nil {
return type_create_struct(value)
return type_create_struct(value, res.bit_size)
}
append(&g_message_list, message_create(.Error, fmt.aprintf("Unknown type: %s", value), node.range))
return nil
@ -726,7 +728,7 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
idx += 1
}
ast.return_type = type_create_struct(ast.value.([dynamic]u8))
ast.return_type = type_create_struct(ast.value.([dynamic]u8), struct_.bit_size)
case:
fmt.panicf("Unhandled node kind in type_check: {}", ast.kind)
}
@ -799,9 +801,11 @@ find_function_definitions :: proc(ast_: ^Node) -> (ret: [dynamic]^FunctionType)
struct_field := struct_field_create()
struct_field.name = field.children[0].value.([dynamic]u8)
struct_field.type = ast_to_type(field.children[1])
struct_.bit_size += type_get_bit_size(struct_field.type)
field.return_type = struct_field.type
append(&struct_.fields, struct_field)
}
scope_stack[len(scope_stack) - 1].structure_definitions[get_character_sum_of_dyn_arr(&ast.children[0].value.([dynamic]u8))] =
struct_
case .Enum: