Browse Source

Stub out expr and const files

gingerBill 2 years ago
parent
commit
6545cc2d48
5 changed files with 283 additions and 64 deletions
  1. 108 59
      src/tilde_backend.cpp
  2. 2 0
      src/tilde_backend.hpp
  3. 5 0
      src/tilde_const.cpp
  4. 68 0
      src/tilde_expr.cpp
  5. 100 5
      src/tilde_stmt.cpp

+ 108 - 59
src/tilde_backend.cpp

@@ -458,6 +458,22 @@ gb_internal TB_FunctionPrototype *cg_procedure_type_as_prototype(cgModule *m, Ty
 			case Basic_f64be: param.dt = TB_TYPE_F64; break;
 			case Basic_f64be: param.dt = TB_TYPE_F64; break;
 			}
 			}
 
 
+		case Type_Pointer:
+		case Type_MultiPointer:
+		case Type_Proc:
+			param.dt = TB_TYPE_PTR;
+			break;
+
+		default:
+			switch (sz) {
+			case 1: param.dt = TB_TYPE_I8;  break;
+			case 2: param.dt = TB_TYPE_I16; break;
+			case 4: param.dt = TB_TYPE_I32; break;
+			case 8: param.dt = TB_TYPE_I64; break;
+			default:
+				param.dt = TB_TYPE_PTR;
+				break;
+			}
 		}
 		}
 
 
 		if (param.dt.width != 0) {
 		if (param.dt.width != 0) {
@@ -468,7 +484,13 @@ gb_internal TB_FunctionPrototype *cg_procedure_type_as_prototype(cgModule *m, Ty
 		}
 		}
 	}
 	}
 
 
