From: Brendan Hansen Date: Sun, 24 Jan 2021 17:32:44 +0000 (-0600) Subject: made explicit types on defaulted struct members optional X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=92d53aac4d25d2980b9eaa7736864a6e812a0794;p=onyx.git made explicit types on defaulted struct members optional there are bugs if you 'use' a structure with this though. --- diff --git a/bin/onyx b/bin/onyx index 74d7969d..c5b5e78d 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/onyx.exe b/onyx.exe index 6949f75b..623482be 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 51b6b7d2..74ee72f7 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -1565,6 +1565,14 @@ CheckStatus check_overloaded_function(AstOverloadedFunction* func) { } CheckStatus check_struct(AstStructType* s_node) { + bh_arr_each(AstStructMember *, smem, s_node->members) { + if ((*smem)->type_node == NULL && (*smem)->initial_value != NULL) { + check_expression(&(*smem)->initial_value); + fill_in_type((*smem)->initial_value); + (*smem)->type = resolve_expression_type((*smem)->initial_value); + } + } + // NOTE: fills in the stcache type_build_from_ast(context.ast_alloc, (AstType *) s_node); if (s_node->stcache == NULL) return Check_Error; diff --git a/src/onyxparser.c b/src/onyxparser.c index 0dda66fa..7f3b6a67 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -1840,8 +1840,11 @@ static AstStructType* parse_struct(OnyxParser* parser) { } mem->token = expect_token(parser, Token_Type_Symbol); + expect_token(parser, ':'); - mem->type_node = parse_type(parser); + if (parser->curr->type != '=') { + mem->type_node = parse_type(parser); + } if (parser->curr->type == '=') { consume_token(parser); diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 8b4d61e5..a755ae31 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -120,27 +120,36 @@ AstType* symres_type(AstType* type) { fori (i, 0, bh_arr_length(s_node->members)) { AstStructMember *member = s_node->members[i]; - member->type_node = symres_type(member->type_node); - if (!node_is_type((AstNode *) member->type_node)) { - onyx_report_error(member->token->pos, "Member type is not a type."); - return type; - } - - if (member->flags & Ast_Flag_Struct_Mem_Used) { - AstStructType *used = (AstStructType *) member->type_node; + if (member->type_node) { + member->type_node = symres_type(member->type_node); - while (used->kind == Ast_Kind_Type_Alias) { - // NOTE: Maybe not a struct type. - used = (AstStructType *) ((AstTypeAlias *) used)->to; + if (!node_is_type((AstNode *) member->type_node)) { + onyx_report_error(member->token->pos, "Member type is not a type."); + return type; } - if (used->kind != Ast_Kind_Struct_Type) { - onyx_report_error(member->token->pos, - "Can only 'use' members of struct type, got '%s'.", - onyx_ast_node_kind_string(used->kind)); + if (member->flags & Ast_Flag_Struct_Mem_Used) { + AstType *used = (AstType *) member->type_node; - return type; + while (used->kind == Ast_Kind_Type_Alias) { + used = ((AstTypeAlias *) used)->to; + } + + b32 use_works = (used->kind == Ast_Kind_Struct_Type); + + if (used->kind == Ast_Kind_Type_Raw_Alias) { + AstTypeRawAlias* alias = (AstTypeRawAlias *) used; + use_works = (alias->to->kind == Type_Kind_Struct); + } + + if (!use_works) { + onyx_report_error(member->token->pos, + "Can only 'use' members of struct type, got '%s'.", + onyx_ast_node_kind_string(used->kind)); + + return type; + } } } } @@ -640,9 +649,6 @@ static void symres_block(AstBlock* block) { } void symres_function_header(AstFunction* func) { - if (func->scope == NULL) - func->scope = scope_create(context.ast_alloc, curr_scope, func->token->pos); - func->flags |= Ast_Flag_Comptime; bh_arr_each(AstParam, param, func->params) { @@ -692,6 +698,17 @@ void symres_function_header(AstFunction* func) { onyx_report_error(func->token->pos, "Return type is not a type."); } + bh_arr_each(AstParam, param, func->params) { + if (param->local->type_node != NULL) { + param->local->type_node = symres_type(param->local->type_node); + } + } +} + +void symres_function(AstFunction* func) { + if (func->scope == NULL) + func->scope = scope_create(context.ast_alloc, curr_scope, func->token->pos); + scope_enter(func->scope); bh_arr_each(AstParam, param, func->params) { @@ -713,12 +730,7 @@ void symres_function_header(AstFunction* func) { // // The 'use t : T' member requires completely knowing the type of T, to know which // members should be brought in. At the moment, that requires completely building the - // type of Foo($T), which is not possible, because the defaulted member 'something_else' - // does not have a known type until the default memory gets checked and reduced. - if (param->local->type_node != NULL) { - param->local->type_node = symres_type(param->local->type_node); - } - + // type of Foo($T). if (param->local->flags & Ast_Flag_Param_Use) { if (param->local->type_node != NULL && param->local->type == NULL) { param->local->type = type_build_from_ast(context.ast_alloc, param->local->type_node); @@ -739,6 +751,7 @@ void symres_function_header(AstFunction* func) { } else if (param->local->type != NULL) { onyx_report_error(param->local->token->pos, "Can only 'use' structures or pointers to structures."); + } else { onyx_report_error(param->local->token->pos, "Cannot deduce type of parameter '%b'; Try adding it explicitly.", param->local->token->text, @@ -747,12 +760,6 @@ void symres_function_header(AstFunction* func) { } } - scope_leave(); -} - -void symres_function(AstFunction* func) { - scope_enter(func->scope); - curr_function = func; symres_block(func->body); diff --git a/src/onyxtypes.c b/src/onyxtypes.c index eefe755c..0b39bc40 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -380,7 +380,14 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) { u32 alignment = 1, mem_alignment; u32 idx = 0; bh_arr_each(AstStructMember *, member, s_node->members) { - (*member)->type = type_build_from_ast(alloc, (*member)->type_node); + if ((*member)->type == NULL) + (*member)->type = type_build_from_ast(alloc, (*member)->type_node); + + if ((*member)->type == NULL) { + onyx_report_error((*member)->token->pos, "Unable to resolve member type. Try adding it explicitly."); + s_node->stcache = NULL; + return NULL; + } mem_alignment = type_alignment_of((*member)->type); if (mem_alignment <= 0) { diff --git a/src/onyxutils.c b/src/onyxutils.c index a8a3a65f..dc4dfdd6 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -971,6 +971,8 @@ AstStructType* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstP .scope = ps_type->scope, }; + entity_bring_to_state(&struct_entity, Entity_State_Check_Types); + entity_bring_to_state(&struct_default_entity, Entity_State_Check_Types); entity_bring_to_state(&struct_entity, Entity_State_Code_Gen); entity_bring_to_state(&struct_default_entity, Entity_State_Code_Gen);