Browse Source

Sort enum entities; Remove sprint* from fmt.odin

Ginger Bill 9 years ago
parent
commit
31c11a5037
4 changed files with 91 additions and 80 deletions
  1. 26 3
      code/demo.odin
  2. 39 69
      core/fmt.odin
  3. 5 8
      core/runtime.odin
  4. 21 0
      src/checker/expr.cpp

+ 26 - 3
code/demo.odin

@@ -1,8 +1,31 @@
-// #import "fmt.odin" as fmt
-// #import "os.odin" as os
+#import "fmt.odin" as fmt
+#import "os.odin" as os
 
 
 main :: proc() {
 main :: proc() {
-
+	Fruit :: enum {
+		APPLE,
+		BANANA,
+		GRAPE,
+		MELON,
+		PEACH,
+		TOMATO,
+	}
+
+	fruit_ti := type_info(Fruit)
+	name := (fruit_ti as ^Type_Info.Named).name // Unsafe casts
+	info := type_info_base(fruit_ti) as ^Type_Info.Enum // Unsafe casts
+
+	fmt.printf("% :: enum ", name);
+	fmt.fprint_type(os.stdout, info.base)
+	fmt.printf(" {\n")
+	for i := 0; i < info.values.count; i++ {
+		fmt.printf("\t%\t= %,\n", info.names[i], info.values[i])
+	}
+	fmt.printf("}\n")
+
+	Vector3 :: struct {x, y, z: f32}
+	v := Vector3{x = 1, y = 4, z = 9}
+	fmt.println(v)
 }
 }
 
 
 
 

+ 39 - 69
core/fmt.odin

@@ -2,30 +2,6 @@
 
 
 PRINT_BUF_SIZE :: 1<<12
 PRINT_BUF_SIZE :: 1<<12
 
 
-bprint :: proc(buf: ^[]byte, args: ..any) {
-	prev_string := false
-
-	for i := 0; i < args.count; i++ {
-		arg := args[i]
-		is_string := arg.data != null && type_info_is_string(arg.type_info)
-		if i > 0 && !is_string && !prev_string {
-			print_space_to_buffer(buf)
-		}
-		print_any_to_buffer(buf, arg)
-		prev_string = is_string;
-	}
-}
-
-bprintln :: proc(buf: ^[]byte, args: ..any) {
-	for i := 0; i < args.count; i++ {
-		if i > 0 {
-			append(buf, #rune " ")
-		}
-		print_any_to_buffer(buf, args[i])
-	}
-	print_nl_to_buffer(buf)
-}
-
 fprint :: proc(f: ^os.File, args: ..any) {
 fprint :: proc(f: ^os.File, args: ..any) {
 	data: [PRINT_BUF_SIZE]byte
 	data: [PRINT_BUF_SIZE]byte
 	buf := data[:0]
 	buf := data[:0]
@@ -57,31 +33,6 @@ printf :: proc(fmt: string, args: ..any) {
 	fprintf(os.stdout, fmt, ..args)
 	fprintf(os.stdout, fmt, ..args)
 }
 }
 
 
-sprint :: proc(args: ..any) -> string {
-	data: [PRINT_BUF_SIZE]byte
-	buf := data[:0]
-	bprint(^buf, ..args)
-	s := new_slice(byte, buf.count)
-	copy(s, buf)
-	return s as string
-}
-sprintln :: proc(args: ..any) -> string {
-	data: [PRINT_BUF_SIZE]byte
-	buf := data[:0]
-	bprintln(^buf, ..args)
-	s := new_slice(byte, buf.count)
-	copy(s, buf)
-	return s as string
-}
-sprintf :: proc(fmt: string, args: ..any) -> string {
-	data: [PRINT_BUF_SIZE]byte
-	buf := data[:0]
-	bprintf(^buf, fmt, ..args)
-	s := new_slice(byte, buf.count)
-	copy(s, buf)
-	return s as string
-}
-
 
 
 
 
 fprint_type :: proc(f: ^os.File, info: ^Type_Info) {
 fprint_type :: proc(f: ^os.File, info: ^Type_Info) {
@@ -578,26 +529,6 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any)  {
 	}
 	}
 }
 }
 
 
