mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 05:08:14 +00:00
Handle enums correctly with printf
This commit is contained in:
+5
-26
@@ -1,31 +1,10 @@
|
|||||||
#import "fmt.odin";
|
#import "fmt.odin";
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
using Type_Info;
|
Fruit :: enum f32 {
|
||||||
is_type_integer :: proc(info: ^Type_Info) -> bool {
|
Apple = 123,
|
||||||
if info == nil {
|
Pear = 321,
|
||||||
return false;
|
Tomato,
|
||||||
}
|
|
||||||
|
|
||||||
match type i : type_info_base(info) {
|
|
||||||
case Integer:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ti := type_info_base(type_info(Allocator_Mode));
|
|
||||||
match type e : ti {
|
|
||||||
case Enum:
|
|
||||||
is_int := is_type_integer(e.base);
|
|
||||||
for i : 0..<e.names.count {
|
|
||||||
name := e.names[i];
|
|
||||||
value := e.values[i];
|
|
||||||
if is_int {
|
|
||||||
fmt.printf("%s - %d\n", name, value.i);
|
|
||||||
} else {
|
|
||||||
fmt.printf("%s - %f\n", name, value.f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
fmt.printf("%s = %f\n", Fruit.Apple, Fruit.Apple);
|
||||||
}
|
}
|
||||||
|
|||||||
+106
-19
@@ -227,19 +227,6 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
|
|
||||||
|
|
||||||
bprint :: proc(buf: ^Buffer, args: ...any) -> int {
|
bprint :: proc(buf: ^Buffer, args: ...any) -> int {
|
||||||
is_type_string :: proc(info: ^Type_Info) -> bool {
|
|
||||||
using Type_Info;
|
|
||||||
if info == nil {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
match type i : type_info_base(info) {
|
|
||||||
case String:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fi: Fmt_Info;
|
fi: Fmt_Info;
|
||||||
fi.buf = buf;
|
fi.buf = buf;
|
||||||
|
|
||||||
@@ -270,6 +257,42 @@ bprintln :: proc(buf: ^Buffer, args: ...any) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
is_type_string :: proc(info: ^Type_Info) -> bool {
|
||||||
|
using Type_Info;
|
||||||
|
if info == nil {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
match type i : type_info_base(info) {
|
||||||
|
case String:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_type_integer :: proc(info: ^Type_Info) -> bool {
|
||||||
|
using Type_Info;
|
||||||
|
if info == nil {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
match type i : type_info_base(info) {
|
||||||
|
case Integer:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_type_float :: proc(info: ^Type_Info) -> bool {
|
||||||
|
using Type_Info;
|
||||||
|
if info == nil {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
match type i : type_info_base(info) {
|
||||||
|
case Float:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -356,6 +379,7 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
|
|||||||
|
|
||||||
|
|
||||||
fmt_bad_verb :: proc(using fi: ^Fmt_Info, verb: rune) {
|
fmt_bad_verb :: proc(using fi: ^Fmt_Info, verb: rune) {
|
||||||
|
assert(verb != 'v');
|
||||||
buffer_write_string(buf, "%!");
|
buffer_write_string(buf, "%!");
|
||||||
buffer_write_rune(buf, verb);
|
buffer_write_rune(buf, verb);
|
||||||
buffer_write_byte(buf, '(');
|
buffer_write_byte(buf, '(');
|
||||||
@@ -527,9 +551,8 @@ fmt_int :: proc(fi: ^Fmt_Info, u: u64, signed: bool, verb: rune) {
|
|||||||
fmt_float :: proc(fi: ^Fmt_Info, v: f64, bits: int, verb: rune) {
|
fmt_float :: proc(fi: ^Fmt_Info, v: f64, bits: int, verb: rune) {
|
||||||
// TODO(bill): Actually print a float correctly
|
// TODO(bill): Actually print a float correctly
|
||||||
// THIS IS FUCKING SHIT!
|
// THIS IS FUCKING SHIT!
|
||||||
|
|
||||||
match verb {
|
match verb {
|
||||||
case 'e', 'E', 'f', 'F', 'g', 'G':
|
case 'e', 'E', 'f', 'F', 'g', 'G', 'v':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fmt_bad_verb(fi, verb);
|
fmt_bad_verb(fi, verb);
|
||||||
@@ -553,8 +576,9 @@ fmt_float :: proc(fi: ^Fmt_Info, v: f64, bits: int, verb: rune) {
|
|||||||
buffer_write_byte(fi.buf, '.');
|
buffer_write_byte(fi.buf, '.');
|
||||||
|
|
||||||
decimal_places := 5;
|
decimal_places := 5;
|
||||||
if bits == 64 {
|
match bits {
|
||||||
decimal_places = 9;
|
case 32: decimal_places = 7;
|
||||||
|
case 64: decimal_places = 15;
|
||||||
}
|
}
|
||||||
if fi.prec_set {
|
if fi.prec_set {
|
||||||
decimal_places = fi.prec;
|
decimal_places = fi.prec;
|
||||||
@@ -570,7 +594,7 @@ fmt_float :: proc(fi: ^Fmt_Info, v: f64, bits: int, verb: rune) {
|
|||||||
}
|
}
|
||||||
fmt_string :: proc(fi: ^Fmt_Info, s: string, verb: rune) {
|
fmt_string :: proc(fi: ^Fmt_Info, s: string, verb: rune) {
|
||||||
match verb {
|
match verb {
|
||||||
case 'v', 's':
|
case 's', 'v':
|
||||||
buffer_write_string(fi.buf, s);
|
buffer_write_string(fi.buf, s);
|
||||||
default:
|
default:
|
||||||
fmt_bad_verb(fi, verb);
|
fmt_bad_verb(fi, verb);
|
||||||
@@ -591,6 +615,69 @@ fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) {
|
|||||||
fmt_integer(fi, u, 16, false, __DIGITS_UPPER);
|
fmt_integer(fi, u, 16, false, __DIGITS_UPPER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||||
|
if v.type_info == nil || v.data == nil {
|
||||||
|
buffer_write_string(fi.buf, "<nil>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using Type_Info;
|
||||||
|
match type e : v.type_info {
|
||||||
|
default:
|
||||||
|
fmt_bad_verb(fi, verb);
|
||||||
|
return;
|
||||||
|
case Enum:
|
||||||
|
match verb {
|
||||||
|
case 'd', 'f':
|
||||||
|
fmt_arg(fi, any{type_info_base(e.base), v.data}, verb);
|
||||||
|
case 's', 'v':
|
||||||
|
i: i64;
|
||||||
|
f: f64;
|
||||||
|
ok := false;
|
||||||
|
a := any{type_info_base(e.base), v.data};
|
||||||
|
match type v : a {
|
||||||
|
case i8: i = v as i64;
|
||||||
|
case i16: i = v as i64;
|
||||||
|
case i32: i = v as i64;
|
||||||
|
case i64: i = v as i64;
|
||||||
|
case int: i = v as i64;
|
||||||
|
case u8: i = v as i64;
|
||||||
|
case u16: i = v as i64;
|
||||||
|
case u32: i = v as i64;
|
||||||
|
case u64: i = v as i64;
|
||||||
|
case uint: i = v as i64;
|
||||||
|
case f32: f = v as f64;
|
||||||
|
case f64: f = v as f64;
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_type_integer(e.base) {
|
||||||
|
for val, idx : e.values {
|
||||||
|
if val.i == i {
|
||||||
|
buffer_write_string(fi.buf, e.names[idx]);
|
||||||
|
ok = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for val, idx : e.values {
|
||||||
|
if val.f == f {
|
||||||
|
buffer_write_string(fi.buf, e.names[idx]);
|
||||||
|
ok = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
buffer_write_string(fi.buf, "!%(BAD ENUM VALUE)");
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fmt_bad_verb(fi, verb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||||
if v.data == nil || v.type_info == nil {
|
if v.data == nil || v.type_info == nil {
|
||||||
@@ -728,7 +815,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
|||||||
buffer_write_string(fi.buf, "(raw_union)");
|
buffer_write_string(fi.buf, "(raw_union)");
|
||||||
|
|
||||||
case Enum:
|
case Enum:
|
||||||
fmt_arg(fi, any{info.base, v.data}, verb);
|
fmt_enum(fi, v, verb);
|
||||||
|
|
||||||
case Procedure:
|
case Procedure:
|
||||||
buffer_write_type(fi.buf, v.type_info);
|
buffer_write_type(fi.buf, v.type_info);
|
||||||
|
|||||||
@@ -1616,7 +1616,6 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
|
|||||||
switch (index) {
|
switch (index) {
|
||||||
case 0: result_type = make_type_pointer(a, make_type_pointer(a, t->Slice.elem)); break;
|
case 0: result_type = make_type_pointer(a, make_type_pointer(a, t->Slice.elem)); break;
|
||||||
case 1: result_type = make_type_pointer(a, t_int); break;
|
case 1: result_type = make_type_pointer(a, t_int); break;
|
||||||
case 2: result_type = make_type_pointer(a, t_int); break;
|
|
||||||
}
|
}
|
||||||
} else if (is_type_string(t)) {
|
} else if (is_type_string(t)) {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
@@ -1786,9 +1785,6 @@ irValue *ir_array_len(irProcedure *proc, irValue *array) {
|
|||||||
GB_ASSERT(t->kind == Type_Array);
|
GB_ASSERT(t->kind == Type_Array);
|
||||||
return ir_make_const_int(proc->module->allocator, t->Array.count);
|
return ir_make_const_int(proc->module->allocator, t->Array.count);
|
||||||
}
|
}
|
||||||
irValue *ir_array_cap(irProcedure *proc, irValue *array) {
|
|
||||||
return ir_array_len(proc, array);
|
|
||||||
}
|
|
||||||
|
|
||||||
irValue *ir_slice_elem(irProcedure *proc, irValue *slice) {
|
irValue *ir_slice_elem(irProcedure *proc, irValue *slice) {
|
||||||
Type *t = ir_type(slice);
|
Type *t = ir_type(slice);
|
||||||
@@ -2855,7 +2851,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|||||||
|
|
||||||
case BuiltinProc_new_slice: {
|
case BuiltinProc_new_slice: {
|
||||||
ir_emit_comment(proc, str_lit("new_slice"));
|
ir_emit_comment(proc, str_lit("new_slice"));
|
||||||
// new_slice :: proc(Type, len: int[, cap: int]) -> ^Type
|
// new_slice :: proc(Type, len: int) -> ^Type
|
||||||
gbAllocator allocator = proc->module->allocator;
|
gbAllocator allocator = proc->module->allocator;
|
||||||
|
|
||||||
Type *type = type_of_expr(proc->module->info, ce->args.e[0]);
|
Type *type = type_of_expr(proc->module->info, ce->args.e[0]);
|
||||||
@@ -3226,7 +3222,6 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|||||||
ir_emit_store(proc, slice_elem, base_elem);
|
ir_emit_store(proc, slice_elem, base_elem);
|
||||||
irValue *len = ir_make_const_int(allocator, slice_len);
|
irValue *len = ir_make_const_int(allocator, slice_len);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, slice, 1), len);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, slice, 1), len);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, slice, 2), len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_count = type->param_count;
|
arg_count = type->param_count;
|
||||||
@@ -5664,11 +5659,9 @@ void ir_gen_tree(irGen *s) {
|
|||||||
|
|
||||||
irValue *elem = ir_emit_struct_ep(proc, slice, 0);
|
irValue *elem = ir_emit_struct_ep(proc, slice, 0);
|
||||||
irValue *len = ir_emit_struct_ep(proc, slice, 1);
|
irValue *len = ir_emit_struct_ep(proc, slice, 1);
|
||||||
irValue *cap = ir_emit_struct_ep(proc, slice, 2);
|
|
||||||
|
|
||||||
ir_emit_store(proc, elem, memory);
|
ir_emit_store(proc, elem, memory);
|
||||||
ir_emit_store(proc, len, field_count);
|
ir_emit_store(proc, len, field_count);
|
||||||
ir_emit_store(proc, cap, field_count);
|
|
||||||
} break;
|
} break;
|
||||||
case TypeRecord_Union:
|
case TypeRecord_Union:
|
||||||
tag = ir_emit_conv(proc, ti_ptr, t_type_info_union_ptr);
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_union_ptr);
|
||||||
@@ -5713,11 +5706,9 @@ void ir_gen_tree(irGen *s) {
|
|||||||
|
|
||||||
irValue *elem = ir_emit_struct_ep(proc, slice, 0);
|
irValue *elem = ir_emit_struct_ep(proc, slice, 0);
|
||||||
irValue *len = ir_emit_struct_ep(proc, slice, 1);
|
irValue *len = ir_emit_struct_ep(proc, slice, 1);
|
||||||
irValue *cap = ir_emit_struct_ep(proc, slice, 2);
|
|
||||||
|
|
||||||
ir_emit_store(proc, elem, memory);
|
ir_emit_store(proc, elem, memory);
|
||||||
ir_emit_store(proc, len, field_count);
|
ir_emit_store(proc, len, field_count);
|
||||||
ir_emit_store(proc, cap, field_count);
|
|
||||||
} break;
|
} break;
|
||||||
case TypeRecord_Enum:
|
case TypeRecord_Enum:
|
||||||
tag = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr);
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr);
|
||||||
@@ -5791,14 +5782,12 @@ void ir_gen_tree(irGen *s) {
|
|||||||
|
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, names, 0), name_array_elem);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, names, 0), name_array_elem);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, names, 1), v_count);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, names, 1), v_count);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, names, 2), v_count);
|
|
||||||
|
|
||||||
irValue *values = ir_emit_struct_ep(proc, tag, 2);
|
irValue *values = ir_emit_struct_ep(proc, tag, 2);
|
||||||
irValue *value_array_elem = ir_array_elem(proc, value_array);
|
irValue *value_array_elem = ir_array_elem(proc, value_array);
|
||||||
|
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, values, 0), value_array_elem);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, values, 0), value_array_elem);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, values, 1), v_count);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, values, 1), v_count);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, values, 2), v_count);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -5837,11 +5826,9 @@ void ir_gen_tree(irGen *s) {
|
|||||||
|
|
||||||
irValue *elem = ir_emit_struct_ep(proc, slice, 0);
|
irValue *elem = ir_emit_struct_ep(proc, slice, 0);
|
||||||
irValue *len = ir_emit_struct_ep(proc, slice, 1);
|
irValue *len = ir_emit_struct_ep(proc, slice, 1);
|
||||||
irValue *cap = ir_emit_struct_ep(proc, slice, 2);
|
|
||||||
|
|
||||||
ir_emit_store(proc, elem, memory);
|
ir_emit_store(proc, elem, memory);
|
||||||
ir_emit_store(proc, len, variable_count);
|
ir_emit_store(proc, len, variable_count);
|
||||||
ir_emit_store(proc, cap, variable_count);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Type_Proc: {
|
case Type_Proc: {
|
||||||
|
|||||||
Reference in New Issue
Block a user