Slight refactoring and adding compiler directives
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 7 Jul 2020 23:21:41 +0000 (18:21 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 7 Jul 2020 23:21:41 +0000 (18:21 -0500)
include/onyxastnodes.h
onyx
progs/test.onyx
src/onyxparser.c
src/onyxsempass.c
src/onyxsymres.c
src/onyxtypecheck.c
src/onyxutils.c
src/onyxwasm.c

index a46ef31d01d53629ef737b32c78e92467c07905d..c1507514aa564582a6c41532a4aa41eb013a9e68 100644 (file)
@@ -91,6 +91,10 @@ typedef enum OnyxAstFlags {
     ONYX_AST_FLAG_LVAL            = BH_BIT(1),
     ONYX_AST_FLAG_CONST           = BH_BIT(2),
     ONYX_AST_FLAG_COMPTIME        = BH_BIT(3),
+
+    // Function flags
+    ONYX_AST_FLAG_INLINE          = BH_BIT(8),
+    ONYX_AST_FLAG_INTRINSIC       = BH_BIT(9),
 } OnyxAstFlags;
 
 typedef enum OnyxUnaryOp {
@@ -192,8 +196,11 @@ struct AstNodeIf {
     AstNode base;
 
     AstNodeTyped *cond;
-    AstNode *true_block;
-    AstNode *false_block;
+
+    union {
+        AstNodeIf *as_if;
+        AstNodeBlock* as_block;
+    } true_block, false_block;
 };
 
 struct AstNodeWhile {
diff --git a/onyx b/onyx
index 283c8b4757ba6fae35aa15d501aed108cc124665..5b8ecd947fd64cc24d11ac298b2521f261bdeaa2 100755 (executable)
Binary files a/onyx and b/onyx differ
index 4f0c08ef43a63f15b103fd38bd3ee465bf4d9cd8..93c9d88a28df0fd50cd24778985aa052f4369a92 100644 (file)
@@ -11,6 +11,10 @@ export in_unit_circle :: proc (x: f32, y: f32) -> bool {
     return (x * x) + (y * y) < 1.0f;
 }
 
+sqrt_f32 ::
+    proc #intrinsic #inline
+    (val: f32) -> f32 ---
+
 // This is the entry point
 export main2 :: proc {
     i := 0;
@@ -49,6 +53,8 @@ export main2 :: proc {
 }
 
 export main :: proc {
+    print_f32(sqrt_f32(2.0f));
+    print_i32(5 * 6 + 2 * 3);
     print_bool(in_unit_circle(0.5f, 0.5f));
 
     big_num := fib(factorial(4));
index 4391ab5150832fd189691c25f2838873a1dc9bfc..f0590eb26ea7d7afc7048e7542917edf06943dd8 100644 (file)
@@ -38,7 +38,6 @@ static void insert_identifier(OnyxParser* parser, AstNode* ident, b32 is_local);
 static void remove_identifier(OnyxParser* parser, AstNode* ident);
 static AstNodeNumLit* parse_numeric_literal(OnyxParser* parser);
 static AstNodeTyped* parse_factor(OnyxParser* parser);
-static AstNodeTyped* parse_bin_op(OnyxParser* parser, AstNode* left);
 static AstNodeTyped* parse_expression(OnyxParser* parser);
 static AstNodeIf* parse_if_stmt(OnyxParser* parser);
 static AstNodeWhile* parse_while_stmt(OnyxParser* parser);
@@ -343,36 +342,36 @@ static AstNodeIf* parse_if_stmt(OnyxParser* parser) {
     expect(parser, TOKEN_TYPE_KEYWORD_IF);
 
     AstNodeTyped* cond = parse_expression(parser);
-    AstNode* true_block = (AstNode *) parse_block(parser);
+    AstNodeBlock* true_block = parse_block(parser);
 
     AstNodeIf* if_node = make_node(AstNodeIf, AST_NODE_KIND_IF);
     AstNodeIf* root_if = if_node;
 
     if_node->cond = cond;
     if (true_block != NULL)
-        if_node->true_block = true_block;
+        if_node->true_block.as_block = true_block;
 
     while (parser->curr_token->type == TOKEN_TYPE_KEYWORD_ELSEIF) {
         parser_next_token(parser);
         AstNodeIf* elseif_node = make_node(AstNodeIf, AST_NODE_KIND_IF);
 
         cond = parse_expression(parser);
-        true_block = (AstNode *) parse_block(parser);
+        true_block = parse_block(parser);
 
         elseif_node->cond = cond;
         if (true_block != NULL)
-            elseif_node->true_block = true_block;
+            elseif_node->true_block.as_block = true_block;
 
-        if_node->false_block = (AstNode *) elseif_node;
+        if_node->false_block.as_if = elseif_node;
         if_node = elseif_node;
     }
 
     if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_ELSE) {
         parser_next_token(parser);
 
-        AstNode* false_block = (AstNode *) parse_block(parser);
+        AstNodeBlock* false_block = parse_block(parser);
         if (false_block != NULL)
-            if_node->false_block = false_block;
+            if_node->false_block.as_block = false_block;
     }
 
     return root_if;
@@ -687,11 +686,30 @@ static AstNodeLocal* parse_function_params(OnyxParser* parser) {
     return first_param;
 }
 
+static b32 parse_possible_directive(OnyxParser* parser, const char* dir) {
+    if (parser->curr_token->type != '#') return 0;
+
+    expect(parser, '#');
+    OnyxToken* sym = expect(parser, TOKEN_TYPE_SYMBOL);
+
+    return strncmp(dir, sym->token, sym->length) == 0;
+}
+
 static AstNodeFunction* parse_function_definition(OnyxParser* parser) {
     expect(parser, TOKEN_TYPE_KEYWORD_PROC);
 
     AstNodeFunction* func_def = make_node(AstNodeFunction, AST_NODE_KIND_FUNCTION);
 
+    while (parser->curr_token->type == '#') {
+        if (parse_possible_directive(parser, "intrinsic")) {
+            func_def->base.flags |= ONYX_AST_FLAG_INTRINSIC;
+        }
+
+        else if (parse_possible_directive(parser, "inline")) {
+            func_def->base.flags |= ONYX_AST_FLAG_INLINE;
+        }
+    }
+
     AstNodeLocal* params = parse_function_params(parser);
     func_def->params = params;
 
@@ -875,9 +893,7 @@ OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, Onyx
     parser.allocator = alloc;
     parser.tokenizer = tokenizer;
     parser.curr_token = tokenizer->tokens;
-    parser.prev_token = NULL;
-    parser.msgs = msgs;
-
+    parser.prev_token = NULL; parser.msgs = msgs;
     return parser;
 }
 
index 6bc9553388870235d94ddd86d9724b7e0cebf495..d3b8c9059220fd2b01525b5c879c95d72f9c6bf6 100644 (file)
@@ -37,11 +37,11 @@ static void collapse_scopes(OnyxProgram* program) {
 
             if (block->base.kind == AST_NODE_KIND_IF) {
                 AstNodeIf* if_node = (AstNodeIf *) block;
-                if (if_node->true_block)
-                    bh_arr_push(traversal_queue, (AstNodeBlock *) if_node->true_block);
+                if (if_node->true_block.as_block != NULL)
+                    bh_arr_push(traversal_queue, if_node->true_block.as_block);
 
-                if (if_node->false_block)
-                    bh_arr_push(traversal_queue, (AstNodeBlock *) if_node->false_block);
+                if (if_node->false_block.as_block != NULL)
+                    bh_arr_push(traversal_queue, if_node->false_block.as_block);
 
             } else {
 
@@ -63,11 +63,11 @@ static void collapse_scopes(OnyxProgram* program) {
                         bh_arr_push(traversal_queue, ((AstNodeWhile *) walker)->body);
 
                     } else if (walker->kind == AST_NODE_KIND_IF) {
-                        if (((AstNodeIf *) walker)->true_block)
-                            bh_arr_push(traversal_queue, (AstNodeBlock *) ((AstNodeIf *) walker)->true_block);
+                        if (((AstNodeIf *) walker)->true_block.as_block != NULL)
+                            bh_arr_push(traversal_queue, ((AstNodeIf *) walker)->true_block.as_block);
 
-                        if (((AstNodeIf *) walker)->false_block)
-                            bh_arr_push(traversal_queue, (AstNodeBlock *) ((AstNodeIf *) walker)->false_block);
+                        if (((AstNodeIf *) walker)->false_block.as_block != NULL)
+                            bh_arr_push(traversal_queue, ((AstNodeIf *) walker)->false_block.as_block);
                     }
 
                     walker = walker->next;
index 32abbbb8a5880f0ef96661174c191a6d1e6c48be..b91e93b6599b961c709416cf782511ca63e4f18b 100644 (file)
@@ -172,22 +172,22 @@ static void symres_return(OnyxSemPassState* state, AstNodeReturn* ret) {
 
 static void symres_if(OnyxSemPassState* state, AstNodeIf* ifnode) {
     symres_expression(state, (AstNode **) &ifnode->cond);
-    if (ifnode->true_block) {
-        if (ifnode->true_block->kind == AST_NODE_KIND_BLOCK)
-            symres_block(state, (AstNodeBlock *) ifnode->true_block);
+    if (ifnode->true_block.as_if != NULL) {
+        if (ifnode->true_block.as_if->base.kind == AST_NODE_KIND_BLOCK)
+            symres_block(state, ifnode->true_block.as_block);
 
-        else if (ifnode->true_block->kind == AST_NODE_KIND_IF)
-            symres_if(state, (AstNodeIf *) ifnode->true_block);
+        else if (ifnode->true_block.as_if->base.kind == AST_NODE_KIND_IF)
+            symres_if(state, ifnode->true_block.as_if);
 
         else DEBUG_HERE;
     }
 
-    if (ifnode->false_block) {
-        if (ifnode->false_block->kind == AST_NODE_KIND_BLOCK)
-            symres_block(state, (AstNodeBlock *) ifnode->false_block);
+    if (ifnode->false_block.as_if != NULL) {
+        if (ifnode->false_block.as_if->base.kind == AST_NODE_KIND_BLOCK)
+            symres_block(state, ifnode->false_block.as_block);
 
-        else if (ifnode->false_block->kind == AST_NODE_KIND_IF)
-            symres_if(state, (AstNodeIf *) ifnode->false_block);
+        else if (ifnode->false_block.as_if->base.kind == AST_NODE_KIND_IF)
+            symres_if(state, ifnode->false_block.as_if);
 
         else DEBUG_HERE;
     }
index 1cc14cde91b378447c47e979a8ed82730f8058aa..04288c44b8ecd1789d63f42adbaadf2d7a176089 100644 (file)
@@ -83,8 +83,8 @@ static void typecheck_if(OnyxSemPassState* state, AstNodeIf* ifnode) {
         return;
     }
 
-    if (ifnode->true_block) typecheck_statement(state, ifnode->true_block);
-    if (ifnode->false_block) typecheck_statement(state, ifnode->false_block);
+    if (ifnode->true_block.as_if) typecheck_statement(state,  (AstNode *) ifnode->true_block.as_block);
+    if (ifnode->false_block.as_if) typecheck_statement(state, (AstNode *) ifnode->false_block.as_block);
 }
 
 static void typecheck_while(OnyxSemPassState* state, AstNodeWhile* whilenode) {
index 53c2f0ff21d6543a8bdc9d0bde98d0ba28a57b61..60fba38f6580998cf088922bd5ef10e7b124f0db 100644 (file)
@@ -196,15 +196,15 @@ void onyx_ast_print(AstNode* node, i32 indent) {
                 bh_printf("Condition:");
                 onyx_ast_print((AstNode *) if_node->cond, indent + 1);
             }
-            if (if_node->true_block) {
+            if (if_node->true_block.as_if) {
                 print_indent;
                 bh_printf("True block:");
-                onyx_ast_print(if_node->true_block, indent + 1);
+                onyx_ast_print((AstNode *) if_node->true_block.as_if, indent + 1);
             }
-            if (if_node->false_block) {
+            if (if_node->false_block.as_if) {
                 print_indent;
                 bh_printf("False block:");
-                onyx_ast_print(if_node->false_block, indent + 1);
+                onyx_ast_print((AstNode *) if_node->false_block.as_if, indent + 1);
             }
 
             break;
index f87965568b0f2a8f225151dd47d841583c7faa6b..9370999cdcb20c0c5357be542469a37091e7e895 100644 (file)
@@ -324,29 +324,29 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstN
 
     bh_arr_push(mod->structured_jump_target, 0);
 
-    if (if_node->true_block) {
+    if (if_node->true_block.as_if) {
         // NOTE: This is kind of gross, but making a function for this doesn't feel right
 
-        if (if_node->true_block->kind == AST_NODE_KIND_IF) {
-            forll (AstNode, stmt, if_node->true_block, next) {
+        if (if_node->true_block.as_if->base.kind == AST_NODE_KIND_IF) {
+            forll (AstNode, stmt, (AstNode *) if_node->true_block.as_if, next) {
                 compile_statement(mod, &code, stmt);
             }
-        } else if (if_node->true_block->kind == AST_NODE_KIND_BLOCK) {
-            forll (AstNode, stmt, ((AstNodeBlock *) if_node->true_block)->body, next) {
+        } else if (if_node->true_block.as_if->base.kind == AST_NODE_KIND_BLOCK) {
+            forll (AstNode, stmt, if_node->true_block.as_block->body, next) {
                 compile_statement(mod, &code, stmt);
             }
         }
     }
 
-    if (if_node->false_block) {
+    if (if_node->false_block.as_if) {
         bh_arr_push(code, ((WasmInstruction){ WI_ELSE, 0x00 }));
 
-        if (if_node->false_block->kind == AST_NODE_KIND_IF) {
-            forll (AstNode, stmt, if_node->false_block, next) {
+        if (if_node->false_block.as_if->base.kind == AST_NODE_KIND_IF) {
+            forll (AstNode, stmt, (AstNode *) if_node->false_block.as_if, next) {
                 compile_statement(mod, &code, stmt);
             }
-        } else if (if_node->false_block->kind == AST_NODE_KIND_BLOCK) {
-            forll (AstNode, stmt, ((AstNodeBlock *) if_node->false_block)->body, next) {
+        } else if (if_node->false_block.as_if->base.kind == AST_NODE_KIND_BLOCK) {
+            forll (AstNode, stmt, if_node->false_block.as_block->body, next) {
                 compile_statement(mod, &code, stmt);
             }
         }
@@ -875,7 +875,7 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxProgram* program) {
         }
         else if (import_kind == AST_NODE_KIND_GLOBAL) {
             module->next_global_idx++;
-            bh_imap_put(&module->global_map, (u64) (*foreign)->import, module->next_import_func_idx++);
+            bh_imap_put(&module->global_map, (u64) (*foreign)->import, module->next_import_global_idx++);
         }
 
         compile_foreign(module, *foreign);