Prechádzať zdrojové kódy

Remove `quaternion128` and `quaternion256` as core types

Ginger Bill 8 rokov pred
rodič
commit
13b8a1e348
10 zmenil súbory, kde vykonal 39 pridanie a 785 odobranie
  1. 0 22
      core/_preload.odin
  2. 0 35
      core/fmt.odin
  3. 9 190
      src/check_expr.c
  4. 17 34
      src/checker.c
  5. 3 173
      src/exact_value.c
  6. 0 215
      src/ir.c
  7. 4 69
      src/ir_print.c
  8. 0 2
      src/ssa.c
  9. 1 3
      src/tokenizer.c
  10. 5 42
      src/types.c

+ 0 - 22
core/_preload.odin

@@ -54,7 +54,6 @@ TypeInfo :: union {
 	Integer{signed: bool},
 	Float{},
 	Complex{},
-	Quaternion{},
 	String{},
 	Boolean{},
 	Any{},
@@ -322,19 +321,6 @@ __complex128_eq :: proc(a, b: complex128) -> bool #inline { return real(a) == re
 __complex128_ne :: proc(a, b: complex128) -> bool #inline { return real(a) != real(b) || imag(a) != imag(b); }
 
 
-__quaternion128_eq :: proc(a, b: quaternion128) -> bool #inline {
-	return real(a) == real(b) && imag(a) == imag(b) && jmag(a) == jmag(b) && kmag(a) == kmag(b);
-}
-__quaternion128_ne :: proc(a, b: quaternion128) -> bool #inline {
-	return real(a) != real(b) || imag(a) != imag(b) || jmag(a) != jmag(b) || kmag(a) != kmag(b);
-}
-__quaternion256_eq :: proc(a, b: quaternion256) -> bool #inline {
-	return real(a) == real(b) && imag(a) == imag(b) && jmag(a) == jmag(b) && kmag(a) == kmag(b);
-}
-__quaternion256_ne :: proc(a, b: quaternion256) -> bool #inline {
-	return real(a) != real(b) || imag(a) != imag(b) || jmag(a) != jmag(b) || kmag(a) != kmag(b);
-}
-
 __assert :: proc(file: string, line, column: int, msg: string) #inline {
 	fmt.fprintf(os.stderr, "%s(%d:%d) Runtime assertion: %s\n",
 	            file, line, column, msg);
@@ -427,14 +413,6 @@ __abs_complex128 :: proc(x: complex128) -> f64 #inline {
 	r, i := real(x), imag(x);
 	return __sqrt_f64(r*r + i*i);
 }
-__abs_quaternion128 :: proc(x: quaternion128) -> f32 #inline {
-	r, i, j, k := real(x), imag(x), jmag(x), kmag(x);
-	return __sqrt_f32(r*r + i*i + j*j + k*k);
-}
-__abs_quaternion256 :: proc(x: quaternion256) -> f64 #inline {
-	r, i, j, k := real(x), imag(x), jmag(x), kmag(x);
-	return __sqrt_f64(r*r + i*i + j*j + k*k);
-}
 
 
 

+ 0 - 35
core/fmt.odin

@@ -205,11 +205,6 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
 		case 8:  write_string(buf, "complex64");
 		case 16: write_string(buf, "complex128");
 		}
-	case Quaternion:
-		match info.size {
-		case 16: write_string(buf, "quaternion128");
-		case 32: write_string(buf, "quaternion");
-		}
 	case String:  write_string(buf, "string");
 	case Boolean: write_string(buf, "bool");
 	case Any:
@@ -773,7 +768,6 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
 	case Integer:    fmt_arg(fi, v, verb);
 	case Float:      fmt_arg(fi, v, verb);
 	case Complex:    fmt_arg(fi, v, verb);
-	case Quaternion: fmt_arg(fi, v, verb);
 	case String:     fmt_arg(fi, v, verb);
 
 	case Pointer:
@@ -931,33 +925,6 @@ fmt_complex :: proc(fi: ^FmtInfo, c: complex128, bits: int, verb: rune) {
 	}
 }
 
-fmt_quaternion :: proc(fi: ^FmtInfo, c: quaternion256, bits: int, verb: rune) {
-	match verb {
-	case 'f', 'F', 'v':
-		r := real(c);
-		i := imag(c);
-		j := jmag(c);
-		k := kmag(c);
-		fmt_float(fi, r, bits/4, verb);
-
-		if !fi.plus && i >= 0 { write_rune(fi.buf, '+'); }
-		fmt_float(fi, i, bits/4, verb);
-		write_rune(fi.buf, 'i');
-
-		if !fi.plus && j >= 0 { write_rune(fi.buf, '+'); }
-		fmt_float(fi, j, bits/4, verb);
-		write_rune(fi.buf, 'j');
-
-		if !fi.plus && k >= 0 { write_rune(fi.buf, '+'); }
-		fmt_float(fi, k, bits/4, verb);
-		write_rune(fi.buf, 'k');
-
-	case:
-		fmt_bad_verb(fi, verb);
-		return;
-	}
-}
-
 _u128_to_lo_hi :: proc(a: u128) -> (lo, hi: u64) { return u64(a), u64(a>>64); }
 _i128_to_lo_hi :: proc(a: u128) -> (lo: u64 hi: i64) { return u64(a), i64(a>>64); }
 
@@ -987,8 +954,6 @@ fmt_arg :: proc(fi: ^FmtInfo, arg: any, verb: rune) {
 	case f64:           fmt_float(fi, a, 64, verb);
 	case complex64:     fmt_complex(fi, complex128(a), 64, verb);
 	case complex128:    fmt_complex(fi, a, 128, verb);
-	case quaternion128: fmt_quaternion(fi, quaternion256(a), 128, verb);
-	case quaternion256: fmt_quaternion(fi, a, 256, verb);
 
 	case int:     fmt_int(fi, u128(a), true,  8*size_of(int), verb);
 	case i8:      fmt_int(fi, u128(a), true,  8, verb);

+ 9 - 190
src/check_expr.c

@@ -170,11 +170,6 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) {
 								return 1;
 							}
 							break;
-						case Basic_UntypedQuaternion:
-							if (is_type_quaternion(dst)) {
-								return 1;
-							}
-							break;
 						}
 					}
 					return 2;
@@ -2054,35 +2049,6 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
 			return true;
 		}
 
