Ginger Bill 8 years ago
parent
commit
9b2f5c359a
5 changed files with 45 additions and 133 deletions
  1. 12 100
      code/demo.odin
  2. 4 4
      src/check_expr.c
  3. 6 6
      src/ir.c
  4. 4 4
      src/ir_print.c
  5. 19 19
      src/types.c

+ 12 - 100
code/demo.odin

@@ -5,107 +5,8 @@
 #import "mem.odin";
 #import "mem.odin";
 #import "opengl.odin";
 #import "opengl.odin";
 #import "os.odin";
 #import "os.odin";
-// #import "halloc.odin";
-
-Token_Kind :: enum {
-}
-Token_Pos :: struct {
-	file:   string,
-	line:   int,
-	column: int,
-}
-Token :: struct {
-	kind:      Token_Kind,
-	name:      string,
-	using pos: Token_Pos,
-}
-
-Exact_Value :: union {
-	Boolean {b: bool},
-	String  {s: string},
-	Integer {i: i64},
-	Float   {f: f64},
-	Pointer {p: i64},
-	Compound{c: rawptr},
-}
-Overload_Kind :: enum {
-	UNKNOWN,
-	NO,
-	YES,
-}
-Scope :: struct {
-	parent:                  ^Scope,
-	prev, next:              ^Scope,
-	first_child, last_child: ^Scope,
-	elements:                map[string]^Entity,
-	implicit:                map[^Entity]bool,
-
-	shared:                  [dynamic]^Scope,
-	imported:                [dynamic]^Scope,
-	is_proc:                 bool,
-	is_global:               bool,
-	is_file:                 bool,
-	is_init:                 bool,
-	has_been_imported:       bool, // This is only applicable to file scopes
-	file:                    rawptr,
-}
-
-Type :: struct {
-}
-
-Entity :: union {
-// Common Fields
-	flags:        u32,
-	using token:  Token,
-	scope:        ^Scope, // Parent's scope
-	type:         ^Type,
-	// identifier:   ^ast.Node,
-
-	using_parent: ^Entity,
-	// using_expr:   ^ast.Node,
-
-// Variants
-	Constant{value: Exact_Value},
-	Variable{
-		field_index, field_src_index:  int,
-		is_immutable, is_thread_local: bool,
-	},
-	Type_Name{},
-	Procedure{
-		is_foreign:      bool,
-		foreign_name:    string,
-		foreign_library: ^Entity,
-		link_name:       string,
-		tags:            u64,
-		overload_kind:   Overload_Kind,
-	},
-	Builtin{id: int},
-	Import_Name{
-		import_path:  string,
-		import_name:  string,
-		import_scope: ^Scope,
-		used:         bool,
-	},
-	Library_Name{
-		library_path: string,
-		library_name: string,
-		used:         bool,
-	},
-	Nil{},
-}
 
 
 main :: proc() {
 main :: proc() {
-	e: Entity;
-	u := union_cast(^Type_Info.Union)type_info_base(type_info_of_val(e));
-
-
-	fmt.println(type_info_base(type_info(Entity)));
-
-
-	// e.flags = 123;
-
-
-/*
 /*
 /*
 	Version 0.1.1
 	Version 0.1.1
 
 
@@ -123,7 +24,14 @@ main :: proc() {
 	 * immutable variables are "completely immutable" - rules need a full explanation
 	 * immutable variables are "completely immutable" - rules need a full explanation
 	 * `slice_to_bytes` - convert any slice to a slice of bytes
 	 * `slice_to_bytes` - convert any slice to a slice of bytes
 	 * `union_cast` allows for optional ok check
 	 * `union_cast` allows for optional ok check
+	 * Record type field `names` (struct/raw_union/enum)
 	 * ?: ternary operator
 	 * ?: ternary operator
+	 * Unions with variants and common fields
+	 * New built-in procedures
+	     - `delete` to delete map entries `delete(m, key)`
+	     - `clear` to clear dynamic maps and arrays `clear(map_or_array)`
+	     - `reserve` to reserve space for the dynamic maps and arrays `reserve(map_or_array)`
+	 * Unexported entities and fields using an underscore prefix
 
 
 	Removed:
 	Removed:
 	 * Maybe/option types
 	 * Maybe/option types
@@ -137,9 +45,14 @@ main :: proc() {
 	 * match x in y {} // For type match statements
 	 * match x in y {} // For type match statements
 	 * Version numbering now starts from 0.1.0 and uses the convention:
 	 * Version numbering now starts from 0.1.0 and uses the convention:
 	 	- major.minor.patch
 	 	- major.minor.patch
+	 * Core library additions to Windows specific stuff
 
 
 	Fixes:
 	Fixes:
 	 * Many fmt.* fixes
 	 * Many fmt.* fixes
+	 * Overloading bug due to comparison of named types
+	 * Overloading bug due to `#import .` collision
+	 * disallow a `cast` from pointers of unions
+	 * Minor bugs in generated IR code for slices
 
 
 	To come very Soon™:
 	To come very Soon™:
 	 * Linux and OS X builds (unofficial ones do exist already)
 	 * Linux and OS X builds (unofficial ones do exist already)
@@ -231,6 +144,5 @@ main :: proc() {
 		compile_assert(size_of([vector 7]i32) == size_of([7]i32));
 		compile_assert(size_of([vector 7]i32) == size_of([7]i32));
 		// align_of([vector 7]i32) != align_of([7]i32) // this may be the case
 		// align_of([vector 7]i32) != align_of([7]i32) // this may be the case
 	}
 	}
-*/
 }
 }
 
 

