From 1c1610b5f1dafb802bc134528ac06df0199a9571 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Mon, 23 Aug 2021 15:24:33 -0500 Subject: [PATCH] added auto-return type --- include/onyxastnodes.h | 4 ++++ src/onyxastnodes.c | 8 ++++++++ src/onyxbuiltins.c | 5 +++++ src/onyxchecker.c | 39 ++++++++++++++++++++++++++++----------- src/onyxparser.c | 2 +- src/onyxtypes.c | 4 ++++ 6 files changed, 50 insertions(+), 12 deletions(-) diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index aa27da73..802fdea6 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -1273,6 +1273,10 @@ extern AstBasicType basic_type_f32x4; extern AstBasicType basic_type_f64x2; extern AstBasicType basic_type_v128; +// HACK +// :AutoReturnType +extern Type type_auto_return; +extern AstBasicType basic_type_auto_return; extern OnyxToken builtin_package_token; extern AstNumLit builtin_heap_start; diff --git a/src/onyxastnodes.c b/src/onyxastnodes.c index 409523f9..97a03128 100644 --- a/src/onyxastnodes.c +++ b/src/onyxastnodes.c @@ -561,6 +561,14 @@ b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) { if (type->kind == Type_Kind_Function && (node->flags & Ast_Flag_Proc_Is_Null) != 0) return 1; if (types_are_compatible(node->type, type)) return 1; + // :AutoReturnType + if (node->type && node->type->kind == Type_Kind_Function + && node->type->Function.return_type == &type_auto_return + && type->kind == Type_Kind_Function) { + + node->type->Function.return_type = type->Function.return_type; + return 1; + } if (node_is_auto_cast((AstNode *) node)) { char* dummy; Type* from_type = ((AstUnaryOp *) node)->expr->type; diff --git a/src/onyxbuiltins.c b/src/onyxbuiltins.c index e33d011c..8731a619 100644 --- a/src/onyxbuiltins.c +++ b/src/onyxbuiltins.c @@ -31,6 +31,11 @@ AstBasicType basic_type_f32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, 0, AstBasicType basic_type_f64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, 0, NULL, NULL, &basic_types[Basic_Kind_F64X2] }; AstBasicType basic_type_v128 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, 0, NULL, NULL, &basic_types[Basic_Kind_V128] }; +// HACK +// :AutoReturnType +Type type_auto_return = { 0 }; +AstBasicType basic_type_auto_return = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, 0, NULL, NULL, &type_auto_return }; + OnyxToken builtin_package_token = { Token_Type_Symbol, 7, "builtin ", { 0 } }; static OnyxToken builtin_heap_start_token = { Token_Type_Symbol, 12, "__heap_start ", { 0 } }; diff --git a/src/onyxchecker.c b/src/onyxchecker.c index f3268778..945d25b9 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -108,25 +108,38 @@ static inline void fill_in_type(AstTyped* node) { } // HACK: This should be baked into a structure, not a global variable. -static Type* expected_return_type = NULL; +static Type** expected_return_type = NULL; CheckStatus check_return(AstReturn* retnode) { if (retnode->expr) { CHECK(expression, &retnode->expr); - if (!type_check_or_auto_cast(&retnode->expr, expected_return_type)) { + if (*expected_return_type == &type_auto_return) { + resolve_expression_type(retnode->expr); + if (retnode->expr->type == NULL) return Check_Yield_Macro; + + *expected_return_type = retnode->expr->type; + return Check_Success; + } + + if (!type_check_or_auto_cast(&retnode->expr, *expected_return_type)) { onyx_report_error(retnode->token->pos, "Expected to return a value of type '%s', returning value of type '%s'.", - type_get_name(expected_return_type), + type_get_name(*expected_return_type), node_get_type_name(retnode->expr)); return Check_Error; } } else { - if (expected_return_type->Basic.size > 0) { + if (*expected_return_type == &type_auto_return) { + *expected_return_type = &basic_types[Basic_Kind_Void]; + return Check_Success; + } + + if ((*expected_return_type)->Basic.size > 0) { onyx_report_error(retnode->token->pos, "Returning from non-void function without a value. Expected a value of type '%s'.", - type_get_name(expected_return_type)); + type_get_name(*expected_return_type)); return Check_Error; } } @@ -593,8 +606,9 @@ CheckStatus check_call(AstCall** pcall) { token_toggle_end(callee->intrinsic_name); } - call->type = callee->type->Function.return_type; call->va_kind = VA_Kind_Not_VA; + call->type = callee->type->Function.return_type; + if (call->type == &type_auto_return) return Check_Yield_Macro; Type **formal_params = callee->type->Function.params; @@ -1622,7 +1636,7 @@ CheckStatus check_expression(AstTyped** pexpr) { } if (expr->kind == Ast_Kind_Polymorphic_Proc) { - // Polymoprhic procedures do not need to be checked. Their concrete instantiations + // polymorphic procedures do not need to be checked. Their concrete instantiations // will be checked when they are created. return Check_Success; } @@ -1914,17 +1928,20 @@ CheckStatus check_function(AstFunction* func) { if (func->flags & Ast_Flag_Already_Checked) return Check_Success; if (func->entity_header && func->entity_header->state < Entity_State_Code_Gen) return Check_Yield_Macro; - expected_return_type = func->type->Function.return_type; + expected_return_type = &func->type->Function.return_type; if (func->body) { CheckStatus status = check_block(func->body); if (status == Check_Error && func->generated_from) onyx_report_error(func->generated_from->pos, "Error in polymorphic procedure generated from this location."); - return status; + if (status != Check_Success) return status; } - - func->flags |= Ast_Flag_Already_Checked; + if (*expected_return_type == &type_auto_return) { + *expected_return_type = &basic_types[Basic_Kind_Void]; + } + + func->flags |= Ast_Flag_Already_Checked; return Check_Success; } diff --git a/src/onyxparser.c b/src/onyxparser.c index aedca557..0892a6cd 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -2220,7 +2220,7 @@ static b32 parse_possible_quick_function_definition(OnyxParser* parser, AstTyped if (parser->curr->type == '{') { body_block = parse_block(parser, 1); - return_type = (AstType *) &basic_type_void; + return_type = (AstType *) &basic_type_auto_return; } else { AstTyped* body = parse_expression(parser, 0); diff --git a/src/onyxtypes.c b/src/onyxtypes.c index eaa931fa..b96fa9f9 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -84,6 +84,10 @@ b32 types_are_compatible_(Type* t1, Type* t2, b32 recurse_pointers) { if (t1 == NULL || t2 == NULL) return 0; if (t1->id == t2->id) return 1; + if (t1 == &type_auto_return || t2 == &type_auto_return) { + return 0; + } + switch (t1->kind) { case Type_Kind_Basic: if (t2->kind == Type_Kind_Basic) { -- 2.25.1