瀏覽代碼

Change cast syntax, int(x), []byte(s), (^int)(p)

Ginger Bill 8 年之前
父節點
當前提交
2af9fb79dc
共有 17 個文件被更改,包括 529 次插入356 次删除
  1. 6 5
      code/demo.odin
  2. 4 4
      core/_preload.odin
  3. 92 92
      core/fmt.odin
  4. 31 31
      core/hash.odin
  5. 7 7
      core/math.odin
  6. 12 12
      core/mem.odin
  7. 2 2
      core/opengl.odin
  8. 32 32
      core/os_windows.odin
  9. 2 2
      core/sync.odin
  10. 3 3
      core/sys/windows.odin
  11. 20 20
      core/utf8.odin
  12. 189 41
      src/check_expr.c
  13. 8 0
      src/checker.c
  14. 46 28
      src/ir.c
  15. 14 16
      src/parser.c
  16. 1 1
      src/string.c
  17. 60 60
      src/tokenizer.c

+ 6 - 5
code/demo.odin

@@ -10,20 +10,22 @@
 #import "utf8.odin";
 
 main :: proc() {
-	foo :: proc(x: ^i32) {
+	foo :: proc(x: ^i32) -> (int, int) {
 		fmt.println("^int");
+		return 123, int(x^);
 	}
 	foo :: proc(x: rawptr) {
 		fmt.println("rawptr");
 	}
 
+
 	THINGI :: 14451;
 	THINGF :: 14451.1;
 
-	a: i32;
+	a: i32 = 111111;
 	b: f32;
 	c: rawptr;
-	foo(^a);
+	fmt.println(foo(^a));
 	foo(^b);
 	foo(c);
 	// foo(nil);
@@ -36,12 +38,11 @@ main :: proc() {
 		fmt.printf("int arg, i=%d\n", i);
 	}
 	foo :: proc(f: f64) {
-		i := f as int;
+		i := int(f);
 		fmt.printf("f64 arg, f=%d\n", i);
 	}
 
 	foo();
-	foo(THINGI as int);
 	foo(int(THINGI));
 	// foo(THINGI);
 	foo(THINGF);

+ 4 - 4
core/_preload.odin

@@ -233,7 +233,7 @@ default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 		case ALLOC:
 			total_size := size + alignment + size_of(mem.AllocationHeader);
 			ptr := os.heap_alloc(total_size);
-			header := ptr as ^mem.AllocationHeader;
+			header := (^mem.AllocationHeader)(ptr);
 			ptr = mem.align_forward(header+1, alignment);
 			mem.allocation_header_fill(header, ptr, size);
 			return mem.zero(ptr, size);
@@ -248,7 +248,7 @@ default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 		case RESIZE:
 			total_size := size + alignment + size_of(mem.AllocationHeader);
 			ptr := os.heap_resize(mem.allocation_header(old_memory), total_size);
-			header := ptr as ^mem.AllocationHeader;
+			header := (^mem.AllocationHeader)(ptr);
 			ptr = mem.align_forward(header+1, alignment);
 			mem.allocation_header_fill(header, ptr, size);
 			return mem.zero(ptr, size);
@@ -297,11 +297,11 @@ __string_eq :: proc(a, b: string) -> bool {
 	if a.data == b.data {
 		return true;
 	}
-	return mem.compare(a.data as rawptr, b.data as rawptr, a.count) == 0;
+	return mem.compare(rawptr(a.data), rawptr(b.data), a.count) == 0;
 }
 
 __string_cmp :: proc(a, b: string) -> int {
-	return mem.compare(a.data as rawptr, b.data as rawptr, min(a.count, b.count));
+	return mem.compare(rawptr(a.data), rawptr(b.data), min(a.count, b.count));
 }
 
 __string_ne :: proc(a, b: string) -> bool #inline { return !__string_eq(a, b); }

+ 92 - 92
core/fmt.odin

@@ -19,7 +19,7 @@ buffer_write :: proc(buf: ^Buffer, b: []byte) {
 	}
 }
 buffer_write_string :: proc(buf: ^Buffer, s: string) {
-	buffer_write(buf, s as []byte);
+	buffer_write(buf, []byte(s));
 }
 buffer_write_byte :: proc(buf: ^Buffer, b: byte) {
 	if buf.length < buf.data.count {
@@ -29,7 +29,7 @@ buffer_write_byte :: proc(buf: ^Buffer, b: byte) {
 }
 buffer_write_rune :: proc(buf: ^Buffer, r: rune) {
 	if r < utf8.RUNE_SELF {
-		buffer_write_byte(buf, r as byte);
+		buffer_write_byte(buf, byte(r));
 		return;
 	}
 
@@ -117,7 +117,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
 		default:
 			buffer_write_string(buf, if info.signed { give "i" } else { give "u"});
 			fi := Fmt_Info{buf = buf};
-			fmt_int(^fi, 8*info.size as u64, false, 'd');
+			fmt_int(^fi, u64(8*info.size), false, 'd');
 		}
 
 	case Float:
@@ -142,7 +142,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
 		if info.params == nil {
 			buffer_write_string(buf, "()");
 		} else {
-			count := (info.params as ^Tuple).fields.count;
+			count := (^Tuple)(info.params).fields.count;
 			if count == 1 { buffer_write_string(buf, "("); }
 			buffer_write_type(buf, info.params);
 			if count == 1 { buffer_write_string(buf, ")"); }
@@ -170,7 +170,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
 	case Array:
 		buffer_write_string(buf, "[");
 		fi := Fmt_Info{buf = buf};
-		fmt_int(^fi, info.count as u64, false, 'd');
+		fmt_int(^fi, u64(info.count), false, 'd');
 		buffer_write_string(buf, "]");
 		buffer_write_type(buf, info.elem);
 	case Slice:
@@ -180,7 +180,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
 	case Vector:
 		buffer_write_string(buf, "[vector ");
 		fi := Fmt_Info{buf = buf};
-		fmt_int(^fi, info.count as u64, false, 'd');
+		fmt_int(^fi, u64(info.count), false, 'd');
 		buffer_write_string(buf, "]");
 		buffer_write_type(buf, info.elem);
 
@@ -307,14 +307,14 @@ parse_int :: proc(s: string, offset: int) -> (int, int, bool) {
 
 	i := 0;
 	for _ : offset..<s.count {
-		c := s[offset] as rune;
+		c := rune(s[offset]);
 		if !is_digit(c) {
 			break;
 		}
 		i += 1;
 
 		result *= 10;
-		result += (c - '0') as int;
+		result += int(c - '0');
 	}
 
 	return result, offset, i != 0;
@@ -361,14 +361,14 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
 		arg.type_info = type_info_base(arg.type_info);
 		match type i : arg {
 		case int:  num = i;
-		case i8:   num = i as int;
-		case i16:  num = i as int;
-		case i32:  num = i as int;
-		case i64:  num = i as int;
-		case u8:   num = i as int;
-		case u16:  num = i as int;
-		case u32:  num = i as int;
-		case u64:  num = i as int;
+		case i8:   num = int(i);
+		case i16:  num = int(i);
+		case i32:  num = int(i);
+		case i64:  num = int(i);
+		case u8:   num = int(i);
+		case u16:  num = int(i);
+		case u32:  num = int(i);
+		case u64:  num = int(i);
 		default:
 			ok = false;
 		}
@@ -421,7 +421,7 @@ fmt_write_padding :: proc(fi: ^Fmt_Info, width: int) {
 }
 
 fmt_integer :: proc(fi: ^Fmt_Info, u: u64, base: int, signed: bool, digits: string) {
-	negative := signed && u as i64 < 0;
+	negative := signed && i64(u) < 0;
 	if negative {
 		u = -u;
 	}
@@ -461,7 +461,7 @@ fmt_integer :: proc(fi: ^Fmt_Info, u: u64, base: int, signed: bool, digits: stri
 		panic("fmt_integer: unknown base, whoops");
 	}
 
-	while b := base as u64; u >= b {
+	while b := u64(base); u >= b {
 		i -= 1;
 		next := u / b;
 		buf[i] = digits[u%b];
@@ -504,7 +504,7 @@ fmt_integer :: proc(fi: ^Fmt_Info, u: u64, base: int, signed: bool, digits: stri
 	if !fi.width_set || fi.width == 0 {
 		buffer_write(fi.buf, buf[i:]);
 	} else {
-		width := fi.width - utf8.rune_count(buf[i:] as string);
+		width := fi.width - utf8.rune_count(string(buf[i:]));
 		if fi.minus {
 			// Right pad
 			buffer_write(fi.buf, buf[i:]);
@@ -533,9 +533,9 @@ fmt_int :: proc(fi: ^Fmt_Info, u: u64, signed: bool, verb: rune) {
 	case 'd': fmt_integer(fi, u, 10, signed, __DIGITS_LOWER);
 	case 'x': fmt_integer(fi, u, 16, signed, __DIGITS_LOWER);
 	case 'X': fmt_integer(fi, u, 16, signed, __DIGITS_UPPER);
-	case 'c': fmt_rune(fi, u as rune);
+	case 'c': fmt_rune(fi, rune(u));
 	case 'U':
-		r := u as rune;
+		r := rune(u);
 		if r < 0 || r > utf8.MAX_RUNE {
 			fmt_bad_verb(fi, verb);
 		} else {
@@ -566,24 +566,24 @@ __TEN_TO_19TH :: 1000000000000000000;
 __ddmulthi :: proc(ol: f64, xh, yh: f64) -> f64 {
 	bt: i64;
 	oh := xh * yh;
-	bt = xh transmute i64;
-	bt &= (~(0 as u64)<<27) as i64;
-	ahi := bt transmute f64;
+	bt = transmute(i64, xh);
+	bt &= i64(~u64(0)<<27);
+	ahi := transmute(f64, bt);
 	alo := xh-ahi;
-	bt = yh transmute i64;
-	bt &= (~(0 as u64)<<27) as i64;
-	bhi := bt transmute f64;
+	bt = transmute(i64, yh);
+	bt &= i64(~u64(0)<<27);
+	bhi := transmute(f64, bt);
 	blo := yh-bhi;
 	return ((ahi*bhi-oh)+ahi*blo+alo*bhi)+alo*blo;
 }
 
 __ddtoi64 :: proc(xh, xl: f64) -> i64 {
-	ob := xh as i64;
-	vh := ob as f64;
+	ob := i64(xh);
+	vh := f64(ob);
 	ahi := xh-vh;
 	t := ahi-xh;
 	alo := (xh-(ahi-t)) - (vh+t);
-	ob += (ahi+alo+xl) as i64;
+	ob += i64(ahi+alo+xl);
 	return ob;
 }
 
@@ -670,9 +670,9 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6
 	e, tens: i32;
 	d: f64 = val;
 
-	bits := d transmute i64;
-	expo := (bits>>52 & 2047) as i32;
-	neg := (bits>>63) as i32 != 0;
+	bits := transmute(i64, d);
+	expo := i32(bits>>52 & 2047);
+	neg := i32(bits>>63) != 0;
 	if neg {
 		d = -d;
 	}
@@ -692,7 +692,7 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6
 		if bits<<1 == 0 {
 			decimal_pos^ = 1;
 			out[0] = '0';
-			start^ = out[:1] as string;
+			start^ = string(out[:1]);
 			return neg;
 		}
 		// find the right expo for denormals
@@ -721,7 +721,7 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6
 		bits = __ddtoi64(ph, pl);
 
 		// check if we undershot
-		if bits as u64 >= __TEN_TO_19TH {
+		if f64(bits) >= __TEN_TO_19TH {
 			tens += 1;
 		}
 	}
@@ -737,10 +737,10 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6
 	if frac_digits < 24 {
 		skip := false;
 		dg: u32 = 1;
-		if bits as u64 >= __powten[9] {
+		if u64(bits) >= __powten[9] {
 			dg = 10;
 		}
-		while bits as u64 >= __powten[dg] {
+		while u64(bits) >= __powten[dg] {
 			dg += 1;
 			if dg == 20 {
 				skip = true;
@@ -751,14 +751,14 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6
 		if (!skip) {
 			r: u64;
 			// add 0.5 at the right position and round
-			e = dg as i32 - frac_digits;
-			if e as u32 < 24 {
+			e = i32(dg) - frac_digits;
+			if u32(e) < 24 {
 				r = __powten[e];
-				bits += (r/2) as i64;
-				if bits as u64 >= __powten[dg] {
+				bits += i64(r/2);
+				if u64(bits) >= __powten[dg] {
 					tens += 1;
 				}
-				bits /= r as i64;
+				bits /= i64(r);
 			}
 		}
 	}
@@ -777,11 +777,11 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6
 			bits /= 1000;
 		}
 		if !skip {
-			n := bits as u32;
+			n := u32(bits);
 			while n%1000 == 0 {
 				n /= 1000;
 			}
-			bits = n as i64;
+			bits = i64(n);
 		}
 	}
 
@@ -793,15 +793,15 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6
 		o := outp-8;
 		// do the conversion in chunks of u32s (avoid most 64-bit divides, worth it, constant denomiators be damned)
 		if bits >= 100000000 {
-			n = (bits%100000000) as u32;
+			n = u32(bits%100000000);
 			bits /= 100000000;
 		} else {
-			n = bits as u32;
+			n = u32(bits);
 			bits = 0;
 		}
 		while n != 0 {
 			outp -= 2;
-			(outp as ^u16)^ = (^__digitpair[(n%100)*2] as ^u16)^;
+			(^u16)(outp)^ = (^u16)(^__digitpair[(n%100)*2])^;
 			n /= 100;
 			e += 2;
 		}
@@ -820,7 +820,7 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6
 	}
 
 	decimal_pos^ = tens;
-	start^ = slice_ptr(outp, e) as string;
+	start^ = string(slice_ptr(outp, e));
 	return neg;
 }
 
@@ -839,18 +839,18 @@ generic_ftoa :: proc(buf: []byte, val: f64, verb: rune, prec, bit_size: int) ->
 	flt: ^Float_Info;
 	match bit_size {
 	case 32:
-		bits = ((val as f32) transmute u32) as u64;
+		bits = u64(transmute(u32, f32(val)));
 		flt = ^f32info;
 	case 64:
-		bits = val transmute u64;
+		bits = u64(val);
 		flt = ^f64info;
 	default:
 		panic("illegal float bit_size");
 	}
 
 	neg := bits>>(flt.expbits+flt.mantbits) != 0;
-	exp := (bits>>flt.mantbits) as int & (1<<flt.expbits - 1);
-	mant := bits & ((1 as u64)<<flt.mantbits - 1);
+	exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1);
+	mant := bits & (u64(1)<<flt.mantbits - 1);
 
 	match exp {
 	case 1<<flt.expbits-1:
@@ -860,13 +860,13 @@ generic_ftoa :: proc(buf: []byte, val: f64, verb: rune, prec, bit_size: int) ->
 		case neg:     s = "-Inf";
 		default:      s = "+Inf";
 		}
-		copy(buf, s as []byte);
+		copy(buf, []byte(s));
 		return buf[:s.count];
 
 	case 0: // denormalized
 		exp+=1;
 	default: // add implicit top bit
-		mant |= (1 as u64)<<flt.mantbits;
+		mant |= u64(1)<<flt.mantbits;
 	}
 
 
@@ -924,7 +924,7 @@ fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) {
 		fmt_bad_verb(fi, verb);
 		return;
 	}
-	u := p as uint as u64;
+	u := u64(uint(p));
 	if !fi.hash || verb == 'v' {
 		buffer_write_string(fi.buf, "0x");
 	}
@@ -952,18 +952,18 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 			ok := false;
 			a := any{type_info_base(e.base), v.data};
 			match type v : a {
-			case i8:   i = v as i64;
-			case i16:  i = v as i64;
-			case i32:  i = v as i64;
-			case i64:  i = v as i64;
-			case int:  i = v as i64;
-			case u8:   i = v as i64;
-			case u16:  i = v as i64;
-			case u32:  i = v as i64;
-			case u64:  i = v as i64;
-			case uint: i = v as i64;
-			case f32:  f = v as f64;
-			case f64:  f = v as f64;
+			case i8:   i = i64(v);
+			case i16:  i = i64(v);
+			case i32:  i = i64(v);
+			case i64:  i = i64(v);
+			case int:  i = i64(v);
+			case u8:   i = i64(v);
+			case u16:  i = i64(v);
+			case u32:  i = i64(v);
+			case u64:  i = i64(v);
+			case uint: i = i64(v);
+			case f32:  f = f64(v);
+			case f64:  f = f64(v);
 			}
 
 			if is_type_integer(e.base) {
@@ -1019,8 +1019,8 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 				buffer_write_string(fi.buf, f.name);
 				// bprint_any(fi.buf, f.offset);
 				buffer_write_string(fi.buf, " = ");
-				data := v.data as ^byte + f.offset;
-				fmt_arg(fi, any{f.type_info, data as rawptr}, 'v');
+				data := (^byte)(v.data) + f.offset;
+				fmt_arg(fi, any{f.type_info, rawptr(data)}, 'v');
 			}
 			buffer_write_byte(fi.buf, '}');
 
@@ -1035,15 +1035,15 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 
 	case Pointer:
 		if v.type_info == type_info(^Type_Info) {
-			buffer_write_type(fi.buf, (v.data as ^^Type_Info)^);
+			buffer_write_type(fi.buf, (^^Type_Info)(v.data)^);
 		} else {
-			fmt_pointer(fi, (v.data as ^rawptr)^, verb);
+			fmt_pointer(fi, (^rawptr)(v.data)^, verb);
 		}
 
 	case Maybe:
 		// TODO(bill): Correct verbs for Maybe types?
 		size := mem.size_of_type_info(info.elem);
-		data := slice_ptr(v.data as ^byte, size+1);
+		data := slice_ptr((^byte)(v.data), size+1);
 		if data[size] != 0 {
 			fmt_arg(fi, any{info.elem, v.data}, verb);
 		} else {
@@ -1062,8 +1062,8 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 			if i > 0 {
 				buffer_write_string(fi.buf, ", ");
 			}
-			data := v.data as ^byte + i*info.elem_size;
-			fmt_arg(fi, any{info.elem, data as rawptr}, 'v');
+			data := (^byte)(v.data) + i*info.elem_size;
+			fmt_arg(fi, any{info.elem, rawptr(data)}, 'v');
 		}
 
 	case Slice:
@@ -1074,13 +1074,13 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 
 		buffer_write_byte(fi.buf, '[');
 		defer buffer_write_byte(fi.buf, ']');
-		slice := v.data as ^[]byte;
+		slice := (^[]byte)(v.data);
 		for i : 0..<slice.count {
 			if i > 0 {
 				buffer_write_string(fi.buf, ", ");
 			}
 			data := slice.data + i*info.elem_size;
-			fmt_arg(fi, any{info.elem, data as rawptr}, 'v');
+			fmt_arg(fi, any{info.elem, rawptr(data)}, 'v');
 		}
 
 	case Vector:
@@ -1106,8 +1106,8 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 				buffer_write_string(fi.buf, ", ");
 			}
 
-			data := v.data as ^byte + i*info.elem_size;
-			fmt_value(fi, any{info.elem, data as rawptr}, 'v');
+			data := (^byte)(v.data) + i*info.elem_size;
+			fmt_value(fi, any{info.elem, rawptr(data)}, 'v');
 		}
 
 	case Struct:
@@ -1120,9 +1120,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 			}
 			buffer_write_string(fi.buf, f.name);
 			buffer_write_string(fi.buf, " = ");
-			data := v.data as ^byte + f.offset;
+			data := (^byte)(v.data) + f.offset;
 			ti := f.type_info;
-			fmt_value(fi, any{ti, data as rawptr}, 'v');
+			fmt_value(fi, any{ti, rawptr(data)}, 'v');
 		}
 
 	case Union:
@@ -1136,7 +1136,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 	case Procedure:
 		buffer_write_type(fi.buf, v.type_info);
 		buffer_write_string(fi.buf, " @ ");
-		fmt_pointer(fi, (v.data as ^rawptr)^, 'p');
+		fmt_pointer(fi, (^rawptr)(v.data)^, 'p');
 	}
 }
 
@@ -1161,19 +1161,19 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
 	base_arg.type_info = type_info_base(base_arg.type_info);
 	match type a : base_arg {
 	case bool:    fmt_bool(fi, a, verb);
-	case f32:     fmt_float(fi, a as f64, 32, verb);
+	case f32:     fmt_float(fi, f64(a), 32, verb);
 	case f64:     fmt_float(fi, a, 64, verb);
 
-	case int:     fmt_int(fi, a as u64, true, verb);
-	case i8:      fmt_int(fi, a as u64, true, verb);
-	case i16:     fmt_int(fi, a as u64, true, verb);
-	case i32:     fmt_int(fi, a as u64, true, verb);
-	case i64:     fmt_int(fi, a as u64, true, verb);
-	case uint:    fmt_int(fi, a as u64, false, verb);
-	case u8:      fmt_int(fi, a as u64, false, verb);
-	case u16:     fmt_int(fi, a as u64, false, verb);
-	case u32:     fmt_int(fi, a as u64, false, verb);
-	case u64:     fmt_int(fi, a as u64, false, verb);
+	case int:     fmt_int(fi, u64(a), true, verb);
+	case i8:      fmt_int(fi, u64(a), true, verb);
+	case i16:     fmt_int(fi, u64(a), true, verb);
+	case i32:     fmt_int(fi, u64(a), true, verb);
+	case i64:     fmt_int(fi, u64(a), true, verb);
+	case uint:    fmt_int(fi, u64(a), false, verb);
+	case u8:      fmt_int(fi, u64(a), false, verb);
+	case u16:     fmt_int(fi, u64(a), false, verb);
+	case u32:     fmt_int(fi, u64(a), false, verb);
+	case u64:     fmt_int(fi, u64(a), false, verb);
 	case string:  fmt_string(fi, a, verb);
 	default:      fmt_value(fi, arg, verb);
 	}

+ 31 - 31
core/hash.odin

@@ -1,58 +1,58 @@
 crc32 :: proc(data: rawptr, len: int) -> u32 {
-	result := ~(0 as u32);
-	s := slice_ptr(data as ^u8, len);
+	result := ~u32(0);
+	s := slice_ptr((^u8)(data), len);
 	for i : 0..<len {
-		b := s[i] as u32;
+		b := u32(s[i]);
 		result = result>>8 ~ __CRC32_TABLE[(result ~ b) & 0xff];
 	}
 	return ~result;
 }
 crc64 :: proc(data: rawptr, len: int) -> u64 {
-	result := ~(0 as u64);
-	s := slice_ptr(data as ^u8, len);
+	result := ~u64(0);
+	s := slice_ptr((^u8)(data), len);
 	for i : 0..<len {
-		b := s[i] as u64;
+		b := u64(s[i]);
 		result = result>>8 ~ __CRC64_TABLE[(result ~ b) & 0xff];
 	}
 	return ~result;
 }
 
 fnv32 :: proc(data: rawptr, len: int) -> u32 {
-	s := slice_ptr(data as ^u8, len);
+	s := slice_ptr((^u8)(data), len);
 
 	h: u32 = 0x811c9dc5;
 	for i : 0..<len {
-		h = (h * 0x01000193) ~ s[i] as u32;
+		h = (h * 0x01000193) ~ u32(s[i]);
 	}
 	return h;
 }
 
 fnv64 :: proc(data: rawptr, len: int) -> u64 {
-	s := slice_ptr(data as ^u8, len);
+	s := slice_ptr((^u8)(data), len);
 
 	h: u64 = 0xcbf29ce484222325;
 	for i : 0..<len {
-		h = (h * 0x100000001b3) ~ s[i] as u64;
+		h = (h * 0x100000001b3) ~ u64(s[i]);
 	}
 	return h;
 }
 
 fnv32a :: proc(data: rawptr, len: int) -> u32 {
-	s := slice_ptr(data as ^u8, len);
+	s := slice_ptr((^u8)(data), len);
 
 	h: u32 = 0x811c9dc5;
 	for i : 0..<len {
-		h = (h ~ s[i] as u32) * 0x01000193;
+		h = (h ~ u32(s[i])) * 0x01000193;
 	}
 	return h;
 }
 
 fnv64a :: proc(data: rawptr, len: int) -> u64 {
-	s := slice_ptr(data as ^u8, len);
+	s := slice_ptr((^u8)(data), len);
 
 	h :u64 = 0xcbf29ce484222325;
 	for i : 0..<len {
-		h = (h ~ s[i] as u64) * 0x100000001b3;
+		h = (h ~ u64(s[i])) * 0x100000001b3;
 	}
 	return h;
 }
@@ -65,10 +65,10 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 {
 		m :: 0xc6a4a7935bd1e995;
 		r :: 47;
 
-		h: u64 = SEED ~ (len as u64 * m);
+		h: u64 = SEED ~ (u64(len) * m);
 
-		data := slice_ptr(data_ as ^u64, len/size_of(u64));
-		data2 := slice_ptr(data_ as ^u8, len);
+		data := slice_ptr((^u64)(data_), len/size_of(u64));
+		data2 := slice_ptr((^u8)(data_), len);
 
 		for i : 0 ..< data.count {
 			k := data[i];
@@ -82,14 +82,14 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 {
 		}
 
 		match len & 7 {
-		case 7: h ~= data2[6] as u64 << 48; fallthrough;
-		case 6: h ~= data2[5] as u64 << 40; fallthrough;
-		case 5: h ~= data2[4] as u64 << 32; fallthrough;
-		case 4: h ~= data2[3] as u64 << 24; fallthrough;
-		case 3: h ~= data2[2] as u64 << 16; fallthrough;
-		case 2: h ~= data2[1] as u64 << 8;  fallthrough;
+		case 7: h ~= u64(data2[6]) << 48; fallthrough;
+		case 6: h ~= u64(data2[5]) << 40; fallthrough;
+		case 5: h ~= u64(data2[4]) << 32; fallthrough;
+		case 4: h ~= u64(data2[3]) << 24; fallthrough;
+		case 3: h ~= u64(data2[2]) << 16; fallthrough;
+		case 2: h ~= u64(data2[1]) << 8;  fallthrough;
 		case 1:
-			h ~= data2[0] as u64;
+			h ~= u64(data2[0]);
 			h *= m;
 		}
 
@@ -102,10 +102,10 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 {
 		m :: 0x5bd1e995;
 		r :: 24;
 
-		h1: u32 = SEED as u32 ~ len as u32;
+		h1: u32 = u32(SEED) ~ u32(len);
 		h2: u32 = SEED >> 32;
 
-		data := slice_ptr(data_ as ^u32, len/size_of(u32));
+		data := slice_ptr((^u32)(data_), len/size_of(u32));
 
 		i := 0;
 		while len >= 8 {
@@ -138,13 +138,13 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 {
 			len -= 4;
 		}
 
-		data8 := slice_ptr((data.data+i) as ^u8, 3); // NOTE(bill): This is unsafe
+		data8 := slice_ptr((^u8)(data.data+i), 3); // NOTE(bill): This is unsafe
 
 		match len {
-		case 3: h2 ~= data8[2] as u32 << 16; fallthrough;
-		case 2: h2 ~= data8[1] as u32 << 8;  fallthrough;
+		case 3: h2 ~= u32(data8[2]) << 16; fallthrough;
+		case 2: h2 ~= u32(data8[1]) << 8;  fallthrough;
 		case 1:
-			h2 ~= data8[0] as u32;
+			h2 ~= u32(data8[0]);
 			h2 *= m;
 		}
 
@@ -157,7 +157,7 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 {
 		h2 ~= h1>>19;
 		h2 *= m;
 
-		h := (h1 as u64)<<32 | h2 as u64;
+		h := u64(h1)<<32 | u64(h2);
 		return h;
 	}
 }

+ 7 - 7
core/math.odin

@@ -45,11 +45,11 @@ sign :: proc(x: f64) -> f64 { if x >= 0 { return +1; } return -1; }
 
 
 copy_sign :: proc(x, y: f32) -> f32 {
-	ix := x transmute u32;
-	iy := y transmute u32;
+	ix := transmute(u32, x);
+	iy := transmute(u32, y);
 	ix &= 0x7fffffff;
 	ix |= iy & 0x80000000;
-	return ix transmute f32;
+	return transmute(f32, ix);
 }
 round :: proc(x: f32) -> f32 {
 	if x >= 0 {
@@ -59,15 +59,15 @@ round :: proc(x: f32) -> f32 {
 }
 floor :: proc(x: f32) -> f32 {
 	if x >= 0 {
-		return x as int as f32;
+		return f32(int(x));
 	}
-	return (x-0.5) as int as f32;
+	return f32(int(x-0.5));
 }
 ceil :: proc(x: f32) -> f32 {
 	if x < 0 {
-		return x as int as f32;
+		return f32(int(x));
 	}
-	return ((x as int)+1) as f32;
+	return f32(int(x)+1);
 }
 
 remainder32 :: proc(x, y: f32) -> f32 {

+ 12 - 12
core/mem.odin

@@ -3,7 +3,7 @@
 
 set :: proc(data: rawptr, value: i32, len: int) -> rawptr #link_name "__mem_set" {
 	llvm_memset_64bit :: proc(dst: rawptr, val: byte, len: int, align: i32, is_volatile: bool) #foreign "llvm.memset.p0i8.i64"
-	llvm_memset_64bit(data, value as byte, len, 1, false);
+	llvm_memset_64bit(data, byte(value), len, 1, false);
 	return data;
 }
 
@@ -26,8 +26,8 @@ copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #link_name "_
 }
 
 compare :: proc(dst, src: rawptr, n: int) -> int #link_name "__mem_compare" {
-	a := slice_ptr(dst as ^byte, n);
-	b := slice_ptr(src as ^byte, n);
+	a := slice_ptr((^byte)(dst), n);
+	b := slice_ptr((^byte)(src), n);
 	for i : 0..<n {
 		match {
 		case a[i] < b[i]:
@@ -56,13 +56,13 @@ is_power_of_two :: proc(x: int) -> bool {
 align_forward :: proc(ptr: rawptr, align: int) -> rawptr {
 	assert(is_power_of_two(align));
 
-	a := align as uint;
-	p := ptr as uint;
+	a := uint(align);
+	p := uint(ptr);
 	modulo := p & (a-1);
 	if modulo != 0 {
 		p += a - modulo;
 	}
-	return p as rawptr;
+	return rawptr(p);
 }
 
 
@@ -73,19 +73,19 @@ Allocation_Header :: struct {
 
 allocation_header_fill :: proc(header: ^Allocation_Header, data: rawptr, size: int) {
 	header.size = size;
-	ptr := (header+1) as ^int;
+	ptr := (^int)(header+1);
 
-	while i := 0; ptr as rawptr < data {
+	while i := 0; rawptr(ptr) < data {
 		(ptr+i)^ = -1;
 		i += 1;
 	}
 }
 allocation_header :: proc(data: rawptr) -> ^Allocation_Header {
-	p := data as ^int;
+	p := (^int)(data);
 	while (p-1)^ == -1 {
 		p = (p-1);
 	}
-	return (p as ^Allocation_Header)-1;
+	return (^Allocation_Header)(p)-1;
 }
 
 
@@ -142,7 +142,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
                           size, alignment: int,
                           old_memory: rawptr, old_size: int, flags: u64) -> rawptr {
 	using Allocator_Mode;
-	arena := allocator_data as ^Arena;
+	arena := (^Arena)(allocator_data);
 
 	match mode {
 	case ALLOC:
@@ -235,7 +235,7 @@ align_of_type_info :: proc(type_info: ^Type_Info) -> int {
 		return WORD_SIZE;
 	case Vector:
 		size := size_of_type_info(info.elem);
-		count := max(prev_pow2(info.count as i64), 1) as int;
+		count := int(max(prev_pow2(i64(info.count)), 1));
 		total := size * count;
 		return clamp(total, 1, MAX_ALIGN);
 	case Struct:

+ 2 - 2
core/opengl.odin

@@ -30,7 +30,7 @@ GetIntegerv :: proc(name: i32, v: ^i32) #foreign "glGetIntegerv"
 
 
 
-_libgl := win32.LoadLibraryA(("opengl32.dll\x00" as string).data);
+_libgl := win32.LoadLibraryA(string("opengl32.dll\x00").data);
 
 GetProcAddress :: proc(name: string) -> proc() #cc_c {
 	assert(name[name.count-1] == 0);
@@ -100,7 +100,7 @@ UniformMatrix4fv:  proc(loc: i32, count: u32, transpose: i32, value: ^f32) #cc_c
 GetUniformLocation:  proc(program: u32, name: ^byte) -> i32 #cc_c;
 
 init :: proc() {
-	set_proc_address :: proc(p: rawptr, name: string) #inline { (p as ^(proc() #cc_c))^ = GetProcAddress(name); }
+	set_proc_address :: proc(p: rawptr, name: string) #inline { (^(proc() #cc_c))(p)^ = GetProcAddress(name); }
 
 	set_proc_address(^GenBuffers,      "glGenBuffers\x00");
 	set_proc_address(^GenVertexArrays, "glGenVertexArrays\x00");

+ 32 - 32
core/os_windows.odin

@@ -73,7 +73,7 @@ open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) {
 		access |= FILE_APPEND_DATA;
 	}
 
-	share_mode := (FILE_SHARE_READ|FILE_SHARE_WRITE) as u32;
+	share_mode := u32(FILE_SHARE_READ|FILE_SHARE_WRITE);
 	sa: ^SECURITY_ATTRIBUTES = nil;
 	sa_inherit := SECURITY_ATTRIBUTES{length = size_of(SECURITY_ATTRIBUTES), inherit_handle = 1};
 	if mode&O_CLOEXEC == 0 {
@@ -95,38 +95,38 @@ open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) {
 	}
 
 	buf: [300]byte;
-	copy(buf[:], path as []byte);
+	copy(buf[:], []byte(path));
 
-	handle := CreateFileA(^buf[0], access, share_mode, sa, create_mode, FILE_ATTRIBUTE_NORMAL, nil) as Handle;
+	handle := Handle(CreateFileA(^buf[0], access, share_mode, sa, create_mode, FILE_ATTRIBUTE_NORMAL, nil));
 	if handle != INVALID_HANDLE {
 		return handle, ERROR_NONE;
 	}
 	err := GetLastError();
-	return INVALID_HANDLE, err as Errno;
+	return INVALID_HANDLE, Errno(err);
 }
 
 close :: proc(fd: Handle) {
-	win32.CloseHandle(fd as win32.HANDLE);
+	win32.CloseHandle(win32.HANDLE(fd));
 }
 
 write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 	bytes_written: i32;
-	e := win32.WriteFile(fd as win32.HANDLE, data.data, data.count as i32, ^bytes_written, nil);
+	e := win32.WriteFile(win32.HANDLE(fd), data.data, i32(data.count), ^bytes_written, nil);
 	if e == win32.FALSE {
 		err := win32.GetLastError();
-		return 0, err as Errno;
+		return 0, Errno(err);
 	}
-	return bytes_written as int, ERROR_NONE;
+	return int(bytes_written), ERROR_NONE;
 }
 
 read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 	bytes_read: i32;
-	e := win32.ReadFile(fd as win32.HANDLE, data.data, data.count as u32, ^bytes_read, nil);
+	e := win32.ReadFile(win32.HANDLE(fd), data.data, u32(data.count), ^bytes_read, nil);
 	if e == win32.FALSE {
 		err := win32.GetLastError();
-		return 0, err as Errno;
+		return 0, Errno(err);
 	}
-	return bytes_read as int, ERROR_NONE;
+	return int(bytes_read), ERROR_NONE;
 }
 
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
@@ -137,18 +137,18 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
 	case 1: w = FILE_CURRENT;
 	case 2: w = FILE_END;
 	}
-	hi := (offset>>32) as i32;
-	lo := offset as i32;
-	ft := GetFileType(fd as HANDLE);
+	hi := i32(offset>>32);
+	lo := i32(offset);
+	ft := GetFileType(HANDLE(fd));
 	if ft == FILE_TYPE_PIPE {
 		return 0, ERROR_FILE_IS_PIPE;
 	}
-	dw_ptr := SetFilePointer(fd as HANDLE, lo, ^hi, w);
+	dw_ptr := SetFilePointer(HANDLE(fd), lo, ^hi, w);
 	if dw_ptr == INVALID_SET_FILE_POINTER {
 		err := GetLastError();
-		return 0, err as Errno;
+		return 0, Errno(err);
 	}
-	return (hi as i64)<<32 + (dw_ptr as i64), ERROR_NONE;
+	return i64(hi)<<32 + i64(dw_ptr), ERROR_NONE;
 }
 
 
@@ -159,9 +159,9 @@ stderr := get_std_handle(win32.STD_ERROR_HANDLE);
 
 
 get_std_handle :: proc(h: int) -> Handle {
-	fd := win32.GetStdHandle(h as i32);
+	fd := win32.GetStdHandle(i32(h));
 	win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0);
-	return fd as Handle;
+	return Handle(fd);
 }
 
 
@@ -171,9 +171,9 @@ get_std_handle :: proc(h: int) -> Handle {
 
 last_write_time :: proc(fd: Handle) -> File_Time {
 	file_info: win32.BY_HANDLE_FILE_INFORMATION;
-	win32.GetFileInformationByHandle(fd as win32.HANDLE, ^file_info);
-	lo := file_info.last_write_time.lo as File_Time;
-	hi := file_info.last_write_time.hi as File_Time;
+	win32.GetFileInformationByHandle(win32.HANDLE(fd), ^file_info);
+	lo := File_Time(file_info.last_write_time.lo);
+	hi := File_Time(file_info.last_write_time.hi);
 	return lo | hi << 32;
 }
 
@@ -184,14 +184,14 @@ last_write_time_by_name :: proc(name: string) -> File_Time {
 
 	assert(buf.count > name.count);
 
-	copy(buf[:], name as []byte);
+	copy(buf[:], []byte(name));
 
 	if win32.GetFileAttributesExA(^buf[0], win32.GetFileExInfoStandard, ^data) != 0 {
 		last_write_time = data.last_write_time;
 	}
 
-	l := last_write_time.lo as File_Time;
-	h := last_write_time.hi as File_Time;
+	l := File_Time(last_write_time.lo);
+	h := File_Time(last_write_time.hi);
 	return l | h << 32;
 }
 
@@ -201,7 +201,7 @@ last_write_time_by_name :: proc(name: string) -> File_Time {
 
 read_entire_file :: proc(name: string) -> ([]byte, bool) {
 	buf: [300]byte;
-	copy(buf[:], name as []byte);
+	copy(buf[:], []byte(name));
 
 	fd, err := open(name, O_RDONLY, 0);
 	if err != ERROR_NONE {
@@ -210,7 +210,7 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
 	defer close(fd);
 
 	length: i64;
-	file_size_ok := win32.GetFileSizeEx(fd as win32.HANDLE, ^length) != 0;
+	file_size_ok := win32.GetFileSizeEx(win32.HANDLE(fd), ^length) != 0;
 	if !file_size_ok {
 		return nil, false;
 	}
@@ -228,18 +228,18 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
 		to_read: u32;
 		MAX :: 1<<32-1;
 		if remaining <= MAX {
-			to_read = remaining as u32;
+			to_read = u32(remaining);
 		} else {
 			to_read = MAX;
 		}
 
-		win32.ReadFile(fd as win32.HANDLE, ^data[total_read], to_read, ^single_read_length, nil);
+		win32.ReadFile(win32.HANDLE(fd), ^data[total_read], to_read, ^single_read_length, nil);
 		if single_read_length <= 0 {
 			free(data.data);
 			return nil, false;
 		}
 
-		total_read += single_read_length as i64;
+		total_read += i64(single_read_length);
 	}
 
 	return data, true;
@@ -259,14 +259,14 @@ heap_free :: proc(ptr: rawptr) {
 
 
 exit :: proc(code: int) {
-	win32.ExitProcess(code as u32);
+	win32.ExitProcess(u32(code));
 }
 
 
 
 current_thread_id :: proc() -> int {
 	GetCurrentThreadId :: proc() -> u32 #foreign #dll_import
-	return GetCurrentThreadId() as int;
+	return int(GetCurrentThreadId());
 }
 
 

+ 2 - 2
core/sync.odin

@@ -13,7 +13,7 @@ Mutex :: struct {
 }
 
 current_thread_id :: proc() -> i32 {
-	return win32.GetCurrentThreadId() as i32;
+	return i32(win32.GetCurrentThreadId());
 }
 
 semaphore_init :: proc(s: ^Semaphore) {
@@ -25,7 +25,7 @@ semaphore_destroy :: proc(s: ^Semaphore) {
 }
 
 semaphore_post :: proc(s: ^Semaphore, count: int) {
-	win32.ReleaseSemaphore(s.handle, count as i32, nil);
+	win32.ReleaseSemaphore(s.handle, i32(count), nil);
 }
 
 semaphore_release :: proc(s: ^Semaphore) #inline { semaphore_post(s, 1); }

+ 3 - 3
core/sys/windows.odin

@@ -19,7 +19,7 @@ BOOL      :: i32;
 WNDPROC   :: type proc(HWND, u32, WPARAM, LPARAM) -> LRESULT #cc_c;
 
 
-INVALID_HANDLE_VALUE :: ~int(0) as HANDLE;
+INVALID_HANDLE_VALUE :: HANDLE(~int(0));
 
 FALSE: BOOL : 0;
 TRUE:  BOOL : 1;
@@ -233,7 +233,7 @@ FILE_TYPE_DISK :: 0x0001;
 FILE_TYPE_CHAR :: 0x0002;
 FILE_TYPE_PIPE :: 0x0003;
 
-INVALID_SET_FILE_POINTER :: ~(0 as u32);
+INVALID_SET_FILE_POINTER :: ~u32(0);
 
 
 
@@ -402,7 +402,7 @@ wglDeleteContext  :: proc(hglrc: HGLRC) -> BOOL #foreign #dll_import
 GetKeyState      :: proc(v_key: i32) -> i16 #foreign #dll_import
 GetAsyncKeyState :: proc(v_key: i32) -> i16 #foreign #dll_import
 
-is_key_down :: proc(key: Key_Code) -> bool #inline { return GetAsyncKeyState(key as i32) < 0; }
+is_key_down :: proc(key: Key_Code) -> bool #inline { return GetAsyncKeyState(i32(key)) < 0; }
 
 Key_Code :: enum i32 {
 	LBUTTON    = 0x01,

+ 20 - 20
core/utf8.odin

@@ -1,7 +1,7 @@
 RUNE_ERROR :: '\ufffd';
 RUNE_SELF  :: 0x80;
 RUNE_BOM   :: 0xfeff;
-RUNE_EOF   :: ~(0 as rune);
+RUNE_EOF   :: ~rune(0);
 MAX_RUNE   :: '\U0010ffff';
 UTF_MAX    :: 4;
 
@@ -40,15 +40,15 @@ accept_sizes := [256]byte{
 
 encode_rune :: proc(r: rune) -> ([4]byte, int) {
 	buf: [4]byte;
-	i := r as u32;
+	i := u32(r);
 	mask: byte : 0x3f;
 	if i <= 1<<7-1 {
-		buf[0] = r as byte;
+		buf[0] = byte(r);
 		return buf, 1;
 	}
 	if i <= 1<<11-1 {
-		buf[0] = 0xc0 | (r>>6) as byte;
-		buf[1] = 0x80 | (r)    as byte & mask;
+		buf[0] = 0xc0 | byte(r>>6);
+		buf[1] = 0x80 | byte(r) & mask;
 		return buf, 2;
 	}
 
@@ -59,16 +59,16 @@ encode_rune :: proc(r: rune) -> ([4]byte, int) {
 	}
 
 	if i <= 1<<16-1 {
-		buf[0] = 0xe0 | (r>>12) as byte;
-		buf[1] = 0x80 | (r>>6)  as byte & mask;
-		buf[2] = 0x80 | (r)     as byte & mask;
+		buf[0] = 0xe0 | byte(r>>12);
+		buf[1] = 0x80 | byte(r>>6) & mask;
+		buf[2] = 0x80 | byte(r)    & mask;
 		return buf, 3;
 	}
 
-	buf[0] = 0xf0 | (r>>18) as byte;
-	buf[1] = 0x80 | (r>>12) as byte & mask;
-	buf[2] = 0x80 | (r>>6)  as byte & mask;
-	buf[3] = 0x80 | (r)     as byte & mask;
+	buf[0] = 0xf0 | byte(r>>18);
+	buf[1] = 0x80 | byte(r>>12) & mask;
+	buf[2] = 0x80 | byte(r>>6)  & mask;
+	buf[3] = 0x80 | byte(r)     & mask;
 	return buf, 4;
 }
 
@@ -80,12 +80,12 @@ decode_rune :: proc(s: string) -> (rune, int) {
 	b0 := s[0];
 	x := accept_sizes[b0];
 	if x >= 0xf0 {
-		mask := (x as rune << 31) >> 31; // all zeros or all ones
-		return (b0 as rune) &~ mask | RUNE_ERROR&mask, 1;
+		mask := (rune(x) << 31) >> 31; // all zeros or all ones
+		return rune(b0) &~ mask | RUNE_ERROR&mask, 1;
 	}
 	size := x & 7;
 	ar := accept_ranges[x>>4];
-	if n < size as int {
+	if n < int(size) {
 		return RUNE_ERROR, 1;
 	}
 	b1 := s[1];
@@ -99,20 +99,20 @@ decode_rune :: proc(s: string) -> (rune, int) {
 	MASK_4 :: 0b00000111;
 
 	if size == 2 {
-		return (b0&MASK_2) as rune <<6 | (b1&MASK_X) as rune, 2;
+		return rune(b0&MASK_2)<<6 | rune(b1&MASK_X), 2;
 	}
 	b2 := s[2];
 	if b2 < 0x80 || 0xbf < b2 {
 		return RUNE_ERROR, 1;
 	}
 	if size == 3 {
-		return (b0&MASK_3) as rune <<12 | (b1&MASK_X) as rune <<6 | (b2&MASK_X) as rune, 3;
+		return rune(b0&MASK_3)<<12 | rune(b1&MASK_X)<<6 | rune(b2&MASK_X), 3;
 	}
 	b3 := s[3];
 	if b3 < 0x80 || 0xbf < b3 {
 		return RUNE_ERROR, 1;
 	}
-	return (b0&MASK_4) as rune <<18 | (b1&MASK_X) as rune <<12 | (b3&MASK_X) as rune <<6 | (b3&MASK_X) as rune, 4;
+	return rune(b0&MASK_4)<<18 | rune(b1&MASK_X)<<12 | rune(b3&MASK_X)<<6 | rune(b3&MASK_X), 4;
 
 }
 
@@ -141,7 +141,7 @@ valid_string :: proc(s: string) -> bool {
 		if x == 0xf1 {
 			return false;
 		}
-		size := (x & 7) as int;
+		size := int(x & 7);
 		if i+size > n {
 			return false;
 		}
@@ -178,7 +178,7 @@ rune_count :: proc(s: string) -> int {
 			i += 1;
 			continue;
 		}
-		size := (x & 7) as int;
+		size := int(x & 7);
 		if i+size > n {
 			i += 1;
 			continue;

+ 189 - 41
src/check_expr.c

@@ -1911,6 +1911,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
 
 	ast_node(be, BinaryExpr, node);
 
+#if 0
 	switch (be->op.kind) {
 	case Token_as: {
 		check_expr(c, x, be->left);
@@ -2103,7 +2104,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
 		return;
 	} break;
 	}
-
+#endif
 	check_expr(c, x, be->left);
 	check_expr(c, y, be->right);
 	if (x->mode == Addressing_Invalid) {
@@ -2728,6 +2729,10 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 	case BuiltinProc_align_of:
 	case BuiltinProc_offset_of:
 	case BuiltinProc_type_info:
+
+	case BuiltinProc_transmute:
+	case BuiltinProc_union_cast:
+	case BuiltinProc_down_cast:
 		// NOTE(bill): The first arg may be a Type, this will be checked case by case
 		break;
 	default:
@@ -2925,6 +2930,10 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 		if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin) {
 			return false;
 		}
+		if (operand->type == NULL || operand->type == t_invalid) {
+			error_node(operand->expr, "Invalid argument to `type_of_val`");
+			return false;
+		}
 		operand->mode = Addressing_Type;
 		break;
 
@@ -2969,6 +2978,184 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 	} break;
 
 
+	case BuiltinProc_transmute: {
+		Type *type = check_type(c, ce->args.e[0]);
+		check_expr(c, operand, ce->args.e[1]);
+		if (operand->mode == Addressing_Invalid) {
+			return false;
+		}
+
+		if (operand->mode == Addressing_Constant) {
+			gbString expr_str = expr_to_string(operand->expr);
+			error_node(operand->expr, "Cannot transmute constant expression: `%s`", expr_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		if (is_type_untyped(operand->type)) {
+			gbString expr_str = expr_to_string(operand->expr);
+			error_node(operand->expr, "Cannot transmute untyped expression: `%s`", expr_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		i64 srcz = type_size_of(c->sizes, c->allocator, operand->type);
+		i64 dstz = type_size_of(c->sizes, c->allocator, type);
+		if (srcz != dstz) {
+			gbString expr_str = expr_to_string(operand->expr);
+			gbString type_str = type_to_string(type);
+			error_node(operand->expr, "Cannot transmute `%s` to `%s`, %lld vs %lld bytes", expr_str, type_str, srcz, dstz);
+			gb_string_free(type_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		operand->type = type;
+	} break;
+	case BuiltinProc_union_cast: {
+		Type *type = check_type(c, ce->args.e[0]);
+		check_expr(c, operand, ce->args.e[1]);
+		if (operand->mode == Addressing_Invalid) {
+			return false;
+		}
+
+		if (operand->mode == Addressing_Constant) {
+			gbString expr_str = expr_to_string(operand->expr);
+			error_node(operand->expr, "Cannot `union_cast` a constant expression: `%s`", expr_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		if (is_type_untyped(operand->type)) {
+			gbString expr_str = expr_to_string(operand->expr);
+			error_node(operand->expr, "Cannot `union_cast` an untyped expression: `%s`", expr_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		bool src_is_ptr = is_type_pointer(operand->type);
+		bool dst_is_ptr = is_type_pointer(type);
+		Type *src = type_deref(operand->type);
+		Type *dst = type_deref(type);
+		Type *bsrc = base_type(src);
+		Type *bdst = base_type(dst);
+
+		if (src_is_ptr != dst_is_ptr) {
+			gbString src_type_str = type_to_string(operand->type);
+			gbString dst_type_str = type_to_string(type);
+			error_node(operand->expr, "Invalid `union_cast` types: `%s` and `%s`", src_type_str, dst_type_str);
+			gb_string_free(dst_type_str);
+			gb_string_free(src_type_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		if (!is_type_union(src)) {
+			error_node(operand->expr, "`union_cast` can only operate on unions");
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		bool ok = false;
+		for (isize i = 1; i < bsrc->Record.field_count; i++) {
+			Entity *f = bsrc->Record.fields[i];
+			if (are_types_identical(f->type, dst)) {
+				ok = true;
+				break;
+			}
+		}
+
+		if (!ok) {
+			gbString expr_str = expr_to_string(operand->expr);
+			gbString dst_type_str = type_to_string(type);
+			error_node(operand->expr, "Cannot `union_cast` `%s` to `%s`", expr_str, dst_type_str);
+			gb_string_free(dst_type_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		Entity **variables = gb_alloc_array(c->allocator, Entity *, 2);
+		variables[0] = make_entity_param(c->allocator, NULL, empty_token, type, false);
+		variables[1] = make_entity_param(c->allocator, NULL, empty_token, t_bool, false);
+
+		Type *tuple = make_type_tuple(c->allocator);
+		tuple->Tuple.variables = variables;
+		tuple->Tuple.variable_count = 2;
+
+		operand->type = tuple;
+		operand->mode = Addressing_Value;
+	} break;
+	case BuiltinProc_down_cast: {
+		Type *type = check_type(c, ce->args.e[0]);
+		check_expr(c, operand, ce->args.e[1]);
+		if (operand->mode == Addressing_Invalid) {
+			return false;
+		}
+
+		if (operand->mode == Addressing_Constant) {
+			gbString expr_str = expr_to_string(operand->expr);
+			error_node(operand->expr, "Cannot `down_cast` a constant expression: `%s`", expr_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		if (is_type_untyped(operand->type)) {
+			gbString expr_str = expr_to_string(operand->expr);
+			error_node(operand->expr, "Cannot `down_cast` an untyped expression: `%s`", expr_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		if (!(is_type_pointer(operand->type) && is_type_pointer(type))) {
+			gbString expr_str = expr_to_string(operand->expr);
+			error_node(operand->expr, "Can only `down_cast` pointers: `%s`", expr_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		Type *src = type_deref(operand->type);
+		Type *dst = type_deref(type);
+		Type *bsrc = base_type(src);
+		Type *bdst = base_type(dst);
+
+		if (!(is_type_struct(bsrc) || is_type_raw_union(bsrc))) {
+			gbString expr_str = expr_to_string(operand->expr);
+			error_node(operand->expr, "Can only `down_cast` pointer from structs or unions: `%s`", expr_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		if (!(is_type_struct(bdst) || is_type_raw_union(bdst))) {
+			gbString expr_str = expr_to_string(operand->expr);
+			error_node(operand->expr, "Can only `down_cast` pointer to structs or unions: `%s`", expr_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		String param_name = check_down_cast_name(dst, src);
+		if (param_name.len == 0) {
+			gbString expr_str = expr_to_string(operand->expr);
+			error_node(operand->expr, "Illegal `down_cast`: `%s`", expr_str);
+			gb_string_free(expr_str);
+			operand->mode = Addressing_Invalid;
+			return false;
+		}
+
+		operand->mode = Addressing_Value;
+		operand->type = type;
+	} break;
+
 
 	case BuiltinProc_compile_assert:
 		// compile_assert :: proc(cond: bool)
@@ -3054,45 +3241,6 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 		operand->mode = Addressing_Value;
 	} break;
 
-	#if 0
-	case BuiltinProc_append: {
-		// append :: proc(x : ^[]Type, y : Type) -> bool
-		Type *x_type = NULL, *y_type = NULL;
-		x_type = base_type(operand->type);
-
-		Operand op = {0};
-		check_expr(c, &op, ce->args.e[1]);
-		if (op.mode == Addressing_Invalid) {
-			return false;
-		}
-		y_type = base_type(op.type);
-
-		if (!(is_type_pointer(x_type) && is_type_slice(x_type->Pointer.elem))) {
-			error_node(call, "First argument to `append` must be a pointer to a slice");
-			return false;
-		}
-
-		Type *elem_type = x_type->Pointer.elem->Slice.elem;
-		if (!check_is_assignable_to(c, &op, elem_type)) {
-			gbString d_arg = expr_to_string(ce->args.e[0]);
-			gbString s_arg = expr_to_string(ce->args.e[1]);
-			gbString d_str = type_to_string(elem_type);
-			gbString s_str = type_to_string(y_type);
-			error_node(call,
-			      "Arguments to `append`, %s, %s, have different element types: %s vs %s",
-			      d_arg, s_arg, d_str, s_str);
-			gb_string_free(s_str);
-			gb_string_free(d_str);
-			gb_string_free(s_arg);
-			gb_string_free(d_arg);
-			return false;
-		}
-
-		operand->type = t_bool; // Returns if it was successful
-		operand->mode = Addressing_Value;
-	} break;
-	#endif
-
 	case BuiltinProc_swizzle: {
 		// swizzle :: proc(v: {N}T, T...) -> {M}T
 		Type *vector_type = base_type(operand->type);
@@ -4557,7 +4705,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
 
 
 	case_ast_node(ue, UnaryExpr, node);
-		check_expr(c, o, ue->expr);
+		check_expr_base(c, o, ue->expr, type_hint);
 		if (o->mode == Addressing_Invalid) {
 			goto error;
 		}

+ 8 - 0
src/checker.c

@@ -135,6 +135,10 @@ typedef enum BuiltinProcId {
 	BuiltinProc_type_info,
 	BuiltinProc_type_info_of_val,
 
+	BuiltinProc_transmute,
+	BuiltinProc_union_cast,
+	BuiltinProc_down_cast,
+
 	BuiltinProc_compile_assert,
 	BuiltinProc_assert,
 	BuiltinProc_panic,
@@ -178,6 +182,10 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
 	{STR_LIT("type_info"),        1, false, Expr_Expr},
 	{STR_LIT("type_info_of_val"), 1, false, Expr_Expr},
 
+	{STR_LIT("transmute"),        2, false, Expr_Expr},
+	{STR_LIT("union_cast"),       2, false, Expr_Expr},
+	{STR_LIT("down_cast"),        2, false, Expr_Expr},
+
 	{STR_LIT("compile_assert"),   1, false, Expr_Stmt},
 	{STR_LIT("assert"),           1, false, Expr_Stmt},
 	{STR_LIT("panic"),            1, false, Expr_Stmt},

+ 46 - 28
src/ir.c

@@ -2772,21 +2772,21 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
 		case Token_CmpOr:
 			return ir_emit_logical_binary_expr(proc, expr);
 
-		case Token_as:
-			ir_emit_comment(proc, str_lit("cast - as"));
-			return ir_emit_conv(proc, left, type);
+		// case Token_as:
+		// 	ir_emit_comment(proc, str_lit("cast - as"));
+		// 	return ir_emit_conv(proc, left, type);
 
-		case Token_transmute:
-			ir_emit_comment(proc, str_lit("cast - transmute"));
-			return ir_emit_transmute(proc, left, type);
+		// case Token_transmute:
+		// 	ir_emit_comment(proc, str_lit("cast - transmute"));
+		// 	return ir_emit_transmute(proc, left, type);
 
-		case Token_down_cast:
-			ir_emit_comment(proc, str_lit("cast - down_cast"));
-			return ir_emit_down_cast(proc, left, type);
+		// case Token_down_cast:
+		// 	ir_emit_comment(proc, str_lit("cast - down_cast"));
+		// 	return ir_emit_down_cast(proc, left, type);
 
-		case Token_union_cast:
-			ir_emit_comment(proc, str_lit("cast - union_cast"));
-			return ir_emit_union_cast(proc, left, type);
+		// case Token_union_cast:
+		// 	ir_emit_comment(proc, str_lit("cast - union_cast"));
+		// 	return ir_emit_union_cast(proc, left, type);
 
 		default:
 			GB_PANIC("Invalid binary expression");
@@ -2844,6 +2844,24 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
 					return ir_type_info(proc, t);
 				} break;
 
+				case BuiltinProc_transmute: {
+					irValue *val = ir_build_expr(proc, ce->args.e[1]);
+					ir_emit_comment(proc, str_lit("cast - transmute"));
+					return ir_emit_transmute(proc, val, type_of_expr(proc->module->info, ce->args.e[0]));
+				}
+
+				case BuiltinProc_down_cast: {
+					irValue *val = ir_build_expr(proc, ce->args.e[1]);
+					ir_emit_comment(proc, str_lit("cast - down_cast"));
+					return ir_emit_down_cast(proc, val, type_of_expr(proc->module->info, ce->args.e[0]));
+				}
+
+				case BuiltinProc_union_cast: {
+					irValue *val = ir_build_expr(proc, ce->args.e[1]);
+					ir_emit_comment(proc, str_lit("cast - union_cast"));
+					return ir_emit_union_cast(proc, val, type_of_expr(proc->module->info, ce->args.e[0]));
+				}
+
 				case BuiltinProc_new: {
 					ir_emit_comment(proc, str_lit("new"));
 					// new :: proc(Type) -> ^Type
@@ -3399,22 +3417,22 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 
 	case_ast_node(be, BinaryExpr, expr);
 		switch (be->op.kind) {
-		case Token_as: {
-			ir_emit_comment(proc, str_lit("Cast - as"));
-			// NOTE(bill): Needed for dereference of pointer conversion
-			Type *type = type_of_expr(proc->module->info, expr);
-			irValue *v = ir_add_local_generated(proc, type);
-			ir_emit_store(proc, v, ir_emit_conv(proc, ir_build_expr(proc, be->left), type));
-			return ir_make_addr(v, expr);
-		}
-		case Token_transmute: {
-			ir_emit_comment(proc, str_lit("Cast - transmute"));
-			// NOTE(bill): Needed for dereference of pointer conversion
-			Type *type = type_of_expr(proc->module->info, expr);
-			irValue *v = ir_add_local_generated(proc, type);
-			ir_emit_store(proc, v, ir_emit_transmute(proc, ir_build_expr(proc, be->left), type));
-			return ir_make_addr(v, expr);
-		}
+		// case Token_as: {
+		// 	ir_emit_comment(proc, str_lit("Cast - as"));
+		// 	// NOTE(bill): Needed for dereference of pointer conversion
+		// 	Type *type = type_of_expr(proc->module->info, expr);
+		// 	irValue *v = ir_add_local_generated(proc, type);
+		// 	ir_emit_store(proc, v, ir_emit_conv(proc, ir_build_expr(proc, be->left), type));
+		// 	return ir_make_addr(v, expr);
+		// }
+		// case Token_transmute: {
+		// 	ir_emit_comment(proc, str_lit("Cast - transmute"));
+		// 	// NOTE(bill): Needed for dereference of pointer conversion
+		// 	Type *type = type_of_expr(proc->module->info, expr);
+		// 	irValue *v = ir_add_local_generated(proc, type);
+		// 	ir_emit_store(proc, v, ir_emit_transmute(proc, ir_build_expr(proc, be->left), type));
+		// 	return ir_make_addr(v, expr);
+		// }
 		default:
 			GB_PANIC("Invalid binary expression for ir_build_addr: %.*s\n", LIT(be->op.string));
 			break;

+ 14 - 16
src/parser.c

@@ -1979,11 +1979,11 @@ i32 token_precedence(Token t) {
 	case Token_Shl:
 	case Token_Shr:
 		return 5;
-	case Token_as:
-	case Token_transmute:
-	case Token_down_cast:
-	case Token_union_cast:
-		return 6;
+	// case Token_as:
+	// case Token_transmute:
+	// case Token_down_cast:
+	// case Token_union_cast:
+		// return 6;
 	}
 	return 0;
 }
@@ -2005,12 +2005,12 @@ AstNode *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) {
 			}
 
 			switch (op.kind) {
-			case Token_as:
+			/* case Token_as:
 			case Token_transmute:
 			case Token_down_cast:
 			case Token_union_cast:
 				right = parse_type(f);
-				break;
+				break; */
 
 			default:
 				right = parse_binary_expr(f, false, prec+1);
@@ -2429,10 +2429,10 @@ AstNode *parse_identifier_or_type(AstFile *f) {
 			AstNode *sel = parse_identifier(f);
 			e = make_selector_expr(f, token, e, sel);
 		}
-		if (f->curr_token.kind == Token_OpenParen) {
-			// HACK NOTE(bill): For type_of_val(expr)
-			e = parse_call_expr(f, e);
-		}
+		// if (f->curr_token.kind == Token_OpenParen) {
+		// 	// HACK NOTE(bill): For type_of_val(expr)
+		// 	e = parse_call_expr(f, e);
+		// }
 		return e;
 	}
 
@@ -2560,11 +2560,9 @@ AstNode *parse_identifier_or_type(AstFile *f) {
 
 	case Token_OpenParen: {
 		// NOTE(bill): Skip the paren expression
-		AstNode *type;
-		Token open, close;
-		open = expect_token(f, Token_OpenParen);
-		type = parse_type(f);
-		close = expect_token(f, Token_CloseParen);
+		Token    open  = expect_token(f, Token_OpenParen);
+		AstNode *type  = parse_type(f);
+		Token    close = expect_token(f, Token_CloseParen);
 		return type;
 		// return make_paren_expr(f, type, open, close);
 	} break;

+ 1 - 1
src/string.c

@@ -46,7 +46,7 @@ gb_inline String make_string_c(char *text) {
 	return make_string(cast(u8 *)cast(void *)text, gb_strlen(text));
 }
 
-#define str_lit(c_str) make_string(cast(u8 *)c_str, gb_size_of(c_str)-1)
+#define str_lit(c_str) (String){cast(u8 *)c_str, gb_size_of(c_str)-1}
 
 
 

+ 60 - 60
src/tokenizer.c

@@ -1,82 +1,82 @@
 #define TOKEN_KINDS \
 	TOKEN_KIND(Token_Invalid, "Invalid"), \
-	TOKEN_KIND(Token_EOF, "EOF"), \
+	TOKEN_KIND(Token_EOF,     "EOF"), \
 	TOKEN_KIND(Token_Comment, "Comment"), \
 \
 TOKEN_KIND(Token__LiteralBegin, "_LiteralBegin"), \
-	TOKEN_KIND(Token_Ident, "identifier"), \
-	TOKEN_KIND(Token_Integer, "integer"), \
-	TOKEN_KIND(Token_Float, "float"), \
-	TOKEN_KIND(Token_Rune, "rune"), \
-	TOKEN_KIND(Token_String, "string"), \
-TOKEN_KIND(Token__LiteralEnd, "_LiteralEnd"), \
+	TOKEN_KIND(Token_Ident,     "identifier"), \
+	TOKEN_KIND(Token_Integer,   "integer"), \
+	TOKEN_KIND(Token_Float,     "float"), \
+	TOKEN_KIND(Token_Rune,      "rune"), \
+	TOKEN_KIND(Token_String,    "string"), \
+TOKEN_KIND(Token__LiteralEnd,   "_LiteralEnd"), \
 \
 TOKEN_KIND(Token__OperatorBegin, "_OperatorBegin"), \
-	TOKEN_KIND(Token_Eq, "="), \
-	TOKEN_KIND(Token_Not, "!"), \
-	TOKEN_KIND(Token_Hash, "#"), \
-	TOKEN_KIND(Token_At, "@"), \
+	TOKEN_KIND(Token_Eq,      "="), \
+	TOKEN_KIND(Token_Not,     "!"), \
+	TOKEN_KIND(Token_Hash,    "#"), \
+	TOKEN_KIND(Token_At,      "@"), \
 	TOKEN_KIND(Token_Pointer, "^"), \
-	TOKEN_KIND(Token_Maybe, "?"), \
-	TOKEN_KIND(Token_Add, "+"), \
-	TOKEN_KIND(Token_Sub, "-"), \
-	TOKEN_KIND(Token_Mul, "*"), \
-	TOKEN_KIND(Token_Quo, "/"), \
-	TOKEN_KIND(Token_Mod, "%"), \
-	TOKEN_KIND(Token_And, "&"), \
-	TOKEN_KIND(Token_Or, "|"), \
-	TOKEN_KIND(Token_Xor, "~"), \
-	TOKEN_KIND(Token_AndNot, "&~"), \
-	TOKEN_KIND(Token_Shl, "<<"), \
-	TOKEN_KIND(Token_Shr, ">>"), \
+	TOKEN_KIND(Token_Maybe,   "?"), \
+	TOKEN_KIND(Token_Add,     "+"), \
+	TOKEN_KIND(Token_Sub,     "-"), \
+	TOKEN_KIND(Token_Mul,     "*"), \
+	TOKEN_KIND(Token_Quo,     "/"), \
+	TOKEN_KIND(Token_Mod,     "%"), \
+	TOKEN_KIND(Token_And,     "&"), \
+	TOKEN_KIND(Token_Or,      "|"), \
+	TOKEN_KIND(Token_Xor,     "~"), \
+	TOKEN_KIND(Token_AndNot,  "&~"), \
+	TOKEN_KIND(Token_Shl,     "<<"), \
+	TOKEN_KIND(Token_Shr,     ">>"), \
 \
-	TOKEN_KIND(Token_as,         "as"), \
-	TOKEN_KIND(Token_transmute,  "transmute"), \
-	TOKEN_KIND(Token_down_cast,  "down_cast"), \
-	TOKEN_KIND(Token_union_cast, "union_cast"), \
+	/*TOKEN_KIND(Token_as,         "as"), */\
+	/*TOKEN_KIND(Token_transmute,  "transmute"), */\
+	/*TOKEN_KIND(Token_down_cast,  "down_cast"), */\
+	/*TOKEN_KIND(Token_union_cast, "union_cast"), */\
 \
 	TOKEN_KIND(Token_CmpAnd, "&&"), \
-	TOKEN_KIND(Token_CmpOr, "||"), \
+	TOKEN_KIND(Token_CmpOr,  "||"), \
 \
 TOKEN_KIND(Token__AssignOpBegin, "_AssignOpBegin"), \
-	TOKEN_KIND(Token_AddEq, "+="), \
-	TOKEN_KIND(Token_SubEq, "-="), \
-	TOKEN_KIND(Token_MulEq, "*="), \
-	TOKEN_KIND(Token_QuoEq, "/="), \
-	TOKEN_KIND(Token_ModEq, "%="), \
-	TOKEN_KIND(Token_AndEq, "&="), \
-	TOKEN_KIND(Token_OrEq, "|="), \
-	TOKEN_KIND(Token_XorEq, "~="), \
-	TOKEN_KIND(Token_AndNotEq, "&~="), \
-	TOKEN_KIND(Token_ShlEq, "<<="), \
-	TOKEN_KIND(Token_ShrEq, ">>="), \
-	TOKEN_KIND(Token_CmpAndEq, "&&="), \
-	TOKEN_KIND(Token_CmpOrEq, "||="), \
-TOKEN_KIND(Token__AssignOpEnd, "_AssignOpEnd"), \
+	TOKEN_KIND(Token_AddEq,      "+="), \
+	TOKEN_KIND(Token_SubEq,      "-="), \
+	TOKEN_KIND(Token_MulEq,      "*="), \
+	TOKEN_KIND(Token_QuoEq,      "/="), \
+	TOKEN_KIND(Token_ModEq,      "%="), \
+	TOKEN_KIND(Token_AndEq,      "&="), \
+	TOKEN_KIND(Token_OrEq,       "|="), \
+	TOKEN_KIND(Token_XorEq,      "~="), \
+	TOKEN_KIND(Token_AndNotEq,   "&~="), \
+	TOKEN_KIND(Token_ShlEq,      "<<="), \
+	TOKEN_KIND(Token_ShrEq,      ">>="), \
+	TOKEN_KIND(Token_CmpAndEq,   "&&="), \
+	TOKEN_KIND(Token_CmpOrEq,    "||="), \
+TOKEN_KIND(Token__AssignOpEnd,   "_AssignOpEnd"), \
 	TOKEN_KIND(Token_ArrowRight, "->"), \
-	TOKEN_KIND(Token_ArrowLeft, "<-"), \
+	TOKEN_KIND(Token_ArrowLeft,  "<-"), \
 \
 TOKEN_KIND(Token__ComparisonBegin, "_ComparisonBegin"), \
 	TOKEN_KIND(Token_CmpEq, "=="), \
 	TOKEN_KIND(Token_NotEq, "!="), \
-	TOKEN_KIND(Token_Lt, "<"), \
-	TOKEN_KIND(Token_Gt, ">"), \
-	TOKEN_KIND(Token_LtEq, "<="), \
-	TOKEN_KIND(Token_GtEq, ">="), \
+	TOKEN_KIND(Token_Lt,    "<"), \
+	TOKEN_KIND(Token_Gt,    ">"), \
+	TOKEN_KIND(Token_LtEq,  "<="), \
+	TOKEN_KIND(Token_GtEq,  ">="), \
 TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
 \
-	TOKEN_KIND(Token_OpenParen, "("), \
-	TOKEN_KIND(Token_CloseParen, ")"), \
-	TOKEN_KIND(Token_OpenBracket, "["), \
+	TOKEN_KIND(Token_OpenParen,    "("), \
+	TOKEN_KIND(Token_CloseParen,   ")"), \
+	TOKEN_KIND(Token_OpenBracket,  "["), \
 	TOKEN_KIND(Token_CloseBracket, "]"), \
-	TOKEN_KIND(Token_OpenBrace, "{"), \
-	TOKEN_KIND(Token_CloseBrace, "}"), \
-	TOKEN_KIND(Token_Colon, ":"), \
-	TOKEN_KIND(Token_Semicolon, ";"), \
-	TOKEN_KIND(Token_Period, "."), \
-	TOKEN_KIND(Token_Comma, ","), \
-	TOKEN_KIND(Token_Ellipsis, "..."), \
-	TOKEN_KIND(Token_Interval, "..<"), \
+	TOKEN_KIND(Token_OpenBrace,    "{"), \
+	TOKEN_KIND(Token_CloseBrace,   "}"), \
+	TOKEN_KIND(Token_Colon,        ":"), \
+	TOKEN_KIND(Token_Semicolon,    ";"), \
+	TOKEN_KIND(Token_Period,       "."), \
+	TOKEN_KIND(Token_Comma,        ","), \
+	TOKEN_KIND(Token_Ellipsis,     "..."), \
+	TOKEN_KIND(Token_Interval,     "..<"), \
 TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
 \
 TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
@@ -722,7 +722,7 @@ Token tokenizer_get_token(Tokenizer *t) {
 
 		// NOTE(bill): All keywords are > 1
 		if (token.string.len > 1) {
-			if (str_eq(token.string, token_strings[Token_as])) {
+			/* if (str_eq(token.string, token_strings[Token_as])) {
 				token.kind = Token_as;
 			} else if (str_eq(token.string, token_strings[Token_transmute])) {
 				token.kind = Token_transmute;
@@ -730,7 +730,7 @@ Token tokenizer_get_token(Tokenizer *t) {
 				token.kind = Token_down_cast;
 			} else if (str_eq(token.string, token_strings[Token_union_cast])) {
 				token.kind = Token_union_cast;
-			} else {
+			} else  */{
 				for (i32 k = Token__KeywordBegin+1; k < Token__KeywordEnd; k++) {
 					if (str_eq(token.string, token_strings[k])) {
 						token.kind = cast(TokenKind)k;