Browse Source

`..` half closed range; `...` open range; `...` variadic syntax

Ginger Bill 8 years ago
parent
commit
4b051a0d3b

+ 21 - 34
code/demo.odin

@@ -12,6 +12,7 @@ import (
 	"strconv.odin";
 	"strconv.odin";
 	"strings.odin";
 	"strings.odin";
 	"sync.odin";
 	"sync.odin";
+	"sort.odin";
 	"types.odin";
 	"types.odin";
 	"utf8.odin";
 	"utf8.odin";
 	"utf16.odin";
 	"utf16.odin";
@@ -19,7 +20,6 @@ import (
 */
 */
 )
 )
 
 
-
 general_stuff :: proc() {
 general_stuff :: proc() {
 	// Complex numbers
 	// Complex numbers
 	a := 3 + 4i;
 	a := 3 + 4i;
@@ -35,10 +35,10 @@ general_stuff :: proc() {
 	// C-style variadic procedures
 	// C-style variadic procedures
 	foreign __llvm_core {
 	foreign __llvm_core {
 		// The variadic part allows for extra type checking too which C does not provide
 		// The variadic part allows for extra type checking too which C does not provide
-		c_printf :: proc(fmt: ^u8, #c_vararg args: ..any) -> i32 #link_name "printf" ---;
+		c_printf :: proc(fmt: ^u8, #c_vararg args: ...any) -> i32 #link_name "printf" ---;
 	}
 	}
-	str := "%d\n";
-	c_printf(&str[0], i32(789456123));
+	str := "%d\n\x00";
+	// c_printf(&str[0], i32(789456123));
 
 
 
 
 	Foo :: struct {
 	Foo :: struct {
@@ -96,8 +96,8 @@ named_arguments :: proc() {
 	using Colour;
 	using Colour;
 
 
 	make_character :: proc(name, catch_phrase: string, favourite_colour, least_favourite_colour: Colour) {
 	make_character :: proc(name, catch_phrase: string, favourite_colour, least_favourite_colour: Colour) {
-	    fmt.println();
-	    fmt.printf("My name is %v and I like %v.  %v\n", name, favourite_colour, catch_phrase);
+		fmt.println();
+		fmt.printf("My name is %v and I like %v.  %v\n", name, favourite_colour, catch_phrase);
 	}
 	}
 
 
 	make_character("Frank", "¡Ay, caramba!", Blue, Green);
 	make_character("Frank", "¡Ay, caramba!", Blue, Green);
@@ -128,7 +128,7 @@ named_arguments :: proc() {
 
 
 	// Named arguments can also aid with default arguments
 	// Named arguments can also aid with default arguments
 	numerous_things :: proc(s: string, a := 1, b := 2, c := 3.14,
 	numerous_things :: proc(s: string, a := 1, b := 2, c := 3.14,
-	                     d := "The Best String!", e := false, f := 10.3/3.1, g := false) {
+	                        d := "The Best String!", e := false, f := 10.3/3.1, g := false) {
 		g_str := g ? "true" : "false";
 		g_str := g ? "true" : "false";
 		fmt.printf("How many?! %s: %v\n", s, g_str);
 		fmt.printf("How many?! %s: %v\n", s, g_str);
 	}
 	}
@@ -196,7 +196,7 @@ default_return_values :: proc() {
 call_location :: proc() {
 call_location :: proc() {
 	amazing :: proc(n: int, using loc := #caller_location) {
 	amazing :: proc(n: int, using loc := #caller_location) {
 		fmt.printf("%s(%d:%d) just asked to do something amazing.\n",
 		fmt.printf("%s(%d:%d) just asked to do something amazing.\n",
-		           fully_pathed_filename, line, column);
+				   fully_pathed_filename, line, column);
 		fmt.printf("Normal -> %d\n", n);
 		fmt.printf("Normal -> %d\n", n);
 		fmt.printf("Amazing -> %d\n", n+1);
 		fmt.printf("Amazing -> %d\n", n+1);
 		fmt.println();
 		fmt.println();
@@ -230,7 +230,7 @@ explicit_parametric_polymorphic_procedures :: proc() {
 	defer free(another_ptr);
 	defer free(another_ptr);
 
 
 
 
-	add :: proc(T: type, args: ..T) -> T {
+	add :: proc(T: type, args: ...T) -> T {
 		res: T;
 		res: T;
 		for arg in args do res += arg;
 		for arg in args do res += arg;
 		return res;
 		return res;
@@ -362,32 +362,21 @@ explicit_parametric_polymorphic_procedures :: proc() {
 }
 }
 
 
 
 
-pop :: proc(array: ^[]$T) -> T {
-	last: T;
-	if len(array) == 0 {
-		panic("Attempt to pop an empty slice");
-		return last;
+implicit_polymorphic_assignment :: proc() {
+	yep :: proc(p: proc(x: int)) {
+		p(123);
 	}
 	}
 
 
-	last = array[len(array)-1];
-	^raw.Slice(array).len -= 1;
-	return last;
+	frank :: proc(x: $T)    do fmt.println("frank ->", x);
+	tim   :: proc(x, y: $T) do fmt.println("tim ->", x, y);
+	yep(frank);
+	// yep(tim);
 }
 }
-pop :: proc(a: ^[dynamic]$T) -> T {
-	last: T;
-	if len(a) == 0 {
-		panic("Attempt to pop an empty dynamic array");
-		return last;
-	}
 
 
-	last = array[len(array)-1];
-	^raw.DynamicArray(array).len -= 1;
-	return last;
-}
+
 
 
 
 
 main :: proc() {
 main :: proc() {
-when true {
 	foo :: proc(x: i64,  y: f32) do fmt.println("#1", x, y);
 	foo :: proc(x: i64,  y: f32) do fmt.println("#1", x, y);
 	foo :: proc(x: type, y: f32) do fmt.println("#2", type_info(x), y);
 	foo :: proc(x: type, y: f32) do fmt.println("#2", type_info(x), y);
 	foo :: proc(x: type)         do fmt.println("#3", type_info(x));
 	foo :: proc(x: type)         do fmt.println("#3", type_info(x));
@@ -397,6 +386,7 @@ when true {
 	f(y = 3785.1546, x = 123);
 	f(y = 3785.1546, x = 123);
 	f(x = int, y = 897.513);
 	f(x = int, y = 897.513);
 	f(x = f32);
 	f(x = f32);
+
 	general_stuff();
 	general_stuff();
 	foreign_blocks();
 	foreign_blocks();
 	default_arguments();
 	default_arguments();
@@ -404,6 +394,8 @@ when true {
 	default_return_values();
 	default_return_values();
 	call_location();
 	call_location();
 	explicit_parametric_polymorphic_procedures();
 	explicit_parametric_polymorphic_procedures();
+	implicit_polymorphic_assignment();
+
 
 
 	// Command line argument(s)!
 	// Command line argument(s)!
 	// -opt=0,1,2,3
 	// -opt=0,1,2,3
@@ -423,11 +415,6 @@ when true {
 	}
 	}
 
 
 	fmt.printf("The program \"%s\" calculates the value %d\n",
 	fmt.printf("The program \"%s\" calculates the value %d\n",
-	           program, accumulator);
+			   program, accumulator);
 */
 */
 }
 }
-}
-
-
-
-

+ 8 - 8
core/_preload.odin

@@ -285,7 +285,7 @@ copy :: proc(dst, src: []$T) -> int #cc_contextless {
 
 
 
 
 
 
-append :: proc(array: ^[]$T, args: ..T) -> int #cc_contextless {
+append :: proc(array: ^[]$T, args: ...T) -> int #cc_contextless {
 	if array == nil do return 0;
 	if array == nil do return 0;
 
 
 	arg_len := len(args);
 	arg_len := len(args);
@@ -303,7 +303,7 @@ append :: proc(array: ^[]$T, args: ..T) -> int #cc_contextless {
 	return len(array);
 	return len(array);
 }
 }
 
 
-append :: proc(array: ^[dynamic]$T, args: ..T) -> int {
+append :: proc(array: ^[dynamic]$T, args: ...T) -> int {
 	if array == nil do return 0;
 	if array == nil do return 0;
 
 
 	arg_len := len(args);
 	arg_len := len(args);
@@ -559,21 +559,21 @@ __complex128_ne :: proc(a, b: complex128) -> bool #cc_contextless #inline { retu
 
 
 __bounds_check_error :: proc(file: string, line, column: int, index, count: int) #cc_contextless {
 __bounds_check_error :: proc(file: string, line, column: int, index, count: int) #cc_contextless {
 	if 0 <= index && index < count do return;
 	if 0 <= index && index < count do return;
-	fmt.fprintf(os.stderr, "%s(%d:%d) Index %d is out of bounds range 0..<%d\n",
+	fmt.fprintf(os.stderr, "%s(%d:%d) Index %d is out of bounds range 0..%d\n",
 	            file, line, column, index, count);
 	            file, line, column, index, count);
 	__debug_trap();
 	__debug_trap();
 }
 }
 
 
 __slice_expr_error :: proc(file: string, line, column: int, low, high, max: int) #cc_contextless {
 __slice_expr_error :: proc(file: string, line, column: int, low, high, max: int) #cc_contextless {
 	if 0 <= low && low <= high && high <= max do return;
 	if 0 <= low && low <= high && high <= max do return;
-	fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: [%d..<%d..<%d]\n",
+	fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: [%d..%d..%d]\n",
 	            file, line, column, low, high, max);
 	            file, line, column, low, high, max);
 	__debug_trap();
 	__debug_trap();
 }
 }
 
 
 __substring_expr_error :: proc(file: string, line, column: int, low, high: int) #cc_contextless {
 __substring_expr_error :: proc(file: string, line, column: int, low, high: int) #cc_contextless {
 	if 0 <= low && low <= high do return;
 	if 0 <= low && low <= high do return;
-	fmt.fprintf(os.stderr, "%s(%d:%d) Invalid substring indices: [%d..<%d]\n",
+	fmt.fprintf(os.stderr, "%s(%d:%d) Invalid substring indices: [%d..%d]\n",
 	            file, line, column, low, high);
 	            file, line, column, low, high);
 	__debug_trap();
 	__debug_trap();
 }
 }
@@ -623,7 +623,7 @@ __mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #cc_con
 }
 }
 
 
 __mem_compare :: proc(a, b: ^u8, n: int) -> int #cc_contextless {
 __mem_compare :: proc(a, b: ^u8, n: int) -> int #cc_contextless {
-	for i in 0..<n {
+	for i in 0..n {
 		match {
 		match {
 		case (a+i)^ < (b+i)^: return -1;
 		case (a+i)^ < (b+i)^: return -1;
 		case (a+i)^ > (b+i)^: return +1;
 		case (a+i)^ > (b+i)^: return +1;
@@ -791,9 +791,9 @@ __dynamic_map_rehash :: proc(using header: __MapHeader, new_count: int) {
 
 
 	__dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count);
 	__dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count);
 	__dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len);
 	__dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len);
-	for i in 0..<new_count do nm.hashes[i] = -1;
+	for i in 0..new_count do nm.hashes[i] = -1;
 
 
-	for i := 0; i < m.entries.len; i++ {
+	for i in 0..m.entries.len {
 		if len(nm.hashes) == 0 do __dynamic_map_grow(new_header);
 		if len(nm.hashes) == 0 do __dynamic_map_grow(new_header);
 
 
 		entry_header := __dynamic_map_get_entry(header, i);
 		entry_header := __dynamic_map_get_entry(header, i);

+ 9 - 9
core/decimal.odin

@@ -20,29 +20,29 @@ decimal_to_string :: proc(buf: []u8, a: ^Decimal) -> string {
 
 
 	// TODO(bill): make this work with a buffer that's not big enough
 	// TODO(bill): make this work with a buffer that's not big enough
 	assert(len(buf) >= n);
 	assert(len(buf) >= n);
-	buf = buf[0..<n];
+	buf = buf[0..n];
 
 
 	if a.count == 0 {
 	if a.count == 0 {
 		buf[0] = '0';
 		buf[0] = '0';
-		return string(buf[0..<1]);
+		return string(buf[0..1]);
 	}
 	}
 
 
 	w := 0;
 	w := 0;
 	if a.decimal_point <= 0 {
 	if a.decimal_point <= 0 {
 		buf[w] = '0'; w++;
 		buf[w] = '0'; w++;
 		buf[w] = '.'; w++;
 		buf[w] = '.'; w++;
-		w += digit_zero(buf[w ..< w-a.decimal_point]);
-		w += copy(buf[w..], a.digits[0..<a.count]);
+		w += digit_zero(buf[w .. w-a.decimal_point]);
+		w += copy(buf[w..], a.digits[0..a.count]);
 	} else if a.decimal_point < a.count {
 	} else if a.decimal_point < a.count {
-		w += copy(buf[w..], a.digits[0..<a.decimal_point]);
+		w += copy(buf[w..], a.digits[0..a.decimal_point]);
 		buf[w] = '.'; w++;
 		buf[w] = '.'; w++;
-		w += copy(buf[w..], a.digits[a.decimal_point ..< a.count]);
+		w += copy(buf[w..], a.digits[a.decimal_point .. a.count]);
 	} else {
 	} else {
-		w += copy(buf[w..], a.digits[0..<a.count]);
-		w += digit_zero(buf[w ..< w+a.decimal_point-a.count]);
+		w += copy(buf[w..], a.digits[0..a.count]);
+		w += digit_zero(buf[w .. w+a.decimal_point-a.count]);
 	}
 	}
 
 
-	return string(buf[0..<w]);
+	return string(buf[0..w]);
 }
 }
 
 
 // trim trailing zeros
 // trim trailing zeros

+ 51 - 51
core/fmt.odin

@@ -70,9 +70,9 @@ write_string :: proc(buf: ^StringBuffer, s: string) {
 write_bytes :: proc(buf: ^StringBuffer, data: []u8) {
 write_bytes :: proc(buf: ^StringBuffer, data: []u8) {
 	match b in buf {
 	match b in buf {
 	case StringBuffer.Static:
 	case StringBuffer.Static:
-		append(&b.buf, ..data);
+		append(&b.buf, ...data);
 	case StringBuffer.Dynamic:
 	case StringBuffer.Dynamic:
-		append(&b.buf, ..data);
+		append(&b.buf, ...data);
 	}
 	}
 }
 }
 write_byte :: proc(buf: ^StringBuffer, data: u8) {
 write_byte :: proc(buf: ^StringBuffer, data: u8) {
@@ -90,43 +90,43 @@ write_rune :: proc(buf: ^StringBuffer, r: rune) {
 	}
 	}
 
 
 	b, n := utf8.encode_rune(r);
 	b, n := utf8.encode_rune(r);
-	write_bytes(buf, b[0..<n]);
+	write_bytes(buf, b[..n]);
 }
 }
 
 
 write_int :: proc(buf: ^StringBuffer, i: i128, base: int) {
 write_int :: proc(buf: ^StringBuffer, i: i128, base: int) {
 	b: [129]u8;
 	b: [129]u8;
-	s := strconv.append_bits(b[0..<0], u128(i), base, true, 128, strconv.digits, 0);
+	s := strconv.append_bits(b[..0], u128(i), base, true, 128, strconv.digits, 0);
 	write_string(buf, s);
 	write_string(buf, s);
 }
 }
 write_int :: proc(buf: ^StringBuffer, i: i64, base: int) {
 write_int :: proc(buf: ^StringBuffer, i: i64, base: int) {
 	b: [129]u8;
 	b: [129]u8;
-	s := strconv.append_bits(b[0..<0], u128(i), base, true, 64, strconv.digits, 0);
+	s := strconv.append_bits(b[..0], u128(i), base, true, 64, strconv.digits, 0);
 	write_string(buf, s);
 	write_string(buf, s);
 }
 }
 
 
 
 
 
 
-fprint :: proc(fd: os.Handle, args: ..any) -> int {
+fprint :: proc(fd: os.Handle, args: ...any) -> int {
 	data: [_BUFFER_SIZE]u8;
 	data: [_BUFFER_SIZE]u8;
-	buf := make_string_buffer_from_slice(data[0..<0]);
-	sbprint(&buf, ..args);
+	buf := make_string_buffer_from_slice(data[..0]);
+	sbprint(&buf, ...args);
 	res := string_buffer_data(buf);
 	res := string_buffer_data(buf);
 	os.write(fd, res);
 	os.write(fd, res);
 	return len(res);
 	return len(res);
 }
 }
 
 
-fprintln :: proc(fd: os.Handle, args: ..any) -> int {
+fprintln :: proc(fd: os.Handle, args: ...any) -> int {
 	data: [_BUFFER_SIZE]u8;
 	data: [_BUFFER_SIZE]u8;
-	buf := make_string_buffer_from_slice(data[0..<0]);
-	sbprintln(&buf, ..args);
+	buf := make_string_buffer_from_slice(data[..0]);
+	sbprintln(&buf, ...args);
 	res := string_buffer_data(buf);
 	res := string_buffer_data(buf);
 	os.write(fd, res);
 	os.write(fd, res);
 	return len(res);
 	return len(res);
 }
 }
-fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
+fprintf :: proc(fd: os.Handle, fmt: string, args: ...any) -> int {
 	data: [_BUFFER_SIZE]u8;
 	data: [_BUFFER_SIZE]u8;
-	buf := make_string_buffer_from_slice(data[0..<0]);
-	sbprintf(&buf, fmt, ..args);
+	buf := make_string_buffer_from_slice(data[..0]);
+	sbprintf(&buf, fmt, ...args);
 	res := string_buffer_data(buf);
 	res := string_buffer_data(buf);
 	os.write(fd, res);
 	os.write(fd, res);
 	return len(res);
 	return len(res);
@@ -134,46 +134,46 @@ fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
 
 
 
 
 // print* procedures return the number of bytes written
 // print* procedures return the number of bytes written
-print       :: proc(args: ..any)              -> int { return fprint(os.stdout, ..args); }
-print_err   :: proc(args: ..any)              -> int { return fprint(os.stderr, ..args); }
-println     :: proc(args: ..any)              -> int { return fprintln(os.stdout, ..args); }
-println_err :: proc(args: ..any)              -> int { return fprintln(os.stderr, ..args); }
-printf      :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args); }
-printf_err  :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stderr, fmt, ..args); }
+print       :: proc(args: ...any)              -> int { return fprint(os.stdout, ...args); }
+print_err   :: proc(args: ...any)              -> int { return fprint(os.stderr, ...args); }
+println     :: proc(args: ...any)              -> int { return fprintln(os.stdout, ...args); }
+println_err :: proc(args: ...any)              -> int { return fprintln(os.stderr, ...args); }
+printf      :: proc(fmt: string, args: ...any) -> int { return fprintf(os.stdout, fmt, ...args); }
+printf_err  :: proc(fmt: string, args: ...any) -> int { return fprintf(os.stderr, fmt, ...args); }
 
 
 
 
 // aprint* procedures return a string that was allocated with the current context
 // aprint* procedures return a string that was allocated with the current context
 // They must be freed accordingly
 // They must be freed accordingly
-aprint :: proc(args: ..any) -> string {
+aprint :: proc(args: ...any) -> string {
 	buf := make_string_dynamic_buffer();
 	buf := make_string_dynamic_buffer();
-	sbprint(&buf, ..args);
+	sbprint(&buf, ...args);
 	return to_string(buf);
 	return to_string(buf);
 }
 }
-aprintln :: proc(args: ..any) -> string {
+aprintln :: proc(args: ...any) -> string {
 	buf := make_string_dynamic_buffer();
 	buf := make_string_dynamic_buffer();
-	sbprintln(&buf, ..args);
+	sbprintln(&buf, ...args);
 	return to_string(buf);
 	return to_string(buf);
 }
 }
-aprintf :: proc(fmt: string, args: ..any) -> string {
+aprintf :: proc(fmt: string, args: ...any) -> string {
 	buf := make_string_dynamic_buffer();
 	buf := make_string_dynamic_buffer();
-	sbprintf(&buf, fmt, ..args);
+	sbprintf(&buf, fmt, ...args);
 	return to_string(buf);
 	return to_string(buf);
 }
 }
 
 
 
 
 // bprint* procedures return a string that was allocated with the current context
 // bprint* procedures return a string that was allocated with the current context
 // They must be freed accordingly
 // They must be freed accordingly
-bprint :: proc(buf: []u8, args: ..any) -> string {
-	sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
-	return sbprint(&sb, ..args);
+bprint :: proc(buf: []u8, args: ...any) -> string {
+	sb := make_string_buffer_from_slice(buf[..0..len(buf)]);
+	return sbprint(&sb, ...args);
 }
 }
-bprintln :: proc(buf: []u8, args: ..any) -> string {
-	sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
-	return sbprintln(&sb, ..args);
+bprintln :: proc(buf: []u8, args: ...any) -> string {
+	sb := make_string_buffer_from_slice(buf[..0..len(buf)]);
+	return sbprintln(&sb, ...args);
 }
 }
-bprintf :: proc(buf: []u8, fmt: string, args: ..any) -> string {
-	sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
-	return sbprintf(&sb, fmt, ..args);
+bprintf :: proc(buf: []u8, fmt: string, args: ...any) -> string {
+	sb := make_string_buffer_from_slice(buf[..0..len(buf)]);
+	return sbprintf(&sb, fmt, ...args);
 }
 }
 
 
 
 
@@ -183,7 +183,7 @@ bprintf :: proc(buf: []u8, fmt: string, args: ..any) -> string {
 
 
 fprint_type :: proc(fd: os.Handle, info: ^TypeInfo) {
 fprint_type :: proc(fd: os.Handle, info: ^TypeInfo) {
 	data: [_BUFFER_SIZE]u8;
 	data: [_BUFFER_SIZE]u8;
-	buf := make_string_buffer_from_slice(data[0..<0]);
+	buf := make_string_buffer_from_slice(data[..0]);
 	write_type(&buf, info);
 	write_type(&buf, info);
 	os.write(fd, string_buffer_data(buf));
 	os.write(fd, string_buffer_data(buf));
 }
 }
@@ -328,7 +328,7 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
 			variant := variant_type.(^Struct);
 			variant := variant_type.(^Struct);
 
 
 			vc := len(variant.names)-len(cf.names);
 			vc := len(variant.names)-len(cf.names);
-			for j in 0..<vc {
+			for j in 0..vc {
 				if j > 0 do write_string(buf, ", ");
 				if j > 0 do write_string(buf, ", ");
 				index := j + len(cf.names);
 				index := j + len(cf.names);
 				write_string(buf, variant.names[index]);
 				write_string(buf, variant.names[index]);
@@ -404,7 +404,7 @@ _arg_number :: proc(fi: ^FmtInfo, arg_index: int, format: string, offset, arg_co
 			return 0, 1, false;
 			return 0, 1, false;
 		}
 		}
 
 
-		for i in 1..len(format) {
+		for i in 1...len(format) {
 			if format[i] == ']' {
 			if format[i] == ']' {
 				width, new_index, ok := _parse_int(format, 1);
 				width, new_index, ok := _parse_int(format, 1);
 				if !ok || new_index != i {
 				if !ok || new_index != i {
@@ -486,7 +486,7 @@ fmt_write_padding :: proc(fi: ^FmtInfo, width: int) {
 
 
 	pad_byte: u8 = fi.space ? ' ' : '0';
 	pad_byte: u8 = fi.space ? ' ' : '0';
 
 
-	for _ in 0..<width {
+	for _ in 0..width {
 		write_byte(fi.buf, pad_byte);
 		write_byte(fi.buf, pad_byte);
 	}
 	}
 }
 }
@@ -535,7 +535,7 @@ _fmt_int :: proc(fi: ^FmtInfo, u: u128, base: int, is_signed: bool, bit_size: in
 	if fi.hash && !fi.zero do flags |= strconv.IntFlag.Prefix;
 	if fi.hash && !fi.zero do flags |= strconv.IntFlag.Prefix;
 	if fi.plus             do flags |= strconv.IntFlag.Plus;
 	if fi.plus             do flags |= strconv.IntFlag.Plus;
 	if fi.space            do flags |= strconv.IntFlag.Space;
 	if fi.space            do flags |= strconv.IntFlag.Space;
-	s := strconv.append_bits(buf[start..<start], u128(u), base, is_signed, bit_size, digits, flags);
+	s := strconv.append_bits(buf[start..start], u128(u), base, is_signed, bit_size, digits, flags);
 
 
 	if fi.hash && fi.zero {
 	if fi.hash && fi.zero {
 		c: u8;
 		c: u8;
@@ -622,8 +622,8 @@ fmt_float :: proc(fi: ^FmtInfo, v: f64, bit_size: int, verb: rune) {
 		prec: int = fi.prec_set ? fi.prec : 3;
 		prec: int = fi.prec_set ? fi.prec : 3;
 		buf: [386]u8;
 		buf: [386]u8;
 
 
-		str := strconv.append_float(buf[1..<1], v, 'f', prec, bit_size);
-		str = string(buf[0..len(str)]);
+		str := strconv.append_float(buf[1..1], v, 'f', prec, bit_size);
+		str = string(buf[...len(str)]);
 		if str[1] == '+' || str[1] == '-' {
 		if str[1] == '+' || str[1] == '-' {
 			str = str[1..];
 			str = str[1..];
 		} else {
 		} else {
@@ -665,7 +665,7 @@ fmt_string :: proc(fi: ^FmtInfo, s: string, verb: rune) {
 		fi.space = false;
 		fi.space = false;
 		defer fi.space = space;
 		defer fi.space = space;
 
 
-		for i in 0..<len(s) {
+		for i in 0..len(s) {
 			if i > 0 && space do write_byte(fi.buf, ' ');
 			if i > 0 && space do write_byte(fi.buf, ' ');
 			_fmt_int(fi, u128(s[i]), 16, false, 8, verb == 'x' ? __DIGITS_LOWER : __DIGITS_UPPER);
 			_fmt_int(fi, u128(s[i]), 16, false, 8, verb == 'x' ? __DIGITS_LOWER : __DIGITS_UPPER);
 		}
 		}
@@ -812,7 +812,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
 	case Array:
 	case Array:
 		write_byte(fi.buf, '[');
 		write_byte(fi.buf, '[');
 		defer write_byte(fi.buf, ']');
 		defer write_byte(fi.buf, ']');
-		for i in 0..<info.count {
+		for i in 0..info.count {
 			if i > 0 do write_string(fi.buf, ", ");
 			if i > 0 do write_string(fi.buf, ", ");
 
 
 			data := ^u8(v.data) + i*info.elem_size;
 			data := ^u8(v.data) + i*info.elem_size;
@@ -823,7 +823,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
 		write_byte(fi.buf, '[');
 		write_byte(fi.buf, '[');
 		defer write_byte(fi.buf, ']');
 		defer write_byte(fi.buf, ']');
 		array := ^raw.DynamicArray(v.data);
 		array := ^raw.DynamicArray(v.data);
-		for i in 0..<array.len {
+		for i in 0..array.len {
 			if i > 0 do write_string(fi.buf, ", ");
 			if i > 0 do write_string(fi.buf, ", ");
 
 
 			data := ^u8(array.data) + i*info.elem_size;
 			data := ^u8(array.data) + i*info.elem_size;
@@ -845,7 +845,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
 		write_byte(fi.buf, '<');
 		write_byte(fi.buf, '<');
 		defer write_byte(fi.buf, '>');
 		defer write_byte(fi.buf, '>');
 
 
-		for i in 0..<info.count {
+		for i in 0..info.count {
 			if i > 0 do write_string(fi.buf, ", ");
 			if i > 0 do write_string(fi.buf, ", ");
 
 
 			data := ^u8(v.data) + i*info.elem_size;
 			data := ^u8(v.data) + i*info.elem_size;
@@ -867,7 +867,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
 		entry_type := ed.elem.(^Struct);
 		entry_type := ed.elem.(^Struct);
 		entry_size := ed.elem_size;
 		entry_size := ed.elem_size;
 
 
-		for i in 0..<entries.len {
+		for i in 0..entries.len {
 			if i > 0 do write_string(fi.buf, ", ");
 			if i > 0 do write_string(fi.buf, ", ");
 
 
 			data := ^u8(entries.data) + i*entry_size;
 			data := ^u8(entries.data) + i*entry_size;
@@ -1008,7 +1008,7 @@ fmt_arg :: proc(fi: ^FmtInfo, arg: any, verb: rune) {
 
 
 
 
 
 
-sbprint :: proc(buf: ^StringBuffer, args: ..any) -> string {
+sbprint :: proc(buf: ^StringBuffer, args: ...any) -> string {
 	fi: FmtInfo;
 	fi: FmtInfo;
 	prev_string := false;
 	prev_string := false;
 
 
@@ -1025,7 +1025,7 @@ sbprint :: proc(buf: ^StringBuffer, args: ..any) -> string {
 	return to_string(buf^);
 	return to_string(buf^);
 }
 }
 
 
-sbprintln :: proc(buf: ^StringBuffer, args: ..any) -> string {
+sbprintln :: proc(buf: ^StringBuffer, args: ...any) -> string {
 	fi: FmtInfo;
 	fi: FmtInfo;
 	fi.buf = buf;
 	fi.buf = buf;
 
 
@@ -1038,7 +1038,7 @@ sbprintln :: proc(buf: ^StringBuffer, args: ..any) -> string {
 	return to_string(buf^);
 	return to_string(buf^);
 }
 }
 
 
-sbprintf :: proc(b: ^StringBuffer, fmt: string, args: ..any) -> string {
+sbprintf :: proc(b: ^StringBuffer, fmt: string, args: ...any) -> string {
 	fi: FmtInfo;
 	fi: FmtInfo;
 	arg_index: int = 0;
 	arg_index: int = 0;
 	end := len(fmt);
 	end := len(fmt);
@@ -1053,7 +1053,7 @@ sbprintf :: proc(b: ^StringBuffer, fmt: string, args: ..any) -> string {
 			i++;
 			i++;
 		}
 		}
 		if i > prev_i {
 		if i > prev_i {
-			write_string(b, fmt[prev_i..<i]);
+			write_string(b, fmt[prev_i..i]);
 		}
 		}
 		if i >= end {
 		if i >= end {
 			break;
 			break;

+ 1 - 1
core/hash.odin

@@ -175,7 +175,7 @@ murmur64 :: proc(data: []u8) -> u64 {
 		}
 		}
 
 
 		// TODO(bill): Fix this
 		// TODO(bill): Fix this
-		#no_bounds_check data8 := slice_to_bytes(data32[i..])[0..<3];
+		#no_bounds_check data8 := slice_to_bytes(data32[i..])[..3];
 		match len {
 		match len {
 		case 3:
 		case 3:
 			h2 ~= u32(data8[2]) << 16;
 			h2 ~= u32(data8[2]) << 16;

+ 4 - 4
core/math.odin

@@ -158,8 +158,8 @@ mat4_identity :: proc() -> Mat4 {
 }
 }
 
 
 mat4_transpose :: proc(m: Mat4) -> Mat4 {
 mat4_transpose :: proc(m: Mat4) -> Mat4 {
-	for j in 0..<4 {
-		for i in 0..<4 {
+	for j in 0..4 {
+		for i in 0..4 {
 			m[i][j], m[j][i] = m[j][i], m[i][j];
 			m[i][j], m[j][i] = m[j][i], m[i][j];
 		}
 		}
 	}
 	}
@@ -168,8 +168,8 @@ mat4_transpose :: proc(m: Mat4) -> Mat4 {
 
 
 mul :: proc(a, b: Mat4) -> Mat4 {
 mul :: proc(a, b: Mat4) -> Mat4 {
 	c: Mat4;
 	c: Mat4;
-	for j in 0..<4 {
-		for i in 0..<4 {
+	for j in 0..4 {
+		for i in 0..4 {
 			c[j][i] = a[0][i]*b[j][0] +
 			c[j][i] = a[0][i]*b[j][0] +
 			          a[1][i]*b[j][1] +
 			          a[1][i]*b[j][1] +
 			          a[2][i]*b[j][2] +
 			          a[2][i]*b[j][2] +

+ 2 - 2
core/mem.odin

@@ -110,7 +110,7 @@ ArenaTempMemory :: struct {
 
 
 init_arena_from_memory :: proc(using a: ^Arena, data: []u8) {
 init_arena_from_memory :: proc(using a: ^Arena, data: []u8) {
 	backing    = Allocator{};
 	backing    = Allocator{};
-	memory     = data[0..<0];
+	memory     = data[..0];
 	temp_count = 0;
 	temp_count = 0;
 }
 }
 
 
@@ -183,7 +183,7 @@ begin_arena_temp_memory :: proc(a: ^Arena) -> ArenaTempMemory {
 end_arena_temp_memory :: proc(using tmp: ArenaTempMemory) {
 end_arena_temp_memory :: proc(using tmp: ArenaTempMemory) {
 	assert(len(arena.memory) >= original_count);
 	assert(len(arena.memory) >= original_count);
 	assert(arena.temp_count > 0);
 	assert(arena.temp_count > 0);
-	arena.memory = arena.memory[0..<original_count];
+	arena.memory = arena.memory[..original_count];
 	arena.temp_count--;
 	arena.temp_count--;
 }
 }
 
 

+ 1 - 1
core/opengl.odin

@@ -45,7 +45,7 @@ _libgl := win32.load_library_a(_string_data("opengl32.dll\x00"));
 
 
 get_proc_address :: proc(name: string) -> rawptr {
 get_proc_address :: proc(name: string) -> rawptr {
 	if name[len(name)-1] == 0 {
 	if name[len(name)-1] == 0 {
-		name = name[0..<len(name)-1];
+		name = name[..len(name)-1];
 	}
 	}
 	// NOTE(bill): null terminated
 	// NOTE(bill): null terminated
 	assert((&name[0] + len(name))^ == 0);
 	assert((&name[0] + len(name))^ == 0);

+ 1 - 1
core/os.odin

@@ -34,7 +34,7 @@ read_entire_file :: proc(name: string) -> ([]u8, bool) {
 		free(data);
 		free(data);
 		return nil, false;
 		return nil, false;
 	}
 	}
-	return data[0..<bytes_read], true;
+	return data[0..bytes_read], true;
 }
 }
 
 
 write_entire_file :: proc(name: string, data: []u8) -> bool {
 write_entire_file :: proc(name: string, data: []u8) -> bool {

+ 1 - 1
core/os_windows.odin

@@ -301,7 +301,7 @@ _alloc_command_line_arguments :: proc() -> []string {
 			}
 			}
 		}
 		}
 
 
-		return string(buf[0..<i]);
+		return string(buf[..i]);
 	}
 	}
 
 
 	arg_count: i32;
 	arg_count: i32;

+ 18 - 18
core/sort.odin

@@ -7,7 +7,7 @@ bubble_sort :: proc(array: []$T, f: proc(T, T) -> int) {
 	for {
 	for {
 		init_swap, prev_swap := -1, -1;
 		init_swap, prev_swap := -1, -1;
 
 
-		for j in init_j..<last_j {
+		for j in init_j..last_j {
 			if f(array[j], array[j+1]) > 0 {
 			if f(array[j], array[j+1]) > 0 {
 				array[j], array[j+1] = array[j+1], array[j];
 				array[j], array[j+1] = array[j+1], array[j];
 				prev_swap = j;
 				prev_swap = j;
@@ -30,7 +30,7 @@ bubble_sort :: proc(array: []$T) {
 	for {
 	for {
 		init_swap, prev_swap := -1, -1;
 		init_swap, prev_swap := -1, -1;
 
 
-		for j in init_j..<last_j {
+		for j in init_j..last_j {
 			if array[j] > array[j+1] {
 			if array[j] > array[j+1] {
 				array[j], array[j+1] = array[j+1], array[j];
 				array[j], array[j+1] = array[j+1], array[j];
 				prev_swap = j;
 				prev_swap = j;
@@ -65,8 +65,8 @@ quick_sort :: proc(array: []$T, f: proc(T, T) -> int) {
 		j -= 1;
 		j -= 1;
 	}
 	}
 
 
-	quick_sort(a[0..<i], f);
-	quick_sort(a[i..<n], f);
+	quick_sort(a[0..i], f);
+	quick_sort(a[i..n], f);
 }
 }
 
 
 quick_sort :: proc(array: []$T) {
 quick_sort :: proc(array: []$T) {
@@ -88,8 +88,8 @@ quick_sort :: proc(array: []$T) {
 		j -= 1;
 		j -= 1;
 	}
 	}
 
 
-	quick_sort(a[0..<i]);
-	quick_sort(a[i..<n]);
+	quick_sort(a[0..i]);
+	quick_sort(a[i..n]);
 }
 }
 
 
 _log2 :: proc(n: int) -> int {
 _log2 :: proc(n: int) -> int {
@@ -102,7 +102,7 @@ merge_sort :: proc(array: []$T, f: proc(T, T) -> int) {
 	merge_slices :: proc(arr1, arr2, out: []$T, f: proc(T, T) -> int) {
 	merge_slices :: proc(arr1, arr2, out: []$T, f: proc(T, T) -> int) {
 		N1, N2 := len(arr1), len(arr2);
 		N1, N2 := len(arr1), len(arr2);
 		i, j := 0, 0;
 		i, j := 0, 0;
-		for k in 0..<N1+N2 {
+		for k in 0..N1+N2 {
 			if j == N2 || i < N1 && j < N2 && f(arr1[i], arr2[j]) < 0 {
 			if j == N2 || i < N1 && j < N2 && f(arr1[i], arr2[j]) < 0 {
 				out[k] = arr1[i]; i++;
 				out[k] = arr1[i]; i++;
 			} else {
 			} else {
@@ -120,16 +120,16 @@ merge_sort :: proc(array: []$T, f: proc(T, T) -> int) {
 
 
 	a, b, m, M := N/2, N, 1, _log2(N);
 	a, b, m, M := N/2, N, 1, _log2(N);
 
 
-	for i in 0..<M+1 {
-		for j in 0..<a {
+	for i in 0..M+1 {
+		for j in 0..a {
 			k := 2*j*m;
 			k := 2*j*m;
-			merge_slices(arr1[k..<k+m], arr1[k+m..<k+m+m], arr2[k..], f);
+			merge_slices(arr1[k..k+m], arr1[k+m..k+m+m], arr2[k..], f);
 		}
 		}
 		if N-b > m {
 		if N-b > m {
 			k := 2*a*m;
 			k := 2*a*m;
-			merge_slices(arr1[k..<k+m], arr1[k+m..<k+m+(N-b)&(m-1)], arr2[k..], f);
+			merge_slices(arr1[k..k+m], arr1[k+m..k+m+(N-b)&(m-1)], arr2[k..], f);
 		} else {
 		} else {
-			copy(arr2[b..N-1], arr1[b..N-1]);
+			copy(arr2[b..N], arr1[b..N]);
 		}
 		}
 		arr1, arr2 = arr2, arr1;
 		arr1, arr2 = arr2, arr1;
 		m <<= 1;
 		m <<= 1;
@@ -144,7 +144,7 @@ merge_sort :: proc(array: []$T) {
 	merge_slices :: proc(arr1, arr2, out: []$T) {
 	merge_slices :: proc(arr1, arr2, out: []$T) {
 		N1, N2 := len(arr1), len(arr2);
 		N1, N2 := len(arr1), len(arr2);
 		i, j := 0, 0;
 		i, j := 0, 0;
-		for k in 0..<N1+N2 {
+		for k in 0..N1+N2 {
 			if j == N2 || i < N1 && j < N2 && arr1[i] < arr2[j] {
 			if j == N2 || i < N1 && j < N2 && arr1[i] < arr2[j] {
 				out[k] = arr1[i]; i++;
 				out[k] = arr1[i]; i++;
 			} else {
 			} else {
@@ -160,16 +160,16 @@ merge_sort :: proc(array: []$T) {
 
 
 	a, b, m, M := N/2, N, 1, _log2(N);
 	a, b, m, M := N/2, N, 1, _log2(N);
 
 
-	for i in 0..<M+1 {
-		for j in 0..<a {
+	for i in 0..M+1 {
+		for j in 0..a {
 			k := 2*j*m;
 			k := 2*j*m;
-			merge_slices(arr1[k..<k+m], arr1[k+m..<k+m+m], arr2[k..]);
+			merge_slices(arr1[k..k+m], arr1[k+m..k+m+m], arr2[k..]);
 		}
 		}
 		if N-b > m {
 		if N-b > m {
 			k := 2*a*m;
 			k := 2*a*m;
-			merge_slices(arr1[k..<k+m], arr1[k+m..<k+m+(N-b)&(m-1)], arr2[k..]);
+			merge_slices(arr1[k..k+m], arr1[k+m..k+m+(N-b)&(m-1)], arr2[k..]);
 		} else {
 		} else {
-			copy(arr2[b..N-1], arr1[b..N-1]);
+			copy(arr2[b..N], arr1[b..N]);
 		}
 		}
 		arr1, arr2 = arr2, arr1;
 		arr1, arr2 = arr2, arr1;
 		m <<= 1;
 		m <<= 1;

+ 7 - 7
core/strconv.odin

@@ -191,7 +191,7 @@ parse_f64 :: proc(s: string) -> f64 {
 
 
 append_bool :: proc(buf: []u8, b: bool) -> string {
 append_bool :: proc(buf: []u8, b: bool) -> string {
 	s := b ? "true" : "false";
 	s := b ? "true" : "false";
-	append(&buf, ..[]u8(s));
+	append(&buf, ...[]u8(s));
 	return string(buf);
 	return string(buf);
 }
 }
 
 
@@ -257,7 +257,7 @@ generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8
 		} else {
 		} else {
 			s = "+Inf";
 			s = "+Inf";
 		}
 		}
-		append(&buf, ..[]u8(s));
+		append(&buf, ...[]u8(s));
 		return buf;
 		return buf;
 
 
 	case 0: // denormalized
 	case 0: // denormalized
@@ -309,7 +309,7 @@ format_digits :: proc(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice,
 		// integer, padded with zeros when needed
 		// integer, padded with zeros when needed
 		if digs.decimal_point > 0 {
 		if digs.decimal_point > 0 {
 			m := min(digs.count, digs.decimal_point);
 			m := min(digs.count, digs.decimal_point);
-			append(&buf, ..digs.digits[0..<m]);
+			append(&buf, ...digs.digits[..m]);
 			for ; m < digs.decimal_point; m++ {
 			for ; m < digs.decimal_point; m++ {
 				append(&buf, '0');
 				append(&buf, '0');
 			}
 			}
@@ -321,7 +321,7 @@ format_digits :: proc(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice,
 		// fractional part
 		// fractional part
 		if prec > 0 {
 		if prec > 0 {
 			append(&buf, '.');
 			append(&buf, '.');
-			for i in 0..<prec {
+			for i in 0..prec {
 				c: u8 = '0';
 				c: u8 = '0';
 				if j := digs.decimal_point + i; 0 <= j && j < digs.count {
 				if j := digs.decimal_point + i; 0 <= j && j < digs.count {
 					c = digs.digits[j];
 					c = digs.digits[j];
@@ -342,7 +342,7 @@ format_digits :: proc(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice,
 	}
 	}
 
 
 	c := [2]u8{'%', fmt};
 	c := [2]u8{'%', fmt};
-	append(&buf, ..c[..]);
+	append(&buf, ...c[..]);
 	return buf;
 	return buf;
 }
 }
 
 
@@ -383,7 +383,7 @@ round_shortest :: proc(d: ^Decimal, mant: u64, exp: int, flt: ^Float_Info) {
 
 
 	inclusive := mant%2 == 0;
 	inclusive := mant%2 == 0;
 
 
-	for i in 0..<d.count {
+	for i in 0..d.count {
 		l: u8 = '0'; // lower digit
 		l: u8 = '0'; // lower digit
 		if i < lower.count {
 		if i < lower.count {
 			l = lower.digits[i];
 			l = lower.digits[i];
@@ -492,7 +492,7 @@ append_bits :: proc(buf: []u8, u: u128, base: int, is_signed: bool, bit_size: in
 		i--; a[i] = ' ';
 		i--; a[i] = ' ';
 	}
 	}
 
 
-	append(&buf, ..a[i..]);
+	append(&buf, ...a[i..]);
 	return string(buf);
 	return string(buf);
 }
 }
 
 

+ 1 - 1
core/strings.odin

@@ -4,7 +4,7 @@ new_string :: proc(s: string) -> string {
 	c := make([]u8, len(s)+1);
 	c := make([]u8, len(s)+1);
 	copy(c, []u8(s));
 	copy(c, []u8(s));
 	c[len(s)] = 0;
 	c[len(s)] = 0;
-	return string(c[0..<len(s)]);
+	return string(c[..len(s)]);
 }
 }
 
 
 new_c_string :: proc(s: string) -> ^u8 {
 new_c_string :: proc(s: string) -> ^u8 {

+ 1 - 1
core/utf16.odin

@@ -36,7 +36,7 @@ encode :: proc(d: []u16, s: []rune) {
 
 
 	for r in s {
 	for r in s {
 		match r {
 		match r {
-		case 0..<_surr1, _surr3..<_surr_self:
+		case 0.._surr1, _surr3.._surr_self:
 			d[n] = u16(r);
 			d[n] = u16(r);
 			n++;
 			n++;
 
 

+ 1 - 1
core/utf8.odin

@@ -160,7 +160,7 @@ decode_last_rune :: proc(s: []u8) -> (rune, int) {
 	}
 	}
 
 
 	start = max(start, 0);
 	start = max(start, 0);
-	r, size = decode_rune(s[start..<end]);
+	r, size = decode_rune(s[start..end]);
 	if start+size != end {
 	if start+size != end {
 		return RUNE_ERROR, 1;
 		return RUNE_ERROR, 1;
 	}
 	}

+ 1 - 3
src/check_decl.cpp

@@ -79,6 +79,7 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, Array<AstNo
 
 
 
 
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
+	defer (gb_temp_arena_memory_end(tmp));
 
 
 	// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
 	// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
 	// an extra allocation
 	// an extra allocation
@@ -100,9 +101,6 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, Array<AstNo
 	if (rhs_count > 0 && lhs_count != rhs_count) {
 	if (rhs_count > 0 && lhs_count != rhs_count) {
 		error(lhs[0]->token, "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count);
 		error(lhs[0]->token, "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count);
 	}
 	}
-
-
-	gb_temp_arena_memory_end(tmp);
 }
 }
 
 
 void check_init_constant(Checker *c, Entity *e, Operand *operand) {
 void check_init_constant(Checker *c, Entity *e, Operand *operand) {

+ 15 - 17
src/check_expr.cpp

@@ -633,7 +633,7 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
 			// TODO(bill): is this a good enough error message?
 			// TODO(bill): is this a good enough error message?
 			// TODO(bill): Actually allow built in procedures to be passed around and thus be created on use
 			// TODO(bill): Actually allow built in procedures to be passed around and thus be created on use
 			error(operand->expr,
 			error(operand->expr,
-			      "Cannot assign type `%s` as a value in %.*s",
+			      "Cannot assign `%s` which is a type in %.*s",
 			      op_type_str,
 			      op_type_str,
 			      LIT(context_name));
 			      LIT(context_name));
 		} else {
 		} else {
@@ -658,8 +658,9 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
 void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map<Entity *> *entity_map) {
 void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map<Entity *> *entity_map) {
 	t = base_type(type_deref(t));
 	t = base_type(type_deref(t));
 	gbString str = nullptr;
 	gbString str = nullptr;
+	defer (gb_string_free(str));
 	if (node != nullptr) {
 	if (node != nullptr) {
-		expr_to_string(node);
+		str = expr_to_string(node);
 	}
 	}
 
 
 	if (t->kind == Type_Record) {
 	if (t->kind == Type_Record) {
@@ -687,7 +688,6 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map<Entity *>
 		}
 		}
 	}
 	}
 
 
-	gb_string_free(str);
 }
 }
 
 
 
 
@@ -696,6 +696,7 @@ isize check_fields(Checker *c, AstNode *node, Array<AstNode *> decls,
                    Entity **fields, isize field_count,
                    Entity **fields, isize field_count,
                    String context) {
                    String context) {
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
+	defer (gb_temp_arena_memory_end(tmp));
 
 
 	Map<Entity *> entity_map = {};
 	Map<Entity *> entity_map = {};
 	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*field_count);
 	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*field_count);
@@ -717,11 +718,9 @@ isize check_fields(Checker *c, AstNode *node, Array<AstNode *> decls,
 		Type *type = check_type(c, f->type);
 		Type *type = check_type(c, f->type);
 		bool is_using = (f->flags&FieldFlag_using) != 0;
 		bool is_using = (f->flags&FieldFlag_using) != 0;
 
 
-		if (is_using) {
-			if (f->names.count > 1) {
-				error(f->names[0], "Cannot apply `using` to more than one of the same type");
-				is_using = false;
-			}
+		if (is_using && f->names.count > 1) {
+			error(f->names[0], "Cannot apply `using` to more than one of the same type");
+			is_using = false;
 		}
 		}
 
 
 		for_array(name_index, f->names) {
 		for_array(name_index, f->names) {
@@ -795,7 +794,6 @@ isize check_fields(Checker *c, AstNode *node, Array<AstNode *> decls,
 		}
 		}
 	}
 	}
 
 
-	gb_temp_arena_memory_end(tmp);
 
 
 	return field_index;
 	return field_index;
 }
 }
@@ -956,6 +954,7 @@ void check_union_type(Checker *c, Type *named_type, Type *union_type, AstNode *n
 	}
 	}
 
 
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
+	defer (gb_temp_arena_memory_end(tmp));
 
 
 	Map<Entity *> entity_map = {}; // Key: String
 	Map<Entity *> entity_map = {}; // Key: String
 	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*variant_count);
 	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*variant_count);
@@ -1057,7 +1056,6 @@ void check_union_type(Checker *c, Type *named_type, Type *union_type, AstNode *n
 
 
 	type_set_offsets(c->allocator, union_type);
 	type_set_offsets(c->allocator, union_type);
 
 
-	gb_temp_arena_memory_end(tmp);
 
 
 	union_type->Record.variants      = variants;
 	union_type->Record.variants      = variants;
 	union_type->Record.variant_count = variant_index;
 	union_type->Record.variant_count = variant_index;
@@ -1093,6 +1091,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
 	GB_ASSERT(is_type_enum(enum_type));
 	GB_ASSERT(is_type_enum(enum_type));
 
 
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
+	defer (gb_temp_arena_memory_end(tmp));
 
 
 	Type *base_type = t_int;
 	Type *base_type = t_int;
 	if (et->base_type != nullptr) {
 	if (et->base_type != nullptr) {
@@ -1208,7 +1207,6 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
 		}
 		}
 	}
 	}
 	GB_ASSERT(field_count <= et->fields.count);
 	GB_ASSERT(field_count <= et->fields.count);
-	gb_temp_arena_memory_end(tmp);
 
 
 
 
 	enum_type->Record.fields = fields;
 	enum_type->Record.fields = fields;
@@ -1230,7 +1228,7 @@ void check_bit_field_type(Checker *c, Type *bit_field_type, Type *named_type, As
 	GB_ASSERT(is_type_bit_field(bit_field_type));
 	GB_ASSERT(is_type_bit_field(bit_field_type));
 
 
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
-
+	defer (gb_temp_arena_memory_end(tmp));
 
 
 	Map<Entity *> entity_map = {}; // Key: String
 	Map<Entity *> entity_map = {}; // Key: String
 	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(bft->fields.count));
 	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(bft->fields.count));
@@ -1293,7 +1291,6 @@ void check_bit_field_type(Checker *c, Type *bit_field_type, Type *named_type, As
 		}
 		}
 	}
 	}
 	GB_ASSERT(field_count <= bft->fields.count);
 	GB_ASSERT(field_count <= bft->fields.count);
-	gb_temp_arena_memory_end(tmp);
 
 
 	bit_field_type->BitField.fields      = fields;
 	bit_field_type->BitField.fields      = fields;
 	bit_field_type->BitField.field_count = field_count;
 	bit_field_type->BitField.field_count = field_count;
@@ -2137,6 +2134,8 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
 		multi_map_get_all(&s->elements, key, procs);
 		multi_map_get_all(&s->elements, key, procs);
 		if (type_hint != nullptr) {
 		if (type_hint != nullptr) {
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
+			defer (gb_temp_arena_memory_end(tmp));
+
 			// NOTE(bill): These should be done
 			// NOTE(bill): These should be done
 			for (isize i = 0; i < overload_count; i++) {
 			for (isize i = 0; i < overload_count; i++) {
 				Type *t = base_type(procs[i]->type);
 				Type *t = base_type(procs[i]->type);
@@ -2153,8 +2152,6 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
 					break;
 					break;
 				}
 				}
 			}
 			}
-			gb_temp_arena_memory_end(tmp);
-
 		}
 		}
 
 
 		if (!skip) {
 		if (!skip) {
@@ -7073,7 +7070,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
 		}
 		}
 
 
 		if (se->low == nullptr && se->high != nullptr) {
 		if (se->low == nullptr && se->high != nullptr) {
-			error(se->interval0, "1st index is required if a 2nd index is specified");
+			// error(se->interval0, "1st index is required if a 2nd index is specified");
 			// It is okay to continue as it will assume the 1st index is zero
 			// It is okay to continue as it will assume the 1st index is zero
 		}
 		}
 
 
@@ -7094,7 +7091,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
 
 
 		TokenKind interval_kind = se->interval0.kind;
 		TokenKind interval_kind = se->interval0.kind;
 
 
-		i64 indices[2] = {};
+		i64 indices[3] = {};
 		AstNode *nodes[3] = {se->low, se->high, se->max};
 		AstNode *nodes[3] = {se->low, se->high, se->max};
 		for (isize i = 0; i < gb_count_of(nodes); i++) {
 		for (isize i = 0; i < gb_count_of(nodes); i++) {
 			i64 index = max_count;
 			i64 index = max_count;
@@ -7159,6 +7156,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
 	case_end;
 	case_end;
 
 
 	case AstNode_TypeType:
 	case AstNode_TypeType:
+	case AstNode_PolyType:
 	case AstNode_ProcType:
 	case AstNode_ProcType:
 	case AstNode_PointerType:
 	case AstNode_PointerType:
 	case AstNode_ArrayType:
 	case AstNode_ArrayType:

+ 3 - 2
src/check_stmt.cpp

@@ -683,6 +683,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 			}
 			}
 
 
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
+			defer (gb_temp_arena_memory_end(tmp));
 
 
 			// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
 			// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
 			// an extra allocation
 			// an extra allocation
@@ -705,7 +706,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 				error(as->lhs[0], "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count);
 				error(as->lhs[0], "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count);
 			}
 			}
 
 
-			gb_temp_arena_memory_end(tmp);
 		} break;
 		} break;
 
 
 		default: {
 		default: {
@@ -1325,6 +1325,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 						TypeAndToken *found = map_get(&seen, key);
 						TypeAndToken *found = map_get(&seen, key);
 						if (found != nullptr) {
 						if (found != nullptr) {
 							gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 							gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
+							defer (gb_temp_arena_memory_end(tmp));
+
 							isize count = multi_map_count(&seen, key);
 							isize count = multi_map_count(&seen, key);
 							TypeAndToken *taps = gb_alloc_array(c->tmp_allocator, TypeAndToken, count);
 							TypeAndToken *taps = gb_alloc_array(c->tmp_allocator, TypeAndToken, count);
 
 
@@ -1347,7 +1349,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 								}
 								}
 							}
 							}
 
 
-							gb_temp_arena_memory_end(tmp);
 
 
 							if (continue_outer) {
 							if (continue_outer) {
 								continue;
 								continue;

+ 5 - 5
src/tokenizer.cpp

@@ -78,8 +78,8 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
 	TOKEN_KIND(Token_Semicolon,     ";"),   \
 	TOKEN_KIND(Token_Semicolon,     ";"),   \
 	TOKEN_KIND(Token_Period,        "."),   \
 	TOKEN_KIND(Token_Period,        "."),   \
 	TOKEN_KIND(Token_Comma,         ","),   \
 	TOKEN_KIND(Token_Comma,         ","),   \
-	TOKEN_KIND(Token_Ellipsis,      ".."),  \
-	TOKEN_KIND(Token_HalfClosed,    "..<"), \
+	TOKEN_KIND(Token_Ellipsis,      "..."), \
+	TOKEN_KIND(Token_HalfClosed,    ".."),  \
 	TOKEN_KIND(Token_BackSlash,     "\\"),  \
 	TOKEN_KIND(Token_BackSlash,     "\\"),  \
 TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
 TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
 \
 \
@@ -885,10 +885,10 @@ Token tokenizer_get_token(Tokenizer *t) {
 			token.kind = Token_Period; // Default
 			token.kind = Token_Period; // Default
 			if (t->curr_rune == '.') { // Could be an ellipsis
 			if (t->curr_rune == '.') { // Could be an ellipsis
 				advance_to_next_rune(t);
 				advance_to_next_rune(t);
-				token.kind = Token_Ellipsis;
-				if (t->curr_rune == '<') {
+				token.kind = Token_HalfClosed;
+				if (t->curr_rune == '.') {
 					advance_to_next_rune(t);
 					advance_to_next_rune(t);
-					token.kind = Token_HalfClosed;
+					token.kind = Token_Ellipsis;
 				}
 				}
 			}
 			}
 			break;
 			break;