diff --git a/core/_preload.odin b/core/_preload.odin index 997ed7674..90ebcde56 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -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.. 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) { diff --git a/core/decimal.odin b/core/decimal.odin index b0b730f99..a758ea3af 100644 --- a/core/decimal.odin +++ b/core/decimal.odin @@ -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.. 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; 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; diff --git a/core/fmt.odin b/core/fmt.odin index 9c6b6c4b2..e4d6df06d 100644 --- a/core/fmt.odin +++ b/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.. int { sb := make_string_buffer_from_slice(buf[0..<0.. int { sb := make_string_buffer_from_slice(buf[0..<0.. 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.. 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.. 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.. 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, ""); } else { - fmt_arg(^fi, args[index], 'v'); + fmt_arg(&fi, args[index], 'v'); } } write_string(b, ")"); diff --git a/core/hash.odin b/core/hash.odin index 2f9659f7a..ac40ca938 100644 --- a/core/hash.odin +++ b/core/hash.odin @@ -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; } diff --git a/core/math.odin b/core/math.odin index 8ad563035..dd6a2868a 100644 --- a/core/math.odin +++ b/core/math.odin @@ -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; } diff --git a/core/mem.odin b/core/mem.odin index 27146a60d..ff7ab8367 100644 --- a/core/mem.odin +++ b/core/mem.odin @@ -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: diff --git a/core/opengl.odin b/core/opengl.odin index 3200dc942..1de71a4d5 100644 --- a/core/opengl.odin +++ b/core/opengl.odin @@ -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.. 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"); } diff --git a/core/os_linux.odin b/core/os_linux.odin index b439b3dc4..1de14b0f9 100644 --- a/core/os_linux.odin +++ b/core/os_linux.odin @@ -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 { diff --git a/core/os_windows.odin b/core/os_windows.odin index 28b83e483..1722efd3a 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -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.. (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.mantbits) & (1< [ } 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..= 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); } diff --git a/core/strings.odin b/core/strings.odin index 846c7398c..bbd5ec303 100644 --- a/core/strings.odin +++ b/core/strings.odin @@ -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)); } diff --git a/core/sys/windows.odin b/core/sys/windows.odin index 3d29bfa83..80466570a 100644 --- a/core/sys/windows.odin +++ b/core/sys/windows.odin @@ -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, diff --git a/core/types.odin b/core/types.odin index 459af5752..63cec2243 100644 --- a/core/types.odin +++ b/core/types.odin @@ -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; } diff --git a/core/utf16.odin b/core/utf16.odin index 222688f1d..f90bbff28 100644 --- a/core/utf16.odin +++ b/core/utf16.odin @@ -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++; } } diff --git a/core/utf8.odin b/core/utf8.odin index db0413885..40338f432 100644 --- a/core/utf8.odin +++ b/core/utf8.odin @@ -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; diff --git a/src/check_expr.c b/src/check_expr.c index 607a7ab5d..c700e7d25 100644 --- a/src/check_expr.c +++ b/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, "["); diff --git a/src/checker.c b/src/checker.c index d61e33633..9c40cd348 100644 --- a/src/checker.c +++ b/src/checker.c @@ -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}, }; diff --git a/src/ir.c b/src/ir.c index 6de568b91..12bb07826 100644 --- a/src/ir.c +++ b/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: diff --git a/src/parser.c b/src/parser.c index 3dab46644..ad1e2945f 100644 --- a/src/parser.c +++ b/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; } diff --git a/src/ssa.c b/src/ssa.c index 2c4394cd3..de4e4ad80 100644 --- a/src/ssa.c +++ b/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 diff --git a/src/tokenizer.c b/src/tokenizer.c index 9a4ecea59..56186f914 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -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;