-		return false;
-	} else if (is_type_quaternion(type)) {
-		ExactValue v = exact_value_to_quaternion(in_value);
-		if (v.kind != ExactValue_Quaternion) {
-			return false;
-		}
-
-		switch (type->Basic.kind) {
-		case Basic_quaternion128:
-		case Basic_quaternion256: {
-			ExactValue real = exact_value_real(v);
-			ExactValue imag = exact_value_imag(v);
-			ExactValue jmag = exact_value_jmag(v);
-			ExactValue kmag = exact_value_kmag(v);
-			if (real.kind != ExactValue_Invalid &&
-			    imag.kind != ExactValue_Invalid &&
-			    jmag.kind != ExactValue_Invalid &&
-			    kmag.kind != ExactValue_Invalid) {
-				ExactValue ov = exact_binary_operator_value(Token_Add, real, exact_value_make_imag(imag));
-				ov = exact_binary_operator_value(Token_Add, ov, exact_value_make_jmag(jmag));
-				ov = exact_binary_operator_value(Token_Add, ov, exact_value_make_kmag(kmag));
-				if (out_value) *out_value = ov;
-				return true;
-			}
-		} break;
-		case Basic_UntypedQuaternion:
-			return true;
-		}
-
 		return false;
 	}else if (is_type_pointer(type)) {
 		if (in_value.kind == ExactValue_Pointer) {
@@ -2510,10 +2476,6 @@ bool check_is_castable_to(Checker *c, Operand *operand, Type *y) {
 		return true;
 	}
 
-	if (is_type_quaternion(src) && is_type_quaternion(dst)) {
-		return true;
-	}
-
 	// Cast between pointers
 	if (is_type_pointer(src) && is_type_pointer(dst)) {
 		Type *s = base_type(type_deref(src));
@@ -2904,8 +2866,6 @@ ExactValue convert_exact_value_for_type(ExactValue v, Type *type) {
 		v = exact_value_to_integer(v);
 	} else if (is_type_complex(t)) {
 		v = exact_value_to_complex(v);
-	} else if (is_type_quaternion(t)) {
-		v = exact_value_to_quaternion(v);
 	}
 	return v;
 }
@@ -2959,7 +2919,6 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
 			case Basic_UntypedInteger:
 			case Basic_UntypedFloat:
 			case Basic_UntypedComplex:
-			case Basic_UntypedQuaternion:
 			case Basic_UntypedRune:
 				if (!is_type_numeric(target_type)) {
 					operand->mode = Addressing_Invalid;
@@ -4128,149 +4087,36 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 		}
 	} break;
 
-	case BuiltinProc_quaternion: {
-		// quaternion :: proc(real, imag, jmag, kmag: float_type) -> quaternion_type
-		Operand x = *operand;
-		Operand y = {0};
-		Operand z = {0};
-		Operand w = {0};
-
-		// NOTE(bill): Invalid will be the default till fixed
-		operand->type = t_invalid;
-		operand->mode = Addressing_Invalid;
-
-		check_expr(c, &y, ce->args.e[1]); if (y.mode == Addressing_Invalid) return false;
-		check_expr(c, &z, ce->args.e[2]); if (z.mode == Addressing_Invalid) return false;
-		check_expr(c, &w, ce->args.e[3]); if (w.mode == Addressing_Invalid) return false;
-
-#define _QUAT_CTT(x, y, z, w) do { \
-		convert_to_typed(c, &(x), (y).type, 0); if ((x).mode == Addressing_Invalid) return false; \
-		convert_to_typed(c, &(x), (z).type, 0); if ((x).mode == Addressing_Invalid) return false; \
-		convert_to_typed(c, &(x), (w).type, 0); if ((x).mode == Addressing_Invalid) return false; \
-	} while (0)
-		_QUAT_CTT(x, y, z, w);
-		_QUAT_CTT(y, z, w, x);
-		_QUAT_CTT(z, w, x, y);
-		_QUAT_CTT(w, x, y, z);
-#undef _QUAT_CTT
-
-		if (x.mode == Addressing_Constant &&
-		    y.mode == Addressing_Constant &&
-		    z.mode == Addressing_Constant &&
-		    w.mode == Addressing_Constant) {
-#define _QUAT_EXACT_VAL(x) do { \
-			if (is_type_numeric((x).type) && \
-			    exact_value_imag((x).value).value_float == 0 && \
-			    exact_value_jmag((x).value).value_float == 0 && \
-			    exact_value_kmag((x).value).value_float == 0) { \
-				(x).type = t_untyped_float; \
-			} \
-		} while (0)
-		_QUAT_EXACT_VAL(x);
-		_QUAT_EXACT_VAL(y);
-		_QUAT_EXACT_VAL(z);
-		_QUAT_EXACT_VAL(w);
-#undef _QUAT_EXACT_VAL
-		}
-
-		if (!are_types_identical(x.type, y.type)) {
-			gbString tx = type_to_string(x.type);
-			gbString ty = type_to_string(y.type);
-			gbString tz = type_to_string(z.type);
-			gbString tw = type_to_string(w.type);
-			error_node(call, "Mismatched types to `complex`, `%s`, `%s` `%s`, `%s`", tx, ty, tz, tw);
-			gb_string_free(tw);
-			gb_string_free(tz);
-			gb_string_free(ty);
-			gb_string_free(tx);
-			return false;
-		}
-
-		if (!is_type_float(x.type)) {
-			gbString s = type_to_string(x.type);
-			error_node(call, "Arguments have type `%s`, expected a floating point", s);
-			gb_string_free(s);
-			return false;
-		}
-
-		if (x.mode == Addressing_Constant &&
-		    y.mode == Addressing_Constant &&
-		    z.mode == Addressing_Constant &&
-		    w.mode == Addressing_Constant) {
-			ExactValue v = exact_binary_operator_value(Token_Add, x.value, y.value);
-			v = exact_binary_operator_value(Token_Add, v, z.value);
-			v = exact_binary_operator_value(Token_Add, v, w.value);
-			operand->value = v;
-			operand->mode = Addressing_Constant;
-		} else {
-			operand->mode = Addressing_Value;
-		}
-
-		BasicKind kind = core_type(x.type)->Basic.kind;
-		switch (kind) {
-		case Basic_f32:          operand->type = t_quaternion128;      break;
-		case Basic_f64:          operand->type = t_quaternion256;      break;
-		case Basic_UntypedFloat: operand->type = t_untyped_quaternion; break;
-		default: GB_PANIC("Invalid type"); break;
-		}
-	} break;
-
 	case BuiltinProc_real:
-	case BuiltinProc_imag:
-	case BuiltinProc_jmag:
-	case BuiltinProc_kmag: {
+	case BuiltinProc_imag: {
 		// real :: proc(x: type) -> float_type
 		// imag :: proc(x: type) -> float_type
-		// jmag :: proc(x: type) -> float_type
-		// kmag :: proc(x: type) -> float_type
 
 		Operand *x = operand;
 		if (is_type_untyped(x->type)) {
 			if (x->mode == Addressing_Constant) {
 				if (is_type_numeric(x->type)) {
-					if (id == BuiltinProc_jmag ||
-					    id == BuiltinProc_kmag) {
-						x->type = t_untyped_quaternion;
-					} else {
-						x->type = t_untyped_complex;
-					}
+					x->type = t_untyped_complex;
 				}
 			} else {
-				if (id == BuiltinProc_jmag ||
-				    id == BuiltinProc_kmag) {
-					convert_to_typed(c, x, t_quaternion256, 0);
-				} else {
-					convert_to_typed(c, x, t_complex128, 0);
-				}
+				convert_to_typed(c, x, t_complex128, 0);
 				if (x->mode == Addressing_Invalid) {
 					return false;
 				}
 			}
 		}
 
-		if (id == BuiltinProc_jmag ||
-		    id == BuiltinProc_kmag) {
-			if (!is_type_quaternion(x->type)) {
-				gbString s = type_to_string(x->type);
-				error_node(call, "Argument has type `%s`, expected a quaternion type", s);
-				gb_string_free(s);
-				return false;
-			}
-		} else {
-			if (!is_type_complex(x->type) && !is_type_quaternion(x->type)) {
-				gbString s = type_to_string(x->type);
-				error_node(call, "Argument has type `%s`, expected a complex or quaternion type", s);
-				gb_string_free(s);
-				return false;
-			}
+		if (!is_type_complex(x->type)) {
+			gbString s = type_to_string(x->type);
+			error_node(call, "Argument has type `%s`, expected a complex type", s);
+			gb_string_free(s);
+			return false;
 		}
 
 		if (x->mode == Addressing_Constant) {
 			switch (id) {
 			case BuiltinProc_real: x->value = exact_value_real(x->value); break;
 			case BuiltinProc_imag: x->value = exact_value_imag(x->value); break;
-			case BuiltinProc_jmag: x->value = exact_value_jmag(x->value); break;
-			case BuiltinProc_kmag: x->value = exact_value_kmag(x->value); break;
 			}
 		} else {
 			x->mode = Addressing_Value;
@@ -4281,9 +4127,6 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 		case Basic_complex64:         x->type = t_f32;           break;
 		case Basic_complex128:        x->type = t_f64;           break;
 		case Basic_UntypedComplex:    x->type = t_untyped_float; break;
-		case Basic_quaternion128:     x->type = t_f32;           break;
-		case Basic_quaternion256:     x->type = t_f64;           break;
-		case Basic_UntypedQuaternion: x->type = t_untyped_float; break;
 		default: GB_PANIC("Invalid type"); break;
 		}
 	} break;
@@ -4301,18 +4144,6 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 			} else {
 				x->mode = Addressing_Value;
 			}
-		} else if (is_type_quaternion(x->type)) {
-			if (x->mode == Addressing_Constant) {
-				ExactValue v = exact_value_to_quaternion(x->value);
-				f64 r = v.value_quaternion.real;
-				f64 i = v.value_quaternion.imag;
-				f64 j = v.value_quaternion.jmag;
-				f64 k = v.value_quaternion.kmag;
-				x->value = exact_value_quaternion(r, i, j, k);
-				x->mode = Addressing_Constant;
-			} else {
-				x->mode = Addressing_Value;
-			}
 		} else {
 			gbString s = type_to_string(x->type);
 			error_node(call, "Expected a complex or quaternion, got `%s`", s);
@@ -4535,13 +4366,6 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 				f64 i = operand->value.value_complex.imag;
 				operand->value = exact_value_float(gb_sqrt(r*r + i*i));
 			} break;
