Ginger Bill 8 years ago
parent
commit
8987a6630c
5 changed files with 66 additions and 44 deletions
  1. 10 11
      code/demo.odin
  2. 6 4
      src/check_decl.cpp
  3. 46 26
      src/check_expr.cpp
  4. 1 0
      src/main.cpp
  5. 3 3
      src/parser.cpp

+ 10 - 11
code/demo.odin

@@ -66,6 +66,7 @@ general_stuff :: proc() {
 		}
 		f := Foo{137, true};
 		x, b := expand_to_tuple(f);
+		fmt.println(f);
 		fmt.println(x, b);
 		fmt.println(expand_to_tuple(f));
 	}
@@ -371,7 +372,7 @@ parametric_polymorphism :: proc() {
 		return t;
 	}
 
-	copy :: proc(dst, src: []$T) -> int {
+	copy_slice :: proc(dst, src: []$T) -> int {
 		n := min(len(dst), len(src));
 		if n > 0 {
 			mem.copy(&dst[0], &src[0], n*size_of(T));
@@ -553,7 +554,7 @@ threading_example :: proc() {
 			for iteration in 1...5 {
 				fmt.printf("Thread %d is on iteration %d\n", t.user_index, iteration);
 				fmt.printf("`%s`: iteration %d\n", prefix_table[t.user_index], iteration);
-				win32.sleep(1);
+				// win32.sleep(1);
 			}
 			return 0;
 		}
@@ -588,15 +589,13 @@ threading_example :: proc() {
 
 
 main :: proc() {
-when false {
-	if true {
-		fmt.println("\ngeneral_stuff:");              general_stuff();
-		fmt.println("\nnested_struct_declarations:"); nested_struct_declarations();
-		fmt.println("\ndefault_struct_values:");      default_struct_values();
-		fmt.println("\nunion_type:");                 union_type();
-		fmt.println("\nparametric_polymorphism:");    parametric_polymorphism();
+	when true {
+		fmt.println("\n# general_stuff");              general_stuff();
+		fmt.println("\n# nested_struct_declarations"); nested_struct_declarations();
+		fmt.println("\n# default_struct_values");      default_struct_values();
+		fmt.println("\n# union_type");                 union_type();
+		fmt.println("\n# parametric_polymorphism");    parametric_polymorphism();
+		fmt.println("\n# threading_example");          threading_example();
 	}
-	fmt.println("\nthreading_example:");           threading_example();
-}
 }
 

+ 6 - 4
src/check_decl.cpp

@@ -711,8 +711,11 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
 			bool is_immutable = e->Variable.is_immutable;
 			String name = e->token.string;
 			Type *t = base_type(type_deref(e->type));
-			if (is_type_struct(t) || is_type_raw_union(t)) {
-				Scope *scope = scope_of_node(&c->info, t->Struct.node);
+			if (t->kind == Type_Struct) {
+				Scope *scope = t->Struct.scope;
+				if (scope == nullptr) {
+					scope = scope_of_node(&c->info, t->Struct.node);
+				}
 				GB_ASSERT(scope != nullptr);
 				for_array(i, scope->elements.entries) {
 					Entity *f = scope->elements.entries[i].value;
@@ -727,7 +730,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
 					}
 				}
 			} else {
-				error(e->token, "`using` can only be applied to variables of type struct or raw_union");
+				error(e->token, "`using` can only be applied to variables of type struct");
 				break;
 			}
 		}
@@ -749,7 +752,6 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
 	}
 	pop_procedure(c);
 
-
 	check_scope_usage(c, c->context.scope);
 
 	if (decl->parent != nullptr) {

+ 46 - 26
src/check_expr.cpp

@@ -31,6 +31,18 @@ struct PolyProcData {
 	ProcedureInfo proc_info;
 };
 
+struct ValidIndexAndScore {
+	isize index;
+	i64   score;
+};
+
+int valid_index_and_score_cmp(void const *a, void const *b) {
+	i64 si = (cast(ValidIndexAndScore const *)a)->score;
+	i64 sj = (cast(ValidIndexAndScore const *)b)->score;
+	return sj < si ? -1 : sj > si;
+}
+
+
 
 
 #define CALL_ARGUMENT_CHECKER(name) CallArgumentError name(Checker *c, AstNode *call, Type *proc_type, Entity *entity, Array<Operand> operands, CallArgumentErrorMode show_error_mode, CallArgumentData *data)
@@ -4386,44 +4398,61 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 			defer (gb_temp_arena_memory_end(tmp));
 			isize count = t->Union.variants.count;
-			i64 *scores = gb_alloc_array(c->tmp_allocator, i64, count);
-			i32 success_count = 0;
+			ValidIndexAndScore *valids = gb_alloc_array(c->tmp_allocator, ValidIndexAndScore, count);
+			i32 valid_count = 0;
 			i32 first_success_index = -1;
 			for_array(i, t->Union.variants) {
 				Type *vt = t->Union.variants[i];
 				i64 score = 0;
 				if (check_is_assignable_to_with_score(c, operand, vt, &score)) {
-					scores[i] = score;
-					success_count += 1;
+					valids[valid_count].index = i;
+					valids[valid_count].score = score;
+					valid_count += 1;
 					if (first_success_index < 0) {
 						first_success_index = i;
 					}
 				}
 			}
 
+			if (valid_count > 1) {
+				gb_sort_array(valids, valid_count, valid_index_and_score_cmp);
+				i64 best_score = valids[0].score;
+				Type *best_type = t->Union.variants[valids[0].index];
+				for (isize i = 1; i < valid_count; i++) {
+					auto v = valids[i];
+					Type *vt = t->Union.variants[v.index];
+					if (best_score > v.score) {
+						valid_count = i;
+						break;
+					}
+					best_score = v.score;
+				}
+				first_success_index = valids[0].index;
+			}
+
 			gbString type_str = type_to_string(target_type);
 			defer (gb_string_free(type_str));
 
-			if (success_count == 1) {
+			if (valid_count == 1) {
 				operand->mode = Addressing_Value;
 				operand->type = t->Union.variants[first_success_index];
 				target_type = t->Union.variants[first_success_index];
 				break;
-			} else if (success_count > 1) {
+			} else if (valid_count > 1) {
 				GB_ASSERT(first_success_index >= 0);
 				operand->mode = Addressing_Invalid;
 				convert_untyped_error(c, operand, target_type);
 
 				gb_printf_err("Ambiguous type conversion to `%s`, which variant did you mean:\n\t", type_str);
 				i32 j = 0;
-				for (i32 i = first_success_index; i < count; i++) {
-					if (scores[i] == 0) continue;
-					if (j > 0 && success_count > 2) gb_printf_err(", ");
-					if (j == success_count-1) {
-						if (success_count == 2) gb_printf_err(" ");
+				for (i32 i = 0; i < valid_count; i++) {
+					ValidIndexAndScore valid = valids[i];
+					if (j > 0 && valid_count > 2) gb_printf_err(", ");
+					if (j == valid_count-1) {
+						if (valid_count == 2) gb_printf_err(" ");
 						gb_printf_err("or ");
 					}
-					gbString str = type_to_string(t->Union.variants[i]);
+					gbString str = type_to_string(t->Union.variants[valid.index]);
 					gb_printf_err("`%s`", str);
 					gb_string_free(str);
 					j++;
@@ -5988,16 +6017,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 }
 
 
-struct ValidProcAndScore {
-	isize index;
-	i64   score;
-};
 
-int valid_proc_and_score_cmp(void const *a, void const *b) {
-	i64 si = (cast(ValidProcAndScore const *)a)->score;
-	i64 sj = (cast(ValidProcAndScore const *)b)->score;
-	return sj < si ? -1 : sj > si;
-}
 
 
 bool check_unpack_arguments(Checker *c, isize lhs_count, Array<Operand> *operands, Array<AstNode *> rhs, bool allow_ok) {
@@ -6439,10 +6459,10 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
 	if (operand->mode == Addressing_Overload) {
 		GB_ASSERT(operand->overload_entities != nullptr &&
 		          operand->overload_count > 0);
-		isize              overload_count = operand->overload_count;
-		Entity **          procs          = operand->overload_entities;
-		ValidProcAndScore *valids         = gb_alloc_array(heap_allocator(), ValidProcAndScore, overload_count);
-		isize              valid_count    = 0;
+		isize               overload_count = operand->overload_count;
+		Entity **           procs          = operand->overload_entities;
+		ValidIndexAndScore *valids         = gb_alloc_array(heap_allocator(), ValidIndexAndScore, overload_count);
+		isize               valid_count    = 0;
 
 		defer (gb_free(heap_allocator(), procs));
 		defer (gb_free(heap_allocator(), valids));
@@ -6478,7 +6498,7 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
 		}
 
 		if (valid_count > 1) {
-			gb_sort_array(valids, valid_count, valid_proc_and_score_cmp);
+			gb_sort_array(valids, valid_count, valid_index_and_score_cmp);
 			i64 best_score = valids[0].score;
 			Entity *best_entity = procs[valids[0].index];
 			for (isize i = 1; i < valid_count; i++) {

+ 1 - 0
src/main.cpp

@@ -1,4 +1,5 @@
 #define USE_CUSTOM_BACKEND 0
+#define USE_THREADED_PARSER 1
 // #define NO_ARRAY_BOUNDS_CHECK
 
 #include "common.cpp"

+ 3 - 3
src/parser.cpp

@@ -3262,7 +3262,7 @@ AstNode *parse_value_decl(AstFile *f, Array<AstNode *> names, CommentGroup docs)
 	AstNode *type = nullptr;
 	Array<AstNode *> values = {};
 
-	Token colon = expect_token_after(f, Token_Colon, "identifier list");
+	expect_token_after(f, Token_Colon, "identifier list");
 	if (f->curr_token.kind == Token_type) {
 		type = ast_type_type(f, advance_token(f), nullptr);
 		is_mutable = false;
@@ -3378,7 +3378,7 @@ AstNode *parse_simple_stmt(AstFile *f, StmtAllowFlag flags) {
 			switch (next) {
 			case Token_for:
 			case Token_match: {
-				advance_token(f);
+				expect_token_after(f, Token_Colon, "identifier list");
 				AstNode *name = lhs[0];
 				AstNode *label = ast_label_decl(f, ast_node_token(name), name);
 				AstNode *stmt = parse_stmt(f);
@@ -5092,7 +5092,7 @@ ParseFileError parse_files(Parser *p, String init_filename) {
 	p->init_fullpath = init_fullpath;
 
 
-#if 1
+#if USE_THREADED_PARSER
 	isize thread_count = gb_max(build_context.thread_count, 1);
 	if (thread_count > 1) {
 		Array<gbThread> worker_threads = {};