making auto polymorphism even better
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 5 Jan 2022 12:59:40 +0000 (06:59 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 5 Jan 2022 12:59:40 +0000 (06:59 -0600)
core/container/map.onyx
include/astnodes.h
src/clone.c
src/polymorph.h
src/symres.c

index 7238bf9a2a2d689c79623a50ac3a3f1e3b22f655..842a2cf29b3bdb284ffbf871e3af91dbb0edd841 100644 (file)
@@ -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.{};
 
index e0761cb1b8eb8084bc7474d256c52f342bb67729..ff6986b46fe4d636e2c30ba9d822e38306c10cec 100644 (file)
@@ -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 {
index 448f254da4f95b600c681d6b98c48b26d6d954f4..e1a17afafbbb0e8e3ee7af1758e04108b1a064e2 100644 (file)
@@ -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;
index af03de6da3bb053fccb3be23700e2c873998f526..64ecbe0499d22e5975086220c0401353b11d6787 100644 (file)
@@ -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;
 }
 
index de655814677226d9e43d1fd19f5091a4a281d03b..675e826965a4332721841b0ee3a4a5364295bdf2 100644 (file)
@@ -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;
     }