-			case ExactValue_Quaternion: {
-				f64 r = operand->value.value_complex.real;
-				f64 i = operand->value.value_complex.imag;
-				f64 j = operand->value.value_complex.imag;
-				f64 k = operand->value.value_complex.imag;
-				operand->value = exact_value_float(gb_sqrt(r*r + i*i + j*j + k*k));
-			} break;
 			default:
 				GB_PANIC("Invalid numeric constant");
 				break;
@@ -4552,10 +4376,8 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 
 		if (is_type_complex(operand->type)) {
 			operand->type = base_complex_elem_type(operand->type);
-		} else if (is_type_quaternion(operand->type)) {
-			operand->type = base_quaternion_elem_type(operand->type);
 		}
-		GB_ASSERT(!is_type_complex(operand->type) && !is_type_quaternion(operand->type));
+		GB_ASSERT(!is_type_complex(operand->type));
 	} break;
 
 	case BuiltinProc_clamp: {
@@ -5218,9 +5040,6 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
 			Rune r = s.text[s.len-1];
 			switch (r) {
 			case 'i': t = t_untyped_complex; break;
-			case 'j': case 'k':
-				t = t_untyped_quaternion;
-				break;
 			}
 		} break;
 		default:            GB_PANIC("Unknown literal"); break;

+ 17 - 34
src/checker.c

@@ -56,11 +56,8 @@ typedef enum BuiltinProcId {
 	BuiltinProc_swizzle,
 
 	BuiltinProc_complex,
-	BuiltinProc_quaternion,
 	BuiltinProc_real,
 	BuiltinProc_imag,
-	BuiltinProc_jmag,
-	BuiltinProc_kmag,
 	BuiltinProc_conj,
 
 	BuiltinProc_slice_ptr,
@@ -110,11 +107,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
 	{STR_LIT("swizzle"),          1, true,  Expr_Expr},
 
 	{STR_LIT("complex"),          2, false, Expr_Expr},
-	{STR_LIT("quaternion"),       4, false, Expr_Expr},
 	{STR_LIT("real"),             1, false, Expr_Expr},
 	{STR_LIT("imag"),             1, false, Expr_Expr},
-	{STR_LIT("jmag"),             1, false, Expr_Expr},
-	{STR_LIT("kmag"),             1, false, Expr_Expr},
 	{STR_LIT("conj"),             1, false, Expr_Expr},
 
 	{STR_LIT("slice_ptr"),        2, true,   Expr_Expr},
@@ -1014,15 +1008,6 @@ void add_type_info_type(Checker *c, Type *t) {
 			add_type_info_type(c, t_type_info_float);
 			add_type_info_type(c, t_f64);
 			break;
-
-		case Basic_quaternion128:
-			add_type_info_type(c, t_type_info_float);
-			add_type_info_type(c, t_f32);
-			break;
-		case Basic_quaternion256:
-			add_type_info_type(c, t_type_info_float);
-			add_type_info_type(c, t_f64);
-			break;
 		}
 	} break;
 
