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:
parent
137e36b81c
commit
a225a5b1fa
10
pong.cat
10
pong.cat
@ -12,15 +12,15 @@ enum MyTypedEnum : i8 {
|
|||||||
EnumItem4,
|
EnumItem4,
|
||||||
}
|
}
|
||||||
|
|
||||||
\struct Vec2 {
|
struct Vec2 {
|
||||||
\ x y: f32,
|
x y: f32,
|
||||||
\}
|
}
|
||||||
\
|
|
||||||
\struct Rect {
|
\struct Rect {
|
||||||
\ pos size: Vec2,
|
\ 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 CONSTSZ :: .Vec2 {100.0 100.0}
|
||||||
\let CONST :: .Rect {(CONSTPOS) (CONSTSZ)}
|
\let CONST :: .Rect {(CONSTPOS) (CONSTSZ)}
|
||||||
\
|
\
|
||||||
|
@ -12,6 +12,7 @@ TypeKind :: enum {
|
|||||||
|
|
||||||
StructType :: struct {
|
StructType :: struct {
|
||||||
name: [dynamic]u8,
|
name: [dynamic]u8,
|
||||||
|
bit_size: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
Type :: struct {
|
Type :: struct {
|
||||||
@ -25,6 +26,29 @@ Type :: struct {
|
|||||||
struct_type: ^StructType,
|
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 {
|
type_to_string :: proc(type: ^Type) -> string {
|
||||||
if type == nil {
|
if type == nil {
|
||||||
return "nil (shouldnt happen lol)"
|
return "nil (shouldnt happen lol)"
|
||||||
@ -42,7 +66,7 @@ type_to_string :: proc(type: ^Type) -> string {
|
|||||||
} else if type.kind == .Array {
|
} else if type.kind == .Array {
|
||||||
return fmt.aprintf("[{}]{}", type.array_size, type_to_string(type.array_of))
|
return fmt.aprintf("[{}]{}", type.array_size, type_to_string(type.array_of))
|
||||||
} else if type.kind == .Struct {
|
} 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 "???"
|
return "???"
|
||||||
}
|
}
|
||||||
@ -145,10 +169,11 @@ type_create_array :: proc(of: ^Type, size: u64) -> (ret: ^Type) {
|
|||||||
return
|
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 = new(Type)
|
||||||
ret.kind = .Struct
|
ret.kind = .Struct
|
||||||
ret.struct_type = new(StructType)
|
ret.struct_type = new(StructType)
|
||||||
ret.struct_type.name = name
|
ret.struct_type.name = name
|
||||||
|
ret.struct_type.bit_size = bit_size
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,13 @@ struct_field_create :: proc() -> ^StructField {
|
|||||||
|
|
||||||
Struct :: struct {
|
Struct :: struct {
|
||||||
fields: [dynamic]^StructField,
|
fields: [dynamic]^StructField,
|
||||||
|
bit_size: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct_create :: proc() -> ^Struct {
|
struct_create :: proc() -> ^Struct {
|
||||||
s := new(Struct)
|
s := new(Struct)
|
||||||
s.fields = [dynamic]^StructField{}
|
s.fields = [dynamic]^StructField{}
|
||||||
|
s.bit_size = 0
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +108,7 @@ ast_to_type :: proc(node: ^Node) -> ^Type {
|
|||||||
} else {
|
} else {
|
||||||
res := scope_struct_lookup(value)
|
res := scope_struct_lookup(value)
|
||||||
if res != nil {
|
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))
|
append(&g_message_list, message_create(.Error, fmt.aprintf("Unknown type: %s", value), node.range))
|
||||||
return nil
|
return nil
|
||||||
@ -726,7 +728,7 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
|
|||||||
idx += 1
|
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:
|
case:
|
||||||
fmt.panicf("Unhandled node kind in type_check: {}", ast.kind)
|
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 := struct_field_create()
|
||||||
struct_field.name = field.children[0].value.([dynamic]u8)
|
struct_field.name = field.children[0].value.([dynamic]u8)
|
||||||
struct_field.type = ast_to_type(field.children[1])
|
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
|
field.return_type = struct_field.type
|
||||||
append(&struct_.fields, struct_field)
|
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))] =
|
scope_stack[len(scope_stack) - 1].structure_definitions[get_character_sum_of_dyn_arr(&ast.children[0].value.([dynamic]u8))] =
|
||||||
struct_
|
struct_
|
||||||
case .Enum:
|
case .Enum:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user