Browse Source

Implement if statements

gingerBill 2 years ago
parent
commit
32ac319525
4 changed files with 71 additions and 16 deletions
  1. 8 2
      src/tilde_backend.hpp
  2. 5 10
      src/tilde_expr.cpp
  3. 2 2
      src/tilde_proc.cpp
  4. 56 2
      src/tilde_stmt.cpp

+ 8 - 2
src/tilde_backend.hpp

@@ -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
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);
 	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_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);
 			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_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);
 			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 *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_);
 		cg_build_cond(p, te->cond, then, else_);
 		tb_inst_set_control(p->func, then);
 		tb_inst_set_control(p->func, then);

+ 2 - 2
src/tilde_proc.cpp

@@ -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
src/tilde_stmt.cpp

@@ -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);
-			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);
 			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;