Browse Source

Fix array of array arithmetic

gingerBill 7 năm trước cách đây
mục cha
commit
b1d1497f4b
3 tập tin đã thay đổi với 31 bổ sung31 xóa
  1. 8 22
      core/math.odin
  2. 13 9
      src/ir.cpp
  3. 10 0
      src/types.cpp

+ 8 - 22
core/math.odin

@@ -122,9 +122,11 @@ to_degrees :: proc(radians: f32) -> f32 do return radians * 360 / TAU;
 
 
 
-dot :: proc(a, b: $T/[2]$E) -> E { c := a*b; return c[0] + c[1]; }
-dot :: proc(a, b: $T/[3]$E) -> E { c := a*b; return c[0] + c[1] + c[2]; }
-dot :: proc(a, b: $T/[4]$E) -> E { c := a*b; return c[0] + c[1] + c[2] + c[3]; }
+dot :: proc(a, b: $T/[$N]$E) -> E {
+	res: E;
+	for i in 0..N do res += a[i] * b[i];
+	return res;
+}
 
 cross :: proc(x, y: $T/[3]$E) -> T {
 	a := swizzle(x, 1, 2, 0) * swizzle(y, 2, 0, 1);
@@ -133,27 +135,11 @@ cross :: proc(x, y: $T/[3]$E) -> T {
 }
 
 
-mag :: proc(v: $T/[2]$E) -> E do return sqrt(dot(v, v));
-mag :: proc(v: $T/[3]$E) -> E do return sqrt(dot(v, v));
-mag :: proc(v: $T/[4]$E) -> E do return sqrt(dot(v, v));
-
-norm :: proc(v: $T/[2]$E) -> T do return v / mag(v);
-norm :: proc(v: $T/[3]$E) -> T do return v / mag(v);
-norm :: proc(v: $T/[4]$E) -> T do return v / mag(v);
+mag :: proc(v: $T/[$N]$E) -> E do return sqrt(dot(v, v));
 
-norm0 :: proc(v: $T/[2]$E) -> T {
-	m := mag(v);
-	if m == 0 do return 0;
-	return v/m;
-}
-
-norm0 :: proc(v: $T/[3]$E) -> T {
-	m := mag(v);
-	if m == 0 do return 0;
-	return v/m;
-}
+norm :: proc(v: $T/[$N]$E) -> T do return v / mag(v);
 
-norm0 :: proc(v: $T/[4]$E) -> T {
+norm0 :: proc(v: $T/[$N]$E) -> T {
 	m := mag(v);
 	if m == 0 do return 0;
 	return v/m;

+ 13 - 9
src/ir.cpp

@@ -2074,7 +2074,7 @@ irValue *ir_emit_unary_arith(irProcedure *proc, TokenKind op, irValue *x, Type *
 		Type *tl = base_type(ir_type(x));
 		irValue *val = ir_address_from_load_or_generate_local(proc, x);
 		GB_ASSERT(is_type_vector(type));
-		Type *elem_type = base_type(type)->Vector.elem;
+		Type *elem_type = base_vector_type(type);
 
 		irValue *res = ir_add_local_generated(proc, type);
 		for (i32 i = 0; i < tl->Vector.count; i++) {
@@ -2093,7 +2093,7 @@ irValue *ir_emit_unary_arith(irProcedure *proc, TokenKind op, irValue *x, Type *
 		Type *tl = base_type(ir_type(x));
 		irValue *val = ir_address_from_load_or_generate_local(proc, x);
 		GB_ASSERT(is_type_array(type));
-		Type *elem_type = base_type(type)->Array.elem;
+		Type *elem_type = base_array_type(type);
 
 		irValue *res = ir_add_local_generated(proc, type);
 		for (i32 i = 0; i < tl->Array.count; i++) {
@@ -2124,7 +2124,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
 		irValue *lhs = ir_address_from_load_or_generate_local(proc, left);
 		irValue *rhs = ir_address_from_load_or_generate_local(proc, right);
 		GB_ASSERT(is_type_vector(type));
-		Type *elem_type = base_type(type)->Vector.elem;
+		Type *elem_type = base_vector_type(type);
 
 		irValue *res = ir_add_local_generated(proc, type);
 		i64 count = base_type(type)->Vector.count;
@@ -2147,7 +2147,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
 		irValue *lhs = ir_address_from_load_or_generate_local(proc, left);
 		irValue *rhs = ir_address_from_load_or_generate_local(proc, right);
 		GB_ASSERT(is_type_array(type));
-		Type *elem_type = base_type(type)->Array.elem;
+		Type *elem_type = base_array_type(type);
 
 		irValue *res = ir_add_local_generated(proc, type);
 		i64 count = base_type(type)->Array.count;
@@ -3229,14 +3229,18 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
 
 #if defined(ALLOW_ARRAY_PROGRAMMING)
 	if (is_type_array(dst)) {
-		Type *dst_elem = dst->Array.elem;
-		value = ir_emit_conv(proc, value, dst_elem);
+		Type *elem = dst->Array.elem;
+		bool is_ta = is_type_array(elem);
+
+		gb_printf("%s\n", type_to_string(ir_type(value)));
+		irValue *e = ir_emit_conv(proc, value, elem);
+		gb_printf("%s\n", type_to_string(elem));
 		irValue *v = ir_add_local_generated(proc, t);
 		isize index_count = dst->Array.count;
 
 		for (i32 i = 0; i < index_count; i++) {
 			irValue *elem = ir_emit_array_epi(proc, v, i);
-			ir_emit_store(proc, elem, value);
+			ir_emit_store(proc, elem, e);
 		}
 		return ir_emit_load(proc, v);
 	}
@@ -4693,7 +4697,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 		// NOTE(bill): Edge case
 		if (tv.value.kind != ExactValue_Compound &&
 		    is_type_vector(tv.type)) {
-			Type *elem = base_vector_type(tv.type);
+			Type *elem = core_array_or_vector_type(tv.type);
 			ExactValue value = convert_exact_value_for_type(tv.value, elem);
 			irValue *x = ir_add_module_constant(proc->module, elem, value);
 			return ir_emit_conv(proc, x, tv.type);
@@ -4703,7 +4707,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 		// NOTE(bill): Edge case
 		if (tv.value.kind != ExactValue_Compound &&
 		    is_type_array(tv.type)) {
-			Type *elem = base_array_type(tv.type);
+			Type *elem = core_array_or_vector_type(tv.type);
 			ExactValue value = convert_exact_value_for_type(tv.value, elem);
 			irValue *x = ir_add_module_constant(proc->module, elem, value);
 			return ir_emit_conv(proc, x, tv.type);

+ 10 - 0
src/types.cpp

@@ -835,6 +835,16 @@ Type *base_array_type(Type *t) {
 	return t;
 }
 
+Type *core_array_or_vector_type(Type *t) {
+	for (;;) {
+		Type *prev = t;
+		t = base_array_type(t);
+		t = base_vector_type(t);
+		if (prev == t) break;
+	}
+	return t;
+}
+
 Type *base_complex_elem_type(Type *t) {
 	t = core_type(t);
 	if (is_type_complex(t)) {