-type_info_is_string :: proc(info: ^Type_Info) -> bool {
-	using Type_Info
-	if info == null {
-		return false
-	}
-
-	for {
-		match type i : info {
-		case Named:
-			info = i.base
-			continue
-		case String:
-			return true
-		default:
-			return false
-		}
-	}
-	return false
-}
-
 
 
 bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) {
 bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) {
 	is_digit :: proc(r: rune) -> bool #inline {
 	is_digit :: proc(r: rune) -> bool #inline {
@@ -661,3 +592,42 @@ bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) {
 
 
 	print_string_to_buffer(buf, fmt[prev:])
 	print_string_to_buffer(buf, fmt[prev:])
 }
 }
+
+
+bprint :: proc(buf: ^[]byte, args: ..any) {
+	is_type_string :: proc(info: ^Type_Info) -> bool {
+		using Type_Info
+		info = type_info_base(info)
+		if info == null {
+			return false
+		}
+
+		match type i : info {
+		case String:
+			return true
+		}
+		return false
+	}
+
+
+	prev_string := false
+	for i := 0; i < args.count; i++ {
+		arg := args[i]
+		is_string := arg.data != null && is_type_string(arg.type_info)
+		if i > 0 && !is_string && !prev_string {
+			print_space_to_buffer(buf)
+		}
+		print_any_to_buffer(buf, arg)
+		prev_string = is_string;
+	}
+}
+
+bprintln :: proc(buf: ^[]byte, args: ..any) {
+	for i := 0; i < args.count; i++ {
+		if i > 0 {
+			append(buf, #rune " ")
+		}
+		print_any_to_buffer(buf, args[i])
+	}
+	print_nl_to_buffer(buf)
+}

+ 5 - 8
core/runtime.odin

@@ -64,6 +64,9 @@ Type_Info :: union {
 }
 }
 
 
 type_info_base :: proc(info: ^Type_Info) -> ^Type_Info {
 type_info_base :: proc(info: ^Type_Info) -> ^Type_Info {
+	if info == null {
+		return null
+	}
 	for {
 	for {
 		match type i : info {
 		match type i : info {
 		case Type_Info.Named:
 		case Type_Info.Named:
@@ -355,17 +358,11 @@ __default_allocator :: proc() -> Allocator {
 
 
 
 
 __enum_to_string :: proc(info: ^Type_Info, value: i64) -> string {
 __enum_to_string :: proc(info: ^Type_Info, value: i64) -> string {
-	for {
-		match type i : info {
-		case Type_Info.Named:
-			info = i.base
-			continue
-		}
-		break
-	}
+	info = type_info_base(info)
 
 
 	match type ti : info {
 	match type ti : info {
 	case Type_Info.Enum:
 	case Type_Info.Enum:
+		// TODO(bill): Search faster than linearly
 		for i := 0; i < ti.values.count; i++ {
 		for i := 0; i < ti.values.count; i++ {
 			if ti.values[i] == value {
 			if ti.values[i] == value {
 				return ti.names[i]
 				return ti.names[i]

+ 21 - 0
src/checker/expr.cpp

@@ -541,6 +541,25 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node, CycleChec
 	union_type->Record.other_field_count = other_field_count;
 	union_type->Record.other_field_count = other_field_count;
 }
 }
 
 
+GB_COMPARE_PROC(cmp_enum_order) {
+	// Rule:
+	// Biggest to smallest alignment
+	// if same alignment: biggest to smallest size
+	// if same size: order by source order
+	Entity *x = *(Entity **)a;
+	Entity *y = *(Entity **)b;
+	GB_ASSERT(x != NULL);
+	GB_ASSERT(y != NULL);
+	GB_ASSERT(x->kind == Entity_Constant);
+	GB_ASSERT(y->kind == Entity_Constant);
+	GB_ASSERT(x->Constant.value.kind == ExactValue_Integer);
+	GB_ASSERT(y->Constant.value.kind == ExactValue_Integer);
+	i64 i = x->Constant.value.value_integer;
+	i64 j = y->Constant.value.value_integer;
+
+	return i < j ? -1 : i > j;
+}
+
 
 
 
 
 void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *node) {
 void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *node) {
@@ -640,6 +659,8 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
 		add_entity_use(&c->info, f->field, e);
 		add_entity_use(&c->info, f->field, e);
 	}
 	}
 
 
+	gb_sort_array(fields, gb_array_count(et->fields), cmp_enum_order);
+
 	enum_type->Record.other_fields = fields;
 	enum_type->Record.other_fields = fields;
 	enum_type->Record.other_field_count = gb_array_count(et->fields);
 	enum_type->Record.other_field_count = gb_array_count(et->fields);