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 {
AstNode base;
AstNodeTyped *cond;
- AstNode *true_block;
- AstNode *false_block;
+
+ union {
+ AstNodeIf *as_if;
+ AstNodeBlock* as_block;
+ } true_block, false_block;
};
struct AstNodeWhile {
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;
}
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));
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);
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;
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;
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;
}
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 {
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;
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;
}
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) {
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;
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);
}
}
}
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);