converted symbol introducing to be an entity, instead of in the parser
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 5 Feb 2021 22:12:38 +0000 (16:12 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 5 Feb 2021 22:12:38 +0000 (16:12 -0600)
bin/onyx
include/onyxastnodes.h
src/onyx.c
src/onyxastnodes.c
src/onyxentities.c
src/onyxparser.c
src/onyxsymres.c

index a2d9e6ea7861fcb96e56088fac3680dab0b9c45d..b25ec394d8bd4c6baba0f30d3b693053228e3817 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index e27854ac0cb9ccdd8ce71a30dc7734273d537882..bda0f218a1bd10c902e6b1db1dbdaed90e2ea7ca 100644 (file)
@@ -859,6 +859,7 @@ typedef enum EntityState {
     Entity_State_Error,
     
     Entity_State_Parse_Builtin,
+    Entity_State_Introduce_Symbols,
     Entity_State_Parse,
     Entity_State_Resolve_Symbols,
     Entity_State_Check_Types,
@@ -877,6 +878,7 @@ typedef enum EntityType {
 
     Entity_Type_Load_Path,
     Entity_Type_Load_File,
+    Entity_Type_Binding,
     Entity_Type_Use_Package,
     Entity_Type_String_Literal,
     Entity_Type_File_Contents,
@@ -910,6 +912,7 @@ typedef struct Entity {
     union {
         AstInclude            *include;
         AstUsePackage         *use_package;
+        AstBinding            *binding;
         AstFunction           *function;
         AstOverloadedFunction *overloaded_function;
         AstGlobal             *global;
index f796c3ffe3873774c03707bd3f627e334aac3466..f3f4f0e9ea5f2894b7959c4a2d5103b1843d9b2b 100644 (file)
@@ -271,24 +271,39 @@ static b32 process_entity(Entity* ent) {
     if (context.options->verbose_output == 3) {
         if (ent->expr && ent->expr->token)
             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);
+                   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);
+        
+        else if (ent->expr)
+            printf("%s | %s\n",
+                   entity_state_strings[ent->state],
+                   entity_type_strings[ent->type]);
     }
+    
+    // CLEANUP: There should be a nicer way to track if the builtins have
+    // already been initialized.
+    static b32 builtins_initialized = 0;
 
     switch (ent->state) {
         case Entity_State_Parse_Builtin:
             process_load_entity(ent);
             ent->state = Entity_State_Finalized;
 
-            if (onyx_has_errors()) return 0;
-
-            initialize_builtins(context.ast_alloc);
+        case Entity_State_Introduce_Symbols:
+            // Currently, introducing symbols is handled in the symbol resolution
+            // function. Maybe there should be a different place where that happens?
+            symres_entity(ent);
             break;
-
+        
         case Entity_State_Parse:
+            if (!builtins_initialized) {
+                builtins_initialized = 1;
+                initialize_builtins(context.ast_alloc);
+            }
+         
             process_load_entity(ent);
             ent->state = Entity_State_Finalized;
             break;
@@ -308,6 +323,7 @@ static b32 process_entity(Entity* ent) {
 #if defined(_BH_LINUX)
 static void output_dummy_progress_bar() {
     EntityHeap* eh = &context.entities;
+    if (bh_arr_length(eh->entities) == 0) return;
 
     printf("\e[2;1H");
     for (i32 i = 0; i < Entity_State_Count - 1; i++) {
index 9d39772fe979ce5967ea32c13039f1a9000aa4c3..5969e12dc9e3586e6ce1e7b53018593b8709528d 100644 (file)
@@ -105,10 +105,11 @@ const char *binaryop_string[Binary_Op_Count] = {
 const char* entity_state_strings[Entity_State_Count] = {
     "Error",
     "Parse Builtin",
+    "Introduce Symbols",
     "Parse",
-    "Resolve_Symbols",
-    "Check_Types",
-    "Code_Gen",
+    "Resolve Symbols",
+    "Check Types",
+    "Code Gen",
     "Finalized",
 };
 
@@ -116,6 +117,7 @@ const char* entity_type_strings[Entity_Type_Count] = {
     "Unknown",
     "Add to Load Path",
     "Load File",
+    "Binding (Declaration)",
     "Use Package",
     "String Literal",
     "File Contents",
index 0f90faaab96b2e0effc3c4c538d2cb2b133ff7d4..ceb2b6cf334f5b15bf32c27a64a0cfdf753e0fc4 100644 (file)
@@ -105,6 +105,14 @@ void add_entities_for_node(AstNode* node, Scope* scope, Package* package) {
             break;
         }
         
+        case Ast_Kind_Binding: {
+            ent.state   = Entity_State_Introduce_Symbols;
+            ent.type    = Entity_Type_Binding;
+            ent.binding = (AstBinding *) node;
+            entity_heap_insert(entities, ent);
+            break;
+        }
+        
         case Ast_Kind_Function: {
             if ((node->flags & Ast_Flag_Foreign) != 0) {
                 ent.type     = Entity_Type_Foreign_Function_Header;
index fe7a86a07bfa77bed41fcb98f2c24b2a11d37d10..14c2c38777b45a7e0aafa73085a096e2124aeaa7 100644 (file)
@@ -1,10 +1,7 @@
-// The job of the parser for Onyx is to do two things:
-//  1. Submit nodes to the entity heap for further processing.
-//     Nodes such as procedure defintions, string literals, etc.
-//
-//  2. Insert static symbols into scopes.
-//     Things defined at top level or inside of static scopes such
-//     as bindings in procedures or in struct scopes.
+// The sole job of the parser for Onyx is to submit nodes to the
+// entity heap for further processing. These nodes include things
+// such as procedure definitions, string literals, struct definitions
+// and declarations to be introduced into scopes.
 
 // Things that need to be cleaned up in the parser:
 //  - control block local variables should be more extensible and reuse more code
 #include "onyxutils.h"
 
 // NOTE: The one weird define you need to know before read the code below
-#define make_node(nclass, kind) onyx_ast_node_new(parser->allocator, sizeof(nclass), kind)
-#define peek_token(ahead)       (parser->curr + ahead)
-#define ENTITY_SUBMIT(node)     (add_entities_for_node((AstNode *) (node), bh_arr_last(parser->scope_stack), parser->package))
+#define make_node(nclass, kind)             onyx_ast_node_new(parser->allocator, sizeof(nclass), kind)
+#define peek_token(ahead)                   (parser->curr + ahead)
+#define ENTITY_SUBMIT(node)                 (add_entities_for_node((AstNode *) (node), bh_arr_last(parser->scope_stack), parser->package))
+#define ENTITY_SUBMIT_IN_SCOPE(node, scope) (add_entities_for_node((AstNode *) (node), scope, parser->package))
 
 static AstNode error_node = { Ast_Kind_Error, 0, NULL, NULL };
 
@@ -1077,8 +1075,7 @@ static i32 parse_possible_symbol_declaration(OnyxParser* parser, AstNode** ret)
         AstBinding* binding = parse_top_level_binding(parser, symbol);
         if (parser->hit_unexpected_token) return 2;
         
-        Scope* insertion_scope = bh_arr_last(parser->scope_stack);
-        symbol_introduce(insertion_scope, symbol, binding->node);
+        ENTITY_SUBMIT(binding);
         return 2;
     }
 
@@ -1705,7 +1702,7 @@ static AstStructType* parse_struct(OnyxParser* parser) {
             consume_token(parser);
 
             AstBinding* binding = parse_top_level_binding(parser, binding_name);
-            symbol_introduce(s_node->scope, binding->token, binding->node);
+            ENTITY_SUBMIT(binding);
             
             consume_token_if_next(parser, ';');
 
@@ -2397,10 +2394,8 @@ void onyx_parse(OnyxParser *parser) {
                             target_scope = parser->package->private_scope;
                         if (((AstBinding *) curr_stmt)->node->flags & Ast_Flag_Private_File)
                             target_scope = parser->file_scope;
-
-                        symbol_introduce(target_scope,
-                            ((AstBinding *) curr_stmt)->token,
-                            ((AstBinding *) curr_stmt)->node);
+                        
+                        ENTITY_SUBMIT_IN_SCOPE(curr_stmt, target_scope);
                         break;
                     }
 
index dd3053ac92ee6b4cc893768440e11ae9a74bdb29..4d54afb413c8233f59193ec941a41bff6862ad4f 100644 (file)
@@ -957,6 +957,12 @@ void symres_entity(Entity* ent) {
     EntityState next_state = Entity_State_Check_Types;
 
     switch (ent->type) {
+        case Entity_Type_Binding: {
+            symbol_introduce(curr_scope, ent->binding->token, ent->binding->node);
+            next_state = Entity_State_Finalized;
+            break;
+        }
+        
         case Entity_Type_Foreign_Function_Header:
         case Entity_Type_Function_Header:         symres_function_header(ent->function); break;
         case Entity_Type_Function:                symres_function(ent->function);        break;