bugfixes and removing arbitrary restrictions
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 28 Apr 2022 20:42:09 +0000 (15:42 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 28 Apr 2022 20:42:09 +0000 (15:42 -0500)
core/conv.onyx
include/astnodes.h
src/astnodes.c
src/checker.c
src/parser.c
src/polymorph.h
src/symres.c
tests/aoc-2020/day7.onyx
tests/baked_parameters.onyx
tests/operator_overload.onyx
tests/poly_structs_with_values.onyx

index bc514bc590b8173a0a8c9a17bba6af8c3fa6d7ba..dfe9871a4dafa18781fc125026dfefff86067ce6 100644 (file)
@@ -6,8 +6,8 @@ Enable_Custom_Formatters :: true
     map :: package core.map
     string :: package core.string
 
-    custom_formatters: Map(type_expr, (^Format_Output, ^Format, rawptr) -> void);
-    custom_parsers   : Map(type_expr, (rawptr, str, Allocator) -> bool);
+    custom_formatters: Map(type_expr, #type (^Format_Output, ^Format, rawptr) -> void);
+    custom_parsers   : Map(type_expr, #type (rawptr, str, Allocator) -> bool);
 }
 
 custom_formatters_initialized :: #init () {
index 9b4d76ddf5242201e5fea3bacc8857e6e32a751a..d5433347f8c5171eca4d75335003d61482df38d6 100644 (file)
@@ -1675,6 +1675,7 @@ AstNode* polymorphic_proc_try_solidify(AstFunction* pp, bh_arr(AstPolySolution)
 AstFunction* polymorphic_proc_build_only_header(AstFunction* pp, PolyProcLookupMethod pp_lookup, ptr actual);
 AstFunction* polymorphic_proc_build_only_header_with_slns(AstFunction* pp, bh_arr(AstPolySolution) slns, b32 error_if_failed);
 b32 potentially_convert_function_to_polyproc(AstFunction *func);
+AstPolyCallType* convert_call_to_polycall(AstCall* call);
 
 void add_overload_option(bh_arr(OverloadOption)* poverloads, u64 precedence, AstTyped* overload);
 AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* args);
index ec2386f980a5084103456cdd174f859a31731ac2..862b17269e04e1b526cecacfdfa1abc98b9dc630 100644 (file)
@@ -1303,3 +1303,19 @@ b32 static_if_resolution(AstIf* static_if) {
 
     return value != 0;
 }
+
+AstPolyCallType* convert_call_to_polycall(AstCall* call) {
+    // HACK HACK HACK
+    AstPolyCallType *pct = onyx_ast_node_new(context.ast_alloc, sizeof(AstPolyCallType), Ast_Kind_Poly_Call_Type);
+    pct->token = call->token;
+    pct->__unused = call->next;
+    pct->callee = (AstType *) call->callee;
+    pct->params = (AstNode **) call->args.values;
+    bh_arr_each(AstNode *, pp, pct->params) {
+        if ((*pp)->kind == Ast_Kind_Argument) {
+            *pp = (AstNode *) (*(AstArgument **) pp)->value;
+        }
+    }
+
+    return pct;
+}
\ No newline at end of file
index 3279919cc1a9265ae8d27d0f8c4d0938a87266be..f788ddd691811b1f63ae554ac6d2cc60ff4f32b1 100644 (file)
@@ -603,17 +603,7 @@ CheckStatus check_call(AstCall** pcall) {
     if (call->kind == Ast_Kind_Call) {
         AstNode* callee = strip_aliases((AstNode *) call->callee);
         if (callee->kind == Ast_Kind_Poly_Struct_Type) {
-            // HACK HACK HACK
-            AstPolyCallType *pct = onyx_ast_node_new(context.ast_alloc, sizeof(AstPolyCallType), Ast_Kind_Poly_Call_Type);
-            pct->token = call->token;
-            pct->__unused = call->next;
-            pct->callee = (AstType *) callee;
-            pct->params = (AstNode **) call->args.values;
-            bh_arr_each(AstNode *, pp, pct->params) {
-                *pp = (AstNode *) (*(AstArgument **) pp)->value;
-            }
-
-            *pcall = (AstCall *) pct;
+            *pcall = (AstCall *) convert_call_to_polycall(call);
             CHECK(expression, (AstTyped **) pcall);
             return Check_Success;
         }
index 348415b6e77715836f033318094f838531e3a095..cf0b5b792c3a7c3e4b1a8c1922768e599e5a0441 100644 (file)
@@ -54,6 +54,7 @@ static AstReturn*     parse_return_stmt(OnyxParser* parser);
 static AstNode*       parse_use_stmt(OnyxParser* parser);
 static AstBlock*      parse_block(OnyxParser* parser, b32 make_a_new_scope, char* block_name);
 static AstNode*       parse_statement(OnyxParser* parser);
+static void           parse_polymorphic_variable(OnyxParser* parser, AstType*** next_insertion);
 static AstType*       parse_type(OnyxParser* parser);
 static AstTypeOf*     parse_typeof(OnyxParser* parser);
 static AstStructType* parse_struct(OnyxParser* parser);
@@ -534,6 +535,12 @@ static AstTyped* parse_factor(OnyxParser* parser) {
             break;
         }
 
+        case '$': {
+            AstType **tmp = (AstType **) &retval;
+            parse_polymorphic_variable(parser, &tmp);
+            break;
+        }
+
         case '#': {
             if (parse_possible_directive(parser, "file_contents")) {
                 AstFileContents* fc = make_node(AstFileContents, Ast_Kind_File_Contents);
@@ -619,7 +626,7 @@ static AstTyped* parse_factor(OnyxParser* parser) {
                     poly_var->token = expect_token(parser, Token_Type_Symbol);
 
                     expect_token(parser, '=');
-                    AstType* poly_type = parse_type(parser);
+                    AstType* poly_type = (AstType *) parse_expression(parser, 0);
 
                     bh_arr_push(solid->known_polyvars, ((AstPolySolution) {
                         .kind     = PSK_Undefined,
@@ -1805,7 +1812,7 @@ static AstType* parse_type(OnyxParser* parser) {
                     while (!consume_token_if_next(parser, ')')) {
                         if (parser->hit_unexpected_token) break;
 
-                        AstNode* t = (AstNode *) parse_type(parser);
+                        AstNode* t = (AstNode *) parse_expression(parser, 0);
                         bh_arr_push(params, t);
 
                         if (parser->curr->type != ')')
@@ -1831,21 +1838,15 @@ static AstType* parse_type(OnyxParser* parser) {
                 break;
             }
 
-            case '#': {
-                // :ValueDirectiveHack
-                if (parse_possible_directive(parser, "value")) {
-                // It is very weird to put these here.
-                case Token_Type_Literal_Integer:
-                case Token_Type_Literal_String:
-                case Token_Type_Literal_Float:
-                case Token_Type_Literal_True:
-                case Token_Type_Literal_False:
-                case '-':
-                    *next_insertion = (AstType *) parse_expression(parser, 0);
-                    next_insertion = NULL;
-                    break;
-                }
-
+            //
+            // I don't think any of these cases are necesary any more?
+            case Token_Type_Literal_Integer:
+            case Token_Type_Literal_String:
+            case Token_Type_Literal_Float:
+            case Token_Type_Literal_True:
+            case Token_Type_Literal_False:
+            case '-': {
+                *next_insertion = (AstType *) parse_expression(parser, 0);
                 next_insertion = NULL;
                 break;
             }
index 34b4ced4f24c31dce51155fa3288d11a83fbe65d..d7974ada7ab69e2fbdf0795a5226534ec5881c70 100644 (file)
@@ -262,6 +262,17 @@ static PolySolveResult solve_poly_type(AstNode* target, AstType* type_expr, Type
                 break;
             }
 
+            case Ast_Kind_Address_Of: {
+                if (elem.actual->kind != Type_Kind_Pointer) break;
+
+                bh_arr_push(elem_queue, ((PolySolveElem) {
+                    .type_expr = (AstType *) ((AstAddressOf *) elem.type_expr)->expr,
+                    .kind = PSK_Type,
+                    .actual = elem.actual->Pointer.elem,
+                }));
+                break;
+            }
+
             case Ast_Kind_Array_Type: {
                 if (elem.actual->kind != Type_Kind_Array) break;
 
@@ -337,6 +348,13 @@ static PolySolveResult solve_poly_type(AstNode* target, AstType* type_expr, Type
                 break;
             }
 
+            case Ast_Kind_Call: {
+                AstPolyCallType *pct = convert_call_to_polycall((AstCall *) elem.type_expr);
+                elem.type_expr = (AstType *) pct;
+
+                // fallthrough
+            }
+
             case Ast_Kind_Poly_Call_Type: {
                 if (elem.actual->kind != Type_Kind_Struct) break;
                 if (bh_arr_length(elem.actual->Struct.poly_sln) != bh_arr_length(((AstPolyCallType *) elem.type_expr)->params)) break;
@@ -397,6 +415,9 @@ static AstTyped* lookup_param_in_arguments(AstFunction* func, AstPolyParam* para
     bh_arr(AstTyped *) arg_arr = args->values;
     bh_arr(AstNamedValue *) named_values = args->named_values;
 
+    if ((i32) param->idx < 0)
+        return NULL;
+
     // NOTE: This check is safe because currently the arguments given without a name
     // always map to the beginning indidies of the argument array.
     if (param->idx >= (u64) bh_arr_length(arg_arr)) {
@@ -1011,7 +1032,7 @@ Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySoluti
     }
 
     if (bh_arr_length(slns) != bh_arr_length(ps_type->poly_params)) {
-        onyx_report_error(pos, Error_Critical, "Wrong number of arguments for '%s'. Expected %d, got %d",
+        onyx_report_error(pos, Error_Critical, "Wrong number of arguments for '%s'. Expected %d, got %d.",
             ps_type->name,
             bh_arr_length(ps_type->poly_params),
             bh_arr_length(slns));
index c2cf26dee92e903f08f2a542fd7eac350459c6de..503073a98a92bb11bdfe393410fa90ce2ba5abec 100644 (file)
@@ -186,7 +186,10 @@ static SymresStatus symres_type(AstType** type) {
 
         case Ast_Kind_Poly_Struct_Type: {
             AstPolyStructType* pst_node = (AstPolyStructType *) *type;
-            pst_node->scope = scope_create(context.ast_alloc, pst_node->entity->scope, pst_node->token->pos);
+
+            if (pst_node->scope == NULL) {
+                pst_node->scope = scope_create(context.ast_alloc, pst_node->entity->scope, pst_node->token->pos);
+            }
 
             bh_arr_each(AstPolyStructParam, param, pst_node->poly_params) {
                 SYMRES(type, &param->type_node);
index 434e70fb81abb1062f96db87599286d217d0ed49..c5be6ba68cdd16ce166341c493699443a56ade1a 100644 (file)
@@ -5,7 +5,7 @@ reader :: package core.string.reader
 
 BagGraph :: struct {
     nodes    : [..] ^BagNode;
-    node_map : map.Map(str, ^BagNode);
+    node_map : map.Map(str, #type ^BagNode);
 }
 
 BagNode :: struct {
index 41ff1e838d2299a71b92bdfbab4212a08ad93537..f0325ac3f75b0381e43bc1307ef25dd8fe67be9c 100644 (file)
@@ -12,7 +12,7 @@ alloc_slice :: ($T: type_expr, N: i32) -> [] T {
     return .{ data, N };
 }
 
-count_to_30 :: #solidify count_to { N = #value 30 };
+count_to_30 :: #solidify count_to { N = 30 };
 
 main :: (args: [] cstr) {
     count_to(5);
index c929cabed7c9c73d8261c38c3cb88b83005049d8..2bf51ab6cc1c479839eb59438ec000e01101b922 100644 (file)
@@ -51,8 +51,8 @@ Vec :: struct (T: type_expr, N: i32) {
     return res;
 }
 
-join :: (a: Vec($T, $N), b: Vec(T, $M)) -> Vec(T, #value N + M) {
-    out : Vec(T, #value N + M);
+join :: (a: Vec($T, $N), b: Vec(T, $M)) -> Vec(T, N + M) {
+    out : Vec(T, N + M);
     for i: 0 .. N do out.data[i]     = a.data[i]; 
     for i: 0 .. M do out.data[i + N] = b.data[i]; 
     return out;
index 2cdcac9242e594293ea99a40a3c646fb08cd2ead..9fd5eeb4c500a0ab8b7454d0fdca00a50d36e4af 100644 (file)
@@ -8,7 +8,7 @@ main :: (args: [] cstr) {
         y : [N] f32;
     }
 
-    nps : NewPolyStruct(i32, #value 4);
+    nps : NewPolyStruct(i32, 4);
 
     for ^x: nps.x do *x = 12345;
     for ^y: nps.y do *y = 67890;