From: Brendan Hansen Date: Fri, 11 Dec 2020 23:34:23 +0000 (-0600) Subject: use statements are now more universal X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=3ca413d03a3a7d7162f0a36e73f05db5b7552b74;p=onyx.git use statements are now more universal --- diff --git a/docs/todo b/docs/todo index def77412..5c6c3303 100644 --- a/docs/todo +++ b/docs/todo @@ -51,7 +51,7 @@ Language Cohesion: var := some.packages.nested.here.StructName.{ value1, value2, ... }; - [ ] 'use' statements have two different variations and should be unified. + [X] 'use' statements have two different variations and should be unified. They can be used to include a package, 'use package', and they can be used to add names from a namespace to the current scope. The problem is that 'use package' can only be at the top level, and 'use' can only diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 9018dfd9..70b19294 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -754,6 +754,7 @@ typedef struct Entity { AstEnumType *enum_type; AstMemRes *mem_res; AstPolyProc *poly_proc; + AstUse *use; }; } Entity; diff --git a/onyx b/onyx index e06f4f93..9b9eec7b 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/foo_test.onyx b/progs/foo_test.onyx index 08e0f2a9..f395f2f5 100644 --- a/progs/foo_test.onyx +++ b/progs/foo_test.onyx @@ -5,3 +5,5 @@ use package core TestFoo :: struct { a: i32; } print_foo :: proc () do println("Foo!"); + +SomeEnum :: enum #flags { Val1; Val2; Val3; } diff --git a/progs/odin_example.onyx b/progs/odin_example.onyx index 76fb770d..e3dea714 100644 --- a/progs/odin_example.onyx +++ b/progs/odin_example.onyx @@ -2,8 +2,6 @@ #include_file "progs/foo_test" use package core -use package test { foo as foo_pkg } -use package test as test Foo :: struct { data1 : i32; @@ -59,6 +57,13 @@ make_bar :: proc () -> Bar { } main :: proc (args: [] cstr) { + use package test { foo as foo_pkg } + use package test as test + use test.foo.SomeEnum + + printf("Val2: %i\n", cast(i32) Val2); + printf("Val3: %i\n", cast(i32) Val3); + foo_pkg.print_foo(); foo := test.foo.TestFoo.{ a = 1234 }; printf("foo.a: %i\n", foo.a); diff --git a/src/onyx.c b/src/onyx.c index a649da20..0229d810 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -360,6 +360,13 @@ static void merge_parse_results(CompilerState* compiler_state, ParseResults* res break; } + case Ast_Kind_Use: { + ent.type = Entity_Type_Use; + ent.use = (AstUse *) node; + entity_heap_insert(&compiler_state->prog_info.entities, ent); + break; + } + case Ast_Kind_Memres: { ent.type = Entity_Type_Memory_Reservation; ent.mem_res = (AstMemRes *) node; diff --git a/src/onyxparser.c b/src/onyxparser.c index a2028659..67e4c8a2 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -32,7 +32,8 @@ static AstIfWhile* parse_while_stmt(OnyxParser* parser); static AstFor* parse_for_stmt(OnyxParser* parser); static AstSwitch* parse_switch_stmt(OnyxParser* parser); static b32 parse_possible_symbol_declaration(OnyxParser* parser, AstNode** ret); -static AstReturn* parse_return_statement(OnyxParser* parser); +static AstReturn* parse_return_stmt(OnyxParser* parser); +static AstNode* parse_use_stmt(OnyxParser* parser); static AstBlock* parse_block(OnyxParser* parser); static AstNode* parse_statement(OnyxParser* parser); static AstType* parse_type(OnyxParser* parser); @@ -1013,7 +1014,7 @@ static b32 parse_possible_symbol_declaration(OnyxParser* parser, AstNode** ret) } // 'return' ? -static AstReturn* parse_return_statement(OnyxParser* parser) { +static AstReturn* parse_return_stmt(OnyxParser* parser) { AstReturn* return_node = make_node(AstReturn, Ast_Kind_Return); return_node->token = expect_token(parser, Token_Type_Keyword_Return); @@ -1032,6 +1033,82 @@ static AstReturn* parse_return_statement(OnyxParser* parser) { return return_node; } +static AstNode* parse_use_stmt(OnyxParser* parser) { + OnyxToken* use_token = expect_token(parser, Token_Type_Keyword_Use); + + if (parser->curr->type == Token_Type_Keyword_Package) { + expect_token(parser, Token_Type_Keyword_Package); + + AstUsePackage* upack = make_node(AstUsePackage, Ast_Kind_Use_Package); + upack->token = use_token; + + AstNode* pack_symbol = make_node(AstNode, Ast_Kind_Symbol); + pack_symbol->token = expect_token(parser, Token_Type_Symbol); + + // CLEANUP: This is just gross. + if (parser->curr->type == '.') { + consume_token(parser); + pack_symbol->token->length += 1; + + while (1) { + if (parser->hit_unexpected_token) break; + + OnyxToken* symbol = expect_token(parser, Token_Type_Symbol); + pack_symbol->token->length += symbol->length; + + if (parser->curr->type == '.') { + pack_symbol->token->length += 1; + consume_token(parser); + } else { + break; + } + } + } + + upack->package = (AstPackage *) pack_symbol; + + if (parser->curr->type == Token_Type_Keyword_As) { + consume_token(parser); + upack->alias = expect_token(parser, Token_Type_Symbol); + } + + if (parser->curr->type == '{') { + consume_token(parser); + + bh_arr_new(global_heap_allocator, upack->only, 4); + + while (parser->curr->type != '}') { + if (parser->hit_unexpected_token) return NULL; + + AstAlias* alias = make_node(AstAlias, Ast_Kind_Alias); + alias->token = expect_token(parser, Token_Type_Symbol); + + if (parser->curr->type == Token_Type_Keyword_As) { + consume_token(parser); + alias->alias = expect_token(parser, Token_Type_Symbol); + } else { + alias->alias = alias->token; + } + + bh_arr_push(upack->only, alias); + + if (parser->curr->type != '}') + expect_token(parser, ','); + } + + consume_token(parser); + } + + return (AstNode *) upack; + + } else { + AstUse* use_node = make_node(AstUse, Ast_Kind_Use); + use_node->token = use_token; + use_node->expr = parse_expression(parser); + return (AstNode *) use_node; + } +} + // ; // // ; @@ -1046,7 +1123,7 @@ static AstNode* parse_statement(OnyxParser* parser) { switch ((u16) parser->curr->type) { case Token_Type_Keyword_Return: - retval = (AstNode *) parse_return_statement(parser); + retval = (AstNode *) parse_return_stmt(parser); break; case '{': @@ -1152,11 +1229,12 @@ static AstNode* parse_statement(OnyxParser* parser) { } 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); + // 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; + needs_semicolon = 0; + retval = (AstNode *) parse_use_stmt(parser); break; } @@ -1835,71 +1913,8 @@ static AstNode* parse_top_level_statement(OnyxParser* parser) { switch ((u16) parser->curr->type) { case Token_Type_Keyword_Use: { - OnyxToken* use_token = expect_token(parser, Token_Type_Keyword_Use); - - expect_token(parser, Token_Type_Keyword_Package); - - AstUsePackage* upack = make_node(AstUsePackage, Ast_Kind_Use_Package); - upack->token = use_token; - - AstNode* pack_symbol = make_node(AstNode, Ast_Kind_Symbol); - pack_symbol->token = expect_token(parser, Token_Type_Symbol); - - // CLEANUP: This is just gross. - if (parser->curr->type == '.') { - consume_token(parser); - pack_symbol->token->length += 1; - - while (1) { - if (parser->hit_unexpected_token) break; - - OnyxToken* symbol = expect_token(parser, Token_Type_Symbol); - pack_symbol->token->length += symbol->length; - - if (parser->curr->type == '.') { - pack_symbol->token->length += 1; - consume_token(parser); - } else { - break; - } - } - } - - upack->package = (AstPackage *) pack_symbol; - - if (parser->curr->type == Token_Type_Keyword_As) { - consume_token(parser); - upack->alias = expect_token(parser, Token_Type_Symbol); - } - - if (parser->curr->type == '{') { - consume_token(parser); - - bh_arr_new(global_heap_allocator, upack->only, 4); - - while (parser->curr->type != '}') { - if (parser->hit_unexpected_token) return NULL; - - AstAlias* alias = make_node(AstAlias, Ast_Kind_Alias); - alias->token = expect_token(parser, Token_Type_Symbol); - - if (parser->curr->type == Token_Type_Keyword_As) { - consume_token(parser); - alias->alias = expect_token(parser, Token_Type_Symbol); - } else { - alias->alias = alias->token; - } - - bh_arr_push(upack->only, alias); - - if (parser->curr->type != '}') - expect_token(parser, ','); - } - - consume_token(parser); - } - - add_node_to_process(parser, (AstNode *) upack); + AstNode* use_node = parse_use_stmt(parser); + add_node_to_process(parser, use_node); return NULL; } diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 7d054a2e..f1683e3c 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -517,17 +517,18 @@ cannot_use: // NOTE: Returns 1 if the statment should be removed static b32 symres_statement(AstNode** stmt) { switch ((*stmt)->kind) { - case Ast_Kind_Local: symres_local((AstLocal **) stmt); return 1; - case Ast_Kind_Return: symres_return((AstReturn *) *stmt); return 0; - case Ast_Kind_If: symres_if((AstIfWhile *) *stmt); return 0; - case Ast_Kind_While: symres_while((AstIfWhile *) *stmt); return 0; - case Ast_Kind_For: symres_for((AstFor *) *stmt); return 0; - case Ast_Kind_Switch: symres_switch((AstSwitch *) *stmt); return 0; - case Ast_Kind_Call: symres_call((AstCall *) *stmt); return 0; - 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_Local: symres_local((AstLocal **) stmt); return 1; + case Ast_Kind_Return: symres_return((AstReturn *) *stmt); return 0; + case Ast_Kind_If: symres_if((AstIfWhile *) *stmt); return 0; + case Ast_Kind_While: symres_while((AstIfWhile *) *stmt); return 0; + case Ast_Kind_For: symres_for((AstFor *) *stmt); return 0; + case Ast_Kind_Switch: symres_switch((AstSwitch *) *stmt); return 0; + case Ast_Kind_Call: symres_call((AstCall *) *stmt); return 0; + 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_Use_Package: symres_use_package((AstUsePackage *) *stmt); return 1; case Ast_Kind_Jump: return 0; @@ -787,6 +788,8 @@ void symres_entity(Entity* ent) { semstate.curr_package = ent->package; } + EntityState next_state = Entity_State_Check_Types; + switch (ent->type) { case Entity_Type_Foreign_Function_Header: case Entity_Type_Function: symres_function(ent->function); break; @@ -795,6 +798,10 @@ void symres_entity(Entity* ent) { case Entity_Type_Global_Header: symres_global(ent->global); break; case Entity_Type_Use_Package: symres_use_package(ent->use_package); break; + case Entity_Type_Use: symres_use(ent->use); + next_state = Entity_State_Finalized; + break; + case Entity_Type_Overloaded_Function: symres_overloaded_function(ent->overloaded_function); break; case Entity_Type_Expression: symres_expression(&ent->expr); break; case Entity_Type_Type_Alias: ent->type_alias = symres_type(ent->type_alias); break; @@ -806,7 +813,7 @@ void symres_entity(Entity* ent) { default: break; } - ent->state = Entity_State_Check_Types; + ent->state = next_state; if (ent->package) scope_leave(); }