-	return tb_prototype_create(m->mod, TB_CDECL, params.count, params.data, 0, nullptr, false);
+	auto results = array_make<TB_PrototypeParam>(heap_allocator(), 0, pt->result_count);
+	// if (pt->results) for (Entity *e : pt->params->Tuple.variables) {
+	// 	// TODO(bill):
+	// }
+
+
+	return tb_prototype_create(m->mod, TB_CDECL, params.count, params.data, results.count, results.data, pt->c_vararg);
 }
 }
 
 
 gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool ignore_body=false) {
 gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool ignore_body=false) {
@@ -619,7 +641,8 @@ 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.main" &&
+	    p->name != "main") {
 		return;
 		return;
 	}
 	}
 	if (p->body != nullptr) {
 	if (p->body != nullptr) {
@@ -628,8 +651,12 @@ gb_internal void cg_procedure_generate(cgProcedure *p) {
 }
 }
 
 
 
 
+#include "tilde_const.cpp"
+#include "tilde_expr.cpp"
 #include "tilde_stmt.cpp"
 #include "tilde_stmt.cpp"
 
 
+
+
 gb_internal bool cg_generate_code(Checker *c) {
 gb_internal bool cg_generate_code(Checker *c) {
 	TIME_SECTION("Tilde Module Initializtion");
 	TIME_SECTION("Tilde Module Initializtion");
 
 
@@ -722,88 +749,110 @@ gb_internal bool cg_generate_code(Checker *c) {
 		cg_procedure_generate(m->procedures_to_generate[i]);
 		cg_procedure_generate(m->procedures_to_generate[i]);
 	}
 	}
 
 
+	TB_DebugFormat debug_format = TB_DEBUGFMT_NONE;
+	if (build_context.ODIN_DEBUG) {
+		switch (build_context.metrics.os) {
+		case TargetOs_windows:
+			debug_format = TB_DEBUGFMT_CODEVIEW;
+			break;
+		case TargetOs_darwin:
+		case TargetOs_linux:
+		case TargetOs_essence:
+		case TargetOs_freebsd:
+		case TargetOs_openbsd:
+			debug_format = TB_DEBUGFMT_DWARF;
+			break;
+		}
+	}
+	TB_ExportBuffer export_buffer = tb_module_object_export(m->mod, debug_format);
+	defer (tb_export_buffer_free(export_buffer));
+
+	char const *path = "W:/Odin/tilde_main.obj";
+	GB_ASSERT(tb_export_buffer_to_file(export_buffer, path));
 
 
 
 
 	////////////////////////////////////////////////////////////////////////////////////
 	////////////////////////////////////////////////////////////////////////////////////
 
 
 
 
-	TB_Arena *arena = tb_default_arena();
+	// TB_Arena *arena = tb_default_arena();
 
 
-	TB_Global *str = nullptr;
-	{
-		TB_Global *str_data = nullptr;
-		{
-			str_data = tb_global_create(m->mod, "csb$1", nullptr, TB_LINKAGE_PRIVATE);
-			tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), str_data, 8, 1, 1);
-			void *region = tb_global_add_region(m->mod, str_data, 0, 8);
-			memcpy(region, "Hellope\x00", 8);
-		}
+	// TB_Global *str = nullptr;
+	// {
+	// 	TB_Global *str_data = nullptr;
+	// 	{
+	// 		str_data = tb_global_create(m->mod, "csb$1", nullptr, TB_LINKAGE_PRIVATE);
+	// 		tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), str_data, 8, 1, 1);
+	// 		void *region = tb_global_add_region(m->mod, str_data, 0, 8);
+	// 		memcpy(region, "Hellope\x00", 8);
+	// 	}
 
 
-		str = tb_global_create(m->mod, "global$str", nullptr, TB_LINKAGE_PRIVATE);
-		tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), str, 16, 8, 2);
-		tb_global_add_symbol_reloc(m->mod, str, 0, cast(TB_Symbol *)str_data);
-		void *len = tb_global_add_region(m->mod, str, 8, 8);
-		*cast(i64 *)len = 7;
-	}
+	// 	str = tb_global_create(m->mod, "global$str", nullptr, TB_LINKAGE_PRIVATE);
+	// 	tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), str, 16, 8, 2);
+	// 	tb_global_add_symbol_reloc(m->mod, str, 0, cast(TB_Symbol *)str_data);
+	// 	void *len = tb_global_add_region(m->mod, str, 8, 8);
+	// 	*cast(i64 *)len = 7;
+	// }
 
 
-	{
-		TB_PrototypeParam printf_ret = {TB_TYPE_I32};
-		TB_PrototypeParam printf_params = {TB_TYPE_PTR};
-		TB_FunctionPrototype *printf_proto = tb_prototype_create(m->mod, TB_STDCALL, 1, &printf_params, 1, &printf_ret, true);
-		TB_External *printf_proc = tb_extern_create(m->mod, "printf", TB_EXTERNAL_SO_LOCAL);
+	// {
+	// 	TB_PrototypeParam printf_ret = {TB_TYPE_I32};
+	// 	TB_PrototypeParam printf_params = {TB_TYPE_PTR};
+	// 	TB_FunctionPrototype *printf_proto = tb_prototype_create(m->mod, TB_STDCALL, 1, &printf_params, 1, &printf_ret, true);
+	// 	TB_External *printf_proc = tb_extern_create(m->mod, "printf", TB_EXTERNAL_SO_LOCAL);
 
 
-		TB_PrototypeParam main_ret = {TB_TYPE_I32};
-		TB_FunctionPrototype *main_proto = tb_prototype_create(m->mod, TB_STDCALL, 0, nullptr, 1, &main_ret, false);
-		TB_Function *         p = tb_function_create(m->mod, "main", TB_LINKAGE_PUBLIC, TB_COMDAT_NONE);
-		tb_function_set_prototype(p, main_proto, arena);
+	// 	TB_PrototypeParam main_ret = {TB_TYPE_I32};
+	// 	TB_FunctionPrototype *main_proto = tb_prototype_create(m->mod, TB_STDCALL, 0, nullptr, 1, &main_ret, false);
+	// 	TB_Function *         p = tb_function_create(m->mod, "main", TB_LINKAGE_PUBLIC, TB_COMDAT_NONE);
+	// 	tb_function_set_prototype(p, main_proto, arena);
 
 
 
 
-		auto str_ptr          = tb_inst_get_symbol_address(p, cast(TB_Symbol *)str);
-		auto str_data_ptr_ptr = tb_inst_member_access(p, str_ptr, 0);
-		auto str_data_ptr     = tb_inst_load(p, TB_TYPE_PTR, str_data_ptr_ptr, 1, false);
-		auto str_len_ptr      = tb_inst_member_access(p, str_ptr, 8);
-		auto str_len          = tb_inst_load(p, TB_TYPE_I64, str_len_ptr, 8, false);
+	// 	auto str_ptr          = tb_inst_get_symbol_address(p, cast(TB_Symbol *)str);
+	// 	auto str_data_ptr_ptr = tb_inst_member_access(p, str_ptr, 0);
+	// 	auto str_data_ptr     = tb_inst_load(p, TB_TYPE_PTR, str_data_ptr_ptr, 1, false);
+	// 	auto str_len_ptr      = tb_inst_member_access(p, str_ptr, 8);
+	// 	auto str_len          = tb_inst_load(p, TB_TYPE_I64, str_len_ptr, 8, false);
 
 
 
 
-		TB_Node *params[4] = {};
-		params[0] = tb_inst_cstring(p, "%.*s %s!\n");
-		params[1] = tb_inst_trunc(p, str_len, TB_TYPE_I32);
-		params[2] = str_data_ptr;
-		params[3] = tb_inst_cstring(p, "World");
-		TB_MultiOutput output = tb_inst_call(p, printf_proto, tb_inst_get_symbol_address(p, cast(TB_Symbol *)printf_proc), gb_count_of(params), params);
-		gb_unused(output);
-		TB_Node *printf_return_value = output.single;
+	// 	TB_Node *params[4] = {};
+	// 	params[0] = tb_inst_cstring(p, "%.*s %s!\n");
+	// 	params[1] = tb_inst_trunc(p, str_len, TB_TYPE_I32);
+	// 	params[2] = str_data_ptr;
+	// 	params[3] = tb_inst_cstring(p, "World");
+	// 	TB_MultiOutput output = tb_inst_call(p, printf_proto, tb_inst_get_symbol_address(p, cast(TB_Symbol *)printf_proc), gb_count_of(params), params);
+	// 	gb_unused(output);
+	// 	TB_Node *printf_return_value = output.single;
 
 
-		TB_Node *zero = tb_inst_uint(p, TB_TYPE_I32, 0);
-		TB_Node *one  = tb_inst_uint(p, TB_TYPE_I32, 1);
+	// 	TB_Node *zero = tb_inst_uint(p, TB_TYPE_I32, 0);
+	// 	TB_Node *one  = tb_inst_uint(p, TB_TYPE_I32, 1);
 
 
-		TB_Node *prev_case = tb_inst_get_control(p);
+	// 	TB_Node *prev_case = tb_inst_get_control(p);
 
 
-		TB_Node *true_case  = tb_inst_region(p);
-		TB_Node *false_case = tb_inst_region(p);
+	// 	TB_Node *true_case  = tb_inst_region(p);
+	// 	TB_Node *false_case = tb_inst_region(p);
 
 
-		TB_Node *cond = tb_inst_cmp_igt(p, printf_return_value, zero, true);
-		tb_inst_if(p, cond, true_case, false_case);
+	// 	TB_Node *cond = tb_inst_cmp_igt(p, printf_return_value, zero, true);
+	// 	tb_inst_if(p, cond, true_case, false_case);
 
 
-		tb_inst_set_control(p, true_case);
-		tb_inst_ret(p, 1, &zero);
+	// 	tb_inst_set_control(p, true_case);
+	// 	tb_inst_ret(p, 1, &zero);
 
 
-		tb_inst_set_control(p, false_case);
-		tb_inst_ret(p, 1, &one);
+	// 	tb_inst_set_control(p, false_case);
+	// 	tb_inst_ret(p, 1, &one);
 
 
-		tb_inst_set_control(p, prev_case);
+	// 	tb_inst_set_control(p, prev_case);
 
 
 
 
-		tb_module_compile_function(m->mod, p, TB_ISEL_FAST);
+	// 	tb_module_compile_function(m->mod, p, TB_ISEL_FAST);
 
 
-		tb_function_print(p, tb_default_print_callback, stdout);
+	// 	tb_function_print(p, tb_default_print_callback, stdout);
 
 
-		TB_ExportBuffer export_buffer = tb_module_object_export(m->mod, TB_DEBUGFMT_NONE);
-		defer (tb_export_buffer_free(export_buffer));
 
 
-		char const *path = "W:/Odin/tilde_main.obj";
-		GB_ASSERT(tb_export_buffer_to_file(export_buffer, path));
-	}
+	// 	TB_DebugFormat debug_format = TB_DEBUGFMT_NONE;
+	// 	TB_ExportBuffer export_buffer = tb_module_object_export(m->mod, debug_format);
+	// 	defer (tb_export_buffer_free(export_buffer));
+
+	// 	char const *path = "W:/Odin/tilde_main.obj";
+	// 	GB_ASSERT(tb_export_buffer_to_file(export_buffer, path));
+	// }
 	return true;
 	return true;
 }
 }
 
 

