Browse Source

Add `for` and `+=` assignments

gingerBill 2 years ago
parent
commit
533f6a552c
3 changed files with 88 additions and 30 deletions
  1. 12 0
      src/tilde_backend.hpp
  2. 7 8
      src/tilde_expr.cpp
  3. 69 22
      src/tilde_stmt.cpp

+ 12 - 0
src/tilde_backend.hpp

@@ -274,6 +274,18 @@ gb_internal cgValue cg_emit_comp(cgProcedure *p, TokenKind op_kind, cgValue left
 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) {
+	#if 1
+	if (n < 0) {
+		n = gb_strlen(name);
+	}
+	static std::atomic<u32> id;
+
+	char *new_name = gb_alloc_array(temporary_allocator(), char, n+12);
+	n = -1 + gb_snprintf(new_name, n+11, "%.*s_%u", cast(int)n, name, 1+id.fetch_add(1));
+
+	name = new_name;
+	#endif
+
 	TB_Node *region = tb_inst_region(f);
 	tb_inst_set_region_name(region, n, name);
 	return region;

+ 7 - 8
src/tilde_expr.cpp

@@ -283,12 +283,12 @@ gb_internal cgValue cg_emit_comp(cgProcedure *p, TokenKind op_kind, cgValue left
 
 
 		// TokenKind cmp_op = Token_And;
-		// lbValue res = lb_const_bool(p->module, t_llvm_bool, true);
+		// lbValue res = lb_const_bool(p->module, t_bool, true);
 		// if (op_kind == Token_NotEq) {
-		// 	res = lb_const_bool(p->module, t_llvm_bool, false);
+		// 	res = lb_const_bool(p->module, t_bool, false);
 		// 	cmp_op = Token_Or;
 		// } else if (op_kind == Token_CmpEq) {
-		// 	res = lb_const_bool(p->module, t_llvm_bool, true);
+		// 	res = lb_const_bool(p->module, t_bool, true);
 		// 	cmp_op = Token_And;
 		// }
 
@@ -706,9 +706,9 @@ gb_internal cgValue cg_emit_comp_against_nil(cgProcedure *p, TokenKind op_kind,
 			GB_PANIC("TODO(bill): cg_emit_struct_ev");
 			// if (type_size_of(t) == 0) {
 			// 	if (op_kind == Token_CmpEq) {
-			// 		return cg_const_bool(p->module, t_llvm_bool, true);
+			// 		return cg_const_bool(p->module, t_bool, true);
 			// 	} else if (op_kind == Token_NotEq) {
-			// 		return cg_const_bool(p->module, t_llvm_bool, false);
+			// 		return cg_const_bool(p->module, t_bool, false);
 			// 	}
 			// } else if (is_type_union_maybe_pointer(t)) {
 			// 	cgValue tag = cg_emit_transmute(p, x, t_rawptr);
@@ -1867,13 +1867,12 @@ gb_internal cgValue cg_build_cond(cgProcedure *p, Ast *cond, TB_Node *true_block
 
 	cgValue v = {};
 	if (cg_is_expr_untyped_const(cond)) {
-		v = cg_expr_untyped_const_to_typed(p, cond, t_llvm_bool);
+		v = cg_expr_untyped_const_to_typed(p, cond, t_bool);
 	} else {
 		v = cg_build_expr(p, cond);
 	}
 
-	v = cg_emit_conv(p, v, t_llvm_bool);
-
+	GB_ASSERT(v.kind == cgValue_Value);
 	tb_inst_if(p->func, v.node, true_block, false_block);
 
 	return v;

+ 69 - 22
src/tilde_stmt.cpp

@@ -778,48 +778,46 @@ gb_internal void cg_build_assign_stmt(cgProcedure *p, AstAssignStmt *as) {
 	// NOTE(bill): Only 1 += 1 is allowed, no tuples
 	// +=, -=, etc
 
-	GB_PANIC("do += etc assignments");
-
 	i32 op_ = cast(i32)as->op.kind;
 	op_ += Token_Add - Token_AddEq; // Convert += to +
 	TokenKind op = cast(TokenKind)op_;
 
-	gb_unused(op);
-/*
 	if (op == Token_CmpAnd || op == Token_CmpOr) {
-		Type *type = as->lhs[0]->tav.type;
-		cgValue new_value = lb_emit_logical_binary_expr(p, op, as->lhs[0], as->rhs[0], type);
+		GB_PANIC("TODO(bill): cg_emit_logical_binary_expr");
+		// Type *type = as->lhs[0]->tav.type;
+		// cgValue new_value = cg_emit_logical_binary_expr(p, op, as->lhs[0], as->rhs[0], type);
 
-		cgAddr lhs = lb_build_addr(p, as->lhs[0]);
-		cg_addr_store(p, lhs, new_value);
+		// cgAddr lhs = cg_build_addr(p, as->lhs[0]);
+		// cg_addr_store(p, lhs, new_value);
 	} else {
-		cgAddr lhs = lb_build_addr(p, as->lhs[0]);
-		cgValue value = lb_build_expr(p, as->rhs[0]);
-		Type *lhs_type = lb_addr_type(lhs);
+		cgAddr lhs = cg_build_addr(p, as->lhs[0]);
+		cgValue value = cg_build_expr(p, as->rhs[0]);
+		Type *lhs_type = cg_addr_type(lhs);
 
 		// NOTE(bill): Allow for the weird edge case of:
 		// array *= matrix
 		if (op == Token_Mul && is_type_matrix(value.type) && is_type_array(lhs_type)) {
-			cgValue old_value = lb_addr_load(p, lhs);
-			Type *type = old_value.type;
-			cgValue new_value = lb_emit_vector_mul_matrix(p, old_value, value, type);
-			cg_addr_store(p, lhs, new_value);
-			return;
+			GB_PANIC("TODO(bill): array *= matrix");
+			// cgValue old_value = cg_addr_load(p, lhs);
+			// Type *type = old_value.type;
+			// cgValue new_value = cg_emit_vector_mul_matrix(p, old_value, value, type);
+			// cg_addr_store(p, lhs, new_value);
+			// return;
 		}
 
 		if (is_type_array(lhs_type)) {
-			lb_build_assign_stmt_array(p, op, lhs, value);
-			return;
+			GB_PANIC("TODO(bill): cg_build_assign_stmt_array");
+			// cg_build_assign_stmt_array(p, op, lhs, value);
+			// return;
 		} else {
-			cgValue old_value = lb_addr_load(p, lhs);
+			cgValue old_value = cg_addr_load(p, lhs);
 			Type *type = old_value.type;
 
-			cgValue change = lb_emit_conv(p, value, type);
-			cgValue new_value = lb_emit_arith(p, op, old_value, change, type);
+			cgValue change = cg_emit_conv(p, value, type);
+			cgValue new_value = cg_emit_arith(p, op, old_value, change, type);
 			cg_addr_store(p, lhs, new_value);
 		}
 	}
-*/
 }
 
 gb_internal void cg_build_return_stmt(cgProcedure *p, Slice<Ast *> const &return_results) {
@@ -903,6 +901,51 @@ gb_internal void cg_build_if_stmt(cgProcedure *p, Ast *node) {
 	tb_inst_set_control(p->func, done);
 }
 
+gb_internal void cg_build_for_stmt(cgProcedure *p, Ast *node) {
+	ast_node(fs, ForStmt, node);
+
+	cg_scope_open(p, fs->scope);
+	defer (cg_scope_close(p, cgDeferExit_Default, nullptr));
+
+	if (fs->init != nullptr) {
+		TB_Node *init = tb_inst_region_with_name(p->func, -1, "for_init");
+		tb_inst_goto(p->func, init);
+		tb_inst_set_control(p->func, init);
+		cg_build_stmt(p, fs->init);
+	}
+	TB_Node *body = tb_inst_region_with_name(p->func, -1, "for_body");
+	TB_Node *done = tb_inst_region_with_name(p->func, -1, "for_done");
+	TB_Node *loop = body;
+	if (fs->cond != nullptr) {
+		loop = tb_inst_region_with_name(p->func, -1, "for_loop");
+	}
+	TB_Node *post = loop;
+	if (fs->post != nullptr) {
+		post = tb_inst_region_with_name(p->func, -1, "for_post");
+	}
+
+	tb_inst_goto(p->func, loop);
+	tb_inst_set_control(p->func, loop);
+
+	if (loop != body) {
+		cg_build_cond(p, fs->cond, body, done);
+		tb_inst_set_control(p->func, body);
+	}
+
+	cg_push_target_list(p, fs->label, done, post, nullptr);
+	cg_build_stmt(p, fs->body);
+	cg_pop_target_list(p);
+
+	tb_inst_goto(p->func, post);
+
+	if (fs->post != nullptr) {
+		tb_inst_set_control(p->func, post);
+		cg_build_stmt(p, fs->post);
+		tb_inst_goto(p->func, loop);
+	}
+	tb_inst_set_control(p->func, done);
+}
+
 
 gb_internal void cg_build_stmt(cgProcedure *p, Ast *node) {
 	Ast *prev_stmt = p->curr_stmt;
@@ -1094,6 +1137,10 @@ gb_internal void cg_build_stmt(cgProcedure *p, Ast *node) {
 		cg_build_if_stmt(p, node);
 	case_end;
 
+	case_ast_node(fs, ForStmt, node);
+		cg_build_for_stmt(p, node);
+	case_end;
+
 	default:
 		GB_PANIC("TODO cg_build_stmt %.*s", LIT(ast_strings[node->kind]));
 		break;