diff --git a/core/_preload.odin b/core/_preload.odin index 9f790ca51..1f539b490 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -74,8 +74,8 @@ Type_Info_Tuple :: struct #ordered { // Only really used for procedures Type_Info_Struct :: struct #ordered { types: []^Type_Info, names: []string, - offsets: []int, // offsets may not be used in tuples - usings: []bool, // usings may not be used in tuples + offsets: []uintptr, // offsets may not be used in tuples + usings: []bool, // usings may not be used in tuples is_packed: bool, is_ordered: bool, is_raw_union: bool, @@ -83,7 +83,7 @@ Type_Info_Struct :: struct #ordered { }; Type_Info_Union :: struct #ordered { variants: []^Type_Info, - tag_offset: int, + tag_offset: uintptr, tag_type: ^Type_Info, }; Type_Info_Enum :: struct #ordered { @@ -136,7 +136,7 @@ Type_Info :: struct #ordered { __type_table: []Type_Info; __argc__: i32; -__argv__: ^^u8; +__argv__: ^^byte; // IMPORTANT NOTE(bill): Must be in this order (as the compiler relies upon it) @@ -149,7 +149,7 @@ Source_Code_Location :: struct #ordered { -Allocator_Mode :: enum u8 { +Allocator_Mode :: enum byte { Alloc, Free, FreeAll, @@ -327,23 +327,6 @@ copy :: proc "contextless" (dst, src: $T/[]$E) -> int { } -append :: proc "contextless" (array: ^$T/[]$E, args: ...E) -> int { - if array == nil do return 0; - - arg_len := len(args); - if arg_len <= 0 do return len(array); - - arg_len = min(cap(array)-len(array), arg_len); - if arg_len > 0 { - s := cast(^raw.Slice)array; - data := cast(^E)s.data; - assert(data != nil); - __mem_copy(data + s.len, &args[0], size_of(E)*arg_len); - s.len += arg_len; - } - return len(array); -} - append :: proc(array: ^$T/[dynamic]$E, args: ...E, loc := #caller_location) -> int { if array == nil do return 0; @@ -366,12 +349,6 @@ append :: proc(array: ^$T/[dynamic]$E, args: ...E, loc := #caller_location) -> i return len(array); } -append_string :: proc(array: ^$T/[]u8, args: ...string) -> int { - for arg in args { - append(array, ...cast(T)arg); - } - return len(array); -} append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ...string, loc := #caller_location) -> int { for arg in args { append(array = array, args = cast([]E)arg, loc = loc); @@ -691,16 +668,24 @@ __bounds_check_error :: proc "contextless" (file: string, line, column: int, ind __debug_trap(); } -__slice_expr_error :: proc "contextless" (file: string, line, column: int, low, high, max: int) { +__slice_expr_error :: proc "contextless" (file: string, line, column: int, low, high: int) { + if 0 <= low && low <= high do return; + fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: %d..%d\n", + file, line, column, low, high); + __debug_trap(); +} + +__dynamic_array_expr_error :: proc "contextless" (file: string, line, column: int, low, high, max: int) { 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 "contextless" (file: string, line, column: int, low, high: int) { 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(); } @@ -718,8 +703,8 @@ __string_decode_rune :: inline proc "contextless" (s: string) -> (rune, int) { __bounds_check_error_loc :: inline proc "contextless" (using loc := #caller_location, index, count: int) { __bounds_check_error(file_path, int(line), int(column), index, count); } -__slice_expr_error_loc :: inline proc "contextless" (using loc := #caller_location, low, high, max: int) { - __slice_expr_error(file_path, int(line), int(column), low, high, max); +__slice_expr_error_loc :: inline proc "contextless" (using loc := #caller_location, low, high: int) { + __slice_expr_error(file_path, int(line), int(column), low, high); } __substring_expr_error_loc :: inline proc "contextless" (using loc := #caller_location, low, high: int) { __substring_expr_error(file_path, int(line), int(column), low, high); @@ -730,13 +715,13 @@ __mem_set :: proc "contextless" (data: rawptr, value: i32, len: int) -> rawptr { foreign __llvm_core { when size_of(rawptr) == 8 { @(link_name="llvm.memset.p0i8.i64") - llvm_memset :: proc(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) ---; + llvm_memset :: proc(dst: rawptr, val: byte, len: int, align: i32, is_volatile: bool) ---; } else { @(link_name="llvm.memset.p0i8.i32") - llvm_memset :: proc(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) ---; + llvm_memset :: proc(dst: rawptr, val: byte, len: int, align: i32, is_volatile: bool) ---; } } - llvm_memset(data, u8(value), len, 1, false); + llvm_memset(data, byte(value), len, 1, false); return data; } __mem_zero :: proc "contextless" (data: rawptr, len: int) -> rawptr { @@ -773,7 +758,7 @@ __mem_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> return dst; } -__mem_compare :: proc "contextless" (a, b: ^u8, n: int) -> int { +__mem_compare :: proc "contextless" (a, b: ^byte, n: int) -> int { for i in 0..n do switch { case (a+i)^ < (b+i)^: return -1; case (a+i)^ > (b+i)^: return +1; @@ -867,7 +852,7 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int, // TODO(bill): Better error handling for failed reservation if !ok do return array.len; - data := cast(^u8)array.data; + data := cast(^byte)array.data; assert(data != nil); __mem_copy(data + (elem_size*array.len), items, elem_size * item_count); array.len += item_count; @@ -885,7 +870,7 @@ __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: in // TODO(bill): Better error handling for failed reservation if !ok do return array.len; - data := cast(^u8)array.data; + data := cast(^byte)array.data; assert(data != nil); __mem_zero(data + (elem_size*array.len), elem_size); array.len += 1; @@ -894,8 +879,8 @@ __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: in // Map stuff -__default_hash :: proc(data: []u8) -> u128 { - fnv128a :: proc(data: []u8) -> u128 { +__default_hash :: proc(data: []byte) -> u128 { + fnv128a :: proc(data: []byte) -> u128 { h: u128 = 0x6c62272e07bb014262b821756295c58d; for b in data { h = (h ~ u128(b)) * 0x1000000000000000000013b; @@ -904,7 +889,7 @@ __default_hash :: proc(data: []u8) -> u128 { } return fnv128a(data); } -__default_hash_string :: proc(s: string) -> u128 do return __default_hash(cast([]u8)s); +__default_hash_string :: proc(s: string) -> u128 do return __default_hash(cast([]byte)s); __dynamic_map_reserve :: proc(using header: __Map_Header, cap: int, loc := #caller_location) { __dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap, loc); @@ -927,7 +912,7 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int, loc := if len(nm.hashes) == 0 do __dynamic_map_grow(new_header, loc); entry_header := __dynamic_map_get_entry(header, i); - data := cast(^u8)entry_header; + data := cast(^byte)entry_header; fr := __dynamic_map_find(new_header, entry_header.key); j := __dynamic_map_add_entry(new_header, entry_header.key, loc); @@ -940,7 +925,7 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int, loc := e := __dynamic_map_get_entry(new_header, j); e.next = fr.entry_index; - ndata := cast(^u8)e; + ndata := cast(^byte)e; __mem_copy(ndata+value_offset, data+value_offset, value_size); if __dynamic_map_full(new_header) do __dynamic_map_grow(new_header, loc); @@ -953,7 +938,7 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int, loc := __dynamic_map_get :: proc(h: __Map_Header, key: __Map_Key) -> rawptr { index := __dynamic_map_find(h, key).entry_index; if index >= 0 { - data := cast(^u8)__dynamic_map_get_entry(h, index); + data := cast(^byte)__dynamic_map_get_entry(h, index); return data + h.value_offset; } return nil; @@ -983,7 +968,7 @@ __dynamic_map_set :: proc(using h: __Map_Header, key: __Map_Key, value: rawptr, { e := __dynamic_map_get_entry(h, index); e.key = key; - val := cast(^u8)e + value_offset; + val := cast(^byte)e + value_offset; __mem_copy(val, value, value_size); } @@ -1045,7 +1030,7 @@ __dynamic_map_delete :: proc(using h: __Map_Header, key: __Map_Key) { } __dynamic_map_get_entry :: proc(using h: __Map_Header, index: int) -> ^__Map_Entry_Header { - return cast(^__Map_Entry_Header)(cast(^u8)m.entries.data + index*entry_size); + return cast(^__Map_Entry_Header)(cast(^byte)m.entries.data + index*entry_size); } __dynamic_map_erase :: proc(using h: __Map_Header, fr: __Map_Find_Result) { diff --git a/core/decimal.odin b/core/decimal.odin index 7a88ab490..7d324ddcc 100644 --- a/core/decimal.odin +++ b/core/decimal.odin @@ -2,14 +2,14 @@ // NOTE: This is only for floating point printing and nothing else Decimal :: struct { - digits: [384]u8, // big-endian digits + digits: [384]byte, // big-endian digits count: int, decimal_point: int, neg, trunc: bool, } -decimal_to_string :: proc(buf: []u8, a: ^Decimal) -> string { - digit_zero :: proc(buf: []u8) -> int { +decimal_to_string :: proc(buf: []byte, a: ^Decimal) -> string { + digit_zero :: proc(buf: []byte) -> int { for _, i in buf do buf[i] = '0'; return len(buf); } @@ -56,12 +56,12 @@ trim :: proc(a: ^Decimal) { assign :: proc(a: ^Decimal, i: u64) { - buf: [64]u8; + buf: [64]byte; n := 0; for i > 0 { j := i/10; i -= 10*j; - buf[n] = u8('0'+i); + buf[n] = byte('0'+i); n += 1; i = j; } @@ -106,7 +106,7 @@ shift_right :: proc(a: ^Decimal, k: uint) { c := uint(a.digits[r]); dig := n>>k; n &= mask; - a.digits[w] = u8('0' + dig); + a.digits[w] = byte('0' + dig); w += 1; n = n*10 + c - '0'; } @@ -115,7 +115,7 @@ shift_right :: proc(a: ^Decimal, k: uint) { dig := n>>k; n &= mask; if w < len(a.digits) { - a.digits[w] = u8('0' + dig); + a.digits[w] = byte('0' + dig); w += 1; } else if dig > 0 { a.trunc = true; @@ -141,7 +141,7 @@ shift_left :: proc(a: ^Decimal, k: uint) { rem := n - 10*quo; w -= 1; if w < len(a.digits) { - a.digits[w] = u8('0' + rem); + a.digits[w] = byte('0' + rem); } else if rem != 0 { a.trunc = true; } @@ -153,7 +153,7 @@ shift_left :: proc(a: ^Decimal, k: uint) { rem := n - 10*quo; w -= 1; if 0 <= w && w < len(a.digits) { - a.digits[w] = u8('0' + rem); + a.digits[w] = byte('0' + rem); } else if rem != 0 { a.trunc = true; } diff --git a/core/fmt.odin b/core/fmt.odin index 78465cbe0..b68dacf12 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -8,10 +8,7 @@ import "core:raw.odin" _BUFFER_SIZE :: 1<<12; -String_Buffer :: union { - []u8, - [dynamic]u8, -} +String_Buffer :: [dynamic]byte; Fmt_Info :: struct { minus: bool, @@ -33,45 +30,34 @@ Fmt_Info :: struct { arg: any, // Temporary } +string_buffer_from_slice :: proc(backing: []byte) -> String_Buffer { + s := transmute(raw.Slice)backing; + d: raw.Dynamic_Array; + d.data = s.data; + d.len = 0; + d.cap = s.len; + d.allocator = nil_allocator(); + return transmute(String_Buffer)d; +} -string_buffer_data :: proc(buf: ^String_Buffer) -> []u8 { - switch b in buf { - case []u8: return b[..]; - case [dynamic]u8: return b[..]; - } - return nil; -} -string_buffer_data :: proc(buf: String_Buffer) -> []u8 { - switch b in buf { - case []u8: return b[..]; - case [dynamic]u8: return b[..]; - } - return nil; -} to_string :: proc(buf: String_Buffer) -> string { - return string(string_buffer_data(buf)); + return string(buf[..]); } write_string :: proc(buf: ^String_Buffer, s: string) { - write_bytes(buf, cast([]u8)s); + append_string(buf, s); } -write_bytes :: proc(buf: ^String_Buffer, data: []u8) { - switch b in buf { - case []u8: append(b, ...data); - case [dynamic]u8: append(b, ...data); - } +write_bytes :: proc(buf: ^String_Buffer, data: []byte) { + append(buf, ...data); } -write_byte :: proc(buf: ^String_Buffer, data: u8) { - switch b in buf { - case []u8: append(b, data); - case [dynamic]u8: append(b, data); - } +write_byte :: proc(buf: ^String_Buffer, data: byte) { + append(buf, data); } write_rune :: proc(buf: ^String_Buffer, r: rune) { if r < utf8.RUNE_SELF { - write_byte(buf, u8(r)); + write_byte(buf, byte(r)); return; } @@ -80,41 +66,36 @@ write_rune :: proc(buf: ^String_Buffer, r: rune) { } write_int :: proc(buf: ^String_Buffer, i: i128, base: int) { - b: [129]u8; - s := strconv.append_bits(b[..0], u128(i), base, true, 128, strconv.digits, 0); + b: [129]byte; + s := strconv.append_bits(b[..], u128(i), base, true, 128, strconv.digits, 0); write_string(buf, s); } write_int :: proc(buf: ^String_Buffer, i: i64, base: int) { - b: [129]u8; - s := strconv.append_bits(b[..0], u128(i), base, true, 64, strconv.digits, 0); + b: [129]byte; + s := strconv.append_bits(b[..], u128(i), base, true, 64, strconv.digits, 0); write_string(buf, s); } - - fprint :: proc(fd: os.Handle, args: ...any) -> int { - data: [_BUFFER_SIZE]u8; - buf := String_Buffer(data[..0]); - sbprint(&buf, ...args); - res := string_buffer_data(buf); - os.write(fd, res); + data: [_BUFFER_SIZE]byte; + buf := string_buffer_from_slice(data[..]); + res := sbprint(&buf, ...args); + os.write_string(fd, res); return len(res); } fprintln :: proc(fd: os.Handle, args: ...any) -> int { - data: [_BUFFER_SIZE]u8; - buf := String_Buffer(data[..0]); - sbprintln(&buf, ...args); - res := string_buffer_data(buf); - os.write(fd, res); + data: [_BUFFER_SIZE]byte; + buf := string_buffer_from_slice(data[..]); + res := sbprintln(&buf, ...args); + os.write_string(fd, res); return len(res); } fprintf :: proc(fd: os.Handle, fmt: string, args: ...any) -> int { - data: [_BUFFER_SIZE]u8; - buf := String_Buffer(data[..0]); - sbprintf(&buf, fmt, ...args); - res := string_buffer_data(buf); - os.write(fd, res); + data: [_BUFFER_SIZE]byte; + buf := string_buffer_from_slice(data[..]); + res := sbprintf(&buf, fmt, ...args); + os.write_string(fd, res); return len(res); } @@ -131,33 +112,33 @@ printf_err :: proc(fmt: string, args: ...any) -> int { return fprintf(os.stderr // aprint* procedures return a string that was allocated with the current context // They must be freed accordingly aprint :: proc(args: ...any) -> string { - buf := String_Buffer(make([dynamic]u8)); + buf := String_Buffer(make([dynamic]byte)); sbprint(&buf, ...args); return to_string(buf); } aprintln :: proc(args: ...any) -> string { - buf := String_Buffer(make([dynamic]u8)); + buf := String_Buffer(make([dynamic]byte)); sbprintln(&buf, ...args); return to_string(buf); } aprintf :: proc(fmt: string, args: ...any) -> string { - buf := String_Buffer(make([dynamic]u8)); + buf := String_Buffer(make([dynamic]byte)); sbprintf(&buf, fmt, ...args); return to_string(buf); } // bprint* procedures return a string using a buffer from an array -bprint :: proc(buf: []u8, args: ...any) -> string { - sb := String_Buffer(buf[..0..len(buf)]); +bprint :: proc(buf: []byte, args: ...any) -> string { + sb := string_buffer_from_slice(buf[0..len(buf)]); return sbprint(&sb, ...args); } -bprintln :: proc(buf: []u8, args: ...any) -> string { - sb := String_Buffer(buf[..0..len(buf)]); +bprintln :: proc(buf: []byte, args: ...any) -> string { + sb := string_buffer_from_slice(buf[0..len(buf)]); return sbprintln(&sb, ...args); } -bprintf :: proc(buf: []u8, fmt: string, args: ...any) -> string { - sb := String_Buffer(buf[..0..len(buf)]); +bprintf :: proc(buf: []byte, fmt: string, args: ...any) -> string { + sb := string_buffer_from_slice(buf[0..len(buf)]); return sbprintf(&sb, fmt, ...args); } @@ -167,10 +148,10 @@ bprintf :: proc(buf: []u8, fmt: string, args: ...any) -> string { fprint_type :: proc(fd: os.Handle, info: ^Type_Info) { - data: [_BUFFER_SIZE]u8; - buf := String_Buffer(data[..0]); + data: [_BUFFER_SIZE]byte; + buf := string_buffer_from_slice(data[..]); write_type(&buf, info); - os.write(fd, string_buffer_data(buf)); + os.write(fd, buf[..]); } write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { @@ -438,7 +419,7 @@ fmt_bool :: proc(using fi: ^Fmt_Info, b: bool, verb: rune) { fmt_write_padding :: proc(fi: ^Fmt_Info, width: int) { if width <= 0 do return; - pad_byte: u8 = '0'; + pad_byte: byte = '0'; if fi.space do pad_byte = ' '; for _ in 0..width { @@ -483,17 +464,17 @@ _fmt_int :: proc(fi: ^Fmt_Info, u: u128, base: int, is_signed: bool, bit_size: i panic("_fmt_int: unknown base, whoops"); } - buf: [256]u8; + buf: [256]byte; start := 0; flags: strconv.Int_Flag; if fi.hash && !fi.zero do flags |= strconv.Int_Flag.Prefix; if fi.plus do flags |= strconv.Int_Flag.Plus; if fi.space do flags |= strconv.Int_Flag.Space; - s := strconv.append_bits(buf[start..start], u128(u), base, is_signed, bit_size, digits, flags); + s := strconv.append_bits(buf[start..], u128(u), base, is_signed, bit_size, digits, flags); if fi.hash && fi.zero { - c: u8; + c: byte; switch base { case 2: c = 'b'; case 8: c = 'o'; @@ -576,9 +557,9 @@ fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) { case 'f', 'F', 'v': prec: int = 3; if fi.prec_set do prec = fi.prec; - buf: [386]u8; + buf: [386]byte; - str := strconv.append_float(buf[1..1], v, 'f', prec, bit_size); + str := strconv.append_float(buf[1..], v, 'f', prec, bit_size); str = string(buf[...len(str)]); if str[1] == '+' || str[1] == '-' { str = str[1..]; @@ -752,7 +733,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { write_string(fi.buf, info.name); write_string(fi.buf, "{}"); return; - } + }; write_string(fi.buf, info.name); write_byte(fi.buf, '{'); @@ -774,7 +755,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { if t := b.types[i]; types.is_any(t) { write_string(fi.buf, "any{}"); } else { - data := cast(^u8)v.data + b.offsets[i]; + data := uintptr(v.data) + b.offsets[i]; fmt_arg(fi, any{rawptr(data), t}, 'v'); } @@ -797,9 +778,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { case Type_Info_Pointer: if v.type_info == type_info_of(^Type_Info) { - write_type(fi.buf, (cast(^^Type_Info)v.data)^); + write_type(fi.buf, (^^Type_Info)(v.data)^); } else { - fmt_pointer(fi, (cast(^rawptr)v.data)^, verb); + fmt_pointer(fi, (^rawptr)(v.data)^, verb); } case Type_Info_Array: @@ -808,7 +789,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { for i in 0..info.count { if i > 0 do write_string(fi.buf, ", "); - data := cast(^u8)v.data + i*info.elem_size; + data := uintptr(v.data) + uintptr(i*info.elem_size); fmt_arg(fi, any{rawptr(data), info.elem}, verb); } @@ -819,18 +800,18 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { for i in 0..array.len { if i > 0 do write_string(fi.buf, ", "); - data := cast(^u8)array.data + i*info.elem_size; + data := uintptr(array.data) + uintptr(i*info.elem_size); fmt_arg(fi, any{rawptr(data), info.elem}, verb); } case Type_Info_Slice: write_byte(fi.buf, '['); defer write_byte(fi.buf, ']'); - slice := cast(^[]u8)v.data; - for _, i in slice { + slice := cast(^raw.Slice)v.data; + for i in 0..slice.len { if i > 0 do write_string(fi.buf, ", "); - data := &slice[0] + i*info.elem_size; + data := uintptr(slice.data) + uintptr(i*info.elem_size); fmt_arg(fi, any{rawptr(data), info.elem}, verb); } @@ -841,7 +822,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { for i in 0..info.count { if i > 0 do write_string(fi.buf, ", "); - data := cast(^u8)v.data + i*info.elem_size; + data := uintptr(v.data) + uintptr(i*info.elem_size); fmt_value(fi, any{rawptr(data), info.elem}, verb); } @@ -863,7 +844,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { for i in 0..entries.len { if i > 0 do write_string(fi.buf, ", "); - data := cast(^u8)entries.data + i*entry_size; + data := uintptr(entries.data) + uintptr(i*entry_size); header := cast(^__Map_Entry_Header)data; if types.is_string(info.key) { @@ -912,16 +893,15 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { if t := info.types[i]; types.is_any(t) { write_string(fi.buf, "any{}"); } else { - data := cast(^u8)v.data + info.offsets[i]; + data := uintptr(v.data) + info.offsets[i]; fmt_arg(fi, any{rawptr(data), t}, 'v'); } if hash do write_string(fi.buf, ",\n"); } case Type_Info_Union: - data := cast(^u8)v.data; - tag_ptr := rawptr(data + info.tag_offset); - tag_any := any{tag_ptr, info.tag_type}; + tag_ptr := uintptr(v.data) + info.tag_offset; + tag_any := any{rawptr(tag_ptr), info.tag_type}; tag: i64 = -1; switch i in tag_any { @@ -938,11 +918,11 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { case: panic("Invalid union tag type"); } - if data == nil || tag <= 0 { + if v.data == nil || tag == 0 { write_string(fi.buf, "nil"); } else { ti := info.variants[tag-1]; - fmt_arg(fi, any{data, ti}, verb); + fmt_arg(fi, any{v.data, ti}, verb); } case Type_Info_Enum: @@ -951,7 +931,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { case Type_Info_Procedure: write_type(fi.buf, v.type_info); write_string(fi.buf, " @ "); - fmt_pointer(fi, (cast(^rawptr)v.data)^, 'p'); + fmt_pointer(fi, (^rawptr)(v.data)^, 'p'); } } @@ -972,14 +952,10 @@ fmt_complex :: proc(fi: ^Fmt_Info, c: complex128, bits: int, verb: rune) { } } -_u128_to_lo_hi :: proc(a: u128) -> (lo, hi: u64) { return u64(a), u64(a>>64); } -_i128_to_lo_hi :: proc(a: u128) -> (lo: u64 hi: i64) { return u64(a), i64(a>>64); } +_u128_to_lo_hi :: proc(a: u128) -> (lo, hi: u64) do return u64(a), u64(a>>64); +_i128_to_lo_hi :: proc(a: u128) -> (lo: u64 hi: i64) do return u64(a), i64(a>>64); -do_foo :: proc(fi: ^Fmt_Info, f: f64) { - fmt_string(fi, "Hellope$%!", 'v'); -} - fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) { if arg == nil { write_string(fi.buf, ""); diff --git a/core/hash.odin b/core/hash.odin index 37cb25ed5..6f3db8076 100644 --- a/core/hash.odin +++ b/core/hash.odin @@ -1,6 +1,6 @@ import "core:mem.odin" -adler32 :: proc(data: []u8) -> u32 { +adler32 :: proc(data: []byte) -> u32 { ADLER_CONST :: 65521; a, b: u32 = 1, 0; for x in data { @@ -10,14 +10,14 @@ adler32 :: proc(data: []u8) -> u32 { return (b << 16) | a; } -crc32 :: proc(data: []u8) -> u32 { +crc32 :: proc(data: []byte) -> u32 { result := ~u32(0); for b in data { result = result>>8 ~ _crc32_table[(result ~ u32(b)) & 0xff]; } return ~result; } -crc64 :: proc(data: []u8) -> u64 { +crc64 :: proc(data: []byte) -> u64 { result := ~u64(0); for b in data { result = result>>8 ~ _crc64_table[(result ~ u64(b)) & 0xff]; @@ -25,7 +25,7 @@ crc64 :: proc(data: []u8) -> u64 { return ~result; } -fnv32 :: proc(data: []u8) -> u32 { +fnv32 :: proc(data: []byte) -> u32 { h: u32 = 0x811c9dc5; for b in data { h = (h * 0x01000193) ~ u32(b); @@ -33,7 +33,7 @@ fnv32 :: proc(data: []u8) -> u32 { return h; } -fnv64 :: proc(data: []u8) -> u64 { +fnv64 :: proc(data: []byte) -> u64 { h: u64 = 0xcbf29ce484222325; for b in data { h = (h * 0x100000001b3) ~ u64(b); @@ -41,7 +41,7 @@ fnv64 :: proc(data: []u8) -> u64 { return h; } -fnv32a :: proc(data: []u8) -> u32 { +fnv32a :: proc(data: []byte) -> u32 { h: u32 = 0x811c9dc5; for b in data { h = (h ~ u32(b)) * 0x01000193; @@ -49,7 +49,7 @@ fnv32a :: proc(data: []u8) -> u32 { return h; } -fnv64a :: proc(data: []u8) -> u64 { +fnv64a :: proc(data: []byte) -> u64 { h: u64 = 0xcbf29ce484222325; for b in data { h = (h ~ u64(b)) * 0x100000001b3; @@ -57,7 +57,7 @@ fnv64a :: proc(data: []u8) -> u64 { return h; } -murmur32 :: proc(data: []u8) -> u32 { +murmur32 :: proc(data: []byte) -> u32 { c1_32: u32 : 0xcc9e2d51; c2_32: u32 : 0x1b873593; @@ -106,7 +106,7 @@ murmur32 :: proc(data: []u8) -> u32 { return h1; } -murmur64 :: proc(data: []u8) -> u64 { +murmur64 :: proc(data: []byte) -> u64 { SEED :: 0x9747b28c; when size_of(int) == 8 { diff --git a/core/mem.odin b/core/mem.odin index 6ec5fa596..4f2830d4e 100644 --- a/core/mem.odin +++ b/core/mem.odin @@ -18,37 +18,27 @@ copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr { copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr { return __mem_copy_non_overlapping(dst, src, len); } -compare :: proc "contextless" (a, b: []u8) -> int { +compare :: proc "contextless" (a, b: []byte) -> int { return __mem_compare(&a[0], &b[0], min(len(a), len(b))); } slice_ptr :: proc "contextless" (ptr: ^$T, len: int) -> []T { assert(len >= 0); - slice := raw.Slice{data = ptr, len = len, cap = len}; - return transmute([]T)slice; -} -slice_ptr :: proc "contextless" (ptr: ^$T, len, cap: int) -> []T { - assert(0 <= len && len <= cap); - slice := raw.Slice{data = ptr, len = len, cap = cap}; + slice := raw.Slice{data = ptr, len = len}; return transmute([]T)slice; } -slice_to_bytes :: proc "contextless" (slice: $E/[]$T) -> []u8 { +slice_to_bytes :: proc "contextless" (slice: $E/[]$T) -> []byte { s := transmute(raw.Slice)slice; s.len *= size_of(T); s.cap *= size_of(T); - return transmute([]u8)s; + return transmute([]byte)s; } -ptr_to_bytes :: proc "contextless" (ptr: ^$T, len := 1) -> []u8 { +ptr_to_bytes :: proc "contextless" (ptr: ^$T, len := 1) -> []byte { assert(len >= 0); - return transmute([]u8)raw.Slice{ptr, len*size_of(T), len*size_of(T)}; -} - -ptr_to_bytes :: proc "contextless" (ptr: ^$T, len, cap: int) -> []u8 { - assert(0 <= len && len <= cap); - return transmute([]u8)raw.Slice{ptr, len*size_of(T), cap*size_of(T)}; + return transmute([]byte)raw.Slice{ptr, len*size_of(T), len*size_of(T)}; } @@ -93,6 +83,17 @@ allocation_header :: proc(data: rawptr) -> ^AllocationHeader { } +Fixed_Byte_Buffer :: [dynamic]byte; + +make_fixed_byte_buffer :: proc(backing: []byte) -> Fixed_Byte_Buffer { + s := transmute(raw.Slice)backing; + d: raw.Dynamic_Array; + d.data = s.data; + d.len = 0; + d.cap = s.len; + d.allocator = nil_allocator(); + return transmute(Fixed_Byte_Buffer)d; +} @@ -100,7 +101,7 @@ allocation_header :: proc(data: rawptr) -> ^AllocationHeader { Arena :: struct { backing: Allocator, - memory: []u8, + memory: Fixed_Byte_Buffer, temp_count: int, } @@ -113,15 +114,15 @@ ArenaTempMemory :: struct { -init_arena_from_memory :: proc(using a: ^Arena, data: []u8) { +init_arena_from_memory :: proc(using a: ^Arena, data: []byte) { backing = Allocator{}; - memory = data[..0]; + memory = make_fixed_byte_buffer(data); temp_count = 0; } init_arena_from_context :: proc(using a: ^Arena, size: int) { backing = context.allocator; - memory = make([]u8, 0, size); + memory = make_fixed_byte_buffer(make([]byte, size)); temp_count = 0; } @@ -135,7 +136,9 @@ context_from_allocator :: proc(a: Allocator) -> Context { destroy_arena :: proc(using a: ^Arena) { if backing.procedure != nil { context <- context_from_allocator(backing) { - free(memory); + if memory != nil { + free(&memory[0]); + } memory = nil; } } @@ -194,7 +197,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[..original_count]; + (^raw.Dynamic_Array)(&arena.memory).len = original_count; arena.temp_count -= 1; } diff --git a/core/os.odin b/core/os.odin index 1ed920a45..9b441c64a 100644 --- a/core/os.odin +++ b/core/os.odin @@ -6,10 +6,10 @@ when ODIN_OS == "essence" do export "core:os_essence.odin"; import "mem.odin"; write_string :: proc(fd: Handle, str: string) -> (int, Errno) { - return write(fd, cast([]u8)str); + return write(fd, cast([]byte)str); } -read_entire_file :: proc(name: string) -> (data: []u8, success: bool) { +read_entire_file :: proc(name: string) -> (data: []byte, success: bool) { fd, err := open(name, O_RDONLY, 0); if err != 0 { return nil, false; @@ -25,7 +25,7 @@ read_entire_file :: proc(name: string) -> (data: []u8, success: bool) { return nil, true; } - data := make([]u8, int(length)); + data := make([]byte, int(length)); if data == nil { return nil, false; } @@ -38,7 +38,7 @@ read_entire_file :: proc(name: string) -> (data: []u8, success: bool) { return data[0..bytes_read], true; } -write_entire_file :: proc(name: string, data: []u8, truncate := true) -> (success: bool) { +write_entire_file :: proc(name: string, data: []byte, truncate := true) -> (success: bool) { flags: int = O_WRONLY|O_CREATE; if truncate { flags |= O_TRUNC; @@ -54,9 +54,9 @@ write_entire_file :: proc(name: string, data: []u8, truncate := true) -> (succes } write :: proc(fd: Handle, data: rawptr, len: int) -> (int, Errno) { - return write(fd, mem.slice_ptr(cast(^u8)data, len)); + return write(fd, mem.slice_ptr(cast(^byte)data, len)); } read :: proc(fd: Handle, data: rawptr, len: int) -> (int, Errno) { - return read(fd, mem.slice_ptr(cast(^u8)data, len)); + return read(fd, mem.slice_ptr(cast(^byte)data, len)); } diff --git a/core/os_essence.odin b/core/os_essence.odin index b6670850f..d35e313e8 100644 --- a/core/os_essence.odin +++ b/core/os_essence.odin @@ -14,35 +14,35 @@ OS_Node_Type :: enum i32 { } OS_Node_Information :: struct #ordered { - handle: Handle, - id: [16]u8, - ntype: OS_Node_Type, - size: i64, + handle: Handle, + id: [16]byte, + ntype: OS_Node_Type, + size: i64, position: i64, } foreign api { - @(link_name="OSHelloWorld") os_hello_world :: proc() ---; - @(link_name="OSPrintDirect") os_print_direct :: proc(string: ^u8, length: int) ---; - @(link_name="OSHeapAllocate") os_heap_allocate :: proc(bytes: int, zero: bool) -> rawptr ---; - @(link_name="OSHeapFree") os_heap_free :: proc(address: rawptr) ---; - @(link_name="OSOpenNode") os_open_node :: proc(path: ^u8, path_length: int, flags: u64, information: ^OS_Node_Information) -> Errno ---; - @(link_name="OSResizeFile") os_resize_file :: proc(handle: Handle, new_size: u64) -> Errno ---; - @(link_name="OSCloseHandle") os_close_handle :: proc(handle: Handle) ---; - @(link_name="OSWriteFileSync") os_write_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---; - @(link_name="OSReadFileSync") os_read_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---; - @(link_name="OSInitialiseAPI") os_initialise_api :: proc() -> int ---; - @(link_name="OSTerminateProcess") os_terminate_process :: proc(handle: Handle) ---; - @(link_name="realloc") os_heap_reallocate :: proc(address: rawptr, size: int) -> rawptr ---; + @(link_name="OSHelloWorld") os_hello_world :: proc() ---; + @(link_name="OSPrintDirect") os_print_direct :: proc(string: ^byte, length: int) ---; + @(link_name="OSHeapAllocate") os_heap_allocate :: proc(bytes: int, zero: bool) -> rawptr ---; + @(link_name="OSHeapFree") os_heap_free :: proc(address: rawptr) ---; + @(link_name="OSOpenNode") os_open_node :: proc(path: ^byte, path_length: int, flags: u64, information: ^OS_Node_Information) -> Errno ---; + @(link_name="OSResizeFile") os_resize_file :: proc(handle: Handle, new_size: u64) -> Errno ---; + @(link_name="OSCloseHandle") os_close_handle :: proc(handle: Handle) ---; + @(link_name="OSWriteFileSync") os_write_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---; + @(link_name="OSReadFileSync") os_read_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---; + @(link_name="OSInitialiseAPI") os_initialise_api :: proc() -> int ---; + @(link_name="OSTerminateProcess") os_terminate_process :: proc(handle: Handle) ---; + @(link_name="realloc") os_heap_reallocate :: proc(address: rawptr, size: int) -> rawptr ---; } -stdin := cast(Handle) -1; // Not implemented -stdout := cast(Handle) 0; -stderr := cast(Handle) 0; +stdin := Handle(-1); // Not implemented +stdout := Handle(0); +stderr := Handle(0); current_thread_id :: proc() -> int { // Not implemented - return int(-1); + return -1; } heap_alloc :: proc(size: int) -> rawptr { @@ -59,55 +59,53 @@ heap_resize :: proc(address: rawptr, new_size: int) -> rawptr { open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno) { information := new(OS_Node_Information); - error := os_open_node(&path[0], len(path), cast(u64) mode, information); - if (error < -1) { return 0,1; } + error := os_open_node(&path[0], len(path), u64(mode), information); + if error < -1 do return 0, 1; information.position = 0; - if (mode&O_TRUNC==O_TRUNC) { + if mode&O_TRUNC==O_TRUNC { error := os_resize_file(information.handle, 0); - if (error < -1) { return 0,1; } + if error < -1 do return 0, 1; } - return cast(Handle) cast(uintptr) information,0; + return Handle(uintptr(information)), 0; } close :: proc(fd: Handle) { - information := cast(^OS_Node_Information) cast(uintptr) fd; + information := (^OS_Node_Information)(uintptr(fd)); os_close_handle(information.handle); free(information); } file_size :: proc(fd: Handle) -> (i64, Errno) { // Not (properly) implemented - information := cast(^OS_Node_Information) cast(uintptr) fd; + information := cast(^OS_Node_Information)uintptr(fd); return information.size,0; } -write :: proc(fd: Handle, data: []u8) -> (int, Errno) { - if (fd == 0) { +write :: proc(fd: Handle, data: []byte) -> (int, Errno) { + if fd == 0 { os_print_direct(&data[0], len(data)); return len(data), 0; - } else if (fd == 1) { + } else if fd == 1 { assert(false); return 0, 1; - } else { - information := cast(^OS_Node_Information) cast(uintptr) fd; - count := os_write_file_sync(information.handle, information.position, cast(i64) len(data), cast(rawptr) &data[0]); - if (count < 0) { return 0, 1; } - information.position += count; - return cast(int) count, 0; } + information := (^OS_Node_Information)(uintptr(fd)); + count := os_write_file_sync(information.handle, information.position, i64(len(data)), &data[0]); + if count < 0 do return 0, 1; + information.position += count; + return int(count), 0; } -read :: proc(fd: Handle, data: []u8) -> (int, Errno) { +read :: proc(fd: Handle, data: []byte) -> (int, Errno) { if (fd == 0 || fd == 1) { assert(false); return 0, 1; - } else { - information := cast(^OS_Node_Information) cast(uintptr) fd; - count := os_read_file_sync(information.handle, information.position, cast(i64) len(data), cast(rawptr) &data[0]); - if (count < 0) { return 0, 1; } - information.position += count; - return cast(int) count, 0; } + information := (^OS_Node_Information)(uintptr(fd)); + count := os_read_file_sync(information.handle, information.position, i64(len(data)), &data[0]); + if count < 0 do return 0, 1; + information.position += count; + return int(count), 0; } os_terminate_this_process :: proc() { diff --git a/core/os_linux.odin b/core/os_linux.odin index 1e9cdd48b..cf457c58f 100644 --- a/core/os_linux.odin +++ b/core/os_linux.odin @@ -122,28 +122,28 @@ W_OK :: 2; // Test for write permission R_OK :: 4; // Test for read permission foreign libc { - @(link_name="open") _unix_open :: proc(path: ^u8, mode: int) -> Handle ---; + @(link_name="open") _unix_open :: proc(path: ^byte, mode: int) -> Handle ---; @(link_name="close") _unix_close :: proc(fd: Handle) -> i32 ---; @(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: int) -> int ---; @(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: int) -> int ---; @(link_name="lseek64") _unix_seek :: proc(fd: Handle, offset: i64, whence: i32) -> i64 ---; @(link_name="gettid") _unix_gettid :: proc() -> u64 ---; - @(link_name="stat") _unix_stat :: proc(path: ^u8, stat: ^Stat) -> i32 ---; - @(link_name="access") _unix_access :: proc(path: ^u8, mask: int) -> i32 ---; + @(link_name="stat") _unix_stat :: proc(path: ^byte, stat: ^Stat) -> i32 ---; + @(link_name="access") _unix_access :: proc(path: ^byte, mask: int) -> i32 ---; @(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr ---; @(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr ---; @(link_name="free") _unix_free :: proc(ptr: rawptr) ---; @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr ---; - @(link_name="getenv") _unix_getenv :: proc(^u8) -> ^u8 ---; + @(link_name="getenv") _unix_getenv :: proc(^byte) -> ^byte ---; @(link_name="exit") _unix_exit :: proc(status: int) ---; } foreign dl { - @(link_name="dlopen") _unix_dlopen :: proc(filename: ^u8, flags: int) -> rawptr ---; - @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: ^u8) -> rawptr ---; + @(link_name="dlopen") _unix_dlopen :: proc(filename: ^byte, flags: int) -> rawptr ---; + @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: ^byte) -> rawptr ---; @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> int ---; - @(link_name="dlerror") _unix_dlerror :: proc() -> ^u8 ---; + @(link_name="dlerror") _unix_dlerror :: proc() -> ^byte ---; } // TODO(zangent): Change this to just `open` when Bill fixes overloading. @@ -166,12 +166,12 @@ close :: proc(fd: Handle) { _unix_close(fd); } -read :: proc(fd: Handle, data: []u8) -> (int, Errno) { +read :: proc(fd: Handle, data: []byte) -> (int, Errno) { sz := _unix_read(fd, &data[0], len(data)); return sz, 0; } -write :: proc(fd: Handle, data: []u8) -> (int, Errno) { +write :: proc(fd: Handle, data: []byte) -> (int, Errno) { sz := _unix_write(fd, &data[0], len(data)); return sz, 0; } @@ -201,9 +201,10 @@ last_write_time_by_name :: proc(name: string) -> File_Time {} */ stat :: inline proc(path: string) -> (Stat, int) { - s: Stat; cstr := strings.new_c_string(path); defer free(cstr); + + s: Stat; ret_int := _unix_stat(cstr, &s); return s, int(ret_int); } @@ -229,9 +230,9 @@ heap_free :: proc(ptr: rawptr) { getenv :: proc(name: string) -> (string, bool) { path_str := strings.new_c_string(name); - cstr: ^u8 = _unix_getenv(path_str); - free(path_str); - if(cstr == nil) { + defer free(path_str); + cstr := _unix_getenv(path_str); + if cstr == nil { return "", false; } return strings.to_odin_string(cstr), true; @@ -248,15 +249,15 @@ current_thread_id :: proc() -> int { dlopen :: inline proc(filename: string, flags: int) -> rawptr { cstr := strings.new_c_string(filename); + defer free(cstr); handle := _unix_dlopen(cstr, flags); - free(cstr); return handle; } dlsym :: inline proc(handle: rawptr, symbol: string) -> rawptr { assert(handle != nil); cstr := strings.new_c_string(symbol); + defer free(cstr); proc_handle := _unix_dlsym(handle, cstr); - free(cstr); return proc_handle; } dlclose :: inline proc(handle: rawptr) -> bool { diff --git a/core/os_windows.odin b/core/os_windows.odin index 0f9e539c6..b62cd7419 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -95,8 +95,8 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn create_mode = win32.OPEN_EXISTING; } - buf: [300]u8; - copy(buf[..], cast([]u8)path); + buf: [300]byte; + copy(buf[..], cast([]byte)path); handle := Handle(win32.create_file_a(&buf[0], access, share_mode, sa, create_mode, win32.FILE_ATTRIBUTE_NORMAL, nil)); if handle != INVALID_HANDLE do return handle, ERROR_NONE; @@ -110,7 +110,7 @@ close :: proc(fd: Handle) { } -write :: proc(fd: Handle, data: []u8) -> (int, Errno) { +write :: proc(fd: Handle, data: []byte) -> (int, Errno) { if len(data) == 0 do return 0, ERROR_NONE; single_write_length: i32; @@ -132,7 +132,7 @@ write :: proc(fd: Handle, data: []u8) -> (int, Errno) { return int(total_write), ERROR_NONE; } -read :: proc(fd: Handle, data: []u8) -> (int, Errno) { +read :: proc(fd: Handle, data: []byte) -> (int, Errno) { if len(data) == 0 do return 0, ERROR_NONE; single_read_length: i32; @@ -213,11 +213,11 @@ last_write_time :: proc(fd: Handle) -> File_Time { last_write_time_by_name :: proc(name: string) -> File_Time { last_write_time: win32.Filetime; data: win32.File_Attribute_Data; - buf: [1024]u8; + buf: [1024]byte; assert(len(buf) > len(name)); - copy(buf[..], cast([]u8)name); + copy(buf[..], cast([]byte)name); if win32.get_file_attributes_ex_a(&buf[0], win32.GetFileExInfoStandard, &data) != 0 { last_write_time = data.last_write_time; @@ -267,7 +267,7 @@ _alloc_command_line_arguments :: proc() -> []string { for (wstr+wstr_len)^ != 0 do wstr_len += 1; len := 2*wstr_len-1; - buf := make([]u8, len+1); + buf := make([]byte, len+1); str := mem.slice_ptr(wstr, wstr_len+1); i, j := 0, 0; @@ -275,28 +275,28 @@ _alloc_command_line_arguments :: proc() -> []string { switch { case str[j] < 0x80: if i+1 > len do return ""; - buf[i] = u8(str[j]); i += 1; + buf[i] = byte(str[j]); i += 1; j += 1; case str[j] < 0x800: if i+2 > len do return ""; - buf[i] = u8(0xc0 + (str[j]>>6)); i += 1; - buf[i] = u8(0x80 + (str[j]&0x3f)); i += 1; + buf[i] = byte(0xc0 + (str[j]>>6)); i += 1; + buf[i] = byte(0x80 + (str[j]&0x3f)); i += 1; j += 1; case 0xd800 <= str[j] && str[j] < 0xdc00: if i+4 > len do return ""; c := rune((str[j] - 0xd800) << 10) + rune((str[j+1]) - 0xdc00) + 0x10000; - buf[i] = u8(0xf0 + (c >> 18)); i += 1; - buf[i] = u8(0x80 + ((c >> 12) & 0x3f)); i += 1; - buf[i] = u8(0x80 + ((c >> 6) & 0x3f)); i += 1; - buf[i] = u8(0x80 + ((c ) & 0x3f)); i += 1; + buf[i] = byte(0xf0 + (c >> 18)); i += 1; + buf[i] = byte(0x80 + ((c >> 12) & 0x3f)); i += 1; + buf[i] = byte(0x80 + ((c >> 6) & 0x3f)); i += 1; + buf[i] = byte(0x80 + ((c ) & 0x3f)); i += 1; j += 2; case 0xdc00 <= str[j] && str[j] < 0xe000: return ""; case: if i+3 > len do return ""; - buf[i] = 0xe0 + u8 (str[j] >> 12); i += 1; - buf[i] = 0x80 + u8((str[j] >> 6) & 0x3f); i += 1; - buf[i] = 0x80 + u8((str[j] ) & 0x3f); i += 1; + buf[i] = 0xe0 + byte (str[j] >> 12); i += 1; + buf[i] = 0x80 + byte((str[j] >> 6) & 0x3f); i += 1; + buf[i] = 0x80 + byte((str[j] ) & 0x3f); i += 1; j += 1; } } diff --git a/core/os_x.odin b/core/os_x.odin index 776f5161e..4bdb2cd9a 100644 --- a/core/os_x.odin +++ b/core/os_x.odin @@ -122,38 +122,37 @@ X_OK :: 1; // Test for execute permission F_OK :: 0; // Test for file existance foreign libc { - @(link_name="open") _unix_open :: proc(path: ^u8, mode: int) -> Handle ---; + @(link_name="open") _unix_open :: proc(path: ^byte, mode: int) -> Handle ---; @(link_name="close") _unix_close :: proc(handle: Handle) ---; @(link_name="read") _unix_read :: proc(handle: Handle, buffer: rawptr, count: int) -> int ---; @(link_name="write") _unix_write :: proc(handle: Handle, buffer: rawptr, count: int) -> int ---; @(link_name="lseek") _unix_lseek :: proc(fs: Handle, offset: int, whence: int) -> int ---; @(link_name="gettid") _unix_gettid :: proc() -> u64 ---; - @(link_name="stat") _unix_stat :: proc(path: ^u8, stat: ^Stat) -> int ---; - @(link_name="access") _unix_access :: proc(path: ^u8, mask: int) -> int ---; + @(link_name="stat") _unix_stat :: proc(path: ^byte, stat: ^Stat) -> int ---; + @(link_name="access") _unix_access :: proc(path: ^byte, mask: int) -> int ---; @(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr ---; @(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr ---; @(link_name="free") _unix_free :: proc(ptr: rawptr) ---; @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr ---; - @(link_name="getenv") _unix_getenv :: proc(^u8) -> ^u8 ---; + @(link_name="getenv") _unix_getenv :: proc(^byte) -> ^byte ---; @(link_name="exit") _unix_exit :: proc(status: int) ---; } foreign dl { - @(link_name="dlopen") _unix_dlopen :: proc(filename: ^u8, flags: int) -> rawptr ---; - @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: ^u8) -> rawptr ---; + @(link_name="dlopen") _unix_dlopen :: proc(filename: ^byte, flags: int) -> rawptr ---; + @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: ^byte) -> rawptr ---; @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> int ---; - @(link_name="dlerror") _unix_dlerror :: proc() -> ^u8 ---; + @(link_name="dlerror") _unix_dlerror :: proc() -> ^byte ---; } // TODO(zangent): Change this to just `open` when Bill fixes overloading. open_simple :: proc(path: string, mode: int) -> (Handle, Errno) { - cstr := strings.new_c_string(path); + defer free(cstr); handle := _unix_open(cstr, mode); - free(cstr); - if(handle == -1) { + if handle == -1 { return 0, 1; } return handle, 0; @@ -182,7 +181,7 @@ read :: proc(fd: Handle, data: []u8) -> (int, Errno) { assert(fd != -1); bytes_read := _unix_read(fd, &data[0], len(data)); - if(bytes_read == -1) { + if bytes_read == -1 { return 0, 1; } return bytes_read, 0; @@ -192,7 +191,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { assert(fd != -1); final_offset := i64(_unix_lseek(fd, int(offset), whence)); - if(final_offset == -1) { + if final_offset == -1 { return 0, 1; } return final_offset, 0; @@ -244,9 +243,9 @@ heap_free :: inline proc(ptr: rawptr) { getenv :: proc(name: string) -> (string, bool) { path_str := strings.new_c_string(name); - cstr: ^u8 = _unix_getenv(path_str); - free(path_str); - if(cstr == nil) { + defer free(path_str); + cstr := _unix_getenv(path_str); + if cstr == nil { return "", false; } return strings.to_odin_string(cstr), true; @@ -258,21 +257,21 @@ exit :: inline proc(code: int) { current_thread_id :: proc() -> int { - // return cast(int) _unix_gettid(); + // return int(_unix_gettid()); return 0; } dlopen :: inline proc(filename: string, flags: int) -> rawptr { cstr := strings.new_c_string(filename); + defer free(cstr); handle := _unix_dlopen(cstr, flags); - free(cstr); return handle; } dlsym :: inline proc(handle: rawptr, symbol: string) -> rawptr { assert(handle != nil); cstr := strings.new_c_string(symbol); + defer free(cstr); proc_handle := _unix_dlsym(handle, cstr); - free(cstr); return proc_handle; } dlclose :: inline proc(handle: rawptr) -> bool { diff --git a/core/raw.odin b/core/raw.odin index ac6310915..d044e1114 100644 --- a/core/raw.odin +++ b/core/raw.odin @@ -11,7 +11,6 @@ String :: struct #ordered { Slice :: struct #ordered { data: rawptr, len: int, - cap: int, } Dynamic_Array :: struct #ordered { diff --git a/core/strconv.odin b/core/strconv.odin index aeffa4965..9aedb541d 100644 --- a/core/strconv.odin +++ b/core/strconv.odin @@ -185,21 +185,22 @@ parse_f64 :: proc(s: string) -> f64 { } -append_bool :: proc(buf: []u8, b: bool) -> string { - if b do append_string(&buf, "true"); - else do append_string(&buf, "false"); - return string(buf); +append_bool :: proc(buf: []byte, b: bool) -> string { + n := 0; + if b do n = copy(buf, cast([]byte)"true"); + else do n = copy(buf, cast([]byte)"false"); + return string(buf[..n]); } -append_uint :: proc(buf: []u8, u: u64, base: int) -> string { +append_uint :: proc(buf: []byte, u: u64, base: int) -> string { return append_bits(buf, u128(u), base, false, 8*size_of(uint), digits, 0); } -append_int :: proc(buf: []u8, i: i64, base: int) -> string { +append_int :: proc(buf: []byte, i: i64, base: int) -> string { return append_bits(buf, u128(i), base, true, 8*size_of(int), digits, 0); } -itoa :: proc(buf: []u8, i: int) -> string do return append_int(buf, i64(i), 10); +itoa :: proc(buf: []byte, i: int) -> string do return append_int(buf, i64(i), 10); -append_float :: proc(buf: []u8, f: f64, fmt: u8, prec, bit_size: int) -> string { +append_float :: proc(buf: []byte, f: f64, fmt: byte, prec, bit_size: int) -> string { return string(generic_ftoa(buf, f, fmt, prec, bit_size)); } @@ -207,7 +208,7 @@ append_float :: proc(buf: []u8, f: f64, fmt: u8, prec, bit_size: int) -> string DecimalSlice :: struct { - digits: []u8, + digits: []byte, count: int, decimal_point: int, neg: bool, @@ -225,7 +226,7 @@ _f32_info := FloatInfo{23, 8, -127}; _f64_info := FloatInfo{52, 11, -1023}; -generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 { +generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, prec, bit_size: int) -> []byte { bits: u64; flt: ^FloatInfo; switch bit_size { @@ -253,8 +254,8 @@ generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 } else { s = "+Inf"; } - append(&buf, ...cast([]u8)s); - return buf; + n := copy(buf, cast([]byte)s); + return buf[..n]; case 0: // denormalized exp += 1; @@ -297,48 +298,62 @@ generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 -format_digits :: proc(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice, prec: int, fmt: u8) -> []u8 { +format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: DecimalSlice, prec: int, fmt: byte) -> []byte { + Buffer :: struct { + b: []byte, + n: int, + } + + to_bytes :: proc(b: Buffer) -> []byte do return b.b[..b.n]; + add_bytes :: proc(buf: ^Buffer, bytes: ...byte) { + buf.n += copy(buf.b[buf.n..], bytes); + } + + b := Buffer{b = buf}; + switch fmt { case 'f', 'F': - append(&buf, neg ? '-' : '+'); + add_bytes(&b, neg ? '-' : '+'); // integer, padded with zeros when needed if digs.decimal_point > 0 { m := min(digs.count, digs.decimal_point); - append(&buf, ...digs.digits[0..m]); + add_bytes(&b, ...digs.digits[0..m]); for ; m < digs.decimal_point; m += 1 { - append(&buf, '0'); + add_bytes(&b, '0'); } } else { - append(&buf, '0'); + add_bytes(&b, '0'); } // fractional part if prec > 0 { - append(&buf, '.'); + add_bytes(&b, '.'); for i in 0..prec { - c: u8 = '0'; + c: byte = '0'; if j := digs.decimal_point + i; 0 <= j && j < digs.count { c = digs.digits[j]; } - append(&buf, c); + add_bytes(&b, c); } } - return buf; + return to_bytes(b); case 'e', 'E': panic("strconv: e/E float printing is not yet supported"); - return buf; // TODO + return to_bytes(b); // TODO case 'g', 'G': panic("strconv: g/G float printing is not yet supported"); - return buf; // TODO + return to_bytes(b); // TODO + + case: + add_bytes(&b, '%', fmt); + return to_bytes(b); } - c := [2]u8{'%', fmt}; - append(&buf, ...c[..]); - return buf; + } round_shortest :: proc(d: ^Decimal, mant: u64, exp: int, flt: ^FloatInfo) { @@ -379,12 +394,12 @@ round_shortest :: proc(d: ^Decimal, mant: u64, exp: int, flt: ^FloatInfo) { inclusive := mant%2 == 0; for i in 0..d.count { - l: u8 = '0'; // lower digit + l: byte = '0'; // lower digit if i < lower.count { l = lower.digits[i]; } m := d.digits[i]; // middle digit - u: u8 = '0'; // upper digit + u: byte = '0'; // upper digit if i < upper.count { u = upper.digits[i]; } @@ -443,13 +458,13 @@ is_integer_negative :: proc(u: u128, is_signed: bool, bit_size: int) -> (unsigne return u, neg; } -append_bits :: proc(buf: []u8, u: u128, base: int, is_signed: bool, bit_size: int, digits: string, flags: Int_Flag) -> string { +append_bits :: proc(buf: []byte, u: u128, base: int, is_signed: bool, bit_size: int, digits: string, flags: Int_Flag) -> string { if base < 2 || base > MAX_BASE { panic("strconv: illegal base passed to append_bits"); } neg: bool; - a: [129]u8; + a: [129]byte; i := len(a); u, neg = is_integer_negative(u, is_signed, bit_size); b := u128(base); @@ -474,15 +489,17 @@ append_bits :: proc(buf: []u8, u: u128, base: int, is_signed: bool, bit_size: in } } - if neg { + switch { + case neg: i-=1; a[i] = '-'; - } else if flags&Int_Flag.Plus != 0 { + case flags&Int_Flag.Plus != 0: i-=1; a[i] = '+'; - } else if flags&Int_Flag.Space != 0 { + case flags&Int_Flag.Space != 0: i-=1; a[i] = ' '; } - append(&buf, ...a[i..]); - return string(buf); + out := a[i..]; + copy(buf, out); + return string(buf[0..len(out)]); } diff --git a/core/sys/wgl.odin b/core/sys/wgl.odin index 4f8aa29e7..66ff838bc 100644 --- a/core/sys/wgl.odin +++ b/core/sys/wgl.odin @@ -55,7 +55,7 @@ Glyph_Metrics_Float :: struct { Create_Context_Attribs_ARB_Type :: #type proc "c" (hdc: Hdc, h_share_context: rawptr, attribList: ^i32) -> Hglrc; Choose_Pixel_Format_ARB_Type :: #type proc "c" (hdc: Hdc, attrib_i_list: ^i32, attrib_f_list: ^f32, max_formats: u32, formats: ^i32, num_formats : ^u32) -> Bool; Swap_Interval_EXT_Type :: #type proc "c" (interval: i32) -> bool; -Get_Extensions_String_ARB_Type :: #type proc "c" (Hdc) -> ^u8; +Get_Extensions_String_ARB_Type :: #type proc "c" (Hdc) -> ^byte; // Procedures create_context_attribs_arb: Create_Context_Attribs_ARB_Type; @@ -72,7 +72,7 @@ foreign opengl32 { make_current :: proc(hdc: Hdc, hglrc: Hglrc) -> Bool ---; @(link_name="wglGetProcAddress") - get_proc_address :: proc(c_str: ^u8) -> rawptr ---; + get_proc_address :: proc(c_str: ^byte) -> rawptr ---; @(link_name="wglDeleteContext") delete_context :: proc(hglrc: Hglrc) -> Bool ---; diff --git a/core/sys/windows.odin b/core/sys/windows.odin index 3d1b066c5..a1bf146f5 100644 --- a/core/sys/windows.odin +++ b/core/sys/windows.odin @@ -42,7 +42,7 @@ Wnd_Class_Ex_A :: struct #ordered { icon: Hicon, cursor: Hcursor, background: Hbrush, - menu_name, class_name: ^u8, + menu_name, class_name: ^byte, sm: Hicon, } @@ -116,8 +116,8 @@ Find_Data :: struct #ordered{ file_size_low: u32, reserved0: u32, reserved1: u32, - file_name: [MAX_PATH]u8, - alternate_file_name: [14]u8, + file_name: [MAX_PATH]byte, + alternate_file_name: [14]byte, } Security_Attributes :: struct #ordered { @@ -152,7 +152,7 @@ Pixel_Format_Descriptor :: struct #ordered { stencil_bits, aux_buffers, layer_type, - reserved: u8, + reserved: byte, layer_mask, visible_mask, @@ -201,7 +201,7 @@ Raw_Input_Header :: struct #ordered { Raw_HID :: struct #ordered { size_hid: u32, count: u32, - raw_data: [1]u8, + raw_data: [1]byte, } Raw_Keyboard :: struct #ordered { @@ -435,14 +435,14 @@ GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1; foreign kernel32 { @(link_name="GetLastError") get_last_error :: proc() -> i32 ---; @(link_name="ExitProcess") exit_process :: proc(exit_code: u32) ---; - @(link_name="GetModuleHandleA") get_module_handle_a :: proc(module_name: ^u8) -> Hinstance ---; + @(link_name="GetModuleHandleA") get_module_handle_a :: proc(module_name: ^byte) -> Hinstance ---; @(link_name="GetModuleHandleW") get_module_handle_w :: proc(module_name: ^u16) -> Hinstance ---; @(link_name="Sleep") sleep :: proc(ms: i32) -> i32 ---; @(link_name="QueryPerformanceFrequency") query_performance_frequency :: proc(result: ^i64) -> i32 ---; @(link_name="QueryPerformanceCounter") query_performance_counter :: proc(result: ^i64) -> i32 ---; - @(link_name="OutputDebugStringA") output_debug_string_a :: proc(c_str: ^u8) ---; + @(link_name="OutputDebugStringA") output_debug_string_a :: proc(c_str: ^byte) ---; - @(link_name="GetCommandLineA") get_command_line_a :: proc() -> ^u8 ---; + @(link_name="GetCommandLineA") get_command_line_a :: proc() -> ^byte ---; @(link_name="GetCommandLineW") get_command_line_w :: proc() -> ^u16 ---; @(link_name="GetSystemMetrics") get_system_metrics :: proc(index: i32) -> i32 ---; @(link_name="GetCurrentThreadId") get_current_thread_id :: proc() -> u32 ---; @@ -456,7 +456,7 @@ foreign kernel32 { @(link_name="GetStdHandle") get_std_handle :: proc(h: i32) -> Handle ---; @(link_name="CreateFileA") - create_file_a :: proc(filename: ^u8, desired_access, share_module: u32, + create_file_a :: proc(filename: ^byte, desired_access, share_module: u32, security: rawptr, creation, flags_and_attribs: u32, template_file: Handle) -> Handle ---; @@ -464,8 +464,8 @@ foreign kernel32 { @(link_name="WriteFile") write_file :: proc(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool ---; @(link_name="GetFileSizeEx") get_file_size_ex :: proc(file_handle: Handle, file_size: ^i64) -> Bool ---; - @(link_name="GetFileAttributesA") get_file_attributes_a :: proc(filename: ^u8) -> u32 ---; - @(link_name="GetFileAttributesExA") get_file_attributes_ex_a :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool ---; + @(link_name="GetFileAttributesA") get_file_attributes_a :: proc(filename: ^byte) -> u32 ---; + @(link_name="GetFileAttributesExA") get_file_attributes_ex_a :: proc(filename: ^byte, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool ---; @(link_name="GetFileInformationByHandle") get_file_information_by_handle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool ---; @(link_name="GetFileType") get_file_type :: proc(file_handle: Handle) -> u32 ---; @@ -473,7 +473,7 @@ foreign kernel32 { @(link_name="SetHandleInformation") set_handle_information :: proc(obj: Handle, mask, flags: u32) -> Bool ---; - @(link_name="FindFirstFileA") find_first_file_a :: proc(file_name : ^u8, data : ^Find_Data) -> Handle ---; + @(link_name="FindFirstFileA") find_first_file_a :: proc(file_name : ^byte, data : ^Find_Data) -> Handle ---; @(link_name="FindNextFileA") find_next_file_a :: proc(file : Handle, data : ^Find_Data) -> Bool ---; @(link_name="FindClose") find_close :: proc(file : Handle) -> Bool ---; @@ -484,7 +484,7 @@ foreign kernel32 { @(link_name="GetProcessHeap") get_process_heap :: proc() -> Handle ---; - @(link_name="CreateSemaphoreA") create_semaphore_a :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle ---; + @(link_name="CreateSemaphoreA") create_semaphore_a :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^byte) -> Handle ---; @(link_name="ReleaseSemaphore") release_semaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool ---; @(link_name="WaitForSingleObject") wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32 ---; } @@ -527,12 +527,12 @@ foreign kernel32 { @(link_name="EnterCriticalSection") enter_critical_section :: proc(critical_section: ^Critical_Section) ---; @(link_name="LeaveCriticalSection") leave_critical_section :: proc(critical_section: ^Critical_Section) ---; - @(link_name="CreateEventA") create_event_a :: proc(event_attributes: ^Security_Attributes, manual_reset, initial_state: Bool, name: ^u8) -> Handle ---; + @(link_name="CreateEventA") create_event_a :: proc(event_attributes: ^Security_Attributes, manual_reset, initial_state: Bool, name: ^byte) -> Handle ---; - @(link_name="LoadLibraryA") load_library_a :: proc(c_str: ^u8) -> Hmodule ---; + @(link_name="LoadLibraryA") load_library_a :: proc(c_str: ^byte) -> Hmodule ---; @(link_name="LoadLibraryW") load_library_a :: proc(c_str: ^u16) -> Hmodule ---; @(link_name="FreeLibrary") free_library :: proc(h: Hmodule) ---; - @(link_name="GetProcAddress") get_proc_address :: proc(h: Hmodule, c_str: ^u8) -> rawptr ---; + @(link_name="GetProcAddress") get_proc_address :: proc(h: Hmodule, c_str: ^byte) -> rawptr ---; } @@ -545,13 +545,13 @@ foreign user32 { @(link_name="ScreenToClient") screen_to_client :: proc(h: Hwnd, p: ^Point) -> Bool ---; @(link_name="ClientToScreen") client_to_screen :: proc(h: Hwnd, p: ^Point) -> Bool ---; @(link_name="PostQuitMessage") post_quit_message :: proc(exit_code: i32) ---; - @(link_name="SetWindowTextA") set_window_text_a :: proc(hwnd: Hwnd, c_string: ^u8) -> Bool ---; + @(link_name="SetWindowTextA") set_window_text_a :: proc(hwnd: Hwnd, c_string: ^byte) -> Bool ---; @(link_name="RegisterClassExA") register_class_ex_a :: proc(wc: ^Wnd_Class_Ex_A) -> i16 ---; @(link_name="RegisterClassExW") register_class_ex_w :: proc(wc: ^Wnd_Class_Ex_W) -> i16 ---; @(link_name="CreateWindowExA") create_window_ex_a :: proc(ex_style: u32, - class_name, title: ^u8, + class_name, title: ^byte, style: u32, x, y, w, h: i32, parent: Hwnd, menu: Hmenu, instance: Hinstance, @@ -601,7 +601,7 @@ foreign user32 { @(link_name="GetWindowLongPtrW") get_window_long_ptr_w :: proc(wnd: Hwnd, index: i32) -> Long_Ptr ---; @(link_name="SetWindowLongPtrW") set_window_long_ptr_w :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr ---; - @(link_name="GetWindowText") get_window_text :: proc(wnd: Hwnd, str: ^u8, maxCount: i32) -> i32 ---; + @(link_name="GetWindowText") get_window_text :: proc(wnd: Hwnd, str: ^byte, maxCount: i32) -> i32 ---; @(link_name="GetClientRect") get_client_rect :: proc(hwnd: Hwnd, rect: ^Rect) -> Bool ---; @@ -757,7 +757,7 @@ Bitmap_Info :: struct #ordered { } -Rgb_Quad :: struct #ordered {blue, green, red, reserved: u8} +Rgb_Quad :: struct #ordered {blue, green, red, reserved: byte} Key_Code :: enum i32 { diff --git a/examples/demo.odin b/examples/demo.odin index 8e6089fca..4992df87f 100644 --- a/examples/demo.odin +++ b/examples/demo.odin @@ -20,6 +20,7 @@ when ODIN_OS == "windows" { } general_stuff :: proc() { + fmt.println("# general_stuff"); { // `do` for inline statmes rather than block foo :: proc() do fmt.println("Foo!"); if false do foo(); @@ -77,6 +78,7 @@ general_stuff :: proc() { } default_struct_values :: proc() { + fmt.println("# default_struct_values"); { Vector3 :: struct { x: f32, @@ -138,6 +140,7 @@ default_struct_values :: proc() { union_type :: proc() { + fmt.println("\n# union_type"); { val: union{int, bool}; val = 137; @@ -310,6 +313,8 @@ union_type :: proc() { } parametric_polymorphism :: proc() { + fmt.println("# parametric_polymorphism"); + print_value :: proc(value: $T) { fmt.printf("print_value: %T %v\n", value, value); } @@ -510,12 +515,14 @@ prefix_table := [...]string{ threading_example :: proc() { when ODIN_OS == "windows" { - unordered_remove :: proc(array: ^[]$T, index: int, loc := #caller_location) { + fmt.println("# threading_example"); + + unordered_remove :: proc(array: ^[dynamic]$T, index: int, loc := #caller_location) { __bounds_check_error_loc(loc, index, len(array)); array[index] = array[len(array)-1]; pop(array); } - ordered_remove :: proc(array: ^[]$T, index: int, loc := #caller_location) { + ordered_remove :: proc(array: ^[dynamic]$T, index: int, loc := #caller_location) { __bounds_check_error_loc(loc, index, len(array)); copy(array[index..], array[index+1..]); pop(array); @@ -530,7 +537,7 @@ threading_example :: proc() { return 0; } - threads := make([]^thread.Thread, 0, len(prefix_table)); + threads := make([dynamic]^thread.Thread, 0, len(prefix_table)); defer free(threads); for i in 0..len(prefix_table) { @@ -559,12 +566,12 @@ threading_example :: proc() { } main :: proc() { - when false { - fmt.println("\n# general_stuff"); general_stuff(); - fmt.println("\n# default_struct_values"); default_struct_values(); - fmt.println("\n# union_type"); union_type(); - fmt.println("\n# parametric_polymorphism"); parametric_polymorphism(); - fmt.println("\n# threading_example"); threading_example(); + when true { + general_stuff(); + default_struct_values(); + union_type(); + parametric_polymorphism(); + threading_example(); } } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 4c52ca400..c59bd995c 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3077,7 +3077,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id isize max_args = 1; if (is_type_slice(type)) { min_args = 2; - max_args = 3; + max_args = 2; } else if (is_type_map(type)) { min_args = 1; max_args = 2; @@ -6084,12 +6084,6 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t switch (t->kind) { case Type_Basic: if (is_type_string(t)) { - if (se->index3) { - error(node, "3-index slice on a string in not needed"); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } valid = true; if (o->mode == Addressing_Constant) { max_count = o->value.value_string.len; @@ -6141,25 +6135,10 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t // It is okay to continue as it will assume the 1st index is zero } - if (se->index3 && (se->high == nullptr || se->max == nullptr)) { - error(se->close, "2nd and 3rd indices are required in a 3-index slice"); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } + TokenKind interval_kind = se->interval.kind; - if (se->index3 && se->interval0.kind != se->interval1.kind) { - error(se->close, "The interval separators for in a 3-index slice must be the same"); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - - TokenKind interval_kind = se->interval0.kind; - - i64 indices[3] = {}; - AstNode *nodes[3] = {se->low, se->high, se->max}; + i64 indices[2] = {}; + AstNode *nodes[2] = {se->low, se->high}; for (isize i = 0; i < gb_count_of(nodes); i++) { i64 index = max_count; if (nodes[i] != nullptr) { @@ -6461,12 +6440,8 @@ gbString write_expr_to_string(gbString str, AstNode *node) { str = write_expr_to_string(str, se->expr); str = gb_string_append_rune(str, '['); str = write_expr_to_string(str, se->low); - str = gb_string_appendc(str, ".."); + str = string_append_token(str, se->interval); str = write_expr_to_string(str, se->high); - if (se->index3) { - str = gb_string_appendc(str, ".."); - str = write_expr_to_string(str, se->max); - } str = gb_string_append_rune(str, ']'); case_end; diff --git a/src/checker.cpp b/src/checker.cpp index 1ba84b5fd..88ad773c0 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -852,6 +852,9 @@ void add_global_string_constant(gbAllocator a, String name, String value) { } +void add_global_type_entity(gbAllocator a, String name, Type *type) { + add_global_entity(make_entity_type_name(a, nullptr, make_token_ident(name), type)); +} @@ -863,17 +866,9 @@ void init_universal_scope(void) { // Types for (isize i = 0; i < gb_count_of(basic_types); i++) { - add_global_entity(make_entity_type_name(a, nullptr, make_token_ident(basic_types[i].Basic.name), &basic_types[i])); + add_global_type_entity(a, basic_types[i].Basic.name, &basic_types[i]); } -#if 1 - // for (isize i = 0; i < gb_count_of(basic_type_aliases); i++) { - // add_global_entity(make_entity_type_name(a, nullptr, make_token_ident(basic_type_aliases[i].Basic.name), &basic_type_aliases[i])); - // } -#else - { - t_byte = add_global_type_alias(a, str_lit("byte"), &basic_types[Basic_u8]); - } -#endif + add_global_type_entity(a, str_lit("byte"), &basic_types[Basic_u8]); // Constants add_global_constant(a, str_lit("true"), t_untyped_bool, exact_value_bool(true)); diff --git a/src/ir.cpp b/src/ir.cpp index ea4d9c9a3..8b84f1e37 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2674,7 +2674,6 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) { switch (index) { case 0: result_type = make_type_pointer(a, t->Slice.elem); break; case 1: result_type = t_int; break; - case 2: result_type = t_int; break; } break; case Type_DynamicArray: @@ -2837,11 +2836,6 @@ irValue *ir_slice_count(irProcedure *proc, irValue *slice) { GB_ASSERT(is_type_slice(ir_type(slice))); return ir_emit_struct_ev(proc, slice, 1); } -irValue *ir_slice_capacity(irProcedure *proc, irValue *slice) { - GB_ASSERT(is_type_slice(ir_type(slice))); - return ir_emit_struct_ev(proc, slice, 2); -} - irValue *ir_dynamic_array_elem(irProcedure *proc, irValue *da) { GB_ASSERT(is_type_dynamic_array(ir_type(da))); return ir_emit_struct_ev(proc, da, 0); @@ -2873,14 +2867,13 @@ irValue *ir_string_len(irProcedure *proc, irValue *string) { } -void ir_fill_slice(irProcedure *proc, irValue *slice_ptr, irValue *data, irValue *len, irValue *cap) { +void ir_fill_slice(irProcedure *proc, irValue *slice_ptr, irValue *data, irValue *len) { Type *t = ir_type(slice_ptr); GB_ASSERT(is_type_pointer(t)); t = type_deref(t); GB_ASSERT(is_type_slice(t)); ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 0), data); ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 1), len); - ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 2), cap); } void ir_fill_string(irProcedure *proc, irValue *string_ptr, irValue *data, irValue *len) { Type *t = ir_type(string_ptr); @@ -2900,7 +2893,7 @@ irValue *ir_emit_string(irProcedure *proc, irValue *elem, irValue *len) { -irValue *ir_add_local_slice(irProcedure *proc, Type *slice_type, irValue *base, irValue *low, irValue *high, irValue *max) { +irValue *ir_add_local_slice(irProcedure *proc, Type *slice_type, irValue *base, irValue *low, irValue *high) { // TODO(bill): array bounds checking for slice creation // TODO(bill): check that low < high <= max gbAllocator a = proc->module->allocator; @@ -2916,16 +2909,8 @@ irValue *ir_add_local_slice(irProcedure *proc, Type *slice_type, irValue *base, case Type_Pointer: high = v_one; break; } } - if (max == nullptr) { - switch (bt->kind) { - case Type_Array: high = ir_array_len(proc, base); break; - case Type_Slice: high = ir_slice_capacity(proc, base); break; - case Type_Pointer: high = v_one; break; - } - } irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int); - irValue *cap = ir_emit_arith(proc, Token_Sub, max, low, t_int); irValue *elem = nullptr; switch (bt->kind) { @@ -2937,7 +2922,7 @@ irValue *ir_add_local_slice(irProcedure *proc, Type *slice_type, irValue *base, elem = ir_emit_ptr_offset(proc, elem, low); irValue *slice = ir_add_local_generated(proc, slice_type); - ir_fill_slice(proc, slice, elem, len, cap); + ir_fill_slice(proc, slice, elem, len); return slice; } @@ -3274,8 +3259,7 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { ir_emit_store(proc, elem_ptr, elem); irValue *len = ir_string_len(proc, value); - irValue *cap = len; - irValue *slice = ir_add_local_slice(proc, t, elem_ptr, v_zero, len, cap); + irValue *slice = ir_add_local_slice(proc, t, elem_ptr, v_zero, len); return ir_emit_load(proc, slice); } @@ -3648,7 +3632,30 @@ void ir_emit_bounds_check(irProcedure *proc, Token token, irValue *index, irValu // ir_emit(proc, ir_instr_bounds_check(proc, token.pos, index, len)); } -void ir_emit_slice_bounds_check(irProcedure *proc, Token token, irValue *low, irValue *high, irValue *max, bool is_substring) { +void ir_emit_slice_bounds_check(irProcedure *proc, Token token, irValue *low, irValue *high, bool is_substring) { + if ((proc->module->stmt_state_flags & StmtStateFlag_no_bounds_check) != 0) { + return; + } + + gbAllocator a = proc->module->allocator; + irValue *file = ir_find_or_add_entity_string(proc->module, token.pos.file); + irValue *line = ir_const_int(a, token.pos.line); + irValue *column = ir_const_int(a, token.pos.column); + low = ir_emit_conv(proc, low, t_int); + high = ir_emit_conv(proc, high, t_int); + + irValue **args = gb_alloc_array(a, irValue *, 5); + args[0] = file; + args[1] = line; + args[2] = column; + args[3] = low; + args[4] = high; + + char *func = is_substring ? "__substring_expr_error" : "__slice_expr_error"; + ir_emit_global_call(proc, func, args, 5); +} + +void ir_emit_dynamic_array_bounds_check(irProcedure *proc, Token token, irValue *low, irValue *high, irValue *max) { if ((proc->module->stmt_state_flags & StmtStateFlag_no_bounds_check) != 0) { return; } @@ -3668,14 +3675,7 @@ void ir_emit_slice_bounds_check(irProcedure *proc, Token token, irValue *low, ir args[4] = high; args[5] = max; - if (is_substring) { - ir_emit_global_call(proc, "__substring_expr_error", args, 5); - } else { - ir_emit_global_call(proc, "__slice_expr_error", args, 6); - } - - - // ir_emit(proc, ir_instr_slice_bounds_check(proc, token.pos, low, high, max, is_substring)); + ir_emit_global_call(proc, "__dynamic_array_expr_error", args, 6); } @@ -4139,7 +4139,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv } else if (is_type_vector(t)) { GB_PANIC("Unreachable"); } else if (is_type_slice(t)) { - return ir_slice_capacity(proc, v); + return ir_slice_count(proc, v); } else if (is_type_dynamic_array(t)) { return ir_dynamic_array_capacity(proc, v); } else if (is_type_map(t)) { @@ -4212,17 +4212,12 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv irValue *elem_align = ir_const_int(a, eal); irValue *len = ir_emit_conv(proc, ir_build_expr(proc, ce->args[1]), t_int); - irValue *cap = len; - if (ce->args.count == 3) { - cap = ir_emit_conv(proc, ir_build_expr(proc, ce->args[2]), t_int); - } + ir_emit_slice_bounds_check(proc, ast_node_token(ce->args[1]), v_zero, len, false); - ir_emit_slice_bounds_check(proc, ast_node_token(ce->args[1]), v_zero, len, cap, false); - - irValue *slice_size = cap; + irValue *slice_size = len; if (eal != 1) { - slice_size = ir_emit_arith(proc, Token_Mul, elem_size, cap, t_int); + slice_size = ir_emit_arith(proc, Token_Mul, elem_size, len, t_int); } TokenPos pos = ast_node_token(ce->args[0]).pos; @@ -4240,7 +4235,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv } irValue *slice = ir_add_local_generated(proc, type); - ir_fill_slice(proc, slice, ptr, len, cap); + ir_fill_slice(proc, slice, ptr, len); return ir_emit_load(proc, slice); } else if (is_type_map(type)) { irValue *int_16 = ir_const_int(a, 16); @@ -4272,7 +4267,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv cap = ir_emit_conv(proc, ir_build_expr(proc, ce->args[2]), t_int); } - ir_emit_slice_bounds_check(proc, ast_node_token(ce->args[0]), v_zero, len, cap, false); + ir_emit_dynamic_array_bounds_check(proc, ast_node_token(ce->args[0]), v_zero, len, cap); irValue *array = ir_add_local_generated(proc, type); irValue **args = gb_alloc_array(a, irValue *, 6); @@ -5270,7 +5265,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { irValue *base_elem = ir_emit_array_epi(proc, base_array, 0); irValue *len = ir_const_int(allocator, slice_len); - ir_fill_slice(proc, slice, base_elem, len, len); + ir_fill_slice(proc, slice, base_elem, len); } arg_count = param_count; @@ -5663,20 +5658,14 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { gbAllocator a = proc->module->allocator; irValue *low = v_zero; irValue *high = nullptr; - irValue *max = nullptr; - if (se->low != nullptr) low = ir_build_expr(proc, se->low); - if (se->high != nullptr) high = ir_build_expr(proc, se->high); - if (se->max != nullptr) max = ir_build_expr(proc, se->max); + if (se->low != nullptr) low = ir_build_expr(proc, se->low); + if (se->high != nullptr) high = ir_build_expr(proc, se->high); - if (high != nullptr && se->interval0.kind == Token_Ellipsis) { + if (high != nullptr && se->interval.kind == Token_Ellipsis) { high = ir_emit_arith(proc, Token_Add, high, v_one, t_int); } - if (max != nullptr && se->interval1.kind == Token_Ellipsis) { - max = ir_emit_arith(proc, Token_Add, max, v_one, t_int); - } - irValue *addr = ir_build_addr_ptr(proc, se->expr); irValue *base = ir_emit_load(proc, addr); Type *type = base_type(ir_type(base)); @@ -5693,16 +5682,14 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { Type *slice_type = type; if (high == nullptr) high = ir_slice_count(proc, base); - if (max == nullptr) max = ir_slice_capacity(proc, base); - ir_emit_slice_bounds_check(proc, se->open, low, high, max, false); + ir_emit_slice_bounds_check(proc, se->open, low, high, false); irValue *elem = ir_emit_ptr_offset(proc, ir_slice_elem(proc, base), low); irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int); - irValue *cap = ir_emit_arith(proc, Token_Sub, max, low, t_int); irValue *slice = ir_add_local_generated(proc, slice_type); - ir_fill_slice(proc, slice, elem, len, cap); + ir_fill_slice(proc, slice, elem, len); return ir_addr(slice); } @@ -5711,16 +5698,15 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { Type *slice_type = make_type_slice(a, elem_type); if (high == nullptr) high = ir_dynamic_array_count(proc, base); - if (max == nullptr) max = ir_dynamic_array_capacity(proc, base); + irValue *cap = ir_dynamic_array_capacity(proc, base); - ir_emit_slice_bounds_check(proc, se->open, low, high, max, false); + ir_emit_dynamic_array_bounds_check(proc, se->open, low, high, cap); irValue *elem = ir_emit_ptr_offset(proc, ir_dynamic_array_elem(proc, base), low); irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int); - irValue *cap = ir_emit_arith(proc, Token_Sub, max, low, t_int); irValue *slice = ir_add_local_generated(proc, slice_type); - ir_fill_slice(proc, slice, elem, len, cap); + ir_fill_slice(proc, slice, elem, len); return ir_addr(slice); } @@ -5729,21 +5715,18 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { Type *slice_type = make_type_slice(a, type->Array.elem); if (high == nullptr) high = ir_array_len(proc, base); - if (max == nullptr) max = ir_array_len(proc, base); bool low_const = type_and_value_of_expr(proc->module->info, se->low).mode == Addressing_Constant; bool high_const = type_and_value_of_expr(proc->module->info, se->high).mode == Addressing_Constant; - bool max_const = type_and_value_of_expr(proc->module->info, se->max).mode == Addressing_Constant; - if (!low_const || !high_const || !max_const) { - ir_emit_slice_bounds_check(proc, se->open, low, high, max, false); + if (!low_const || !high_const) { + ir_emit_slice_bounds_check(proc, se->open, low, high, false); } irValue *elem = ir_emit_ptr_offset(proc, ir_array_elem(proc, addr), low); irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int); - irValue *cap = ir_emit_arith(proc, Token_Sub, max, low, t_int); irValue *slice = ir_add_local_generated(proc, slice_type); - ir_fill_slice(proc, slice, elem, len, cap); + ir_fill_slice(proc, slice, elem, len); return ir_addr(slice); } @@ -5752,7 +5735,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { if (high == nullptr) high = ir_string_len(proc, base); // if (max == nullptr) max = ir_string_len(proc, base); - ir_emit_slice_bounds_check(proc, se->open, low, high, nullptr, true); + ir_emit_slice_bounds_check(proc, se->open, low, high, true); irValue *elem = ir_emit_ptr_offset(proc, ir_string_elem(proc, base), low); irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int); @@ -5760,7 +5743,6 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { irValue *str = ir_add_local_generated(proc, t_string); ir_fill_string(proc, str, elem, len); return ir_addr(str); - break; } } @@ -5984,7 +5966,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { } irValue *count = ir_const_int(proc->module->allocator, slice->ConstantSlice.count); - ir_fill_slice(proc, v, data, count, count); + ir_fill_slice(proc, v, data, count); } break; } @@ -7746,7 +7728,7 @@ void ir_init_module(irModule *m, Checker *c) { { String name = str_lit(IR_TYPE_INFO_OFFSETS_NAME); Entity *e = make_entity_variable(m->allocator, nullptr, make_token_ident(name), - make_type_array(m->allocator, t_int, count), false); + make_type_array(m->allocator, t_uintptr, count), false); irValue *g = ir_value_global(m->allocator, e, nullptr); ir_module_add_value(m, e, g); map_set(&m->members, hash_string(name), g); @@ -7899,7 +7881,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info irValue *len = ir_const_int(proc->module->allocator, type->Array.count); ir_fill_slice(proc, global_type_table, ir_emit_array_epi(proc, ir_global_type_info_data, 0), - len, len); + len); } @@ -8098,8 +8080,8 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info } irValue *count = ir_const_int(a, t->Tuple.variables.count); - ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, count, count); - ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, count, count); + ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, count); + ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, count); break; } case Type_Enum: @@ -8138,11 +8120,11 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info irValue *names = ir_emit_struct_ep(proc, tag, 1); irValue *name_array_elem = ir_array_elem(proc, name_array); - ir_fill_slice(proc, names, name_array_elem, v_count, v_count); + ir_fill_slice(proc, names, name_array_elem, v_count); irValue *values = ir_emit_struct_ep(proc, tag, 2); irValue *value_array_elem = ir_array_elem(proc, value_array); - ir_fill_slice(proc, values, value_array_elem, v_count, v_count); + ir_fill_slice(proc, values, value_array_elem, v_count); } } break; @@ -8170,11 +8152,11 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info } irValue *count = ir_const_int(a, variant_count); - ir_fill_slice(proc, variant_types, memory_types, count, count); + ir_fill_slice(proc, variant_types, memory_types, count); - i64 tag_size = union_tag_size(t); + i64 tag_size = union_tag_size(t); i64 tag_offset = align_formula(t->Union.variant_block_size, tag_size); - ir_emit_store(proc, tag_offset_ptr, ir_const_int(a, tag_offset)); + ir_emit_store(proc, tag_offset_ptr, ir_const_uintptr(a, tag_offset)); ir_emit_store(proc, tag_type_ptr, ir_type_info(proc, union_tag_type(t))); } @@ -8224,15 +8206,15 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info irValue *name = ir_emit_ptr_offset(proc, memory_names, index); ir_emit_store(proc, name, ir_const_string(a, f->token.string)); } - ir_emit_store(proc, offset, ir_const_int(a, foffset)); + ir_emit_store(proc, offset, ir_const_uintptr(a, foffset)); ir_emit_store(proc, is_using, ir_const_bool(a, (f->flags&EntityFlag_Using) != 0)); } irValue *cv = ir_const_int(a, count); - ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, cv, cv); - ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, cv, cv); - ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, cv, cv); - ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 3), memory_usings, cv, cv); + ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, cv); + ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, cv); + ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, cv); + ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 3), memory_usings, cv); break; } case Type_Map: { @@ -8281,15 +8263,15 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info irValue *names = ir_emit_struct_ep(proc, tag, 0); irValue *name_array_elem = ir_array_elem(proc, name_array); - ir_fill_slice(proc, names, name_array_elem, v_count, v_count); + ir_fill_slice(proc, names, name_array_elem, v_count); irValue *bits = ir_emit_struct_ep(proc, tag, 1); irValue *bit_array_elem = ir_array_elem(proc, bit_array); - ir_fill_slice(proc, bits, bit_array_elem, v_count, v_count); + ir_fill_slice(proc, bits, bit_array_elem, v_count); irValue *offsets = ir_emit_struct_ep(proc, tag, 2); irValue *offset_array_elem = ir_array_elem(proc, offset_array); - ir_fill_slice(proc, offsets, offset_array_elem, v_count, v_count); + ir_fill_slice(proc, offsets, offset_array_elem, v_count); } break; } diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 0c84b3567..0b0e5d97b 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -323,7 +323,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { case Type_Slice: ir_write_byte(f, '{'); ir_print_type(f, m, t->Slice.elem); - ir_fprintf(f, "*, i%lld, i%lld}", word_bits, word_bits); + ir_fprintf(f, "*, i%lld}", word_bits); return; case Type_DynamicArray: ir_write_byte(f, '{'); diff --git a/src/parser.cpp b/src/parser.cpp index fc0dd13a0..d513bd79c 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -192,10 +192,8 @@ AST_NODE_KIND(_ExprBegin, "", i32) \ AST_NODE_KIND(SliceExpr, "slice expression", struct { \ AstNode *expr; \ Token open, close; \ - Token interval0; \ - Token interval1; \ - bool index3; \ - AstNode *low, *high, *max; \ + Token interval; \ + AstNode *low, *high; \ }) \ AST_NODE_KIND(CallExpr, "call expression", struct { \ AstNode * proc; \ @@ -714,7 +712,6 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) { n->SliceExpr.expr = clone_ast_node(a, n->SliceExpr.expr); n->SliceExpr.low = clone_ast_node(a, n->SliceExpr.low); n->SliceExpr.high = clone_ast_node(a, n->SliceExpr.high); - n->SliceExpr.max = clone_ast_node(a, n->SliceExpr.max); break; case AstNode_CallExpr: n->CallExpr.proc = clone_ast_node(a, n->CallExpr.proc); @@ -1064,17 +1061,14 @@ AstNode *ast_index_expr(AstFile *f, AstNode *expr, AstNode *index, Token open, T } -AstNode *ast_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, Token interval0, Token interval1, bool index3, AstNode *low, AstNode *high, AstNode *max) { +AstNode *ast_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, Token interval, AstNode *low, AstNode *high) { AstNode *result = make_ast_node(f, AstNode_SliceExpr); result->SliceExpr.expr = expr; result->SliceExpr.open = open; result->SliceExpr.close = close; - result->SliceExpr.interval0 = interval0; - result->SliceExpr.interval1 = interval1; - result->SliceExpr.index3 = index3; + result->SliceExpr.interval = interval; result->SliceExpr.low = low; result->SliceExpr.high = high; - result->SliceExpr.max = max; return result; } @@ -2726,9 +2720,9 @@ AstNode *parse_atom_expr(AstFile *f, AstNode *operand, bool lhs) { f->allow_range = false; Token open = {}, close = {}, interval = {}; - AstNode *indices[3] = {}; - isize ellipsis_count = 0; - Token ellipses[2] = {}; + AstNode *indices[2] = {}; + Token ellipsis = {}; + bool is_ellipsis = false; f->expr_level++; open = expect_token(f, Token_OpenBracket); @@ -2739,15 +2733,15 @@ AstNode *parse_atom_expr(AstFile *f, AstNode *operand, bool lhs) { } bool is_index = true; - while ((f->curr_token.kind == Token_Ellipsis || - f->curr_token.kind == Token_HalfClosed) - && ellipsis_count < gb_count_of(ellipses)) { - ellipses[ellipsis_count++] = advance_token(f); + if ((f->curr_token.kind == Token_Ellipsis || + f->curr_token.kind == Token_HalfClosed)) { + ellipsis = advance_token(f); + is_ellipsis = true; if (f->curr_token.kind != Token_Ellipsis && f->curr_token.kind != Token_HalfClosed && f->curr_token.kind != Token_CloseBracket && f->curr_token.kind != Token_EOF) { - indices[ellipsis_count] = parse_expr(f, false); + indices[1] = parse_expr(f, false); } } @@ -2755,21 +2749,8 @@ AstNode *parse_atom_expr(AstFile *f, AstNode *operand, bool lhs) { f->expr_level--; close = expect_token(f, Token_CloseBracket); - if (ellipsis_count > 0) { - bool index3 = false; - if (ellipsis_count == 2) { - index3 = true; - // 2nd and 3rd index must be present - if (indices[1] == nullptr) { - syntax_error(ellipses[0], "2nd index required in 3-index slice expression"); - indices[1] = ast_bad_expr(f, ellipses[0], ellipses[1]); - } - if (indices[2] == nullptr) { - syntax_error(ellipses[1], "3rd index required in 3-index slice expression"); - indices[2] = ast_bad_expr(f, ellipses[1], close); - } - } - operand = ast_slice_expr(f, operand, open, close, ellipses[0], ellipses[1], index3, indices[0], indices[1], indices[2]); + if (is_ellipsis) { + operand = ast_slice_expr(f, operand, open, close, ellipsis, indices[0], indices[1]); } else { operand = ast_index_expr(f, operand, indices[0], open, close); } diff --git a/src/types.cpp b/src/types.cpp index f5acd073b..8dae03451 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -327,6 +327,7 @@ gb_global Type *t_untyped_nil = &basic_types[Basic_UntypedNil]; gb_global Type *t_untyped_undef = &basic_types[Basic_UntypedUndef]; + gb_global Type *t_u8_ptr = nullptr; gb_global Type *t_int_ptr = nullptr; gb_global Type *t_i64_ptr = nullptr; @@ -2127,8 +2128,8 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) { } break; - case Type_Slice: // ptr + count - return 3 * build_context.word_size; + case Type_Slice: // ptr + len + return 2 * build_context.word_size; case Type_DynamicArray: // data + len + cap + allocator(procedure+data)