renamed type_check_or_auto_cast
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 8 Sep 2021 15:03:55 +0000 (10:03 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 8 Sep 2021 15:03:55 +0000 (10:03 -0500)
bin/onyx
include/astnodes.h
src/astnodes.c
src/checker.c
src/polymorph.c
src/utils.c

index 17501404afe787b8fd019d66eddfcccd842ff85a..878738106bf2d562850938ee6dcecb94d040ee49 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index e15aef54dd95e3d6599cb7947efac30f1a681332..9aa31d08d48b164b1c7f28450859db761f79e6ad 100644 (file)
@@ -1336,7 +1336,8 @@ void clone_function_body(bh_allocator a, AstFunction* dest, AstFunction* source)
 void promote_numlit_to_larger(AstNumLit* num);
 b32 convert_numlit_to_type(AstNumLit* num, Type* type);
 
-b32 type_check_or_auto_cast(AstTyped** pnode, Type* type);
+#define unify_node_and_type(node, type) (unify_node_and_type_((node), (type), 1))
+b32 unify_node_and_type_(AstTyped** pnode, Type* type, b32 permanent);
 Type* resolve_expression_type(AstTyped* node);
 i64 get_expression_integer_value(AstTyped* node);
 
index f67d92b0cab78ba138b4206eb30672a0f4b9e84f..b8ae2c6c5fb1ee68732f3308b4f0144777a20cfe 100644 (file)
@@ -504,18 +504,20 @@ b32 convert_numlit_to_type(AstNumLit* num, Type* type) {
 }
 
 // NOTE: Returns 0 if it was not possible to make the types compatible.
-b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) {
+b32 unify_node_and_type_(AstTyped** pnode, Type* type, b32 permanent) {
     AstTyped* node = *pnode;
     if (type == NULL) return 0;
     if (node == NULL) return 0;
 
-    // if (node_is_type((AstNode *) node)) return 0;
-
     if (node->kind == Ast_Kind_Struct_Literal && node->type_node == NULL) {
         if (node->entity != NULL) return 1;
         if (type->kind == Type_Kind_VarArgs) type = type->VarArgs.elem;
         if (!type_is_sl_constructable(type)) return 0;
 
+        // If this shouldn't make permanent changes and submit entities,
+        // just assume that it works and don't submit the entities.
+        if (!permanent) return 1;
+
         node->type = type;
 
         add_entities_for_node(NULL, (AstNode *) node, NULL, NULL);
@@ -524,6 +526,11 @@ b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) {
 
     if (node->kind == Ast_Kind_Array_Literal && node->type_node == NULL) {
         if (node->entity != NULL) return 1;
+
+        // If this shouldn't make permanent changes and submit entities,
+        // just assume that it works and don't submit the entities.
+        if (!permanent) return 1;
+
         node->type = type;
         node->flags |= Ast_Flag_Array_Literal_Typed;
 
@@ -595,7 +602,7 @@ b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) {
         if (expr_count != type->Compound.count) return 0;
 
         fori (i, 0, (i64) expr_count) {
-            if (!type_check_or_auto_cast(&compound->exprs[i], type->Compound.types[i])) return 0;
+            if (!unify_node_and_type_(&compound->exprs[i], type->Compound.types[i], permanent)) return 0;
         }
 
         compound->type = type_build_compound_type(context.ast_alloc, compound);
@@ -605,8 +612,8 @@ b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) {
     else if (node->kind == Ast_Kind_If_Expression) {
         AstIfExpression* if_expr = (AstIfExpression *) node;
 
-        b32 true_success  = type_check_or_auto_cast(&if_expr->true_expr,  type);
-        b32 false_success = type_check_or_auto_cast(&if_expr->false_expr, type);
+        b32 true_success  = unify_node_and_type_(&if_expr->true_expr,  type, permanent);
+        b32 false_success = unify_node_and_type_(&if_expr->false_expr, type, permanent);
 
         if (true_success && false_success) {
             if_expr->type = type;
@@ -618,7 +625,7 @@ b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) {
     }
     else if (node->kind == Ast_Kind_Alias) {
         AstAlias* alias = (AstAlias *) node;
-        return type_check_or_auto_cast(&alias->alias, type);
+        return unify_node_and_type_(&alias->alias, type, permanent);
     }
 
     return 0;
@@ -641,7 +648,7 @@ Type* resolve_expression_type(AstTyped* node) {
         AstIfExpression* if_expr = (AstIfExpression *) node;
 
         Type* ltype = resolve_expression_type(if_expr->true_expr);
-        type_check_or_auto_cast(&if_expr->false_expr, ltype);
+        unify_node_and_type(&if_expr->false_expr, ltype);
 
         if_expr->type = ltype;
     }
index 80a9e46ccaf9b09cd0e5916dcbd54f0ae3676743..becae7ad2188bc5755974e5fcb82673decae29c1 100644 (file)
@@ -151,7 +151,7 @@ CheckStatus check_return(AstReturn* retnode) {
             return Check_Success;
         }
 
-        if (!type_check_or_auto_cast(&retnode->expr, *expected_return_type)) {
+        if (!unify_node_and_type(&retnode->expr, *expected_return_type)) {
             ERROR_(retnode->token->pos,
                     "Expected to return a value of type '%s', returning value of type '%s'.",
                     type_get_name(*expected_return_type),
@@ -363,7 +363,7 @@ CheckStatus check_switch(AstSwitch* switchnode) {
                 continue;
             }
 
-            if (!type_check_or_auto_cast(value, resolved_expr_type)) {
+            if (!unify_node_and_type(value, resolved_expr_type)) {
                 OnyxToken* tkn = sc->block->token;
                 if ((*value)->token) tkn = (*value)->token;
 
@@ -650,7 +650,7 @@ CheckStatus check_call(AstCall** pcall) {
                 }
 
                 if (arg_pos >= (u32) bh_arr_length(arg_arr)) goto type_checking_done;
-                if (!type_check_or_auto_cast(&arg_arr[arg_pos]->value, formal_params[arg_pos])) {
+                if (!unify_node_and_type(&arg_arr[arg_pos]->value, formal_params[arg_pos])) {
                     ERROR_(arg_arr[arg_pos]->token->pos,
                             "The procedure '%s' expects a value of type '%s' for %d%s parameter, got '%s'.",
                             get_function_name(callee),
@@ -665,11 +665,10 @@ CheckStatus check_call(AstCall** pcall) {
             }
 
             case AS_Expecting_Typed_VA: {
+                if (variadic_type->id == any_type->id) call->va_kind = VA_Kind_Any;
                 if (arg_pos >= (u32) bh_arr_length(arg_arr)) goto type_checking_done;
 
                 if (variadic_type->id == any_type->id) {
-                    call->va_kind = VA_Kind_Any;
-
                     resolve_expression_type(arg_arr[arg_pos]->value);
                     arg_arr[arg_pos]->va_kind = VA_Kind_Any; 
                     break;
@@ -677,7 +676,7 @@ CheckStatus check_call(AstCall** pcall) {
 
                 call->va_kind = VA_Kind_Typed;
 
-                if (!type_check_or_auto_cast(&arg_arr[arg_pos]->value, variadic_type)) {
+                if (!unify_node_and_type(&arg_arr[arg_pos]->value, variadic_type)) {
                     onyx_report_error(arg_arr[arg_pos]->token->pos,
                             "The procedure '%s' expects a value of type '%s' for the variadic parameter, '%b', got '%s'.",
                             get_function_name(callee),
@@ -872,7 +871,7 @@ CheckStatus check_binaryop_assignment(AstBinaryOp** pbinop) {
         }
     }
 
-    if (!type_check_or_auto_cast(&binop->right, binop->left->type)) {
+    if (!unify_node_and_type(&binop->right, binop->left->type)) {
         ERROR_(binop->token->pos,
                 "Cannot assign value of type '%s' to a '%s'.",
                 node_get_type_name(binop->right),
@@ -955,8 +954,8 @@ CheckStatus check_binaryop_compare(AstBinaryOp** pbinop) {
         b32 right_ac = node_is_auto_cast((AstNode *) binop->right);
 
         if (left_ac && right_ac) ERROR(binop->token->pos, "Cannot have auto cast on both sides of binary operator.");
-        else if (type_check_or_auto_cast(&binop->left, rtype));
-        else if (type_check_or_auto_cast(&binop->right, ltype));
+        else if (unify_node_and_type(&binop->left, rtype));
+        else if (unify_node_and_type(&binop->right, ltype));
         else {
             ERROR_(binop->token->pos,
                     "Cannot compare '%s' to '%s'.",
@@ -1018,8 +1017,8 @@ CheckStatus check_binaryop(AstBinaryOp** pbinop) {
 
     // :UnaryFieldAccessIsGross
     if (binop->left->kind == Ast_Kind_Unary_Field_Access || binop->right->kind == Ast_Kind_Unary_Field_Access) {
-        if      (type_check_or_auto_cast(&binop->left, binop->right->type));
-        else if (type_check_or_auto_cast(&binop->right, binop->left->type));
+        if      (unify_node_and_type(&binop->left, binop->right->type));
+        else if (unify_node_and_type(&binop->right, binop->left->type));
         else {
             report_bad_binaryop(binop);
             return Check_Error;
@@ -1088,8 +1087,8 @@ CheckStatus check_binaryop(AstBinaryOp** pbinop) {
         if (left_ac && right_ac) {
             ERROR(binop->token->pos, "Cannot have auto cast on both sides of binary operator.");
         }
-        else if (type_check_or_auto_cast(&binop->left, binop->right->type));
-        else if (type_check_or_auto_cast(&binop->right, binop->left->type));
+        else if (unify_node_and_type(&binop->left, binop->right->type));
+        else if (unify_node_and_type(&binop->right, binop->left->type));
         else {
             ERROR_(binop->token->pos,
                     "Mismatched types for binary operation '%s'. left: '%s', right: '%s'.",
@@ -1242,7 +1241,7 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) {
             YIELD_((*actual)->token->pos, "Trying to resolve type of expression for member '%s'.", smem.name);
         }
 
-        if (!type_check_or_auto_cast(actual, formal)) {
+        if (!unify_node_and_type(actual, formal)) {
             ERROR_(sl->token->pos,
                     "Mismatched types for %d%s member named '%s', expected '%s', got '%s'.",
                     i + 1, bh_num_suffix(i + 1),
@@ -1298,7 +1297,7 @@ CheckStatus check_array_literal(AstArrayLiteral* al) {
 
         al->flags &= ((*expr)->flags & Ast_Flag_Comptime) | (al->flags &~ Ast_Flag_Comptime);
 
-        if (!type_check_or_auto_cast(expr, elem_type)) {
+        if (!unify_node_and_type(expr, elem_type)) {
             ERROR_((*expr)->token->pos, "Mismatched types for value of in array, expected '%s', got '%s'.",
                 type_get_name(elem_type),
                 node_get_type_name(*expr));
@@ -1317,14 +1316,14 @@ CheckStatus check_range_literal(AstRangeLiteral** prange) {
     StructMember smem;
 
     type_lookup_member(expected_range_type, "low", &smem);
-    if (!type_check_or_auto_cast(&range->low, smem.type)) {
+    if (!unify_node_and_type(&range->low, smem.type)) {
         ERROR_(range->token->pos,
             "Expected left side of range to be a 32-bit integer, got '%s'.",
             node_get_type_name(range->low));
     }
 
     type_lookup_member(expected_range_type, "high", &smem);
-    if (!type_check_or_auto_cast(&range->high, smem.type)) {
+    if (!unify_node_and_type(&range->high, smem.type)) {
         ERROR_(range->token->pos,
             "Expected right side of range to be a 32-bit integer, got '%s'.",
             node_get_type_name(range->high));
@@ -1355,7 +1354,7 @@ CheckStatus check_if_expression(AstIfExpression* if_expr) {
     CHECK(expression, &if_expr->true_expr);
     CHECK(expression, &if_expr->false_expr);
 
-    if (!type_check_or_auto_cast(&if_expr->cond, &basic_types[Basic_Kind_Bool])) {
+    if (!unify_node_and_type(&if_expr->cond, &basic_types[Basic_Kind_Bool])) {
         ERROR_(if_expr->token->pos, "If-expression expected boolean for condition, got '%s'.",
             type_get_name(if_expr->cond->type));
     }
@@ -1826,7 +1825,7 @@ CheckStatus check_insert_directive(AstDirectiveInsert** pinsert) {
 
     Type* code_type = type_build_from_ast(context.ast_alloc, builtin_code_type);
 
-    if (!type_check_or_auto_cast(&insert->code_expr, code_type)) {
+    if (!unify_node_and_type(&insert->code_expr, code_type)) {
         ERROR_(insert->token->pos, "#insert expected a value of type 'Code', got '%s'.",
             type_get_name(insert->code_expr->type));
     }
@@ -2041,7 +2040,7 @@ CheckStatus check_struct_defaults(AstStructType* s_node) {
         if ((*smem)->initial_value && *(*smem)->initial_value) {
             CHECK(expression, (*smem)->initial_value);
 
-            if (!type_check_or_auto_cast((*smem)->initial_value, (*smem)->type)) {
+            if (!unify_node_and_type((*smem)->initial_value, (*smem)->type)) {
                 ERROR_((*(*smem)->initial_value)->token->pos,
                         "Mismatched type for initial value, expected '%s', got '%s'.",
                         type_get_name((*smem)->type),
@@ -2127,7 +2126,7 @@ CheckStatus check_function_header(AstFunction* func) {
         // when the default value is used as an argument and then has to be checked against
         // the parameter type                                  - brendanfh 2021/01/06
         // if (param->default_value != NULL) {
-        //     if (!type_check_or_auto_cast(&param->default_value, param->local->type)) {
+        //     if (!unify_node_and_type(&param->default_value, param->local->type)) {
         //         onyx_report_error(param->local->token->pos,
         //                 "Expected default value of type '%s', was of type '%s'.",
         //                 type_get_name(param->local->type),
@@ -2169,7 +2168,7 @@ CheckStatus check_memres(AstMemRes* memres) {
 
         if (memres->type != NULL) {
             Type* memres_type = memres->type;
-            if (!type_check_or_auto_cast(&memres->initial_value, memres_type)) {
+            if (!unify_node_and_type(&memres->initial_value, memres_type)) {
                 ERROR_(memres->token->pos,
                         "Cannot assign value of type '%s' to a '%s'.",
                         node_get_type_name(memres->initial_value),
index d072b98e096bc80f22ed4045aa98acabc1b34dc6..e5e709711052ad8358dfae08b637ac550f47ae38 100644 (file)
@@ -494,7 +494,7 @@ static void solve_for_polymorphic_param_value(PolySolveResult* resolved, AstPoly
             param->type = type_build_from_ast(context.ast_alloc, param->type_expr);
         assert(param->type);
 
-        if (!type_check_or_auto_cast(&value, param->type)) {
+        if (!unify_node_and_type(&value, param->type)) {
             if (err_msg) *err_msg = bh_aprintf(global_scratch_allocator,
                     "The procedure '%s' expects a value of type '%s' for baked %d%s parameter, got '%s'.",
                     get_function_name(pp->base_func),
index ea4eadeb0c1c131d9661b1fe5fd11ef990981faa..017ed8c5bf8fa9d2fea7ea535cba431fda743143 100644 (file)
@@ -389,7 +389,7 @@ AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads,
                 value = &((AstArgument *) *value)->value;
             }
 
-            if (!type_check_or_auto_cast(value, type_to_match)) {
+            if (!unify_node_and_type_(value, type_to_match, 0)) {
                 all_arguments_work = 0;
                 break;
             }
@@ -419,7 +419,7 @@ AstTyped* find_matching_overload_by_type(bh_arr(OverloadOption) overloads, Type*
         AstTyped* node = (AstTyped *) entry->key;
         if (node->kind == Ast_Kind_Overloaded_Function) continue;
 
-        if (type_check_or_auto_cast(&node, type)) {
+        if (unify_node_and_type(&node, type)) {
             matched_overload = node;
             break;
         }