Browse Source

Clean up _preload.odin types

Ginger Bill 8 years ago
parent
commit
3868a9a0f0
7 changed files with 70 additions and 108 deletions
  1. 26 29
      core/_preload.odin
  2. 3 42
      core/fmt.odin
  3. 4 4
      core/mem.odin
  4. 2 2
      src/check_expr.cpp
  5. 6 4
      src/ir.cpp
  6. 17 8
      src/parser.cpp
  7. 12 19
      src/types.cpp

+ 26 - 29
core/_preload.odin

@@ -17,12 +17,14 @@ import (
 // Local Variables:    snake_case
 // Constant Variables: SCREAMING_SNAKE_CASE
 
+
+
+
 // IMPORTANT NOTE(bill): `type_info` cannot be used within a
 // #shared_global_scope due to  the internals of the compiler.
 // This could change at a later date if the all these data structures are
 // implemented within the compiler rather than in this "preload" file
 
-
 // NOTE(bill): This must match the compiler's
 CallingConvention :: enum {
 	Invalid         = 0,
@@ -81,13 +83,7 @@ TypeInfo :: struct #ordered {
 	Struct       :: Record;
 	RawUnion     :: Record;
 	Union :: struct #ordered {
-		common_fields: struct #ordered {
-			types:     []^TypeInfo;
-			names:     []string;
-			offsets:   []int;    // offsets may not be used in tuples
-		};
-		variant_names: []string;
-		variant_types: []^TypeInfo;
+		variants: []^TypeInfo;
 	};
 	Enum :: struct #ordered {
 		base:   ^TypeInfo;
@@ -145,17 +141,19 @@ __argv__: ^^u8;
 __argc__: i32;
 
 // IMPORTANT NOTE(bill): Must be in this order (as the compiler relies upon it)
-AllocatorMode :: enum u8 {
-	Alloc,
-	Free,
-	FreeAll,
-	Resize,
-}
-AllocatorProc :: proc(allocator_data: rawptr, mode: AllocatorMode,
-                      size, alignment: int,
-                      old_memory: rawptr, old_size: int, flags: u64 = 0) -> rawptr;
+
 Allocator :: struct #ordered {
-	procedure: AllocatorProc;
+	Mode :: enum u8 {
+		Alloc,
+		Free,
+		FreeAll,
+		Resize,
+	}
+	Proc :: proc(allocator_data: rawptr, mode: Mode,
+	             size, alignment: int,
+	             old_memory: rawptr, old_size: int, flags: u64 = 0) -> rawptr;
+
+	procedure: Proc;
 	data:      rawptr;
 }
 
@@ -283,26 +281,26 @@ __check_context :: proc() {
 
 alloc :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr #inline {
 	a := context.allocator;
-	return a.procedure(a.data, AllocatorMode.Alloc, size, alignment, nil, 0, 0);
+	return a.procedure(a.data, Allocator.Mode.Alloc, size, alignment, nil, 0, 0);
 }
 
 free_ptr_with_allocator :: proc(a: Allocator, ptr: rawptr) #inline {
 	if ptr == nil do return;
 	if a.procedure == nil do return;
-	a.procedure(a.data, AllocatorMode.Free, 0, 0, ptr, 0, 0);
+	a.procedure(a.data, Allocator.Mode.Free, 0, 0, ptr, 0, 0);
 }
 
 free_ptr :: proc(ptr: rawptr) #inline do free_ptr_with_allocator(context.allocator, ptr);
 
 free_all :: proc() #inline {
 	a := context.allocator;
-	a.procedure(a.data, AllocatorMode.FreeAll, 0, 0, nil, 0, 0);
+	a.procedure(a.data, Allocator.Mode.FreeAll, 0, 0, nil, 0, 0);
 }
 
 
 resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr #inline {
 	a := context.allocator;
-	return a.procedure(a.data, AllocatorMode.Resize, new_size, alignment, ptr, old_size, 0);
+	return a.procedure(a.data, Allocator.Mode.Resize, new_size, alignment, ptr, old_size, 0);
 }
 
 