+ 2 - 0
src/tilde_backend.hpp

@@ -188,6 +188,8 @@ gb_internal cgValue cg_value(TB_Node *    node, Type *type);
 gb_internal cgAddr cg_addr(cgValue const &value);
 gb_internal cgAddr cg_addr(cgValue const &value);
 
 
 
 
+gb_internal cgValue cg_const_value(cgProcedure *p, Type *type, ExactValue const &value);
+
 
 
 gb_internal void cg_build_stmt(cgProcedure *p, Ast *stmt);
 gb_internal void cg_build_stmt(cgProcedure *p, Ast *stmt);
 gb_internal void cg_build_stmt_list(cgProcedure *p, Slice<Ast *> const &stmts);
 gb_internal void cg_build_stmt_list(cgProcedure *p, Slice<Ast *> const &stmts);

+ 5 - 0
src/tilde_const.cpp

@@ -0,0 +1,5 @@
+gb_internal cgValue cg_const_value(cgProcedure *p, Type *type, ExactValue const &value) {
+	TB_Node *node = nullptr;
+
+	return cg_value(node, type);
+}

+ 68 - 0
src/tilde_expr.cpp

@@ -0,0 +1,68 @@
+gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr);
+gb_internal cgValue cg_build_expr(cgProcedure *p, Ast *expr) {
+	u16 prev_state_flags = p->state_flags;
+	defer (p->state_flags = prev_state_flags);
+
+	if (expr->state_flags != 0) {
+		u16 in = expr->state_flags;
+		u16 out = p->state_flags;
+
+		if (in & StateFlag_bounds_check) {
+			out |= StateFlag_bounds_check;
+			out &= ~StateFlag_no_bounds_check;
+		} else if (in & StateFlag_no_bounds_check) {
+			out |= StateFlag_no_bounds_check;
+			out &= ~StateFlag_bounds_check;
+		}
+
+		if (in & StateFlag_type_assert) {
+			out |= StateFlag_type_assert;
+			out &= ~StateFlag_no_type_assert;
+		} else if (in & StateFlag_no_type_assert) {
+			out |= StateFlag_no_type_assert;
+			out &= ~StateFlag_type_assert;
+		}
+
+		p->state_flags = out;
+	}
+
+
+	// IMPORTANT NOTE(bill):
+	// Selector Call Expressions (foo->bar(...))
+	// must only evaluate `foo` once as it gets transformed into
+	// `foo.bar(foo, ...)`
+	// And if `foo` is a procedure call or something more complex, storing the value
+	// once is a very good idea
+	// If a stored value is found, it must be removed from the cache
+	if (expr->state_flags & StateFlag_SelectorCallExpr) {
+		// cgValue *pp = map_get(&p->selector_values, expr);
+		// if (pp != nullptr) {
+		// 	cgValue res = *pp;
+		// 	map_remove(&p->selector_values, expr);
+		// 	return res;
+		// }
+		// cgAddr *pa = map_get(&p->selector_addr, expr);
+		// if (pa != nullptr) {
+		// 	cgAddr res = *pa;
+		// 	map_remove(&p->selector_addr, expr);
+		// 	return cg_addr_load(p, res);
+		// }
+	}
+
+	cgValue res = cg_build_expr_internal(p, expr);
+
+	if (expr->state_flags & StateFlag_SelectorCallExpr) {
+		// map_set(&p->selector_values, expr, res);
+	}
+	return res;
+}
+
+
+gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) {
+	return {};
+}
+
+
+gb_internal cgAddr cg_build_addr(cgProcedure *p, Ast *expr) {
+	return {};
+}

