From 4b051a0d3b9da924924ed2a28ef7c102902a880c Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Fri, 7 Jul 2017 23:42:43 +0100 Subject: [PATCH] `..` half closed range; `...` open range; `...` variadic syntax --- code/demo.odin | 55 +++++++++-------------- core/_preload.odin | 16 +++---- core/decimal.odin | 18 ++++---- core/fmt.odin | 102 +++++++++++++++++++++---------------------- core/hash.odin | 2 +- core/math.odin | 8 ++-- core/mem.odin | 4 +- core/opengl.odin | 2 +- core/os.odin | 2 +- core/os_windows.odin | 2 +- core/sort.odin | 36 +++++++-------- core/strconv.odin | 14 +++--- core/strings.odin | 2 +- core/utf16.odin | 2 +- core/utf8.odin | 2 +- src/check_decl.cpp | 4 +- src/check_expr.cpp | 32 +++++++------- src/check_stmt.cpp | 5 ++- src/tokenizer.cpp | 10 ++--- 19 files changed, 151 insertions(+), 167 deletions(-) diff --git a/code/demo.odin b/code/demo.odin index 41a02c098..e2825c5fa 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -12,6 +12,7 @@ import ( "strconv.odin"; "strings.odin"; "sync.odin"; + "sort.odin"; "types.odin"; "utf8.odin"; "utf16.odin"; @@ -19,7 +20,6 @@ import ( */ ) - general_stuff :: proc() { // Complex numbers a := 3 + 4i; @@ -35,10 +35,10 @@ general_stuff :: proc() { // C-style variadic procedures foreign __llvm_core { // 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 { @@ -96,8 +96,8 @@ named_arguments :: proc() { using 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); @@ -128,7 +128,7 @@ named_arguments :: proc() { // Named arguments can also aid with default arguments 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"; fmt.printf("How many?! %s: %v\n", s, g_str); } @@ -196,7 +196,7 @@ default_return_values :: proc() { call_location :: proc() { amazing :: proc(n: int, using loc := #caller_location) { 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("Amazing -> %d\n", n+1); fmt.println(); @@ -230,7 +230,7 @@ explicit_parametric_polymorphic_procedures :: proc() { defer free(another_ptr); - add :: proc(T: type, args: ..T) -> T { + add :: proc(T: type, args: ...T) -> T { res: T; for arg in args do res += arg; 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() { -when true { 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) do fmt.println("#3", type_info(x)); @@ -397,6 +386,7 @@ when true { f(y = 3785.1546, x = 123); f(x = int, y = 897.513); f(x = f32); + general_stuff(); foreign_blocks(); default_arguments(); @@ -404,6 +394,8 @@ when true { default_return_values(); call_location(); explicit_parametric_polymorphic_procedures(); + implicit_polymorphic_assignment(); + // Command line argument(s)! // -opt=0,1,2,3 @@ -423,11 +415,6 @@ when true { } fmt.printf("The program \"%s\" calculates the value %d\n", - program, accumulator); + program, accumulator); */ } -} - - - - diff --git a/core/_preload.odin b/core/_preload.odin index b497c98ed..4d438aad3 100644 --- a/core/_preload.odin +++ b/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; arg_len := len(args); @@ -303,7 +303,7 @@ append :: proc(array: ^[]$T, args: ..T) -> int #cc_contextless { 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; 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 { 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); __debug_trap(); } __slice_expr_error :: proc(file: string, line, column: int, low, high, max: int) #cc_contextless { 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); __debug_trap(); } __substring_expr_error :: proc(file: string, line, column: int, low, high: int) #cc_contextless { 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); __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 { - for i in 0.. (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_reserve(&nm.entries, entry_size, entry_align, m.entries.len); - for i in 0.. string { // TODO(bill): make this work with a buffer that's not big enough assert(len(buf) >= n); - buf = buf[0.. int { +fprint :: proc(fd: os.Handle, args: ...any) -> int { 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); os.write(fd, res); return len(res); } -fprintln :: proc(fd: os.Handle, args: ..any) -> int { +fprintln :: proc(fd: os.Handle, args: ...any) -> int { 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); os.write(fd, 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; - 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); os.write(fd, 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 :: 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 // They must be freed accordingly -aprint :: proc(args: ..any) -> string { +aprint :: proc(args: ...any) -> string { buf := make_string_dynamic_buffer(); - sbprint(&buf, ..args); + sbprint(&buf, ...args); return to_string(buf); } -aprintln :: proc(args: ..any) -> string { +aprintln :: proc(args: ...any) -> string { buf := make_string_dynamic_buffer(); - sbprintln(&buf, ..args); + sbprintln(&buf, ...args); return to_string(buf); } -aprintf :: proc(fmt: string, args: ..any) -> string { +aprintf :: proc(fmt: string, args: ...any) -> string { buf := make_string_dynamic_buffer(); - sbprintf(&buf, fmt, ..args); + sbprintf(&buf, fmt, ...args); return to_string(buf); } // bprint* procedures return a string that was allocated with the current context // They must be freed accordingly -bprint :: proc(buf: []u8, args: ..any) -> string { - sb := make_string_buffer_from_slice(buf[0..<0.. 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.. 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.. 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) { 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); os.write(fd, string_buffer_data(buf)); } @@ -328,7 +328,7 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) { variant := variant_type.(^Struct); vc := len(variant.names)-len(cf.names); - for j in 0.. 0 do write_string(buf, ", "); index := j + len(cf.names); 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; } - for i in 1..len(format) { + for i in 1...len(format) { if format[i] == ']' { width, new_index, ok := _parse_int(format, 1); if !ok || new_index != i { @@ -486,7 +486,7 @@ fmt_write_padding :: proc(fi: ^FmtInfo, width: int) { pad_byte: u8 = fi.space ? ' ' : '0'; - for _ in 0.. 0 && space do write_byte(fi.buf, ' '); _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: write_byte(fi.buf, '['); defer write_byte(fi.buf, ']'); - for i in 0.. 0 do write_string(fi.buf, ", "); 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, '['); defer write_byte(fi.buf, ']'); array := ^raw.DynamicArray(v.data); - for i in 0.. 0 do write_string(fi.buf, ", "); 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, '<'); defer write_byte(fi.buf, '>'); - for i in 0.. 0 do write_string(fi.buf, ", "); 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_size := ed.elem_size; - for i in 0.. 0 do write_string(fi.buf, ", "); 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; prev_string := false; @@ -1025,7 +1025,7 @@ sbprint :: proc(buf: ^StringBuffer, args: ..any) -> string { return to_string(buf^); } -sbprintln :: proc(buf: ^StringBuffer, args: ..any) -> string { +sbprintln :: proc(buf: ^StringBuffer, args: ...any) -> string { fi: FmtInfo; fi.buf = buf; @@ -1038,7 +1038,7 @@ sbprintln :: proc(buf: ^StringBuffer, args: ..any) -> string { return to_string(buf^); } -sbprintf :: proc(b: ^StringBuffer, fmt: string, args: ..any) -> string { +sbprintf :: proc(b: ^StringBuffer, fmt: string, args: ...any) -> string { fi: FmtInfo; arg_index: int = 0; end := len(fmt); @@ -1053,7 +1053,7 @@ sbprintf :: proc(b: ^StringBuffer, fmt: string, args: ..any) -> string { i++; } if i > prev_i { - write_string(b, fmt[prev_i..= end { break; diff --git a/core/hash.odin b/core/hash.odin index ca1c6cbf7..5747776a5 100644 --- a/core/hash.odin +++ b/core/hash.odin @@ -175,7 +175,7 @@ murmur64 :: proc(data: []u8) -> u64 { } // 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 { case 3: h2 ~= u32(data8[2]) << 16; diff --git a/core/math.odin b/core/math.odin index 8fdd51cbd..e3f525fc0 100644 --- a/core/math.odin +++ b/core/math.odin @@ -158,8 +158,8 @@ mat4_identity :: proc() -> 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]; } } @@ -168,8 +168,8 @@ mat4_transpose :: proc(m: Mat4) -> Mat4 { mul :: proc(a, b: Mat4) -> 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] + a[1][i]*b[j][1] + a[2][i]*b[j][2] + diff --git a/core/mem.odin b/core/mem.odin index dfd15c138..705f30401 100644 --- a/core/mem.odin +++ b/core/mem.odin @@ -110,7 +110,7 @@ ArenaTempMemory :: struct { init_arena_from_memory :: proc(using a: ^Arena, data: []u8) { backing = Allocator{}; - memory = data[0..<0]; + memory = data[..0]; temp_count = 0; } @@ -183,7 +183,7 @@ begin_arena_temp_memory :: proc(a: ^Arena) -> ArenaTempMemory { end_arena_temp_memory :: proc(using tmp: ArenaTempMemory) { assert(len(arena.memory) >= original_count); assert(arena.temp_count > 0); - arena.memory = arena.memory[0.. rawptr { if name[len(name)-1] == 0 { - name = name[0.. ([]u8, bool) { free(data); return nil, false; } - return data[0.. bool { diff --git a/core/os_windows.odin b/core/os_windows.odin index 443ab909d..3144089a0 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -301,7 +301,7 @@ _alloc_command_line_arguments :: proc() -> []string { } } - return string(buf[0.. int) { for { init_swap, prev_swap := -1, -1; - for j in init_j.. 0 { array[j], array[j+1] = array[j+1], array[j]; prev_swap = j; @@ -30,7 +30,7 @@ bubble_sort :: proc(array: []$T) { for { init_swap, prev_swap := -1, -1; - for j in init_j.. array[j+1] { array[j], array[j+1] = array[j+1], array[j]; prev_swap = j; @@ -65,8 +65,8 @@ quick_sort :: proc(array: []$T, f: proc(T, T) -> int) { j -= 1; } - quick_sort(a[0.. 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) { N1, N2 := len(arr1), len(arr2); i, j := 0, 0; - for k in 0.. int) { a, b, m, M := N/2, N, 1, _log2(N); - for i in 0.. m { k := 2*a*m; - merge_slices(arr1[k.. m { k := 2*a*m; - merge_slices(arr1[k.. f64 { append_bool :: proc(buf: []u8, b: bool) -> string { s := b ? "true" : "false"; - append(&buf, ..[]u8(s)); + append(&buf, ...[]u8(s)); return string(buf); } @@ -257,7 +257,7 @@ generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 } else { s = "+Inf"; } - append(&buf, ..[]u8(s)); + append(&buf, ...[]u8(s)); return buf; case 0: // denormalized @@ -309,7 +309,7 @@ format_digits :: proc(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice, // integer, padded with zeros when needed if digs.decimal_point > 0 { m := min(digs.count, digs.decimal_point); - append(&buf, ..digs.digits[0.. 0 { append(&buf, '.'); - for i in 0.. string { c := make([]u8, len(s)+1); copy(c, []u8(s)); c[len(s)] = 0; - return string(c[0.. ^u8 { diff --git a/core/utf16.odin b/core/utf16.odin index 8d3108fa4..959dd7bcd 100644 --- a/core/utf16.odin +++ b/core/utf16.odin @@ -36,7 +36,7 @@ encode :: proc(d: []u16, s: []rune) { for r in s { match r { - case 0..<_surr1, _surr3..<_surr_self: + case 0.._surr1, _surr3.._surr_self: d[n] = u16(r); n++; diff --git a/core/utf8.odin b/core/utf8.odin index 28c5bc932..50d3c4cdb 100644 --- a/core/utf8.odin +++ b/core/utf8.odin @@ -160,7 +160,7 @@ decode_last_rune :: proc(s: []u8) -> (rune, int) { } start = max(start, 0); - r, size = decode_rune(s[start..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 // an extra allocation @@ -100,9 +101,6 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, Array 0 && 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) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e99706836..f0fc0f0e7 100644 --- a/src/check_expr.cpp +++ b/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): Actually allow built in procedures to be passed around and thus be created on use error(operand->expr, - "Cannot assign type `%s` as a value in %.*s", + "Cannot assign `%s` which is a type in %.*s", op_type_str, LIT(context_name)); } 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_map) { t = base_type(type_deref(t)); gbString str = nullptr; + defer (gb_string_free(str)); if (node != nullptr) { - expr_to_string(node); + str = expr_to_string(node); } if (t->kind == Type_Record) { @@ -687,7 +688,6 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map } } - gb_string_free(str); } @@ -696,6 +696,7 @@ isize check_fields(Checker *c, AstNode *node, Array decls, Entity **fields, isize field_count, String context) { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); + defer (gb_temp_arena_memory_end(tmp)); Map entity_map = {}; map_init_with_reserve(&entity_map, c->tmp_allocator, 2*field_count); @@ -717,11 +718,9 @@ isize check_fields(Checker *c, AstNode *node, Array decls, Type *type = check_type(c, f->type); 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) { @@ -795,7 +794,6 @@ isize check_fields(Checker *c, AstNode *node, Array decls, } } - gb_temp_arena_memory_end(tmp); 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); + defer (gb_temp_arena_memory_end(tmp)); Map entity_map = {}; // Key: String 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); - gb_temp_arena_memory_end(tmp); union_type->Record.variants = variants; 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)); gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); + defer (gb_temp_arena_memory_end(tmp)); Type *base_type = t_int; 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_temp_arena_memory_end(tmp); 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)); gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); - + defer (gb_temp_arena_memory_end(tmp)); Map entity_map = {}; // Key: String 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_temp_arena_memory_end(tmp); bit_field_type->BitField.fields = fields; 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); if (type_hint != nullptr) { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); + defer (gb_temp_arena_memory_end(tmp)); + // NOTE(bill): These should be done for (isize i = 0; i < overload_count; i++) { 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; } } - gb_temp_arena_memory_end(tmp); - } 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) { - 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 } @@ -7094,7 +7091,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t TokenKind interval_kind = se->interval0.kind; - i64 indices[2] = {}; + i64 indices[3] = {}; AstNode *nodes[3] = {se->low, se->high, se->max}; for (isize i = 0; i < gb_count_of(nodes); i++) { i64 index = max_count; @@ -7159,6 +7156,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t case_end; case AstNode_TypeType: + case AstNode_PolyType: case AstNode_ProcType: case AstNode_PointerType: case AstNode_ArrayType: diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 3f9efda9a..fe70fd672 100644 --- a/src/check_stmt.cpp +++ b/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); + 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 // 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); } - gb_temp_arena_memory_end(tmp); } break; default: { @@ -1325,6 +1325,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { TypeAndToken *found = map_get(&seen, key); if (found != nullptr) { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); + defer (gb_temp_arena_memory_end(tmp)); + isize count = multi_map_count(&seen, key); 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) { continue; diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 78833453d..31d1e8933 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -78,8 +78,8 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \ TOKEN_KIND(Token_Semicolon, ";"), \ TOKEN_KIND(Token_Period, "."), \ 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__OperatorEnd, "_OperatorEnd"), \ \ @@ -885,10 +885,10 @@ Token tokenizer_get_token(Tokenizer *t) { token.kind = Token_Period; // Default if (t->curr_rune == '.') { // Could be an ellipsis 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); - token.kind = Token_HalfClosed; + token.kind = Token_Ellipsis; } } break;