From 73f930e8bde5599c7a3620ef1702d829423fdb6c Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Wed, 5 Jan 2022 06:59:40 -0600 Subject: [PATCH] making auto polymorphism even better --- core/container/map.onyx | 14 +++++++------- include/astnodes.h | 2 ++ src/clone.c | 17 +++++++++++++++++ src/polymorph.h | 5 +++++ src/symres.c | 15 ++++++++++----- 5 files changed, 41 insertions(+), 12 deletions(-) diff --git a/core/container/map.onyx b/core/container/map.onyx index 7238bf9a..842a2cf2 100644 --- a/core/container/map.onyx +++ b/core/container/map.onyx @@ -71,7 +71,7 @@ free :: (use map: ^Map) { array.free(^entries); } -put :: (use map: ^Map($K, $V), key: map.Key_Type, value: map.Value_Type) { +put :: (use map: ^Map, key: map.Key_Type, value: map.Value_Type) { if map.hashes.data == null do init(map); lr := lookup(map, key); @@ -86,12 +86,12 @@ put :: (use map: ^Map($K, $V), key: map.Key_Type, value: map.Value_Type) { if full(map) do grow(map); } -has :: (use map: ^Map($K, $V), key: K) -> bool { +has :: (use map: ^Map, key: map.Key_Type) -> bool { lr := lookup(map, key); return lr.entry_index >= 0; } -get :: (use map: ^Map($K, $V), key: K) -> V { +get :: (use map: ^Map, key: map.Key_Type) -> map.Value_Type { lr := lookup(map, key); if lr.entry_index >= 0 do return entries[lr.entry_index].value; @@ -102,14 +102,14 @@ get :: (use map: ^Map($K, $V), key: K) -> V { #operator []= macro (map: Map($K, $V), key: K, value: V) do (package core.map).put(^map, key, value); #operator ^[] macro (map: Map($K, $V), key: K) -> ^V do return (package core.map).get_ptr(^map, key); -get_ptr :: (use map: ^Map($K, $V), key: K) -> ^V { +get_ptr :: (use map: ^Map, key: map.Key_Type) -> ^map.Value_Type { lr := lookup(map, key); if lr.entry_index >= 0 do return ^entries[lr.entry_index].value; return null; } -delete :: (use map: ^Map($K, $V), key: K) { +delete :: (use map: ^Map, key: map.Key_Type) { lr := lookup(map, key); if lr.entry_index < 0 do return; @@ -127,7 +127,7 @@ delete :: (use map: ^Map($K, $V), key: K) { else do hashes[last.hash_index] = lr.entry_index; } -update :: macro (map: ^Map($K, $V), key: K, body: Code) { +update :: macro (map: ^Map, key: map.Key_Type, body: Code) { @Hack // Weird hack because 'lookup' exists at file scope. lookup_ :: lookup @@ -166,7 +166,7 @@ format_map :: (output: ^conv.Format_Output, format: ^conv.Format, x: ^Map($K, $V entry_prev : i32 = -1; } - lookup :: (use map: ^Map($K, $V), key: K) -> MapLookupResult { + lookup :: (use map: ^Map, key: map.Key_Type) -> MapLookupResult { if hashes.data == null do init(map); lr := MapLookupResult.{}; diff --git a/include/astnodes.h b/include/astnodes.h index e0761cb1..ff6986b4 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -269,6 +269,8 @@ typedef enum AstFlags { Ast_Flag_Header_Check_No_Error = BH_BIT(19), Ast_Flag_Decl_Followed_By_Init = BH_BIT(20), + + Ast_Flag_Param_Symbol_Dirty = BH_BIT(21), } AstFlags; typedef enum UnaryOp { diff --git a/src/clone.c b/src/clone.c index 448f254d..e1a17afa 100644 --- a/src/clone.c +++ b/src/clone.c @@ -2,9 +2,16 @@ #include "parser.h" #include "utils.h" +// Weird flags that shouldn't be used too often because they complicate things +static b32 dont_copy_structs = 0; + static inline b32 should_clone(AstNode* node) { if (node->flags & Ast_Flag_No_Clone) return 0; + if (dont_copy_structs) { + if (node->kind == Ast_Kind_Struct_Type) return 0; + } + switch (node->kind) { // List of nodes that should not be copied case Ast_Kind_Global: @@ -419,7 +426,12 @@ AstNode* ast_clone(bh_allocator a, void* n) { bh_arr_each(AstParam, param, sf->params) { AstParam new_param = { 0 }; + + dont_copy_structs = 1; new_param.local = (AstLocal *) ast_clone(a, param->local); + new_param.local->flags &= ~Ast_Flag_Param_Symbol_Dirty; + dont_copy_structs = 0; + new_param.default_value = (AstTyped *) ast_clone(a, param->default_value); new_param.vararg_kind = param->vararg_kind; new_param.is_used = param->is_used; @@ -541,7 +553,12 @@ AstFunction* clone_function_header(bh_allocator a, AstFunction* func) { bh_arr_new(global_heap_allocator, new_func->params, bh_arr_length(func->params)); bh_arr_each(AstParam, param, func->params) { AstParam new_param; + + dont_copy_structs = 1; new_param.local = (AstLocal *) ast_clone(a, param->local); + new_param.local->flags &= ~Ast_Flag_Param_Symbol_Dirty; + dont_copy_structs = 0; + new_param.default_value = (AstTyped *) ast_clone(a, param->default_value); new_param.vararg_kind = param->vararg_kind; new_param.is_used = param->is_used; diff --git a/src/polymorph.h b/src/polymorph.h index af03de6d..64ecbe04 100644 --- a/src/polymorph.h +++ b/src/polymorph.h @@ -926,6 +926,11 @@ b32 potentially_convert_function_to_polyproc(AstFunction *func) { } convert_function_to_polyproc(func); + + bh_arr_each(AstParam, param, func->params) { + param->local->flags |= Ast_Flag_Param_Symbol_Dirty; + } + return 1; } diff --git a/src/symres.c b/src/symres.c index de655814..675e8269 100644 --- a/src/symres.c +++ b/src/symres.c @@ -80,11 +80,8 @@ static SymresStatus symres_symbol(AstNode** symbol_node) { char *closest = find_closest_symbol_in_scope_and_parents(curr_scope, token->text); token_toggle_end(token); - onyx_report_error(token->pos, Error_Critical, - "Unable to resolve symbol '%b'. Did you mean '%s'?", - token->text, - token->length, - closest); + if (closest) onyx_report_error(token->pos, Error_Critical, "Unable to resolve symbol '%b'. Did you mean '%s'?", token->text, token->length, closest); + else onyx_report_error(token->pos, Error_Critical, "Unable to resolve symbol '%b'.", token->text, token->length); return Symres_Error; } else { @@ -537,6 +534,14 @@ static SymresStatus symres_expression(AstTyped** expr) { SYMRES(block, ((AstDoBlock *) *expr)->block); break; + case Ast_Kind_Param: + if ((*expr)->flags & Ast_Flag_Param_Symbol_Dirty) { + assert((*expr)->token->type == Token_Type_Symbol); + *expr = make_symbol(context.ast_alloc, (*expr)->token); + SYMRES(expression, expr); + } + break; + default: break; } -- 2.25.1