From: Brendan Hansen Date: Wed, 6 Jan 2021 03:19:52 +0000 (-0600) Subject: moved some logic from symbol resolution to type checking X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=5a4b84055fa7f36be3db05586c8278e77c96919b;p=onyx.git moved some logic from symbol resolution to type checking --- diff --git a/bin/onyx b/bin/onyx index f7892b47..ab00105d 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/include/onyxtypes.h b/include/onyxtypes.h index cec94fa5..526eddcb 100644 --- a/include/onyxtypes.h +++ b/include/onyxtypes.h @@ -68,7 +68,7 @@ typedef struct StructMember { // easier and less costly. - brendanfh 2020/09/17 char *name; - struct AstTyped* initial_value; + struct AstTyped** initial_value; b32 included_through_use : 1; } StructMember; diff --git a/onyx.exe b/onyx.exe index 192f9e4f..0ea5726e 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyx.c b/src/onyx.c index defec5e2..204130b5 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -469,8 +469,9 @@ static b32 process_entity(CompilerState* compiler_state, Entity* ent) { if (compiler_state->options->verbose_output == 2) { if (ent->expr && ent->expr->token) - printf("%s | %s:%i:%i\n", + printf("%s | %s | %s:%i:%i\n", entity_state_strings[ent->state], + entity_type_strings[ent->type], ent->expr->token->pos.filename, ent->expr->token->pos.line, ent->expr->token->pos.column); diff --git a/src/onyxchecker.c b/src/onyxchecker.c index d3d7d472..ab6b8aba 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -925,7 +925,63 @@ CheckStatus check_unaryop(AstUnaryOp** punop) { } CheckStatus check_struct_literal(AstStructLiteral* sl) { + if (!node_is_type((AstNode *) sl->stnode)) { + onyx_report_error(sl->token->pos, "Struct type is not a type."); + return Check_Error; + } + fill_in_type((AstTyped *) sl); + if (sl->type == NULL) return Check_Error; + + if (!type_is_structlike_strict(sl->type)) { + onyx_report_error(sl->token->pos, "Type is not a constructable using a struct literal."); + return Check_Error; + } + + if (bh_arr_length(sl->values) == 0) { + bh_arr_new(global_heap_allocator, sl->values, type_structlike_mem_count(sl->type)); + bh_arr_set_length(sl->values, type_structlike_mem_count(sl->type)); + bh_arr_zero(sl->values); + + StructMember s; + bh_arr_each(AstStructMember *, smem, sl->named_values) { + token_toggle_end((*smem)->token); + if (!type_lookup_member(sl->type, (*smem)->token->text, &s)) { + onyx_report_error((*smem)->token->pos, + "The field '%s' does not exist on type '%s'.", (*smem)->token->text, type_get_name(sl->type)); + token_toggle_end((*smem)->token); + return Check_Error; + } + token_toggle_end((*smem)->token); + + if (s.included_through_use) { + onyx_report_error((*smem)->token->pos, "Cannot specify value for member '%s', whic was included through a 'use' statement.", s.name); + return Check_Error; + } + + if (sl->values[s.idx] != NULL) { + onyx_report_error((*smem)->token->pos, "Multiple values given for '%b'.", (*smem)->token->text, (*smem)->token->length); + return Check_Error; + } + + sl->values[s.idx] = (*smem)->initial_value; + } + + if (sl->type->kind == Type_Kind_Struct) { + bh_arr_each(StructMember*, smem, sl->type->Struct.memarr) { + u32 idx = (*smem)->idx; + + if (sl->values[idx] == NULL) { + if ((*smem)->initial_value == NULL) { + onyx_report_error(sl->token->pos, "No value was given for the field '%s'.", (*smem)->name); + return Check_Error; + } + + sl->values[idx] = *(*smem)->initial_value; + } + } + } + } i32 mem_count = type_structlike_mem_count(sl->type); @@ -975,9 +1031,18 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) { } CheckStatus check_array_literal(AstArrayLiteral* al) { + if (!node_is_type((AstNode *) al->atnode)) { + onyx_report_error(al->token->pos, "Array type is not a type."); + return Check_Error; + } + fill_in_type((AstTyped *) al); - assert(al->type->kind == Type_Kind_Array); + al->type = type_make_array(semstate.allocator, al->type, bh_arr_length(al->values)); + if (al->type == NULL || al->type->kind != Type_Kind_Array) { + onyx_report_error(al->token->pos, "Expected array type for array literal. This is a compiler bug."); + return Check_Error; + } if (al->type->Array.count != (u32) bh_arr_length(al->values)) { onyx_report_error(al->token->pos, "Wrong array size (%d) for number of values (%d).", @@ -1031,9 +1096,9 @@ CheckStatus check_range_literal(AstRangeLiteral** prange) { if (range->step == NULL) { type_lookup_member(expected_range_type, "step", &smem); assert(smem.initial_value != NULL); - CHECK(expression, &smem.initial_value); + CHECK(expression, smem.initial_value); - range->step = smem.initial_value; + range->step = *smem.initial_value; } return Check_Success; @@ -1244,7 +1309,7 @@ CheckStatus check_expression(AstTyped** pexpr) { case Ast_Kind_Symbol: onyx_report_error(expr->token->pos, - "Unable to resolve symbol '%b'.", + "Symbol was unresolved in symbol resolution phase, '%b'. This is definitely a compiler bug.", expr->token->text, expr->token->length); retval = Check_Error; break; diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 0f9154c7..9773e613 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -305,13 +305,7 @@ static void symres_unaryop(AstUnaryOp** unaryop) { } static void symres_struct_literal(AstStructLiteral* sl) { - // @CLEANUP if (sl->stnode != NULL) symres_expression(&sl->stnode); - if (!node_is_type((AstNode *) sl->stnode)) { - onyx_report_error(sl->token->pos, "Struct type is not a type."); - return; - } - sl->stnode = (AstTyped *) symres_type((AstType *) sl->stnode); if (sl->stnode == NULL || sl->stnode->kind == Ast_Kind_Error || sl->stnode->kind == Ast_Kind_Symbol) return; @@ -319,72 +313,23 @@ static void symres_struct_literal(AstStructLiteral* sl) { while (sl->type_node->kind == Ast_Kind_Type_Alias) sl->type_node = ((AstTypeAlias *) sl->type_node)->to; - sl->type = type_build_from_ast(semstate.allocator, sl->type_node); - - if (sl->type == NULL) return; - - if (!type_is_structlike_strict(sl->type)) { - onyx_report_error(sl->token->pos, "Type is not a constructable using a struct literal."); - return; + if (sl->values != NULL) { + bh_arr_each(AstTyped *, expr, sl->values) { + if (*expr == NULL) onyx_report_error(sl->token->pos, "Some kind of error occured with this struct literal."); + else symres_expression(expr); + } } - if (bh_arr_length(sl->values) == 0) { - bh_arr_new(global_heap_allocator, sl->values, type_structlike_mem_count(sl->type)); - bh_arr_set_length(sl->values, type_structlike_mem_count(sl->type)); - bh_arr_zero(sl->values); - - StructMember s; + if (sl->named_values != NULL) { bh_arr_each(AstStructMember *, smem, sl->named_values) { - token_toggle_end((*smem)->token); - if (!type_lookup_member(sl->type, (*smem)->token->text, &s)) { - onyx_report_error((*smem)->token->pos, - "The field '%s' does not exist on type '%s'.", (*smem)->token->text, type_get_name(sl->type)); - token_toggle_end((*smem)->token); - return; - } - token_toggle_end((*smem)->token); - - if (s.included_through_use) { - onyx_report_error((*smem)->token->pos, "Cannot specify value for member '%s', whic was included through a 'use' statement.", s.name); - return; - } - - if (sl->values[s.idx] != NULL) { - onyx_report_error((*smem)->token->pos, "Multiple values given for '%b'.", (*smem)->token->text, (*smem)->token->length); - return; - } - - sl->values[s.idx] = (*smem)->initial_value; - } - - if (sl->type->kind == Type_Kind_Struct) { - bh_arr_each(StructMember*, smem, sl->type->Struct.memarr) { - u32 idx = (*smem)->idx; - - if (sl->values[idx] == NULL) { - if ((*smem)->initial_value == NULL) { - onyx_report_error(sl->token->pos, "No value was given for the field '%s'.", (*smem)->name); - return; - } - - sl->values[idx] = (*smem)->initial_value; - } - } + if ((*smem)->initial_value == NULL) onyx_report_error(sl->token->pos, "Some kind of error occured with this struct literal."); + else symres_expression(&(*smem)->initial_value); } } - - bh_arr_each(AstTyped *, expr, sl->values) { - if (*expr == NULL) onyx_report_error(sl->token->pos, "Some kind of error occured with this struct literal."); - else symres_expression(expr); - } } static void symres_array_literal(AstArrayLiteral* al) { if (al->atnode != NULL) symres_expression(&al->atnode); - if (!node_is_type((AstNode *) al->atnode)) { - onyx_report_error(al->token->pos, "Array type is not a type."); - return; - } al->atnode = (AstTyped *) symres_type((AstType *) al->atnode); if (al->atnode == NULL || al->atnode->kind == Ast_Kind_Error || al->atnode->kind == Ast_Kind_Symbol) return; @@ -393,12 +338,6 @@ static void symres_array_literal(AstArrayLiteral* al) { while (al->type_node->kind == Ast_Kind_Type_Alias) al->type_node = ((AstTypeAlias *) al->type_node)->to; - al->type = type_build_from_ast(semstate.allocator, al->type_node); - if (al->type == NULL) return; - - al->type = type_make_array(semstate.allocator, al->type, bh_arr_length(al->values)); - if (al->type == NULL) return; - bh_arr_each(AstTyped *, expr, al->values) symres_expression(expr); diff --git a/src/onyxtypes.c b/src/onyxtypes.c index 10765a19..d346d960 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -368,7 +368,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) { .type = (*member)->type, .idx = idx, .name = bh_strdup(alloc, (*member)->token->text), - .initial_value = (*member)->initial_value, + .initial_value = &(*member)->initial_value, .included_through_use = 0, };