fixed error printing; added #inject blocks
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 27 Sep 2022 21:21:20 +0000 (16:21 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 27 Sep 2022 21:21:20 +0000 (16:21 -0500)
compiler/include/parser.h
compiler/src/onyx.c
compiler/src/parser.c

index 325f552a330255ef81d25fa42850f34698582a7a..76961fd98e2080f7bb240052bddab9e8203c4cce 100644 (file)
@@ -34,6 +34,12 @@ typedef struct OnyxParser {
 
     bh_arr(AstTyped *) stored_tags;
 
+    // NOTE: When inside of an #inject block, this is set to the node
+    // that should have the symbols injected onto it. If this is non-
+    // NULL, then top-level binding nodes are converted into injects
+    // onto this node.
+    AstTyped *injection_point;
+
     // Used to set default precedence of #overload options.
     // This way, the precedence order of multiple #overload
     // options in the same file is given to be the lexical
index 628adfb4f3a8fbf56cb75d80eb1fc9728e86119f..4e7540c536ecced3baa20cfad482de129198d9c3 100644 (file)
@@ -654,13 +654,19 @@ static i32 onyx_compile() {
             context.cycle_almost_detected = 0;
         }
 
-        if (onyx_has_errors()) return ONYX_COMPILER_PROGRESS_ERROR;
+        if (onyx_has_errors()) {
+            onyx_errors_print();
+            return ONYX_COMPILER_PROGRESS_ERROR;
+        }
 
         if (ent->state != Entity_State_Finalized && ent->state != Entity_State_Failed)
             entity_heap_insert_existing(&context.entities, ent);
     }
 
+    //
+    // There should not be any errors printing here, but there might be warnings.
     onyx_errors_print();
+
     u64 duration = bh_time_duration(start_time);
 
     if (context.options->verbose_output > 0) {
index d5309853f5345e277871273cca99c018c06ea981..1ea389f04240872c4a729b1d9d4063bbcb824e99 100644 (file)
@@ -3272,18 +3272,31 @@ static void parse_top_level_statement(OnyxParser* parser) {
                 return;
             }
             else if (parse_possible_directive(parser, "inject")) {
-                AstInjection *inject = make_node(AstInjection, Ast_Kind_Injection);
-                inject->token = dir_token;
-
+                AstTyped *injection_point;
                 parser->parse_calls = 0;
-                inject->full_loc = parse_expression(parser, 0);
+                injection_point = parse_expression(parser, 0);
                 parser->parse_calls = 1;
 
+                if (peek_token(0)->type == '{') {
+                    assert(!parser->injection_point);
+                    parser->injection_point = injection_point;
+
+                    expect_token(parser, '{');
+                    parse_top_level_statements_until(parser, '}');
+                    expect_token(parser, '}');
+
+                    parser->injection_point = NULL;
+                    return;
+                }
+
                 // See comment above
                 if (next_tokens_are(parser, 2, ':', ':')) {
                     consume_tokens(parser, 2);
                 }
 
+                AstInjection *inject = make_node(AstInjection, Ast_Kind_Injection);
+                inject->token = dir_token;
+                inject->full_loc = injection_point;
                 inject->to_inject = parse_top_level_expression(parser);
                 
                 ENTITY_SUBMIT(inject);
@@ -3374,6 +3387,17 @@ submit_binding_to_entities:
     {
         if (!binding) return;
 
+        if (parser->injection_point) {
+            AstInjection *injection = make_node(AstInjection, Ast_Kind_Injection);
+            injection->token = parser->injection_point->token;
+            injection->dest = parser->injection_point;
+            injection->symbol = binding->token;
+            injection->to_inject = (AstTyped *) binding->node;
+
+            ENTITY_SUBMIT(injection);
+            return;
+        }
+
         Scope* target_scope = parser->package->scope;
 
         if (binding->flags & Ast_Flag_Private_Package)
@@ -3504,6 +3528,7 @@ OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer) {
     parser.parse_calls = 1;
     parser.tag_depth = 0;
     parser.overload_count = 0;
+    parser.injection_point = NULL;
 
     parser.polymorph_context = (PolymorphicContext) {
         .root_node = NULL,