added macros at the expression level
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 28 Aug 2021 20:10:18 +0000 (15:10 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 28 Aug 2021 20:10:18 +0000 (15:10 -0500)
bin/onyx
docs/bugs
src/onyxchecker.c
src/onyxsymres.c
src/onyxutils.c
src/onyxwasm.c

index 7758c4dc245a51f75514141ce8bbd2c91bd6cc9b..a124e1379839d79e75cb1b5a98ed41908f01d3d6 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index 55a744520cdc7fa247b5526ec8fbf25c5124ee6a..c77390864d936172a39a223e4b44711c70deaba8 100644 (file)
--- a/docs/bugs
+++ b/docs/bugs
@@ -1,6 +1,6 @@
 List of known bugs:
 
-[ ] macros are not allowed at the expression level. This is not necessarily a bug, but does
+[X] macros are not allowed at the expression level. This is not necessarily a bug, but does
     bring many complications to the table about how resolve this. Current solution is to
     turn expression macros (macros that specify a return value) into a `do` expression.
 
index 9a7b4f8ded6aefa5fb0c106904752807222629c8..a2ff9458efcf0876968e4fc6896ba97b399df2cd 100644 (file)
@@ -462,10 +462,6 @@ static CheckStatus check_resolve_callee(AstCall* call, AstTyped** effective_call
     }
 
     if (callee->kind == Ast_Kind_Macro) {
-        if (current_checking_level == EXPRESSION_LEVEL) {
-            ERROR(call->token->pos, "Macros calls are not allowed at the expression level yet.");
-        }
-
         calling_a_macro = 1;
         call->callee = callee;
 
index 475e3f951449d2503d3b09bd69eae1526f20715e..0bc9b32a801147408db3963679eaf8623fd6649a 100644 (file)
@@ -359,10 +359,14 @@ static SymresStatus symres_method_call(AstBinaryOp** mcall) {
     SYMRES(expression, &(*mcall)->left);
     if ((*mcall)->left == NULL) return Symres_Error;
 
-    AstFieldAccess* implicit_field_access = make_field_access(context.ast_alloc, (*mcall)->left, NULL);
-    implicit_field_access->token = call_node->callee->token;
-    call_node->callee = (AstTyped *) implicit_field_access;
+    if (((*mcall)->flags & Ast_Flag_Has_Been_Symres) == 0) {
+        AstFieldAccess* implicit_field_access = make_field_access(context.ast_alloc, (*mcall)->left, NULL);
+        implicit_field_access->token = call_node->callee->token;
+        call_node->callee = (AstTyped *) implicit_field_access;
+    }
+
     SYMRES(expression, (AstTyped **) &call_node);
+    (*mcall)->flags |= Ast_Flag_Has_Been_Symres;
 
     return Symres_Success;
 }
index 6e64c76874f923f86fbc391348a39a6a145507b4..3e44f60c835c4cde9b5d28668d08a3e06fac9c9e 100644 (file)
@@ -1212,12 +1212,26 @@ void expand_macro(AstCall** pcall, AstFunction* template) {
 
     assert(template->kind == Ast_Kind_Function);
     assert(template->type != NULL);
+    assert(template->type->kind == Type_Kind_Function);
 
     AstBlock* expansion = (AstBlock *) ast_clone(context.ast_alloc, template->body);
     expansion->rules = Block_Rule_Macro;
     expansion->scope = NULL;
     expansion->next = call->next;
 
+    AstNode* subst = (AstNode *) expansion;
+
+    if (template->type->Function.return_type != &basic_types[Basic_Kind_Void]) {
+        AstDoBlock* doblock = (AstDoBlock *) onyx_ast_node_new(context.ast_alloc, sizeof(AstDoBlock), Ast_Kind_Do_Block);
+        doblock->token = expansion->token;
+        doblock->block = expansion;
+        doblock->type = template->type->Function.return_type;
+        doblock->next = expansion->next;
+        expansion->next = NULL;
+
+        subst = (AstNode *) doblock;
+    }
+
     Scope* argument_scope = scope_create(context.ast_alloc, NULL, call->token->pos);
     if (expansion->binding_scope != NULL)
         scope_include(argument_scope, expansion->binding_scope, call->token->pos);
@@ -1245,7 +1259,7 @@ void expand_macro(AstCall** pcall, AstFunction* template) {
         bh_table_each_end;
     }
 
-    *(AstBlock **) pcall = expansion;
+    *(AstNode **) pcall = subst;
     return;
 }
 
index c15a66d04288e9fbabec2bb4d5e278780bae53d3..ff62a18514cd4db3459e91e49b20758c5fa23123 100644 (file)
@@ -2296,6 +2296,8 @@ EMIT_FUNC(if_expression, AstIfExpression* if_expr) {
         WIL(WI_LOCAL_GET, result_local);
     }
 
+    local_free(mod->local_alloc, (AstTyped *) if_expr);
+
     *pcode = code;
 }
 
@@ -2320,6 +2322,7 @@ EMIT_FUNC(do_block, AstDoBlock* doblock) {
     }
 
     bh_arr_pop(mod->return_location_stack);
+    local_free(mod->local_alloc, (AstTyped *) doblock);
 
     *pcode = code;
 }