@@ -1215,36 +1200,34 @@ void init_preload(Checker *c) {
 
 
 
-		if (record->variant_count != 22) {
+		if (record->variant_count != 21) {
 			compiler_error("Invalid `TypeInfo` layout");
 		}
 		t_type_info_named         = record->variants[ 1]->type;
 		t_type_info_integer       = record->variants[ 2]->type;
 		t_type_info_float         = record->variants[ 3]->type;
 		t_type_info_complex       = record->variants[ 4]->type;
-		t_type_info_quaternion    = record->variants[ 5]->type;
-		t_type_info_string        = record->variants[ 6]->type;
-		t_type_info_boolean       = record->variants[ 7]->type;
-		t_type_info_any           = record->variants[ 8]->type;
-		t_type_info_pointer       = record->variants[ 9]->type;
-		t_type_info_atomic        = record->variants[10]->type;
-		t_type_info_procedure     = record->variants[11]->type;
-		t_type_info_array         = record->variants[12]->type;
-		t_type_info_dynamic_array = record->variants[13]->type;
-		t_type_info_slice         = record->variants[14]->type;
-		t_type_info_vector        = record->variants[15]->type;
-		t_type_info_tuple         = record->variants[16]->type;
-		t_type_info_struct        = record->variants[17]->type;
-		t_type_info_raw_union     = record->variants[18]->type;
-		t_type_info_union         = record->variants[19]->type;
-		t_type_info_enum          = record->variants[20]->type;
-		t_type_info_map           = record->variants[21]->type;
+		t_type_info_string        = record->variants[ 5]->type;
+		t_type_info_boolean       = record->variants[ 6]->type;
+		t_type_info_any           = record->variants[ 7]->type;
+		t_type_info_pointer       = record->variants[ 8]->type;
+		t_type_info_atomic        = record->variants[ 9]->type;
+		t_type_info_procedure     = record->variants[10]->type;
+		t_type_info_array         = record->variants[11]->type;
+		t_type_info_dynamic_array = record->variants[12]->type;
+		t_type_info_slice         = record->variants[13]->type;
+		t_type_info_vector        = record->variants[14]->type;
+		t_type_info_tuple         = record->variants[15]->type;
+		t_type_info_struct        = record->variants[16]->type;
+		t_type_info_raw_union     = record->variants[17]->type;
+		t_type_info_union         = record->variants[18]->type;
+		t_type_info_enum          = record->variants[19]->type;
+		t_type_info_map           = record->variants[20]->type;
 
 		t_type_info_named_ptr         = make_type_pointer(c->allocator, t_type_info_named);
 		t_type_info_integer_ptr       = make_type_pointer(c->allocator, t_type_info_integer);
 		t_type_info_float_ptr         = make_type_pointer(c->allocator, t_type_info_float);
 		t_type_info_complex_ptr       = make_type_pointer(c->allocator, t_type_info_complex);
-		t_type_info_quaternion_ptr    = make_type_pointer(c->allocator, t_type_info_quaternion);
 		t_type_info_string_ptr        = make_type_pointer(c->allocator, t_type_info_string);
 		t_type_info_boolean_ptr       = make_type_pointer(c->allocator, t_type_info_boolean);
 		t_type_info_any_ptr           = make_type_pointer(c->allocator, t_type_info_any);

+ 3 - 173
src/exact_value.c

@@ -9,10 +9,6 @@ typedef struct Complex128 {
 	f64 real, imag;
 } Complex128;
 
-typedef struct Quaternion256 {
-	f64 real, imag, jmag, kmag;
-} Quaternion256;
-
 typedef enum ExactValueKind {
 	ExactValue_Invalid,
 
@@ -21,7 +17,6 @@ typedef enum ExactValueKind {
 	ExactValue_Integer,
 	ExactValue_Float,
 	ExactValue_Complex,
-	ExactValue_Quaternion,
 	ExactValue_Pointer,
 	ExactValue_Compound, // TODO(bill): Is this good enough?
 
@@ -37,7 +32,6 @@ typedef struct ExactValue {
 		f64           value_float;
 		i64           value_pointer;
 		Complex128    value_complex;
-		Quaternion256 value_quaternion;
 		AstNode *     value_compound;
 	};
 } ExactValue;
@@ -91,16 +85,6 @@ ExactValue exact_value_complex(f64 real, f64 imag) {
 	return result;
 }
 
-ExactValue exact_value_quaternion(f64 real, f64 imag, f64 jmag, f64 kmag) {
-	ExactValue result = {ExactValue_Quaternion};
-	result.value_quaternion.real = real;
-	result.value_quaternion.imag = imag;
-	result.value_quaternion.jmag = jmag;
-	result.value_quaternion.kmag = kmag;
-	return result;
-}
-
-
 ExactValue exact_value_pointer(i64 ptr) {
 	ExactValue result = {ExactValue_Pointer};
 	result.value_pointer = ptr;
@@ -206,10 +190,8 @@ ExactValue exact_value_from_basic_literal(Token token) {
 		str.len--; // Ignore the `i|j|k`
 		f64 imag = float_from_string(str);
 
-		switch (last_rune) {
-		case 'i': return exact_value_complex(0, imag);
-		case 'j': return exact_value_quaternion(0, 0, imag, 0);
-		case 'k': return exact_value_quaternion(0, 0, 0, imag);
+		if (last_rune == 'i') {
+			return exact_value_complex(0, imag);
 		}
 	}
 	case Token_Rune: {
@@ -271,22 +253,6 @@ ExactValue exact_value_to_complex(ExactValue v) {
 }
 
 
-ExactValue exact_value_to_quaternion(ExactValue v) {
-	switch (v.kind) {
-	case ExactValue_Integer:
-		return exact_value_quaternion(i128_to_f64(v.value_integer), 0, 0, 0);
-	case ExactValue_Float:
-		return exact_value_quaternion(v.value_float, 0, 0, 0);
-	case ExactValue_Complex:
-		return exact_value_quaternion(v.value_complex.real, v.value_complex.imag, 0, 0);
-	case ExactValue_Quaternion:
-		return v;
-	}
-	ExactValue r = {ExactValue_Invalid};
-	return r;
-}
-
-
 ExactValue exact_value_real(ExactValue v) {
 	switch (v.kind) {
 	case ExactValue_Integer:
@@ -294,8 +260,6 @@ ExactValue exact_value_real(ExactValue v) {
 		return v;
 	case ExactValue_Complex:
 		return exact_value_float(v.value_complex.real);
-	case ExactValue_Quaternion:
-		return exact_value_float(v.value_quaternion.real);
 	}
 	ExactValue r = {ExactValue_Invalid};
 	return r;
@@ -308,39 +272,11 @@ ExactValue exact_value_imag(ExactValue v) {
 		return exact_value_i64(0);
 	case ExactValue_Complex:
 		return exact_value_float(v.value_complex.imag);
-	case ExactValue_Quaternion:
-		return exact_value_float(v.value_quaternion.imag);
 	}
 	ExactValue r = {ExactValue_Invalid};
 	return r;
 }
 
-ExactValue exact_value_jmag(ExactValue v) {
-	switch (v.kind) {
-	case ExactValue_Integer:
-	case ExactValue_Float:
-	case ExactValue_Complex:
-		return exact_value_i64(0);
-	case ExactValue_Quaternion:
-		return exact_value_float(v.value_quaternion.jmag);
-	}
-	ExactValue r = {ExactValue_Invalid};
-	return r;
-}
-ExactValue exact_value_kmag(ExactValue v) {
-	switch (v.kind) {
-	case ExactValue_Integer:
-	case ExactValue_Float:
-	case ExactValue_Complex:
-		return exact_value_i64(0);
-	case ExactValue_Quaternion:
-		return exact_value_float(v.value_quaternion.kmag);
-	}
-	ExactValue r = {ExactValue_Invalid};
-	return r;
-}
-
-
 ExactValue exact_value_make_imag(ExactValue v) {
 	switch (v.kind) {
 	case ExactValue_Integer:
@@ -353,31 +289,6 @@ ExactValue exact_value_make_imag(ExactValue v) {
 	ExactValue r = {ExactValue_Invalid};
 	return r;
 }
-ExactValue exact_value_make_jmag(ExactValue v) {
-	switch (v.kind) {
-	case ExactValue_Integer:
-		return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0);
-	case ExactValue_Float:
-		return exact_value_quaternion(0, 0, v.value_float, 0);
-	default:
-		GB_PANIC("Expected an integer or float type for `exact_value_make_jmag`");
-	}
-	ExactValue r = {ExactValue_Invalid};
-	return r;
-}
-ExactValue exact_value_make_kmag(ExactValue v) {
-	switch (v.kind) {
-	case ExactValue_Integer:
-		return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float);
-	case ExactValue_Float:
-		return exact_value_quaternion(0, 0, 0, v.value_float);
-	default:
-		GB_PANIC("Expected an integer or float type for `exact_value_make_kmag`");
-	}
-	ExactValue r = {ExactValue_Invalid};
-	return r;
-}
-
 
 
 ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision) {
@@ -388,7 +299,6 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision)
 		case ExactValue_Integer:
 		case ExactValue_Float:
 		case ExactValue_Complex:
-		case ExactValue_Quaternion:
 			return v;
 		}
 	} break;
@@ -412,13 +322,6 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision)
 			f64 imag = v.value_complex.imag;
 			return exact_value_complex(-real, -imag);
 		}
-		case ExactValue_Quaternion: {
-			f64 real = v.value_quaternion.real;
-			f64 imag = v.value_quaternion.imag;
-			f64 jmag = v.value_quaternion.jmag;
-			f64 kmag = v.value_quaternion.kmag;
-			return exact_value_quaternion(-real, -imag, -jmag, -kmag);
-		}
 		}
 	} break;
 
@@ -474,10 +377,8 @@ i32 exact_value_order(ExactValue v) {
 		return 3;
 	case ExactValue_Complex:
 		return 4;
-	case ExactValue_Quaternion:
-		return 5;
 	case ExactValue_Pointer:
-		return 6;
+		return 5;
 
 	default:
 		GB_PANIC("How'd you get here? Invalid Value.kind");
@@ -499,7 +400,6 @@ void match_exact_values(ExactValue *x, ExactValue *y) {
 	case ExactValue_Bool:
 	case ExactValue_String:
 	case ExactValue_Complex:
-	case ExactValue_Quaternion:
 		return;
 
 	case ExactValue_Integer:
@@ -513,9 +413,6 @@ void match_exact_values(ExactValue *x, ExactValue *y) {
 		case ExactValue_Complex:
 			*x = exact_value_complex(i128_to_f64(x->value_integer), 0);
 			return;
-		case ExactValue_Quaternion:
-			*x = exact_value_quaternion(i128_to_f64(x->value_integer), 0, 0, 0);
-			return;
 		}
 		break;
 
@@ -526,9 +423,6 @@ void match_exact_values(ExactValue *x, ExactValue *y) {
 		case ExactValue_Complex:
 			*x = exact_value_to_complex(*x);
 			return;
-		case ExactValue_Quaternion:
-			*x = exact_value_to_quaternion(*x);
-			return;
 		}
 		break;
 	}
@@ -620,53 +514,6 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
 		}
 		return exact_value_complex(real, imag);
 	} break;
-
-	case ExactValue_Quaternion: {
-		y = exact_value_to_quaternion(y);
-		f64 a = x.value_quaternion.real;
-		f64 b = x.value_quaternion.imag;
-		f64 c = x.value_quaternion.jmag;
-		f64 d = x.value_quaternion.kmag;
-
-		f64 e = x.value_quaternion.real;
-		f64 f = x.value_quaternion.imag;
-		f64 g = x.value_quaternion.jmag;
-		f64 h = x.value_quaternion.kmag;
-
-		f64 real = 0;
-		f64 imag = 0;
-		f64 jmag = 0;
-		f64 kmag = 0;
-		switch (op) {
-		case Token_Add:
-			real = a + e;
-			imag = b + f;
-			jmag = c + g;
-			kmag = d + h;
-			break;
-		case Token_Sub:
-			real = a - e;
-			imag = b - f;
-			jmag = c - g;
-			kmag = d - h;
-			break;
-		case Token_Mul:
-			real = a*f + b*e + c*h - d*g;
-			imag = a*g - b*h + c*e + d*f;
-			jmag = a*h + b*g - c*f + d*e;
-			kmag = a*e - b*f - c*g - d*h;
-			break;
-		case Token_Quo: {
-			f64 s = e*e + f*f + g*g + h*h;
-			real = (+a*e + b*f + c*g + d*h)/s;
-			imag = (-a*f + b*e - c*h + d*h)/s;
-			jmag = (-a*g + b*h + c*e - d*f)/s;
-			kmag = (-a*h - b*g + c*f + d*e)/s;
-		} break;
-		default: goto error;
-		}
-		return exact_value_quaternion(real, imag, jmag, kmag);
-	} break;
 	}
 
 error:
@@ -738,23 +585,6 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
 		}
 	} break;
 
-	case ExactValue_Quaternion: {
-		f64 a = x.value_quaternion.real;
-		f64 b = x.value_quaternion.imag;
-		f64 c = x.value_quaternion.jmag;
-		f64 d = x.value_quaternion.kmag;
-
-		f64 e = y.value_quaternion.real;
-		f64 f = y.value_quaternion.imag;
-		f64 g = y.value_quaternion.jmag;
-		f64 h = y.value_quaternion.kmag;
-
-		switch (op) {
-		case Token_CmpEq: return cmp_f64(a, e) == 0 && cmp_f64(b, f) == 0 && cmp_f64(c, g) == 0 && cmp_f64(d, h) == 0;
-		case Token_NotEq: return cmp_f64(a, e) != 0 || cmp_f64(b, f) != 0 || cmp_f64(c, g) != 0 || cmp_f64(d, h) != 0;
-		}
-	} break;
-
 	case ExactValue_String: {
 		String a = x.value_string;
 		String b = y.value_string;

+ 0 - 215
src/ir.c

@@ -1922,126 +1922,6 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
 
 		ir_emit_comment(proc, str_lit("complex.end.begin"));
 		return ir_emit_load(proc, res);
-	} else if (is_type_quaternion(t_left)) {
-		ir_emit_comment(proc, str_lit("quaternion.arith.begin"));
-		Type *ft = base_quaternion_elem_type(t_left);
-
-		irValue *res = ir_add_local_generated(proc, type);
-		irValue *a = ir_emit_struct_ev(proc, left,  0);
-		irValue *b = ir_emit_struct_ev(proc, left,  1);
-		irValue *c = ir_emit_struct_ev(proc, left,  2);
-		irValue *d = ir_emit_struct_ev(proc, left,  3);
-
-		irValue *e = ir_emit_struct_ev(proc, right, 0);
-		irValue *f = ir_emit_struct_ev(proc, right, 1);
-		irValue *g = ir_emit_struct_ev(proc, right, 2);
-		irValue *h = ir_emit_struct_ev(proc, right, 3);
-
-		irValue *real = NULL;
-		irValue *imag = NULL;
-		irValue *jmag = NULL;
-		irValue *kmag = NULL;
-
-		switch (op) {
-		case Token_Add:
-			real = ir_emit_arith(proc, Token_Add, a, e, ft);
-			imag = ir_emit_arith(proc, Token_Add, b, f, ft);
-			jmag = ir_emit_arith(proc, Token_Add, c, g, ft);
-			kmag = ir_emit_arith(proc, Token_Add, d, h, ft);
-			break;
-		case Token_Sub:
-			real = ir_emit_arith(proc, Token_Sub, a, e, ft);
-			imag = ir_emit_arith(proc, Token_Sub, b, f, ft);
-			jmag = ir_emit_arith(proc, Token_Sub, c, g, ft);
-			kmag = ir_emit_arith(proc, Token_Sub, d, h, ft);
-			break;
-		case Token_Mul: {
-			irValue *r0 = ir_emit_arith(proc, Token_Mul, a, e, ft);
-			irValue *r1 = ir_emit_arith(proc, Token_Mul, b, f, ft);
-			irValue *r2 = ir_emit_arith(proc, Token_Mul, c, h, ft);
-			irValue *r3 = ir_emit_arith(proc, Token_Mul, d, g, ft);
-			real = ir_emit_arith(proc, Token_Add, r0, r1, ft);
-			real = ir_emit_arith(proc, Token_Add, real, r2, ft);
-			real = ir_emit_arith(proc, Token_Add, real, r3, ft);
-
-			irValue *i0 = ir_emit_arith(proc, Token_Mul, a, g, ft);
-			irValue *i1 = ir_emit_arith(proc, Token_Mul, b, h, ft);
-			irValue *i2 = ir_emit_arith(proc, Token_Mul, c, e, ft);
-			irValue *i3 = ir_emit_arith(proc, Token_Mul, d, f, ft);
-			imag = ir_emit_arith(proc, Token_Sub, i0, i1, ft);
-			imag = ir_emit_arith(proc, Token_Add, imag, i2, ft);
-			imag = ir_emit_arith(proc, Token_Add, imag, i3, ft);
-
-			irValue *j0 = ir_emit_arith(proc, Token_Mul, a, h, ft);
-			irValue *j1 = ir_emit_arith(proc, Token_Mul, b, g, ft);
-			irValue *j2 = ir_emit_arith(proc, Token_Mul, c, f, ft);
-			irValue *j3 = ir_emit_arith(proc, Token_Mul, d, e, ft);
-			jmag = ir_emit_arith(proc, Token_Add, j0, j1, ft);
-			jmag = ir_emit_arith(proc, Token_Sub, imag, j2, ft);
-			jmag = ir_emit_arith(proc, Token_Sub, imag, j3, ft);
-
-			irValue *k0 = ir_emit_arith(proc, Token_Mul, a, e, ft);
-			irValue *k1 = ir_emit_arith(proc, Token_Mul, b, f, ft);
-			irValue *k2 = ir_emit_arith(proc, Token_Mul, c, g, ft);
-			irValue *k3 = ir_emit_arith(proc, Token_Mul, d, h, ft);
-			kmag = ir_emit_arith(proc, Token_Sub, j0, j1, ft);
-			kmag = ir_emit_arith(proc, Token_Sub, imag, j2, ft);
-			kmag = ir_emit_arith(proc, Token_Sub, imag, j3, ft);
-		} break;
-		case Token_Quo: {
-			irValue *s0 = ir_emit_arith(proc, Token_Mul, e, e, ft);
-			irValue *s1 = ir_emit_arith(proc, Token_Mul, f, f, ft);
-			irValue *s2 = ir_emit_arith(proc, Token_Mul, g, g, ft);
-			irValue *s3 = ir_emit_arith(proc, Token_Mul, h, h, ft);
-			irValue *s = ir_emit_arith(proc, Token_Add, s0, s1, ft);
-			s = ir_emit_arith(proc, Token_Add, s, s2, ft);
-			s = ir_emit_arith(proc, Token_Add, s, s3, ft);
-
-			irValue *r0 = ir_emit_arith(proc, Token_Mul, a, e, ft);
-			irValue *r1 = ir_emit_arith(proc, Token_Mul, b, f, ft);
-			irValue *r2 = ir_emit_arith(proc, Token_Mul, c, h, ft);
-			irValue *r3 = ir_emit_arith(proc, Token_Mul, d, g, ft);
-			real = ir_emit_arith(proc, Token_Add, r0, r1, ft);
-			real = ir_emit_arith(proc, Token_Add, real, r2, ft);
-			real = ir_emit_arith(proc, Token_Add, real, r3, ft);
-			real = ir_emit_arith(proc, Token_Quo, real, s, ft);
-
-			irValue *i0 = ir_emit_arith(proc, Token_Mul, a, f, ft);
-			irValue *i1 = ir_emit_arith(proc, Token_Mul, b, e, ft);
-			irValue *i2 = ir_emit_arith(proc, Token_Mul, c, h, ft);
-			irValue *i3 = ir_emit_arith(proc, Token_Mul, d, g, ft);
-			imag = ir_emit_arith(proc, Token_Sub, i1, i0, ft);
-			imag = ir_emit_arith(proc, Token_Sub, imag, i2, ft);
-			imag = ir_emit_arith(proc, Token_Add, imag, i3, ft);
-			imag = ir_emit_arith(proc, Token_Quo, imag, s, ft);
-
-			irValue *j0 = ir_emit_arith(proc, Token_Mul, a, g, ft);
-			irValue *j1 = ir_emit_arith(proc, Token_Mul, b, h, ft);
-			irValue *j2 = ir_emit_arith(proc, Token_Mul, c, e, ft);
-			irValue *j3 = ir_emit_arith(proc, Token_Mul, d, f, ft);
-			jmag = ir_emit_arith(proc, Token_Sub, j1, j0, ft);
-			jmag = ir_emit_arith(proc, Token_Add, imag, j2, ft);
-			jmag = ir_emit_arith(proc, Token_Sub, imag, j3, ft);
-			jmag = ir_emit_arith(proc, Token_Quo, jmag, s, ft);
-
-			irValue *k0 = ir_emit_arith(proc, Token_Mul, a, h, ft);
-			irValue *k1 = ir_emit_arith(proc, Token_Mul, b, g, ft);
-			irValue *k2 = ir_emit_arith(proc, Token_Mul, c, f, ft);
-			irValue *k3 = ir_emit_arith(proc, Token_Mul, d, e, ft);
-			kmag = ir_emit_arith(proc, Token_Add, k2, k3, ft);
-			kmag = ir_emit_arith(proc, Token_Sub, imag, k0, ft);
-			kmag = ir_emit_arith(proc, Token_Sub, imag, k1, ft);
-			kmag = ir_emit_arith(proc, Token_Quo, kmag, s, ft);
-		} break;
-		}
-
-		ir_emit_store(proc, ir_emit_struct_ep(proc, res, 0), real);
-		ir_emit_store(proc, ir_emit_struct_ep(proc, res, 1), imag);
-		ir_emit_store(proc, ir_emit_struct_ep(proc, res, 2), jmag);
-		ir_emit_store(proc, ir_emit_struct_ep(proc, res, 3), kmag);
-
-		ir_emit_comment(proc, str_lit("quaternion.end.begin"));
-		return ir_emit_load(proc, res);
 	}
 
 