@@ -403,7 +401,7 @@ reserve :: proc(array: ^[dynamic]$T, capacity: int) -> bool {
 	new_size  := capacity * size_of(T);
 	allocator := a.allocator;
 
-	new_data := allocator.procedure(allocator.data, AllocatorMode.Resize, new_size, align_of(T), a.data, old_size, 0);
+	new_data := allocator.procedure(allocator.data, Allocator.Mode.Resize, new_size, align_of(T), a.data, old_size, 0);
 	if new_data == nil do return false;
 
 	a.data = new_data;
@@ -503,10 +501,10 @@ default_resize_align :: proc(old_memory: rawptr, old_size, new_size, alignment:
 }
 
 
-default_allocator_proc :: proc(allocator_data: rawptr, mode: AllocatorMode,
+default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator.Mode,
                             size, alignment: int,
                             old_memory: rawptr, old_size: int, flags: u64) -> rawptr {
-	using AllocatorMode;
+	using Allocator.Mode;
 
 	match mode {
 	case Alloc:
@@ -715,7 +713,7 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap:
 	new_size  := cap * elem_size;
 	allocator := array.allocator;
 
-	new_data := allocator.procedure(allocator.data, AllocatorMode.Resize, new_size, elem_align, array.data, old_size, 0);
+	new_data := allocator.procedure(allocator.data, Allocator.Mode.Resize, new_size, elem_align, array.data, old_size, 0);
 	if new_data == nil do return false;
 
 	array.data = new_data;
@@ -736,9 +734,8 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
                                items: rawptr, item_count: int) -> int {
 	array := ^raw.DynamicArray(array_);
 
-	if item_count <= 0 || items == nil {
-		return array.len;
-	}
+	if items == nil    do return 0;
+	if item_count <= 0 do return 0;
 
 
 	ok := true;

+ 3 - 42
core/fmt.odin

@@ -295,32 +295,9 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
 
 	case Union:
 		write_string(buf, "union {");
-		cf := info.common_fields;
-		total_count := 0;
-		for name, i in cf.names {
+		for variant, i in info.variants {
 			if i > 0 do write_string(buf, ", ");
-			write_string(buf, name);
-			write_string(buf, ": ");
-			write_type(buf, cf.types[i]);
-			total_count++;
-		}
-		for name, i in info.variant_names {
-			if total_count > 0 || i > 0 do write_string(buf, ", ");
-			write_string(buf, name);
-			write_byte(buf, '{');
-			defer write_byte(buf, '}');
-
-			variant_type := type_info_base(info.variant_types[i]).variant;
-			variant := (&variant_type).(Struct);
-
-			vc := len(variant.names)-len(cf.names);
-			for j in 0..vc {
-				if j > 0 do write_string(buf, ", ");
-				index := j + len(cf.names);
-				write_string(buf, variant.names[index]);
-				write_string(buf, ": ");
-				write_type(buf, variant.types[index]);
-			}
+			write_type(buf, variant);
 		}
 		write_string(buf, "}");
 
@@ -897,23 +874,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
 		}
 
 	case Union:
-		write_byte(fi.buf, '{');
-		defer write_byte(fi.buf, '}');
-
-		cf := info.common_fields;
-		for _, i in cf.names {
-			if i > 0 do write_string(fi.buf, ", ");
-
-			write_string(fi.buf, cf.names[i]);
-			write_string(fi.buf, " = ");
-
-			if t := cf.types[i]; types.is_any(t) {
-				write_string(fi.buf, "any{}");
-			} else {
-				data := ^u8(v.data) + cf.offsets[i];
-				fmt_arg(fi, any{rawptr(data), t}, 'v');
-			}
-		}
+		write_string(fi.buf, "(union)");
 
 	case RawUnion:
 		write_string(fi.buf, "(raw_union)");

+ 4 - 4
core/mem.odin

@@ -137,10 +137,10 @@ arena_allocator :: proc(arena: ^Arena) -> Allocator {
 	};
 }
 
-arena_allocator_proc :: proc(allocator_data: rawptr, mode: AllocatorMode,
-                          size, alignment: int,
-                          old_memory: rawptr, old_size: int, flags: u64) -> rawptr {
-	using AllocatorMode;
+arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator.Mode,
+                             size, alignment: int,
+                             old_memory: rawptr, old_size: int, flags: u64) -> rawptr {
+	using Allocator.Mode;
 	arena := ^Arena(allocator_data);
 
 	match mode {

+ 2 - 2
src/check_expr.cpp

@@ -6837,14 +6837,14 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
 
 			o->type = t;
 			o->mode = Addressing_OptionalOk;
-		} else if (is_type_any(o->type)) {
+		} else if (is_type_any(src)) {
 			o->type = t;
 			o->mode = Addressing_OptionalOk;
 
 			add_type_info_type(c, o->type);
 			add_type_info_type(c, t);
 		} else {
-			error(o->expr, "Type assertions can only operate on unions");
+			error(o->expr, "Type assertions can only operate on unions and `any`");
 			o->mode = Addressing_Invalid;
 			o->expr = node;
 			return kind;

+ 6 - 4
src/ir.cpp

@@ -3339,6 +3339,11 @@ irValue *ir_emit_union_cast(irProcedure *proc, irValue *value, Type *type, Token
 irAddr ir_emit_any_cast_addr(irProcedure *proc, irValue *value, Type *type, TokenPos pos) {
 	gbAllocator a = proc->module->allocator;
 	Type *src_type = ir_type(value);
+
+	if (is_type_pointer(src_type)) {
+		value = ir_emit_load(proc, value);
+	}
+
 	bool is_tuple = true;
 	Type *tuple = type;
 	if (type->kind != Type_Tuple) {
@@ -8049,11 +8054,9 @@ void ir_gen_tree(irGen *s) {
 					tag = ir_emit_conv(proc, variant_ptr, t_type_info_union_ptr);
 
 					{
-						irValue *variant_names = ir_emit_struct_ep(proc, tag, 1);
-						irValue *variant_types = ir_emit_struct_ep(proc, tag, 2);
+						irValue *variant_types = ir_emit_struct_ep(proc, tag, 0);
 
 						isize variant_count = gb_max(0, t->Union.variant_count-1);
-						irValue *memory_names = ir_type_info_member_names_offset(proc, variant_count);
 						irValue *memory_types = ir_type_info_member_types_offset(proc, variant_count);
 
 						// NOTE(bill): Zeroth is nil so ignore it
@@ -8067,7 +8070,6 @@ void ir_gen_tree(irGen *s) {
 						}
 
 						irValue *count = ir_const_int(a, variant_count);
-						ir_fill_slice(proc, variant_names, memory_names, count, count);
 						ir_fill_slice(proc, variant_types, memory_types, count, count);
 					}
 

+ 17 - 8
src/parser.cpp

@@ -4134,20 +4134,29 @@ AstNode *parse_match_stmt(AstFile *f) {
 	if (f->curr_token.kind != Token_OpenBrace) {
 		isize prev_level = f->expr_level;
 		f->expr_level = -1;
+		defer (f->expr_level = prev_level);
+
+		if (allow_token(f, Token_in)) {
+			Array<AstNode *> lhs = {};
+			Array<AstNode *> rhs = make_ast_node_array(f, 1);
+			array_add(&rhs, parse_expr(f, false));
 
-		tag = parse_simple_stmt(f, StmtAllowFlag_In);
-		if (tag->kind == AstNode_AssignStmt && tag->AssignStmt.op.kind == Token_in) {
+			tag = ast_assign_stmt(f, token, lhs, rhs);
 			is_type_match = true;
 		} else {
-			if (allow_token(f, Token_Semicolon)) {
-				init = tag;
-				tag = nullptr;
-				if (f->curr_token.kind != Token_OpenBrace) {
-					tag = parse_simple_stmt(f, StmtAllowFlag_None);
+			tag = parse_simple_stmt(f, StmtAllowFlag_In);
+			if (tag->kind == AstNode_AssignStmt && tag->AssignStmt.op.kind == Token_in) {
+				is_type_match = true;
+			} else {
+				if (allow_token(f, Token_Semicolon)) {
+					init = tag;
+					tag = nullptr;
+					if (f->curr_token.kind != Token_OpenBrace) {
+						tag = parse_simple_stmt(f, StmtAllowFlag_None);
+					}
 				}
 			}
 		}
-		f->expr_level = prev_level;
 	}
 	open = expect_token(f, Token_OpenBrace);
 

+ 12 - 19
src/types.cpp

@@ -84,23 +84,13 @@ struct TypeRecord {
 
 	// All record types
 	// Theses are arrays
-	// Entity_Variable - struct/raw_union/union (for common fields)
-	// Entity_Constant - enum
+	// Entity_Variable - struct/raw_union (for common fields)
 	Entity **fields;
 	i32      field_count; // == struct_offsets count
 	Entity **fields_in_src_order; // Entity_Variable
 	AstNode *node;
 	Scope *  scope;
 
-	// Entity_TypeName - union
-	// Type **  variants;
-	// i32      variant_count;
-	// Entity * union__tag;
-	// i64      variant_block_size; // NOTE(bill): Internal use only
-
-	// Type *   variant_parent;
-	// i32      variant_index;
-
 	i64 *    offsets;
 	bool     are_offsets_set;
 	bool     are_offsets_being_processed;
@@ -109,11 +99,6 @@ struct TypeRecord {
 
 	i64      custom_align; // NOTE(bill): Only used in structs at the moment
 	Entity * names;
-
-	// Type *   enum_base_type;
-	// Entity * enum_count;
-	// Entity * enum_min_value;
-	// Entity * enum_max_value;
 };
 
 #define TYPE_KINDS                                        \
@@ -144,8 +129,6 @@ struct TypeRecord {
 		Scope *  scope;                                   \
 		Entity * union__tag;                              \
 		i64      variant_block_size;                      \
-		Type *   variant_parent;                          \
-		i32      variant_index;                           \
 		i64      custom_align;                            \
 	})                                                    \
 	TYPE_KIND(Named, struct {                             \
@@ -1559,14 +1542,24 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
 	}
 
 	if (is_type) {
-		if (type->kind == Type_Record) {
+		switch (type->kind) {
+		case Type_Record:
 			if (type->Record.names != nullptr &&
 			    field_name == "names") {
 				sel.entity = type->Record.names;
 				return sel;
 			}
+			break;
+		case Type_Enum:
+			if (type->Enum.names != nullptr &&
+			    field_name == "names") {
+				sel.entity = type->Enum.names;
+				return sel;
+			}
+			break;
 		}
 
+
 		if (is_type_enum(type)) {
 			// NOTE(bill): These may not have been added yet, so check in case
 			if (type->Enum.count != nullptr) {