Browse Source

Specific sized booleans: b8, b16, b32, b64

gingerBill 7 years ago
parent
commit
9428d86f2b
5 changed files with 69 additions and 19 deletions
  1. 21 7
      core/fmt.odin
  2. 18 1
      examples/demo.odin
  3. 15 9
      src/ir.cpp
  4. 6 2
      src/ir_print.cpp
  5. 9 0
      src/types.cpp

+ 21 - 7
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);

+ 18 - 1
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();

+ 15 - 9
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;
 

+ 6 - 2
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;

+ 9 - 0
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")}},