top level bindings in struct scopes are even more useful
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 30 Jan 2021 00:26:30 +0000 (18:26 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 30 Jan 2021 00:26:30 +0000 (18:26 -0600)
bin/onyx
onyx.exe
src/onyxparser.c
src/onyxsymres.c
src/onyxtypes.c

index 039edd7eba7da4544f5640718963d212567e2d91..c7bfabc0fd9d638523234e17911a337f315f18b0 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index 61ba581eef1e70fa0ab6e20e5ff771fef116c871..5f4d6e7644abe6a7a759abaac65c52e39274d771 100644 (file)
Binary files a/onyx.exe and b/onyx.exe differ
index 731a0ec22b4fe514eda4a6187e9a4f0242e45beb..dc06f3735585a66a605f816c167ba5644def0fff 100644 (file)
@@ -1829,6 +1829,13 @@ static AstStructType* parse_struct(OnyxParser* parser) {
     }
 
     expect_token(parser, '{');
+
+    // HACK: There should be a better way to change which scope symbols will
+    // be placed in when converted to entities. Right now, you have to mess
+    // with parser->file_scope to change that. There is the block stack mechanism,
+    // but that feels very limited for this purpose.
+    Scope* parent_scope = parser->file_scope;
+
     b32 member_is_used = 0;
     while (parser->curr->type != '}') {
         if (parser->hit_unexpected_token) return s_node;
@@ -1848,7 +1855,8 @@ static AstStructType* parse_struct(OnyxParser* parser) {
             
             if (!s_node->scope) {
                 // NOTE: The parent scope will be filled out during symbol resolution.
-                s_node->scope = scope_create(context.ast_alloc, NULL, s_node->token->pos);
+                s_node->scope = scope_create(context.ast_alloc, parent_scope, s_node->token->pos);
+                parser->file_scope = s_node->scope;
             }
             
             AstBinding* binding = parse_top_level_binding(parser, member_name);
@@ -1881,6 +1889,8 @@ static AstStructType* parse_struct(OnyxParser* parser) {
 
     expect_token(parser, '}');
 
+    parser->file_scope = parent_scope;
+
     if (poly_struct != NULL) {
         // NOTE: Not a StructType
         return (AstStructType *) poly_struct;
index 77c0047e69a5b4a63eb24e17c9bd519a4d22faaa..3eaddbb11891f95cdcaabb3ebb3f3315c2df5c4e 100644 (file)
@@ -548,7 +548,7 @@ static void symres_switch(AstSwitch* switchnode) {
 
 static void symres_use(AstUse* use) {
     symres_expression(&use->expr);
-    if (use->expr == NULL) return;
+    if (use->expr == NULL || use->expr->kind == Ast_Kind_Error) return;
 
     if (use->expr->kind == Ast_Kind_Enum_Type) {
         AstEnumType* et = (AstEnumType *) use->expr;
@@ -559,6 +559,15 @@ static void symres_use(AstUse* use) {
         return;
     }
 
+    if (use->expr->kind == Ast_Kind_Struct_Type) {
+        AstStructType* st = (AstStructType *) use->expr;
+
+        if (st->scope)
+            scope_include(curr_scope, st->scope, use->token->pos);
+
+        return;
+    }
+
     if (use->expr->type_node == NULL && use->expr->type == NULL) goto cannot_use;
 
     AstType* effective_type = use->expr->type_node;
index 94ff6094273fa30672e10052f2d817521032fdc7..26ccd63ae4a113d23792160adfe2a8737ca13a1c 100644 (file)
@@ -376,7 +376,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
             s_type->Struct.memarr = NULL;
             s_type->Struct.poly_sln = NULL;
 
-            bh_table_init(global_heap_allocator, s_type->Struct.members, s_type->Struct.mem_count);
+            bh_table_init(global_heap_allocator, s_type->Struct.members, s_type->Struct.mem_count + 1);
             bh_arr_new(global_heap_allocator, s_type->Struct.memarr, s_type->Struct.mem_count);
 
             b32 is_union = (s_node->flags & Ast_Flag_Struct_Is_Union) != 0;