@@ -2319,14 +2199,6 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
 		case 0: result_type = make_type_pointer(a, ft); break;
 		case 1: result_type = make_type_pointer(a, ft); break;
 		}
-	} else if (is_type_quaternion(t)) {
-		Type *ft = base_quaternion_elem_type(t);
-		switch (index) {
-		case 0: result_type = make_type_pointer(a, ft); break;
-		case 1: result_type = make_type_pointer(a, ft); break;
-		case 2: result_type = make_type_pointer(a, ft); break;
-		case 3: result_type = make_type_pointer(a, ft); break;
-		}
 	} else if (is_type_slice(t)) {
 		switch (index) {
 		case 0: result_type = make_type_pointer(a, make_type_pointer(a, t->Slice.elem)); break;
@@ -2396,14 +2268,6 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
 		case 0: result_type = ft; break;
 		case 1: result_type = ft; break;
 		}
-	} else if (is_type_quaternion(t)) {
-		Type *ft = base_quaternion_elem_type(t);
-		switch (index) {
-		case 0: result_type = ft; break;
-		case 1: result_type = ft; break;
-		case 2: result_type = ft; break;
-		case 3: result_type = ft; break;
-		}
 	} else if (is_type_slice(t)) {
 		switch (index) {
 		case 0: result_type = make_type_pointer(a, t->Slice.elem); break;
@@ -2744,8 +2608,6 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
 				ev = exact_value_to_float(ev);
 			} else if (is_type_complex(dst)) {
 				ev = exact_value_to_complex(ev);
-			} else if (is_type_quaternion(dst)) {
-				ev = exact_value_to_quaternion(ev);
 			} else if (is_type_string(dst)) {
 				// Handled elsewhere
 				GB_ASSERT(ev.kind == ExactValue_String);
@@ -2821,20 +2683,6 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
 		return ir_emit_load(proc, gen);
 	}
 
-	if (is_type_quaternion(src) && is_type_quaternion(dst)) {
-		Type *ft = base_quaternion_elem_type(dst);
-		irValue *gen = ir_add_local_generated(proc, dst);
-		irValue *real = ir_emit_conv(proc, ir_emit_struct_ev(proc, value, 0), ft);
-		irValue *imag = ir_emit_conv(proc, ir_emit_struct_ev(proc, value, 1), ft);
-		irValue *jmag = ir_emit_conv(proc, ir_emit_struct_ev(proc, value, 2), ft);
-		irValue *kmag = ir_emit_conv(proc, ir_emit_struct_ev(proc, value, 3), ft);
-		ir_emit_store(proc, ir_emit_struct_ep(proc, gen, 0), real);
-		ir_emit_store(proc, ir_emit_struct_ep(proc, gen, 1), imag);
-		ir_emit_store(proc, ir_emit_struct_ep(proc, gen, 2), jmag);
-		ir_emit_store(proc, ir_emit_struct_ep(proc, gen, 3), kmag);
-		return ir_emit_load(proc, gen);
-	}
-
 	// float <-> integer
 	if (is_type_float(src) && is_type_integer(dst)) {
 		irConvKind kind = irConv_fptosi;
@@ -3032,8 +2880,6 @@ bool ir_is_type_aggregate(Type *t) {
 
 		case Basic_complex64:
 		case Basic_complex128:
-		case Basic_quaternion128:
-		case Basic_quaternion256:
 			return true;
 		}
 		break;
@@ -4476,27 +4322,6 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 					return ir_emit_load(proc, dst);
 				} break;
 
-				case BuiltinProc_quaternion: {
-					ir_emit_comment(proc, str_lit("quaternion"));
-					irValue *real = ir_build_expr(proc, ce->args.e[0]);
-					irValue *imag = ir_build_expr(proc, ce->args.e[1]);
-					irValue *jmag = ir_build_expr(proc, ce->args.e[2]);
-					irValue *kmag = ir_build_expr(proc, ce->args.e[3]);
-					irValue *dst = ir_add_local_generated(proc, tv.type);
-
-					Type *ft = base_quaternion_elem_type(tv.type);
-					real = ir_emit_conv(proc, real, ft);
-					imag = ir_emit_conv(proc, imag, ft);
-					jmag = ir_emit_conv(proc, jmag, ft);
-					kmag = ir_emit_conv(proc, kmag, ft);
-					ir_emit_store(proc, ir_emit_struct_ep(proc, dst, 0), real);
-					ir_emit_store(proc, ir_emit_struct_ep(proc, dst, 1), imag);
-					ir_emit_store(proc, ir_emit_struct_ep(proc, dst, 2), jmag);
-					ir_emit_store(proc, ir_emit_struct_ep(proc, dst, 3), kmag);
-
-					return ir_emit_load(proc, dst);
-				} break;
-
 				case BuiltinProc_real: {
 					ir_emit_comment(proc, str_lit("real"));
 					irValue *val = ir_build_expr(proc, ce->args.e[0]);
@@ -4509,18 +4334,6 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 					irValue *imag = ir_emit_struct_ev(proc, val, 1);
 					return ir_emit_conv(proc, imag, tv.type);
 				} break;
-				case BuiltinProc_jmag: {
-					ir_emit_comment(proc, str_lit("jmag"));
-					irValue *val = ir_build_expr(proc, ce->args.e[0]);
-					irValue *jmag = ir_emit_struct_ev(proc, val, 2);
-					return ir_emit_conv(proc, jmag, tv.type);
-				} break;
-				case BuiltinProc_kmag: {
-					ir_emit_comment(proc, str_lit("kmag"));
-					irValue *val = ir_build_expr(proc, ce->args.e[0]);
-					irValue *kmag = ir_emit_struct_ev(proc, val, 3);
-					return ir_emit_conv(proc, kmag, tv.type);
-				} break;
 
 				case BuiltinProc_conj: {
 					ir_emit_comment(proc, str_lit("conj"));
@@ -4534,19 +4347,6 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 						imag = ir_emit_unary_arith(proc, Token_Sub, imag, ir_type(imag));
 						ir_emit_store(proc, ir_emit_struct_ep(proc, res, 0), real);
 						ir_emit_store(proc, ir_emit_struct_ep(proc, res, 1), imag);
-					} else if (is_type_quaternion(t)) {
-						res = ir_add_local_generated(proc, tv.type);
-						irValue *real = ir_emit_struct_ev(proc, val, 0);
-						irValue *imag = ir_emit_struct_ev(proc, val, 1);
-						irValue *jmag = ir_emit_struct_ev(proc, val, 2);
-						irValue *kmag = ir_emit_struct_ev(proc, val, 3);
-						imag = ir_emit_unary_arith(proc, Token_Sub, imag, ir_type(imag));
-						jmag = ir_emit_unary_arith(proc, Token_Sub, jmag, ir_type(jmag));
-						kmag = ir_emit_unary_arith(proc, Token_Sub, kmag, ir_type(kmag));
-						ir_emit_store(proc, ir_emit_struct_ep(proc, res, 0), real);
-						ir_emit_store(proc, ir_emit_struct_ep(proc, res, 1), imag);
-						ir_emit_store(proc, ir_emit_struct_ep(proc, res, 2), jmag);
-						ir_emit_store(proc, ir_emit_struct_ep(proc, res, 3), kmag);
 					}
 					return ir_emit_load(proc, res);
 				} break;
