From: Brendan Hansen Date: Thu, 9 Mar 2023 00:53:42 +0000 (-0600) Subject: added: `#if` works in macro expansions X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=7c8b2935f40aef9d64056af64546e941924a2f09;p=onyx.git added: `#if` works in macro expansions --- diff --git a/compiler/include/astnodes.h b/compiler/include/astnodes.h index bfe28a13..2a43446c 100644 --- a/compiler/include/astnodes.h +++ b/compiler/include/astnodes.h @@ -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); diff --git a/compiler/src/clone.c b/compiler/src/clone.c index 62731947..f5b31188 100644 --- a/compiler/src/clone.c +++ b/compiler/src/clone.c @@ -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; \ diff --git a/compiler/src/utils.c b/compiler/src/utils.c index d7016b3a..2e235de9 100644 --- a/compiler/src/utils.c +++ b/compiler/src/utils.c @@ -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; } diff --git a/compiler/src/wasm_intrinsics.h b/compiler/src/wasm_intrinsics.h index 49dae8c0..653ab7e1 100644 --- a/compiler/src/wasm_intrinsics.h +++ b/compiler/src/wasm_intrinsics.h @@ -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; }