diff --git a/code/demo.odin b/code/demo.odin index 83d9f09e0..9fb3e9aad 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -10,20 +10,22 @@ #import "utf8.odin"; main :: proc() { - foo :: proc(x: ^i32) { + foo :: proc(x: ^i32) -> (int, int) { fmt.println("^int"); + return 123, int(x^); } foo :: proc(x: rawptr) { fmt.println("rawptr"); } + THINGI :: 14451; THINGF :: 14451.1; - a: i32; + a: i32 = 111111; b: f32; c: rawptr; - foo(^a); + fmt.println(foo(^a)); foo(^b); foo(c); // foo(nil); @@ -36,12 +38,11 @@ main :: proc() { fmt.printf("int arg, i=%d\n", i); } foo :: proc(f: f64) { - i := f as int; + i := int(f); fmt.printf("f64 arg, f=%d\n", i); } foo(); - foo(THINGI as int); foo(int(THINGI)); // foo(THINGI); foo(THINGF); diff --git a/core/_preload.odin b/core/_preload.odin index bed8c953d..8c852d94a 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -233,7 +233,7 @@ default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, case ALLOC: total_size := size + alignment + size_of(mem.AllocationHeader); ptr := os.heap_alloc(total_size); - header := ptr as ^mem.AllocationHeader; + header := (^mem.AllocationHeader)(ptr); ptr = mem.align_forward(header+1, alignment); mem.allocation_header_fill(header, ptr, size); return mem.zero(ptr, size); @@ -248,7 +248,7 @@ default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, case RESIZE: total_size := size + alignment + size_of(mem.AllocationHeader); ptr := os.heap_resize(mem.allocation_header(old_memory), total_size); - header := ptr as ^mem.AllocationHeader; + header := (^mem.AllocationHeader)(ptr); ptr = mem.align_forward(header+1, alignment); mem.allocation_header_fill(header, ptr, size); return mem.zero(ptr, size); @@ -297,11 +297,11 @@ __string_eq :: proc(a, b: string) -> bool { if a.data == b.data { return true; } - return mem.compare(a.data as rawptr, b.data as rawptr, a.count) == 0; + return mem.compare(rawptr(a.data), rawptr(b.data), a.count) == 0; } __string_cmp :: proc(a, b: string) -> int { - return mem.compare(a.data as rawptr, b.data as rawptr, min(a.count, b.count)); + return mem.compare(rawptr(a.data), rawptr(b.data), min(a.count, b.count)); } __string_ne :: proc(a, b: string) -> bool #inline { return !__string_eq(a, b); } diff --git a/core/fmt.odin b/core/fmt.odin index 46cffb90b..91b83cc3a 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -19,7 +19,7 @@ buffer_write :: proc(buf: ^Buffer, b: []byte) { } } buffer_write_string :: proc(buf: ^Buffer, s: string) { - buffer_write(buf, s as []byte); + buffer_write(buf, []byte(s)); } buffer_write_byte :: proc(buf: ^Buffer, b: byte) { if buf.length < buf.data.count { @@ -29,7 +29,7 @@ buffer_write_byte :: proc(buf: ^Buffer, b: byte) { } buffer_write_rune :: proc(buf: ^Buffer, r: rune) { if r < utf8.RUNE_SELF { - buffer_write_byte(buf, r as byte); + buffer_write_byte(buf, byte(r)); return; } @@ -117,7 +117,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) { default: buffer_write_string(buf, if info.signed { give "i" } else { give "u"}); fi := Fmt_Info{buf = buf}; - fmt_int(^fi, 8*info.size as u64, false, 'd'); + fmt_int(^fi, u64(8*info.size), false, 'd'); } case Float: @@ -142,7 +142,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) { if info.params == nil { buffer_write_string(buf, "()"); } else { - count := (info.params as ^Tuple).fields.count; + count := (^Tuple)(info.params).fields.count; if count == 1 { buffer_write_string(buf, "("); } buffer_write_type(buf, info.params); if count == 1 { buffer_write_string(buf, ")"); } @@ -170,7 +170,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) { case Array: buffer_write_string(buf, "["); fi := Fmt_Info{buf = buf}; - fmt_int(^fi, info.count as u64, false, 'd'); + fmt_int(^fi, u64(info.count), false, 'd'); buffer_write_string(buf, "]"); buffer_write_type(buf, info.elem); case Slice: @@ -180,7 +180,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) { case Vector: buffer_write_string(buf, "[vector "); fi := Fmt_Info{buf = buf}; - fmt_int(^fi, info.count as u64, false, 'd'); + fmt_int(^fi, u64(info.count), false, 'd'); buffer_write_string(buf, "]"); buffer_write_type(buf, info.elem); @@ -307,14 +307,14 @@ parse_int :: proc(s: string, offset: int) -> (int, int, bool) { i := 0; for _ : offset.. (int, int, bool) { arg.type_info = type_info_base(arg.type_info); match type i : arg { case int: num = i; - case i8: num = i as int; - case i16: num = i as int; - case i32: num = i as int; - case i64: num = i as int; - case u8: num = i as int; - case u16: num = i as int; - case u32: num = i as int; - case u64: num = i as int; + 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; } @@ -421,7 +421,7 @@ fmt_write_padding :: proc(fi: ^Fmt_Info, width: int) { } fmt_integer :: proc(fi: ^Fmt_Info, u: u64, base: int, signed: bool, digits: string) { - negative := signed && u as i64 < 0; + negative := signed && i64(u) < 0; if negative { u = -u; } @@ -461,7 +461,7 @@ fmt_integer :: proc(fi: ^Fmt_Info, u: u64, base: int, signed: bool, digits: stri panic("fmt_integer: unknown base, whoops"); } - while b := base as u64; u >= b { + while b := u64(base); u >= b { i -= 1; next := u / b; buf[i] = digits[u%b]; @@ -504,7 +504,7 @@ fmt_integer :: proc(fi: ^Fmt_Info, u: u64, base: int, signed: bool, digits: stri if !fi.width_set || fi.width == 0 { buffer_write(fi.buf, buf[i:]); } else { - width := fi.width - utf8.rune_count(buf[i:] as string); + width := fi.width - utf8.rune_count(string(buf[i:])); if fi.minus { // Right pad buffer_write(fi.buf, buf[i:]); @@ -533,9 +533,9 @@ fmt_int :: proc(fi: ^Fmt_Info, u: u64, signed: bool, verb: rune) { case 'd': fmt_integer(fi, u, 10, signed, __DIGITS_LOWER); case 'x': fmt_integer(fi, u, 16, signed, __DIGITS_LOWER); case 'X': fmt_integer(fi, u, 16, signed, __DIGITS_UPPER); - case 'c': fmt_rune(fi, u as rune); + case 'c': fmt_rune(fi, rune(u)); case 'U': - r := u as rune; + r := rune(u); if r < 0 || r > utf8.MAX_RUNE { fmt_bad_verb(fi, verb); } else { @@ -566,24 +566,24 @@ __TEN_TO_19TH :: 1000000000000000000; __ddmulthi :: proc(ol: f64, xh, yh: f64) -> f64 { bt: i64; oh := xh * yh; - bt = xh transmute i64; - bt &= (~(0 as u64)<<27) as i64; - ahi := bt transmute f64; + bt = transmute(i64, xh); + bt &= i64(~u64(0)<<27); + ahi := transmute(f64, bt); alo := xh-ahi; - bt = yh transmute i64; - bt &= (~(0 as u64)<<27) as i64; - bhi := bt transmute f64; + bt = transmute(i64, yh); + bt &= i64(~u64(0)<<27); + bhi := transmute(f64, bt); blo := yh-bhi; return ((ahi*bhi-oh)+ahi*blo+alo*bhi)+alo*blo; } __ddtoi64 :: proc(xh, xl: f64) -> i64 { - ob := xh as i64; - vh := ob as f64; + ob := i64(xh); + vh := f64(ob); ahi := xh-vh; t := ahi-xh; alo := (xh-(ahi-t)) - (vh+t); - ob += (ahi+alo+xl) as i64; + ob += i64(ahi+alo+xl); return ob; } @@ -670,9 +670,9 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6 e, tens: i32; d: f64 = val; - bits := d transmute i64; - expo := (bits>>52 & 2047) as i32; - neg := (bits>>63) as i32 != 0; + bits := transmute(i64, d); + expo := i32(bits>>52 & 2047); + neg := i32(bits>>63) != 0; if neg { d = -d; } @@ -692,7 +692,7 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6 if bits<<1 == 0 { decimal_pos^ = 1; out[0] = '0'; - start^ = out[:1] as string; + start^ = string(out[:1]); return neg; } // find the right expo for denormals @@ -721,7 +721,7 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6 bits = __ddtoi64(ph, pl); // check if we undershot - if bits as u64 >= __TEN_TO_19TH { + if f64(bits) >= __TEN_TO_19TH { tens += 1; } } @@ -737,10 +737,10 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6 if frac_digits < 24 { skip := false; dg: u32 = 1; - if bits as u64 >= __powten[9] { + if u64(bits) >= __powten[9] { dg = 10; } - while bits as u64 >= __powten[dg] { + while u64(bits) >= __powten[dg] { dg += 1; if dg == 20 { skip = true; @@ -751,14 +751,14 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6 if (!skip) { r: u64; // add 0.5 at the right position and round - e = dg as i32 - frac_digits; - if e as u32 < 24 { + e = i32(dg) - frac_digits; + if u32(e) < 24 { r = __powten[e]; - bits += (r/2) as i64; - if bits as u64 >= __powten[dg] { + bits += i64(r/2); + if u64(bits) >= __powten[dg] { tens += 1; } - bits /= r as i64; + bits /= i64(r); } } } @@ -777,11 +777,11 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6 bits /= 1000; } if !skip { - n := bits as u32; + n := u32(bits); while n%1000 == 0 { n /= 1000; } - bits = n as i64; + bits = i64(n); } } @@ -793,15 +793,15 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6 o := outp-8; // do the conversion in chunks of u32s (avoid most 64-bit divides, worth it, constant denomiators be damned) if bits >= 100000000 { - n = (bits%100000000) as u32; + n = u32(bits%100000000); bits /= 100000000; } else { - n = bits as u32; + n = u32(bits); bits = 0; } while n != 0 { outp -= 2; - (outp as ^u16)^ = (^__digitpair[(n%100)*2] as ^u16)^; + (^u16)(outp)^ = (^u16)(^__digitpair[(n%100)*2])^; n /= 100; e += 2; } @@ -820,7 +820,7 @@ __real_to_string :: proc(start: ^string, out: []byte, decimal_pos: ^i32, val: f6 } decimal_pos^ = tens; - start^ = slice_ptr(outp, e) as string; + start^ = string(slice_ptr(outp, e)); return neg; } @@ -839,18 +839,18 @@ generic_ftoa :: proc(buf: []byte, val: f64, verb: rune, prec, bit_size: int) -> flt: ^Float_Info; match bit_size { case 32: - bits = ((val as f32) transmute u32) as u64; + bits = u64(transmute(u32, f32(val))); flt = ^f32info; case 64: - bits = val transmute u64; + bits = u64(val); flt = ^f64info; default: panic("illegal float bit_size"); } neg := bits>>(flt.expbits+flt.mantbits) != 0; - exp := (bits>>flt.mantbits) as int & (1<>flt.mantbits) & (1< case neg: s = "-Inf"; default: s = "+Inf"; } - copy(buf, s as []byte); + copy(buf, []byte(s)); return buf[:s.count]; case 0: // denormalized exp+=1; default: // add implicit top bit - mant |= (1 as u64)< 0 { buffer_write_string(fi.buf, ", "); } data := slice.data + i*info.elem_size; - fmt_arg(fi, any{info.elem, data as rawptr}, 'v'); + fmt_arg(fi, any{info.elem, rawptr(data)}, 'v'); } case Vector: @@ -1106,8 +1106,8 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { buffer_write_string(fi.buf, ", "); } - data := v.data as ^byte + i*info.elem_size; - fmt_value(fi, any{info.elem, data as rawptr}, 'v'); + data := (^byte)(v.data) + i*info.elem_size; + fmt_value(fi, any{info.elem, rawptr(data)}, 'v'); } case Struct: @@ -1120,9 +1120,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { } buffer_write_string(fi.buf, f.name); buffer_write_string(fi.buf, " = "); - data := v.data as ^byte + f.offset; + data := (^byte)(v.data) + f.offset; ti := f.type_info; - fmt_value(fi, any{ti, data as rawptr}, 'v'); + fmt_value(fi, any{ti, rawptr(data)}, 'v'); } case Union: @@ -1136,7 +1136,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { case Procedure: buffer_write_type(fi.buf, v.type_info); buffer_write_string(fi.buf, " @ "); - fmt_pointer(fi, (v.data as ^rawptr)^, 'p'); + fmt_pointer(fi, (^rawptr)(v.data)^, 'p'); } } @@ -1161,19 +1161,19 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) { base_arg.type_info = type_info_base(base_arg.type_info); match type a : base_arg { case bool: fmt_bool(fi, a, verb); - case f32: fmt_float(fi, a as f64, 32, verb); + case f32: fmt_float(fi, f64(a), 32, verb); case f64: fmt_float(fi, a, 64, verb); - case int: fmt_int(fi, a as u64, true, verb); - case i8: fmt_int(fi, a as u64, true, verb); - case i16: fmt_int(fi, a as u64, true, verb); - case i32: fmt_int(fi, a as u64, true, verb); - case i64: fmt_int(fi, a as u64, true, verb); - case uint: fmt_int(fi, a as u64, false, verb); - case u8: fmt_int(fi, a as u64, false, verb); - case u16: fmt_int(fi, a as u64, false, verb); - case u32: fmt_int(fi, a as u64, false, verb); - case u64: fmt_int(fi, a as u64, false, verb); + case int: fmt_int(fi, u64(a), true, verb); + case i8: fmt_int(fi, u64(a), true, verb); + case i16: fmt_int(fi, u64(a), true, verb); + case i32: fmt_int(fi, u64(a), true, verb); + case i64: fmt_int(fi, u64(a), true, verb); + case uint: fmt_int(fi, u64(a), false, verb); + case u8: fmt_int(fi, u64(a), false, verb); + case u16: fmt_int(fi, u64(a), false, verb); + case u32: fmt_int(fi, u64(a), false, verb); + case u64: fmt_int(fi, u64(a), false, verb); case string: fmt_string(fi, a, verb); default: fmt_value(fi, arg, verb); } diff --git a/core/hash.odin b/core/hash.odin index 6d5690d44..e9ca2c5f3 100644 --- a/core/hash.odin +++ b/core/hash.odin @@ -1,58 +1,58 @@ crc32 :: proc(data: rawptr, len: int) -> u32 { - result := ~(0 as u32); - s := slice_ptr(data as ^u8, len); + result := ~u32(0); + s := slice_ptr((^u8)(data), len); for i : 0..>8 ~ __CRC32_TABLE[(result ~ b) & 0xff]; } return ~result; } crc64 :: proc(data: rawptr, len: int) -> u64 { - result := ~(0 as u64); - s := slice_ptr(data as ^u8, len); + result := ~u64(0); + s := slice_ptr((^u8)(data), len); for i : 0..>8 ~ __CRC64_TABLE[(result ~ b) & 0xff]; } return ~result; } fnv32 :: proc(data: rawptr, len: int) -> u32 { - s := slice_ptr(data as ^u8, len); + s := slice_ptr((^u8)(data), len); h: u32 = 0x811c9dc5; for i : 0.. u64 { - s := slice_ptr(data as ^u8, len); + s := slice_ptr((^u8)(data), len); h: u64 = 0xcbf29ce484222325; for i : 0.. u32 { - s := slice_ptr(data as ^u8, len); + s := slice_ptr((^u8)(data), len); h: u32 = 0x811c9dc5; for i : 0.. u64 { - s := slice_ptr(data as ^u8, len); + s := slice_ptr((^u8)(data), len); h :u64 = 0xcbf29ce484222325; for i : 0.. u64 { m :: 0xc6a4a7935bd1e995; r :: 47; - h: u64 = SEED ~ (len as u64 * m); + h: u64 = SEED ~ (u64(len) * m); - data := slice_ptr(data_ as ^u64, len/size_of(u64)); - data2 := slice_ptr(data_ as ^u8, len); + data := slice_ptr((^u64)(data_), len/size_of(u64)); + data2 := slice_ptr((^u8)(data_), len); for i : 0 ..< data.count { k := data[i]; @@ -82,14 +82,14 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 { } match len & 7 { - case 7: h ~= data2[6] as u64 << 48; fallthrough; - case 6: h ~= data2[5] as u64 << 40; fallthrough; - case 5: h ~= data2[4] as u64 << 32; fallthrough; - case 4: h ~= data2[3] as u64 << 24; fallthrough; - case 3: h ~= data2[2] as u64 << 16; fallthrough; - case 2: h ~= data2[1] as u64 << 8; fallthrough; + case 7: h ~= u64(data2[6]) << 48; fallthrough; + case 6: h ~= u64(data2[5]) << 40; fallthrough; + case 5: h ~= u64(data2[4]) << 32; fallthrough; + case 4: h ~= u64(data2[3]) << 24; fallthrough; + case 3: h ~= u64(data2[2]) << 16; fallthrough; + case 2: h ~= u64(data2[1]) << 8; fallthrough; case 1: - h ~= data2[0] as u64; + h ~= u64(data2[0]); h *= m; } @@ -102,10 +102,10 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 { m :: 0x5bd1e995; r :: 24; - h1: u32 = SEED as u32 ~ len as u32; + h1: u32 = u32(SEED) ~ u32(len); h2: u32 = SEED >> 32; - data := slice_ptr(data_ as ^u32, len/size_of(u32)); + data := slice_ptr((^u32)(data_), len/size_of(u32)); i := 0; while len >= 8 { @@ -138,13 +138,13 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 { len -= 4; } - data8 := slice_ptr((data.data+i) as ^u8, 3); // NOTE(bill): This is unsafe + data8 := slice_ptr((^u8)(data.data+i), 3); // NOTE(bill): This is unsafe match len { - case 3: h2 ~= data8[2] as u32 << 16; fallthrough; - case 2: h2 ~= data8[1] as u32 << 8; fallthrough; + case 3: h2 ~= u32(data8[2]) << 16; fallthrough; + case 2: h2 ~= u32(data8[1]) << 8; fallthrough; case 1: - h2 ~= data8[0] as u32; + h2 ~= u32(data8[0]); h2 *= m; } @@ -157,7 +157,7 @@ murmur64 :: proc(data_: rawptr, len: int) -> u64 { h2 ~= h1>>19; h2 *= m; - h := (h1 as u64)<<32 | h2 as u64; + h := u64(h1)<<32 | u64(h2); return h; } } diff --git a/core/math.odin b/core/math.odin index 00bef37f7..479fe920b 100644 --- a/core/math.odin +++ b/core/math.odin @@ -45,11 +45,11 @@ sign :: proc(x: f64) -> f64 { if x >= 0 { return +1; } return -1; } copy_sign :: proc(x, y: f32) -> f32 { - ix := x transmute u32; - iy := y transmute u32; + ix := transmute(u32, x); + iy := transmute(u32, y); ix &= 0x7fffffff; ix |= iy & 0x80000000; - return ix transmute f32; + return transmute(f32, ix); } round :: proc(x: f32) -> f32 { if x >= 0 { @@ -59,15 +59,15 @@ round :: proc(x: f32) -> f32 { } floor :: proc(x: f32) -> f32 { if x >= 0 { - return x as int as f32; + return f32(int(x)); } - return (x-0.5) as int as f32; + return f32(int(x-0.5)); } ceil :: proc(x: f32) -> f32 { if x < 0 { - return x as int as f32; + return f32(int(x)); } - return ((x as int)+1) as f32; + return f32(int(x)+1); } remainder32 :: proc(x, y: f32) -> f32 { diff --git a/core/mem.odin b/core/mem.odin index a8a38bc90..3aee897e8 100644 --- a/core/mem.odin +++ b/core/mem.odin @@ -3,7 +3,7 @@ set :: proc(data: rawptr, value: i32, len: int) -> rawptr #link_name "__mem_set" { llvm_memset_64bit :: proc(dst: rawptr, val: byte, len: int, align: i32, is_volatile: bool) #foreign "llvm.memset.p0i8.i64" - llvm_memset_64bit(data, value as byte, len, 1, false); + llvm_memset_64bit(data, byte(value), len, 1, false); return data; } @@ -26,8 +26,8 @@ copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #link_name "_ } compare :: proc(dst, src: rawptr, n: int) -> int #link_name "__mem_compare" { - a := slice_ptr(dst as ^byte, n); - b := slice_ptr(src as ^byte, n); + a := slice_ptr((^byte)(dst), n); + b := slice_ptr((^byte)(src), n); for i : 0.. bool { align_forward :: proc(ptr: rawptr, align: int) -> rawptr { assert(is_power_of_two(align)); - a := align as uint; - p := ptr as uint; + a := uint(align); + p := uint(ptr); modulo := p & (a-1); if modulo != 0 { p += a - modulo; } - return p as rawptr; + return rawptr(p); } @@ -73,19 +73,19 @@ Allocation_Header :: struct { allocation_header_fill :: proc(header: ^Allocation_Header, data: rawptr, size: int) { header.size = size; - ptr := (header+1) as ^int; + ptr := (^int)(header+1); - while i := 0; ptr as rawptr < data { + while i := 0; rawptr(ptr) < data { (ptr+i)^ = -1; i += 1; } } allocation_header :: proc(data: rawptr) -> ^Allocation_Header { - p := data as ^int; + p := (^int)(data); while (p-1)^ == -1 { p = (p-1); } - return (p as ^Allocation_Header)-1; + return (^Allocation_Header)(p)-1; } @@ -142,7 +142,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 := allocator_data as ^Arena; + arena := (^Arena)(allocator_data); match mode { case ALLOC: @@ -235,7 +235,7 @@ align_of_type_info :: proc(type_info: ^Type_Info) -> int { return WORD_SIZE; case Vector: size := size_of_type_info(info.elem); - count := max(prev_pow2(info.count as i64), 1) as int; + count := int(max(prev_pow2(i64(info.count)), 1)); total := size * count; return clamp(total, 1, MAX_ALIGN); case Struct: diff --git a/core/opengl.odin b/core/opengl.odin index f7bf2ac00..499a28333 100644 --- a/core/opengl.odin +++ b/core/opengl.odin @@ -30,7 +30,7 @@ GetIntegerv :: proc(name: i32, v: ^i32) #foreign "glGetIntegerv" -_libgl := win32.LoadLibraryA(("opengl32.dll\x00" as string).data); +_libgl := win32.LoadLibraryA(string("opengl32.dll\x00").data); GetProcAddress :: proc(name: string) -> proc() #cc_c { assert(name[name.count-1] == 0); @@ -100,7 +100,7 @@ UniformMatrix4fv: proc(loc: i32, count: u32, transpose: i32, value: ^f32) #cc_c GetUniformLocation: proc(program: u32, name: ^byte) -> i32 #cc_c; init :: proc() { - set_proc_address :: proc(p: rawptr, name: string) #inline { (p as ^(proc() #cc_c))^ = GetProcAddress(name); } + set_proc_address :: proc(p: rawptr, name: string) #inline { (^(proc() #cc_c))(p)^ = GetProcAddress(name); } set_proc_address(^GenBuffers, "glGenBuffers\x00"); set_proc_address(^GenVertexArrays, "glGenVertexArrays\x00"); diff --git a/core/os_windows.odin b/core/os_windows.odin index 8836504ce..fa77e63cf 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -73,7 +73,7 @@ open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) { access |= FILE_APPEND_DATA; } - share_mode := (FILE_SHARE_READ|FILE_SHARE_WRITE) as u32; + share_mode := u32(FILE_SHARE_READ|FILE_SHARE_WRITE); sa: ^SECURITY_ATTRIBUTES = nil; sa_inherit := SECURITY_ATTRIBUTES{length = size_of(SECURITY_ATTRIBUTES), inherit_handle = 1}; if mode&O_CLOEXEC == 0 { @@ -95,38 +95,38 @@ open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) { } buf: [300]byte; - copy(buf[:], path as []byte); + copy(buf[:], []byte(path)); - handle := CreateFileA(^buf[0], access, share_mode, sa, create_mode, FILE_ATTRIBUTE_NORMAL, nil) as Handle; + handle := Handle(CreateFileA(^buf[0], access, share_mode, sa, create_mode, FILE_ATTRIBUTE_NORMAL, nil)); if handle != INVALID_HANDLE { return handle, ERROR_NONE; } err := GetLastError(); - return INVALID_HANDLE, err as Errno; + return INVALID_HANDLE, Errno(err); } close :: proc(fd: Handle) { - win32.CloseHandle(fd as win32.HANDLE); + win32.CloseHandle(win32.HANDLE(fd)); } write :: proc(fd: Handle, data: []byte) -> (int, Errno) { bytes_written: i32; - e := win32.WriteFile(fd as win32.HANDLE, data.data, data.count as i32, ^bytes_written, nil); + e := win32.WriteFile(win32.HANDLE(fd), data.data, i32(data.count), ^bytes_written, nil); if e == win32.FALSE { err := win32.GetLastError(); - return 0, err as Errno; + return 0, Errno(err); } - return bytes_written as int, ERROR_NONE; + return int(bytes_written), ERROR_NONE; } read :: proc(fd: Handle, data: []byte) -> (int, Errno) { bytes_read: i32; - e := win32.ReadFile(fd as win32.HANDLE, data.data, data.count as u32, ^bytes_read, nil); + e := win32.ReadFile(win32.HANDLE(fd), data.data, u32(data.count), ^bytes_read, nil); if e == win32.FALSE { err := win32.GetLastError(); - return 0, err as Errno; + return 0, Errno(err); } - return bytes_read as int, ERROR_NONE; + return int(bytes_read), ERROR_NONE; } seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { @@ -137,18 +137,18 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { case 1: w = FILE_CURRENT; case 2: w = FILE_END; } - hi := (offset>>32) as i32; - lo := offset as i32; - ft := GetFileType(fd as HANDLE); + hi := i32(offset>>32); + lo := i32(offset); + ft := GetFileType(HANDLE(fd)); if ft == FILE_TYPE_PIPE { return 0, ERROR_FILE_IS_PIPE; } - dw_ptr := SetFilePointer(fd as HANDLE, lo, ^hi, w); + dw_ptr := SetFilePointer(HANDLE(fd), lo, ^hi, w); if dw_ptr == INVALID_SET_FILE_POINTER { err := GetLastError(); - return 0, err as Errno; + return 0, Errno(err); } - return (hi as i64)<<32 + (dw_ptr as i64), ERROR_NONE; + return i64(hi)<<32 + i64(dw_ptr), ERROR_NONE; } @@ -159,9 +159,9 @@ stderr := get_std_handle(win32.STD_ERROR_HANDLE); get_std_handle :: proc(h: int) -> Handle { - fd := win32.GetStdHandle(h as i32); + fd := win32.GetStdHandle(i32(h)); win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0); - return fd as Handle; + return Handle(fd); } @@ -171,9 +171,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(fd as win32.HANDLE, ^file_info); - lo := file_info.last_write_time.lo as File_Time; - hi := file_info.last_write_time.hi as File_Time; + 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; } @@ -184,14 +184,14 @@ last_write_time_by_name :: proc(name: string) -> File_Time { assert(buf.count > name.count); - copy(buf[:], name as []byte); + copy(buf[:], []byte(name)); if win32.GetFileAttributesExA(^buf[0], win32.GetFileExInfoStandard, ^data) != 0 { last_write_time = data.last_write_time; } - l := last_write_time.lo as File_Time; - h := last_write_time.hi as File_Time; + l := File_Time(last_write_time.lo); + h := File_Time(last_write_time.hi); return l | h << 32; } @@ -201,7 +201,7 @@ last_write_time_by_name :: proc(name: string) -> File_Time { read_entire_file :: proc(name: string) -> ([]byte, bool) { buf: [300]byte; - copy(buf[:], name as []byte); + copy(buf[:], []byte(name)); fd, err := open(name, O_RDONLY, 0); if err != ERROR_NONE { @@ -210,7 +210,7 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) { defer close(fd); length: i64; - file_size_ok := win32.GetFileSizeEx(fd as win32.HANDLE, ^length) != 0; + file_size_ok := win32.GetFileSizeEx(win32.HANDLE(fd), ^length) != 0; if !file_size_ok { return nil, false; } @@ -228,18 +228,18 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) { to_read: u32; MAX :: 1<<32-1; if remaining <= MAX { - to_read = remaining as u32; + to_read = u32(remaining); } else { to_read = MAX; } - win32.ReadFile(fd as win32.HANDLE, ^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.data); return nil, false; } - total_read += single_read_length as i64; + total_read += i64(single_read_length); } return data, true; @@ -259,14 +259,14 @@ heap_free :: proc(ptr: rawptr) { exit :: proc(code: int) { - win32.ExitProcess(code as u32); + win32.ExitProcess(u32(code)); } current_thread_id :: proc() -> int { GetCurrentThreadId :: proc() -> u32 #foreign #dll_import - return GetCurrentThreadId() as int; + return int(GetCurrentThreadId()); } diff --git a/core/sync.odin b/core/sync.odin index ec223446e..dbab820b4 100644 --- a/core/sync.odin +++ b/core/sync.odin @@ -13,7 +13,7 @@ Mutex :: struct { } current_thread_id :: proc() -> i32 { - return win32.GetCurrentThreadId() as i32; + return i32(win32.GetCurrentThreadId()); } semaphore_init :: proc(s: ^Semaphore) { @@ -25,7 +25,7 @@ semaphore_destroy :: proc(s: ^Semaphore) { } semaphore_post :: proc(s: ^Semaphore, count: int) { - win32.ReleaseSemaphore(s.handle, count as i32, nil); + win32.ReleaseSemaphore(s.handle, i32(count), nil); } semaphore_release :: proc(s: ^Semaphore) #inline { semaphore_post(s, 1); } diff --git a/core/sys/windows.odin b/core/sys/windows.odin index df9f5aea7..e9c265231 100644 --- a/core/sys/windows.odin +++ b/core/sys/windows.odin @@ -19,7 +19,7 @@ BOOL :: i32; WNDPROC :: type proc(HWND, u32, WPARAM, LPARAM) -> LRESULT #cc_c; -INVALID_HANDLE_VALUE :: ~int(0) as HANDLE; +INVALID_HANDLE_VALUE :: HANDLE(~int(0)); FALSE: BOOL : 0; TRUE: BOOL : 1; @@ -233,7 +233,7 @@ FILE_TYPE_DISK :: 0x0001; FILE_TYPE_CHAR :: 0x0002; FILE_TYPE_PIPE :: 0x0003; -INVALID_SET_FILE_POINTER :: ~(0 as u32); +INVALID_SET_FILE_POINTER :: ~u32(0); @@ -402,7 +402,7 @@ wglDeleteContext :: proc(hglrc: HGLRC) -> BOOL #foreign #dll_import GetKeyState :: proc(v_key: i32) -> i16 #foreign #dll_import GetAsyncKeyState :: proc(v_key: i32) -> i16 #foreign #dll_import -is_key_down :: proc(key: Key_Code) -> bool #inline { return GetAsyncKeyState(key as i32) < 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/utf8.odin b/core/utf8.odin index 9bcc237a2..1cd9f0d8c 100644 --- a/core/utf8.odin +++ b/core/utf8.odin @@ -1,7 +1,7 @@ RUNE_ERROR :: '\ufffd'; RUNE_SELF :: 0x80; RUNE_BOM :: 0xfeff; -RUNE_EOF :: ~(0 as rune); +RUNE_EOF :: ~rune(0); MAX_RUNE :: '\U0010ffff'; UTF_MAX :: 4; @@ -40,15 +40,15 @@ accept_sizes := [256]byte{ encode_rune :: proc(r: rune) -> ([4]byte, int) { buf: [4]byte; - i := r as u32; + i := u32(r); mask: byte : 0x3f; if i <= 1<<7-1 { - buf[0] = r as byte; + buf[0] = byte(r); return buf, 1; } if i <= 1<<11-1 { - buf[0] = 0xc0 | (r>>6) as byte; - buf[1] = 0x80 | (r) as byte & mask; + buf[0] = 0xc0 | byte(r>>6); + buf[1] = 0x80 | byte(r) & mask; return buf, 2; } @@ -59,16 +59,16 @@ encode_rune :: proc(r: rune) -> ([4]byte, int) { } if i <= 1<<16-1 { - buf[0] = 0xe0 | (r>>12) as byte; - buf[1] = 0x80 | (r>>6) as byte & mask; - buf[2] = 0x80 | (r) as byte & 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 | (r>>18) as byte; - buf[1] = 0x80 | (r>>12) as byte & mask; - buf[2] = 0x80 | (r>>6) as byte & mask; - buf[3] = 0x80 | (r) as byte & 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; } @@ -80,12 +80,12 @@ decode_rune :: proc(s: string) -> (rune, int) { b0 := s[0]; x := accept_sizes[b0]; if x >= 0xf0 { - mask := (x as rune << 31) >> 31; // all zeros or all ones - return (b0 as rune) &~ mask | RUNE_ERROR&mask, 1; + mask := (rune(x) << 31) >> 31; // all zeros or all ones + return rune(b0) &~ mask | RUNE_ERROR&mask, 1; } size := x & 7; ar := accept_ranges[x>>4]; - if n < size as int { + if n < int(size) { return RUNE_ERROR, 1; } b1 := s[1]; @@ -99,20 +99,20 @@ decode_rune :: proc(s: string) -> (rune, int) { MASK_4 :: 0b00000111; if size == 2 { - return (b0&MASK_2) as rune <<6 | (b1&MASK_X) as rune, 2; + return rune(b0&MASK_2)<<6 | rune(b1&MASK_X), 2; } b2 := s[2]; if b2 < 0x80 || 0xbf < b2 { return RUNE_ERROR, 1; } if size == 3 { - return (b0&MASK_3) as rune <<12 | (b1&MASK_X) as rune <<6 | (b2&MASK_X) as rune, 3; + return rune(b0&MASK_3)<<12 | rune(b1&MASK_X)<<6 | rune(b2&MASK_X), 3; } b3 := s[3]; if b3 < 0x80 || 0xbf < b3 { return RUNE_ERROR, 1; } - return (b0&MASK_4) as rune <<18 | (b1&MASK_X) as rune <<12 | (b3&MASK_X) as rune <<6 | (b3&MASK_X) as rune, 4; + return rune(b0&MASK_4)<<18 | rune(b1&MASK_X)<<12 | rune(b3&MASK_X)<<6 | rune(b3&MASK_X), 4; } @@ -141,7 +141,7 @@ valid_string :: proc(s: string) -> bool { if x == 0xf1 { return false; } - size := (x & 7) as int; + size := int(x & 7); if i+size > n { return false; } @@ -178,7 +178,7 @@ rune_count :: proc(s: string) -> int { i += 1; continue; } - size := (x & 7) as int; + size := int(x & 7); if i+size > n { i += 1; continue; diff --git a/src/check_expr.c b/src/check_expr.c index 0096c7566..9ba5f4db2 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -1911,6 +1911,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) { ast_node(be, BinaryExpr, node); +#if 0 switch (be->op.kind) { case Token_as: { check_expr(c, x, be->left); @@ -2103,7 +2104,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) { return; } break; } - +#endif check_expr(c, x, be->left); check_expr(c, y, be->right); if (x->mode == Addressing_Invalid) { @@ -2728,6 +2729,10 @@ 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: + case BuiltinProc_union_cast: + case BuiltinProc_down_cast: // NOTE(bill): The first arg may be a Type, this will be checked case by case break; default: @@ -2925,6 +2930,10 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin) { return false; } + if (operand->type == NULL || operand->type == t_invalid) { + error_node(operand->expr, "Invalid argument to `type_of_val`"); + return false; + } operand->mode = Addressing_Type; break; @@ -2969,6 +2978,184 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id } break; + case BuiltinProc_transmute: { + Type *type = check_type(c, ce->args.e[0]); + check_expr(c, operand, ce->args.e[1]); + if (operand->mode == Addressing_Invalid) { + return false; + } + + if (operand->mode == Addressing_Constant) { + gbString expr_str = expr_to_string(operand->expr); + error_node(operand->expr, "Cannot transmute constant expression: `%s`", expr_str); + gb_string_free(expr_str); + operand->mode = Addressing_Invalid; + return false; + } + + if (is_type_untyped(operand->type)) { + gbString expr_str = expr_to_string(operand->expr); + error_node(operand->expr, "Cannot transmute untyped expression: `%s`", expr_str); + gb_string_free(expr_str); + operand->mode = Addressing_Invalid; + return false; + } + + i64 srcz = type_size_of(c->sizes, c->allocator, operand->type); + i64 dstz = type_size_of(c->sizes, c->allocator, type); + if (srcz != dstz) { + gbString expr_str = expr_to_string(operand->expr); + gbString type_str = type_to_string(type); + error_node(operand->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); + operand->mode = Addressing_Invalid; + return false; + } + + operand->type = type; + } break; + case BuiltinProc_union_cast: { + Type *type = check_type(c, ce->args.e[0]); + check_expr(c, operand, ce->args.e[1]); + if (operand->mode == Addressing_Invalid) { + return false; + } + + if (operand->mode == Addressing_Constant) { + gbString expr_str = expr_to_string(operand->expr); + error_node(operand->expr, "Cannot `union_cast` a constant expression: `%s`", expr_str); + gb_string_free(expr_str); + operand->mode = Addressing_Invalid; + return false; + } + + if (is_type_untyped(operand->type)) { + gbString expr_str = expr_to_string(operand->expr); + error_node(operand->expr, "Cannot `union_cast` an untyped expression: `%s`", expr_str); + gb_string_free(expr_str); + operand->mode = Addressing_Invalid; + return false; + } + + bool src_is_ptr = is_type_pointer(operand->type); + bool dst_is_ptr = is_type_pointer(type); + Type *src = type_deref(operand->type); + Type *dst = type_deref(type); + Type *bsrc = base_type(src); + Type *bdst = base_type(dst); + + if (src_is_ptr != dst_is_ptr) { + gbString src_type_str = type_to_string(operand->type); + gbString dst_type_str = type_to_string(type); + error_node(operand->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); + operand->mode = Addressing_Invalid; + return false; + } + + if (!is_type_union(src)) { + error_node(operand->expr, "`union_cast` can only operate on unions"); + operand->mode = Addressing_Invalid; + return false; + } + + bool ok = false; + for (isize i = 1; i < bsrc->Record.field_count; i++) { + Entity *f = bsrc->Record.fields[i]; + if (are_types_identical(f->type, dst)) { + ok = true; + break; + } + } + + if (!ok) { + gbString expr_str = expr_to_string(operand->expr); + gbString dst_type_str = type_to_string(type); + error_node(operand->expr, "Cannot `union_cast` `%s` to `%s`", expr_str, dst_type_str); + gb_string_free(dst_type_str); + gb_string_free(expr_str); + operand->mode = Addressing_Invalid; + return false; + } + + Entity **variables = gb_alloc_array(c->allocator, Entity *, 2); + variables[0] = make_entity_param(c->allocator, NULL, empty_token, type, false); + variables[1] = make_entity_param(c->allocator, NULL, empty_token, t_bool, false); + + Type *tuple = make_type_tuple(c->allocator); + tuple->Tuple.variables = variables; + tuple->Tuple.variable_count = 2; + + operand->type = tuple; + operand->mode = Addressing_Value; + } break; + case BuiltinProc_down_cast: { + Type *type = check_type(c, ce->args.e[0]); + check_expr(c, operand, ce->args.e[1]); + if (operand->mode == Addressing_Invalid) { + return false; + } + + if (operand->mode == Addressing_Constant) { + gbString expr_str = expr_to_string(operand->expr); + error_node(operand->expr, "Cannot `down_cast` a constant expression: `%s`", expr_str); + gb_string_free(expr_str); + operand->mode = Addressing_Invalid; + return false; + } + + if (is_type_untyped(operand->type)) { + gbString expr_str = expr_to_string(operand->expr); + error_node(operand->expr, "Cannot `down_cast` an untyped expression: `%s`", expr_str); + gb_string_free(expr_str); + operand->mode = Addressing_Invalid; + return false; + } + + if (!(is_type_pointer(operand->type) && is_type_pointer(type))) { + gbString expr_str = expr_to_string(operand->expr); + error_node(operand->expr, "Can only `down_cast` pointers: `%s`", expr_str); + gb_string_free(expr_str); + operand->mode = Addressing_Invalid; + return false; + } + + Type *src = type_deref(operand->type); + Type *dst = type_deref(type); + Type *bsrc = base_type(src); + Type *bdst = base_type(dst); + + if (!(is_type_struct(bsrc) || is_type_raw_union(bsrc))) { + gbString expr_str = expr_to_string(operand->expr); + error_node(operand->expr, "Can only `down_cast` pointer from structs or unions: `%s`", expr_str); + gb_string_free(expr_str); + operand->mode = Addressing_Invalid; + return false; + } + + if (!(is_type_struct(bdst) || is_type_raw_union(bdst))) { + gbString expr_str = expr_to_string(operand->expr); + error_node(operand->expr, "Can only `down_cast` pointer to structs or unions: `%s`", expr_str); + gb_string_free(expr_str); + operand->mode = Addressing_Invalid; + return false; + } + + String param_name = check_down_cast_name(dst, src); + if (param_name.len == 0) { + gbString expr_str = expr_to_string(operand->expr); + error_node(operand->expr, "Illegal `down_cast`: `%s`", expr_str); + gb_string_free(expr_str); + operand->mode = Addressing_Invalid; + return false; + } + + operand->mode = Addressing_Value; + operand->type = type; + } break; + case BuiltinProc_compile_assert: // compile_assert :: proc(cond: bool) @@ -3054,45 +3241,6 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id operand->mode = Addressing_Value; } break; - #if 0 - case BuiltinProc_append: { - // append :: proc(x : ^[]Type, y : Type) -> bool - Type *x_type = NULL, *y_type = NULL; - x_type = base_type(operand->type); - - Operand op = {0}; - check_expr(c, &op, ce->args.e[1]); - if (op.mode == Addressing_Invalid) { - return false; - } - y_type = base_type(op.type); - - if (!(is_type_pointer(x_type) && is_type_slice(x_type->Pointer.elem))) { - error_node(call, "First argument to `append` must be a pointer to a slice"); - return false; - } - - Type *elem_type = x_type->Pointer.elem->Slice.elem; - if (!check_is_assignable_to(c, &op, elem_type)) { - gbString d_arg = expr_to_string(ce->args.e[0]); - gbString s_arg = expr_to_string(ce->args.e[1]); - gbString d_str = type_to_string(elem_type); - gbString s_str = type_to_string(y_type); - error_node(call, - "Arguments to `append`, %s, %s, have different element types: %s vs %s", - d_arg, s_arg, d_str, s_str); - gb_string_free(s_str); - gb_string_free(d_str); - gb_string_free(s_arg); - gb_string_free(d_arg); - return false; - } - - operand->type = t_bool; // Returns if it was successful - operand->mode = Addressing_Value; - } break; - #endif - case BuiltinProc_swizzle: { // swizzle :: proc(v: {N}T, T...) -> {M}T Type *vector_type = base_type(operand->type); @@ -4557,7 +4705,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint case_ast_node(ue, UnaryExpr, node); - check_expr(c, o, ue->expr); + check_expr_base(c, o, ue->expr, type_hint); if (o->mode == Addressing_Invalid) { goto error; } diff --git a/src/checker.c b/src/checker.c index a3a6b63f4..a294787d7 100644 --- a/src/checker.c +++ b/src/checker.c @@ -135,6 +135,10 @@ typedef enum BuiltinProcId { BuiltinProc_type_info, BuiltinProc_type_info_of_val, + BuiltinProc_transmute, + BuiltinProc_union_cast, + BuiltinProc_down_cast, + BuiltinProc_compile_assert, BuiltinProc_assert, BuiltinProc_panic, @@ -178,6 +182,10 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = { {STR_LIT("type_info"), 1, false, Expr_Expr}, {STR_LIT("type_info_of_val"), 1, false, Expr_Expr}, + {STR_LIT("transmute"), 2, false, Expr_Expr}, + {STR_LIT("union_cast"), 2, false, Expr_Expr}, + {STR_LIT("down_cast"), 2, false, Expr_Expr}, + {STR_LIT("compile_assert"), 1, false, Expr_Stmt}, {STR_LIT("assert"), 1, false, Expr_Stmt}, {STR_LIT("panic"), 1, false, Expr_Stmt}, diff --git a/src/ir.c b/src/ir.c index 4ad0db922..eb4506ce7 100644 --- a/src/ir.c +++ b/src/ir.c @@ -2772,21 +2772,21 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv case Token_CmpOr: return ir_emit_logical_binary_expr(proc, expr); - case Token_as: - ir_emit_comment(proc, str_lit("cast - as")); - return ir_emit_conv(proc, left, type); + // case Token_as: + // ir_emit_comment(proc, str_lit("cast - as")); + // return ir_emit_conv(proc, left, type); - case Token_transmute: - ir_emit_comment(proc, str_lit("cast - transmute")); - return ir_emit_transmute(proc, left, type); + // case Token_transmute: + // ir_emit_comment(proc, str_lit("cast - transmute")); + // return ir_emit_transmute(proc, left, type); - case Token_down_cast: - ir_emit_comment(proc, str_lit("cast - down_cast")); - return ir_emit_down_cast(proc, left, type); + // case Token_down_cast: + // ir_emit_comment(proc, str_lit("cast - down_cast")); + // return ir_emit_down_cast(proc, left, type); - case Token_union_cast: - ir_emit_comment(proc, str_lit("cast - union_cast")); - return ir_emit_union_cast(proc, left, type); + // case Token_union_cast: + // ir_emit_comment(proc, str_lit("cast - union_cast")); + // return ir_emit_union_cast(proc, left, type); default: GB_PANIC("Invalid binary expression"); @@ -2844,6 +2844,24 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv return ir_type_info(proc, t); } break; + case BuiltinProc_transmute: { + irValue *val = ir_build_expr(proc, ce->args.e[1]); + ir_emit_comment(proc, str_lit("cast - transmute")); + return ir_emit_transmute(proc, val, type_of_expr(proc->module->info, ce->args.e[0])); + } + + case BuiltinProc_down_cast: { + irValue *val = ir_build_expr(proc, ce->args.e[1]); + ir_emit_comment(proc, str_lit("cast - down_cast")); + return ir_emit_down_cast(proc, val, type_of_expr(proc->module->info, ce->args.e[0])); + } + + case BuiltinProc_union_cast: { + irValue *val = ir_build_expr(proc, ce->args.e[1]); + ir_emit_comment(proc, str_lit("cast - union_cast")); + return ir_emit_union_cast(proc, val, type_of_expr(proc->module->info, ce->args.e[0])); + } + case BuiltinProc_new: { ir_emit_comment(proc, str_lit("new")); // new :: proc(Type) -> ^Type @@ -3399,22 +3417,22 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { case_ast_node(be, BinaryExpr, expr); switch (be->op.kind) { - case Token_as: { - ir_emit_comment(proc, str_lit("Cast - as")); - // 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_conv(proc, ir_build_expr(proc, be->left), type)); - return ir_make_addr(v, expr); - } - 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, be->left), type)); - return ir_make_addr(v, expr); - } + // case Token_as: { + // ir_emit_comment(proc, str_lit("Cast - as")); + // // 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_conv(proc, ir_build_expr(proc, be->left), type)); + // return ir_make_addr(v, expr); + // } + // 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, be->left), type)); + // return ir_make_addr(v, expr); + // } default: GB_PANIC("Invalid binary expression for ir_build_addr: %.*s\n", LIT(be->op.string)); break; diff --git a/src/parser.c b/src/parser.c index f42e3c94c..53173eb4b 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1979,11 +1979,11 @@ i32 token_precedence(Token t) { case Token_Shl: case Token_Shr: return 5; - case Token_as: - case Token_transmute: - case Token_down_cast: - case Token_union_cast: - return 6; + // case Token_as: + // case Token_transmute: + // case Token_down_cast: + // case Token_union_cast: + // return 6; } return 0; } @@ -2005,12 +2005,12 @@ AstNode *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) { } switch (op.kind) { - case Token_as: + /* case Token_as: case Token_transmute: case Token_down_cast: case Token_union_cast: right = parse_type(f); - break; + break; */ default: right = parse_binary_expr(f, false, prec+1); @@ -2429,10 +2429,10 @@ AstNode *parse_identifier_or_type(AstFile *f) { AstNode *sel = parse_identifier(f); e = make_selector_expr(f, token, e, sel); } - if (f->curr_token.kind == Token_OpenParen) { - // HACK NOTE(bill): For type_of_val(expr) - e = parse_call_expr(f, e); - } + // if (f->curr_token.kind == Token_OpenParen) { + // // HACK NOTE(bill): For type_of_val(expr) + // e = parse_call_expr(f, e); + // } return e; } @@ -2560,11 +2560,9 @@ AstNode *parse_identifier_or_type(AstFile *f) { case Token_OpenParen: { // NOTE(bill): Skip the paren expression - AstNode *type; - Token open, close; - open = expect_token(f, Token_OpenParen); - type = parse_type(f); - close = expect_token(f, Token_CloseParen); + Token open = expect_token(f, Token_OpenParen); + AstNode *type = parse_type(f); + Token close = expect_token(f, Token_CloseParen); return type; // return make_paren_expr(f, type, open, close); } break; diff --git a/src/string.c b/src/string.c index 1198af7d1..69dbf1b58 100644 --- a/src/string.c +++ b/src/string.c @@ -46,7 +46,7 @@ gb_inline String make_string_c(char *text) { return make_string(cast(u8 *)cast(void *)text, gb_strlen(text)); } -#define str_lit(c_str) make_string(cast(u8 *)c_str, gb_size_of(c_str)-1) +#define str_lit(c_str) (String){cast(u8 *)c_str, gb_size_of(c_str)-1} diff --git a/src/tokenizer.c b/src/tokenizer.c index 9c7a12ea3..d9a258a31 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -1,82 +1,82 @@ #define TOKEN_KINDS \ TOKEN_KIND(Token_Invalid, "Invalid"), \ - TOKEN_KIND(Token_EOF, "EOF"), \ + TOKEN_KIND(Token_EOF, "EOF"), \ TOKEN_KIND(Token_Comment, "Comment"), \ \ TOKEN_KIND(Token__LiteralBegin, "_LiteralBegin"), \ - TOKEN_KIND(Token_Ident, "identifier"), \ - TOKEN_KIND(Token_Integer, "integer"), \ - TOKEN_KIND(Token_Float, "float"), \ - TOKEN_KIND(Token_Rune, "rune"), \ - TOKEN_KIND(Token_String, "string"), \ -TOKEN_KIND(Token__LiteralEnd, "_LiteralEnd"), \ + TOKEN_KIND(Token_Ident, "identifier"), \ + TOKEN_KIND(Token_Integer, "integer"), \ + TOKEN_KIND(Token_Float, "float"), \ + TOKEN_KIND(Token_Rune, "rune"), \ + TOKEN_KIND(Token_String, "string"), \ +TOKEN_KIND(Token__LiteralEnd, "_LiteralEnd"), \ \ TOKEN_KIND(Token__OperatorBegin, "_OperatorBegin"), \ - TOKEN_KIND(Token_Eq, "="), \ - TOKEN_KIND(Token_Not, "!"), \ - TOKEN_KIND(Token_Hash, "#"), \ - TOKEN_KIND(Token_At, "@"), \ + TOKEN_KIND(Token_Eq, "="), \ + TOKEN_KIND(Token_Not, "!"), \ + TOKEN_KIND(Token_Hash, "#"), \ + TOKEN_KIND(Token_At, "@"), \ TOKEN_KIND(Token_Pointer, "^"), \ - TOKEN_KIND(Token_Maybe, "?"), \ - TOKEN_KIND(Token_Add, "+"), \ - TOKEN_KIND(Token_Sub, "-"), \ - TOKEN_KIND(Token_Mul, "*"), \ - TOKEN_KIND(Token_Quo, "/"), \ - TOKEN_KIND(Token_Mod, "%"), \ - TOKEN_KIND(Token_And, "&"), \ - TOKEN_KIND(Token_Or, "|"), \ - TOKEN_KIND(Token_Xor, "~"), \ - TOKEN_KIND(Token_AndNot, "&~"), \ - TOKEN_KIND(Token_Shl, "<<"), \ - TOKEN_KIND(Token_Shr, ">>"), \ + TOKEN_KIND(Token_Maybe, "?"), \ + TOKEN_KIND(Token_Add, "+"), \ + TOKEN_KIND(Token_Sub, "-"), \ + TOKEN_KIND(Token_Mul, "*"), \ + TOKEN_KIND(Token_Quo, "/"), \ + TOKEN_KIND(Token_Mod, "%"), \ + TOKEN_KIND(Token_And, "&"), \ + TOKEN_KIND(Token_Or, "|"), \ + TOKEN_KIND(Token_Xor, "~"), \ + TOKEN_KIND(Token_AndNot, "&~"), \ + TOKEN_KIND(Token_Shl, "<<"), \ + TOKEN_KIND(Token_Shr, ">>"), \ \ - TOKEN_KIND(Token_as, "as"), \ - TOKEN_KIND(Token_transmute, "transmute"), \ - TOKEN_KIND(Token_down_cast, "down_cast"), \ - TOKEN_KIND(Token_union_cast, "union_cast"), \ + /*TOKEN_KIND(Token_as, "as"), */\ + /*TOKEN_KIND(Token_transmute, "transmute"), */\ + /*TOKEN_KIND(Token_down_cast, "down_cast"), */\ + /*TOKEN_KIND(Token_union_cast, "union_cast"), */\ \ TOKEN_KIND(Token_CmpAnd, "&&"), \ - TOKEN_KIND(Token_CmpOr, "||"), \ + TOKEN_KIND(Token_CmpOr, "||"), \ \ TOKEN_KIND(Token__AssignOpBegin, "_AssignOpBegin"), \ - TOKEN_KIND(Token_AddEq, "+="), \ - TOKEN_KIND(Token_SubEq, "-="), \ - TOKEN_KIND(Token_MulEq, "*="), \ - TOKEN_KIND(Token_QuoEq, "/="), \ - TOKEN_KIND(Token_ModEq, "%="), \ - TOKEN_KIND(Token_AndEq, "&="), \ - TOKEN_KIND(Token_OrEq, "|="), \ - TOKEN_KIND(Token_XorEq, "~="), \ - TOKEN_KIND(Token_AndNotEq, "&~="), \ - TOKEN_KIND(Token_ShlEq, "<<="), \ - TOKEN_KIND(Token_ShrEq, ">>="), \ - TOKEN_KIND(Token_CmpAndEq, "&&="), \ - TOKEN_KIND(Token_CmpOrEq, "||="), \ -TOKEN_KIND(Token__AssignOpEnd, "_AssignOpEnd"), \ + TOKEN_KIND(Token_AddEq, "+="), \ + TOKEN_KIND(Token_SubEq, "-="), \ + TOKEN_KIND(Token_MulEq, "*="), \ + TOKEN_KIND(Token_QuoEq, "/="), \ + TOKEN_KIND(Token_ModEq, "%="), \ + TOKEN_KIND(Token_AndEq, "&="), \ + TOKEN_KIND(Token_OrEq, "|="), \ + TOKEN_KIND(Token_XorEq, "~="), \ + TOKEN_KIND(Token_AndNotEq, "&~="), \ + TOKEN_KIND(Token_ShlEq, "<<="), \ + TOKEN_KIND(Token_ShrEq, ">>="), \ + TOKEN_KIND(Token_CmpAndEq, "&&="), \ + TOKEN_KIND(Token_CmpOrEq, "||="), \ +TOKEN_KIND(Token__AssignOpEnd, "_AssignOpEnd"), \ TOKEN_KIND(Token_ArrowRight, "->"), \ - TOKEN_KIND(Token_ArrowLeft, "<-"), \ + TOKEN_KIND(Token_ArrowLeft, "<-"), \ \ TOKEN_KIND(Token__ComparisonBegin, "_ComparisonBegin"), \ TOKEN_KIND(Token_CmpEq, "=="), \ TOKEN_KIND(Token_NotEq, "!="), \ - TOKEN_KIND(Token_Lt, "<"), \ - TOKEN_KIND(Token_Gt, ">"), \ - TOKEN_KIND(Token_LtEq, "<="), \ - TOKEN_KIND(Token_GtEq, ">="), \ + TOKEN_KIND(Token_Lt, "<"), \ + TOKEN_KIND(Token_Gt, ">"), \ + TOKEN_KIND(Token_LtEq, "<="), \ + TOKEN_KIND(Token_GtEq, ">="), \ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \ \ - TOKEN_KIND(Token_OpenParen, "("), \ - TOKEN_KIND(Token_CloseParen, ")"), \ - TOKEN_KIND(Token_OpenBracket, "["), \ + TOKEN_KIND(Token_OpenParen, "("), \ + TOKEN_KIND(Token_CloseParen, ")"), \ + TOKEN_KIND(Token_OpenBracket, "["), \ TOKEN_KIND(Token_CloseBracket, "]"), \ - TOKEN_KIND(Token_OpenBrace, "{"), \ - TOKEN_KIND(Token_CloseBrace, "}"), \ - TOKEN_KIND(Token_Colon, ":"), \ - TOKEN_KIND(Token_Semicolon, ";"), \ - TOKEN_KIND(Token_Period, "."), \ - TOKEN_KIND(Token_Comma, ","), \ - TOKEN_KIND(Token_Ellipsis, "..."), \ - TOKEN_KIND(Token_Interval, "..<"), \ + TOKEN_KIND(Token_OpenBrace, "{"), \ + TOKEN_KIND(Token_CloseBrace, "}"), \ + TOKEN_KIND(Token_Colon, ":"), \ + TOKEN_KIND(Token_Semicolon, ";"), \ + TOKEN_KIND(Token_Period, "."), \ + TOKEN_KIND(Token_Comma, ","), \ + TOKEN_KIND(Token_Ellipsis, "..."), \ + TOKEN_KIND(Token_Interval, "..<"), \ TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \ \ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ @@ -722,7 +722,7 @@ Token tokenizer_get_token(Tokenizer *t) { // NOTE(bill): All keywords are > 1 if (token.string.len > 1) { - if (str_eq(token.string, token_strings[Token_as])) { + /* if (str_eq(token.string, token_strings[Token_as])) { token.kind = Token_as; } else if (str_eq(token.string, token_strings[Token_transmute])) { token.kind = Token_transmute; @@ -730,7 +730,7 @@ Token tokenizer_get_token(Tokenizer *t) { token.kind = Token_down_cast; } else if (str_eq(token.string, token_strings[Token_union_cast])) { token.kind = Token_union_cast; - } else { + } else */{ for (i32 k = Token__KeywordBegin+1; k < Token__KeywordEnd; k++) { if (str_eq(token.string, token_strings[k])) { token.kind = cast(TokenKind)k;