diff --git a/pong.cat b/pong.cat index 6f032a5..1ec5704 100644 --- a/pong.cat +++ b/pong.cat @@ -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)} \ diff --git a/src/type.odin b/src/type.odin index 4e78a32..ffbdb8b 100644 --- a/src/type.odin +++ b/src/type.odin @@ -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 } diff --git a/src/type_checker.odin b/src/type_checker.odin index 4080f3c..543d3c4 100644 --- a/src/type_checker.odin +++ b/src/type_checker.odin @@ -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: