mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-01 19:02:13 +00:00
New slice memory layout (ptr+len); byte
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
164
core/fmt.odin
164
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, "<nil>");
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
12
core/os.odin
12
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));
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -11,7 +11,6 @@ String :: struct #ordered {
|
||||
Slice :: struct #ordered {
|
||||
data: rawptr,
|
||||
len: int,
|
||||
cap: int,
|
||||
}
|
||||
|
||||
Dynamic_Array :: struct #ordered {
|
||||
|
||||
@@ -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)]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ---;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
150
src/ir.cpp
150
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;
|
||||
}
|
||||
|
||||
@@ -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, '{');
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user