From 32ac319525832794f3758daf3a08869deca30770 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 19 Jul 2023 12:55:44 +0100 Subject: [PATCH] Implement if statements --- src/tilde_backend.hpp | 10 ++++++-- src/tilde_expr.cpp | 15 ++++------- src/tilde_proc.cpp | 4 +-- src/tilde_stmt.cpp | 58 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 71 insertions(+), 16 deletions(-) diff --git a/src/tilde_backend.hpp b/src/tilde_backend.hpp index 8fc02e3fa..bed3fd6a7 100644 --- a/src/tilde_backend.hpp +++ b/src/tilde_backend.hpp @@ -203,7 +203,7 @@ struct cgModule { }; #ifndef ABI_PKG_NAME_SEPARATOR -#define ABI_PKG_NAME_SEPARATOR "." +#define ABI_PKG_NAME_SEPARATOR "@" #endif 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_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_arith(cgProcedure *p, TokenKind op, cgValue lhs, cgValue rhs, Type *type); \ No newline at end of file +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; +} diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index e754d473f..61dabbb52 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -1850,15 +1850,13 @@ gb_internal cgValue cg_build_cond(cgProcedure *p, Ast *cond, TB_Node *true_block case_ast_node(be, BinaryExpr, cond); if (be->op.kind == Token_CmpAnd) { - TB_Node *block = tb_inst_region(p->func); - tb_inst_set_region_name(block, -1, "cmp.and"); + TB_Node *block = tb_inst_region_with_name(p->func, -1, "cmp_and"); cg_build_cond(p, be->left, block, false_block); tb_inst_set_control(p->func, block); cg_build_cond(p, be->right, true_block, false_block); return no_comptime_short_circuit; } else if (be->op.kind == Token_CmpOr) { - TB_Node *block = tb_inst_region(p->func); - tb_inst_set_region_name(block, -1, "cmp.or"); + TB_Node *block = tb_inst_region_with_name(p->func, -1, "cmp_or"); cg_build_cond(p, be->left, true_block, block); tb_inst_set_control(p->func, 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] = {}; TB_Node *incoming_regions[2] = {}; - TB_Node *then = tb_inst_region(p->func); - TB_Node *done = tb_inst_region(p->func); - TB_Node *else_ = tb_inst_region(p->func); - 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"); + 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_ = tb_inst_region_with_name(p->func, -1, "if_else"); cg_build_cond(p, te->cond, then, else_); tb_inst_set_control(p->func, then); diff --git a/src/tilde_proc.cpp b/src/tilde_proc.cpp index c925ee692..7f67f3a5c 100644 --- a/src/tilde_proc.cpp +++ b/src/tilde_proc.cpp @@ -243,7 +243,7 @@ gb_internal void cg_procedure_end(cgProcedure *p) { tb_inst_ret(p->func, 0, nullptr); } // if (p->name == "main") { - if (p->name == "bug.main") { + if (p->name == "bug" ABI_PKG_NAME_SEPARATOR "main") { TB_Arena *arena = tb_default_arena(); defer (arena->free(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); defer (cg_procedure_end(p)); - if (p->name != "bug.main" && + if (p->name != "bug" ABI_PKG_NAME_SEPARATOR "main" && p->name != "main") { return; } diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp index ff4c007ea..bd856e542 100644 --- a/src/tilde_stmt.cpp +++ b/src/tilde_stmt.cpp @@ -852,6 +852,57 @@ gb_internal void cg_build_return_stmt(cgProcedure *p, Slice 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) { 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); TB_Node *done = nullptr; if (bs->label != nullptr) { - done = tb_inst_region(p->func); - tb_inst_set_region_name(done, -1, "block.done"); + done = tb_inst_region_with_name(p->func, -1, "block_done"); cgTargetList *tl = cg_push_target_list(p, bs->label, done, nullptr, nullptr); 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); case_end; + case_ast_node(is, IfStmt, node); + cg_build_if_stmt(p, node); + case_end; + default: GB_PANIC("TODO cg_build_stmt %.*s", LIT(ast_strings[node->kind])); break;