polymorphic macros as overloads
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 13 Aug 2021 14:50:17 +0000 (09:50 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 13 Aug 2021 14:50:17 +0000 (09:50 -0500)
bin/onyx
include/onyxastnodes.h
src/onyxchecker.c
src/onyxutils.c

index fe2bd2b265a22591bb311e29f9011240bf2a48c2..755a2379652bb145515b97ed51b9e4875e426d71 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index aa4985321457f6a62625f9223f1207d4186b25db..e53efbfd98271bbfef06df02dec01d34451d91d9 100644 (file)
@@ -1412,6 +1412,7 @@ static inline ParamPassType type_get_param_pass(Type* type) {
 static inline AstFunction* get_function_from_node(AstNode* node) {
     if (node->kind == Ast_Kind_Function) return (AstFunction *) node;
     if (node->kind == Ast_Kind_Polymorphic_Proc) return ((AstPolyProc *) node)->base_func;
+    if (node->kind == Ast_Kind_Macro) return get_function_from_node((AstNode*) ((AstMacro *) node)->body);
     return NULL;
 }
 
index 8642554676081f3a011d8255a628de3baa298171..2704b088c549f7c77e0ce78c4fc047d4c7d2e588 100644 (file)
@@ -953,6 +953,11 @@ static AstCall* binaryop_try_operator_overload(AstBinaryOp* binop) {
 
     b32 should_yield = 0;
     AstTyped* overload = find_matching_overload_by_arguments(operator_overloads[binop->operation], &args, &should_yield);
+    if (should_yield) {
+        bh_arr_free(args.values);
+        return (AstCall *) &node_that_signals_a_yield;
+    }
+
     if (overload == NULL) {
         bh_arr_free(args.values);
         return NULL;
@@ -1006,11 +1011,15 @@ CheckStatus check_binaryop(AstBinaryOp** pbinop) {
         (binop->left->type->kind != Type_Kind_Basic || binop->right->type->kind != Type_Kind_Basic)) {
         AstCall *implicit_call = binaryop_try_operator_overload(binop);
 
-        if (implicit_call != NULL) {
-            CHECK(call, &implicit_call);
+        if (implicit_call == (AstCall *) &node_that_signals_a_yield)
+            return Check_Yield_Macro;
 
+        if (implicit_call != NULL) {
             // NOTE: Not a binary op
+            implicit_call->next = binop->next;
             *pbinop = (AstBinaryOp *) implicit_call;
+
+            CHECK(call, (AstCall **) pbinop);
             return Check_Success;
         }
     }
@@ -1404,11 +1413,15 @@ CheckStatus check_subscript(AstSubscript** psub) {
         AstBinaryOp* binop = (AstBinaryOp *) sub;
         AstCall *implicit_call = binaryop_try_operator_overload(binop);
 
-        if (implicit_call != NULL) {
-            CHECK(call, &implicit_call);
+        if (implicit_call == (AstCall *) &node_that_signals_a_yield)
+            return Check_Yield_Macro;
 
+        if (implicit_call != NULL) {
             // NOTE: Not an array access
+            implicit_call->next = sub->next;
             *psub = (AstSubscript *) implicit_call;
+
+            CHECK(call, (AstCall **) psub);
             return Check_Success;
         }
     }
index 3ab680a5d28088d9e8dbd8af5f3e727b56a8400e..6cac0d55ff570cfb8b50ee1157e163e2da41eec0 100644 (file)
@@ -1083,7 +1083,7 @@ AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads,
         AstFunction* overload = NULL;
         switch (node->kind) {
             case Ast_Kind_Function:         overload = (AstFunction *) node; break;
-            case Ast_Kind_Macro:            overload = (AstFunction *) ((AstMacro *) node)->body; break;
+            case Ast_Kind_Macro:            overload = macro_resolve_header((AstMacro *) node, param_args, NULL); break;
             case Ast_Kind_Polymorphic_Proc: overload = polymorphic_proc_build_only_header((AstPolyProc *) node, PPLM_By_Arguments, param_args); break;
         }
 
@@ -1263,7 +1263,8 @@ AstFunction* macro_resolve_header(AstMacro* macro, Arguments* args, OnyxToken* c
                     return (AstFunction *) &node_that_signals_a_yield;
                 }
 
-                onyx_report_error(callsite->pos, err_msg);
+                if (callsite) onyx_report_error(callsite->pos, err_msg);
+                
                 return NULL;
             }