+ 4 - 4
src/check_expr.c

@@ -490,8 +490,8 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
 
 
 	field_count = check_fields(c, node, st->fields, fields, field_count, str_lit("struct"));
 	field_count = check_fields(c, node, st->fields, fields, field_count, str_lit("struct"));
 
 
-	struct_type->Record.struct_is_packed    = st->is_packed;
-	struct_type->Record.struct_is_ordered   = st->is_ordered;
+	struct_type->Record.is_packed           = st->is_packed;
+	struct_type->Record.is_ordered          = st->is_ordered;
 	struct_type->Record.fields              = fields;
 	struct_type->Record.fields              = fields;
 	struct_type->Record.fields_in_src_order = fields;
 	struct_type->Record.fields_in_src_order = fields;
 	struct_type->Record.field_count         = field_count;
 	struct_type->Record.field_count         = field_count;
@@ -629,8 +629,8 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
 			check_open_scope(c, dummy_struct);
 			check_open_scope(c, dummy_struct);
 			Entity **fields = gb_alloc_array(c->allocator, Entity *, list_count);
 			Entity **fields = gb_alloc_array(c->allocator, Entity *, list_count);
 			isize field_count = check_fields(c, dummy_struct, list, fields, list_count, str_lit("variant"));
 			isize field_count = check_fields(c, dummy_struct, list, fields, list_count, str_lit("variant"));
-			base_type->Record.struct_is_packed    = false;
-			base_type->Record.struct_is_ordered   = true;
+			base_type->Record.is_packed           = false;
+			base_type->Record.is_ordered          = true;
 			base_type->Record.fields              = fields;
 			base_type->Record.fields              = fields;
 			base_type->Record.fields_in_src_order = fields;
 			base_type->Record.fields_in_src_order = fields;
 			base_type->Record.field_count         = field_count;
 			base_type->Record.field_count         = field_count;

+ 6 - 6
src/ir.c

@@ -1832,7 +1832,7 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
 		GB_ASSERT(t->Record.field_count > 0);
 		GB_ASSERT(t->Record.field_count > 0);
 		GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
 		GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
 		result_type = make_type_pointer(a, t->Record.fields[index]->type);
 		result_type = make_type_pointer(a, t->Record.fields[index]->type);
-		i64 offset = t->Record.struct_offsets[index];
+		i64 offset = t->Record.offsets[index];
 		irValue *ptr = ir_emit_conv(proc, s, t_u8_ptr);
 		irValue *ptr = ir_emit_conv(proc, s, t_u8_ptr);
 		ptr = ir_emit_ptr_offset(proc, ptr, ir_make_const_int(a, offset));
 		ptr = ir_emit_ptr_offset(proc, ptr, ir_make_const_int(a, offset));
 		return ir_emit_conv(proc, ptr, result_type);
 		return ir_emit_conv(proc, ptr, result_type);