@@ -4619,16 +4419,6 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 						case 128: return ir_emit_global_call(proc, "__abs_complex128", args, 1);
 						}
 						GB_PANIC("Unknown complex type");
-					} else if (is_type_quaternion(t)) {
-						gbAllocator a = proc->module->allocator;
-						i64 sz = 8*type_size_of(a, t);
-						irValue **args = gb_alloc_array(a, irValue *, 1);
-						args[0] = x;
-						switch (sz) {
-						case 128: return ir_emit_global_call(proc, "__abs_quaternion128", args, 1);
-						case 256: return ir_emit_global_call(proc, "__abs_quaternion256", args, 1);
-						}
-						GB_PANIC("Unknown quaternion type");
 					}
 					irValue *zero = ir_emit_conv(proc, v_zero, t);
 					irValue *cond = ir_emit_comp(proc, Token_Lt, x, zero);
@@ -7566,11 +7356,6 @@ void ir_gen_tree(irGen *s) {
 						tag = ir_emit_conv(proc, ti_ptr, t_type_info_complex_ptr);
 					} break;
 
-					case Basic_quaternion128:
-					case Basic_quaternion256: {
-						tag = ir_emit_conv(proc, ti_ptr, t_type_info_quaternion_ptr);
-					} break;
-
 					case Basic_rawptr:
 						tag = ir_emit_conv(proc, ti_ptr, t_type_info_pointer_ptr);
 						break;

+ 4 - 69
src/ir_print.c

@@ -199,9 +199,6 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
 		case Basic_complex64:  ir_fprintf(f, "%%..complex64");        return;
 		case Basic_complex128: ir_fprintf(f, "%%..complex128");       return;
 
-		case Basic_quaternion128: ir_fprintf(f, "%%..quaternion128"); return;
-		case Basic_quaternion256: ir_fprintf(f, "%%..quaternion256"); return;
-
 		case Basic_rawptr: ir_fprintf(f, "%%..rawptr");               return;
 		case Basic_string: ir_fprintf(f, "%%..string");               return;
 		case Basic_uint:   ir_fprintf(f, "i%lld", word_bits);         return;
@@ -447,41 +444,12 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
 
 	case ExactValue_Complex: {
 		type = core_type(type);
-		if (is_type_quaternion(type)) {
-			Type *ft = base_quaternion_elem_type(type);
-			ir_fprintf(f, " {"); ir_print_type(f, m, ft); ir_fprintf(f, " ");
-			ir_print_exact_value(f, m, exact_value_float(value.value_complex.real), ft);
-			ir_fprintf(f, ", "); ir_print_type(f, m, ft); ir_fprintf(f, " ");
-			ir_print_exact_value(f, m, exact_value_float(value.value_complex.imag), ft);
-			ir_fprintf(f, ", "); ir_print_type(f, m, ft); ir_fprintf(f, " ");
-			ir_print_exact_value(f, m, exact_value_float(0), ft);
-			ir_fprintf(f, ", "); ir_print_type(f, m, ft); ir_fprintf(f, " ");
-			ir_print_exact_value(f, m, exact_value_float(0), ft);
-			ir_fprintf(f, "}");
-
-		} else {
-			GB_ASSERT_MSG(is_type_complex(type), "%s", type_to_string(type));
-			Type *ft = base_complex_elem_type(type);
-			ir_fprintf(f, " {"); ir_print_type(f, m, ft); ir_fprintf(f, " ");
-			ir_print_exact_value(f, m, exact_value_float(value.value_complex.real), ft);
-			ir_fprintf(f, ", "); ir_print_type(f, m, ft); ir_fprintf(f, " ");
-			ir_print_exact_value(f, m, exact_value_float(value.value_complex.imag), ft);
-			ir_fprintf(f, "}");
-		}
-	} break;
-
-	case ExactValue_Quaternion: {
-		GB_ASSERT_MSG(is_type_quaternion(type), "%s", type_to_string(type));
-		type = core_type(type);
-		Type *ft = base_quaternion_elem_type(type);
+		GB_ASSERT_MSG(is_type_complex(type), "%s", type_to_string(type));
+		Type *ft = base_complex_elem_type(type);
 		ir_fprintf(f, " {"); ir_print_type(f, m, ft); ir_fprintf(f, " ");
-		ir_print_exact_value(f, m, exact_value_float(value.value_quaternion.real), ft);
-		ir_fprintf(f, ", "); ir_print_type(f, m, ft); ir_fprintf(f, " ");
-		ir_print_exact_value(f, m, exact_value_float(value.value_quaternion.imag), ft);
+		ir_print_exact_value(f, m, exact_value_float(value.value_complex.real), ft);
 		ir_fprintf(f, ", "); ir_print_type(f, m, ft); ir_fprintf(f, " ");
-		ir_print_exact_value(f, m, exact_value_float(value.value_quaternion.jmag), ft);
-		ir_fprintf(f, ", "); ir_print_type(f, m, ft); ir_fprintf(f, " ");
-		ir_print_exact_value(f, m, exact_value_float(value.value_quaternion.kmag), ft);
+		ir_print_exact_value(f, m, exact_value_float(value.value_complex.imag), ft);
 		ir_fprintf(f, "}");
 	} break;
 
@@ -1153,39 +1121,6 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
 					break;
 				}
 
