added: `#if` works in macro expansions
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 9 Mar 2023 00:53:42 +0000 (18:53 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 9 Mar 2023 00:53:42 +0000 (18:53 -0600)
compiler/include/astnodes.h
compiler/src/clone.c
compiler/src/utils.c
compiler/src/wasm_intrinsics.h

index bfe28a13d1eead57a5a3305397ef679e5b258d36..2a43446c66e5e713a6f38ba09058e8a91219b3bb 100644 (file)
@@ -1745,6 +1745,7 @@ void introduce_build_options(bh_allocator a);
 // NOTE: Useful not inlined functions
 AstTyped* ast_reduce(bh_allocator a, AstTyped* node);
 AstNode* ast_clone(bh_allocator a, void* n);
+AstNode* ast_clone_with_captured_entities(bh_allocator a, void* n, bh_arr(AstNode *)* ents);
 AstFunction* clone_function_header(bh_allocator a, AstFunction* func);
 void clone_function_body(bh_allocator a, AstFunction* dest, AstFunction* source);
 
index 627319470dcbab87e3b39ef759e4abe2f77225e4..f5b31188bff850b537e349974acf930c50fc2b2e 100644 (file)
@@ -122,6 +122,17 @@ static inline i32 ast_kind_to_size(AstNode* node) {
     return 0;
 }
 
+static bh_arr(AstNode *) captured_entities=NULL;
+
+AstNode* ast_clone_with_captured_entities(bh_allocator a, void* n, bh_arr(AstNode *)* ents) {
+    captured_entities = *ents;
+
+    AstNode* cloned = ast_clone(a, n);
+
+    *ents = captured_entities;
+    return cloned;
+}
+
 AstNode* ast_clone_list(bh_allocator a, void* n) {
     AstNode* node = (AstNode *) n;
     if (node == NULL) return NULL;
@@ -140,7 +151,6 @@ AstNode* ast_clone_list(bh_allocator a, void* n) {
     return root;
 }
 
-static bh_arr(AstNode *) captured_entities=NULL;
 #define E(ent) do { \
     assert(captured_entities); \
     ent->entity = NULL; \
index d7016b3af0284f90f026ff615374eab31d849161..2e235de9d501fb9a8d7fbca39a5df52c76d1768e 100644 (file)
@@ -676,7 +676,10 @@ void expand_macro(AstCall** pcall, AstFunction* template) {
     assert(template->type != NULL);
     assert(template->type->kind == Type_Kind_Function);
 
-    AstBlock* expansion = (AstBlock *) ast_clone(context.ast_alloc, template->body);
+    bh_arr(AstNode *) nodes_that_need_entities=NULL;
+    bh_arr_new(global_heap_allocator, nodes_that_need_entities, 4);
+
+    AstBlock* expansion = (AstBlock *) ast_clone_with_captured_entities(context.ast_alloc, template->body, &nodes_that_need_entities);
     expansion->rules = Block_Rule_Macro;
     expansion->scope = NULL;
     expansion->next = call->next;
@@ -720,7 +723,34 @@ void expand_macro(AstCall** pcall, AstFunction* template) {
     if (template->poly_scope != NULL)
         scope_include(argument_scope, template->poly_scope, call->token->pos);
 
+    if (bh_arr_length(nodes_that_need_entities) > 0) {
+        // :CopyPaste from symres_function
+        bh_arr_each(AstNode *, node, nodes_that_need_entities) {
+            // This makes a lot of assumptions about how these nodes are being processed,
+            // and I don't want to start using this with other nodes without considering
+            // what the ramifications of that is.
+            assert((*node)->kind == Ast_Kind_Static_If || (*node)->kind == Ast_Kind_File_Contents);
+
+            Scope *scope = argument_scope;
+
+            if ((*node)->kind == Ast_Kind_Static_If) {
+                AstIf *static_if = (AstIf *) *node;
+                assert(static_if->defined_in_scope);
+                scope = static_if->defined_in_scope;
+
+                if (template->poly_scope) {
+                    scope = scope_create(context.ast_alloc, scope, static_if->token->pos);
+                    scope_include(scope, template->poly_scope, static_if->token->pos);
+                }
+            }
+
+            add_entities_for_node(NULL, *node, scope, macro->entity->package);
+        }
+    }
+
     *(AstNode **) pcall = subst;
+
+    bh_arr_free(nodes_that_need_entities);
     return;
 }
 
index 49dae8c0e628831b930993d4f04aa16b1cba218c..653ab7e1773eb55df4cbef4d097c312eb29a6703 100644 (file)
@@ -143,9 +143,11 @@ EMIT_FUNC(initialize_type, Type* type, OnyxToken* where) {
         }
 
         default:
-            onyx_report_error(where->pos, Error_Critical,
-                    "Unable to initialize type, '%s'. The reason for this is largely due to the compiler not knowing what the initial value should be.",
-                    type_get_name(type)); 
+            //
+            // If none of the above, simply zero the buffer.
+            WIL(NULL, WI_I32_CONST, 0);
+            WIL(NULL, WI_I32_CONST, type_size_of(type));
+            emit_wasm_fill(mod, &code, NULL);
             break;
     }