mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-06 02:34:05 +00:00
Syntax change: cast(T)x => T(x); union_cast(T)x => x.(T); transmute(T)x => transmute(T, x); y:=^x => y:=&x;
Sorry for all the code breaking in this commit :(
This commit is contained in:
@@ -166,7 +166,7 @@ DEFAULT_ALIGNMENT :: align_of([vector 4]f32);
|
||||
|
||||
|
||||
__check_context :: proc() {
|
||||
c := ^__context;
|
||||
c := &__context;
|
||||
|
||||
if c.allocator.procedure == nil {
|
||||
c.allocator = default_allocator();
|
||||
@@ -287,14 +287,14 @@ __string_eq :: proc(a, b: string) -> bool {
|
||||
if len(a) == 0 {
|
||||
return true;
|
||||
}
|
||||
if ^a[0] == ^b[0] {
|
||||
if &a[0] == &b[0] {
|
||||
return true;
|
||||
}
|
||||
return __string_cmp(a, b) == 0;
|
||||
}
|
||||
|
||||
__string_cmp :: proc(a, b: string) -> int {
|
||||
return __mem_compare(^a[0], ^b[0], min(len(a), len(b)));
|
||||
return __mem_compare(&a[0], &b[0], min(len(a), len(b)));
|
||||
}
|
||||
|
||||
__string_ne :: proc(a, b: string) -> bool #inline { return !__string_eq(a, b); }
|
||||
@@ -360,9 +360,9 @@ __substring_expr_error :: proc(file: string, line, column: int, low, high: int)
|
||||
file, line, column, low, high);
|
||||
__debug_trap();
|
||||
}
|
||||
__union_cast_check :: proc(ok: bool, file: string, line, column: int, from, to: ^Type_Info) {
|
||||
__type_assertion_check :: proc(ok: bool, file: string, line, column: int, from, to: ^Type_Info) {
|
||||
if !ok {
|
||||
fmt.fprintf(os.stderr, "%s(%d:%d) Invalid `union_cast` from %T to %T\n",
|
||||
fmt.fprintf(os.stderr, "%s(%d:%d) Invalid type_assertion from %T to %T\n",
|
||||
file, line, column, from, to);
|
||||
__debug_trap();
|
||||
}
|
||||
@@ -375,7 +375,7 @@ __string_decode_rune :: proc(s: string) -> (rune, int) #inline {
|
||||
|
||||
__mem_set :: proc(data: rawptr, value: i32, len: int) -> rawptr {
|
||||
llvm_memset_64bit :: proc(dst: rawptr, val: byte, len: int, align: i32, is_volatile: bool) #foreign __llvm_core "llvm.memset.p0i8.i64";
|
||||
llvm_memset_64bit(data, cast(byte)value, len, 1, false);
|
||||
llvm_memset_64bit(data, byte(value), len, 1, false);
|
||||
return data;
|
||||
}
|
||||
__mem_zero :: proc(data: rawptr, len: int) -> rawptr {
|
||||
@@ -429,7 +429,7 @@ __abs_quaternion256 :: proc(x: quaternion256) -> f64 #inline {
|
||||
|
||||
|
||||
__dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, cap: int) {
|
||||
array := cast(^raw.Dynamic_Array)array_;
|
||||
array := ^raw.Dynamic_Array(array_);
|
||||
__check_context();
|
||||
array.allocator = context.allocator;
|
||||
assert(array.allocator.procedure != nil);
|
||||
@@ -441,7 +441,7 @@ __dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, ca
|
||||
}
|
||||
|
||||
__dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: int) -> bool {
|
||||
array := cast(^raw.Dynamic_Array)array_;
|
||||
array := ^raw.Dynamic_Array(array_);
|
||||
|
||||
if cap <= array.cap {
|
||||
return true;
|
||||
@@ -468,7 +468,7 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap:
|
||||
}
|
||||
|
||||
__dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len: int) -> bool {
|
||||
array := cast(^raw.Dynamic_Array)array_;
|
||||
array := ^raw.Dynamic_Array(array_);
|
||||
|
||||
ok := __dynamic_array_reserve(array_, elem_size, elem_align, len);
|
||||
if ok {
|
||||
@@ -480,7 +480,7 @@ __dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len:
|
||||
|
||||
__dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
||||
items: rawptr, item_count: int) -> int {
|
||||
array := cast(^raw.Dynamic_Array)array_;
|
||||
array := ^raw.Dynamic_Array(array_);
|
||||
|
||||
if item_count <= 0 || items == nil {
|
||||
return array.len;
|
||||
@@ -496,7 +496,7 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
||||
// TODO(bill): Better error handling for failed reservation
|
||||
return array.len;
|
||||
}
|
||||
data := cast(^byte)array.data;
|
||||
data := ^byte(array.data);
|
||||
assert(data != nil);
|
||||
__mem_copy(data + (elem_size*array.len), items, elem_size * item_count);
|
||||
array.len += item_count;
|
||||
@@ -504,7 +504,7 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
||||
}
|
||||
|
||||
__dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: int) -> int {
|
||||
array := cast(^raw.Dynamic_Array)array_;
|
||||
array := ^raw.Dynamic_Array(array_);
|
||||
|
||||
ok := true;
|
||||
if array.cap <= array.len+1 {
|
||||
@@ -515,7 +515,7 @@ __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: in
|
||||
// TODO(bill): Better error handling for failed reservation
|
||||
return array.len;
|
||||
}
|
||||
data := cast(^byte)array.data;
|
||||
data := ^byte(array.data);
|
||||
assert(data != nil);
|
||||
__mem_zero(data + (elem_size*array.len), elem_size);
|
||||
array.len++;
|
||||
@@ -524,7 +524,7 @@ __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: in
|
||||
|
||||
__slice_append :: proc(slice_: rawptr, elem_size, elem_align: int,
|
||||
items: rawptr, item_count: int) -> int {
|
||||
slice := cast(^raw.Slice)slice_;
|
||||
slice := ^raw.Slice(slice_);
|
||||
|
||||
if item_count <= 0 || items == nil {
|
||||
return slice.len;
|
||||
@@ -532,7 +532,7 @@ __slice_append :: proc(slice_: rawptr, elem_size, elem_align: int,
|
||||
|
||||
item_count = min(slice.cap-slice.len, item_count);
|
||||
if item_count > 0 {
|
||||
data := cast(^byte)slice.data;
|
||||
data := ^byte(slice.data);
|
||||
assert(data != nil);
|
||||
__mem_copy(data + (elem_size*slice.len), items, elem_size * item_count);
|
||||
slice.len += item_count;
|
||||
@@ -547,14 +547,14 @@ __default_hash :: proc(data: []byte) -> u64 {
|
||||
fnv64a :: proc(data: []byte) -> u64 {
|
||||
h: u64 = 0xcbf29ce484222325;
|
||||
for b in data {
|
||||
h = (h ~ cast(u64)b) * 0x100000001b3;
|
||||
h = (h ~ u64(b)) * 0x100000001b3;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
return fnv64a(data);
|
||||
}
|
||||
__default_hash_string :: proc(s: string) -> u64 {
|
||||
return __default_hash(cast([]byte)s);
|
||||
return __default_hash([]byte(s));
|
||||
}
|
||||
|
||||
__INITIAL_MAP_CAP :: 16;
|
||||
@@ -588,20 +588,20 @@ __Map_Header :: struct #ordered {
|
||||
}
|
||||
|
||||
__dynamic_map_reserve :: proc(using header: __Map_Header, cap: int) {
|
||||
__dynamic_array_reserve(^m.hashes, size_of(int), align_of(int), cap);
|
||||
__dynamic_array_reserve(^m.entries, entry_size, entry_align, cap);
|
||||
__dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap);
|
||||
__dynamic_array_reserve(&m.entries, entry_size, entry_align, cap);
|
||||
}
|
||||
|
||||
__dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int) {
|
||||
new_header: __Map_Header = header;
|
||||
nm: raw.Dynamic_Map;
|
||||
new_header.m = ^nm;
|
||||
new_header.m = &nm;
|
||||
|
||||
header_hashes := cast(^raw.Dynamic_Array)^header.m.hashes;
|
||||
nm_hashes := cast(^raw.Dynamic_Array)^nm.hashes;
|
||||
header_hashes := ^raw.Dynamic_Array(&header.m.hashes);
|
||||
nm_hashes := ^raw.Dynamic_Array(&nm.hashes);
|
||||
|
||||
__dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count);
|
||||
__dynamic_array_reserve(^nm.entries, entry_size, entry_align, m.entries.len);
|
||||
__dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len);
|
||||
for i in 0..<new_count {
|
||||
nm.hashes[i] = -1;
|
||||
}
|
||||
@@ -612,7 +612,7 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int) {
|
||||
}
|
||||
|
||||
entry_header := __dynamic_map_get_entry(header, i);
|
||||
data := cast(^byte)entry_header;
|
||||
data := ^byte(entry_header);
|
||||
|
||||
fr := __dynamic_map_find(new_header, entry_header.key);
|
||||
j := __dynamic_map_add_entry(new_header, entry_header.key);
|
||||
@@ -625,7 +625,7 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int) {
|
||||
|
||||
e := __dynamic_map_get_entry(new_header, j);
|
||||
e.next = fr.entry_index;
|
||||
ndata := cast(^byte)e;
|
||||
ndata := ^byte(e);
|
||||
__mem_copy(ndata+value_offset, data+value_offset, value_size);
|
||||
|
||||
if __dynamic_map_full(new_header) {
|
||||
@@ -640,7 +640,7 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int) {
|
||||
__dynamic_map_get :: proc(h: __Map_Header, key: __Map_Key) -> rawptr {
|
||||
index := __dynamic_map_find(h, key).entry_index;
|
||||
if index >= 0 {
|
||||
data := cast(^byte)__dynamic_map_get_entry(h, index);
|
||||
data := ^byte(__dynamic_map_get_entry(h, index));
|
||||
val := data + h.value_offset;
|
||||
return val;
|
||||
}
|
||||
@@ -672,7 +672,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(^byte)e + value_offset;
|
||||
val := ^byte(e) + value_offset;
|
||||
__mem_copy(val, value, value_size);
|
||||
}
|
||||
|
||||
@@ -688,7 +688,7 @@ __dynamic_map_grow :: proc(using h: __Map_Header) {
|
||||
}
|
||||
|
||||
__dynamic_map_full :: proc(using h: __Map_Header) -> bool {
|
||||
return cast(int)(0.75 * cast(f64)len(m.hashes)) <= m.entries.cap;
|
||||
return int(0.75 * f64(len(m.hashes))) <= m.entries.cap;
|
||||
}
|
||||
|
||||
|
||||
@@ -705,7 +705,7 @@ __dynamic_map_hash_equal :: proc(h: __Map_Header, a, b: __Map_Key) -> bool {
|
||||
__dynamic_map_find :: proc(using h: __Map_Header, key: __Map_Key) -> __Map_Find_Result {
|
||||
fr := __Map_Find_Result{-1, -1, -1};
|
||||
if len(m.hashes) > 0 {
|
||||
fr.hash_index = cast(int)(key.hash % cast(u64)len(m.hashes));
|
||||
fr.hash_index = int(key.hash % u64(len(m.hashes)));
|
||||
fr.entry_index = m.hashes[fr.hash_index];
|
||||
for fr.entry_index >= 0 {
|
||||
entry := __dynamic_map_get_entry(h, fr.entry_index);
|
||||
@@ -721,7 +721,7 @@ __dynamic_map_find :: proc(using h: __Map_Header, key: __Map_Key) -> __Map_Find_
|
||||
|
||||
__dynamic_map_add_entry :: proc(using h: __Map_Header, key: __Map_Key) -> int {
|
||||
prev := m.entries.len;
|
||||
c := __dynamic_array_append_nothing(^m.entries, entry_size, entry_align);
|
||||
c := __dynamic_array_append_nothing(&m.entries, entry_size, entry_align);
|
||||
if c != prev {
|
||||
end := __dynamic_map_get_entry(h, c-1);
|
||||
end.key = key;
|
||||
@@ -739,8 +739,8 @@ __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 {
|
||||
data := cast(^byte)m.entries.data + index*entry_size;
|
||||
return cast(^__Map_Entry_Header)data;
|
||||
data := ^byte(m.entries.data) + index*entry_size;
|
||||
return ^__Map_Entry_Header(data);
|
||||
}
|
||||
|
||||
__dynamic_map_erase :: proc(using h: __Map_Header, fr: __Map_Find_Result) {
|
||||
|
||||
@@ -26,7 +26,7 @@ decimal_to_string :: proc(buf: []byte, a: ^Decimal) -> string {
|
||||
|
||||
if a.count == 0 {
|
||||
buf[0] = '0';
|
||||
return cast(string)buf[0..<1];
|
||||
return string(buf[0..<1]);
|
||||
}
|
||||
|
||||
w := 0;
|
||||
@@ -44,7 +44,7 @@ decimal_to_string :: proc(buf: []byte, a: ^Decimal) -> string {
|
||||
w += digit_zero(buf[w ..< w+a.decimal_point-a.count]);
|
||||
}
|
||||
|
||||
return cast(string)buf[0..<w];
|
||||
return string(buf[0..<w]);
|
||||
}
|
||||
|
||||
// trim trailing zeros
|
||||
@@ -64,7 +64,7 @@ assign :: proc(a: ^Decimal, i: u64) {
|
||||
for i > 0 {
|
||||
j := i/10;
|
||||
i -= 10*j;
|
||||
buf[n] = cast(byte)('0'+i);
|
||||
buf[n] = byte('0'+i);
|
||||
n++;
|
||||
i = j;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ shift_right :: proc(a: ^Decimal, k: uint) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
c := cast(uint)a.digits[r];
|
||||
c := uint(a.digits[r]);
|
||||
n = n*10 + c - '0';
|
||||
}
|
||||
a.decimal_point -= r-1;
|
||||
@@ -107,10 +107,10 @@ shift_right :: proc(a: ^Decimal, k: uint) {
|
||||
mask: uint = (1<<k) - 1;
|
||||
|
||||
for ; r < a.count; r++ {
|
||||
c := cast(uint)a.digits[r];
|
||||
c := uint(a.digits[r]);
|
||||
dig := n>>k;
|
||||
n &= mask;
|
||||
a.digits[w] = cast(byte)('0' + dig);
|
||||
a.digits[w] = byte('0' + dig);
|
||||
w++;
|
||||
n = n*10 + c - '0';
|
||||
}
|
||||
@@ -119,7 +119,7 @@ shift_right :: proc(a: ^Decimal, k: uint) {
|
||||
dig := n>>k;
|
||||
n &= mask;
|
||||
if w < len(a.digits) {
|
||||
a.digits[w] = cast(byte)('0' + dig);
|
||||
a.digits[w] = byte('0' + dig);
|
||||
w++;
|
||||
} else if dig > 0 {
|
||||
a.trunc = true;
|
||||
@@ -133,19 +133,19 @@ shift_right :: proc(a: ^Decimal, k: uint) {
|
||||
}
|
||||
|
||||
shift_left :: proc(a: ^Decimal, k: uint) {
|
||||
delta := cast(int)(k/4);
|
||||
delta := int(k/4);
|
||||
|
||||
r := a.count; // read index
|
||||
w := a.count+delta; // write index
|
||||
|
||||
n: uint;
|
||||
for r--; r >= 0; r-- {
|
||||
n += (cast(uint)a.digits[r] - '0') << k;
|
||||
n += (uint(a.digits[r]) - '0') << k;
|
||||
quo := n/10;
|
||||
rem := n - 10*quo;
|
||||
w--;
|
||||
if w < len(a.digits) {
|
||||
a.digits[w] = cast(byte)('0' + rem);
|
||||
a.digits[w] = byte('0' + rem);
|
||||
} else if rem != 0 {
|
||||
a.trunc = true;
|
||||
}
|
||||
@@ -157,7 +157,7 @@ shift_left :: proc(a: ^Decimal, k: uint) {
|
||||
rem := n - 10*quo;
|
||||
w--;
|
||||
if 0 <= w && w < len(a.digits) {
|
||||
a.digits[w] = cast(byte)('0' + rem);
|
||||
a.digits[w] = byte('0' + rem);
|
||||
} else if rem != 0 {
|
||||
a.trunc = true;
|
||||
}
|
||||
@@ -179,7 +179,7 @@ shift :: proc(a: ^Decimal, k: int) {
|
||||
shift_left(a, max_shift);
|
||||
k -= max_shift;
|
||||
}
|
||||
shift_left(a, cast(uint)k);
|
||||
shift_left(a, uint(k));
|
||||
|
||||
|
||||
case k < 0:
|
||||
@@ -187,7 +187,7 @@ shift :: proc(a: ^Decimal, k: int) {
|
||||
shift_right(a, max_shift);
|
||||
k += max_shift;
|
||||
}
|
||||
shift_right(a, cast(uint)-k);
|
||||
shift_right(a, uint(-k));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ rounded_integer :: proc(a: ^Decimal) -> u64 {
|
||||
n: u64 = 0;
|
||||
m := min(a.decimal_point, a.count);
|
||||
for i = 0; i < m; i++ {
|
||||
n = n*10 + cast(u64)(a.digits[i]-'0');
|
||||
n = n*10 + u64(a.digits[i]-'0');
|
||||
}
|
||||
for ; i < a.decimal_point; i++ {
|
||||
n *= 10;
|
||||
|
||||
217
core/fmt.odin
217
core/fmt.odin
@@ -37,12 +37,12 @@ string_buffer_data :: proc(buf: String_Buffer) -> []byte {
|
||||
return buf.sa[..];
|
||||
}
|
||||
to_string :: proc(buf: String_Buffer) -> string {
|
||||
return cast(string)string_buffer_data(buf);
|
||||
return string(string_buffer_data(buf));
|
||||
}
|
||||
|
||||
|
||||
write_string :: proc(buf: ^String_Buffer, s: string) {
|
||||
write_bytes(buf, cast([]byte)s);
|
||||
write_bytes(buf, []byte(s));
|
||||
}
|
||||
write_bytes :: proc(buf: ^String_Buffer, b: []byte) {
|
||||
if buf.is_dynamic {
|
||||
@@ -60,7 +60,7 @@ write_byte :: proc(buf: ^String_Buffer, b: byte) {
|
||||
}
|
||||
write_rune :: proc(buf: ^String_Buffer, r: rune) {
|
||||
if r < utf8.RUNE_SELF {
|
||||
write_byte(buf, cast(byte)r);
|
||||
write_byte(buf, byte(r));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ Fmt_Info :: struct {
|
||||
fprint :: proc(fd: os.Handle, args: ..any) -> int {
|
||||
data: [_BUFFER_SIZE]byte;
|
||||
buf := make_string_buffer_from_slice(data[0..<0]);
|
||||
sbprint(^buf, ..args);
|
||||
sbprint(&buf, ..args);
|
||||
res := string_buffer_data(buf);
|
||||
os.write(fd, res);
|
||||
return len(res);
|
||||
@@ -101,7 +101,7 @@ fprint :: proc(fd: os.Handle, args: ..any) -> int {
|
||||
fprintln :: proc(fd: os.Handle, args: ..any) -> int {
|
||||
data: [_BUFFER_SIZE]byte;
|
||||
buf := make_string_buffer_from_slice(data[0..<0]);
|
||||
sbprintln(^buf, ..args);
|
||||
sbprintln(&buf, ..args);
|
||||
res := string_buffer_data(buf);
|
||||
os.write(fd, res);
|
||||
return len(res);
|
||||
@@ -109,7 +109,7 @@ fprintln :: proc(fd: os.Handle, args: ..any) -> int {
|
||||
fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
|
||||
data: [_BUFFER_SIZE]byte;
|
||||
buf := make_string_buffer_from_slice(data[0..<0]);
|
||||
sbprintf(^buf, fmt, ..args);
|
||||
sbprintf(&buf, fmt, ..args);
|
||||
res := string_buffer_data(buf);
|
||||
os.write(fd, res);
|
||||
return len(res);
|
||||
@@ -131,17 +131,17 @@ printf :: proc(fmt: string, args: ..any) -> int {
|
||||
// They must be freed accordingly
|
||||
aprint :: proc(args: ..any) -> string {
|
||||
buf := make_string_dynamic_buffer();
|
||||
sbprint(^buf, ..args);
|
||||
sbprint(&buf, ..args);
|
||||
return to_string(buf);
|
||||
}
|
||||
aprintln :: proc(args: ..any) -> string {
|
||||
buf := make_string_dynamic_buffer();
|
||||
sbprintln(^buf, ..args);
|
||||
sbprintln(&buf, ..args);
|
||||
return to_string(buf);
|
||||
}
|
||||
aprintf :: proc(fmt: string, args: ..any) -> string {
|
||||
buf := make_string_dynamic_buffer();
|
||||
sbprintf(^buf, fmt, ..args);
|
||||
sbprintf(&buf, fmt, ..args);
|
||||
return to_string(buf);
|
||||
}
|
||||
|
||||
@@ -153,15 +153,15 @@ aprintf :: proc(fmt: string, args: ..any) -> string {
|
||||
// They must be freed accordingly
|
||||
bprint :: proc(buf: []byte, args: ..any) -> int {
|
||||
sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
|
||||
return sbprint(^sb, ..args);
|
||||
return sbprint(&sb, ..args);
|
||||
}
|
||||
bprintln :: proc(buf: []byte, args: ..any) -> int {
|
||||
sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
|
||||
return sbprintln(^sb, ..args);
|
||||
return sbprintln(&sb, ..args);
|
||||
}
|
||||
bprintf :: proc(buf: []byte, fmt: string, args: ..any) -> int {
|
||||
sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
|
||||
return sbprintf(^sb, fmt, ..args);
|
||||
return sbprintf(&sb, fmt, ..args);
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ bprintf :: proc(buf: []byte, fmt: string, args: ..any) -> int {
|
||||
fprint_type :: proc(fd: os.Handle, info: ^Type_Info) {
|
||||
data: [_BUFFER_SIZE]byte;
|
||||
buf := make_string_buffer_from_slice(data[0..<0]);
|
||||
write_type(^buf, info);
|
||||
write_type(&buf, info);
|
||||
os.write(fd, string_buffer_data(buf));
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) {
|
||||
default:
|
||||
write_string(buf, info.signed ? "i" : "u");
|
||||
fi := Fmt_Info{buf = buf};
|
||||
fmt_int(^fi, cast(u64)(8*info.size), false, 64, 'd');
|
||||
fmt_int(&fi, u64(8*info.size), false, 64, 'd');
|
||||
}
|
||||
|
||||
case Float:
|
||||
@@ -228,7 +228,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) {
|
||||
if info.params == nil {
|
||||
write_string(buf, "()");
|
||||
} else {
|
||||
t := union_cast(^Tuple)info.params;
|
||||
t := info.params.(^Tuple);
|
||||
write_string(buf, "(");
|
||||
for type, i in t.types {
|
||||
if i > 0 { write_string(buf, ", "); }
|
||||
@@ -259,7 +259,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) {
|
||||
case Array:
|
||||
write_string(buf, "[");
|
||||
fi := Fmt_Info{buf = buf};
|
||||
fmt_int(^fi, cast(u64)info.count, false, 64, 'd');
|
||||
fmt_int(&fi, u64(info.count), false, 64, 'd');
|
||||
write_string(buf, "]");
|
||||
write_type(buf, info.elem);
|
||||
case Dynamic_Array:
|
||||
@@ -271,7 +271,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) {
|
||||
case Vector:
|
||||
write_string(buf, "[vector ");
|
||||
fi := Fmt_Info{buf = buf};
|
||||
fmt_int(^fi, cast(u64)info.count, false, 64, 'd');
|
||||
fmt_int(&fi, u64(info.count), false, 64, 'd');
|
||||
write_string(buf, "]");
|
||||
write_type(buf, info.elem);
|
||||
|
||||
@@ -288,7 +288,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) {
|
||||
if info.custom_align {
|
||||
write_string(buf, "#align ");
|
||||
fi := Fmt_Info{buf = buf};
|
||||
fmt_int(^fi, cast(u64)info.align, false, 64, 'd');
|
||||
fmt_int(&fi, u64(info.align), false, 64, 'd');
|
||||
write_byte(buf, ' ');
|
||||
}
|
||||
write_byte(buf, '{');
|
||||
@@ -324,7 +324,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) {
|
||||
defer write_byte(buf, '}');
|
||||
|
||||
variant_type := type_info_base(info.variant_types[i]);
|
||||
variant := union_cast(^Struct)variant_type;
|
||||
variant := variant_type.(^Struct);
|
||||
|
||||
vc := len(variant.names)-len(cf.names);
|
||||
for j in 0..vc {
|
||||
@@ -376,26 +376,21 @@ _parse_int :: proc(s: string, offset: int) -> (result: int, offset: int, ok: boo
|
||||
ok := true;
|
||||
|
||||
i := 0;
|
||||
for o in offset..len(s) {
|
||||
c := cast(rune)s[offset+i];
|
||||
for i < len(s[offset..]) {
|
||||
c := rune(s[offset+i]);
|
||||
if !is_digit(c) {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
|
||||
result *= 10;
|
||||
result += cast(int)(c - '0');
|
||||
result += int(c)-'0';
|
||||
}
|
||||
|
||||
return result, offset+i, i != 0;
|
||||
}
|
||||
|
||||
_arg_number :: proc(fi: ^Fmt_Info,
|
||||
arg_index: int,
|
||||
format: string,
|
||||
offset: int,
|
||||
arg_count: int,
|
||||
) -> (index: int, offset: int, ok: bool) {
|
||||
_arg_number :: proc(fi: ^Fmt_Info, arg_index: int, format: string, offset, arg_count: int) -> (index, offset: int, ok: bool) {
|
||||
parse_arg_number :: proc(format: string) -> (int, int, bool) {
|
||||
if len(format) < 3 {
|
||||
return 0, 1, false;
|
||||
@@ -436,14 +431,14 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
|
||||
arg.type_info = type_info_base(arg.type_info);
|
||||
match i in arg {
|
||||
case int: num = i;
|
||||
case i8: num = cast(int)i;
|
||||
case i16: num = cast(int)i;
|
||||
case i32: num = cast(int)i;
|
||||
case i64: num = cast(int)i;
|
||||
case u8: num = cast(int)i;
|
||||
case u16: num = cast(int)i;
|
||||
case u32: num = cast(int)i;
|
||||
case u64: num = cast(int)i;
|
||||
case i8: num = int(i);
|
||||
case i16: num = int(i);
|
||||
case i32: num = int(i);
|
||||
case i64: num = int(i);
|
||||
case u8: num = int(i);
|
||||
case u16: num = int(i);
|
||||
case u32: num = int(i);
|
||||
case u64: num = int(i);
|
||||
default:
|
||||
ok = false;
|
||||
}
|
||||
@@ -500,25 +495,25 @@ is_integer_negative :: proc(u: u64, is_signed: bool, bit_size: int) -> (unsigned
|
||||
if is_signed {
|
||||
match bit_size {
|
||||
case 8:
|
||||
i := cast(i8)u;
|
||||
i := i8(u);
|
||||
neg = i < 0;
|
||||
if neg { i = -i; }
|
||||
u = cast(u64)i;
|
||||
u = u64(i);
|
||||
case 16:
|
||||
i := cast(i16)u;
|
||||
i := i16(u);
|
||||
neg = i < 0;
|
||||
if neg { i = -i; }
|
||||
u = cast(u64)i;
|
||||
u = u64(i);
|
||||
case 32:
|
||||
i := cast(i32)u;
|
||||
i := i32(u);
|
||||
neg = i < 0;
|
||||
if neg { i = -i; }
|
||||
u = cast(u64)i;
|
||||
u = u64(i);
|
||||
case 64:
|
||||
i := cast(i64)u;
|
||||
i := i64(u);
|
||||
neg = i < 0;
|
||||
if neg { i = -i; }
|
||||
u = cast(u64)i;
|
||||
u = u64(i);
|
||||
default:
|
||||
panic("is_integer_negative: Unknown integer size");
|
||||
}
|
||||
@@ -592,9 +587,9 @@ fmt_int :: proc(fi: ^Fmt_Info, u: u64, is_signed: bool, bit_size: int, verb: run
|
||||
case 'x': _write_int(fi, u, 16, is_signed, bit_size, __DIGITS_LOWER);
|
||||
case 'X': _write_int(fi, u, 16, is_signed, bit_size, __DIGITS_UPPER);
|
||||
case 'c', 'r':
|
||||
fmt_rune(fi, cast(rune)u);
|
||||
fmt_rune(fi, rune(u));
|
||||
case 'U':
|
||||
r := cast(rune)u;
|
||||
r := rune(u);
|
||||
if r < 0 || r > utf8.MAX_RUNE {
|
||||
fmt_bad_verb(fi, verb);
|
||||
} else {
|
||||
@@ -634,7 +629,7 @@ fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) {
|
||||
}
|
||||
buf: [128]byte;
|
||||
str := strconv.append_float(buf[1..<1], v, 'f', prec, bit_size);
|
||||
str = cast(string)buf[0..<len(str)];
|
||||
str = string(buf[0..<len(str)]);
|
||||
if str[1] == '+' || str[1] == '-' {
|
||||
str = str[1..];
|
||||
} else {
|
||||
@@ -645,7 +640,7 @@ fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) {
|
||||
str[0] = ' ';
|
||||
}
|
||||
|
||||
if str[1] == 'N' && str[1] == 'I' {
|
||||
if len(str) > 1 && str[1] == 'N' && str[1] == 'I' {
|
||||
write_string(fi.buf, str);
|
||||
return;
|
||||
}
|
||||
@@ -681,7 +676,7 @@ fmt_string :: proc(fi: ^Fmt_Info, s: string, verb: rune) {
|
||||
if i > 0 && space {
|
||||
write_byte(fi.buf, ' ');
|
||||
}
|
||||
_write_int(fi, cast(u64)s[i], 16, false, 8, verb == 'x' ? __DIGITS_LOWER : __DIGITS_UPPER);
|
||||
_write_int(fi, u64(s[i]), 16, false, 8, verb == 'x' ? __DIGITS_LOWER : __DIGITS_UPPER);
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -697,7 +692,7 @@ fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) {
|
||||
fmt_bad_verb(fi, verb);
|
||||
return;
|
||||
}
|
||||
u := cast(u64)cast(uint)p;
|
||||
u := u64(uint(p));
|
||||
if !fi.hash || verb == 'v' {
|
||||
write_string(fi.buf, "0x");
|
||||
}
|
||||
@@ -725,18 +720,18 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
ok := false;
|
||||
a := any{v.data, type_info_base(e.base)};
|
||||
match v in a {
|
||||
case i8: i = cast(i64)v;
|
||||
case i16: i = cast(i64)v;
|
||||
case i32: i = cast(i64)v;
|
||||
case i64: i = cast(i64)v;
|
||||
case int: i = cast(i64)v;
|
||||
case u8: i = cast(i64)v;
|
||||
case u16: i = cast(i64)v;
|
||||
case u32: i = cast(i64)v;
|
||||
case u64: i = cast(i64)v;
|
||||
case uint: i = cast(i64)v;
|
||||
case f32: f = cast(f64)v; i = transmute(i64)f;
|
||||
case f64: f = cast(f64)v; i = transmute(i64)f;
|
||||
case i8: i = i64(v);
|
||||
case i16: i = i64(v);
|
||||
case i32: i = i64(v);
|
||||
case i64: i = i64(v);
|
||||
case int: i = i64(v);
|
||||
case u8: i = i64(v);
|
||||
case u16: i = i64(v);
|
||||
case u32: i = i64(v);
|
||||
case u64: i = i64(v);
|
||||
case uint: i = i64(v);
|
||||
case f32: f = f64(v); i = transmute(i64, f);
|
||||
case f64: f = f64(v); i = transmute(i64, f);
|
||||
}
|
||||
|
||||
if types.is_string(e.base) {
|
||||
@@ -794,8 +789,8 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
}
|
||||
write_string(fi.buf, b.names[i]);
|
||||
write_string(fi.buf, " = ");
|
||||
data := cast(^byte)v.data + b.offsets[i];
|
||||
fmt_arg(fi, any{cast(rawptr)data, b.types[i]}, 'v');
|
||||
data := ^byte(v.data) + b.offsets[i];
|
||||
fmt_arg(fi, any{rawptr(data), b.types[i]}, 'v');
|
||||
}
|
||||
write_byte(fi.buf, '}');
|
||||
|
||||
@@ -812,9 +807,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
|
||||
case Pointer:
|
||||
if v.type_info == type_info(^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 Atomic:
|
||||
@@ -832,8 +827,8 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
if i > 0 {
|
||||
write_string(fi.buf, ", ");
|
||||
}
|
||||
data := cast(^byte)v.data + i*info.elem_size;
|
||||
fmt_arg(fi, any{cast(rawptr)data, info.elem}, 'v');
|
||||
data := ^byte(v.data) + i*info.elem_size;
|
||||
fmt_arg(fi, any{rawptr(data), info.elem}, 'v');
|
||||
}
|
||||
|
||||
case Dynamic_Array:
|
||||
@@ -844,13 +839,13 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
|
||||
write_byte(fi.buf, '[');
|
||||
defer write_byte(fi.buf, ']');
|
||||
array := cast(^raw.Dynamic_Array)v.data;
|
||||
array := (^raw.Dynamic_Array)(v.data);
|
||||
for i in 0..<array.len {
|
||||
if i > 0 {
|
||||
write_string(fi.buf, ", ");
|
||||
}
|
||||
data := cast(^byte)array.data + i*info.elem_size;
|
||||
fmt_arg(fi, any{cast(rawptr)data, info.elem}, 'v');
|
||||
data := ^byte(array.data) + i*info.elem_size;
|
||||
fmt_arg(fi, any{rawptr(data), info.elem}, 'v');
|
||||
}
|
||||
|
||||
case Map:
|
||||
@@ -861,30 +856,30 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
|
||||
write_string(fi.buf, "map[");
|
||||
defer write_byte(fi.buf, ']');
|
||||
entries := ^(cast(^raw.Dynamic_Map)v.data).entries;
|
||||
gs := union_cast(^Struct)type_info_base(info.generated_struct);
|
||||
ed := union_cast(^Dynamic_Array)type_info_base(gs.types[1]);
|
||||
entries := &(^raw.Dynamic_Map(v.data).entries);
|
||||
gs := type_info_base(info.generated_struct).(^Struct);
|
||||
ed := type_info_base(gs.types[1]).(^Dynamic_Array);
|
||||
|
||||
entry_type := union_cast(^Struct)ed.elem;
|
||||
entry_type := ed.elem.(^Struct);
|
||||
entry_size := ed.elem_size;
|
||||
for i in 0..<entries.len {
|
||||
if i > 0 {
|
||||
write_string(fi.buf, ", ");
|
||||
}
|
||||
data := cast(^byte)entries.data + i*entry_size;
|
||||
data := ^byte(entries.data) + i*entry_size;
|
||||
|
||||
header := cast(^__Map_Entry_Header)data;
|
||||
header := ^__Map_Entry_Header(data);
|
||||
if types.is_string(info.key) {
|
||||
write_string(fi.buf, header.key.str);
|
||||
} else {
|
||||
fi := Fmt_Info{buf = fi.buf};
|
||||
fmt_arg(^fi, any{cast(rawptr)^header.key.hash, info.key}, 'v');
|
||||
fmt_arg(&fi, any{rawptr(&header.key.hash), info.key}, 'v');
|
||||
}
|
||||
|
||||
write_string(fi.buf, "=");
|
||||
|
||||
value := data + entry_type.offsets[2];
|
||||
fmt_arg(fi, any{cast(rawptr)value, info.value}, 'v');
|
||||
fmt_arg(fi, any{rawptr(value), info.value}, 'v');
|
||||
}
|
||||
|
||||
case Slice:
|
||||
@@ -895,13 +890,13 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
|
||||
write_byte(fi.buf, '[');
|
||||
defer write_byte(fi.buf, ']');
|
||||
slice := cast(^[]byte)v.data;
|
||||
slice := (^[]byte)(v.data);
|
||||
for _, i in slice {
|
||||
if i > 0 {
|
||||
write_string(fi.buf, ", ");
|
||||
}
|
||||
data := ^slice[0] + i*info.elem_size;
|
||||
fmt_arg(fi, any{cast(rawptr)data, info.elem}, 'v');
|
||||
data := &slice[0] + i*info.elem_size;
|
||||
fmt_arg(fi, any{rawptr(data), info.elem}, 'v');
|
||||
}
|
||||
|
||||
case Vector:
|
||||
@@ -913,8 +908,8 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
write_string(fi.buf, ", ");
|
||||
}
|
||||
|
||||
data := cast(^byte)v.data + i*info.elem_size;
|
||||
fmt_value(fi, any{cast(rawptr)data, info.elem}, 'v');
|
||||
data := ^byte(v.data) + i*info.elem_size;
|
||||
fmt_value(fi, any{rawptr(data), info.elem}, 'v');
|
||||
}
|
||||
|
||||
case Struct:
|
||||
@@ -927,8 +922,8 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
}
|
||||
write_string(fi.buf, info.names[i]);
|
||||
write_string(fi.buf, " = ");
|
||||
data := cast(^byte)v.data + info.offsets[i];
|
||||
fmt_value(fi, any{cast(rawptr)data, info.types[i]}, 'v');
|
||||
data := ^byte(v.data) + info.offsets[i];
|
||||
fmt_value(fi, any{rawptr(data), info.types[i]}, 'v');
|
||||
}
|
||||
|
||||
case Union:
|
||||
@@ -943,8 +938,8 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
}
|
||||
write_string(fi.buf, cf.names[i]);
|
||||
write_string(fi.buf, " = ");
|
||||
data := cast(^byte)v.data + cf.offsets[i];
|
||||
fmt_value(fi, any{cast(rawptr)data, cf.types[i]}, 'v');
|
||||
data := ^byte(v.data) + cf.offsets[i];
|
||||
fmt_value(fi, any{rawptr(data), cf.types[i]}, 'v');
|
||||
}
|
||||
|
||||
case Raw_Union:
|
||||
@@ -956,7 +951,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
case 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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1027,23 +1022,23 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
|
||||
match a in base_arg {
|
||||
case any: fmt_arg(fi, a, verb);
|
||||
case bool: fmt_bool(fi, a, verb);
|
||||
case f32: fmt_float(fi, cast(f64)a, 32, verb);
|
||||
case f32: fmt_float(fi, f64(a), 32, verb);
|
||||
case f64: fmt_float(fi, a, 64, verb);
|
||||
case complex64: fmt_complex(fi, cast(complex128)a, 64, verb);
|
||||
case complex64: fmt_complex(fi, complex128(a), 64, verb);
|
||||
case complex128: fmt_complex(fi, a, 128, verb);
|
||||
case quaternion128: fmt_quaternion(fi, cast(quaternion256)a, 128, verb);
|
||||
case quaternion128: fmt_quaternion(fi, quaternion256(a), 128, verb);
|
||||
case quaternion256: fmt_quaternion(fi, a, 256, verb);
|
||||
|
||||
case int: fmt_int(fi, cast(u64)a, true, 8*size_of(int), verb);
|
||||
case i8: fmt_int(fi, cast(u64)a, true, 8, verb);
|
||||
case i16: fmt_int(fi, cast(u64)a, true, 16, verb);
|
||||
case i32: fmt_int(fi, cast(u64)a, true, 32, verb);
|
||||
case i64: fmt_int(fi, cast(u64)a, true, 64, verb);
|
||||
case uint: fmt_int(fi, cast(u64)a, false, 8*size_of(uint), verb);
|
||||
case u8: fmt_int(fi, cast(u64)a, false, 8, verb);
|
||||
case u16: fmt_int(fi, cast(u64)a, false, 16, verb);
|
||||
case u32: fmt_int(fi, cast(u64)a, false, 32, verb);
|
||||
case u64: fmt_int(fi, cast(u64)a, false, 64, verb);
|
||||
case int: fmt_int(fi, u64(a), true, 8*size_of(int), verb);
|
||||
case i8: fmt_int(fi, u64(a), true, 8, verb);
|
||||
case i16: fmt_int(fi, u64(a), true, 16, verb);
|
||||
case i32: fmt_int(fi, u64(a), true, 32, verb);
|
||||
case i64: fmt_int(fi, u64(a), true, 64, verb);
|
||||
case uint: fmt_int(fi, u64(a), false, 8*size_of(uint), verb);
|
||||
case u8: fmt_int(fi, u64(a), false, 8, verb);
|
||||
case u16: fmt_int(fi, u64(a), false, 16, verb);
|
||||
case u32: fmt_int(fi, u64(a), false, 32, verb);
|
||||
case u64: fmt_int(fi, u64(a), false, 64, verb);
|
||||
case string: fmt_string(fi, a, verb);
|
||||
default: fmt_value(fi, arg, verb);
|
||||
}
|
||||
@@ -1062,7 +1057,7 @@ sbprint :: proc(buf: ^String_Buffer, args: ..any) -> int {
|
||||
if i > 0 && !is_string && !prev_string {
|
||||
write_byte(buf, ' ');
|
||||
}
|
||||
fmt_value(^fi, args[i], 'v');
|
||||
fmt_value(&fi, args[i], 'v');
|
||||
prev_string = is_string;
|
||||
}
|
||||
return len(string_buffer_data(buf));
|
||||
@@ -1076,7 +1071,7 @@ sbprintln :: proc(buf: ^String_Buffer, args: ..any) -> int {
|
||||
if i > 0 {
|
||||
write_byte(buf, ' ');
|
||||
}
|
||||
fmt_value(^fi, args[i], 'v');
|
||||
fmt_value(&fi, args[i], 'v');
|
||||
}
|
||||
write_byte(buf, '\n');
|
||||
return len(string_buffer_data(buf));
|
||||
@@ -1123,7 +1118,7 @@ sbprintf :: proc(b: ^String_Buffer, fmt: string, args: ..any) -> int {
|
||||
}
|
||||
}
|
||||
|
||||
arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, len(args));
|
||||
arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args));
|
||||
|
||||
// Width
|
||||
if i < end && fmt[i] == '*' {
|
||||
@@ -1153,7 +1148,7 @@ sbprintf :: proc(b: ^String_Buffer, fmt: string, args: ..any) -> int {
|
||||
fi.good_arg_index = false;
|
||||
}
|
||||
if i < end && fmt[i] == '*' {
|
||||
arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, len(args));
|
||||
arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args));
|
||||
i++;
|
||||
fi.prec, arg_index, fi.prec_set = int_from_arg(args, arg_index);
|
||||
if fi.prec < 0 {
|
||||
@@ -1167,14 +1162,14 @@ sbprintf :: proc(b: ^String_Buffer, fmt: string, args: ..any) -> int {
|
||||
} else {
|
||||
fi.prec, i, fi.prec_set = _parse_int(fmt, i);
|
||||
if !fi.prec_set {
|
||||
fi.prec_set = true;
|
||||
fi.prec = 0;
|
||||
// fi.prec_set = true;
|
||||
// fi.prec = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !was_prev_index {
|
||||
arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, len(args));
|
||||
arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args));
|
||||
}
|
||||
|
||||
if i >= end {
|
||||
@@ -1192,7 +1187,7 @@ sbprintf :: proc(b: ^String_Buffer, fmt: string, args: ..any) -> int {
|
||||
} else if arg_index >= len(args) {
|
||||
write_string(b, "%!(MISSING ARGUMENT)");
|
||||
} else {
|
||||
fmt_arg(^fi, args[arg_index], verb);
|
||||
fmt_arg(&fi, args[arg_index], verb);
|
||||
arg_index++;
|
||||
}
|
||||
}
|
||||
@@ -1206,7 +1201,7 @@ sbprintf :: proc(b: ^String_Buffer, fmt: string, args: ..any) -> int {
|
||||
if arg == nil {
|
||||
write_string(b, "<nil>");
|
||||
} else {
|
||||
fmt_arg(^fi, args[index], 'v');
|
||||
fmt_arg(&fi, args[index], 'v');
|
||||
}
|
||||
}
|
||||
write_string(b, ")");
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
crc32 :: proc(data: []byte) -> u32 {
|
||||
result := ~cast(u32)0;
|
||||
result := ~u32(0);
|
||||
for b in data {
|
||||
result = result>>8 ~ _crc32_table[(result ~ cast(u32)b) & 0xff];
|
||||
result = result>>8 ~ _crc32_table[(result ~ u32(b)) & 0xff];
|
||||
}
|
||||
return ~result;
|
||||
}
|
||||
crc64 :: proc(data: []byte) -> u64 {
|
||||
result := ~cast(u64)0;
|
||||
result := ~u64(0);
|
||||
for b in data {
|
||||
result = result>>8 ~ _crc64_table[(result ~ cast(u64)b) & 0xff];
|
||||
result = result>>8 ~ _crc64_table[(result ~ u64(b)) & 0xff];
|
||||
}
|
||||
return ~result;
|
||||
}
|
||||
@@ -16,7 +16,7 @@ crc64 :: proc(data: []byte) -> u64 {
|
||||
fnv32 :: proc(data: []byte) -> u32 {
|
||||
h: u32 = 0x811c9dc5;
|
||||
for b in data {
|
||||
h = (h * 0x01000193) ~ cast(u32)b;
|
||||
h = (h * 0x01000193) ~ u32(b);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
@@ -24,7 +24,7 @@ fnv32 :: proc(data: []byte) -> u32 {
|
||||
fnv64 :: proc(data: []byte) -> u64 {
|
||||
h: u64 = 0xcbf29ce484222325;
|
||||
for b in data {
|
||||
h = (h * 0x100000001b3) ~ cast(u64)b;
|
||||
h = (h * 0x100000001b3) ~ u64(b);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ fnv64 :: proc(data: []byte) -> u64 {
|
||||
fnv32a :: proc(data: []byte) -> u32 {
|
||||
h: u32 = 0x811c9dc5;
|
||||
for b in data {
|
||||
h = (h ~ cast(u32)b) * 0x01000193;
|
||||
h = (h ~ u32(b)) * 0x01000193;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
@@ -40,7 +40,7 @@ fnv32a :: proc(data: []byte) -> u32 {
|
||||
fnv64a :: proc(data: []byte) -> u64 {
|
||||
h: u64 = 0xcbf29ce484222325;
|
||||
for b in data {
|
||||
h = (h ~ cast(u64)b) * 0x100000001b3;
|
||||
h = (h ~ u64(b)) * 0x100000001b3;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
@@ -51,11 +51,11 @@ murmur32 :: proc(data: []byte) -> u32 {
|
||||
|
||||
h1: u32 = 0;
|
||||
nblocks := len(data)/4;
|
||||
p := ^data[0];
|
||||
p := &data[0];
|
||||
p1 := p + 4*nblocks;
|
||||
|
||||
for ; p < p1; p += 4 {
|
||||
k1 := (cast(^u32)p)^;
|
||||
k1 := ^u32(p)^;
|
||||
|
||||
k1 *= c1_32;
|
||||
k1 = (k1 << 15) | (k1 >> 17);
|
||||
@@ -71,20 +71,20 @@ murmur32 :: proc(data: []byte) -> u32 {
|
||||
k1: u32;
|
||||
match len(tail)&3 {
|
||||
case 3:
|
||||
k1 ~= cast(u32)tail[2] << 16;
|
||||
k1 ~= u32(tail[2]) << 16;
|
||||
fallthrough;
|
||||
case 2:
|
||||
k1 ~= cast(u32)tail[2] << 8;
|
||||
k1 ~= u32(tail[2]) << 8;
|
||||
fallthrough;
|
||||
case 1:
|
||||
k1 ~= cast(u32)tail[0];
|
||||
k1 ~= u32(tail[0]);
|
||||
k1 *= c1_32;
|
||||
k1 = (k1 << 15) | (k1 >> 17) ;
|
||||
k1 *= c2_32;
|
||||
h1 ~= k1;
|
||||
}
|
||||
|
||||
h1 ~= cast(u32)len(data);
|
||||
h1 ~= u32(len(data));
|
||||
|
||||
h1 ~= h1 >> 16;
|
||||
h1 *= 0x85ebca6b;
|
||||
@@ -98,12 +98,12 @@ murmur32 :: proc(data: []byte) -> u32 {
|
||||
murmur64 :: proc(data: []byte) -> u64 {
|
||||
SEED :: 0x9747b28c;
|
||||
|
||||
when false && size_of(int) == 8 {
|
||||
when size_of(int) == 8 {
|
||||
m :: 0xc6a4a7935bd1e995;
|
||||
r :: 47;
|
||||
|
||||
h: u64 = SEED ~ (cast(u64)data.count * m);
|
||||
data64 := slice_ptr(cast(^u64)^data[0], data.count/size_of(u64));
|
||||
h: u64 = SEED ~ (u64(len(data)) * m);
|
||||
data64 := slice_ptr(^u64(&data[0]), len(data)/size_of(u64));
|
||||
|
||||
for _, i in data64 {
|
||||
k := data64[i];
|
||||
@@ -116,15 +116,15 @@ murmur64 :: proc(data: []byte) -> u64 {
|
||||
h *= m;
|
||||
}
|
||||
|
||||
match data.count&7 {
|
||||
case 7: h ~= cast(u64)data[6] << 48; fallthrough;
|
||||
case 6: h ~= cast(u64)data[5] << 40; fallthrough;
|
||||
case 5: h ~= cast(u64)data[4] << 32; fallthrough;
|
||||
case 4: h ~= cast(u64)data[3] << 24; fallthrough;
|
||||
case 3: h ~= cast(u64)data[2] << 16; fallthrough;
|
||||
case 2: h ~= cast(u64)data[1] << 8; fallthrough;
|
||||
match len(data)&7 {
|
||||
case 7: h ~= u64(data[6]) << 48; fallthrough;
|
||||
case 6: h ~= u64(data[5]) << 40; fallthrough;
|
||||
case 5: h ~= u64(data[4]) << 32; fallthrough;
|
||||
case 4: h ~= u64(data[3]) << 24; fallthrough;
|
||||
case 3: h ~= u64(data[2]) << 16; fallthrough;
|
||||
case 2: h ~= u64(data[1]) << 8; fallthrough;
|
||||
case 1:
|
||||
h ~= cast(u64)data[0];
|
||||
h ~= u64(data[0]);
|
||||
h *= m;
|
||||
}
|
||||
|
||||
@@ -137,10 +137,10 @@ murmur64 :: proc(data: []byte) -> u64 {
|
||||
m :: 0x5bd1e995;
|
||||
r :: 24;
|
||||
|
||||
h1: u32 = cast(u32)SEED ~ cast(u32)len(data);
|
||||
h2: u32 = SEED >> 32;
|
||||
h1 := u32(SEED) ~ u32(len(data));
|
||||
h2 := u32(SEED) >> 32;
|
||||
|
||||
data32 := slice_ptr(cast(^u32)^data[0], len(data)/size_of(u32));
|
||||
data32 := slice_ptr(cast(^u32)&data[0], len(data)/size_of(u32));
|
||||
len := len(data);
|
||||
|
||||
i := 0;
|
||||
@@ -175,16 +175,16 @@ murmur64 :: proc(data: []byte) -> u64 {
|
||||
}
|
||||
|
||||
// TODO(bill): Fix this
|
||||
#no_bounds_check data8 := slice_to_bytes(data32[i..])[..<3];
|
||||
#no_bounds_check data8 := slice_to_bytes(data32[i..])[0..<3];
|
||||
match len {
|
||||
case 3:
|
||||
h2 ~= cast(u32)data8[2] << 16;
|
||||
h2 ~= u32(data8[2]) << 16;
|
||||
fallthrough;
|
||||
case 2:
|
||||
h2 ~= cast(u32)data8[1] << 8;
|
||||
h2 ~= u32(data8[1]) << 8;
|
||||
fallthrough;
|
||||
case 1:
|
||||
h2 ~= cast(u32)data8[0];
|
||||
h2 ~= u32(data8[0]);
|
||||
h2 *= m;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,29 +55,29 @@ fmuladd :: proc(a, b, c: f64) -> f64 #foreign __llvm_core "llvm.fmuladd.f64";
|
||||
|
||||
|
||||
copy_sign :: proc(x, y: f32) -> f32 {
|
||||
ix := transmute(u32)x;
|
||||
iy := transmute(u32)y;
|
||||
ix := transmute(u32, x);
|
||||
iy := transmute(u32, y);
|
||||
ix &= 0x7fff_ffff;
|
||||
ix |= iy & 0x8000_0000;
|
||||
return transmute(f32)ix;
|
||||
return transmute(f32, ix);
|
||||
}
|
||||
|
||||
copy_sign :: proc(x, y: f64) -> f64 {
|
||||
ix := transmute(u64)x;
|
||||
iy := transmute(u64)y;
|
||||
ix := transmute(u64, x);
|
||||
iy := transmute(u64, y);
|
||||
ix &= 0x7fff_ffff_ffff_ff;
|
||||
ix |= iy & 0x8000_0000_0000_0000;
|
||||
return transmute(f64)ix;
|
||||
return transmute(f64, ix);
|
||||
}
|
||||
|
||||
round :: proc(x: f32) -> f32 { return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5); }
|
||||
round :: proc(x: f64) -> f64 { return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5); }
|
||||
|
||||
floor :: proc(x: f32) -> f32 { return x >= 0 ? cast(f32)cast(i64)x : cast(f32)cast(i64)(x-0.5); } // TODO: Get accurate versions
|
||||
floor :: proc(x: f64) -> f64 { return x >= 0 ? cast(f64)cast(i64)x : cast(f64)cast(i64)(x-0.5); } // TODO: Get accurate versions
|
||||
floor :: proc(x: f32) -> f32 { return x >= 0 ? f32(i64(x)) : f32(i64(x-0.5)); } // TODO: Get accurate versions
|
||||
floor :: proc(x: f64) -> f64 { return x >= 0 ? f64(i64(x)) : f64(i64(x-0.5)); } // TODO: Get accurate versions
|
||||
|
||||
ceil :: proc(x: f32) -> f32 { return x < 0 ? cast(f32)cast(i64)x : cast(f32)cast(i64)(x+1); } // TODO: Get accurate versions
|
||||
ceil :: proc(x: f64) -> f64 { return x < 0 ? cast(f64)cast(i64)x : cast(f64)cast(i64)(x+1); } // TODO: Get accurate versions
|
||||
ceil :: proc(x: f32) -> f32 { return x < 0 ? f32(i64(x)) : f32(i64(x+1)); } // TODO: Get accurate versions
|
||||
ceil :: proc(x: f64) -> f64 { return x < 0 ? f64(i64(x)) : f64(i64(x+1)); } // TODO: Get accurate versions
|
||||
|
||||
remainder :: proc(x, y: f32) -> f32 { return x - round(x/y) * y; }
|
||||
remainder :: proc(x, y: f64) -> f64 { return x - round(x/y) * y; }
|
||||
|
||||
@@ -19,7 +19,7 @@ copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr {
|
||||
return __mem_copy_non_overlapping(dst, src, len);
|
||||
}
|
||||
compare :: proc(a, b: []byte) -> int {
|
||||
return __mem_compare(^a[0], ^b[0], min(len(a), len(b)));
|
||||
return __mem_compare(&a[0], &b[0], min(len(a), len(b)));
|
||||
}
|
||||
|
||||
|
||||
@@ -39,13 +39,13 @@ is_power_of_two :: proc(x: int) -> bool {
|
||||
align_forward :: proc(ptr: rawptr, align: int) -> rawptr {
|
||||
assert(is_power_of_two(align));
|
||||
|
||||
a := cast(uint)align;
|
||||
p := cast(uint)ptr;
|
||||
a := uint(align);
|
||||
p := uint(ptr);
|
||||
modulo := p & (a-1);
|
||||
if modulo != 0 {
|
||||
p += a - modulo;
|
||||
}
|
||||
return cast(rawptr)p;
|
||||
return rawptr(p);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@ Allocation_Header :: struct {
|
||||
|
||||
allocation_header_fill :: proc(header: ^Allocation_Header, data: rawptr, size: int) {
|
||||
header.size = size;
|
||||
ptr := cast(^int)(header+1);
|
||||
ptr := ^int(header+1);
|
||||
|
||||
for i := 0; cast(rawptr)ptr < data; i++ {
|
||||
for i := 0; rawptr(ptr) < data; i++ {
|
||||
(ptr+i)^ = -1;
|
||||
}
|
||||
}
|
||||
@@ -66,11 +66,11 @@ allocation_header :: proc(data: rawptr) -> ^Allocation_Header {
|
||||
if data == nil {
|
||||
return nil;
|
||||
}
|
||||
p := cast(^int)data;
|
||||
p := ^int(data);
|
||||
for (p-1)^ == -1 {
|
||||
p = (p-1);
|
||||
}
|
||||
return cast(^Allocation_Header)p-1;
|
||||
return ^Allocation_Header(p-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int, flags: u64) -> rawptr {
|
||||
using Allocator_Mode;
|
||||
arena := cast(^Arena)allocator_data;
|
||||
arena := ^Arena(allocator_data);
|
||||
|
||||
match mode {
|
||||
case ALLOC:
|
||||
@@ -138,7 +138,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
return nil;
|
||||
}
|
||||
|
||||
#no_bounds_check end := ^arena.memory[arena.offset];
|
||||
#no_bounds_check end := &arena.memory[arena.offset];
|
||||
|
||||
ptr := align_forward(end, alignment);
|
||||
arena.offset += total_size;
|
||||
@@ -221,7 +221,7 @@ align_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
||||
return WORD_SIZE;
|
||||
case Vector:
|
||||
size := size_of_type_info(info.elem);
|
||||
count := cast(int)max(prev_pow2(cast(i64)info.count), 1);
|
||||
count := int(max(prev_pow2(i64(info.count)), 1));
|
||||
total := size * count;
|
||||
return clamp(total, 1, MAX_ALIGN);
|
||||
case Tuple:
|
||||
|
||||
@@ -31,7 +31,7 @@ TexImage2D :: proc(target, level, internal_format,
|
||||
format, type: i32, pixels: rawptr) #foreign lib "glTexImage2D";
|
||||
|
||||
|
||||
_string_data :: proc(s: string) -> ^u8 #inline { return ^s[0]; }
|
||||
_string_data :: proc(s: string) -> ^u8 #inline { return &s[0]; }
|
||||
|
||||
_libgl := win32.LoadLibraryA(_string_data("opengl32.dll\x00"));
|
||||
|
||||
@@ -40,10 +40,10 @@ GetProcAddress :: proc(name: string) -> proc() #cc_c {
|
||||
name = name[0..<len(name)-1];
|
||||
}
|
||||
// NOTE(bill): null terminated
|
||||
assert((^name[0] + len(name))^ == 0);
|
||||
res := wgl.GetProcAddress(^name[0]);
|
||||
assert((&name[0] + len(name))^ == 0);
|
||||
res := wgl.GetProcAddress(&name[0]);
|
||||
if res == nil {
|
||||
res = win32.GetProcAddress(_libgl, ^name[0]);
|
||||
res = win32.GetProcAddress(_libgl, &name[0]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -108,56 +108,59 @@ UniformMatrix4fv: proc(loc: i32, count: u32, transpose: i32, value: ^f32
|
||||
GetUniformLocation: proc(program: u32, name: ^byte) -> i32 #cc_c;
|
||||
|
||||
init :: proc() {
|
||||
set_proc_address :: proc(p: rawptr, name: string) #inline { (cast(^(proc() #cc_c))p)^ = GetProcAddress(name); }
|
||||
set_proc_address :: proc(p: rawptr, name: string) #inline {
|
||||
x := ^(proc() #cc_c)(p);
|
||||
x^ = GetProcAddress(name);
|
||||
}
|
||||
|
||||
set_proc_address(^GenBuffers, "glGenBuffers\x00");
|
||||
set_proc_address(^GenVertexArrays, "glGenVertexArrays\x00");
|
||||
set_proc_address(^GenSamplers, "glGenSamplers\x00");
|
||||
set_proc_address(^DeleteBuffers, "glDeleteBuffers\x00");
|
||||
set_proc_address(^BindBuffer, "glBindBuffer\x00");
|
||||
set_proc_address(^BindSampler, "glBindSampler\x00");
|
||||
set_proc_address(^BindVertexArray, "glBindVertexArray\x00");
|
||||
set_proc_address(^BufferData, "glBufferData\x00");
|
||||
set_proc_address(^BufferSubData, "glBufferSubData\x00");
|
||||
set_proc_address(&GenBuffers, "glGenBuffers\x00");
|
||||
set_proc_address(&GenVertexArrays, "glGenVertexArrays\x00");
|
||||
set_proc_address(&GenSamplers, "glGenSamplers\x00");
|
||||
set_proc_address(&DeleteBuffers, "glDeleteBuffers\x00");
|
||||
set_proc_address(&BindBuffer, "glBindBuffer\x00");
|
||||
set_proc_address(&BindSampler, "glBindSampler\x00");
|
||||
set_proc_address(&BindVertexArray, "glBindVertexArray\x00");
|
||||
set_proc_address(&BufferData, "glBufferData\x00");
|
||||
set_proc_address(&BufferSubData, "glBufferSubData\x00");
|
||||
|
||||
set_proc_address(^DrawArrays, "glDrawArrays\x00");
|
||||
set_proc_address(^DrawElements, "glDrawElements\x00");
|
||||
set_proc_address(&DrawArrays, "glDrawArrays\x00");
|
||||
set_proc_address(&DrawElements, "glDrawElements\x00");
|
||||
|
||||
set_proc_address(^MapBuffer, "glMapBuffer\x00");
|
||||
set_proc_address(^UnmapBuffer, "glUnmapBuffer\x00");
|
||||
set_proc_address(&MapBuffer, "glMapBuffer\x00");
|
||||
set_proc_address(&UnmapBuffer, "glUnmapBuffer\x00");
|
||||
|
||||
set_proc_address(^VertexAttribPointer, "glVertexAttribPointer\x00");
|
||||
set_proc_address(^EnableVertexAttribArray, "glEnableVertexAttribArray\x00");
|
||||
set_proc_address(&VertexAttribPointer, "glVertexAttribPointer\x00");
|
||||
set_proc_address(&EnableVertexAttribArray, "glEnableVertexAttribArray\x00");
|
||||
|
||||
set_proc_address(^CreateShader, "glCreateShader\x00");
|
||||
set_proc_address(^ShaderSource, "glShaderSource\x00");
|
||||
set_proc_address(^CompileShader, "glCompileShader\x00");
|
||||
set_proc_address(^CreateProgram, "glCreateProgram\x00");
|
||||
set_proc_address(^AttachShader, "glAttachShader\x00");
|
||||
set_proc_address(^DetachShader, "glDetachShader\x00");
|
||||
set_proc_address(^DeleteShader, "glDeleteShader\x00");
|
||||
set_proc_address(^LinkProgram, "glLinkProgram\x00");
|
||||
set_proc_address(^UseProgram, "glUseProgram\x00");
|
||||
set_proc_address(^DeleteProgram, "glDeleteProgram\x00");
|
||||
set_proc_address(&CreateShader, "glCreateShader\x00");
|
||||
set_proc_address(&ShaderSource, "glShaderSource\x00");
|
||||
set_proc_address(&CompileShader, "glCompileShader\x00");
|
||||
set_proc_address(&CreateProgram, "glCreateProgram\x00");
|
||||
set_proc_address(&AttachShader, "glAttachShader\x00");
|
||||
set_proc_address(&DetachShader, "glDetachShader\x00");
|
||||
set_proc_address(&DeleteShader, "glDeleteShader\x00");
|
||||
set_proc_address(&LinkProgram, "glLinkProgram\x00");
|
||||
set_proc_address(&UseProgram, "glUseProgram\x00");
|
||||
set_proc_address(&DeleteProgram, "glDeleteProgram\x00");
|
||||
|
||||
set_proc_address(^GetShaderiv, "glGetShaderiv\x00");
|
||||
set_proc_address(^GetProgramiv, "glGetProgramiv\x00");
|
||||
set_proc_address(^GetShaderInfoLog, "glGetShaderInfoLog\x00");
|
||||
set_proc_address(^GetProgramInfoLog, "glGetProgramInfoLog\x00");
|
||||
set_proc_address(&GetShaderiv, "glGetShaderiv\x00");
|
||||
set_proc_address(&GetProgramiv, "glGetProgramiv\x00");
|
||||
set_proc_address(&GetShaderInfoLog, "glGetShaderInfoLog\x00");
|
||||
set_proc_address(&GetProgramInfoLog, "glGetProgramInfoLog\x00");
|
||||
|
||||
set_proc_address(^ActiveTexture, "glActiveTexture\x00");
|
||||
set_proc_address(^GenerateMipmap, "glGenerateMipmap\x00");
|
||||
set_proc_address(&ActiveTexture, "glActiveTexture\x00");
|
||||
set_proc_address(&GenerateMipmap, "glGenerateMipmap\x00");
|
||||
|
||||
set_proc_address(^Uniform1i, "glUniform1i\x00");
|
||||
set_proc_address(^UniformMatrix4fv, "glUniformMatrix4fv\x00");
|
||||
set_proc_address(&Uniform1i, "glUniform1i\x00");
|
||||
set_proc_address(&UniformMatrix4fv, "glUniformMatrix4fv\x00");
|
||||
|
||||
set_proc_address(^GetUniformLocation, "glGetUniformLocation\x00");
|
||||
set_proc_address(&GetUniformLocation, "glGetUniformLocation\x00");
|
||||
|
||||
set_proc_address(^SamplerParameteri, "glSamplerParameteri\x00");
|
||||
set_proc_address(^SamplerParameterf, "glSamplerParameterf\x00");
|
||||
set_proc_address(^SamplerParameteriv, "glSamplerParameteriv\x00");
|
||||
set_proc_address(^SamplerParameterfv, "glSamplerParameterfv\x00");
|
||||
set_proc_address(^SamplerParameterIiv, "glSamplerParameterIiv\x00");
|
||||
set_proc_address(^SamplerParameterIuiv, "glSamplerParameterIuiv\x00");
|
||||
set_proc_address(&SamplerParameteri, "glSamplerParameteri\x00");
|
||||
set_proc_address(&SamplerParameterf, "glSamplerParameterf\x00");
|
||||
set_proc_address(&SamplerParameteriv, "glSamplerParameteriv\x00");
|
||||
set_proc_address(&SamplerParameterfv, "glSamplerParameterfv\x00");
|
||||
set_proc_address(&SamplerParameterIiv, "glSamplerParameterIiv\x00");
|
||||
set_proc_address(&SamplerParameterIuiv, "glSamplerParameterIuiv\x00");
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ Stat :: struct #ordered {
|
||||
size: i64, // Size of the file, in bytes
|
||||
block_size: i64, // Optimal bllocksize for I/O
|
||||
blocks: i64, // Number of 512-byte blocks allocated
|
||||
|
||||
|
||||
last_access: _File_Time, // Time of last access
|
||||
modified: _File_Time, // Time of last modification
|
||||
status_change: _File_Time, // Time of last status change
|
||||
@@ -146,7 +146,7 @@ _unix_dlerror :: proc() -> ^u8
|
||||
|
||||
// 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);
|
||||
handle := _unix_open(cstr, mode);
|
||||
free(cstr);
|
||||
@@ -175,15 +175,15 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||
}
|
||||
|
||||
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
|
||||
res := _unix_seek(fd, offset, cast(i32)whence);
|
||||
res := _unix_seek(fd, offset, i32(whence));
|
||||
return res, 0;
|
||||
}
|
||||
|
||||
|
||||
// NOTE(bill): Uses startup to initialize it
|
||||
stdin: Handle = 0;
|
||||
stdout: Handle = 1;
|
||||
stderr: Handle = 2;
|
||||
stdin: Handle = 0;
|
||||
stdout: Handle = 1;
|
||||
stderr: Handle = 2;
|
||||
|
||||
/* TODO(zangent): Implement these!
|
||||
last_write_time :: proc(fd: Handle) -> File_Time {}
|
||||
@@ -195,7 +195,7 @@ stat :: proc(path: string) -> (Stat, int) #inline {
|
||||
cstr := strings.new_c_string(path);
|
||||
defer free(cstr);
|
||||
ret_int := _unix_stat(cstr, ^s);
|
||||
return s, cast(int)ret_int;
|
||||
return s, int(ret_int);
|
||||
}
|
||||
|
||||
access :: proc(path: string, mask: int) -> bool #inline {
|
||||
|
||||
@@ -73,11 +73,11 @@ open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) {
|
||||
access |= win32.FILE_APPEND_DATA;
|
||||
}
|
||||
|
||||
share_mode := cast(u32)(win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE);
|
||||
share_mode := u32(win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE);
|
||||
sa: ^win32.Security_Attributes = nil;
|
||||
sa_inherit := win32.Security_Attributes{length = size_of(win32.Security_Attributes), inherit_handle = 1};
|
||||
if mode&O_CLOEXEC == 0 {
|
||||
sa = ^sa_inherit;
|
||||
sa = &sa_inherit;
|
||||
}
|
||||
|
||||
create_mode: u32;
|
||||
@@ -95,34 +95,34 @@ open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) {
|
||||
}
|
||||
|
||||
buf: [300]byte;
|
||||
copy(buf[..], cast([]byte)path);
|
||||
copy(buf[..], []byte(path));
|
||||
|
||||
handle := cast(Handle)win32.CreateFileA(^buf[0], access, share_mode, sa, create_mode, win32.FILE_ATTRIBUTE_NORMAL, nil);
|
||||
handle := Handle(win32.CreateFileA(&buf[0], access, share_mode, sa, create_mode, win32.FILE_ATTRIBUTE_NORMAL, nil));
|
||||
if handle != INVALID_HANDLE {
|
||||
return handle, ERROR_NONE;
|
||||
}
|
||||
err := win32.GetLastError();
|
||||
return INVALID_HANDLE, cast(Errno)err;
|
||||
return INVALID_HANDLE, Errno(err);
|
||||
}
|
||||
|
||||
close :: proc(fd: Handle) {
|
||||
win32.CloseHandle(cast(win32.Handle)fd);
|
||||
win32.CloseHandle(win32.Handle(fd));
|
||||
}
|
||||
|
||||
write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
|
||||
return write(fd, cast([]byte)str);
|
||||
return write(fd, []byte(str));
|
||||
}
|
||||
write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||
if len(data) == 0 {
|
||||
return 0, ERROR_NONE;
|
||||
}
|
||||
bytes_written: i32;
|
||||
e := win32.WriteFile(cast(win32.Handle)fd, ^data[0], cast(i32)len(data), ^bytes_written, nil);
|
||||
e := win32.WriteFile(win32.Handle(fd), &data[0], i32(len(data)), &bytes_written, nil);
|
||||
if e == win32.FALSE {
|
||||
err := win32.GetLastError();
|
||||
return 0, cast(Errno)err;
|
||||
return 0, Errno(err);
|
||||
}
|
||||
return cast(int)bytes_written, ERROR_NONE;
|
||||
return int(bytes_written), ERROR_NONE;
|
||||
}
|
||||
|
||||
read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||
@@ -130,12 +130,12 @@ read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||
return 0, ERROR_NONE;
|
||||
}
|
||||
bytes_read: i32;
|
||||
e := win32.ReadFile(cast(win32.Handle)fd, ^data[0], cast(u32)len(data), ^bytes_read, nil);
|
||||
e := win32.ReadFile(win32.Handle(fd), &data[0], u32(len(data)), &bytes_read, nil);
|
||||
if e == win32.FALSE {
|
||||
err := win32.GetLastError();
|
||||
return 0, cast(Errno)err;
|
||||
return 0, Errno(err);
|
||||
}
|
||||
return cast(int)bytes_read, ERROR_NONE;
|
||||
return int(bytes_read), ERROR_NONE;
|
||||
}
|
||||
|
||||
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
|
||||
@@ -145,18 +145,18 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
|
||||
case 1: w = win32.FILE_CURRENT;
|
||||
case 2: w = win32.FILE_END;
|
||||
}
|
||||
hi := cast(i32)(offset>>32);
|
||||
lo := cast(i32)(offset);
|
||||
ft := win32.GetFileType(cast(win32.Handle)fd);
|
||||
hi := i32(offset>>32);
|
||||
lo := i32(offset);
|
||||
ft := win32.GetFileType(win32.Handle(fd));
|
||||
if ft == win32.FILE_TYPE_PIPE {
|
||||
return 0, ERROR_FILE_IS_PIPE;
|
||||
}
|
||||
dw_ptr := win32.SetFilePointer(cast(win32.Handle)fd, lo, ^hi, w);
|
||||
dw_ptr := win32.SetFilePointer(win32.Handle(fd), lo, &hi, w);
|
||||
if dw_ptr == win32.INVALID_SET_FILE_POINTER {
|
||||
err := win32.GetLastError();
|
||||
return 0, cast(Errno)err;
|
||||
return 0, Errno(err);
|
||||
}
|
||||
return cast(i64)hi<<32 + cast(i64)dw_ptr, ERROR_NONE;
|
||||
return i64(hi)<<32 + i64(dw_ptr), ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -167,9 +167,9 @@ stderr := get_std_handle(win32.STD_ERROR_HANDLE);
|
||||
|
||||
|
||||
get_std_handle :: proc(h: int) -> Handle {
|
||||
fd := win32.GetStdHandle(cast(i32)h);
|
||||
fd := win32.GetStdHandle(i32(h));
|
||||
win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0);
|
||||
return cast(Handle)fd;
|
||||
return Handle(fd);
|
||||
}
|
||||
|
||||
|
||||
@@ -179,9 +179,9 @@ get_std_handle :: proc(h: int) -> Handle {
|
||||
|
||||
last_write_time :: proc(fd: Handle) -> File_Time {
|
||||
file_info: win32.By_Handle_File_Information;
|
||||
win32.GetFileInformationByHandle(cast(win32.Handle)fd, ^file_info);
|
||||
lo := cast(File_Time)file_info.last_write_time.lo;
|
||||
hi := cast(File_Time)file_info.last_write_time.hi;
|
||||
win32.GetFileInformationByHandle(win32.Handle(fd), &file_info);
|
||||
lo := File_Time(file_info.last_write_time.lo);
|
||||
hi := File_Time(file_info.last_write_time.hi);
|
||||
return lo | hi << 32;
|
||||
}
|
||||
|
||||
@@ -192,21 +192,21 @@ last_write_time_by_name :: proc(name: string) -> File_Time {
|
||||
|
||||
assert(len(buf) > len(name));
|
||||
|
||||
copy(buf[..], cast([]byte)name);
|
||||
copy(buf[..], []byte(name));
|
||||
|
||||
if win32.GetFileAttributesExA(^buf[0], win32.GetFileExInfoStandard, ^data) != 0 {
|
||||
if win32.GetFileAttributesExA(&buf[0], win32.GetFileExInfoStandard, &data) != 0 {
|
||||
last_write_time = data.last_write_time;
|
||||
}
|
||||
|
||||
l := cast(File_Time)last_write_time.lo;
|
||||
h := cast(File_Time)last_write_time.hi;
|
||||
l := File_Time(last_write_time.lo);
|
||||
h := File_Time(last_write_time.hi);
|
||||
return l | h << 32;
|
||||
}
|
||||
|
||||
|
||||
read_entire_file :: proc(name: string) -> ([]byte, bool) {
|
||||
buf: [300]byte;
|
||||
copy(buf[..], cast([]byte)name);
|
||||
copy(buf[..], []byte(name));
|
||||
|
||||
fd, err := open(name, O_RDONLY, 0);
|
||||
if err != ERROR_NONE {
|
||||
@@ -215,7 +215,7 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
|
||||
defer close(fd);
|
||||
|
||||
length: i64;
|
||||
if ok := win32.GetFileSizeEx(cast(win32.Handle)fd, ^length) != 0; !ok {
|
||||
if ok := win32.GetFileSizeEx(win32.Handle(fd), &length) != 0; !ok {
|
||||
return nil, false;
|
||||
}
|
||||
|
||||
@@ -236,18 +236,18 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
|
||||
to_read: u32;
|
||||
MAX :: 1<<32-1;
|
||||
if remaining <= MAX {
|
||||
to_read = cast(u32)remaining;
|
||||
to_read = u32(remaining);
|
||||
} else {
|
||||
to_read = MAX;
|
||||
}
|
||||
|
||||
win32.ReadFile(cast(win32.Handle)fd, ^data[total_read], to_read, ^single_read_length, nil);
|
||||
win32.ReadFile(win32.Handle(fd), &data[total_read], to_read, &single_read_length, nil);
|
||||
if single_read_length <= 0 {
|
||||
free(data);
|
||||
return nil, false;
|
||||
}
|
||||
|
||||
total_read += cast(i64)single_read_length;
|
||||
total_read += i64(single_read_length);
|
||||
}
|
||||
|
||||
return data, true;
|
||||
@@ -277,13 +277,13 @@ heap_free :: proc(ptr: rawptr) {
|
||||
|
||||
|
||||
exit :: proc(code: int) {
|
||||
win32.ExitProcess(cast(u32)code);
|
||||
win32.ExitProcess(u32(code));
|
||||
}
|
||||
|
||||
|
||||
|
||||
current_thread_id :: proc() -> int {
|
||||
return cast(int)win32.GetCurrentThreadId();
|
||||
return int(win32.GetCurrentThreadId());
|
||||
}
|
||||
|
||||
|
||||
@@ -306,24 +306,24 @@ _alloc_command_line_arguments :: proc() -> []string {
|
||||
if i+1 > len {
|
||||
return "";
|
||||
}
|
||||
buf[i] = cast(byte)str[j]; i++;
|
||||
buf[i] = byte(str[j]); i++;
|
||||
j++;
|
||||
case str[j] < 0x800:
|
||||
if i+2 > len {
|
||||
return "";
|
||||
}
|
||||
buf[i] = cast(byte)(0xc0 + (str[j]>>6)); i++;
|
||||
buf[i] = cast(byte)(0x80 + (str[j]&0x3f)); i++;
|
||||
buf[i] = byte(0xc0 + (str[j]>>6)); i++;
|
||||
buf[i] = byte(0x80 + (str[j]&0x3f)); i++;
|
||||
j++;
|
||||
case 0xd800 <= str[j] && str[j] < 0xdc00:
|
||||
if i+4 > len {
|
||||
return "";
|
||||
}
|
||||
c := cast(rune)((str[j] - 0xd800) << 10) + cast(rune)((str[j+1]) - 0xdc00) + 0x10000;
|
||||
buf[i] = cast(byte)(0xf0 + (c >> 18)); i++;
|
||||
buf[i] = cast(byte)(0x80 + ((c >> 12) & 0x3f)); i++;
|
||||
buf[i] = cast(byte)(0x80 + ((c >> 6) & 0x3f)); i++;
|
||||
buf[i] = cast(byte)(0x80 + ((c ) & 0x3f)); i++;
|
||||
c := rune((str[j] - 0xd800) << 10) + rune((str[j+1]) - 0xdc00) + 0x10000;
|
||||
buf[i] = byte(0xf0 + (c >> 18)); i++;
|
||||
buf[i] = byte(0x80 + ((c >> 12) & 0x3f)); i++;
|
||||
buf[i] = byte(0x80 + ((c >> 6) & 0x3f)); i++;
|
||||
buf[i] = byte(0x80 + ((c ) & 0x3f)); i++;
|
||||
j += 2;
|
||||
case 0xdc00 <= str[j] && str[j] < 0xe000:
|
||||
return "";
|
||||
@@ -331,18 +331,18 @@ _alloc_command_line_arguments :: proc() -> []string {
|
||||
if i+3 > len {
|
||||
return "";
|
||||
}
|
||||
buf[i] = 0xe0 + cast(byte) (str[j] >> 12); i++;
|
||||
buf[i] = 0x80 + cast(byte)((str[j] >> 6) & 0x3f); i++;
|
||||
buf[i] = 0x80 + cast(byte)((str[j] ) & 0x3f); i++;
|
||||
buf[i] = 0xe0 + byte (str[j] >> 12); i++;
|
||||
buf[i] = 0x80 + byte((str[j] >> 6) & 0x3f); i++;
|
||||
buf[i] = 0x80 + byte((str[j] ) & 0x3f); i++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
return cast(string)buf[0..<i];
|
||||
return string(buf[0..<i]);
|
||||
}
|
||||
|
||||
arg_count: i32;
|
||||
arg_list_ptr := win32.CommandLineToArgvW(win32.GetCommandLineW(), ^arg_count);
|
||||
arg_list_ptr := win32.CommandLineToArgvW(win32.GetCommandLineW(), &arg_count);
|
||||
arg_list := make([]string, arg_count);
|
||||
for _, i in arg_list {
|
||||
arg_list[i] = alloc_ucs2_to_utf8((arg_list_ptr+i)^);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Any :: struct #ordered {
|
||||
type_info: ^Type_Info,
|
||||
data: rawptr,
|
||||
type_info: ^Type_Info,
|
||||
}
|
||||
|
||||
String :: struct #ordered {
|
||||
|
||||
@@ -19,15 +19,12 @@ parse_bool :: proc(s: string) -> (result: bool, ok: bool) {
|
||||
}
|
||||
|
||||
_digit_value :: proc(r: rune) -> (int) {
|
||||
ri := cast(int)r;
|
||||
ri := int(r);
|
||||
v: int = 16;
|
||||
match r {
|
||||
case '0'..'9':
|
||||
v = ri - '0';
|
||||
case 'a'..'z':
|
||||
v = ri - 'a' + 10;
|
||||
case 'A'..'Z':
|
||||
v = ri - 'A' + 10;
|
||||
case '0'..'9': v = ri-'0';
|
||||
case 'a'..'z': v = ri-'a'+10;
|
||||
case 'A'..'Z': v = ri-'A'+10;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
@@ -39,8 +36,8 @@ parse_i64 :: proc(s: string, base: int) -> i64 {
|
||||
if v >= base {
|
||||
break;
|
||||
}
|
||||
result *= cast(i64)base;
|
||||
result += cast(i64)v;
|
||||
result *= i64(base);
|
||||
result += i64(v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -51,35 +48,35 @@ parse_u64 :: proc(s: string, base: int) -> u64 {
|
||||
if v >= base {
|
||||
break;
|
||||
}
|
||||
result *= cast(u64)base;
|
||||
result += cast(u64)v;
|
||||
result *= u64(base);
|
||||
result += u64(v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
parse_int :: proc(s: string, base: int) -> int {
|
||||
return cast(int)parse_i64(s, base);
|
||||
return int(parse_i64(s, base));
|
||||
}
|
||||
parse_uint :: proc(s: string, base: int) -> uint {
|
||||
return cast(uint)parse_u64(s, base);
|
||||
return uint(parse_u64(s, base));
|
||||
}
|
||||
|
||||
|
||||
append_bool :: proc(buf: []byte, b: bool) -> string {
|
||||
s := b ? "true" : "false";
|
||||
append(buf, ..cast([]byte)s);
|
||||
return cast(string)buf;
|
||||
append(buf, ..[]byte(s));
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
append_uint :: proc(buf: []byte, u: u64, base: int) -> string {
|
||||
return append_bits(buf, u, base, false, 8*size_of(uint), digits, 0);
|
||||
}
|
||||
append_int :: proc(buf: []byte, i: i64, base: int) -> string {
|
||||
return append_bits(buf, cast(u64)i, base, true, 8*size_of(int), digits, 0);
|
||||
return append_bits(buf, u64(i), base, true, 8*size_of(int), digits, 0);
|
||||
}
|
||||
itoa :: proc(buf: []byte, i: int) -> string { return append_int(buf, cast(i64)i, 10); }
|
||||
itoa :: proc(buf: []byte, i: int) -> string { return append_int(buf, i64(i), 10); }
|
||||
|
||||
append_float :: proc(buf: []byte, f: f64, fmt: byte, prec, bit_size: int) -> string {
|
||||
return cast(string)generic_ftoa(buf, f, fmt, prec, bit_size);
|
||||
return string(generic_ftoa(buf, f, fmt, prec, bit_size));
|
||||
}
|
||||
|
||||
|
||||
@@ -107,18 +104,18 @@ generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, prec, bit_size: int) -> [
|
||||
flt: ^Float_Info;
|
||||
match bit_size {
|
||||
case 32:
|
||||
bits = cast(u64)transmute(u32)cast(f32)val;
|
||||
flt = ^f32_info;
|
||||
bits = u64(transmute(u32, f32(val)));
|
||||
flt = &f32_info;
|
||||
case 64:
|
||||
bits = transmute(u64)val;
|
||||
flt = ^f64_info;
|
||||
bits = transmute(u64, val);
|
||||
flt = &f64_info;
|
||||
default:
|
||||
panic("strconv: invalid bit_size");
|
||||
}
|
||||
|
||||
neg := bits>>(flt.expbits+flt.mantbits) != 0;
|
||||
exp := cast(int)(bits>>flt.mantbits) & (1<<flt.expbits - 1);
|
||||
mant := bits & (cast(u64)1 << flt.mantbits - 1);
|
||||
exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1);
|
||||
mant := bits & (u64(1) << flt.mantbits - 1);
|
||||
|
||||
match exp {
|
||||
case 1<<flt.expbits - 1:
|
||||
@@ -130,22 +127,22 @@ generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, prec, bit_size: int) -> [
|
||||
} else {
|
||||
s = "+Inf";
|
||||
}
|
||||
append(buf, ..cast([]byte)s);
|
||||
append(buf, ..[]byte(s));
|
||||
return buf;
|
||||
|
||||
case 0: // denormalized
|
||||
exp++;
|
||||
|
||||
default:
|
||||
mant |= cast(u64)1 << flt.mantbits;
|
||||
mant |= u64(1) << flt.mantbits;
|
||||
}
|
||||
|
||||
exp += flt.bias;
|
||||
|
||||
d_: Decimal;
|
||||
d := ^d_;
|
||||
d := &d_;
|
||||
assign(d, mant);
|
||||
shift(d, exp - cast(int)flt.mantbits);
|
||||
shift(d, exp - int(flt.mantbits));
|
||||
digs: Decimal_Slice;
|
||||
shortest := prec < 0;
|
||||
if shortest {
|
||||
@@ -194,7 +191,7 @@ format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slic
|
||||
// fractional part
|
||||
if prec > 0 {
|
||||
append(buf, '.');
|
||||
for i in 0..<prec {
|
||||
for i in 0..prec {
|
||||
c: byte = '0';
|
||||
if j := digs.decimal_point + i; 0 <= j && j < digs.count {
|
||||
c = digs.digits[j];
|
||||
@@ -234,14 +231,14 @@ round_shortest :: proc(d: ^Decimal, mant: u64, exp: int, flt: ^Float_Info) {
|
||||
332*(dp-nd) >= 100*(exp-mantbits)
|
||||
*/
|
||||
minexp := flt.bias+1;
|
||||
if exp > minexp && 332*(d.decimal_point-d.count) >= 100*(exp - cast(int)flt.mantbits) {
|
||||
if exp > minexp && 332*(d.decimal_point-d.count) >= 100*(exp - int(flt.mantbits)) {
|
||||
// Number is already its shortest
|
||||
return;
|
||||
}
|
||||
|
||||
upper_: Decimal; upper: = ^upper_;
|
||||
upper_: Decimal; upper: = &upper_;
|
||||
assign(upper, 2*mant - 1);
|
||||
shift(upper, exp - cast(int)flt.mantbits - 1);
|
||||
shift(upper, exp - int(flt.mantbits) - 1);
|
||||
|
||||
mantlo: u64;
|
||||
explo: int;
|
||||
@@ -252,9 +249,9 @@ round_shortest :: proc(d: ^Decimal, mant: u64, exp: int, flt: ^Float_Info) {
|
||||
mantlo = 2*mant - 1;
|
||||
explo = exp-1;
|
||||
}
|
||||
lower_: Decimal; lower: = ^lower_;
|
||||
lower_: Decimal; lower: = &lower_;
|
||||
assign(lower, 2*mantlo + 1);
|
||||
shift(lower, explo - cast(int)flt.mantbits - 1);
|
||||
shift(lower, explo - int(flt.mantbits) - 1);
|
||||
|
||||
inclusive := mant%2 == 0;
|
||||
|
||||
@@ -297,25 +294,25 @@ is_integer_negative :: proc(u: u64, is_signed: bool, bit_size: int) -> (unsigned
|
||||
if is_signed {
|
||||
match bit_size {
|
||||
case 8:
|
||||
i := cast(i8)u;
|
||||
i := i8(u);
|
||||
neg = i < 0;
|
||||
if neg { i = -i; }
|
||||
u = cast(u64)i;
|
||||
u = u64(i);
|
||||
case 16:
|
||||
i := cast(i16)u;
|
||||
i := i16(u);
|
||||
neg = i < 0;
|
||||
if neg { i = -i; }
|
||||
u = cast(u64)i;
|
||||
u = u64(i);
|
||||
case 32:
|
||||
i := cast(i32)u;
|
||||
i := i32(u);
|
||||
neg = i < 0;
|
||||
if neg { i = -i; }
|
||||
u = cast(u64)i;
|
||||
u = u64(i);
|
||||
case 64:
|
||||
i := cast(i64)u;
|
||||
i := i64(u);
|
||||
neg = i < 0;
|
||||
if neg { i = -i; }
|
||||
u = cast(u64)i;
|
||||
u = u64(i);
|
||||
default:
|
||||
panic("is_integer_negative: Unknown integer size");
|
||||
}
|
||||
@@ -342,15 +339,15 @@ append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: i
|
||||
neg: bool;
|
||||
u, neg = is_integer_negative(u, is_signed, bit_size);
|
||||
|
||||
for b := cast(u64)base; u >= b; {
|
||||
for b := u64(base); u >= b; {
|
||||
i--;
|
||||
q := u / b;
|
||||
a[i] = digits[cast(uint)(u-q*b)];
|
||||
a[i] = digits[uint(u-q*b)];
|
||||
u = q;
|
||||
}
|
||||
|
||||
i--;
|
||||
a[i] = digits[cast(uint)u];
|
||||
a[i] = digits[uint(u)];
|
||||
|
||||
if flags&Int_Flag.PREFIX != 0 {
|
||||
ok := true;
|
||||
@@ -378,6 +375,6 @@ append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: i
|
||||
|
||||
|
||||
append(buf, ..a[i..]);
|
||||
return cast(string)buf;
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
new_c_string :: proc(s: string) -> ^byte {
|
||||
c := make([]byte, len(s)+1);
|
||||
copy(c, cast([]byte)s);
|
||||
copy(c, []byte(s));
|
||||
c[len(s)] = 0;
|
||||
return ^c[0];
|
||||
return &c[0];
|
||||
}
|
||||
|
||||
to_odin_string :: proc(c: ^byte) -> string {
|
||||
@@ -10,5 +10,5 @@ to_odin_string :: proc(c: ^byte) -> string {
|
||||
for (c+len)^ != 0 {
|
||||
len++;
|
||||
}
|
||||
return cast(string)slice_ptr(c, len);
|
||||
return string(slice_ptr(c, len));
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ Bool :: i32;
|
||||
Wnd_Proc :: #type proc(Hwnd, u32, Wparam, Lparam) -> Lresult #cc_c;
|
||||
|
||||
|
||||
INVALID_HANDLE :: cast(Handle)~cast(int)0;
|
||||
INVALID_HANDLE :: Handle(~int(0));
|
||||
|
||||
FALSE: Bool : 0;
|
||||
TRUE: Bool : 1;
|
||||
@@ -56,7 +56,7 @@ WM_CHAR :: 0x0102;
|
||||
|
||||
PM_REMOVE :: 1;
|
||||
|
||||
COLOR_BACKGROUND :: cast(Hbrush)(cast(int)1);
|
||||
COLOR_BACKGROUND :: Hbrush(int(1));
|
||||
BLACK_BRUSH :: 4;
|
||||
|
||||
SM_CXSCREEN :: 0;
|
||||
@@ -178,7 +178,7 @@ DescribePixelFormat :: proc(dc: Hdc, pixel_format: i32, bytes : u32, pfd: ^PIXEL
|
||||
|
||||
GetQueryPerformanceFrequency :: proc() -> i64 {
|
||||
r: i64;
|
||||
QueryPerformanceFrequency(^r);
|
||||
QueryPerformanceFrequency(&r);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ FILE_TYPE_DISK :: 0x0001;
|
||||
FILE_TYPE_CHAR :: 0x0002;
|
||||
FILE_TYPE_PIPE :: 0x0003;
|
||||
|
||||
INVALID_SET_FILE_POINTER :: ~cast(u32)0;
|
||||
INVALID_SET_FILE_POINTER :: ~u32(0);
|
||||
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ Hmonitor :: Handle;
|
||||
|
||||
GWL_STYLE :: -16;
|
||||
|
||||
Hwnd_TOP :: cast(Hwnd)cast(uint)0;
|
||||
Hwnd_TOP :: Hwnd(uint(0));
|
||||
|
||||
MONITOR_DEFAULTTONULL :: 0x00000000;
|
||||
MONITOR_DEFAULTTOPRIMARY :: 0x00000001;
|
||||
@@ -356,10 +356,10 @@ SetWindowLongPtrA :: proc(wnd: Hwnd, index: i32, new: i64) -> i64 #foreign user3
|
||||
|
||||
GetWindowText :: proc(wnd: Hwnd, str: ^byte, maxCount: i32) -> i32 #foreign user32;
|
||||
|
||||
HIWORD :: proc(wParam: Wparam) -> u16 { return cast(u16)((cast(u32)wParam >> 16) & 0xffff); }
|
||||
HIWORD :: proc(lParam: Lparam) -> u16 { return cast(u16)((cast(u32)lParam >> 16) & 0xffff); }
|
||||
LOWORD :: proc(wParam: Wparam) -> u16 { return cast(u16)wParam; }
|
||||
LOWORD :: proc(lParam: Lparam) -> u16 { return cast(u16)lParam; }
|
||||
HIWORD :: proc(wParam: Wparam) -> u16 { return u16((u32(wParam) >> 16) & 0xffff); }
|
||||
HIWORD :: proc(lParam: Lparam) -> u16 { return u16((u32(lParam) >> 16) & 0xffff); }
|
||||
LOWORD :: proc(wParam: Wparam) -> u16 { return u16(wParam); }
|
||||
LOWORD :: proc(lParam: Lparam) -> u16 { return u16(lParam); }
|
||||
|
||||
|
||||
|
||||
@@ -477,7 +477,7 @@ Proc :: #type proc() #cc_c;
|
||||
GetKeyState :: proc(v_key: i32) -> i16 #foreign user32;
|
||||
GetAsyncKeyState :: proc(v_key: i32) -> i16 #foreign user32;
|
||||
|
||||
is_key_down :: proc(key: Key_Code) -> bool #inline { return GetAsyncKeyState(cast(i32)key) < 0; }
|
||||
is_key_down :: proc(key: Key_Code) -> bool #inline { return GetAsyncKeyState(i32(key)) < 0; }
|
||||
|
||||
Key_Code :: enum i32 {
|
||||
LBUTTON = 0x01,
|
||||
|
||||
@@ -1,100 +1,98 @@
|
||||
is_signed :: proc(info: ^Type_Info) -> bool {
|
||||
info = type_info_base(info);
|
||||
if i, ok := union_cast(^Type_Info.Integer)info; ok {
|
||||
return i.signed;
|
||||
}
|
||||
if _, ok := union_cast(^Type_Info.Float)info; ok {
|
||||
return true;
|
||||
if info == nil { return false; }
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Integer: return i.signed;
|
||||
case Type_Info.Float: return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
is_integer :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Integer)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Integer);
|
||||
return ok;
|
||||
}
|
||||
is_float :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Float)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Float);
|
||||
return ok;
|
||||
}
|
||||
is_complex :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Complex)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Complex);
|
||||
return ok;
|
||||
}
|
||||
is_any :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Any)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Any);
|
||||
return ok;
|
||||
}
|
||||
is_string :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.String)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.String);
|
||||
return ok;
|
||||
}
|
||||
is_boolean :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Boolean)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Boolean);
|
||||
return ok;
|
||||
}
|
||||
is_pointer :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Pointer)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Pointer);
|
||||
return ok;
|
||||
}
|
||||
is_procedure :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Procedure)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Procedure);
|
||||
return ok;
|
||||
}
|
||||
is_array :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Array)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Array);
|
||||
return ok;
|
||||
}
|
||||
is_dynamic_array :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Dynamic_Array)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Dynamic_Array);
|
||||
return ok;
|
||||
}
|
||||
is_dynamic_map :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Map)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Map);
|
||||
return ok;
|
||||
}
|
||||
is_slice :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Slice)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Slice);
|
||||
return ok;
|
||||
}
|
||||
is_vector :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Vector)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Vector);
|
||||
return ok;
|
||||
}
|
||||
is_tuple :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Tuple)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Tuple);
|
||||
return ok;
|
||||
}
|
||||
is_struct :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Struct)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Struct);
|
||||
return ok;
|
||||
}
|
||||
is_union :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Union)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Union);
|
||||
return ok;
|
||||
}
|
||||
is_raw_union :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Raw_Union)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Raw_Union);
|
||||
return ok;
|
||||
}
|
||||
is_enum :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
_, ok := union_cast(^Type_Info.Enum)type_info_base(info);
|
||||
_, ok := type_info_base(info).(^Type_Info.Enum);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -41,17 +41,17 @@ encode :: proc(d: []u16, s: []rune) {
|
||||
for r in s {
|
||||
match r {
|
||||
case 0..<_surr1, _surr3..<_surr_self:
|
||||
d[n] = cast(u16)r;
|
||||
d[n] = u16(r);
|
||||
n++;
|
||||
|
||||
case _surr_self..MAX_RUNE:
|
||||
r1, r2 := encode_surrogate_pair(r);
|
||||
d[n] = cast(u16)r1;
|
||||
d[n+1] = cast(u16)r2;
|
||||
d[n] = u16(r1);
|
||||
d[n+1] = u16(r2);
|
||||
n += 2;
|
||||
|
||||
default:
|
||||
d[n] = cast(u16)REPLACEMENT_CHAR;
|
||||
d[n] = u16(REPLACEMENT_CHAR);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
RUNE_ERROR :: '\ufffd';
|
||||
RUNE_SELF :: 0x80;
|
||||
RUNE_BOM :: 0xfeff;
|
||||
RUNE_EOF :: ~cast(rune)0;
|
||||
RUNE_EOF :: ~rune(0);
|
||||
MAX_RUNE :: '\U0010ffff';
|
||||
UTF_MAX :: 4;
|
||||
|
||||
@@ -60,15 +60,15 @@ immutable accept_sizes := [256]byte{
|
||||
|
||||
encode_rune :: proc(r: rune) -> ([4]byte, int) {
|
||||
buf: [4]byte;
|
||||
i := cast(u32)r;
|
||||
i := u32(r);
|
||||
mask: byte : 0x3f;
|
||||
if i <= 1<<7-1 {
|
||||
buf[0] = cast(byte)r;
|
||||
buf[0] = byte(r);
|
||||
return buf, 1;
|
||||
}
|
||||
if i <= 1<<11-1 {
|
||||
buf[0] = 0xc0 | cast(byte)(r>>6);
|
||||
buf[1] = 0x80 | cast(byte)r & mask;
|
||||
buf[0] = 0xc0 | byte(r>>6);
|
||||
buf[1] = 0x80 | byte(r) & mask;
|
||||
return buf, 2;
|
||||
}
|
||||
|
||||
@@ -79,20 +79,20 @@ encode_rune :: proc(r: rune) -> ([4]byte, int) {
|
||||
}
|
||||
|
||||
if i <= 1<<16-1 {
|
||||
buf[0] = 0xe0 | cast(byte)(r>>12);
|
||||
buf[1] = 0x80 | cast(byte)(r>>6) & mask;
|
||||
buf[2] = 0x80 | cast(byte)r & mask;
|
||||
buf[0] = 0xe0 | byte(r>>12);
|
||||
buf[1] = 0x80 | byte(r>>6) & mask;
|
||||
buf[2] = 0x80 | byte(r) & mask;
|
||||
return buf, 3;
|
||||
}
|
||||
|
||||
buf[0] = 0xf0 | cast(byte)(r>>18);
|
||||
buf[1] = 0x80 | cast(byte)(r>>12) & mask;
|
||||
buf[2] = 0x80 | cast(byte)(r>>6) & mask;
|
||||
buf[3] = 0x80 | cast(byte)r & mask;
|
||||
buf[0] = 0xf0 | byte(r>>18);
|
||||
buf[1] = 0x80 | byte(r>>12) & mask;
|
||||
buf[2] = 0x80 | byte(r>>6) & mask;
|
||||
buf[3] = 0x80 | byte(r) & mask;
|
||||
return buf, 4;
|
||||
}
|
||||
|
||||
decode_rune :: proc(s: string) -> (rune, int) #inline { return decode_rune(cast([]byte)s); }
|
||||
decode_rune :: proc(s: string) -> (rune, int) #inline { return decode_rune([]byte(s)); }
|
||||
decode_rune :: proc(s: []byte) -> (rune, int) {
|
||||
n := len(s);
|
||||
if n < 1 {
|
||||
@@ -101,12 +101,12 @@ decode_rune :: proc(s: []byte) -> (rune, int) {
|
||||
s0 := s[0];
|
||||
x := accept_sizes[s0];
|
||||
if x >= 0xF0 {
|
||||
mask := cast(rune)(x) << 31 >> 31; // NOTE(bill): Create 0x0000 or 0xffff.
|
||||
return cast(rune)(s[0])&~mask | RUNE_ERROR&mask, 1;
|
||||
mask := rune(x) << 31 >> 31; // NOTE(bill): Create 0x0000 or 0xffff.
|
||||
return rune(s[0])&~mask | RUNE_ERROR&mask, 1;
|
||||
}
|
||||
sz := x & 7;
|
||||
accept := accept_ranges[x>>4];
|
||||
if n < cast(int)sz {
|
||||
if n < int(sz) {
|
||||
return RUNE_ERROR, 1;
|
||||
}
|
||||
b1 := s[1];
|
||||
@@ -114,25 +114,25 @@ decode_rune :: proc(s: []byte) -> (rune, int) {
|
||||
return RUNE_ERROR, 1;
|
||||
}
|
||||
if sz == 2 {
|
||||
return cast(rune)(s0&MASK2)<<6 | cast(rune)(b1&MASKX), 2;
|
||||
return rune(s0&MASK2)<<6 | rune(b1&MASKX), 2;
|
||||
}
|
||||
b2 := s[2];
|
||||
if b2 < LOCB || HICB < b2 {
|
||||
return RUNE_ERROR, 1;
|
||||
}
|
||||
if sz == 3 {
|
||||
return cast(rune)(s0&MASK3)<<12 | cast(rune)(b1&MASKX)<<6 | cast(rune)(b2&MASKX), 3;
|
||||
return rune(s0&MASK3)<<12 | rune(b1&MASKX)<<6 | rune(b2&MASKX), 3;
|
||||
}
|
||||
b3 := s[3];
|
||||
if b3 < LOCB || HICB < b3 {
|
||||
return RUNE_ERROR, 1;
|
||||
}
|
||||
return cast(rune)(s0&MASK4)<<18 | cast(rune)(b1&MASKX)<<12 | cast(rune)(b2&MASKX)<<6 | cast(rune)(b3&MASKX), 4;
|
||||
return rune(s0&MASK4)<<18 | rune(b1&MASKX)<<12 | rune(b2&MASKX)<<6 | rune(b3&MASKX), 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
decode_last_rune :: proc(s: string) -> (rune, int) #inline { return decode_last_rune(cast([]byte)s); }
|
||||
decode_last_rune :: proc(s: string) -> (rune, int) #inline { return decode_last_rune([]byte(s)); }
|
||||
decode_last_rune :: proc(s: []byte) -> (rune, int) {
|
||||
r: rune;
|
||||
size: int;
|
||||
@@ -143,7 +143,7 @@ decode_last_rune :: proc(s: []byte) -> (rune, int) {
|
||||
return RUNE_ERROR, 0;
|
||||
}
|
||||
start = end-1;
|
||||
r = cast(rune)s[start];
|
||||
r = rune(s[start]);
|
||||
if r < RUNE_SELF {
|
||||
return r, 1;
|
||||
}
|
||||
@@ -194,7 +194,7 @@ valid_string :: proc(s: string) -> bool {
|
||||
if x == 0xf1 {
|
||||
return false;
|
||||
}
|
||||
size := cast(int)(x & 7);
|
||||
size := int(x & 7);
|
||||
if i+size > n {
|
||||
return false;
|
||||
}
|
||||
@@ -217,7 +217,7 @@ valid_string :: proc(s: string) -> bool {
|
||||
|
||||
rune_start :: proc(b: byte) -> bool #inline { return b&0xc0 != 0x80; }
|
||||
|
||||
rune_count :: proc(s: string) -> int #inline { return rune_count(cast([]byte)s); }
|
||||
rune_count :: proc(s: string) -> int #inline { return rune_count([]byte(s)); }
|
||||
rune_count :: proc(s: []byte) -> int {
|
||||
count := 0;
|
||||
n := len(s);
|
||||
@@ -234,7 +234,7 @@ rune_count :: proc(s: []byte) -> int {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
size := cast(int)(x & 7);
|
||||
size := int(x & 7);
|
||||
if i+size > n {
|
||||
i++;
|
||||
continue;
|
||||
|
||||
263
src/check_expr.c
263
src/check_expr.c
@@ -1839,6 +1839,12 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
|
||||
return false;
|
||||
}
|
||||
if (out_value) *out_value = v;
|
||||
|
||||
|
||||
if (is_type_untyped(type)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
i64 i = v.value_integer;
|
||||
u64 u = *cast(u64 *)&i;
|
||||
i64 s = 8*type_size_of(c->allocator, type);
|
||||
@@ -2005,7 +2011,7 @@ bool check_is_vector_elem(Checker *c, AstNode *expr) {
|
||||
|
||||
void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
||||
switch (op.kind) {
|
||||
case Token_Pointer: { // Pointer address
|
||||
case Token_And: { // Pointer address
|
||||
if (o->mode == Addressing_Type) {
|
||||
o->type = make_type_pointer(c->allocator, o->type);
|
||||
return;
|
||||
@@ -3217,6 +3223,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
case BuiltinProc_align_of:
|
||||
case BuiltinProc_offset_of:
|
||||
case BuiltinProc_type_info:
|
||||
case BuiltinProc_transmute:
|
||||
// NOTE(bill): The first arg may be a Type, this will be checked case by case
|
||||
break;
|
||||
default:
|
||||
@@ -4463,6 +4470,56 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case BuiltinProc_transmute: {
|
||||
Operand op = {0};
|
||||
check_expr_or_type(c, &op, ce->args.e[0]);
|
||||
Type *t = op.type;
|
||||
if ((op.mode != Addressing_Type && t == NULL) || t == t_invalid) {
|
||||
error_node(ce->args.e[0], "Expected a type for `transmute`");
|
||||
return false;
|
||||
}
|
||||
AstNode *expr = ce->args.e[1];
|
||||
Operand *o = operand;
|
||||
check_expr(c, o, expr);
|
||||
if (o->mode == Addressing_Invalid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (o->mode == Addressing_Constant) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
error_node(o->expr, "Cannot transmute a constant expression: `%s`", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = expr;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_type_untyped(o->type)) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
error_node(o->expr, "Cannot transmute untyped expression: `%s`", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = expr;
|
||||
return false;
|
||||
}
|
||||
|
||||
i64 srcz = type_size_of(c->allocator, o->type);
|
||||
i64 dstz = type_size_of(c->allocator, t);
|
||||
if (srcz != dstz) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
gbString type_str = type_to_string(t);
|
||||
error_node(o->expr, "Cannot transmute `%s` to `%s`, %lld vs %lld bytes", expr_str, type_str, srcz, dstz);
|
||||
gb_string_free(type_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = expr;
|
||||
return false;
|
||||
}
|
||||
|
||||
o->mode = Addressing_Value;
|
||||
o->type = t;
|
||||
} break;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -4766,13 +4823,14 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
|
||||
}
|
||||
|
||||
if (operand->mode == Addressing_Type) {
|
||||
#if 0
|
||||
gbString str = type_to_string(operand->type);
|
||||
error_node(call, "Expected a procedure, got a type `%s`", str);
|
||||
gb_string_free(str);
|
||||
operand->mode = Addressing_Invalid;
|
||||
operand->expr = call;
|
||||
return Expr_Stmt;
|
||||
#if 0
|
||||
#else
|
||||
Type *t = operand->type;
|
||||
gbString str = type_to_string(t);
|
||||
operand->mode = Addressing_Invalid;
|
||||
@@ -5480,128 +5538,84 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
o->expr = node;
|
||||
case_end;
|
||||
|
||||
case_ast_node(ce, CastExpr, node);
|
||||
Type *t = check_type(c, ce->type);
|
||||
check_expr(c, o, ce->expr);
|
||||
case_ast_node(ta, TypeAssertion, node);
|
||||
check_expr(c, o, ta->expr);
|
||||
if (o->mode == Addressing_Invalid) {
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
switch (ce->token.kind) {
|
||||
case Token_cast:
|
||||
check_cast(c, o, t);
|
||||
break;
|
||||
case Token_transmute: {
|
||||
if (o->mode == Addressing_Constant) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
error_node(o->expr, "Cannot transmute a constant expression: `%s`", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
Type *t = check_type(c, ta->type);
|
||||
|
||||
if (is_type_untyped(o->type)) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
error_node(o->expr, "Cannot transmute untyped expression: `%s`", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
i64 srcz = type_size_of(c->allocator, o->type);
|
||||
i64 dstz = type_size_of(c->allocator, t);
|
||||
if (srcz != dstz) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
gbString type_str = type_to_string(t);
|
||||
error_node(o->expr, "Cannot transmute `%s` to `%s`, %lld vs %lld bytes", expr_str, type_str, srcz, dstz);
|
||||
gb_string_free(type_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
o->type = t;
|
||||
} break;
|
||||
|
||||
case Token_union_cast: {
|
||||
if (o->mode == Addressing_Constant) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
error_node(o->expr, "Cannot `union_cast` a constant expression: `%s`", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
if (is_type_untyped(o->type)) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
error_node(o->expr, "Cannot `union_cast` an untyped expression: `%s`", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
bool src_is_ptr = is_type_pointer(o->type);
|
||||
bool dst_is_ptr = is_type_pointer(t);
|
||||
Type *src = type_deref(o->type);
|
||||
Type *dst = type_deref(t);
|
||||
Type *bsrc = base_type(src);
|
||||
Type *bdst = base_type(dst);
|
||||
|
||||
if (src_is_ptr != dst_is_ptr) {
|
||||
gbString src_type_str = type_to_string(o->type);
|
||||
gbString dst_type_str = type_to_string(t);
|
||||
error_node(o->expr, "Invalid `union_cast` types: `%s` and `%s`", src_type_str, dst_type_str);
|
||||
gb_string_free(dst_type_str);
|
||||
gb_string_free(src_type_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
if (!is_type_union(src)) {
|
||||
error_node(o->expr, "`union_cast` can only operate on unions");
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
for (isize i = 1; i < bsrc->Record.variant_count; i++) {
|
||||
Entity *f = bsrc->Record.variants[i];
|
||||
if (are_types_identical(f->type, dst)) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
gbString dst_type_str = type_to_string(t);
|
||||
error_node(o->expr, "Cannot `union_cast` `%s` to `%s`", expr_str, dst_type_str);
|
||||
gb_string_free(dst_type_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
add_type_info_type(c, o->type);
|
||||
add_type_info_type(c, t);
|
||||
|
||||
o->type = t;
|
||||
o->mode = Addressing_OptionalOk;
|
||||
} break;
|
||||
|
||||
default:
|
||||
GB_PANIC("Unknown cast expression");
|
||||
if (o->mode == Addressing_Constant) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
error_node(o->expr, "A type assertion cannot be applied to a constant expression: `%s`", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
case_end;
|
||||
|
||||
if (is_type_untyped(o->type)) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
error_node(o->expr, "A type assertion cannot be applied to an untyped expression: `%s`", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
|
||||
bool src_is_ptr = is_type_pointer(o->type);
|
||||
bool dst_is_ptr = is_type_pointer(t);
|
||||
Type *src = type_deref(o->type);
|
||||
Type *dst = type_deref(t);
|
||||
Type *bsrc = base_type(src);
|
||||
Type *bdst = base_type(dst);
|
||||
|
||||
if (src_is_ptr != dst_is_ptr) {
|
||||
gbString src_type_str = type_to_string(o->type);
|
||||
gbString dst_type_str = type_to_string(t);
|
||||
error_node(o->expr, "Invalid type assertion types: `%s` and `%s`", src_type_str, dst_type_str);
|
||||
gb_string_free(dst_type_str);
|
||||
gb_string_free(src_type_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
if (!is_type_union(src)) {
|
||||
error_node(o->expr, "Type assertions can only operate on unions");
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
for (isize i = 1; i < bsrc->Record.variant_count; i++) {
|
||||
Entity *f = bsrc->Record.variants[i];
|
||||
if (are_types_identical(f->type, dst)) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
gbString dst_type_str = type_to_string(t);
|
||||
error_node(o->expr, "Cannot type assert `%s` to `%s`", expr_str, dst_type_str);
|
||||
gb_string_free(dst_type_str);
|
||||
gb_string_free(expr_str);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
}
|
||||
|
||||
add_type_info_type(c, o->type);
|
||||
add_type_info_type(c, t);
|
||||
|
||||
o->type = t;
|
||||
o->mode = Addressing_OptionalOk;
|
||||
case_end;
|
||||
|
||||
case_ast_node(ue, UnaryExpr, node);
|
||||
check_expr_base(c, o, ue->expr, type_hint);
|
||||
@@ -6022,14 +6036,6 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
|
||||
str = write_expr_to_string(str, ue->expr);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ce, CastExpr, node);
|
||||
str = string_append_token(str, ce->token);
|
||||
str = gb_string_appendc(str, "(");
|
||||
str = write_expr_to_string(str, ce->type);
|
||||
str = gb_string_appendc(str, ")");
|
||||
str = write_expr_to_string(str, ce->expr);
|
||||
case_end;
|
||||
|
||||
case_ast_node(de, DerefExpr, node);
|
||||
str = write_expr_to_string(str, de->expr);
|
||||
str = gb_string_appendc(str, "^");
|
||||
@@ -6055,6 +6061,13 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
|
||||
str = write_expr_to_string(str, se->selector);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ta, TypeAssertion, node);
|
||||
str = write_expr_to_string(str, ta->expr);
|
||||
str = gb_string_appendc(str, ".(");
|
||||
str = write_expr_to_string(str, ta->type);
|
||||
str = gb_string_appendc(str, ")");
|
||||
case_end;
|
||||
|
||||
case_ast_node(ie, IndexExpr, node);
|
||||
str = write_expr_to_string(str, ie->expr);
|
||||
str = gb_string_appendc(str, "[");
|
||||
|
||||
@@ -52,7 +52,6 @@ typedef enum BuiltinProcId {
|
||||
BuiltinProc_panic,
|
||||
|
||||
BuiltinProc_copy,
|
||||
// BuiltinProc_append,
|
||||
|
||||
BuiltinProc_swizzle,
|
||||
|
||||
@@ -72,6 +71,8 @@ typedef enum BuiltinProcId {
|
||||
BuiltinProc_abs,
|
||||
BuiltinProc_clamp,
|
||||
|
||||
BuiltinProc_transmute,
|
||||
|
||||
BuiltinProc_Count,
|
||||
} BuiltinProcId;
|
||||
gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
|
||||
@@ -123,6 +124,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
|
||||
{STR_LIT("max"), 2, false, Expr_Expr},
|
||||
{STR_LIT("abs"), 1, false, Expr_Expr},
|
||||
{STR_LIT("clamp"), 3, false, Expr_Expr},
|
||||
|
||||
{STR_LIT("transmute"), 2, false, Expr_Expr},
|
||||
};
|
||||
|
||||
|
||||
|
||||
81
src/ir.c
81
src/ir.c
@@ -3105,7 +3105,7 @@ irValue *ir_emit_union_cast(irProcedure *proc, irValue *value, Type *type, Token
|
||||
|
||||
args[4] = ir_type_info(proc, src_type);
|
||||
args[5] = ir_type_info(proc, dst_type);
|
||||
ir_emit_global_call(proc, "__union_cast_check", args, 6);
|
||||
ir_emit_global_call(proc, "__type_assertion_check", args, 6);
|
||||
|
||||
return ir_emit_load(proc, ir_emit_struct_ep(proc, v, 0));
|
||||
}
|
||||
@@ -3606,36 +3606,21 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
case_end;
|
||||
#endif
|
||||
|
||||
case_ast_node(ce, CastExpr, expr);
|
||||
case_ast_node(ta, TypeAssertion, expr);
|
||||
Type *type = tv->type;
|
||||
irValue *e = ir_build_expr(proc, ce->expr);
|
||||
switch (ce->token.kind) {
|
||||
case Token_cast:
|
||||
ir_emit_comment(proc, str_lit("cast - cast"));
|
||||
return ir_emit_conv(proc, e, type);
|
||||
|
||||
case Token_transmute:
|
||||
ir_emit_comment(proc, str_lit("cast - transmute"));
|
||||
return ir_emit_transmute(proc, e, type);
|
||||
|
||||
#if 0
|
||||
case Token_down_cast:
|
||||
ir_emit_comment(proc, str_lit("cast - down_cast"));
|
||||
return ir_emit_down_cast(proc, e, type);
|
||||
#endif
|
||||
|
||||
case Token_union_cast:
|
||||
irValue *e = ir_build_expr(proc, ta->expr);
|
||||
Type *t = type_deref(ir_type(e));
|
||||
if (is_type_union(t)) {
|
||||
ir_emit_comment(proc, str_lit("cast - union_cast"));
|
||||
return ir_emit_union_cast(proc, e, type, ast_node_token(expr).pos);
|
||||
|
||||
default:
|
||||
GB_PANIC("Unknown cast expression");
|
||||
} else {
|
||||
GB_PANIC("TODO(bill): type assertion %s", type_to_string(ir_type(e)));
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(ue, UnaryExpr, expr);
|
||||
switch (ue->op.kind) {
|
||||
case Token_Pointer:
|
||||
case Token_And:
|
||||
return ir_emit_ptr_offset(proc, ir_build_addr(proc, ue->expr).addr, v_zero); // Make a copy of the pointer
|
||||
default:
|
||||
return ir_emit_unary_arith(proc, ue->op.kind, ir_build_expr(proc, ue->expr), tv->type);
|
||||
@@ -3734,6 +3719,11 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
return ir_type_info(proc, t);
|
||||
} break;
|
||||
|
||||
case BuiltinProc_transmute: {
|
||||
irValue *x = ir_build_expr(proc, ce->args.e[1]);
|
||||
return ir_emit_transmute(proc, x, tv->type);
|
||||
}
|
||||
|
||||
case BuiltinProc_len: {
|
||||
irValue *v = ir_build_expr(proc, ce->args.e[0]);
|
||||
Type *t = base_type(ir_type(v));
|
||||
@@ -4736,50 +4726,23 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(ce, CastExpr, expr);
|
||||
switch (ce->token.kind) {
|
||||
case Token_cast: {
|
||||
ir_emit_comment(proc, str_lit("Cast - cast"));
|
||||
// NOTE(bill): Needed for dereference of pointer conversion
|
||||
case_ast_node(ta, TypeAssertion, expr);
|
||||
irValue *e = ir_build_expr(proc, ta->expr);
|
||||
Type *t = type_deref(ir_type(e));
|
||||
if (is_type_union(t)) {
|
||||
Type *type = type_of_expr(proc->module->info, expr);
|
||||
irValue *v = ir_add_local_generated(proc, type);
|
||||
ir_emit_store(proc, v, ir_emit_conv(proc, ir_build_expr(proc, ce->expr), type));
|
||||
ir_emit_comment(proc, str_lit("cast - union_cast"));
|
||||
ir_emit_store(proc, v, ir_emit_union_cast(proc, ir_build_expr(proc, ta->expr), type, ast_node_token(expr).pos));
|
||||
return ir_addr(v);
|
||||
}
|
||||
case Token_transmute: {
|
||||
ir_emit_comment(proc, str_lit("Cast - transmute"));
|
||||
// NOTE(bill): Needed for dereference of pointer conversion
|
||||
Type *type = type_of_expr(proc->module->info, expr);
|
||||
irValue *v = ir_add_local_generated(proc, type);
|
||||
ir_emit_store(proc, v, ir_emit_transmute(proc, ir_build_expr(proc, ce->expr), type));
|
||||
return ir_addr(v);
|
||||
}
|
||||
#if 0
|
||||
case Token_down_cast: {
|
||||
ir_emit_comment(proc, str_lit("Cast - down_cast"));
|
||||
// NOTE(bill): Needed for dereference of pointer conversion
|
||||
Type *type = type_of_expr(proc->module->info, expr);
|
||||
irValue *v = ir_add_local_generated(proc, type);
|
||||
ir_emit_store(proc, v, ir_emit_down_cast(proc, ir_build_expr(proc, ce->expr), type));
|
||||
return ir_addr(v);
|
||||
}
|
||||
#endif
|
||||
case Token_union_cast: {
|
||||
ir_emit_comment(proc, str_lit("Cast - union_cast"));
|
||||
// NOTE(bill): Needed for dereference of pointer conversion
|
||||
Type *type = type_of_expr(proc->module->info, expr);
|
||||
irValue *v = ir_add_local_generated(proc, type);
|
||||
ir_emit_store(proc, v, ir_emit_union_cast(proc, ir_build_expr(proc, ce->expr), type, ast_node_token(expr).pos));
|
||||
return ir_addr(v);
|
||||
}
|
||||
default:
|
||||
GB_PANIC("Unknown cast expression");
|
||||
} else {
|
||||
GB_PANIC("TODO(bill): type assertion %s", type_to_string(ir_type(e)));
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(ue, UnaryExpr, expr);
|
||||
switch (ue->op.kind) {
|
||||
case Token_Pointer: {
|
||||
case Token_And: {
|
||||
return ir_build_addr(proc, ue->expr);
|
||||
}
|
||||
default:
|
||||
|
||||
97
src/parser.c
97
src/parser.c
@@ -182,9 +182,9 @@ AST_NODE_KIND(_ExprBegin, "", i32) \
|
||||
Token open; \
|
||||
Token close; \
|
||||
}) \
|
||||
AST_NODE_KIND(CastExpr, "cast expression", struct { Token token; AstNode *type, *expr; Token open, close; }) \
|
||||
AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \
|
||||
AST_NODE_KIND(TernaryExpr, "ternary expression", struct { AstNode *cond, *x, *y; }) \
|
||||
AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \
|
||||
AST_NODE_KIND(TernaryExpr, "ternary expression", struct { AstNode *cond, *x, *y; }) \
|
||||
AST_NODE_KIND(TypeAssertion, "type assertion", struct { AstNode *expr; Token dot; AstNode *type; }) \
|
||||
AST_NODE_KIND(_ExprEnd, "", i32) \
|
||||
AST_NODE_KIND(_StmtBegin, "", i32) \
|
||||
AST_NODE_KIND(BadStmt, "bad statement", struct { Token begin, end; }) \
|
||||
@@ -485,13 +485,13 @@ Token ast_node_token(AstNode *node) {
|
||||
return ast_node_token(node->SelectorExpr.selector);
|
||||
}
|
||||
return node->SelectorExpr.token;
|
||||
case AstNode_IndexExpr: return node->IndexExpr.open;
|
||||
case AstNode_SliceExpr: return node->SliceExpr.open;
|
||||
case AstNode_Ellipsis: return node->Ellipsis.token;
|
||||
case AstNode_CastExpr: return node->CastExpr.token;
|
||||
case AstNode_FieldValue: return node->FieldValue.eq;
|
||||
case AstNode_DerefExpr: return node->DerefExpr.op;
|
||||
case AstNode_TernaryExpr: return ast_node_token(node->TernaryExpr.cond);
|
||||
case AstNode_IndexExpr: return node->IndexExpr.open;
|
||||
case AstNode_SliceExpr: return node->SliceExpr.open;
|
||||
case AstNode_Ellipsis: return node->Ellipsis.token;
|
||||
case AstNode_FieldValue: return node->FieldValue.eq;
|
||||
case AstNode_DerefExpr: return node->DerefExpr.op;
|
||||
case AstNode_TernaryExpr: return ast_node_token(node->TernaryExpr.cond);
|
||||
case AstNode_TypeAssertion: return ast_node_token(node->TypeAssertion.expr);
|
||||
|
||||
case AstNode_BadStmt: return node->BadStmt.begin;
|
||||
case AstNode_EmptyStmt: return node->EmptyStmt.token;
|
||||
@@ -773,16 +773,6 @@ AstNode *ast_field_value(AstFile *f, AstNode *field, AstNode *value, Token eq) {
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *ast_cast_expr(AstFile *f, Token token, AstNode *type, AstNode *expr, Token open, Token close) {
|
||||
AstNode *result = make_ast_node(f, AstNode_CastExpr);
|
||||
result->CastExpr.token = token;
|
||||
result->CastExpr.type = type;
|
||||
result->CastExpr.expr = expr;
|
||||
result->CastExpr.open = open;
|
||||
result->CastExpr.close = close;
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *ast_compound_lit(AstFile *f, AstNode *type, AstNodeArray elems, Token open, Token close) {
|
||||
AstNode *result = make_ast_node(f, AstNode_CompoundLit);
|
||||
result->CompoundLit.type = type;
|
||||
@@ -806,6 +796,14 @@ AstNode *ast_ternary_expr(AstFile *f, AstNode *cond, AstNode *x, AstNode *y) {
|
||||
result->TernaryExpr.y = y;
|
||||
return result;
|
||||
}
|
||||
AstNode *ast_type_assertion(AstFile *f, AstNode *expr, Token dot, AstNode *type) {
|
||||
AstNode *result = make_ast_node(f, AstNode_TypeAssertion);
|
||||
result->TypeAssertion.expr = expr;
|
||||
result->TypeAssertion.dot = dot;
|
||||
result->TypeAssertion.type = type;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1977,6 +1975,13 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
|
||||
// case Token_Integer:
|
||||
// operand = ast_selector_expr(f, token, operand, parse_expr(f, lhs));
|
||||
// break;
|
||||
case Token_OpenParen: {
|
||||
Token open = expect_token(f, Token_OpenParen);
|
||||
AstNode *type = parse_type(f);
|
||||
Token close = expect_token(f, Token_CloseParen);
|
||||
operand = ast_type_assertion(f, operand, token, type);
|
||||
} break;
|
||||
|
||||
default:
|
||||
syntax_error(f->curr_token, "Expected a selector");
|
||||
next_token(f);
|
||||
@@ -2073,32 +2078,33 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
|
||||
AstNode *parse_unary_expr(AstFile *f, bool lhs) {
|
||||
switch (f->curr_token.kind) {
|
||||
|
||||
case Token_cast:
|
||||
case Token_transmute:
|
||||
case Token_union_cast:
|
||||
{
|
||||
Token token = f->curr_token; next_token(f);
|
||||
Token open = expect_token(f, Token_OpenParen);
|
||||
AstNode *type = parse_type(f);
|
||||
Token close = expect_token(f, Token_CloseParen);
|
||||
AstNode *expr = parse_unary_expr(f, lhs);
|
||||
return ast_cast_expr(f, token, type, expr, open, close);
|
||||
} break;
|
||||
// case Token_cast:
|
||||
// case Token_transmute:
|
||||
// case Token_union_cast:
|
||||
// {
|
||||
// Token token = f->curr_token; next_token(f);
|
||||
// Token open = expect_token(f, Token_OpenParen);
|
||||
// AstNode *type = parse_type(f);
|
||||
// Token close = expect_token(f, Token_CloseParen);
|
||||
// AstNode *expr = parse_unary_expr(f, lhs);
|
||||
// return ast_cast_expr(f, token, type, expr, open, close);
|
||||
// } break;
|
||||
|
||||
// case Token_Pointer: {
|
||||
// Token op = f->curr_token;
|
||||
// next_token(f);
|
||||
// AstNode *expr = parse_unary_expr(f, lhs);
|
||||
// if (is_ast_node_type(expr)) {
|
||||
// return ast_pointer_type(f, op, expr);
|
||||
// }
|
||||
// return ast_unary_expr(f, op, expr);
|
||||
// } break;
|
||||
|
||||
case Token_Pointer: {
|
||||
Token op = f->curr_token;
|
||||
next_token(f);
|
||||
AstNode *expr = parse_unary_expr(f, lhs);
|
||||
if (is_ast_node_type(expr)) {
|
||||
return ast_pointer_type(f, op, expr);
|
||||
}
|
||||
return ast_unary_expr(f, op, expr);
|
||||
} break;
|
||||
// case Token_Maybe:
|
||||
case Token_Add:
|
||||
case Token_Sub:
|
||||
case Token_Not:
|
||||
case Token_Xor: {
|
||||
case Token_Xor:
|
||||
case Token_And: {
|
||||
Token op = f->curr_token;
|
||||
next_token(f);
|
||||
return ast_unary_expr(f, op, parse_unary_expr(f, lhs));
|
||||
@@ -2663,10 +2669,11 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
||||
AstNode *sel = parse_ident(f);
|
||||
e = ast_selector_expr(f, token, e, sel);
|
||||
}
|
||||
if (f->curr_token.kind == Token_OpenParen) {
|
||||
// TODO(bill): Merge type_or_ident into the general parsing for expressions
|
||||
// if (f->curr_token.kind == Token_OpenParen) {
|
||||
// HACK NOTE(bill): For type_of_val(expr) et al.
|
||||
e = parse_call_expr(f, e);
|
||||
}
|
||||
// e = parse_call_expr(f, e);
|
||||
// }
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
61
src/ssa.c
61
src/ssa.c
@@ -1111,40 +1111,6 @@ ssaAddr ssa_build_addr(ssaProc *p, AstNode *expr) {
|
||||
}
|
||||
case_end;
|
||||
|
||||
|
||||
case_ast_node(ce, CastExpr, expr);
|
||||
switch (ce->token.kind) {
|
||||
case Token_cast: {
|
||||
ssa_emit_comment(p, str_lit("Cast - cast"));
|
||||
// NOTE(bill): Needed for dereference of pointer conversion
|
||||
Type *type = type_of_expr(p->module->info, expr);
|
||||
ssaAddr addr = ssa_add_local_generated(p, type);
|
||||
ssa_addr_store(p, addr, ssa_emit_conv(p, ssa_build_expr(p, ce->expr), type));
|
||||
return addr;
|
||||
}
|
||||
#if 0
|
||||
case Token_transmute: {
|
||||
ssa_emit_comment(p, str_lit("Cast - transmute"));
|
||||
// NOTE(bill): Needed for dereference of pointer conversion
|
||||
Type *type = type_of_expr(p->module->info, expr);
|
||||
ssaValue *v = ssa_add_local_generated(p, type);
|
||||
ssa_emit_store(p, v, ssa_emit_transmute(p, ssa_build_expr(p, ce->expr), type));
|
||||
return ssa_addr(v);
|
||||
}
|
||||
case Token_union_cast: {
|
||||
ssa_emit_comment(p, str_lit("Cast - union_cast"));
|
||||
// NOTE(bill): Needed for dereference of pointer conversion
|
||||
Type *type = type_of_expr(p->module->info, expr);
|
||||
ssaValue *v = ssa_add_local_generated(p, type);
|
||||
ssa_emit_store(p, v, ssa_emit_union_cast(p, ssa_build_expr(p, ce->expr), type, ast_node_token(expr).pos));
|
||||
return ssa_addr(v);
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
GB_PANIC("Unknown cast expression");
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(ue, UnaryExpr, expr);
|
||||
switch (ue->op.kind) {
|
||||
case Token_Pointer: {
|
||||
@@ -1841,33 +1807,6 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
|
||||
case_end;
|
||||
|
||||
|
||||
case_ast_node(ce, CastExpr, expr);
|
||||
Type *type = tv->type;
|
||||
ssaValue *e = ssa_build_expr(p, ce->expr);
|
||||
switch (ce->token.kind) {
|
||||
case Token_cast:
|
||||
ssa_emit_comment(p, str_lit("cast - cast"));
|
||||
return ssa_emit_conv(p, e, type);
|
||||
|
||||
// case Token_transmute:
|
||||
// ssa_emit_comment(p, str_lit("cast - transmute"));
|
||||
// return ssa_emit_transmute(p, e, type);
|
||||
|
||||
#if 0
|
||||
case Token_down_cast:
|
||||
ssa_emit_comment(p, str_lit("cast - down_cast"));
|
||||
return ssa_emit_down_cast(p, e, type);
|
||||
#endif
|
||||
|
||||
// case Token_union_cast:
|
||||
// ssa_emit_comment(p, str_lit("cast - union_cast"));
|
||||
// return ssa_emit_union_cast(p, e, type, ast_node_token(expr).pos);
|
||||
|
||||
default:
|
||||
GB_PANIC("Unhandled cast expression %.*s", LIT(token_strings[ce->token.kind]));
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(pl, ProcLit, expr);
|
||||
GB_PANIC("TODO(bill): ssa_build_expr ProcLit");
|
||||
#if 0
|
||||
|
||||
@@ -76,6 +76,7 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
|
||||
TOKEN_KIND(Token_Comma, ","), \
|
||||
TOKEN_KIND(Token_Ellipsis, ".."), \
|
||||
TOKEN_KIND(Token_HalfClosed, "..<"), \
|
||||
TOKEN_KIND(Token_BackSlash, "\\"), \
|
||||
TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
|
||||
\
|
||||
TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
@@ -106,9 +107,9 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
TOKEN_KIND(Token_using, "using"), \
|
||||
TOKEN_KIND(Token_no_alias, "no_alias"), \
|
||||
TOKEN_KIND(Token_immutable, "immutable"), \
|
||||
TOKEN_KIND(Token_cast, "cast"), \
|
||||
TOKEN_KIND(Token_transmute, "transmute"), \
|
||||
TOKEN_KIND(Token_union_cast, "union_cast"), \
|
||||
/* TOKEN_KIND(Token_cast, "cast"), */ \
|
||||
/* TOKEN_KIND(Token_transmute, "transmute"), */ \
|
||||
/* TOKEN_KIND(Token_union_cast, "union_cast"), */ \
|
||||
TOKEN_KIND(Token_context, "context"), \
|
||||
TOKEN_KIND(Token_push_context, "push_context"), \
|
||||
TOKEN_KIND(Token_push_allocator, "push_allocator"), \
|
||||
@@ -878,20 +879,21 @@ Token tokenizer_get_token(Tokenizer *t) {
|
||||
}
|
||||
break;
|
||||
|
||||
case '#': token.kind = Token_Hash; break;
|
||||
case '@': token.kind = Token_At; break;
|
||||
case '$': token.kind = Token_Dollar; break;
|
||||
case '?': token.kind = Token_Question; break;
|
||||
case '^': token.kind = Token_Pointer; break;
|
||||
case ';': token.kind = Token_Semicolon; break;
|
||||
case ',': token.kind = Token_Comma; break;
|
||||
case ':': token.kind = Token_Colon; break;
|
||||
case '(': token.kind = Token_OpenParen; break;
|
||||
case ')': token.kind = Token_CloseParen; break;
|
||||
case '[': token.kind = Token_OpenBracket; break;
|
||||
case ']': token.kind = Token_CloseBracket; break;
|
||||
case '{': token.kind = Token_OpenBrace; break;
|
||||
case '}': token.kind = Token_CloseBrace; break;
|
||||
case '#': token.kind = Token_Hash; break;
|
||||
case '@': token.kind = Token_At; break;
|
||||
case '$': token.kind = Token_Dollar; break;
|
||||
case '?': token.kind = Token_Question; break;
|
||||
case '^': token.kind = Token_Pointer; break;
|
||||
case ';': token.kind = Token_Semicolon; break;
|
||||
case ',': token.kind = Token_Comma; break;
|
||||
case ':': token.kind = Token_Colon; break;
|
||||
case '(': token.kind = Token_OpenParen; break;
|
||||
case ')': token.kind = Token_CloseParen; break;
|
||||
case '[': token.kind = Token_OpenBracket; break;
|
||||
case ']': token.kind = Token_CloseBracket; break;
|
||||
case '{': token.kind = Token_OpenBrace; break;
|
||||
case '}': token.kind = Token_CloseBrace; break;
|
||||
case '\\': token.kind = Token_BackSlash; break;
|
||||
|
||||
case '*': token.kind = token_kind_variant2(t, Token_Mul, Token_MulEq); break;
|
||||
case '%': token.kind = token_kind_variant2(t, Token_Mod, Token_ModEq); break;
|
||||
|
||||
Reference in New Issue
Block a user