diff --git a/code/demo.odin b/code/demo.odin index 05307c40f..a7bf7aa88 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -21,13 +21,13 @@ main :: proc() { msg := "Hellope"; list := []int{1, 4, 7, 3, 7, 2, 1}; - range value : msg { + for value : msg { fmt.println(value); } - range value : list { + for value : list { fmt.println(value); } - range x : 0 ..< 5 { - fmt.println(x); + for val, idx : 12 ..< 17 { + fmt.println(val, idx); } } diff --git a/core/_preload.odin b/core/_preload.odin index c0ca2ec6a..d65f3d8e4 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -313,19 +313,19 @@ __bounds_check_error :: proc(file: string, line, column: int, index, count: int) __debug_trap(); } -__slice_expr_error :: proc(file: string, line, column: int, low, high, max: int) { - if 0 <= low && low <= high && high <= max { +__slice_expr_error :: proc(file: string, line, column: int, low, high: int) { + if 0 <= low && low <= high { return; } - fmt.fprintf(os.stderr, "%(%:%) Invalid slice indices: [%:%:%]\n", - file, line, column, low, high, max); + fmt.fprintf(os.stderr, "%(%:%) Invalid slice indices: [%:%]\n", + file, line, column, low, high); __debug_trap(); } __substring_expr_error :: proc(file: string, line, column: int, low, high: int) { if 0 <= low && low <= high { return; } - fmt.fprintf(os.stderr, "%(%:%) Invalid substring indices: [%:%:%]\n", + fmt.fprintf(os.stderr, "%(%:%) Invalid substring indices: [%:%]\n", file, line, column, low, high); __debug_trap(); } diff --git a/core/atomic.odin b/core/atomic.odin index d41685d6b..cb931813b 100644 --- a/core/atomic.odin +++ b/core/atomic.odin @@ -37,8 +37,8 @@ fetch_or32 :: proc(a: ^i32, operand: i32) -> i32 { spin_lock32 :: proc(a: ^i32, time_out: int) -> bool { // NOTE(bill) time_out = -1 as default old_value := compare_exchange32(a, 1, 0); counter := 0; - for old_value != 0 && (time_out < 0 || counter < time_out) { - counter++; + while old_value != 0 && (time_out < 0 || counter < time_out) { + counter += 1; yield_thread(); old_value = compare_exchange32(a, 1, 0); mfence(); @@ -81,8 +81,8 @@ fetch_or64 :: proc(a: ^i64, operand: i64) -> i64 { spin_lock64 :: proc(a: ^i64, time_out: int) -> bool { // NOTE(bill) time_out = -1 as default old_value := compare_exchange64(a, 1, 0); counter := 0; - for old_value != 0 && (time_out < 0 || counter < time_out) { - counter++; + while old_value != 0 && (time_out < 0 || counter < time_out) { + counter += 1; yield_thread(); old_value = compare_exchange64(a, 1, 0); mfence(); diff --git a/core/fmt.odin b/core/fmt.odin index 4fbb8b126..68da7e413 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -4,84 +4,90 @@ PRINT_BUF_SIZE :: 1<<12; -fprint :: proc(fd: os.Handle, args: ..any) -> int { - data: [PRINT_BUF_SIZE]byte; - buf := data[:0]; - bprint(^buf, ..args); - os.write(fd, buf); - return buf.count; -} - -fprintln :: proc(fd: os.Handle, args: ..any) -> int { - data: [PRINT_BUF_SIZE]byte; - buf := data[:0]; - bprintln(^buf, ..args); - os.write(fd, buf); - return buf.count; -} -fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int { - data: [PRINT_BUF_SIZE]byte; - buf := data[:0]; - bprintf(^buf, fmt, ..args); - os.write(fd, buf); - return buf.count; +Buffer :: struct { + data: []byte; + length: int; } -print :: proc(args: ..any) -> int { - return fprint(os.stdout, ..args); +fprint :: proc(fd: os.Handle, args: ...any) -> int { + data: [PRINT_BUF_SIZE]byte; + buf := Buffer{data[:], 0}; + bprint(^buf, ...args); + os.write(fd, buf.data[:buf.length]); + return buf.length; } -println :: proc(args: ..any) -> int { - return fprintln(os.stdout, ..args); + +fprintln :: proc(fd: os.Handle, args: ...any) -> int { + data: [PRINT_BUF_SIZE]byte; + buf := Buffer{data[:], 0}; + bprintln(^buf, ...args); + os.write(fd, buf.data[:buf.length]); + return buf.length; } -printf :: proc(fmt: string, args: ..any) -> int { - return fprintf(os.stdout, fmt, ..args); +fprintf :: proc(fd: os.Handle, fmt: string, args: ...any) -> int { + data: [PRINT_BUF_SIZE]byte; + buf := Buffer{data[:], 0}; + bprintf(^buf, fmt, ...args); + os.write(fd, buf.data[:buf.length]); + return buf.length; +} + + +print :: proc(args: ...any) -> int { + return fprint(os.stdout, ...args); +} +println :: proc(args: ...any) -> int { + return fprintln(os.stdout, ...args); +} +printf :: proc(fmt: string, args: ...any) -> int { + return fprintf(os.stdout, fmt, ...args); } fprint_type :: proc(fd: os.Handle, info: ^Type_Info) { data: [PRINT_BUF_SIZE]byte; - buf := data[:0]; + buf := Buffer{data[:], 0}; bprint_type(^buf, info); - os.write(fd, buf); + os.write(fd, buf.data[:buf.length]); } -print_byte_buffer :: proc(buf: ^[]byte, b: []byte) { - if buf.count < buf.capacity { - n := min(buf.capacity-buf.count, b.count); +print_byte_buffer :: proc(buf: ^Buffer, b: []byte) { + if buf.length < buf.data.count { + n := min(buf.data.count-buf.length, b.count); if n > 0 { - mem.copy(buf.data + buf.count, b.data, n); - buf.count += n; + copy(buf.data[buf.length:], b[:n]); + buf.length += n; } } } -bprint_string :: proc(buf: ^[]byte, s: string) { +bprint_string :: proc(buf: ^Buffer, s: string) { print_byte_buffer(buf, s as []byte); } byte_reverse :: proc(b: []byte) { n := b.count; - for i := 0; i < n/2; i++ { + for i : 0.. 0 { + while i > 0 { buf[len] = __NUM_TO_CHAR_TABLE[i % 10]; - len++; + len += 1; i /= 10; } byte_reverse(buf[:len]); bprint_string(buffer, buf[:len] as string); } -bprint_i64 :: proc(buffer: ^[]byte, value: i64) { +bprint_i64 :: proc(buffer: ^Buffer, value: i64) { // TODO(bill): Cleanup printing i := value; if i < 0 { @@ -124,14 +130,14 @@ bprint_i64 :: proc(buffer: ^[]byte, value: i64) { } /* -bprint_u128 :: proc(buffer: ^[]byte, value u128) { +bprint_u128 :: proc(buffer: ^Buffer, value u128) { a := value transmute [2]u64; if a[1] != 0 { bprint_u64(buffer, a[1]); } bprint_u64(buffer, a[0]); } -bprint_i128 :: proc(buffer: ^[]byte, value i128) { +bprint_i128 :: proc(buffer: ^Buffer, value i128) { i := value; if i < 0 { i = -i; @@ -142,7 +148,7 @@ bprint_i128 :: proc(buffer: ^[]byte, value i128) { */ -print__f64 :: proc(buffer: ^[]byte, value: f64, decimal_places: int) { +print__f64 :: proc(buffer: ^Buffer, value: f64, decimal_places: int) { f := value; if f == 0 { bprint_rune(buffer, '0'); @@ -159,16 +165,17 @@ print__f64 :: proc(buffer: ^[]byte, value: f64, decimal_places: int) { bprint_rune(buffer, '.'); - mult :f64 = 10.0; - for ; decimal_places >= 0; decimal_places-- { + mult: f64 = 10.0; + while decimal_places >= 0 { i = (f * mult) as u64; bprint_u64(buffer, i as u64); f -= i as f64 / mult; mult *= 10; + decimal_places -= 1; } } -bprint_type :: proc(buf: ^[]byte, ti: ^Type_Info) { +bprint_type :: proc(buf: ^Buffer, ti: ^Type_Info) { if ti == nil { return; } @@ -224,7 +231,7 @@ bprint_type :: proc(buf: ^[]byte, ti: ^Type_Info) { case Tuple: count := info.fields.count; if count != 1 { bprint_string(buf, "("); } - for i := 0; i < count; i++ { + for i : 0.. 0 { bprint_string(buf, ", "); } f := info.fields[i]; @@ -257,37 +264,37 @@ bprint_type :: proc(buf: ^[]byte, ti: ^Type_Info) { if info.packed { bprint_string(buf, "#packed "); } if info.ordered { bprint_string(buf, "#ordered "); } bprint_string(buf, "{"); - for i := 0; i < info.fields.count; i++ { + for field, i : info.fields { if i > 0 { bprint_string(buf, ", "); } - bprint_any(buf, info.fields[i].name); + bprint_any(buf, field.name); bprint_string(buf, ": "); - bprint_type(buf, info.fields[i].type_info); + bprint_type(buf, field.type_info); } bprint_string(buf, "}"); case Union: bprint_string(buf, "union {"); - for i := 0; i < info.fields.count; i++ { + for field, i : info.fields { if i > 0 { bprint_string(buf, ", "); } - bprint_any(buf, info.fields[i].name); + bprint_any(buf, field.name); bprint_string(buf, ": "); - bprint_type(buf, info.fields[i].type_info); + bprint_type(buf, field.type_info); } bprint_string(buf, "}"); case Raw_Union: bprint_string(buf, "raw_union {"); - for i := 0; i < info.fields.count; i++ { + for field, i : info.fields { if i > 0 { bprint_string(buf, ", "); } - bprint_any(buf, info.fields[i].name); + bprint_any(buf, field.name); bprint_string(buf, ": "); - bprint_type(buf, info.fields[i].type_info); + bprint_type(buf, field.type_info); } bprint_string(buf, "}"); @@ -307,7 +314,7 @@ make_any :: proc(type_info: ^Type_Info, data: rawptr) -> any { return a; } -bprint_any :: proc(buf: ^[]byte, arg: any) { +bprint_any :: proc(buf: ^Buffer, arg: any) { if arg.type_info == nil { bprint_string(buf, ""); return; @@ -326,8 +333,7 @@ bprint_any :: proc(buf: ^[]byte, arg: any) { case Struct: bprint_string(buf, info.name); bprint_string(buf, "{"); - for i := 0; i < b.fields.count; i++ { - f := b.fields[i]; + for f, i : b.fields { if i > 0 { bprint_string(buf, ", "); } @@ -397,7 +403,7 @@ bprint_any :: proc(buf: ^[]byte, arg: any) { bprintf(buf, "[%]%{", info.count, info.elem); defer bprint_string(buf, "}"); - for i := 0; i < info.count; i++ { + for i : 0.. 0 { bprint_string(buf, ", "); } @@ -411,7 +417,7 @@ bprint_any :: proc(buf: ^[]byte, arg: any) { bprintf(buf, "[]%{", info.elem); defer bprint_string(buf, "}"); - for i := 0; i < slice.count; i++ { + for i : 0.. 0 { bprint_string(buf, ", "); } @@ -438,7 +444,7 @@ bprint_any :: proc(buf: ^[]byte, arg: any) { return; } - for i := 0; i < info.count; i++ { + for i : 0.. 0 { bprint_string(buf, ", "); } @@ -452,14 +458,14 @@ bprint_any :: proc(buf: ^[]byte, arg: any) { bprintf(buf, "%{", arg.type_info); defer bprint_string(buf, "}"); - for i := 0; i < info.fields.count; i++ { + for f, i : info.fields { if i > 0 { bprint_string(buf, ", "); } - bprint_string(buf, info.fields[i].name); + bprint_string(buf, f.name); bprint_string(buf, " = "); - data := arg.data as ^byte + info.fields[i].offset; - ti := info.fields[i].type_info; + data := arg.data as ^byte + f.offset; + ti := f.type_info; bprint_any(buf, make_any(ti, data)); } @@ -479,7 +485,7 @@ bprint_any :: proc(buf: ^[]byte, arg: any) { } -bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) -> int { +bprintf :: proc(buf: ^Buffer, fmt: string, args: ...any) -> int { is_digit :: proc(r: rune) -> bool #inline { return '0' <= r && r <= '9'; } @@ -487,7 +493,7 @@ bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) -> int { parse_int :: proc(s: string, offset: int) -> (int, int) { result := 0; - for ; offset < s.count; offset++ { + for _ : offset.. int { prev := 0; implicit_index := 0; - for i := 0; i < fmt.count; i++ { + while i := 0; i < fmt.count { defer i += 1; r := fmt[i] as rune; index := implicit_index; @@ -512,13 +518,13 @@ bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) -> int { } bprint_string(buf, fmt[prev:i]); - i++; // Skip % + i += 1; // Skip % if i < fmt.count { next := fmt[i] as rune; if next == '%' { bprint_string(buf, "%"); - i++; + i += 1; prev = i; continue; } @@ -540,11 +546,11 @@ bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) -> int { } bprint_string(buf, fmt[prev:]); - return buf.count; + return buf.length; } -bprint :: proc(buf: ^[]byte, args: ..any) -> int { +bprint :: proc(buf: ^Buffer, args: ...any) -> int { is_type_string :: proc(info: ^Type_Info) -> bool { using Type_Info; if info == nil { @@ -560,8 +566,7 @@ bprint :: proc(buf: ^[]byte, args: ..any) -> int { prev_string := false; - for i := 0; i < args.count; i++ { - arg := args[i]; + for arg, i : args { is_string := arg.data != nil && is_type_string(arg.type_info); if i > 0 && !is_string && !prev_string { bprint_space(buf); @@ -569,16 +574,16 @@ bprint :: proc(buf: ^[]byte, args: ..any) -> int { bprint_any(buf, arg); prev_string = is_string; } - return buf.count; + return buf.length; } -bprintln :: proc(buf: ^[]byte, args: ..any) -> int { - for i := 0; i < args.count; i++ { +bprintln :: proc(buf: ^Buffer, args: ...any) -> int { + for arg, i : args { if i > 0 { - append(buf, ' '); + bprint_space(buf); } - bprint_any(buf, args[i]); + bprint_any(buf, arg); } bprint_nl(buf); - return buf.count; + return buf.length; } diff --git a/core/hash.odin b/core/hash.odin index 372a7cd4a..6d5690d44 100644 --- a/core/hash.odin +++ b/core/hash.odin @@ -1,7 +1,7 @@ crc32 :: proc(data: rawptr, len: int) -> u32 { result := ~(0 as u32); s := slice_ptr(data as ^u8, len); - for i := 0; i < len; i++ { + for i : 0..>8 ~ __CRC32_TABLE[(result ~ b) & 0xff]; } @@ -10,7 +10,7 @@ crc32 :: proc(data: rawptr, len: int) -> u32 { crc64 :: proc(data: rawptr, len: int) -> u64 { result := ~(0 as u64); s := slice_ptr(data as ^u8, len); - for i := 0; i < len; i++ { + for i : 0..>8 ~ __CRC64_TABLE[(result ~ b) & 0xff]; } @@ -20,8 +20,8 @@ crc64 :: proc(data: rawptr, len: int) -> u64 { fnv32 :: proc(data: rawptr, len: int) -> u32 { s := slice_ptr(data as ^u8, len); - h :u32 = 0x811c9dc5; - for i := 0; i < len; i++ { + h: u32 = 0x811c9dc5; + for i : 0.. u32 { fnv64 :: proc(data: rawptr, len: int) -> u64 { s := slice_ptr(data as ^u8, len); - h :u64 = 0xcbf29ce484222325; - for i := 0; i < len; i++ { + h: u64 = 0xcbf29ce484222325; + for i : 0.. u64 { fnv32a :: proc(data: rawptr, len: int) -> u32 { s := slice_ptr(data as ^u8, len); - h :u32 = 0x811c9dc5; - for i := 0; i < len; i++ { + h: u32 = 0x811c9dc5; + for i : 0.. u64 { s := slice_ptr(data as ^u8, len); h :u64 = 0xcbf29ce484222325; - for i := 0; i < len; i++ { + for i : 0.. u64 { data := slice_ptr(data_ as ^u64, len/size_of(u64)); data2 := slice_ptr(data_ as ^u8, len); - for i := 0; i < data.count; i++ { + for i : 0 ..< data.count { k := data[i]; k *= m; @@ -108,9 +108,9 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 { data := slice_ptr(data_ as ^u32, len/size_of(u32)); i := 0; - for len >= 8 { + while len >= 8 { k1, k2: u32; - k1 = data[i]; i++; + k1 = data[i]; i += 1; k1 *= m; k1 ~= k1>>r; k1 *= m; @@ -118,7 +118,7 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 { h1 ~= k1; len -= 4; - k2 = data[i]; i++; + k2 = data[i]; i += 1; k2 *= m; k2 ~= k2>>r; k2 *= m; @@ -127,9 +127,9 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 { len -= 4; } - if (len >= 4) { + if len >= 4 { k1: u32; - k1 = data[i]; i++; + k1 = data[i]; i += 1; k1 *= m; k1 ~= k1>>r; k1 *= m; diff --git a/core/math.odin b/core/math.odin index 27afb45a5..9a0f8b1eb 100644 --- a/core/math.odin +++ b/core/math.odin @@ -145,8 +145,8 @@ mat4_identity :: proc() -> Mat4 { } mat4_transpose :: proc(m: Mat4) -> Mat4 { - for j := 0; j < 4; j++ { - for i := 0; i < 4; i++ { + for j : 0..<4 { + for i : 0..<4 { m[i][j], m[j][i] = m[j][i], m[i][j]; } } @@ -155,8 +155,8 @@ mat4_transpose :: proc(m: Mat4) -> Mat4 { mat4_mul :: proc(a, b: Mat4) -> Mat4 { c: Mat4; - for j := 0; j < 4; j++ { - for i := 0; i < 4; i++ { + for j : 0..<4 { + for i : 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 c6e84bc9a..d625ec0b2 100644 --- a/core/mem.odin +++ b/core/mem.odin @@ -40,9 +40,9 @@ compare :: proc(dst, src: rawptr, n: int) -> int #link_name "__mem_compare" { la := slice_ptr(^a[0] as ^int, fast); lb := slice_ptr(^b[0] as ^int, fast); - for ; curr_block < fast; curr_block++ { + for _ : curr_block ..< fast { if (la[curr_block] ~ lb[curr_block]) != 0 { - for pos := curr_block*size_of(int); pos < n; pos++ { + for pos : curr_block*size_of(int) ..< n { if (a[pos] ~ b[pos]) != 0 { return a[pos] as int - b[pos] as int; } @@ -51,7 +51,7 @@ compare :: proc(dst, src: rawptr, n: int) -> int #link_name "__mem_compare" { } - for ; offset < n; offset++ { + for _ : offset ..< n { if (a[offset] ~ b[offset]) != 0 { return a[offset] as int - b[offset] as int; } @@ -96,13 +96,14 @@ allocation_header_fill :: proc(header: ^Allocation_Header, data: rawptr, size: i header.size = size; ptr := (header+1) as ^int; - for i := 0; ptr as rawptr < data; i++ { + while i := 0; ptr as rawptr < data { (ptr+i)^ = -1; + i += 1; } } allocation_header :: proc(data: rawptr) -> ^Allocation_Header { p := data as ^int; - for (p-1)^ == -1 { + while (p-1)^ == -1 { p = (p-1); } return (p as ^Allocation_Header)-1; @@ -115,6 +116,7 @@ allocation_header :: proc(data: rawptr) -> ^Allocation_Header { // Custom allocators Arena :: struct { backing: Allocator; + offset: int; memory: []byte; temp_count: int; } @@ -144,7 +146,8 @@ free_arena :: proc(using a: ^Arena) { if backing.procedure != nil { push_allocator backing { free(memory.data); - memory = memory[0:0:0]; + memory = memory[0:0]; + offset = 0; } } } @@ -166,15 +169,15 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, case ALLOC: total_size := size + alignment; - if arena.memory.count + total_size > arena.memory.capacity { + if arena.offset + total_size > arena.memory.count { fmt.fprintln(os.stderr, "Arena out of memory"); return nil; } - #no_bounds_check end := ^arena.memory[arena.memory.count]; + #no_bounds_check end := ^arena.memory[arena.offset]; ptr := align_forward(end, alignment); - arena.memory.count += total_size; + arena.offset += total_size; return zero(ptr, size); case FREE: @@ -182,7 +185,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, // Use Arena_Temp_Memory if you want to free a block case FREE_ALL: - arena.memory.count = 0; + arena.offset = 0; case RESIZE: return default_resize_align(old_memory, old_size, size, alignment); @@ -195,7 +198,7 @@ begin_arena_temp_memory :: proc(a: ^Arena) -> Arena_Temp_Memory { tmp: Arena_Temp_Memory; tmp.arena = a; tmp.original_count = a.memory.count; - a.temp_count++; + a.temp_count += 1; return tmp; } @@ -203,7 +206,7 @@ end_arena_temp_memory :: proc(using tmp: Arena_Temp_Memory) { assert(arena.memory.count >= original_count); assert(arena.temp_count > 0); arena.memory.count = original_count; - arena.temp_count--; + arena.temp_count -= 1; } diff --git a/core/os_windows.odin b/core/os_windows.odin index 1ed897a0c..e63d3d8a7 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -222,7 +222,7 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) { single_read_length: i32; total_read: i64; - for total_read < length { + while total_read < length { remaining := length - total_read; to_read: u32; MAX :: 1<<32-1; diff --git a/core/sync.odin b/core/sync.odin index 72e83ae2d..de13eec5e 100644 --- a/core/sync.odin +++ b/core/sync.odin @@ -52,7 +52,7 @@ mutex_lock :: proc(m: ^Mutex) { } } atomic.store32(^m.owner, thread_id); - m.recursion++; + m.recursion += 1; } mutex_try_lock :: proc(m: ^Mutex) -> bool { thread_id := current_thread_id(); @@ -68,7 +68,7 @@ mutex_try_lock :: proc(m: ^Mutex) -> bool { } atomic.store32(^m.owner, thread_id); } - m.recursion++; + m.recursion += 1; return true; } mutex_unlock :: proc(m: ^Mutex) { @@ -76,7 +76,7 @@ mutex_unlock :: proc(m: ^Mutex) { thread_id := current_thread_id(); assert(thread_id == atomic.load32(^m.owner)); - m.recursion--; + m.recursion -= 1; recursion = m.recursion; if recursion == 0 { atomic.store32(^m.owner, thread_id); diff --git a/core/utf8.odin b/core/utf8.odin index 45ff89ee3..fca660e91 100644 --- a/core/utf8.odin +++ b/core/utf8.odin @@ -132,10 +132,11 @@ valid_rune :: proc(r: rune) -> bool { valid_string :: proc(s: string) -> bool { n := s.count; - for i := 0; i < n; { + i := 0; + while i < n { si := s[i]; if si < RUNE_SELF { // ascii - i++; + i += 1; continue; } x := accept_sizes[si]; @@ -166,20 +167,22 @@ valid_string :: proc(s: string) -> bool { rune_count :: proc(s: string) -> int { count := 0; n := s.count; - for i := 0; i < n; count++ { + i := 0; + while i < n { + defer count += 1; si := s[i]; if si < RUNE_SELF { // ascii - i++; + i += 1; continue; } x := accept_sizes[si]; if x == 0xf1 { - i++; + i += 1; continue; } size := (x & 7) as int; if i+size > n { - i++; + i += 1; continue; } ar := accept_ranges[x>>4]; diff --git a/src/checker/checker.c b/src/checker/checker.c index a43a7853b..5b81003db 100644 --- a/src/checker/checker.c +++ b/src/checker/checker.c @@ -132,7 +132,7 @@ typedef enum BuiltinProcId { BuiltinProc_panic, BuiltinProc_copy, - BuiltinProc_append, + // BuiltinProc_append, BuiltinProc_swizzle, @@ -175,7 +175,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = { {STR_LIT("panic"), 1, false, Expr_Stmt}, {STR_LIT("copy"), 2, false, Expr_Expr}, - {STR_LIT("append"), 2, false, Expr_Expr}, + // {STR_LIT("append"), 2, false, Expr_Expr}, {STR_LIT("swizzle"), 1, true, Expr_Expr}, diff --git a/src/checker/entity.c b/src/checker/entity.c index 614fa0ce2..17fb70e06 100644 --- a/src/checker/entity.c +++ b/src/checker/entity.c @@ -57,6 +57,7 @@ struct Entity { struct { i32 field_index; i32 field_src_index; + bool is_immutable; } Variable; i32 TypeName; struct { diff --git a/src/checker/expr.c b/src/checker/expr.c index bf1303e4c..5a200df6a 100644 --- a/src/checker/expr.c +++ b/src/checker/expr.c @@ -965,9 +965,9 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type) { } #else o->mode = Addressing_Variable; - // if (e->Variable.is_let) { - // o->mode = Addressing_Value; - // } + if (e->Variable.is_immutable) { + o->mode = Addressing_Value; + } #endif break; @@ -2967,6 +2967,7 @@ 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; @@ -3003,6 +3004,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id 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 @@ -4342,9 +4344,6 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint if (o->mode == Addressing_Constant) { max_count = o->value.value_string.len; } - if (se->max != NULL) { - error_node(se->max, "Max (3rd) index not needed in substring expression"); - } o->type = t_string; } break; @@ -4375,8 +4374,8 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint o->mode = Addressing_Value; - i64 indices[3] = {0}; - AstNode *nodes[3] = {se->low, se->high, se->max}; + i64 indices[2] = {0}; + AstNode *nodes[2] = {se->low, se->high}; for (isize i = 0; i < gb_count_of(nodes); i++) { i64 index = max_count; if (nodes[i] != NULL) { @@ -4680,10 +4679,6 @@ gbString write_expr_to_string(gbString str, AstNode *node) { str = write_expr_to_string(str, se->low); str = gb_string_appendc(str, ":"); str = write_expr_to_string(str, se->high); - if (se->triple_indexed) { - str = gb_string_appendc(str, ":"); - str = write_expr_to_string(str, se->max); - } str = gb_string_appendc(str, "]"); case_end; diff --git a/src/checker/stmt.c b/src/checker/stmt.c index 6113c519a..4f545c471 100644 --- a/src/checker/stmt.c +++ b/src/checker/stmt.c @@ -127,13 +127,13 @@ bool check_is_terminating(AstNode *node) { } case_end; - case_ast_node(fs, ForStmt, node); - if (fs->cond == NULL && !check_has_break(fs->body, true)) { + case_ast_node(ws, WhileStmt, node); + if (ws->cond == NULL && !check_has_break(ws->body, true)) { return true; } case_end; - case_ast_node(rs, RangeStmt, node); + case_ast_node(rs, ForStmt, node); if (!check_has_break(rs->body, true)) { return true; } @@ -375,48 +375,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { check_stmt(c, ts->stmt, flags); case_end; - case_ast_node(ids, IncDecStmt, node); - Token op = ids->op; - switch (ids->op.kind) { - case Token_Increment: - op.kind = Token_Add; - op.string.len = 1; - break; - case Token_Decrement: - op.kind = Token_Sub; - op.string.len = 1; - break; - default: - error(ids->op, "Unknown inc/dec operation %.*s", LIT(ids->op.string)); - return; - } - - Operand operand = {Addressing_Invalid}; - check_expr(c, &operand, ids->expr); - if (operand.mode == Addressing_Invalid) { - return; - } - if (!is_type_numeric(operand.type) && !is_type_pointer(operand.type)) { - gbString type_str = type_to_string(operand.type); - error(ids->op, "Non numeric type `%s`", type_str); - gb_string_free(type_str); - return; - } - - AstNode basic_lit = {AstNode_BasicLit}; - ast_node(bl, BasicLit, &basic_lit); - *bl = ids->op; - bl->kind = Token_Integer; - bl->string = str_lit("1"); - - AstNode binary_expr = {AstNode_BinaryExpr}; - ast_node(be, BinaryExpr, &binary_expr); - be->op = op; - be->left = ids->expr; - be->right = &basic_lit; - check_binary_expr(c, &operand, &binary_expr); - case_end; - case_ast_node(as, AssignStmt, node); switch (as->op.kind) { case Token_Eq: { @@ -567,30 +525,27 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { } case_end; - case_ast_node(fs, ForStmt, node); + case_ast_node(ws, WhileStmt, node); u32 new_flags = mod_flags | Stmt_BreakAllowed | Stmt_ContinueAllowed; check_open_scope(c, node); - if (fs->init != NULL) { - check_stmt(c, fs->init, 0); + if (ws->init != NULL) { + check_stmt(c, ws->init, 0); } - if (fs->cond) { + if (ws->cond) { Operand operand = {Addressing_Invalid}; - check_expr(c, &operand, fs->cond); + check_expr(c, &operand, ws->cond); if (operand.mode != Addressing_Invalid && !is_type_boolean(operand.type)) { - error_node(fs->cond, "Non-boolean condition in `for` statement"); + error_node(ws->cond, "Non-boolean condition in `while` statement"); } } - if (fs->post != NULL) { - check_stmt(c, fs->post, 0); - } - check_stmt(c, fs->body, new_flags); + check_stmt(c, ws->body, new_flags); check_close_scope(c); case_end; - case_ast_node(rs, RangeStmt, node); + case_ast_node(rs, ForStmt, node); u32 new_flags = mod_flags | Stmt_BreakAllowed | Stmt_ContinueAllowed; check_open_scope(c, node); @@ -646,8 +601,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { goto skip_expr; } - if (!is_type_integer(x.type) && !is_type_float(x.type)) { - error(ie->op, "Only numerical types are allowed within interval expressions"); + if (!is_type_integer(x.type) && !is_type_float(x.type) && !is_type_pointer(x.type)) { + error(ie->op, "Only numerical and pointer types are allowed within interval expressions"); goto skip_expr; } @@ -661,7 +616,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { bool ok = compare_exact_values(Token_Lt, a, b); if (!ok) { // TODO(bill): Better error message - error(ie->op, "Invalid interval expression"); + error(ie->op, "Invalid interval range"); goto skip_expr; } } @@ -723,6 +678,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { } if (found == NULL) { entity = make_entity_variable(c->allocator, c->context.scope, token, type); + entity->Variable.is_immutable = true; add_entity_definition(&c->info, name, entity); } else { TokenPos pos = found->token.pos; @@ -1051,12 +1007,12 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { switch (token.kind) { case Token_break: if ((flags & Stmt_BreakAllowed) == 0) { - error(token, "`break` only allowed in `for` or `match` statements"); + error(token, "`break` only allowed in loops or `match` statements"); } break; case Token_continue: if ((flags & Stmt_ContinueAllowed) == 0) { - error(token, "`continue` only allowed in `for` statements"); + error(token, "`continue` only allowed in loops"); } break; case Token_fallthrough: diff --git a/src/checker/types.c b/src/checker/types.c index df11e1097..89cda3d02 100644 --- a/src/checker/types.c +++ b/src/checker/types.c @@ -116,6 +116,8 @@ typedef struct TypeRecord { ProcCallingConvention calling_convention; \ }) + + typedef enum TypeKind { Type_Invalid, #define TYPE_KIND(k, ...) GB_JOIN2(Type_, k), @@ -987,7 +989,6 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n } else if (type->kind == Type_Slice) { String data_str = str_lit("data"); String count_str = str_lit("count"); - String capacity_str = str_lit("capacity"); if (str_eq(field_name, data_str)) { selection_add_index(&sel, 0); @@ -1002,14 +1003,6 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n sel.entity = entity__slice_count; return sel; - } else if (str_eq(field_name, capacity_str)) { - selection_add_index(&sel, 2); - if (entity__slice_capacity == NULL) { - entity__slice_capacity = make_entity_field(a, NULL, make_token_ident(capacity_str), t_int, false, 2); - } - - sel.entity = entity__slice_capacity; - return sel; } } @@ -1393,8 +1386,8 @@ i64 type_size_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, TypeP } break; - case Type_Slice: // ptr + len + cap - return 3 * s.word_size; + case Type_Slice: // ptr + count + return 2 * s.word_size; case Type_Maybe: { // value + bool i64 align, size; diff --git a/src/parser.c b/src/parser.c index 1332fd929..43b2b7591 100644 --- a/src/parser.c +++ b/src/parser.c @@ -140,8 +140,7 @@ AST_NODE_KIND(_ExprBegin, "", i32) \ AST_NODE_KIND(SliceExpr, "slice expression", struct { \ AstNode *expr; \ Token open, close; \ - AstNode *low, *high, *max; \ - bool triple_indexed; \ + AstNode *low, *high; \ }) \ AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \ AST_NODE_KIND(BlockExpr, "block expr", struct { \ @@ -166,7 +165,6 @@ AST_NODE_KIND(_StmtBegin, "", i32) \ AST_NODE_KIND(BadStmt, "bad statement", struct { Token begin, end; }) \ AST_NODE_KIND(EmptyStmt, "empty statement", struct { Token token; }) \ AST_NODE_KIND(ExprStmt, "expression statement", struct { AstNode *expr; } ) \ - AST_NODE_KIND(IncDecStmt, "increment/decrement statement", struct { Token op; AstNode *expr; }) \ AST_NODE_KIND(TagStmt, "tag statement", struct { \ Token token; \ Token name; \ @@ -198,14 +196,13 @@ AST_NODE_KIND(_ComplexStmtBegin, "", i32) \ Token token; \ AstNodeArray results; \ }) \ - AST_NODE_KIND(ForStmt, "for statement", struct { \ + AST_NODE_KIND(WhileStmt, "while statement", struct { \ Token token; \ AstNode *init; \ AstNode *cond; \ - AstNode *post; \ AstNode *body; \ }) \ - AST_NODE_KIND(RangeStmt, "range statement", struct { \ + AST_NODE_KIND(ForStmt, "range statement", struct { \ Token token; \ AstNode *value; \ AstNode *index; \ @@ -463,8 +460,6 @@ Token ast_node_token(AstNode *node) { return ast_node_token(node->ExprStmt.expr); case AstNode_TagStmt: return node->TagStmt.token; - case AstNode_IncDecStmt: - return node->IncDecStmt.op; case AstNode_AssignStmt: return node->AssignStmt.op; case AstNode_BlockStmt: @@ -475,8 +470,8 @@ Token ast_node_token(AstNode *node) { return node->WhenStmt.token; case AstNode_ReturnStmt: return node->ReturnStmt.token; - case AstNode_ForStmt: - return node->ForStmt.token; + case AstNode_WhileStmt: + return node->WhileStmt.token; case AstNode_MatchStmt: return node->MatchStmt.token; case AstNode_CaseClause: @@ -677,15 +672,13 @@ AstNode *make_index_expr(AstFile *f, AstNode *expr, AstNode *index, Token open, } -AstNode *make_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, AstNode *low, AstNode *high, AstNode *max, bool triple_indexed) { +AstNode *make_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, AstNode *low, AstNode *high) { AstNode *result = make_node(f, AstNode_SliceExpr); result->SliceExpr.expr = expr; result->SliceExpr.open = open; result->SliceExpr.close = close; result->SliceExpr.low = low; result->SliceExpr.high = high; - result->SliceExpr.max = max; - result->SliceExpr.triple_indexed = triple_indexed; return result; } @@ -810,13 +803,6 @@ AstNode *make_expr_stmt(AstFile *f, AstNode *expr) { return result; } -AstNode *make_inc_dec_stmt(AstFile *f, Token op, AstNode *expr) { - AstNode *result = make_node(f, AstNode_IncDecStmt); - result->IncDecStmt.op = op; - result->IncDecStmt.expr = expr; - return result; -} - AstNode *make_assign_stmt(AstFile *f, Token op, AstNodeArray lhs, AstNodeArray rhs) { AstNode *result = make_node(f, AstNode_AssignStmt); result->AssignStmt.op = op; @@ -860,22 +846,21 @@ AstNode *make_return_stmt(AstFile *f, Token token, AstNodeArray results) { return result; } -AstNode *make_for_stmt(AstFile *f, Token token, AstNode *init, AstNode *cond, AstNode *post, AstNode *body) { - AstNode *result = make_node(f, AstNode_ForStmt); - result->ForStmt.token = token; - result->ForStmt.init = init; - result->ForStmt.cond = cond; - result->ForStmt.post = post; - result->ForStmt.body = body; +AstNode *make_while_stmt(AstFile *f, Token token, AstNode *init, AstNode *cond, AstNode *body) { + AstNode *result = make_node(f, AstNode_WhileStmt); + result->WhileStmt.token = token; + result->WhileStmt.init = init; + result->WhileStmt.cond = cond; + result->WhileStmt.body = body; return result; } -AstNode *make_range_stmt(AstFile *f, Token token, AstNode *value, AstNode *index, AstNode *expr, AstNode *body) { - AstNode *result = make_node(f, AstNode_RangeStmt); - result->RangeStmt.token = token; - result->RangeStmt.value = value; - result->RangeStmt.index = index; - result->RangeStmt.expr = expr; - result->RangeStmt.body = body; +AstNode *make_for_stmt(AstFile *f, Token token, AstNode *value, AstNode *index, AstNode *expr, AstNode *body) { + AstNode *result = make_node(f, AstNode_ForStmt); + result->ForStmt.token = token; + result->ForStmt.value = value; + result->ForStmt.index = index; + result->ForStmt.expr = expr; + result->ForStmt.body = body; return result; } @@ -1224,7 +1209,7 @@ void fix_advance_to_next_stmt(AstFile *f) { case Token_if: case Token_when: case Token_return: - case Token_for: + case Token_while: case Token_range: case Token_match: case Token_defer: @@ -1908,7 +1893,7 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) { isize colon_count = 0; Token colons[2] = {0}; - while (f->curr_token.kind == Token_Colon && colon_count < 2) { + while (f->curr_token.kind == Token_Colon && colon_count < 1) { colons[colon_count++] = f->curr_token; next_token(f); if (f->curr_token.kind != Token_Colon && @@ -1924,19 +1909,7 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) { if (colon_count == 0) { operand = make_index_expr(f, operand, indices[0], open, close); } else { - bool triple_indexed = false; - if (colon_count == 2) { - triple_indexed = true; - if (indices[1] == NULL) { - syntax_error(colons[0], "Second index is required in a triple indexed slice"); - indices[1] = make_bad_expr(f, colons[0], colons[1]); - } - if (indices[2] == NULL) { - syntax_error(colons[1], "Third index is required in a triple indexed slice"); - indices[2] = make_bad_expr(f, colons[1], close); - } - } - operand = make_slice_expr(f, operand, open, close, indices[0], indices[1], indices[2], triple_indexed); + operand = make_slice_expr(f, operand, open, close, indices[0], indices[1]); } } break; @@ -2239,19 +2212,6 @@ AstNode *parse_simple_stmt(AstFile *f) { return make_bad_stmt(f, token, f->curr_token); } - token = f->curr_token; - switch (token.kind) { - case Token_Increment: - case Token_Decrement: - if (f->curr_proc == NULL) { - syntax_error(f->curr_token, "You cannot use a simple statement in the file scope"); - return make_bad_stmt(f, f->curr_token, f->curr_token); - } - AstNode *stmt = make_inc_dec_stmt(f, token, lhs.e[0]); - next_token(f); - return stmt; - } - return make_expr_stmt(f, lhs.e[0]); } @@ -2748,6 +2708,41 @@ AstNode *parse_give_stmt(AstFile *f) { return make_expr_stmt(f, ge); } +AstNode *parse_while_stmt(AstFile *f) { + if (f->curr_proc == NULL) { + syntax_error(f->curr_token, "You cannot use a while statement in the file scope"); + return make_bad_stmt(f, f->curr_token, f->curr_token); + } + + Token token = expect_token(f, Token_while); + + AstNode *init = NULL; + AstNode *cond = NULL; + AstNode *body = NULL; + + isize prev_level = f->expr_level; + f->expr_level = -1; + + + cond = parse_simple_stmt(f); + if (is_ast_node_complex_stmt(cond)) { + syntax_error(f->curr_token, "You are not allowed that type of statement in a while statement, it is too complex!"); + } + + if (allow_token(f, Token_Semicolon)) { + init = cond; + cond = parse_simple_stmt(f); + } + f->expr_level = prev_level; + + body = parse_block_stmt(f, false); + + cond = convert_stmt_to_expr(f, cond, str_lit("boolean expression")); + + return make_while_stmt(f, token, init, cond, body); +} + + AstNode *parse_for_stmt(AstFile *f) { if (f->curr_proc == NULL) { syntax_error(f->curr_token, "You cannot use a for statement in the file scope"); @@ -2755,53 +2750,9 @@ AstNode *parse_for_stmt(AstFile *f) { } Token token = expect_token(f, Token_for); - - AstNode *init = NULL; - AstNode *cond = NULL; - AstNode *end = NULL; - AstNode *body = NULL; - - if (f->curr_token.kind != Token_OpenBrace) { - isize prev_level = f->expr_level; - f->expr_level = -1; - if (f->curr_token.kind != Token_Semicolon) { - cond = parse_simple_stmt(f); - if (is_ast_node_complex_stmt(cond)) { - syntax_error(f->curr_token, "You are not allowed that type of statement in a for statement, it is too complex!"); - } - } - - if (allow_token(f, Token_Semicolon)) { - init = cond; - cond = NULL; - if (f->curr_token.kind != Token_Semicolon) { - cond = parse_simple_stmt(f); - } - expect_token(f, Token_Semicolon); - if (f->curr_token.kind != Token_OpenBrace) { - end = parse_simple_stmt(f); - } - } - f->expr_level = prev_level; - } - body = parse_block_stmt(f, false); - - cond = convert_stmt_to_expr(f, cond, str_lit("boolean expression")); - - return make_for_stmt(f, token, init, cond, end, body); -} - - -AstNode *parse_range_stmt(AstFile *f) { - if (f->curr_proc == NULL) { - syntax_error(f->curr_token, "You cannot use a range statement in the file scope"); - return make_bad_stmt(f, f->curr_token, f->curr_token); - } - - Token token = expect_token(f, Token_range); AstNodeArray names = parse_identifier_list(f); parse_check_name_list_for_reserves(f, names); - Token colon = expect_token_after(f, Token_Colon, "range name list"); + Token colon = expect_token_after(f, Token_Colon, "for name list"); isize prev_level = f->expr_level; f->expr_level = -1; @@ -2830,7 +2781,7 @@ AstNode *parse_range_stmt(AstFile *f) { return make_bad_stmt(f, token, f->curr_token); } - return make_range_stmt(f, token, value, index, expr, body); + return make_for_stmt(f, token, value, index, expr, body); } AstNode *parse_case_clause(AstFile *f) { @@ -3009,8 +2960,8 @@ AstNode *parse_stmt(AstFile *f) { case Token_if: return parse_if_stmt(f); case Token_when: return parse_when_stmt(f); + case Token_while: return parse_while_stmt(f); case Token_for: return parse_for_stmt(f); - case Token_range: return parse_range_stmt(f); case Token_match: return parse_match_stmt(f); case Token_defer: return parse_defer_stmt(f); case Token_asm: return parse_asm_stmt(f); diff --git a/src/ssa.c b/src/ssa.c index a31f3e281..87eba55aa 100644 --- a/src/ssa.c +++ b/src/ssa.c @@ -234,7 +234,6 @@ struct ssaProcedure { TokenPos pos; \ ssaValue *low; \ ssaValue *high; \ - ssaValue *max; \ bool is_substring; \ }) @@ -1016,12 +1015,11 @@ ssaValue *ssa_make_instr_bounds_check(ssaProcedure *p, TokenPos pos, ssaValue *i v->Instr.BoundsCheck.len = len; return v; } -ssaValue *ssa_make_instr_slice_bounds_check(ssaProcedure *p, TokenPos pos, ssaValue *low, ssaValue *high, ssaValue *max, bool is_substring) { +ssaValue *ssa_make_instr_slice_bounds_check(ssaProcedure *p, TokenPos pos, ssaValue *low, ssaValue *high, bool is_substring) { ssaValue *v = ssa_alloc_instr(p, ssaInstr_SliceBoundsCheck); v->Instr.SliceBoundsCheck.pos = pos; v->Instr.SliceBoundsCheck.low = low; v->Instr.SliceBoundsCheck.high = high; - v->Instr.SliceBoundsCheck.max = max; v->Instr.SliceBoundsCheck.is_substring = is_substring; return v; } @@ -1794,11 +1792,6 @@ ssaValue *ssa_slice_len(ssaProcedure *proc, ssaValue *slice) { GB_ASSERT(t->kind == Type_Slice); return ssa_emit_struct_ev(proc, slice, 1); } -ssaValue *ssa_slice_cap(ssaProcedure *proc, ssaValue *slice) { - Type *t = ssa_type(slice); - GB_ASSERT(t->kind == Type_Slice); - return ssa_emit_struct_ev(proc, slice, 2); -} ssaValue *ssa_string_elem(ssaProcedure *proc, ssaValue *string) { Type *t = ssa_type(string); @@ -1813,7 +1806,7 @@ ssaValue *ssa_string_len(ssaProcedure *proc, ssaValue *string) { -ssaValue *ssa_add_local_slice(ssaProcedure *proc, Type *slice_type, ssaValue *base, ssaValue *low, ssaValue *high, ssaValue *max) { +ssaValue *ssa_add_local_slice(ssaProcedure *proc, Type *slice_type, ssaValue *base, ssaValue *low, ssaValue *high) { // TODO(bill): array bounds checking for slice creation // TODO(bill): check that low < high <= max gbAllocator a = proc->module->allocator; @@ -1829,17 +1822,8 @@ ssaValue *ssa_add_local_slice(ssaProcedure *proc, Type *slice_type, ssaValue *ba case Type_Pointer: high = v_one; break; } } - if (max == NULL) { - switch (bt->kind) { - case Type_Array: max = ssa_array_cap(proc, base); break; - case Type_Slice: max = ssa_slice_cap(proc, base); break; - case Type_Pointer: max = high; break; - } - } - GB_ASSERT(max != NULL); ssaValue *len = ssa_emit_arith(proc, Token_Sub, high, low, t_int); - ssaValue *cap = ssa_emit_arith(proc, Token_Sub, max, low, t_int); ssaValue *elem = NULL; switch (bt->kind) { @@ -1859,9 +1843,6 @@ ssaValue *ssa_add_local_slice(ssaProcedure *proc, Type *slice_type, ssaValue *ba gep = ssa_emit_struct_ep(proc, slice, 1); ssa_emit_store(proc, gep, len); - gep = ssa_emit_struct_ep(proc, slice, 2); - ssa_emit_store(proc, gep, cap); - return slice; } @@ -2103,7 +2084,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { ssa_emit_store(proc, elem_ptr, elem); ssaValue *len = ssa_string_len(proc, value); - ssaValue *slice = ssa_add_local_slice(proc, dst, elem_ptr, v_zero, len, len); + ssaValue *slice = ssa_add_local_slice(proc, dst, elem_ptr, v_zero, len); return ssa_emit_load(proc, slice); } @@ -2463,16 +2444,15 @@ void ssa_emit_bounds_check(ssaProcedure *proc, Token token, ssaValue *index, ssa // ssa_emit_global_call(proc, "__bounds_check_error", args, 5); } -void ssa_emit_slice_bounds_check(ssaProcedure *proc, Token token, ssaValue *low, ssaValue *high, ssaValue *max, bool is_substring) { +void ssa_emit_slice_bounds_check(ssaProcedure *proc, Token token, ssaValue *low, ssaValue *high, bool is_substring) { if ((proc->module->stmt_state_flags & StmtStateFlag_no_bounds_check) != 0) { return; } low = ssa_emit_conv(proc, low, t_int); high = ssa_emit_conv(proc, high, t_int); - max = ssa_emit_conv(proc, max, t_int); - ssa_emit(proc, ssa_make_instr_slice_bounds_check(proc, token.pos, low, high, max, is_substring)); + ssa_emit(proc, ssa_make_instr_slice_bounds_check(proc, token.pos, low, high, is_substring)); } @@ -2886,7 +2866,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue cap = ssa_emit_conv(proc, ssa_build_expr(proc, ce->args.e[2]), t_int); } - ssa_emit_slice_bounds_check(proc, ast_node_token(ce->args.e[1]), v_zero, len, cap, false); + ssa_emit_slice_bounds_check(proc, ast_node_token(ce->args.e[1]), v_zero, len, false); ssaValue *slice_size = ssa_emit_arith(proc, Token_Mul, elem_size, cap, t_int); @@ -2995,6 +2975,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue return len; } break; + #if 0 case BuiltinProc_append: { ssa_emit_comment(proc, str_lit("append")); // append :: proc(s: ^[]Type, item: Type) -> bool @@ -3051,6 +3032,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue return ssa_emit_conv(proc, cond, t_bool); } break; + #endif case BuiltinProc_swizzle: { ssa_emit_comment(proc, str_lit("swizzle")); @@ -3533,11 +3515,9 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { gbAllocator a = proc->module->allocator; ssaValue *low = v_zero; ssaValue *high = NULL; - ssaValue *max = NULL; if (se->low != NULL) low = ssa_build_expr(proc, se->low); if (se->high != NULL) high = ssa_build_expr(proc, se->high); - if (se->triple_indexed) max = ssa_build_expr(proc, se->max); ssaValue *addr = ssa_build_addr(proc, se->expr).addr; ssaValue *base = ssa_emit_load(proc, addr); Type *type = base_type(ssa_type(base)); @@ -3555,22 +3535,17 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { Type *slice_type = type; if (high == NULL) high = ssa_slice_len(proc, base); - if (max == NULL) max = ssa_slice_cap(proc, base); - GB_ASSERT(max != NULL); - ssa_emit_slice_bounds_check(proc, se->open, low, high, max, false); + ssa_emit_slice_bounds_check(proc, se->open, low, high, false); ssaValue *elem = ssa_emit_ptr_offset(proc, ssa_slice_elem(proc, base), low); ssaValue *len = ssa_emit_arith(proc, Token_Sub, high, low, t_int); - ssaValue *cap = ssa_emit_arith(proc, Token_Sub, max, low, t_int); ssaValue *slice = ssa_add_local_generated(proc, slice_type); ssaValue *gep0 = ssa_emit_struct_ep(proc, slice, 0); ssaValue *gep1 = ssa_emit_struct_ep(proc, slice, 1); - ssaValue *gep2 = ssa_emit_struct_ep(proc, slice, 2); ssa_emit_store(proc, gep0, elem); ssa_emit_store(proc, gep1, len); - ssa_emit_store(proc, gep2, cap); return ssa_make_addr(slice, expr); } @@ -3579,22 +3554,17 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { Type *slice_type = make_type_slice(a, type->Array.elem); if (high == NULL) high = ssa_array_len(proc, base); - if (max == NULL) max = ssa_array_cap(proc, base); - GB_ASSERT(max != NULL); - ssa_emit_slice_bounds_check(proc, se->open, low, high, max, false); + ssa_emit_slice_bounds_check(proc, se->open, low, high, false); ssaValue *elem = ssa_emit_ptr_offset(proc, ssa_array_elem(proc, addr), low); ssaValue *len = ssa_emit_arith(proc, Token_Sub, high, low, t_int); - ssaValue *cap = ssa_emit_arith(proc, Token_Sub, max, low, t_int); ssaValue *slice = ssa_add_local_generated(proc, slice_type); ssaValue *gep0 = ssa_emit_struct_ep(proc, slice, 0); ssaValue *gep1 = ssa_emit_struct_ep(proc, slice, 1); - ssaValue *gep2 = ssa_emit_struct_ep(proc, slice, 2); ssa_emit_store(proc, gep0, elem); ssa_emit_store(proc, gep1, len); - ssa_emit_store(proc, gep2, cap); return ssa_make_addr(slice, expr); } @@ -3605,7 +3575,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { high = ssa_string_len(proc, base); } - ssa_emit_slice_bounds_check(proc, se->open, low, high, high, true); + ssa_emit_slice_bounds_check(proc, se->open, low, high, true); ssaValue *elem, *len; len = ssa_emit_arith(proc, Token_Sub, high, low, t_int); @@ -4249,20 +4219,6 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { } case_end; - case_ast_node(ids, IncDecStmt, node); - ssa_emit_comment(proc, str_lit("IncDecStmt")); - TokenKind op = ids->op.kind; - if (op == Token_Increment) { - op = Token_Add; - } else if (op == Token_Decrement) { - op = Token_Sub; - } - ssaAddr lval = ssa_build_addr(proc, ids->expr); - ssaValue *one = ssa_emit_conv(proc, v_one, ssa_addr_type(lval)); - ssa_build_assign_op(proc, lval, one, op); - - case_end; - case_ast_node(as, AssignStmt, node); ssa_emit_comment(proc, str_lit("AssignStmt")); @@ -4444,56 +4400,44 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { proc->curr_block = done; case_end; - case_ast_node(fs, ForStmt, node); - ssa_emit_comment(proc, str_lit("ForStmt")); - if (fs->init != NULL) { - ssaBlock *init = ssa_add_block(proc, node, "for.init"); + case_ast_node(ws, WhileStmt, node); + ssa_emit_comment(proc, str_lit("WhileStmt")); + if (ws->init != NULL) { + ssaBlock *init = ssa_add_block(proc, node, "while.init"); ssa_emit_jump(proc, init); proc->curr_block = init; - ssa_build_stmt(proc, fs->init); + ssa_build_stmt(proc, ws->init); } - ssaBlock *body = ssa_add_block(proc, node, "for.body"); - ssaBlock *done = ssa_add_block(proc, node, "for.done"); // NOTE(bill): Append later + ssaBlock *body = ssa_add_block(proc, node, "while.body"); + ssaBlock *done = ssa_add_block(proc, node, "while.done"); // NOTE(bill): Append later ssaBlock *loop = body; - if (fs->cond != NULL) { - loop = ssa_add_block(proc, node, "for.loop"); - } - ssaBlock *cont = loop; - if (fs->post != NULL) { - cont = ssa_add_block(proc, node, "for.post"); - + if (ws->cond != NULL) { + loop = ssa_add_block(proc, node, "while.loop"); } ssa_emit_jump(proc, loop); proc->curr_block = loop; if (loop != body) { - ssa_build_cond(proc, fs->cond, body, done); + ssa_build_cond(proc, ws->cond, body, done); proc->curr_block = body; } - ssa_push_target_list(proc, done, cont, NULL); + ssa_push_target_list(proc, done, loop, NULL); ssa_open_scope(proc); - ssa_build_stmt(proc, fs->body); + ssa_build_stmt(proc, ws->body); ssa_close_scope(proc, ssaDeferExit_Default, NULL); ssa_pop_target_list(proc); - ssa_emit_jump(proc, cont); - - if (fs->post != NULL) { - proc->curr_block = cont; - ssa_build_stmt(proc, fs->post); - ssa_emit_jump(proc, loop); - } - + ssa_emit_jump(proc, loop); proc->curr_block = done; case_end; - case_ast_node(rs, RangeStmt, node); - ssa_emit_comment(proc, str_lit("RangeStmt")); + case_ast_node(rs, ForStmt, node); + ssa_emit_comment(proc, str_lit("ForStmt")); Type *val_type = NULL; Type *idx_type = NULL; diff --git a/src/ssa_opt.c b/src/ssa_opt.c index 42ce830c9..7db5b1b89 100644 --- a/src/ssa_opt.c +++ b/src/ssa_opt.c @@ -90,7 +90,6 @@ void ssa_opt_add_operands(ssaValueArray *ops, ssaInstr *i) { case ssaInstr_SliceBoundsCheck: array_add(ops, i->SliceBoundsCheck.low); array_add(ops, i->SliceBoundsCheck.high); - array_add(ops, i->SliceBoundsCheck.max); break; } } diff --git a/src/ssa_print.c b/src/ssa_print.c index 81842e72a..41f8551a7 100644 --- a/src/ssa_print.c +++ b/src/ssa_print.c @@ -1225,13 +1225,6 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) { ssa_fprintf(f, " "); ssa_print_value(f, m, bc->high, t_int); - if (!bc->is_substring) { - ssa_fprintf(f, ", "); - ssa_print_type(f, m, t_int); - ssa_fprintf(f, " "); - ssa_print_value(f, m, bc->max, t_int); - } - ssa_fprintf(f, ")\n"); } break; diff --git a/src/tokenizer.c b/src/tokenizer.c index b5f46bcd7..715c759db 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -53,8 +53,6 @@ TOKEN_KIND(Token__AssignOpBegin, "_AssignOpBegin"), \ TOKEN_KIND(Token_CmpAndEq, "&&="), \ TOKEN_KIND(Token_CmpOrEq, "||="), \ TOKEN_KIND(Token__AssignOpEnd, "_AssignOpEnd"), \ - TOKEN_KIND(Token_Increment, "++"), \ - TOKEN_KIND(Token_Decrement, "--"), \ TOKEN_KIND(Token_ArrowRight, "->"), \ TOKEN_KIND(Token_ArrowLeft, "<-"), \ \ @@ -77,7 +75,7 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \ TOKEN_KIND(Token_Semicolon, ";"), \ TOKEN_KIND(Token_Period, "."), \ TOKEN_KIND(Token_Comma, ","), \ - TOKEN_KIND(Token_Ellipsis, ".."), \ + TOKEN_KIND(Token_Ellipsis, "..."), \ TOKEN_KIND(Token_Interval, "..<"), \ TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \ \ @@ -94,6 +92,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ TOKEN_KIND(Token_then, "then"), \ TOKEN_KIND(Token_if, "if"), \ TOKEN_KIND(Token_else, "else"), \ + TOKEN_KIND(Token_while, "while"), \ TOKEN_KIND(Token_for, "for"), \ TOKEN_KIND(Token_when, "when"), \ TOKEN_KIND(Token_range, "range"), \ @@ -837,8 +836,10 @@ Token tokenizer_get_token(Tokenizer *t) { token = scan_number_to_token(t, true); } else if (t->curr_rune == '.') { // Could be an ellipsis advance_to_next_rune(t); - token.kind = Token_Ellipsis; - if (t->curr_rune == '<') { + if (t->curr_rune == '.') { + advance_to_next_rune(t); + token.kind = Token_Ellipsis; + } else if (t->curr_rune == '<') { advance_to_next_rune(t); token.kind = Token_Interval; } @@ -891,10 +892,10 @@ Token tokenizer_get_token(Tokenizer *t) { case '~': token.kind = token_kind_variant2(t, Token_Xor, Token_XorEq); break; case '!': token.kind = token_kind_variant2(t, Token_Not, Token_NotEq); break; case '+': - token.kind = token_kind_variant3(t, Token_Add, Token_AddEq, '+', Token_Increment); + token.kind = token_kind_variant2(t, Token_Add, Token_AddEq); break; case '-': - token.kind = token_kind_variant4(t, Token_Sub, Token_SubEq, '-', Token_Decrement, '>', Token_ArrowRight); + token.kind = token_kind_variant3(t, Token_Sub, Token_SubEq, '>', Token_ArrowRight); break; case '/': { if (t->curr_rune == '/') {