diff --git a/core/fmt.odin b/core/fmt.odin index 1c7869338..2e6ab523c 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -159,10 +159,11 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { case Type_Info_Named: write_string(buf, info.name); case Type_Info_Integer: - switch { - case ti == type_info_of(int): write_string(buf, "int"); - case ti == type_info_of(uint): write_string(buf, "uint"); - case ti == type_info_of(uintptr): write_string(buf, "uintptr"); + a := any{type_info = ti}; + switch _ in a { + case int: write_string(buf, "int"); + case uint: write_string(buf, "uint"); + case uintptr: write_string(buf, "uintptr"); case: if info.signed do write_byte(buf, 'i'); else do write_byte(buf, 'u'); @@ -182,8 +183,16 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { case 8: write_string(buf, "complex64"); case 16: write_string(buf, "complex128"); } - case Type_Info_String: write_string(buf, "string"); - case Type_Info_Boolean: write_string(buf, "bool"); + case Type_Info_String: + write_string(buf, "string"); + case Type_Info_Boolean: + a := any{type_info = ti}; + switch _ in a { + case bool: write_string(buf, "bool"); + case: + write_byte(buf, 'b'); + write_i64(buf, i64(8*ti.size), 10); + } case Type_Info_Any: write_string(buf, "any"); @@ -948,8 +957,13 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) { base_arg := arg; base_arg.type_info = type_info_base(base_arg.type_info); switch a in base_arg { + case bool: fmt_bool(fi, bool(a), verb); + case b8: fmt_bool(fi, bool(a), verb); + case b16: fmt_bool(fi, bool(a), verb); + case b32: fmt_bool(fi, bool(a), verb); + case b64: fmt_bool(fi, bool(a), verb); + case any: fmt_arg(fi, a, verb); - case bool: fmt_bool(fi, a, verb); case rune: fmt_rune(fi, a, verb); case f32: fmt_float(fi, f64(a), 32, verb); diff --git a/examples/demo.odin b/examples/demo.odin index fce879c1f..3a915e354 100644 --- a/examples/demo.odin +++ b/examples/demo.odin @@ -75,6 +75,23 @@ general_stuff :: proc() { for in 0..2 {} // 0, 1 for in 0...2 {} // 0, 1, 2 } + + { // Multiple sized booleans + + x0: bool; // default + x1: b8 = true; + x2: b16 = false; + x3: b32 = true; + x4: b64 = false; + + fmt.printf("x1: %T = %v;\n", x1, x1); + fmt.printf("x2: %T = %v;\n", x2, x2); + fmt.printf("x3: %T = %v;\n", x3, x3); + fmt.printf("x4: %T = %v;\n", x4, x4); + + // Having specific sized booleans is very useful when dealing with foreign code + // and to enforce specific alignment for a boolean, especially within a struct + } } default_struct_values :: proc() { @@ -632,8 +649,8 @@ using_in :: proc() { } main :: proc() { + general_stuff(); when false { - general_stuff(); default_struct_values(); union_type(); parametric_polymorphism(); diff --git a/src/ir.cpp b/src/ir.cpp index e68eb1a26..61014247b 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3019,8 +3019,18 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { return value; } + + // bool <-> llvm bool + if (is_type_boolean(src) && dst == t_llvm_bool) { + return ir_emit(proc, ir_instr_conv(proc, irConv_trunc, value, src_type, t)); + } + if (src == t_llvm_bool && is_type_boolean(dst)) { + return ir_emit(proc, ir_instr_conv(proc, irConv_zext, value, src_type, t)); + } + // integer -> integer - if (is_type_integer(src) && is_type_integer(dst)) { + if ((is_type_integer(src) && is_type_integer(dst)) || + (is_type_boolean(src) && is_type_boolean(dst))) { GB_ASSERT(src->kind == Type_Basic && dst->kind == Type_Basic); i64 sz = type_size_of(proc->module->allocator, default_type(src)); @@ -3044,13 +3054,6 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { return ir_emit(proc, ir_instr_conv(proc, kind, value, src_type, t)); } - // bool <-> llvm bool - if (is_type_boolean(src) && dst == t_llvm_bool) { - return ir_emit(proc, ir_instr_conv(proc, irConv_trunc, value, src_type, t)); - } - if (src == t_llvm_bool && is_type_boolean(dst)) { - return ir_emit(proc, ir_instr_conv(proc, irConv_zext, value, src_type, t)); - } // boolean -> integer if (is_type_boolean(src) && is_type_integer(dst)) { @@ -3062,7 +3065,6 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { return ir_emit_comp(proc, Token_NotEq, value, v_zero); } - // float -> float if (is_type_float(src) && is_type_float(dst)) { gbAllocator a = proc->module->allocator; @@ -7870,6 +7872,10 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info ir_emit_comment(proc, str_lit("Type_Info_Basic")); switch (t->Basic.kind) { case Basic_bool: + case Basic_b8: + case Basic_b16: + case Basic_b32: + case Basic_b64: tag = ir_emit_conv(proc, variant_ptr, t_type_info_boolean_ptr); break; diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 02b502605..52815d3f1 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -269,8 +269,12 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) { switch (t->kind) { case Type_Basic: switch (t->Basic.kind) { - case Basic_bool: ir_write_string(f, "i8"); return; - case Basic_llvm_bool: ir_write_string(f, "i1"); return; + case Basic_llvm_bool: ir_write_string(f, "i1"); return; + case Basic_bool: ir_write_string(f, "i8"); return; + case Basic_b8: ir_write_string(f, "i8"); return; + case Basic_b16: ir_write_string(f, "i16"); return; + case Basic_b32: ir_write_string(f, "i32"); return; + case Basic_b64: ir_write_string(f, "i64"); return; case Basic_i8: ir_write_string(f, "i8"); return; case Basic_u8: ir_write_string(f, "i8"); return; diff --git a/src/types.cpp b/src/types.cpp index 68912adbb..eb673232f 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -6,6 +6,11 @@ enum BasicKind { Basic_llvm_bool, Basic_bool, + Basic_b8, + Basic_b16, + Basic_b32, + Basic_b64, + Basic_i8, Basic_u8, Basic_i16, @@ -238,6 +243,10 @@ gb_global Type basic_types[] = { {Type_Basic, {Basic_llvm_bool, BasicFlag_Boolean, 1, STR_LIT("llvm bool")}}, {Type_Basic, {Basic_bool, BasicFlag_Boolean, 1, STR_LIT("bool")}}, + {Type_Basic, {Basic_b8, BasicFlag_Boolean, 1, STR_LIT("b8")}}, + {Type_Basic, {Basic_b16, BasicFlag_Boolean, 2, STR_LIT("b16")}}, + {Type_Basic, {Basic_b32, BasicFlag_Boolean, 4, STR_LIT("b32")}}, + {Type_Basic, {Basic_b64, BasicFlag_Boolean, 8, STR_LIT("b64")}}, {Type_Basic, {Basic_i8, BasicFlag_Integer, 1, STR_LIT("i8")}}, {Type_Basic, {Basic_u8, BasicFlag_Integer | BasicFlag_Unsigned, 1, STR_LIT("u8")}},