@@ -1895,7 +1895,7 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
 		GB_ASSERT(t->Record.field_count > 0);
 		GB_ASSERT(t->Record.field_count > 0);
 		GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
 		GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
 		Type *ptr_type = make_type_pointer(a, t->Record.fields[index]->type);
 		Type *ptr_type = make_type_pointer(a, t->Record.fields[index]->type);
-		i64 offset = t->Record.struct_offsets[index];
+		i64 offset = t->Record.offsets[index];
 		irValue *ptr = ir_address_from_load_or_generate_local(proc, s);
 		irValue *ptr = ir_address_from_load_or_generate_local(proc, s);
 		ptr = ir_emit_conv(proc, s, t_u8_ptr);
 		ptr = ir_emit_conv(proc, s, t_u8_ptr);
 		ptr = ir_emit_ptr_offset(proc, ptr, ir_make_const_int(a, offset));
 		ptr = ir_emit_ptr_offset(proc, ptr, ir_make_const_int(a, offset));
@@ -6555,8 +6555,8 @@ void ir_gen_tree(irGen *s) {
 						{
 						{
 							irValue *size         = ir_make_const_int(a,  type_size_of(a, t));
 							irValue *size         = ir_make_const_int(a,  type_size_of(a, t));
 							irValue *align        = ir_make_const_int(a,  type_align_of(a, t));
 							irValue *align        = ir_make_const_int(a,  type_align_of(a, t));
-							irValue *packed       = ir_make_const_bool(a, t->Record.struct_is_packed);
-							irValue *ordered      = ir_make_const_bool(a, t->Record.struct_is_ordered);
+							irValue *packed       = ir_make_const_bool(a, t->Record.is_packed);
+							irValue *ordered      = ir_make_const_bool(a, t->Record.is_ordered);
 							irValue *custom_align = ir_make_const_bool(a, t->Record.custom_align);
 							irValue *custom_align = ir_make_const_bool(a, t->Record.custom_align);
 							ir_emit_store(proc, ir_emit_struct_ep(proc, record, 3), size);
 							ir_emit_store(proc, ir_emit_struct_ep(proc, record, 3), size);
 							ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), align);
 							ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), align);
