From 7905c885a2c9b2632b2449c16ee16929ee92f46c Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Mon, 15 Nov 2021 09:28:48 -0600 Subject: [PATCH] fixed a couple of very annoying bugs --- core/container/iter.onyx | 8 +++---- include/astnodes.h | 1 - src/checker.c | 2 +- src/clone.c | 3 +++ src/polymorph.c | 44 +++++++++++++++++++-------------------- src/symres.c | 13 ++++-------- src/wasm_emit.c | 3 +++ tests/lazy_iterators | 10 ++++----- tests/lazy_iterators.onyx | 40 ++++++++++++++++++----------------- 9 files changed, 62 insertions(+), 62 deletions(-) diff --git a/core/container/iter.onyx b/core/container/iter.onyx index fc508515..cb9b372a 100644 --- a/core/container/iter.onyx +++ b/core/container/iter.onyx @@ -22,7 +22,7 @@ filter :: (it: Iterator($T), predicate: (T) -> bool) -> Iterator(T) { filter_iterator.iterator = it; filter_iterator.predicate = predicate; - next :: ($T: type_expr, fi: ^FilterIterator(T)) -> (T, bool) { + next :: (fi: ^FilterIterator($T)) -> (T, bool) { value, cont := fi.iterator.next(fi.iterator.data); if cont { while !fi.predicate(value) { @@ -36,7 +36,7 @@ filter :: (it: Iterator($T), predicate: (T) -> bool) -> Iterator(T) { } } - close :: ($T: type_expr, fi: ^FilterIterator(T)) { + close :: (fi: ^FilterIterator($T)) { if fi.iterator.close != null_proc do fi.iterator.close(fi.iterator.data); cfree(fi); } @@ -58,14 +58,14 @@ map :: (it: Iterator($T), transform: (T) -> $R) -> Iterator(R) { map_iterator.iterator = it; map_iterator.transform = transform; - next :: ($T: type_expr, $R: type_expr, mi: ^MapIterator(T, R)) -> (R, bool) { + next :: (mi: ^MapIterator($T, $R)) -> (R, bool) { value, cont := mi.iterator.next(mi.iterator.data); if !cont do return __zero_value(R), false; return mi.transform(value), true; } - close :: ($T: type_expr, $R: type_expr, mi: ^MapIterator(T, R)) { + close :: (mi: ^MapIterator($T, $R)) { if mi.iterator.close != null_proc do mi.iterator.close(mi.iterator.data); cfree(mi); } diff --git a/include/astnodes.h b/include/astnodes.h index 277a0186..64a620dd 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -951,7 +951,6 @@ struct AstFunction { char* name; - // NOTE: This is NULL, unless this function was generated from a polymorphic // procedure call. Then it is set to the token of the call node. OnyxToken* generated_from; diff --git a/src/checker.c b/src/checker.c index bb586666..e03fe86e 100644 --- a/src/checker.c +++ b/src/checker.c @@ -1926,7 +1926,7 @@ CheckStatus check_function(AstFunction* func) { if (func->flags & Ast_Flag_Has_Been_Checked) return Check_Success; if (func->entity_header && func->entity_header->state < Entity_State_Code_Gen) YIELD(func->token->pos, "Waiting for procedure header to pass type-checking"); - + expected_return_type = &func->type->Function.return_type; if (func->body) { CheckStatus status = check_block(func->body); diff --git a/src/clone.c b/src/clone.c index 753a23e4..b1411deb 100644 --- a/src/clone.c +++ b/src/clone.c @@ -162,6 +162,7 @@ AstNode* ast_clone(bh_allocator a, void* n) { break; case Ast_Kind_Call: + C(AstCall, callee); arguments_deep_clone(a, &((AstCall *) nn)->args, &((AstCall *) node)->args); break; @@ -404,6 +405,7 @@ AstNode* ast_clone(bh_allocator a, void* n) { AstFunction* sf = (AstFunction *) node; if (sf->is_foreign) return node; + assert(df->scope == NULL); df->return_type = (AstType *) ast_clone(a, sf->return_type); df->body = (AstBlock *) ast_clone(a, sf->body); @@ -524,6 +526,7 @@ AstFunction* clone_function_header(bh_allocator a, AstFunction* func) { AstFunction* new_func = onyx_ast_node_new(a, sizeof(AstFunction), func->kind); memmove(new_func, func, sizeof(AstFunction)); + assert(new_func->scope == NULL); new_func->return_type = (AstType *) ast_clone(a, func->return_type); diff --git a/src/polymorph.c b/src/polymorph.c index 51f6da59..dd3c6dff 100644 --- a/src/polymorph.c +++ b/src/polymorph.c @@ -20,11 +20,8 @@ static b32 doing_nested_polymorph_lookup = 0; AstTyped node_that_signals_a_yield = { Ast_Kind_Function, 0 }; static void ensure_polyproc_cache_is_created(AstPolyProc* pp) { - if (pp->concrete_funcs == NULL) { - bh_table_init(global_heap_allocator, pp->concrete_funcs, 16); - - bh_imap_init(&pp->active_queries, global_heap_allocator, 31); - } + if (pp->concrete_funcs == NULL) bh_table_init(global_heap_allocator, pp->concrete_funcs, 16); + if (pp->active_queries.hashes == NULL) bh_imap_init(&pp->active_queries, global_heap_allocator, 31); } void insert_poly_sln_into_scope(Scope* scope, AstPolySolution *sln) { @@ -102,32 +99,32 @@ static char* build_poly_slns_unique_key(bh_arr(AstPolySolution) slns) { // NOTE: This function adds a solidified function to the entity heap for it to be processed // later. It optionally can start the function header entity at the code generation state if // the header has already been processed. -static b32 add_solidified_function_entities(AstSolidifiedFunction solidified_func) { - solidified_func.func->flags |= Ast_Flag_Function_Used; - solidified_func.func->flags |= Ast_Flag_From_Polymorphism; +static b32 add_solidified_function_entities(AstSolidifiedFunction *solidified_func) { + solidified_func->func->flags |= Ast_Flag_Function_Used; + solidified_func->func->flags |= Ast_Flag_From_Polymorphism; Entity func_header_entity = { .state = Entity_State_Resolve_Symbols, .type = Entity_Type_Function_Header, - .function = solidified_func.func, + .function = solidified_func->func, .package = NULL, - .scope = solidified_func.func->poly_scope, + .scope = solidified_func->func->poly_scope, }; Entity func_entity = { .state = Entity_State_Resolve_Symbols, .type = Entity_Type_Function, - .function = solidified_func.func, + .function = solidified_func->func, .package = NULL, - .scope = solidified_func.func->poly_scope, + .scope = solidified_func->func->poly_scope, }; Entity* entity_header = entity_heap_insert(&context.entities, func_header_entity); Entity* entity_body = entity_heap_insert(&context.entities, func_entity); - solidified_func.func_header_entity = entity_header; - solidified_func.func->entity_header = entity_header; - solidified_func.func->entity_body = entity_body; + solidified_func->func_header_entity = entity_header; + solidified_func->func->entity_header = entity_header; + solidified_func->func->entity_body = entity_body; return 1; } @@ -179,9 +176,9 @@ static AstSolidifiedFunction generate_solidified_function( return solidified_func; } -static void ensure_solidified_function_has_body(AstPolyProc* pp, AstSolidifiedFunction solidified_func) { - if (solidified_func.func->flags & Ast_Flag_Incomplete_Body) { - clone_function_body(context.ast_alloc, solidified_func.func, pp->base_func); +static void ensure_solidified_function_has_body(AstPolyProc* pp, AstSolidifiedFunction *solidified_func) { + if (solidified_func->func->flags & Ast_Flag_Incomplete_Body) { + clone_function_body(context.ast_alloc, solidified_func->func, pp->base_func); // HACK: I'm asserting that this function should return without an error, because // the only case where it can return an error is if there was a problem with the @@ -190,7 +187,7 @@ static void ensure_solidified_function_has_body(AstPolyProc* pp, AstSolidifiedFu // procedure. assert(add_solidified_function_entities(solidified_func)); - solidified_func.func->flags &= ~Ast_Flag_Incomplete_Body; + solidified_func->func->flags &= ~Ast_Flag_Incomplete_Body; } } @@ -633,6 +630,7 @@ TypeMatch find_polymorphic_sln(AstPolySolution *out, AstPolyParam *param, AstFun // solving for the polymorphic variables, in order to return an array of the solutions for all // of the polymorphic variables. static bh_arr(AstPolySolution) find_polymorphic_slns(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual, OnyxToken *tkn, b32 necessary) { + ensure_polyproc_cache_is_created(pp); if (bh_imap_has(&pp->active_queries, (u64) actual)) { AstPolyQuery *query = (AstPolyQuery *) bh_imap_get(&pp->active_queries, (u64) actual); assert(query->kind == Ast_Kind_Polymorph_Query); @@ -662,6 +660,7 @@ static bh_arr(AstPolySolution) find_polymorphic_slns(AstPolyProc* pp, PolyProcLo query->slns = slns; query->function_header = clone_function_header(context.ast_alloc, pp->base_func); query->function_header->flags |= Ast_Flag_Header_Check_No_Error; + query->function_header->scope = NULL; query->error_on_fail = necessary; query->successful_symres = 1; @@ -703,7 +702,7 @@ AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) // NOTE: If this solution was originally created from a "build_only_header" call, then the body // will not have been or type checked, or anything. This ensures that the body is copied, the // entities are created and entered into the pipeline. - ensure_solidified_function_has_body(pp, solidified_func); + ensure_solidified_function_has_body(pp, &solidified_func); // NOTE: Again, if this came from a "build_only_header" call, then there was no known token and // the "generated_from" member will be null. It is best to set it here so errors reported in that @@ -715,12 +714,11 @@ AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) } AstSolidifiedFunction solidified_func = generate_solidified_function(pp, slns, tkn, 0); + add_solidified_function_entities(&solidified_func); // NOTE: Cache the function for later use, reducing duplicate functions. bh_table_put(AstSolidifiedFunction, pp->concrete_funcs, unique_key, solidified_func); - add_solidified_function_entities(solidified_func); - return (AstFunction *) &node_that_signals_a_yield; } @@ -757,7 +755,7 @@ AstNode* polymorphic_proc_try_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) // made it through the symbol resolution phase. // - brendanfh 2020/12/25 AstPolyProc* new_pp = onyx_ast_node_new(context.ast_alloc, sizeof(AstPolyProc), Ast_Kind_Polymorphic_Proc); - new_pp->token = pp->token; // TODO: Change this to be the solidify->token + new_pp->token = tkn; new_pp->base_func = pp->base_func; new_pp->flags = pp->flags; new_pp->poly_params = pp->poly_params; diff --git a/src/symres.c b/src/symres.c index 85690d2e..12ad701c 100644 --- a/src/symres.c +++ b/src/symres.c @@ -917,7 +917,7 @@ SymresStatus symres_function_header(AstFunction* func) { bh_arr_each(AstParam, param, func->params) { symbol_introduce(curr_scope, param->local->token, (AstNode *) param->local); - + if (param->local->type_node != NULL) { SYMRES(type, ¶m->local->type_node); } @@ -943,9 +943,8 @@ SymresStatus symres_function_header(AstFunction* func) { } SymresStatus symres_function(AstFunction* func) { - if (func->scope == NULL) - func->scope = scope_create(context.ast_alloc, curr_scope, func->token->pos); if (func->entity_header && func->entity_header->state < Entity_State_Check_Types) return Symres_Yield_Macro; + assert(func->scope); scope_enter(func->scope); @@ -1319,11 +1318,7 @@ static SymresStatus symres_polyquery(AstPolyQuery *query) { } void symres_entity(Entity* ent) { - Scope* old_scope = NULL; - if (ent->scope) { - old_scope = curr_scope; - scope_enter(ent->scope); - } + if (ent->scope) scope_enter(ent->scope); report_unresolved_symbols = context.cycle_detected; //(context.entities.type_count[Entity_Type_Static_If] == 0 && @@ -1380,5 +1375,5 @@ void symres_entity(Entity* ent) { ent->state = next_state; } - if (ent->scope) curr_scope = old_scope; + curr_scope = NULL; } diff --git a/src/wasm_emit.c b/src/wasm_emit.c index 5589cb7e..850050f0 100644 --- a/src/wasm_emit.c +++ b/src/wasm_emit.c @@ -2545,12 +2545,14 @@ EMIT_FUNC(expression, AstTyped* expr) { fori (idx, 0, mem_count) WIL(WI_LOCAL_GET, localidx + idx); } else { + assert(localidx & LOCAL_IS_WASM); WIL(WI_LOCAL_GET, localidx); } break; } case Param_Pass_By_Implicit_Pointer: { + assert(localidx & LOCAL_IS_WASM); WIL(WI_LOCAL_GET, localidx); emit_load_instruction(mod, &code, expr->type, 0); break; @@ -2682,6 +2684,7 @@ EMIT_FUNC(expression, AstTyped* expr) { if (field->expr->kind == Ast_Kind_Param) { if (type_get_param_pass(field->expr->type) == Param_Pass_By_Value && !type_is_pointer(field->expr->type)) { u64 localidx = bh_imap_get(&mod->local_map, (u64) field->expr) + field->idx; + assert(localidx & LOCAL_IS_WASM); WIL(WI_LOCAL_GET, localidx); break; } diff --git a/tests/lazy_iterators b/tests/lazy_iterators index 2c7ab48d..24126473 100644 --- a/tests/lazy_iterators +++ b/tests/lazy_iterators @@ -1,9 +1,9 @@ Closing the count iterator... -54 -56 -58 -60 -62 +54.0000 +56.0000 +58.0000 +60.0000 +62.0000 Starting the iteration... 54 56 diff --git a/tests/lazy_iterators.onyx b/tests/lazy_iterators.onyx index 700bf1b5..7eb274a6 100644 --- a/tests/lazy_iterators.onyx +++ b/tests/lazy_iterators.onyx @@ -2,9 +2,8 @@ use package core -count_iterator :: (lo: i32, hi: i32, step := 1) -> Iterator(i32) { - next :: (data: rawptr) -> (i32, bool) { - ci := cast(^CountIterator) data; +count_iterator :: (lo: $T, hi: T, step: T = 1) -> Iterator(T) { + next :: (ci: ^CountIterator($T)) -> (T, bool) { if ci.current > ci.high do return 0, false; defer ci.current += ci.step; @@ -16,36 +15,39 @@ count_iterator :: (lo: i32, hi: i32, step := 1) -> Iterator(i32) { cfree(data); } - CountIterator :: struct { - low, high, step: i32; - current: i32; + CountIterator :: struct (T:type_expr) { + low, high, step: T; + current: T; } - count_iterator := new(CountIterator); + count_iterator := new(CountIterator(T)); count_iterator.low = lo; count_iterator.high = hi; count_iterator.step = step; count_iterator.current = lo; return .{ - data = count_iterator, - next = next, + data = count_iterator, + next = #solidify next {T=T}, close = close, }; } main :: (args: [] cstr) { // Hopefully soon, the following will be possible. - quick_iterator := - count_iterator(1, 10) - |> iter.map((x) => x * 2) - |> iter.filter((x) => x > 10) - |> iter.map((x) => x + 42) - |> iter.take(5) - |> iter.to_array(); - - for v: quick_iterator { - println(v); + + { + quick_iterator := + count_iterator(1.0f, 10.0f) + |> iter.map((x) => x * 2) + |> iter.filter((x) => x > 10) + |> iter.map((x) => x + 42) + |> iter.take(5) + |> iter.to_array(); + + for v: quick_iterator { + println(v); + } } iterator := count_iterator(1, 10) -- 2.25.1