-				ir_fprintf(f, " ");
-				ir_print_encoded_global(f, make_string_c(runtime_proc), false);
-				ir_fprintf(f, "(");
-				ir_print_type(f, m, type);
-				ir_fprintf(f, " ");
-				ir_print_value(f, m, bo->left, type);
-				ir_fprintf(f, ", ");
-				ir_print_type(f, m, type);
-				ir_fprintf(f, " ");
-				ir_print_value(f, m, bo->right, type);
-				ir_fprintf(f, ")\n");
-				return;
-			} else if (is_type_quaternion(elem_type)) {
-				ir_fprintf(f, "call ");
-				ir_print_calling_convention(f, m, ProcCC_Odin);
-				ir_print_type(f, m, t_bool);
-				char *runtime_proc = "";
-				i64 sz = 8*type_size_of(m->allocator, elem_type);
-				switch (sz) {
-				case 128:
-					switch (bo->op) {
-					case Token_CmpEq: runtime_proc = "__quaternion128_eq"; break;
-					case Token_NotEq: runtime_proc = "__quaternion128_ne"; break;
-					}
-					break;
-				case 256:
-					switch (bo->op) {
-					case Token_CmpEq: runtime_proc = "__quaternion256_eq"; break;
-					case Token_NotEq: runtime_proc = "__quaternion256_ne"; break;
-					}
-					break;
-				}
-
 				ir_fprintf(f, " ");
 				ir_print_encoded_global(f, make_string_c(runtime_proc), false);
 				ir_fprintf(f, "(");

+ 0 - 2
src/ssa.c

@@ -1495,8 +1495,6 @@ ssaValue *ssa_emit_arith(ssaProc *p, TokenKind op, ssaValue *x, ssaValue *y, Typ
 		GB_PANIC("TODO(bill): ssa_emit_arith vector");
 	} else if (is_type_complex(x->type)) {
 		GB_PANIC("TODO(bill): ssa_emit_arith complex");
-	} else if (is_type_quaternion(x->type)) {
-		GB_PANIC("TODO(bill): ssa_emit_arith quaternion");
 	}
 
 	if (op == Token_Add) {

+ 1 - 3
src/tokenizer.c

@@ -577,11 +577,9 @@ exponent:
 		scan_mantissa(t, 10);
 	}
 
-	switch (t->curr_rune) {
-	case 'i': case 'j': case 'k':
+	if (t->curr_rune == 'i') {
 		token.kind = Token_Imag;
 		advance_to_next_rune(t);
-		break;
 	}
 
 end:

+ 5 - 42
src/types.c

@@ -20,9 +20,6 @@ typedef enum BasicKind {
 	Basic_complex64,
 	Basic_complex128,
 
-	Basic_quaternion128,
-	Basic_quaternion256,
-
 	Basic_int,
 	Basic_uint,
 	Basic_rawptr,
@@ -33,7 +30,6 @@ typedef enum BasicKind {
 	Basic_UntypedInteger,
 	Basic_UntypedFloat,
 	Basic_UntypedComplex,
-	Basic_UntypedQuaternion,
 	Basic_UntypedString,
 	Basic_UntypedRune,
 	Basic_UntypedNil,
@@ -50,13 +46,12 @@ typedef enum BasicFlag {
 	BasicFlag_Unsigned    = GB_BIT(2),
 	BasicFlag_Float       = GB_BIT(3),
 	BasicFlag_Complex     = GB_BIT(4),
-	BasicFlag_Quaternion  = GB_BIT(5),
-	BasicFlag_Pointer     = GB_BIT(6),
-	BasicFlag_String      = GB_BIT(7),
-	BasicFlag_Rune        = GB_BIT(8),
-	BasicFlag_Untyped     = GB_BIT(9),
+	BasicFlag_Pointer     = GB_BIT(5),
+	BasicFlag_String      = GB_BIT(6),
+	BasicFlag_Rune        = GB_BIT(7),
+	BasicFlag_Untyped     = GB_BIT(8),
 
-	BasicFlag_Numeric      = BasicFlag_Integer | BasicFlag_Float   | BasicFlag_Complex | BasicFlag_Quaternion,
+	BasicFlag_Numeric      = BasicFlag_Integer | BasicFlag_Float   | BasicFlag_Complex,
 	BasicFlag_Ordered      = BasicFlag_Integer | BasicFlag_Float   | BasicFlag_String  | BasicFlag_Pointer,
 	BasicFlag_ConstantType = BasicFlag_Boolean | BasicFlag_Numeric | BasicFlag_Pointer | BasicFlag_String | BasicFlag_Rune,
 } BasicFlag;
@@ -236,9 +231,6 @@ gb_global Type basic_types[] = {
 	{Type_Basic, {Basic_complex64,         BasicFlag_Complex,                          8, STR_LIT("complex64")}},
 	{Type_Basic, {Basic_complex128,        BasicFlag_Complex,                         16, STR_LIT("complex128")}},
 
-	{Type_Basic, {Basic_quaternion128,     BasicFlag_Quaternion,                      16, STR_LIT("quaternion128")}},
-	{Type_Basic, {Basic_quaternion256,     BasicFlag_Quaternion,                      32, STR_LIT("quaternion256")}},
-
 	{Type_Basic, {Basic_int,               BasicFlag_Integer,                         -1, STR_LIT("int")}},
 	{Type_Basic, {Basic_uint,              BasicFlag_Integer | BasicFlag_Unsigned,    -1, STR_LIT("uint")}},
 
@@ -250,7 +242,6 @@ gb_global Type basic_types[] = {
 	{Type_Basic, {Basic_UntypedInteger,    BasicFlag_Integer    | BasicFlag_Untyped,   0, STR_LIT("untyped integer")}},
 	{Type_Basic, {Basic_UntypedFloat,      BasicFlag_Float      | BasicFlag_Untyped,   0, STR_LIT("untyped float")}},
 	{Type_Basic, {Basic_UntypedComplex,    BasicFlag_Complex    | BasicFlag_Untyped,   0, STR_LIT("untyped complex")}},
-	{Type_Basic, {Basic_UntypedQuaternion, BasicFlag_Quaternion | BasicFlag_Untyped,   0, STR_LIT("untyped quaternion")}},
 	{Type_Basic, {Basic_UntypedString,     BasicFlag_String     | BasicFlag_Untyped,   0, STR_LIT("untyped string")}},
 	{Type_Basic, {Basic_UntypedRune,       BasicFlag_Integer    | BasicFlag_Untyped,   0, STR_LIT("untyped rune")}},
 	{Type_Basic, {Basic_UntypedNil,        BasicFlag_Untyped,                          0, STR_LIT("untyped nil")}},
@@ -280,9 +271,6 @@ gb_global Type *t_f64             = &basic_types[Basic_f64];
 gb_global Type *t_complex64       = &basic_types[Basic_complex64];
 gb_global Type *t_complex128      = &basic_types[Basic_complex128];
 
-gb_global Type *t_quaternion128   = &basic_types[Basic_quaternion128];
-gb_global Type *t_quaternion256   = &basic_types[Basic_quaternion256];
-
 gb_global Type *t_int             = &basic_types[Basic_int];
 gb_global Type *t_uint            = &basic_types[Basic_uint];
 
@@ -294,7 +282,6 @@ gb_global Type *t_untyped_bool       = &basic_types[Basic_UntypedBool];
 gb_global Type *t_untyped_integer    = &basic_types[Basic_UntypedInteger];
 gb_global Type *t_untyped_float      = &basic_types[Basic_UntypedFloat];
 gb_global Type *t_untyped_complex    = &basic_types[Basic_UntypedComplex];
-gb_global Type *t_untyped_quaternion = &basic_types[Basic_UntypedQuaternion];
 gb_global Type *t_untyped_string     = &basic_types[Basic_UntypedString];
 gb_global Type *t_untyped_rune       = &basic_types[Basic_UntypedRune];
 gb_global Type *t_untyped_nil        = &basic_types[Basic_UntypedNil];
@@ -322,7 +309,6 @@ gb_global Type *t_type_info_named         = NULL;
 gb_global Type *t_type_info_integer       = NULL;
 gb_global Type *t_type_info_float         = NULL;
 gb_global Type *t_type_info_complex       = NULL;
-gb_global Type *t_type_info_quaternion    = NULL;
 gb_global Type *t_type_info_any           = NULL;
 gb_global Type *t_type_info_string        = NULL;
 gb_global Type *t_type_info_boolean       = NULL;
@@ -697,13 +683,6 @@ bool is_type_complex(Type *t) {
 	}
 	return false;
 }
-bool is_type_quaternion(Type *t) {
-	t = core_type(t);
-	if (t->kind == Type_Basic) {
-		return (t->Basic.flags & BasicFlag_Quaternion) != 0;
-	}
-	return false;
-}
 bool is_type_f32(Type *t) {
 	t = core_type(t);
 	if (t->kind == Type_Basic) {
@@ -806,19 +785,6 @@ Type *base_complex_elem_type(Type *t) {
 	GB_PANIC("Invalid complex type");
 	return t_invalid;
 }
-Type *base_quaternion_elem_type(Type *t) {
-	t = core_type(t);
-	if (is_type_quaternion(t)) {
-		switch (t->Basic.kind) {
-		case Basic_quaternion128:     return t_f32;
-		case Basic_quaternion256:     return t_f64;
-		case Basic_UntypedQuaternion: return t_untyped_float;
-		}
-	}
-	GB_PANIC("Invalid quaternion type");
-	return t_invalid;
-}
-
 
 bool is_type_struct(Type *t) {
 	t = base_type(t);
@@ -1094,7 +1060,6 @@ Type *default_type(Type *type) {
 		case Basic_UntypedInteger:    return t_int;
 		case Basic_UntypedFloat:      return t_f64;
 		case Basic_UntypedComplex:    return t_complex128;
-		case Basic_UntypedQuaternion: return t_quaternion256;
 		case Basic_UntypedString:     return t_string;
 		case Basic_UntypedRune:       return t_rune;
 		}
@@ -1566,8 +1531,6 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
 
 		case Basic_complex64: case Basic_complex128:
 			return type_size_of_internal(allocator, t, path) / 2;
-		case Basic_quaternion128: case Basic_quaternion256:
-			return type_size_of_internal(allocator, t, path) / 4;
 		}
 	} break;