@@ -6574,7 +6574,7 @@ void ir_gen_tree(irGen *s) {
 							// TODO(bill): Order fields in source order not layout order
 							// TODO(bill): Order fields in source order not layout order
 							Entity *f = t->Record.fields_in_src_order[source_index];
 							Entity *f = t->Record.fields_in_src_order[source_index];
 							irValue *tip = ir_get_type_info_ptr(proc, f->type);
 							irValue *tip = ir_get_type_info_ptr(proc, f->type);
-							i64 foffset = t->Record.struct_offsets[f->Variable.field_index];
+							i64 foffset = t->Record.offsets[f->Variable.field_index];
 							GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
 							GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
 
 
 							irValue *index     = ir_make_const_int(a, source_index);
 							irValue *index     = ir_make_const_int(a, source_index);
@@ -6616,7 +6616,7 @@ void ir_gen_tree(irGen *s) {
 								// TODO(bill): Order fields in source order not layout order
 								// TODO(bill): Order fields in source order not layout order
 								Entity *f = t->Record.fields[field_index];
 								Entity *f = t->Record.fields[field_index];
 								irValue *tip = ir_get_type_info_ptr(proc, f->type);
 								irValue *tip = ir_get_type_info_ptr(proc, f->type);
-								i64 foffset = t->Record.struct_offsets[f->Variable.field_index];
+								i64 foffset = t->Record.offsets[f->Variable.field_index];
 								GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
 								GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
 
 
 								irValue *index     = ir_make_const_int(a, field_index);
 								irValue *index     = ir_make_const_int(a, field_index);

+ 4 - 4
src/ir_print.c

@@ -203,7 +203,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
 	case Type_Record: {
 	case Type_Record: {
 		switch (t->Record.kind) {
 		switch (t->Record.kind) {
 		case TypeRecord_Struct:
 		case TypeRecord_Struct:
-			if (t->Record.struct_is_packed) {
+			if (t->Record.is_packed) {
 				ir_fprintf(f, "<");
 				ir_fprintf(f, "<");
 			}
 			}
 			ir_fprintf(f, "{");
 			ir_fprintf(f, "{");
@@ -220,7 +220,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
 				ir_print_type(f, m, t->Record.fields[i]->type);
 				ir_print_type(f, m, t->Record.fields[i]->type);
 			}
 			}
 			ir_fprintf(f, "}");
 			ir_fprintf(f, "}");
-			if (t->Record.struct_is_packed) {
+			if (t->Record.is_packed) {
 				ir_fprintf(f, ">");
 				ir_fprintf(f, ">");
 			}
 			}
 			return;
 			return;
@@ -526,7 +526,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
 
 
 
 
 
 
-			if (type->Record.struct_is_packed) {
+			if (type->Record.is_packed) {
 				ir_fprintf(f, "<");
 				ir_fprintf(f, "<");
 			}
 			}
 			ir_fprintf(f, "{");
 			ir_fprintf(f, "{");
@@ -543,7 +543,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
 
 
 
 
 			ir_fprintf(f, "}");
 			ir_fprintf(f, "}");
-			if (type->Record.struct_is_packed) {
+			if (type->Record.is_packed) {
 				ir_fprintf(f, ">");
 				ir_fprintf(f, ">");
 			}
 			}
 
 

+ 19 - 19
src/types.c

@@ -88,21 +88,21 @@ typedef struct TypeRecord {
 
 
 	// All record types
 	// All record types
 	// Theses are arrays
 	// Theses are arrays
-	// Entity_Variable - struct/raw_union
+	// Entity_Variable - struct/raw_union/union (for common fields)
 	// Entity_Constant - enum
 	// Entity_Constant - enum
 	Entity **fields;
 	Entity **fields;
 	i32      field_count; // == struct_offsets count
 	i32      field_count; // == struct_offsets count
+	Entity **fields_in_src_order; // Entity_Variable
 	AstNode *node;
 	AstNode *node;
 
 
 	// Entity_TypeName - union
 	// Entity_TypeName - union
 	Entity **variants;
 	Entity **variants;
 	i32      variant_count;
 	i32      variant_count;
 
 
-	i64 *    struct_offsets;
-	bool     struct_are_offsets_set;
-	bool     struct_is_packed;
-	bool     struct_is_ordered;
-	Entity **fields_in_src_order; // Entity_Variable
+	i64 *    offsets;
+	bool     are_offsets_set;
+	bool     is_packed;
+	bool     is_ordered;
 
 
 	i64      custom_align; // NOTE(bill): Only used in structs at the moment
 	i64      custom_align; // NOTE(bill): Only used in structs at the moment
 	Entity * names;
 	Entity * names;
@@ -862,8 +862,8 @@ bool are_types_identical(Type *x, Type *y) {
 				case TypeRecord_Union:
 				case TypeRecord_Union:
 					if (x->Record.field_count == y->Record.field_count &&
 					if (x->Record.field_count == y->Record.field_count &&
 					    x->Record.variant_count == y->Record.variant_count &&
 					    x->Record.variant_count == y->Record.variant_count &&
-					    x->Record.struct_is_packed == y->Record.struct_is_packed &&
-					    x->Record.struct_is_ordered == y->Record.struct_is_ordered &&
+					    x->Record.is_packed == y->Record.is_packed &&
+					    x->Record.is_ordered == y->Record.is_ordered &&
 					    x->Record.custom_align == y->Record.custom_align) {
 					    x->Record.custom_align == y->Record.custom_align) {
 						// TODO(bill); Fix the custom alignment rule
 						// TODO(bill); Fix the custom alignment rule
 						for (isize i = 0; i < x->Record.field_count; i++) {
 						for (isize i = 0; i < x->Record.field_count; i++) {
@@ -1587,7 +1587,7 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
 			}
 			}
 			if (t->Record.field_count > 0) {
 			if (t->Record.field_count > 0) {
 				// TODO(bill): What is this supposed to be?
 				// TODO(bill): What is this supposed to be?
-				if (t->Record.struct_is_packed) {
+				if (t->Record.is_packed) {
 					i64 max = build_context.word_size;
 					i64 max = build_context.word_size;
 					for (isize i = 0; i < t->Record.field_count; i++) {
 					for (isize i = 0; i < t->Record.field_count; i++) {
 						Type *field_type = t->Record.fields[i]->type;
 						Type *field_type = t->Record.fields[i]->type;
@@ -1678,15 +1678,15 @@ i64 *type_set_offsets_of(gbAllocator allocator, Entity **fields, isize field_cou
 bool type_set_offsets(gbAllocator allocator, Type *t) {
 bool type_set_offsets(gbAllocator allocator, Type *t) {
 	t = base_type(t);
 	t = base_type(t);
 	if (is_type_struct(t)) {
 	if (is_type_struct(t)) {
-		if (!t->Record.struct_are_offsets_set) {
-			t->Record.struct_offsets = type_set_offsets_of(allocator, t->Record.fields, t->Record.field_count, t->Record.struct_is_packed);
-			t->Record.struct_are_offsets_set = true;
+		if (!t->Record.are_offsets_set) {
+			t->Record.offsets = type_set_offsets_of(allocator, t->Record.fields, t->Record.field_count, t->Record.is_packed);
+			t->Record.are_offsets_set = true;
 			return true;
 			return true;
 		}
 		}
 	} else if (is_type_union(t)) {
 	} else if (is_type_union(t)) {
-		if (!t->Record.struct_are_offsets_set) {
-			t->Record.struct_offsets = type_set_offsets_of(allocator, t->Record.fields, t->Record.field_count, false);
-			t->Record.struct_are_offsets_set = true;
+		if (!t->Record.are_offsets_set) {
+			t->Record.offsets = type_set_offsets_of(allocator, t->Record.fields, t->Record.field_count, false);
+			t->Record.are_offsets_set = true;
 			return true;
 			return true;
 		}
 		}
 	}  else if (is_type_tuple(t)) {
 	}  else if (is_type_tuple(t)) {
@@ -1812,7 +1812,7 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
 				return FAILURE_SIZE;
 				return FAILURE_SIZE;
 			}
 			}
 			type_set_offsets(allocator, t);
 			type_set_offsets(allocator, t);
-			i64 size = t->Record.struct_offsets[count-1] + type_size_of_internal(allocator, t->Record.fields[count-1]->type, path);
+			i64 size = t->Record.offsets[count-1] + type_size_of_internal(allocator, t->Record.fields[count-1]->type, path);
 			return align_formula(size, align);
 			return align_formula(size, align);
 		} break;
 		} break;
 
 
@@ -1865,7 +1865,7 @@ i64 type_offset_of(gbAllocator allocator, Type *t, i32 index) {
 	if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) {
 	if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) {
 		type_set_offsets(allocator, t);
 		type_set_offsets(allocator, t);
 		if (gb_is_between(index, 0, t->Record.field_count-1)) {
 		if (gb_is_between(index, 0, t->Record.field_count-1)) {
-			return t->Record.struct_offsets[index];
+			return t->Record.offsets[index];
 		}
 		}
 	} else if (t->kind == Type_Tuple) {
 	} else if (t->kind == Type_Tuple) {
 		type_set_offsets(allocator, t);
 		type_set_offsets(allocator, t);
@@ -1989,10 +1989,10 @@ gbString write_type_to_string(gbString str, Type *type) {
 		switch (type->Record.kind) {
 		switch (type->Record.kind) {
 		case TypeRecord_Struct:
 		case TypeRecord_Struct:
 			str = gb_string_appendc(str, "struct");
 			str = gb_string_appendc(str, "struct");
-			if (type->Record.struct_is_packed) {
+			if (type->Record.is_packed) {
 				str = gb_string_appendc(str, " #packed");
 				str = gb_string_appendc(str, " #packed");
 			}
 			}
-			if (type->Record.struct_is_ordered) {
+			if (type->Record.is_ordered) {
 				str = gb_string_appendc(str, " #ordered");
 				str = gb_string_appendc(str, " #ordered");
 			}
 			}
 			str = gb_string_appendc(str, " {");
 			str = gb_string_appendc(str, " {");