New slice memory layout (ptr+len); byte

This commit is contained in:
gingerBill
2017-11-26 18:36:46 +00:00
parent 5a9223afda
commit 74fa7ca25d
21 changed files with 426 additions and 507 deletions

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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, "<nil>");

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -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));
}

View File

@@ -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() {

View File

@@ -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 {

View File

@@ -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;
}
}

View File

@@ -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 {

View File

@@ -11,7 +11,6 @@ String :: struct #ordered {
Slice :: struct #ordered {
data: rawptr,
len: int,
cap: int,
}
Dynamic_Array :: struct #ordered {

View File

@@ -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)]);
}

View File

@@ -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 ---;

View File

@@ -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 {

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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));

View File

@@ -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;
}

View File

@@ -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, '{');

View File

@@ -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);
}

View File

@@ -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)