From: Brendan Hansen Date: Wed, 23 Sep 2020 14:26:53 +0000 (-0500) Subject: added 'use' statement for enums and variables of struct type X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=6f6735f30a9d09c7029dcdb29265009c4c1d514d;p=onyx.git added 'use' statement for enums and variables of struct type --- diff --git a/Makefile b/Makefile index 72e04827..302e4efa 100644 --- a/Makefile +++ b/Makefile @@ -17,9 +17,13 @@ OBJ_FILES=\ ifeq (, $(shell which tcc)) CC=gcc +else +ifeq ($(RELEASE), 0) + CC=gcc else CC=tcc endif +endif INCLUDES=-I./include LIBS= diff --git a/onyx b/onyx index bba7794e..cf023545 100755 Binary files a/onyx and b/onyx differ diff --git a/src/onyxchecker.c b/src/onyxchecker.c index b12c866f..5f9940ae 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -978,14 +978,19 @@ b32 check_field_access(AstFieldAccess** pfield) { return 1; } - token_toggle_end(field->token); StructMember smem; - if (!type_lookup_member(field->expr->type, field->token->text, &smem)) { + if (field->token != NULL) { + token_toggle_end(field->token); + field->field = field->token->text; + } + + if (!type_lookup_member(field->expr->type, field->field, &smem)) { onyx_report_error(field->token->pos, "Field '%s' does not exists on '%s'.", - field->token->text, + field->field, type_get_name(field->expr->type)); - token_toggle_end(field->token); + + if (field->token != NULL) token_toggle_end(field->token); return 1; } @@ -993,7 +998,7 @@ b32 check_field_access(AstFieldAccess** pfield) { field->idx = smem.idx; field->type = smem.type; - token_toggle_end(field->token); + if (field->token != NULL) token_toggle_end(field->token); return 0; } diff --git a/src/onyxparser.c b/src/onyxparser.c index 1d8b2a27..be50983d 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -1145,6 +1145,15 @@ static AstNode* parse_statement(OnyxParser* parser) { break; } + case Token_Type_Keyword_Use: { + AstUse* use_node = make_node(AstUse, Ast_Kind_Use); + use_node->token = expect_token(parser, Token_Type_Keyword_Use); + use_node->expr = parse_expression(parser); + + retval = (AstNode *) use_node; + break; + } + default: break; } diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 146494fe..7abad056 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -20,6 +20,7 @@ static void symres_if(AstIfWhile* ifnode); static void symres_while(AstIfWhile* whilenode); static void symres_for(AstFor* fornode); static void symres_switch(AstSwitch* switchnode); +static void symres_use(AstUse* use); static void symres_statement_chain(AstNode** walker); static b32 symres_statement(AstNode** stmt); static void symres_block(AstBlock* block); @@ -30,6 +31,14 @@ static void symres_use_package(AstUsePackage* package); static void symres_enum(AstEnumType* enum_node); static void symres_memres(AstMemRes** memres); +static AstFieldAccess* make_field_access(AstTyped* node, char* field) { + AstFieldAccess* fa = onyx_ast_node_new(semstate.node_allocator, sizeof(AstFieldAccess), Ast_Kind_Field_Access); + fa->field = field; + fa->expr = node; + + return fa; +} + static void scope_enter(Scope* new_scope) { // if (new_scope->parent == NULL) // new_scope->parent = semstate.curr_scope; @@ -457,6 +466,41 @@ static void symres_switch(AstSwitch* switchnode) { if (switchnode->assignment != NULL) scope_leave(); } +static void symres_use(AstUse* use) { + symres_expression(&use->expr); + if (use->expr == NULL) return; + + if (use->expr->kind == Ast_Kind_Enum_Type) { + AstEnumType* et = (AstEnumType *) use->expr; + + bh_arr_each(AstEnumValue *, ev, et->values) + symbol_introduce(semstate.curr_scope, (*ev)->token, (AstNode *) *ev); + + return; + } + + if (use->expr->type_node == NULL) goto cannot_use; + + if (use->expr->type_node->kind == Ast_Kind_Struct_Type || + use->expr->type_node->kind == Ast_Kind_Poly_Call_Type) { + + if (use->expr->type == NULL) + use->expr->type = type_build_from_ast(semstate.node_allocator, use->expr->type_node); + if (use->expr->type == NULL) goto cannot_use; + + Type* st = use->expr->type; + bh_arr_each(StructMember *, smem, st->Struct.memarr) { + AstFieldAccess* fa = make_field_access(use->expr, (*smem)->name); + symbol_raw_introduce(semstate.curr_scope, (*smem)->name, use->token->pos, (AstNode *) fa); + } + + return; + } + +cannot_use: + onyx_report_error(use->token->pos, "Cannot use this."); +} + // NOTE: Returns 1 if the statment should be removed static b32 symres_statement(AstNode** stmt) { switch ((*stmt)->kind) { @@ -470,6 +514,7 @@ static b32 symres_statement(AstNode** stmt) { case Ast_Kind_Argument: symres_expression((AstTyped **) &((AstArgument *) *stmt)->value); return 0; case Ast_Kind_Block: symres_block((AstBlock *) *stmt); return 0; case Ast_Kind_Defer: symres_statement(&((AstDefer *) *stmt)->stmt); return 0; + case Ast_Kind_Use: symres_use((AstUse *) *stmt); return 1; case Ast_Kind_Jump: return 0; diff --git a/src/onyxutils.c b/src/onyxutils.c index 05eeb478..0b66aaab 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -82,6 +82,7 @@ static const char* ast_node_names[] = { "FOR", "WHILE", "JUMP", + "USE", "DEFER", "SWITCH", "SWITCH CASE",