From 8987a6630c8ec43da770dd92c10f6b92e17201f2 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Sun, 30 Jul 2017 22:26:22 +0100 Subject: [PATCH] v0.6.0 --- code/demo.odin | 21 +++++++------- src/check_decl.cpp | 10 ++++--- src/check_expr.cpp | 72 +++++++++++++++++++++++++++++----------------- src/main.cpp | 1 + src/parser.cpp | 6 ++-- 5 files changed, 66 insertions(+), 44 deletions(-) diff --git a/code/demo.odin b/code/demo.odin index b1d1e1490..19869caac 100644 --- a/code/demo.odin +++ b/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(); -} } diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 8b2ab0941..5d0fc5ed3 100644 --- a/src/check_decl.cpp +++ b/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) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index ae7018a8c..60da0dd08 100644 --- a/src/check_expr.cpp +++ b/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 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 *operands, Array 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++) { diff --git a/src/main.cpp b/src/main.cpp index 0dcf16fc2..aa2158e31 100644 --- a/src/main.cpp +++ b/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" diff --git a/src/parser.cpp b/src/parser.cpp index e95b606b1..3ae3f767e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3262,7 +3262,7 @@ AstNode *parse_value_decl(AstFile *f, Array names, CommentGroup docs) AstNode *type = nullptr; Array 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 worker_threads = {};