mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Implement if statements
This commit is contained in:
@@ -203,7 +203,7 @@ struct cgModule {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifndef ABI_PKG_NAME_SEPARATOR
|
#ifndef ABI_PKG_NAME_SEPARATOR
|
||||||
#define ABI_PKG_NAME_SEPARATOR "."
|
#define ABI_PKG_NAME_SEPARATOR "@"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gb_global Entity *cg_global_type_info_data_entity = {};
|
gb_global Entity *cg_global_type_info_data_entity = {};
|
||||||
@@ -271,4 +271,10 @@ gb_internal cgValue cg_emit_deep_field_gep(cgProcedure *p, cgValue e, Selection
|
|||||||
gb_internal cgValue cg_emit_conv(cgProcedure *p, cgValue value, Type *t);
|
gb_internal cgValue cg_emit_conv(cgProcedure *p, cgValue value, Type *t);
|
||||||
gb_internal cgValue cg_emit_comp_against_nil(cgProcedure *p, TokenKind op_kind, cgValue x);
|
gb_internal cgValue cg_emit_comp_against_nil(cgProcedure *p, TokenKind op_kind, cgValue x);
|
||||||
gb_internal cgValue cg_emit_comp(cgProcedure *p, TokenKind op_kind, cgValue left, cgValue right);
|
gb_internal cgValue cg_emit_comp(cgProcedure *p, TokenKind op_kind, cgValue left, cgValue right);
|
||||||
gb_internal cgValue cg_emit_arith(cgProcedure *p, TokenKind op, cgValue lhs, cgValue rhs, Type *type);
|
gb_internal cgValue cg_emit_arith(cgProcedure *p, TokenKind op, cgValue lhs, cgValue rhs, Type *type);
|
||||||
|
|
||||||
|
gb_internal TB_Node *tb_inst_region_with_name(TB_Function *f, ptrdiff_t n, char const *name) {
|
||||||
|
TB_Node *region = tb_inst_region(f);
|
||||||
|
tb_inst_set_region_name(region, n, name);
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|||||||
+5
-10
@@ -1850,15 +1850,13 @@ gb_internal cgValue cg_build_cond(cgProcedure *p, Ast *cond, TB_Node *true_block
|
|||||||
|
|
||||||
case_ast_node(be, BinaryExpr, cond);
|
case_ast_node(be, BinaryExpr, cond);
|
||||||
if (be->op.kind == Token_CmpAnd) {
|
if (be->op.kind == Token_CmpAnd) {
|
||||||
TB_Node *block = tb_inst_region(p->func);
|
TB_Node *block = tb_inst_region_with_name(p->func, -1, "cmp_and");
|
||||||
tb_inst_set_region_name(block, -1, "cmp.and");
|
|
||||||
cg_build_cond(p, be->left, block, false_block);
|
cg_build_cond(p, be->left, block, false_block);
|
||||||
tb_inst_set_control(p->func, block);
|
tb_inst_set_control(p->func, block);
|
||||||
cg_build_cond(p, be->right, true_block, false_block);
|
cg_build_cond(p, be->right, true_block, false_block);
|
||||||
return no_comptime_short_circuit;
|
return no_comptime_short_circuit;
|
||||||
} else if (be->op.kind == Token_CmpOr) {
|
} else if (be->op.kind == Token_CmpOr) {
|
||||||
TB_Node *block = tb_inst_region(p->func);
|
TB_Node *block = tb_inst_region_with_name(p->func, -1, "cmp_or");
|
||||||
tb_inst_set_region_name(block, -1, "cmp.or");
|
|
||||||
cg_build_cond(p, be->left, true_block, block);
|
cg_build_cond(p, be->left, true_block, block);
|
||||||
tb_inst_set_control(p->func, block);
|
tb_inst_set_control(p->func, block);
|
||||||
cg_build_cond(p, be->right, true_block, false_block);
|
cg_build_cond(p, be->right, true_block, false_block);
|
||||||
@@ -2053,12 +2051,9 @@ gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) {
|
|||||||
cgValue incoming_values[2] = {};
|
cgValue incoming_values[2] = {};
|
||||||
TB_Node *incoming_regions[2] = {};
|
TB_Node *incoming_regions[2] = {};
|
||||||
|
|
||||||
TB_Node *then = tb_inst_region(p->func);
|
TB_Node *then = tb_inst_region_with_name(p->func, -1, "if_then");
|
||||||
TB_Node *done = tb_inst_region(p->func);
|
TB_Node *done = tb_inst_region_with_name(p->func, -1, "if_done");
|
||||||
TB_Node *else_ = tb_inst_region(p->func);
|
TB_Node *else_ = tb_inst_region_with_name(p->func, -1, "if_else");
|
||||||
tb_inst_set_region_name(then, -1, "if.then");
|
|
||||||
tb_inst_set_region_name(done, -1, "if.done");
|
|
||||||
tb_inst_set_region_name(else_, -1, "if.else");
|
|
||||||
|
|
||||||
cg_build_cond(p, te->cond, then, else_);
|
cg_build_cond(p, te->cond, then, else_);
|
||||||
tb_inst_set_control(p->func, then);
|
tb_inst_set_control(p->func, then);
|
||||||
|
|||||||
+2
-2
@@ -243,7 +243,7 @@ gb_internal void cg_procedure_end(cgProcedure *p) {
|
|||||||
tb_inst_ret(p->func, 0, nullptr);
|
tb_inst_ret(p->func, 0, nullptr);
|
||||||
}
|
}
|
||||||
// if (p->name == "main") {
|
// if (p->name == "main") {
|
||||||
if (p->name == "bug.main") {
|
if (p->name == "bug" ABI_PKG_NAME_SEPARATOR "main") {
|
||||||
TB_Arena *arena = tb_default_arena();
|
TB_Arena *arena = tb_default_arena();
|
||||||
defer (arena->free(arena));
|
defer (arena->free(arena));
|
||||||
TB_FuncOpt *opt = tb_funcopt_enter(p->func, arena);
|
TB_FuncOpt *opt = tb_funcopt_enter(p->func, arena);
|
||||||
@@ -262,7 +262,7 @@ gb_internal void cg_procedure_generate(cgProcedure *p) {
|
|||||||
cg_procedure_begin(p);
|
cg_procedure_begin(p);
|
||||||
defer (cg_procedure_end(p));
|
defer (cg_procedure_end(p));
|
||||||
|
|
||||||
if (p->name != "bug.main" &&
|
if (p->name != "bug" ABI_PKG_NAME_SEPARATOR "main" &&
|
||||||
p->name != "main") {
|
p->name != "main") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+56
-2
@@ -852,6 +852,57 @@ gb_internal void cg_build_return_stmt(cgProcedure *p, Slice<Ast *> const &return
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_internal void cg_build_if_stmt(cgProcedure *p, Ast *node) {
|
||||||
|
ast_node(is, IfStmt, node);
|
||||||
|
cg_scope_open(p, is->scope); // Scope #1
|
||||||
|
defer (cg_scope_close(p, cgDeferExit_Default, nullptr));
|
||||||
|
|
||||||
|
if (is->init != nullptr) {
|
||||||
|
TB_Node *init = tb_inst_region_with_name(p->func, -1, "if_init");
|
||||||
|
tb_inst_goto(p->func, init);
|
||||||
|
tb_inst_set_control(p->func, init);
|
||||||
|
cg_build_stmt(p, is->init);
|
||||||
|
}
|
||||||
|
|
||||||
|
TB_Node *then = tb_inst_region_with_name(p->func, -1, "if_then");
|
||||||
|
TB_Node *done = tb_inst_region_with_name(p->func, -1, "if_done");
|
||||||
|
TB_Node *else_ = done;
|
||||||
|
if (is->else_stmt != nullptr) {
|
||||||
|
else_ = tb_inst_region_with_name(p->func, -1, "if_else");
|
||||||
|
}
|
||||||
|
|
||||||
|
cgValue cond = cg_build_cond(p, is->cond, then, else_);
|
||||||
|
gb_unused(cond);
|
||||||
|
|
||||||
|
if (is->label != nullptr) {
|
||||||
|
cgTargetList *tl = cg_push_target_list(p, is->label, done, nullptr, nullptr);
|
||||||
|
tl->is_block = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(bill): should we do a constant check?
|
||||||
|
// Which philosophy are we following?
|
||||||
|
// - IR represents what the code represents (probably this)
|
||||||
|
// - IR represents what the code executes
|
||||||
|
|
||||||
|
tb_inst_set_control(p->func, then);
|
||||||
|
|
||||||
|
cg_build_stmt(p, is->body);
|
||||||
|
|
||||||
|
tb_inst_goto(p->func, done);
|
||||||
|
|
||||||
|
if (is->else_stmt != nullptr) {
|
||||||
|
tb_inst_set_control(p->func, else_);
|
||||||
|
|
||||||
|
cg_scope_open(p, scope_of_node(is->else_stmt));
|
||||||
|
cg_build_stmt(p, is->else_stmt);
|
||||||
|
cg_scope_close(p, cgDeferExit_Default, nullptr);
|
||||||
|
|
||||||
|
tb_inst_goto(p->func, done);
|
||||||
|
}
|
||||||
|
|
||||||
|
tb_inst_set_control(p->func, done);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_internal void cg_build_stmt(cgProcedure *p, Ast *node) {
|
gb_internal void cg_build_stmt(cgProcedure *p, Ast *node) {
|
||||||
Ast *prev_stmt = p->curr_stmt;
|
Ast *prev_stmt = p->curr_stmt;
|
||||||
@@ -907,8 +958,7 @@ gb_internal void cg_build_stmt(cgProcedure *p, Ast *node) {
|
|||||||
case_ast_node(bs, BlockStmt, node);
|
case_ast_node(bs, BlockStmt, node);
|
||||||
TB_Node *done = nullptr;
|
TB_Node *done = nullptr;
|
||||||
if (bs->label != nullptr) {
|
if (bs->label != nullptr) {
|
||||||
done = tb_inst_region(p->func);
|
done = tb_inst_region_with_name(p->func, -1, "block_done");
|
||||||
tb_inst_set_region_name(done, -1, "block.done");
|
|
||||||
cgTargetList *tl = cg_push_target_list(p, bs->label, done, nullptr, nullptr);
|
cgTargetList *tl = cg_push_target_list(p, bs->label, done, nullptr, nullptr);
|
||||||
tl->is_block = true;
|
tl->is_block = true;
|
||||||
}
|
}
|
||||||
@@ -1040,6 +1090,10 @@ gb_internal void cg_build_stmt(cgProcedure *p, Ast *node) {
|
|||||||
cg_build_return_stmt(p, rs->results);
|
cg_build_return_stmt(p, rs->results);
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(is, IfStmt, node);
|
||||||
|
cg_build_if_stmt(p, node);
|
||||||
|
case_end;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
GB_PANIC("TODO cg_build_stmt %.*s", LIT(ast_strings[node->kind]));
|
GB_PANIC("TODO cg_build_stmt %.*s", LIT(ast_strings[node->kind]));
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user