+ 100 - 5
src/tilde_stmt.cpp

@@ -44,12 +44,13 @@ gb_internal void cg_pop_target_list(cgProcedure *p) {
 	p->target_list = p->target_list->prev;
 	p->target_list = p->target_list->prev;
 }
 }
 
 
+gb_internal TB_DebugType *cg_debug_type(cgModule *m, Type *type) {
+	// TODO(bill): cg_debug_type
+	return tb_debug_get_void(m->mod);
+}
+
 gb_internal cgAddr cg_add_local(cgProcedure *p, Type *type, Entity *e, bool zero_init) {
 gb_internal cgAddr cg_add_local(cgProcedure *p, Type *type, Entity *e, bool zero_init) {
-	char const *name = "";
-	if (e != nullptr && e->token.string.len > 0 && e->token.string != "_") {
-		// NOTE(bill): for debugging purposes only
-		name = alloc_cstring(permanent_allocator(), e->token.string);
-	}
+	GB_ASSERT(type != nullptr);
 
 
 	isize size = type_size_of(type);
 	isize size = type_size_of(type);
 	TB_CharUnits alignment = cast(TB_CharUnits)type_align_of(type);
 	TB_CharUnits alignment = cast(TB_CharUnits)type_align_of(type);
@@ -59,6 +60,14 @@ gb_internal cgAddr cg_add_local(cgProcedure *p, Type *type, Entity *e, bool zero
 
 
 	TB_Node *local = tb_inst_local(p->func, cast(u32)size, alignment);
 	TB_Node *local = tb_inst_local(p->func, cast(u32)size, alignment);
 
 
+	if (e != nullptr && e->token.string.len > 0 && e->token.string != "_") {
+		// NOTE(bill): for debugging purposes only
+		char const *name = alloc_cstring(permanent_allocator(), e->token.string);
+
+		TB_DebugType *debug_type = cg_debug_type(p->module, type);
+		tb_function_attrib_variable(p->func, local, name, debug_type);
+	}
+
 	if (zero_init) {
 	if (zero_init) {
 		bool is_volatile = false;
 		bool is_volatile = false;
 		TB_Node *zero  = tb_inst_uint(p->func, TB_TYPE_I8,  0);
 		TB_Node *zero  = tb_inst_uint(p->func, TB_TYPE_I8,  0);
@@ -82,6 +91,80 @@ gb_internal void cg_emit_defer_stmts(cgProcedure *p, cgDeferExitKind kind, TB_No
 	// TODO(bill): cg_emit_defer_stmts
 	// TODO(bill): cg_emit_defer_stmts
 }
 }
 
 
+gb_internal void cg_build_assignment(cgProcedure *p, Array<cgAddr> const &lhs, Slice<Ast *> const &rhs) {
+
+}
+
+
+gb_internal void cg_build_assign_stmt(cgProcedure *p, AstAssignStmt *as) {
+	if (as->op.kind == Token_Eq) {
+		auto lvals = array_make<cgAddr>(permanent_allocator(), 0, as->lhs.count);
+
+		for (Ast *lhs : as->lhs) {
+			cgAddr lval = {};
+			if (!is_blank_ident(lhs)) {
+				lval = cg_build_addr(p, lhs);
+			}
+			array_add(&lvals, lval);
+		}
+		cg_build_assignment(p, lvals, as->rhs);
+		return;
+	}
+
+	GB_ASSERT(as->lhs.count == 1);
+	GB_ASSERT(as->rhs.count == 1);
+	// 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);
+
+		cgAddr lhs = lb_build_addr(p, as->lhs[0]);
+		lb_addr_store(p, lhs, new_value);
+	} else {
+		cgAddr lhs = lb_build_addr(p, as->lhs[0]);
+		lbValue value = lb_build_expr(p, as->rhs[0]);
+		Type *lhs_type = lb_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)) {
+			lbValue old_value = lb_addr_load(p, lhs);
+			Type *type = old_value.type;
+			lbValue new_value = lb_emit_vector_mul_matrix(p, old_value, value, type);
+			lb_addr_store(p, lhs, new_value);
+			return;
+		}
+
+		if (is_type_array(lhs_type)) {
+			lb_build_assign_stmt_array(p, op, lhs, value);
+			return;
+		} else {
+			lbValue old_value = lb_addr_load(p, lhs);
+			Type *type = old_value.type;
+
+			lbValue change = lb_emit_conv(p, value, type);
+			lbValue new_value = lb_emit_arith(p, op, old_value, change, type);
+			lb_addr_store(p, lhs, new_value);
+		}
+	}
+*/
+}
+
+gb_internal void cg_build_return_stmt(cgProcedure *p, Slice<Ast *> const &return_results) {
+
+}
+
+
 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;
 	defer (p->curr_stmt = prev_stmt);
 	defer (p->curr_stmt = prev_stmt);
@@ -238,6 +321,18 @@ gb_internal void cg_build_stmt(cgProcedure *p, Ast *node) {
 		tb_inst_set_control(p->func, prev_block);
 		tb_inst_set_control(p->func, prev_block);
 	case_end;
 	case_end;
 
 
+	case_ast_node(es, ExprStmt, node);
+		cg_build_expr(p, es->expr);
+	case_end;
+
+	case_ast_node(as, AssignStmt, node);
+		cg_build_assign_stmt(p, as);
+	case_end;
+
+	case_ast_node(rs, ReturnStmt, node);
+		cg_build_return_stmt(p, rs->results);
+	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;