diff --git a/core/_preload.odin b/core/_preload.odin index bc202df33..657ac875b 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -17,8 +17,6 @@ import "core:raw.odin" // Constant Variables: SCREAMING_SNAKE_CASE - - // IMPORTANT NOTE(bill): `type_info_of` cannot be used within a // #shared_global_scope due to the internals of the compiler. // This could change at a later date if the all these data structures are @@ -237,15 +235,22 @@ type_info_base_without_enum :: proc(info: ^Type_Info) -> ^Type_Info { foreign __llvm_core { - assume :: proc(cond: bool) #cc_c #link_name "llvm.assume" ---; - __debug_trap :: proc() #cc_c #link_name "llvm.debugtrap" ---; - __trap :: proc() #cc_c #link_name "llvm.trap" ---; - read_cycle_counter :: proc() -> u64 #cc_c #link_name "llvm.readcyclecounter" ---; + @(link_name="llvm.assume") + assume :: proc(cond: bool) #cc_c ---; + + @(link_name="llvm.debugtrap") + __debug_trap :: proc() #cc_c ---; + + @(link_name="llvm.trap") + __trap :: proc() #cc_c ---; + + @(link_name="llvm.readcyclecounter") + read_cycle_counter :: proc() -> u64 #cc_c ---; } -make_source_code_location :: proc(file: string, line, column: i64, procedure: string) -> Source_Code_Location #cc_contextless #inline { +make_source_code_location :: inline proc(file: string, line, column: i64, procedure: string) -> Source_Code_Location #cc_contextless { return Source_Code_Location{file, line, column, procedure}; } @@ -282,32 +287,32 @@ __check_context :: proc() { } */ -alloc :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr #inline { +alloc :: inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr { a := context.allocator; return a.procedure(a.data, Allocator_Mode.Alloc, size, alignment, nil, 0, 0); } -free_ptr_with_allocator :: proc(a: Allocator, ptr: rawptr) #inline { +free_ptr_with_allocator :: inline proc(a: Allocator, ptr: rawptr) { if ptr == nil do return; if a.procedure == nil do return; a.procedure(a.data, Allocator_Mode.Free, 0, 0, ptr, 0, 0); } -free_ptr :: proc(ptr: rawptr) #inline do free_ptr_with_allocator(context.allocator, ptr); +free_ptr :: inline proc(ptr: rawptr) do free_ptr_with_allocator(context.allocator, ptr); -free_all :: proc() #inline { +free_all :: inline proc() { a := context.allocator; a.procedure(a.data, Allocator_Mode.FreeAll, 0, 0, nil, 0, 0); } -resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr #inline { +resize :: inline proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr { a := context.allocator; return a.procedure(a.data, Allocator_Mode.Resize, new_size, alignment, ptr, old_size, 0); } -copy :: proc(dst, src: $T/[]$E) -> int #cc_contextless { +copy :: proc(dst, src: $T/[]$E) -> int { n := max(0, min(len(dst), len(src))); if n > 0 do __mem_copy(&dst[0], &src[0], n*size_of(E)); return n; @@ -384,13 +389,13 @@ pop :: proc(array: ^$T/[dynamic]$E) -> E #cc_contextless { return res; } -clear :: proc(slice: ^$T/[]$E) #cc_contextless #inline { +clear :: inline proc(slice: ^$T/[]$E) #cc_contextless { if slice != nil do (cast(^raw.Slice)slice).len = 0; } -clear :: proc(array: ^$T/[dynamic]$E) #cc_contextless #inline { +clear :: inline proc(array: ^$T/[dynamic]$E) #cc_contextless { if array != nil do (cast(^raw.Dynamic_Array)array).len = 0; } -clear :: proc(m: ^$T/map[$K]$V) #cc_contextless #inline { +clear :: inline proc(m: ^$T/map[$K]$V) #cc_contextless { if m == nil do return; raw_map := cast(^raw.Map)m; hashes := cast(^raw.Dynamic_Array)&raw_map.hashes; @@ -483,12 +488,12 @@ delete :: proc(m: ^$T/map[$K]$V, key: K) { -new :: proc(T: type) -> ^T #inline { +new :: inline proc(T: type) -> ^T { ptr := cast(^T)alloc(size_of(T), align_of(T)); ptr^ = T{}; return ptr; } -new_clone :: proc(data: $T) -> ^T #inline { +new_clone :: inline proc(data: $T) -> ^T { ptr := cast(^T)alloc(size_of(T), align_of(T)); ptr^ = data; return ptr; @@ -637,18 +642,18 @@ __string_cmp :: proc(a, b: string) -> int #cc_contextless { return __mem_compare(&a[0], &b[0], min(len(a), len(b))); } -__string_ne :: proc(a, b: string) -> bool #cc_contextless #inline { return !__string_eq(a, b); } -__string_lt :: proc(a, b: string) -> bool #cc_contextless #inline { return __string_cmp(a, b) < 0; } -__string_gt :: proc(a, b: string) -> bool #cc_contextless #inline { return __string_cmp(a, b) > 0; } -__string_le :: proc(a, b: string) -> bool #cc_contextless #inline { return __string_cmp(a, b) <= 0; } -__string_ge :: proc(a, b: string) -> bool #cc_contextless #inline { return __string_cmp(a, b) >= 0; } +__string_ne :: inline proc(a, b: string) -> bool #cc_contextless { return !__string_eq(a, b); } +__string_lt :: inline proc(a, b: string) -> bool #cc_contextless { return __string_cmp(a, b) < 0; } +__string_gt :: inline proc(a, b: string) -> bool #cc_contextless { return __string_cmp(a, b) > 0; } +__string_le :: inline proc(a, b: string) -> bool #cc_contextless { return __string_cmp(a, b) <= 0; } +__string_ge :: inline proc(a, b: string) -> bool #cc_contextless { return __string_cmp(a, b) >= 0; } -__complex64_eq :: proc (a, b: complex64) -> bool #cc_contextless #inline { return real(a) == real(b) && imag(a) == imag(b); } -__complex64_ne :: proc (a, b: complex64) -> bool #cc_contextless #inline { return real(a) != real(b) || imag(a) != imag(b); } +__complex64_eq :: inline proc (a, b: complex64) -> bool #cc_contextless { return real(a) == real(b) && imag(a) == imag(b); } +__complex64_ne :: inline proc (a, b: complex64) -> bool #cc_contextless { return real(a) != real(b) || imag(a) != imag(b); } -__complex128_eq :: proc(a, b: complex128) -> bool #cc_contextless #inline { return real(a) == real(b) && imag(a) == imag(b); } -__complex128_ne :: proc(a, b: complex128) -> bool #cc_contextless #inline { return real(a) != real(b) || imag(a) != imag(b); } +__complex128_eq :: inline proc(a, b: complex128) -> bool #cc_contextless { return real(a) == real(b) && imag(a) == imag(b); } +__complex128_ne :: inline proc(a, b: complex128) -> bool #cc_contextless { return real(a) != real(b) || imag(a) != imag(b); } __bounds_check_error :: proc(file: string, line, column: int, index, count: int) #cc_contextless { @@ -678,7 +683,7 @@ __type_assertion_check :: proc(ok: bool, file: string, line, column: int, from, __debug_trap(); } -__string_decode_rune :: proc(s: string) -> (rune, int) #cc_contextless #inline { +__string_decode_rune :: inline proc(s: string) -> (rune, int) #cc_contextless { return utf8.decode_rune(s); } @@ -694,10 +699,14 @@ __substring_expr_error_loc :: proc(using loc := #caller_location, low, high: int __mem_set :: proc(data: rawptr, value: i32, len: int) -> rawptr #cc_contextless { if data == nil do return nil; - when size_of(rawptr) == 8 { - foreign __llvm_core llvm_memset :: proc(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) #link_name "llvm.memset.p0i8.i64" ---; - } else { - foreign __llvm_core llvm_memset :: proc(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) #link_name "llvm.memset.p0i8.i32" ---; + foreign __llvm_core { + when size_of(rawptr) == 8 { + @(link_name="llvm.memset.p0i8.i64") + llvm_memset :: proc(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) ---; + } else { + @(link_name="llvm.memset.p0i8.i32") + llvm_memset :: proc(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) ---; + } } llvm_memset(data, u8(value), len, 1, false); return data; @@ -708,10 +717,14 @@ __mem_zero :: proc(data: rawptr, len: int) -> rawptr #cc_contextless { __mem_copy :: proc(dst, src: rawptr, len: int) -> rawptr #cc_contextless { if src == nil do return dst; // NOTE(bill): This _must_ be implemented like C's memmove - when size_of(rawptr) == 8 { - foreign __llvm_core llvm_memmove :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memmove.p0i8.p0i8.i64" ---; - } else { - foreign __llvm_core llvm_memmove :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memmove.p0i8.p0i8.i32" ---; + foreign __llvm_core { + when size_of(rawptr) == 8 { + @(link_name="llvm.memmove.p0i8.p0i8.i64") + llvm_memmove :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) ---; + } else { + @(link_name="llvm.memmove.p0i8.p0i8.i32") + llvm_memmove :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) ---; + } } llvm_memmove(dst, src, len, 1, false); return dst; @@ -719,10 +732,14 @@ __mem_copy :: proc(dst, src: rawptr, len: int) -> rawptr #cc_contextless { __mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #cc_contextless { if src == nil do return dst; // NOTE(bill): This _must_ be implemented like C's memcpy - when size_of(rawptr) == 8 { - foreign __llvm_core llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memcpy.p0i8.p0i8.i64" ---; - } else { - foreign __llvm_core llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memcpy.p0i8.p0i8.i32" ---; + foreign __llvm_core { + when size_of(rawptr) == 8 { + @(link_name="llvm.memcpy.p0i8.p0i8.i64") + llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) ---; + } else { + @(link_name="llvm.memcpy.p0i8.p0i8.i32") + llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) ---; + } } llvm_memcpy(dst, src, len, 1, false); return dst; @@ -737,26 +754,26 @@ __mem_compare :: proc(a, b: ^u8, n: int) -> int #cc_contextless { } foreign __llvm_core { - __sqrt_f32 :: proc(x: f32) -> f32 #link_name "llvm.sqrt.f32" ---; - __sqrt_f64 :: proc(x: f64) -> f64 #link_name "llvm.sqrt.f64" ---; + @(link_name="llvm.sqrt.f32") __sqrt_f32 :: proc(x: f32) -> f32 ---; + @(link_name="llvm.sqrt.f64") __sqrt_f64 :: proc(x: f64) -> f64 ---; - __sin_f32 :: proc(θ: f32) -> f32 #link_name "llvm.sin.f32" ---; - __sin_f64 :: proc(θ: f64) -> f64 #link_name "llvm.sin.f64" ---; + @(link_name="llvm.sin.f32") __sin_f32 :: proc(θ: f32) -> f32 ---; + @(link_name="llvm.sin.f64") __sin_f64 :: proc(θ: f64) -> f64 ---; - __cos_f32 :: proc(θ: f32) -> f32 #link_name "llvm.cos.f32" ---; - __cos_f64 :: proc(θ: f64) -> f64 #link_name "llvm.cos.f64" ---; + @(link_name="llvm.cos.f32") __cos_f32 :: proc(θ: f32) -> f32 ---; + @(link_name="llvm.cos.f64") __cos_f64 :: proc(θ: f64) -> f64 ---; - __pow_f32 :: proc(x, power: f32) -> f32 #link_name "llvm.pow.f32" ---; - __pow_f64 :: proc(x, power: f64) -> f64 #link_name "llvm.pow.f64" ---; + @(link_name="llvm.pow.f32") __pow_f32 :: proc(x, power: f32) -> f32 ---; + @(link_name="llvm.pow.f64") __pow_f64 :: proc(x, power: f64) -> f64 ---; - fmuladd32 :: proc(a, b, c: f32) -> f32 #link_name "llvm.fmuladd.f32" ---; - fmuladd64 :: proc(a, b, c: f64) -> f64 #link_name "llvm.fmuladd.f64" ---; + @(link_name="llvm.fmuladd.f32") fmuladd32 :: proc(a, b, c: f32) -> f32 ---; + @(link_name="llvm.fmuladd.f64") fmuladd64 :: proc(a, b, c: f64) -> f64 ---; } -__abs_complex64 :: proc(x: complex64) -> f32 #inline #cc_contextless { +__abs_complex64 :: inline proc(x: complex64) -> f32 #cc_contextless { r, i := real(x), imag(x); return __sqrt_f32(r*r + i*i); } -__abs_complex128 :: proc(x: complex128) -> f64 #inline #cc_contextless { +__abs_complex128 :: inline proc(x: complex128) -> f64 #cc_contextless { r, i := real(x), imag(x); return __sqrt_f64(r*r + i*i); } @@ -971,7 +988,7 @@ __dynamic_map_grow :: proc(using h: __Map_Header) { __dynamic_map_rehash(h, new_count); } -__dynamic_map_full :: proc(using h: __Map_Header) -> bool #inline { +__dynamic_map_full :: inline proc(using h: __Map_Header) -> bool { return int(0.75 * f64(len(m.hashes))) <= m.entries.cap; } diff --git a/core/_soft_numbers.odin b/core/_soft_numbers.odin index 6daabf74e..9ab8b7bbd 100644 --- a/core/_soft_numbers.odin +++ b/core/_soft_numbers.odin @@ -1,6 +1,7 @@ #shared_global_scope -__multi3 :: proc(a, b: u128) -> u128 #cc_c #link_name "__multi3" { +@(link_name="__multi3") +__multi3 :: proc(a, b: u128) -> u128 #cc_c { bits_in_dword_2 :: size_of(i64) * 4; lower_mask :: u128(~u64(0) >> bits_in_dword_2); @@ -35,27 +36,32 @@ __multi3 :: proc(a, b: u128) -> u128 #cc_c #link_name "__multi3" { return r.all; } -__u128_mod :: proc(a, b: u128) -> u128 #cc_c #link_name "__umodti3" { +@(link_name="__umodti3") +__u128_mod :: proc(a, b: u128) -> u128 #cc_c { r: u128; __u128_quo_mod(a, b, &r); return r; } -__u128_quo :: proc(a, b: u128) -> u128 #cc_c #link_name "__udivti3" { +@(link_name="__udivti3") +__u128_quo :: proc(a, b: u128) -> u128 #cc_c { return __u128_quo_mod(a, b, nil); } -__i128_mod :: proc(a, b: i128) -> i128 #cc_c #link_name "__modti3" { +@(link_name="__modti3") +__i128_mod :: proc(a, b: i128) -> i128 #cc_c { r: i128; __i128_quo_mod(a, b, &r); return r; } -__i128_quo :: proc(a, b: i128) -> i128 #cc_c #link_name "__divti3" { +@(link_name="__divti3") +__i128_quo :: proc(a, b: i128) -> i128 #cc_c { return __i128_quo_mod(a, b, nil); } -__i128_quo_mod :: proc(a, b: i128, rem: ^i128) -> (quo: i128) #cc_c #link_name "__divmodti4" { +@(link_name="__divmodti4") +__i128_quo_mod :: proc(a, b: i128, rem: ^i128) -> (quo: i128) #cc_c { s: i128; s = b >> 127; b = (b~s) - s; @@ -74,7 +80,8 @@ __i128_quo_mod :: proc(a, b: i128, rem: ^i128) -> (quo: i128) #cc_c #link_name " } -__u128_quo_mod :: proc(a, b: u128, rem: ^u128) -> (quo: u128) #cc_c #link_name "__udivmodti4" { +@(link_name="__udivmodti4") +__u128_quo_mod :: proc(a, b: u128, rem: ^u128) -> (quo: u128) #cc_c { alo := u64(a); blo := u64(b); if b == 0 { @@ -103,7 +110,8 @@ __u128_quo_mod :: proc(a, b: u128, rem: ^u128) -> (quo: u128) #cc_c #link_name " } /* -__f16_to_f32 :: proc(f: f16) -> f32 #cc_c #no_inline #link_name "__gnu_h2f_ieee" { +@(link_name="__gnu_h2f_ieee") +__f16_to_f32 :: proc(f: f16) -> f32 #cc_c #no_inline { when true { // Source: https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/ FP32 :: struct #raw_union {u: u32, f: f32}; @@ -127,7 +135,8 @@ __f16_to_f32 :: proc(f: f16) -> f32 #cc_c #no_inline #link_name "__gnu_h2f_ieee" return 0; } } -__f32_to_f16 :: proc(f_: f32) -> f16 #cc_c #no_inline #link_name "__gnu_f2h_ieee" { +@(link_name="__gnu_f2h_ieee") +__f32_to_f16 :: proc(f_: f32) -> f16 #cc_c #no_inline { when false { // Source: https://gist.github.com/rygorous/2156668 FP16 :: struct #raw_union {u: u16, f: f16}; @@ -217,7 +226,8 @@ __f32_to_f16 :: proc(f_: f32) -> f16 #cc_c #no_inline #link_name "__gnu_f2h_ieee } } -__f64_to_f16 :: proc(f: f64) -> f16 #cc_c #no_inline #link_name "__truncdfhf2" { +@(link_name="__truncdfhf2") +__f64_to_f16 :: proc(f: f64) -> f16 #cc_c #no_inline { return __f32_to_f16(f32(f)); } diff --git a/core/bits.odin b/core/bits.odin index 22c5f62a3..012a1f593 100644 --- a/core/bits.odin +++ b/core/bits.odin @@ -22,16 +22,16 @@ I32_MAX :: i32(0x7fff_ffff); I64_MAX :: i64(0x7fff_ffff_ffff_ffff); I128_MAX :: i128(0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff); -count_ones :: proc(i: u8) -> u8 { foreign __llvm_core __llvm_ctpop :: proc(u8) -> u8 #link_name "llvm.ctpop.i8" ---; return __llvm_ctpop(i); } -count_ones :: proc(i: i8) -> i8 { foreign __llvm_core __llvm_ctpop :: proc(i8) -> i8 #link_name "llvm.ctpop.i8" ---; return __llvm_ctpop(i); } -count_ones :: proc(i: u16) -> u16 { foreign __llvm_core __llvm_ctpop :: proc(u16) -> u16 #link_name "llvm.ctpop.i16" ---; return __llvm_ctpop(i); } -count_ones :: proc(i: i16) -> i16 { foreign __llvm_core __llvm_ctpop :: proc(i16) -> i16 #link_name "llvm.ctpop.i16" ---; return __llvm_ctpop(i); } -count_ones :: proc(i: u32) -> u32 { foreign __llvm_core __llvm_ctpop :: proc(u32) -> u32 #link_name "llvm.ctpop.i32" ---; return __llvm_ctpop(i); } -count_ones :: proc(i: i32) -> i32 { foreign __llvm_core __llvm_ctpop :: proc(i32) -> i32 #link_name "llvm.ctpop.i32" ---; return __llvm_ctpop(i); } -count_ones :: proc(i: u64) -> u64 { foreign __llvm_core __llvm_ctpop :: proc(u64) -> u64 #link_name "llvm.ctpop.i64" ---; return __llvm_ctpop(i); } -count_ones :: proc(i: i64) -> i64 { foreign __llvm_core __llvm_ctpop :: proc(i64) -> i64 #link_name "llvm.ctpop.i64" ---; return __llvm_ctpop(i); } -count_ones :: proc(i: u128) -> u128 { foreign __llvm_core __llvm_ctpop :: proc(u128) -> u128 #link_name "llvm.ctpop.i128" ---;return __llvm_ctpop(i); } -count_ones :: proc(i: i128) -> i128 { foreign __llvm_core __llvm_ctpop :: proc(i128) -> i128 #link_name "llvm.ctpop.i128" ---;return __llvm_ctpop(i); } +count_ones :: proc(i: u8) -> u8 { foreign __llvm_core @(link_name="llvm.ctpop.i8") __llvm_ctpop :: proc(u8) -> u8 ---; return __llvm_ctpop(i); } +count_ones :: proc(i: i8) -> i8 { foreign __llvm_core @(link_name="llvm.ctpop.i8") __llvm_ctpop :: proc(i8) -> i8 ---; return __llvm_ctpop(i); } +count_ones :: proc(i: u16) -> u16 { foreign __llvm_core @(link_name="llvm.ctpop.i16") __llvm_ctpop :: proc(u16) -> u16 ---; return __llvm_ctpop(i); } +count_ones :: proc(i: i16) -> i16 { foreign __llvm_core @(link_name="llvm.ctpop.i16") __llvm_ctpop :: proc(i16) -> i16 ---; return __llvm_ctpop(i); } +count_ones :: proc(i: u32) -> u32 { foreign __llvm_core @(link_name="llvm.ctpop.i32") __llvm_ctpop :: proc(u32) -> u32 ---; return __llvm_ctpop(i); } +count_ones :: proc(i: i32) -> i32 { foreign __llvm_core @(link_name="llvm.ctpop.i32") __llvm_ctpop :: proc(i32) -> i32 ---; return __llvm_ctpop(i); } +count_ones :: proc(i: u64) -> u64 { foreign __llvm_core @(link_name="llvm.ctpop.i64") __llvm_ctpop :: proc(u64) -> u64 ---; return __llvm_ctpop(i); } +count_ones :: proc(i: i64) -> i64 { foreign __llvm_core @(link_name="llvm.ctpop.i64") __llvm_ctpop :: proc(i64) -> i64 ---; return __llvm_ctpop(i); } +count_ones :: proc(i: u128) -> u128 { foreign __llvm_core @(link_name="llvm.ctpop.i128") __llvm_ctpop :: proc(u128) -> u128 ---;return __llvm_ctpop(i); } +count_ones :: proc(i: i128) -> i128 { foreign __llvm_core @(link_name="llvm.ctpop.i128") __llvm_ctpop :: proc(i128) -> i128 ---;return __llvm_ctpop(i); } count_ones :: proc(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(count_ones(u32(i))); } else { return uint(count_ones(u64(i))); } } count_ones :: proc(i: int) -> int { when size_of(int) == size_of(i32) { return int(count_ones(i32(i))); } else { return int(count_ones(i64(i))); } } @@ -77,55 +77,55 @@ rotate_right :: proc(i: uint, s: uint) -> uint { when size_of(uint) == size_of(u rotate_right :: proc(i: int, s: uint) -> int { when size_of(int) == size_of(i32) { return int(rotate_right(i32(i), s)); } else { return int(rotate_right(i64(i), s)); } } -leading_zeros :: proc(i: u8) -> u8 { foreign __llvm_core __llvm_ctlz :: proc(u8, bool) -> u8 #link_name "llvm.ctlz.i8" ---; return __llvm_ctlz(i, false); } -leading_zeros :: proc(i: i8) -> i8 { foreign __llvm_core __llvm_ctlz :: proc(i8, bool) -> i8 #link_name "llvm.ctlz.i8" ---; return __llvm_ctlz(i, false); } -leading_zeros :: proc(i: u16) -> u16 { foreign __llvm_core __llvm_ctlz :: proc(u16, bool) -> u16 #link_name "llvm.ctlz.i16" ---; return __llvm_ctlz(i, false); } -leading_zeros :: proc(i: i16) -> i16 { foreign __llvm_core __llvm_ctlz :: proc(i16, bool) -> i16 #link_name "llvm.ctlz.i16" ---; return __llvm_ctlz(i, false); } -leading_zeros :: proc(i: u32) -> u32 { foreign __llvm_core __llvm_ctlz :: proc(u32, bool) -> u32 #link_name "llvm.ctlz.i32" ---; return __llvm_ctlz(i, false); } -leading_zeros :: proc(i: i32) -> i32 { foreign __llvm_core __llvm_ctlz :: proc(i32, bool) -> i32 #link_name "llvm.ctlz.i32" ---; return __llvm_ctlz(i, false); } -leading_zeros :: proc(i: u64) -> u64 { foreign __llvm_core __llvm_ctlz :: proc(u64, bool) -> u64 #link_name "llvm.ctlz.i64" ---; return __llvm_ctlz(i, false); } -leading_zeros :: proc(i: i64) -> i64 { foreign __llvm_core __llvm_ctlz :: proc(i64, bool) -> i64 #link_name "llvm.ctlz.i64" ---; return __llvm_ctlz(i, false); } -leading_zeros :: proc(i: u128) -> u128 { foreign __llvm_core __llvm_ctlz :: proc(u128, bool) -> u128 #link_name "llvm.ctlz.i128" ---;return __llvm_ctlz(i, false); } -leading_zeros :: proc(i: i128) -> i128 { foreign __llvm_core __llvm_ctlz :: proc(i128, bool) -> i128 #link_name "llvm.ctlz.i128" ---;return __llvm_ctlz(i, false); } +leading_zeros :: proc(i: u8) -> u8 { foreign __llvm_core @(link_name="llvm.ctlz.i8") __llvm_ctlz :: proc(u8, bool) -> u8 ---; return __llvm_ctlz(i, false); } +leading_zeros :: proc(i: i8) -> i8 { foreign __llvm_core @(link_name="llvm.ctlz.i8") __llvm_ctlz :: proc(i8, bool) -> i8 ---; return __llvm_ctlz(i, false); } +leading_zeros :: proc(i: u16) -> u16 { foreign __llvm_core @(link_name="llvm.ctlz.i16") __llvm_ctlz :: proc(u16, bool) -> u16 ---; return __llvm_ctlz(i, false); } +leading_zeros :: proc(i: i16) -> i16 { foreign __llvm_core @(link_name="llvm.ctlz.i16") __llvm_ctlz :: proc(i16, bool) -> i16 ---; return __llvm_ctlz(i, false); } +leading_zeros :: proc(i: u32) -> u32 { foreign __llvm_core @(link_name="llvm.ctlz.i32") __llvm_ctlz :: proc(u32, bool) -> u32 ---; return __llvm_ctlz(i, false); } +leading_zeros :: proc(i: i32) -> i32 { foreign __llvm_core @(link_name="llvm.ctlz.i32") __llvm_ctlz :: proc(i32, bool) -> i32 ---; return __llvm_ctlz(i, false); } +leading_zeros :: proc(i: u64) -> u64 { foreign __llvm_core @(link_name="llvm.ctlz.i64") __llvm_ctlz :: proc(u64, bool) -> u64 ---; return __llvm_ctlz(i, false); } +leading_zeros :: proc(i: i64) -> i64 { foreign __llvm_core @(link_name="llvm.ctlz.i64") __llvm_ctlz :: proc(i64, bool) -> i64 ---; return __llvm_ctlz(i, false); } +leading_zeros :: proc(i: u128) -> u128 { foreign __llvm_core @(link_name="llvm.ctlz.i128") __llvm_ctlz :: proc(u128, bool) -> u128 ---;return __llvm_ctlz(i, false); } +leading_zeros :: proc(i: i128) -> i128 { foreign __llvm_core @(link_name="llvm.ctlz.i128") __llvm_ctlz :: proc(i128, bool) -> i128 ---;return __llvm_ctlz(i, false); } leading_zeros :: proc(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(leading_zeros(u32(i))); } else { return uint(leading_zeros(u64(i))); } } leading_zeros :: proc(i: int) -> int { when size_of(int) == size_of(i32) { return int(leading_zeros(i32(i))); } else { return int(leading_zeros(i64(i))); } } -trailing_zeros :: proc(i: u8) -> u8 { foreign __llvm_core __llvm_cttz :: proc(u8, bool) -> u8 #link_name "llvm.cttz.i8" ---; return __llvm_cttz(i, false); } -trailing_zeros :: proc(i: i8) -> i8 { foreign __llvm_core __llvm_cttz :: proc(i8, bool) -> i8 #link_name "llvm.cttz.i8" ---; return __llvm_cttz(i, false); } -trailing_zeros :: proc(i: u16) -> u16 { foreign __llvm_core __llvm_cttz :: proc(u16, bool) -> u16 #link_name "llvm.cttz.i16" ---; return __llvm_cttz(i, false); } -trailing_zeros :: proc(i: i16) -> i16 { foreign __llvm_core __llvm_cttz :: proc(i16, bool) -> i16 #link_name "llvm.cttz.i16" ---; return __llvm_cttz(i, false); } -trailing_zeros :: proc(i: u32) -> u32 { foreign __llvm_core __llvm_cttz :: proc(u32, bool) -> u32 #link_name "llvm.cttz.i32" ---; return __llvm_cttz(i, false); } -trailing_zeros :: proc(i: i32) -> i32 { foreign __llvm_core __llvm_cttz :: proc(i32, bool) -> i32 #link_name "llvm.cttz.i32" ---; return __llvm_cttz(i, false); } -trailing_zeros :: proc(i: u64) -> u64 { foreign __llvm_core __llvm_cttz :: proc(u64, bool) -> u64 #link_name "llvm.cttz.i64" ---; return __llvm_cttz(i, false); } -trailing_zeros :: proc(i: i64) -> i64 { foreign __llvm_core __llvm_cttz :: proc(i64, bool) -> i64 #link_name "llvm.cttz.i64" ---; return __llvm_cttz(i, false); } -trailing_zeros :: proc(i: u128) -> u128 { foreign __llvm_core __llvm_cttz :: proc(u128, bool) -> u128 #link_name "llvm.cttz.i128" ---;return __llvm_cttz(i, false); } -trailing_zeros :: proc(i: i128) -> i128 { foreign __llvm_core __llvm_cttz :: proc(i128, bool) -> i128 #link_name "llvm.cttz.i128" ---;return __llvm_cttz(i, false); } +trailing_zeros :: proc(i: u8) -> u8 { foreign __llvm_core @(link_name="llvm.cttz.i8") __llvm_cttz :: proc(u8, bool) -> u8 ---; return __llvm_cttz(i, false); } +trailing_zeros :: proc(i: i8) -> i8 { foreign __llvm_core @(link_name="llvm.cttz.i8") __llvm_cttz :: proc(i8, bool) -> i8 ---; return __llvm_cttz(i, false); } +trailing_zeros :: proc(i: u16) -> u16 { foreign __llvm_core @(link_name="llvm.cttz.i16") __llvm_cttz :: proc(u16, bool) -> u16 ---; return __llvm_cttz(i, false); } +trailing_zeros :: proc(i: i16) -> i16 { foreign __llvm_core @(link_name="llvm.cttz.i16") __llvm_cttz :: proc(i16, bool) -> i16 ---; return __llvm_cttz(i, false); } +trailing_zeros :: proc(i: u32) -> u32 { foreign __llvm_core @(link_name="llvm.cttz.i32") __llvm_cttz :: proc(u32, bool) -> u32 ---; return __llvm_cttz(i, false); } +trailing_zeros :: proc(i: i32) -> i32 { foreign __llvm_core @(link_name="llvm.cttz.i32") __llvm_cttz :: proc(i32, bool) -> i32 ---; return __llvm_cttz(i, false); } +trailing_zeros :: proc(i: u64) -> u64 { foreign __llvm_core @(link_name="llvm.cttz.i64") __llvm_cttz :: proc(u64, bool) -> u64 ---; return __llvm_cttz(i, false); } +trailing_zeros :: proc(i: i64) -> i64 { foreign __llvm_core @(link_name="llvm.cttz.i64") __llvm_cttz :: proc(i64, bool) -> i64 ---; return __llvm_cttz(i, false); } +trailing_zeros :: proc(i: u128) -> u128 { foreign __llvm_core @(link_name="llvm.cttz.i128") __llvm_cttz :: proc(u128, bool) -> u128 ---;return __llvm_cttz(i, false); } +trailing_zeros :: proc(i: i128) -> i128 { foreign __llvm_core @(link_name="llvm.cttz.i128") __llvm_cttz :: proc(i128, bool) -> i128 ---;return __llvm_cttz(i, false); } trailing_zeros :: proc(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(trailing_zeros(u32(i))); } else { return uint(trailing_zeros(u64(i))); } } trailing_zeros :: proc(i: int) -> int { when size_of(int) == size_of(i32) { return int(trailing_zeros(i32(i))); } else { return int(trailing_zeros(i64(i))); } } -reverse_bits :: proc(i: u8) -> u8 { foreign __llvm_core __llvm_bitreverse :: proc(u8) -> u8 #link_name "llvm.bitreverse.i8" ---; return __llvm_bitreverse(i); } -reverse_bits :: proc(i: i8) -> i8 { foreign __llvm_core __llvm_bitreverse :: proc(i8) -> i8 #link_name "llvm.bitreverse.i8" ---; return __llvm_bitreverse(i); } -reverse_bits :: proc(i: u16) -> u16 { foreign __llvm_core __llvm_bitreverse :: proc(u16) -> u16 #link_name "llvm.bitreverse.i16" ---; return __llvm_bitreverse(i); } -reverse_bits :: proc(i: i16) -> i16 { foreign __llvm_core __llvm_bitreverse :: proc(i16) -> i16 #link_name "llvm.bitreverse.i16" ---; return __llvm_bitreverse(i); } -reverse_bits :: proc(i: u32) -> u32 { foreign __llvm_core __llvm_bitreverse :: proc(u32) -> u32 #link_name "llvm.bitreverse.i32" ---; return __llvm_bitreverse(i); } -reverse_bits :: proc(i: i32) -> i32 { foreign __llvm_core __llvm_bitreverse :: proc(i32) -> i32 #link_name "llvm.bitreverse.i32" ---; return __llvm_bitreverse(i); } -reverse_bits :: proc(i: u64) -> u64 { foreign __llvm_core __llvm_bitreverse :: proc(u64) -> u64 #link_name "llvm.bitreverse.i64" ---; return __llvm_bitreverse(i); } -reverse_bits :: proc(i: i64) -> i64 { foreign __llvm_core __llvm_bitreverse :: proc(i64) -> i64 #link_name "llvm.bitreverse.i64" ---; return __llvm_bitreverse(i); } -reverse_bits :: proc(i: u128) -> u128 { foreign __llvm_core __llvm_bitreverse :: proc(u128) -> u128 #link_name "llvm.bitreverse.i128" ---;return __llvm_bitreverse(i); } -reverse_bits :: proc(i: i128) -> i128 { foreign __llvm_core __llvm_bitreverse :: proc(i128) -> i128 #link_name "llvm.bitreverse.i128" ---;return __llvm_bitreverse(i); } +reverse_bits :: proc(i: u8) -> u8 { foreign __llvm_core @(link_name="llvm.bitreverse.i8") __llvm_bitreverse :: proc(u8) -> u8 ---; return __llvm_bitreverse(i); } +reverse_bits :: proc(i: i8) -> i8 { foreign __llvm_core @(link_name="llvm.bitreverse.i8") __llvm_bitreverse :: proc(i8) -> i8 ---; return __llvm_bitreverse(i); } +reverse_bits :: proc(i: u16) -> u16 { foreign __llvm_core @(link_name="llvm.bitreverse.i16") __llvm_bitreverse :: proc(u16) -> u16 ---; return __llvm_bitreverse(i); } +reverse_bits :: proc(i: i16) -> i16 { foreign __llvm_core @(link_name="llvm.bitreverse.i16") __llvm_bitreverse :: proc(i16) -> i16 ---; return __llvm_bitreverse(i); } +reverse_bits :: proc(i: u32) -> u32 { foreign __llvm_core @(link_name="llvm.bitreverse.i32") __llvm_bitreverse :: proc(u32) -> u32 ---; return __llvm_bitreverse(i); } +reverse_bits :: proc(i: i32) -> i32 { foreign __llvm_core @(link_name="llvm.bitreverse.i32") __llvm_bitreverse :: proc(i32) -> i32 ---; return __llvm_bitreverse(i); } +reverse_bits :: proc(i: u64) -> u64 { foreign __llvm_core @(link_name="llvm.bitreverse.i64") __llvm_bitreverse :: proc(u64) -> u64 ---; return __llvm_bitreverse(i); } +reverse_bits :: proc(i: i64) -> i64 { foreign __llvm_core @(link_name="llvm.bitreverse.i64") __llvm_bitreverse :: proc(i64) -> i64 ---; return __llvm_bitreverse(i); } +reverse_bits :: proc(i: u128) -> u128 { foreign __llvm_core @(link_name="llvm.bitreverse.i128") __llvm_bitreverse :: proc(u128) -> u128 ---;return __llvm_bitreverse(i); } +reverse_bits :: proc(i: i128) -> i128 { foreign __llvm_core @(link_name="llvm.bitreverse.i128") __llvm_bitreverse :: proc(i128) -> i128 ---;return __llvm_bitreverse(i); } reverse_bits :: proc(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(reverse_bits(u32(i))); } else { return uint(reverse_bits(u64(i))); } } reverse_bits :: proc(i: int) -> int { when size_of(int) == size_of(i32) { return int(reverse_bits(i32(i))); } else { return int(reverse_bits(i64(i))); } } foreign __llvm_core { - byte_swap :: proc(u16) -> u16 #link_name "llvm.bswap.i16" ---; - byte_swap :: proc(i16) -> i16 #link_name "llvm.bswap.i16" ---; - byte_swap :: proc(u32) -> u32 #link_name "llvm.bswap.i32" ---; - byte_swap :: proc(i32) -> i32 #link_name "llvm.bswap.i32" ---; - byte_swap :: proc(u64) -> u64 #link_name "llvm.bswap.i64" ---; - byte_swap :: proc(i64) -> i64 #link_name "llvm.bswap.i64" ---; - byte_swap :: proc(u128) -> u128 #link_name "llvm.bswap.i128" ---; - byte_swap :: proc(i128) -> i128 #link_name "llvm.bswap.i128" ---; + @(link_name="llvm.bswap.i16") byte_swap :: proc(u16) -> u16 ---; + @(link_name="llvm.bswap.i16") byte_swap :: proc(i16) -> i16 ---; + @(link_name="llvm.bswap.i32") byte_swap :: proc(u32) -> u32 ---; + @(link_name="llvm.bswap.i32") byte_swap :: proc(i32) -> i32 ---; + @(link_name="llvm.bswap.i64") byte_swap :: proc(u64) -> u64 ---; + @(link_name="llvm.bswap.i64") byte_swap :: proc(i64) -> i64 ---; + @(link_name="llvm.bswap.i128") byte_swap :: proc(u128) -> u128 ---; + @(link_name="llvm.bswap.i128") byte_swap :: proc(i128) -> i128 ---; } byte_swap :: proc(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(byte_swap(u32(i))); } else { return uint(byte_swap(u64(i))); } } byte_swap :: proc(i: int) -> int { when size_of(int) == size_of(i32) { return int(byte_swap(i32(i))); } else { return int(byte_swap(i64(i))); } } @@ -184,16 +184,16 @@ to_le :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i; } else to_le :: proc(i: int) -> int { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } } -overflowing_add :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core op :: proc(u8, u8) -> (u8, bool) #link_name "llvm.uadd.with.overflow.i8" ---; return op(lhs, rhs); } -overflowing_add :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core op :: proc(i8, i8) -> (i8, bool) #link_name "llvm.sadd.with.overflow.i8" ---; return op(lhs, rhs); } -overflowing_add :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core op :: proc(u16, u16) -> (u16, bool) #link_name "llvm.uadd.with.overflow.i16" ---; return op(lhs, rhs); } -overflowing_add :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core op :: proc(i16, i16) -> (i16, bool) #link_name "llvm.sadd.with.overflow.i16" ---; return op(lhs, rhs); } -overflowing_add :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core op :: proc(u32, u32) -> (u32, bool) #link_name "llvm.uadd.with.overflow.i32" ---; return op(lhs, rhs); } -overflowing_add :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core op :: proc(i32, i32) -> (i32, bool) #link_name "llvm.sadd.with.overflow.i32" ---; return op(lhs, rhs); } -overflowing_add :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core op :: proc(u64, u64) -> (u64, bool) #link_name "llvm.uadd.with.overflow.i64" ---; return op(lhs, rhs); } -overflowing_add :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core op :: proc(i64, i64) -> (i64, bool) #link_name "llvm.sadd.with.overflow.i64" ---; return op(lhs, rhs); } -overflowing_add :: proc(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core op :: proc(u128, u128) -> (u128, bool) #link_name "llvm.uadd.with.overflow.i128" ---; return op(lhs, rhs); } -overflowing_add :: proc(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core op :: proc(i128, i128) -> (i128, bool) #link_name "llvm.sadd.with.overflow.i128" ---; return op(lhs, rhs); } +overflowing_add :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) ---; return op(lhs, rhs); } +overflowing_add :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) ---; return op(lhs, rhs); } +overflowing_add :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) ---; return op(lhs, rhs); } +overflowing_add :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) ---; return op(lhs, rhs); } +overflowing_add :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) ---; return op(lhs, rhs); } +overflowing_add :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) ---; return op(lhs, rhs); } +overflowing_add :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) ---; return op(lhs, rhs); } +overflowing_add :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) ---; return op(lhs, rhs); } +overflowing_add :: proc(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i128") op :: proc(u128, u128) -> (u128, bool) ---; return op(lhs, rhs); } +overflowing_add :: proc(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i128") op :: proc(i128, i128) -> (i128, bool) ---; return op(lhs, rhs); } overflowing_add :: proc(lhs, rhs: uint) -> (uint, bool) { when size_of(uint) == size_of(u32) { x, ok := overflowing_add(u32(lhs), u32(rhs)); @@ -213,16 +213,16 @@ overflowing_add :: proc(lhs, rhs: int) -> (int, bool) { } } -overflowing_sub :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core op :: proc(u8, u8) -> (u8, bool) #link_name "llvm.usub.with.overflow.i8" ---; return op(lhs, rhs); } -overflowing_sub :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core op :: proc(i8, i8) -> (i8, bool) #link_name "llvm.ssub.with.overflow.i8" ---; return op(lhs, rhs); } -overflowing_sub :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core op :: proc(u16, u16) -> (u16, bool) #link_name "llvm.usub.with.overflow.i16" ---; return op(lhs, rhs); } -overflowing_sub :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core op :: proc(i16, i16) -> (i16, bool) #link_name "llvm.ssub.with.overflow.i16" ---; return op(lhs, rhs); } -overflowing_sub :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core op :: proc(u32, u32) -> (u32, bool) #link_name "llvm.usub.with.overflow.i32" ---; return op(lhs, rhs); } -overflowing_sub :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core op :: proc(i32, i32) -> (i32, bool) #link_name "llvm.ssub.with.overflow.i32" ---; return op(lhs, rhs); } -overflowing_sub :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core op :: proc(u64, u64) -> (u64, bool) #link_name "llvm.usub.with.overflow.i64" ---; return op(lhs, rhs); } -overflowing_sub :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core op :: proc(i64, i64) -> (i64, bool) #link_name "llvm.ssub.with.overflow.i64" ---; return op(lhs, rhs); } -overflowing_sub :: proc(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core op :: proc(u128, u128) -> (u128, bool) #link_name "llvm.usub.with.overflow.i128" ---; return op(lhs, rhs); } -overflowing_sub :: proc(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core op :: proc(i128, i128) -> (i128, bool) #link_name "llvm.ssub.with.overflow.i128" ---; return op(lhs, rhs); } +overflowing_sub :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) ---; return op(lhs, rhs); } +overflowing_sub :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) ---; return op(lhs, rhs); } +overflowing_sub :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) ---; return op(lhs, rhs); } +overflowing_sub :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) ---; return op(lhs, rhs); } +overflowing_sub :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) ---; return op(lhs, rhs); } +overflowing_sub :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) ---; return op(lhs, rhs); } +overflowing_sub :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) ---; return op(lhs, rhs); } +overflowing_sub :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) ---; return op(lhs, rhs); } +overflowing_sub :: proc(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i128") op :: proc(u128, u128) -> (u128, bool) ---; return op(lhs, rhs); } +overflowing_sub :: proc(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i128") op :: proc(i128, i128) -> (i128, bool) ---; return op(lhs, rhs); } overflowing_sub :: proc(lhs, rhs: uint) -> (uint, bool) { when size_of(uint) == size_of(u32) { x, ok := overflowing_sub(u32(lhs), u32(rhs)); @@ -242,16 +242,16 @@ overflowing_sub :: proc(lhs, rhs: int) -> (int, bool) { } } -overflowing_mul :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core op :: proc(u8, u8) -> (u8, bool) #link_name "llvm.umul.with.overflow.i8" ---; return op(lhs, rhs); } -overflowing_mul :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core op :: proc(i8, i8) -> (i8, bool) #link_name "llvm.smul.with.overflow.i8" ---; return op(lhs, rhs); } -overflowing_mul :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core op :: proc(u16, u16) -> (u16, bool) #link_name "llvm.umul.with.overflow.i16" ---; return op(lhs, rhs); } -overflowing_mul :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core op :: proc(i16, i16) -> (i16, bool) #link_name "llvm.smul.with.overflow.i16" ---; return op(lhs, rhs); } -overflowing_mul :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core op :: proc(u32, u32) -> (u32, bool) #link_name "llvm.umul.with.overflow.i32" ---; return op(lhs, rhs); } -overflowing_mul :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core op :: proc(i32, i32) -> (i32, bool) #link_name "llvm.smul.with.overflow.i32" ---; return op(lhs, rhs); } -overflowing_mul :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core op :: proc(u64, u64) -> (u64, bool) #link_name "llvm.umul.with.overflow.i64" ---; return op(lhs, rhs); } -overflowing_mul :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core op :: proc(i64, i64) -> (i64, bool) #link_name "llvm.smul.with.overflow.i64" ---; return op(lhs, rhs); } -overflowing_mul :: proc(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core op :: proc(u128, u128) -> (u128, bool) #link_name "llvm.umul.with.overflow.i128" ---; return op(lhs, rhs); } -overflowing_mul :: proc(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core op :: proc(i128, i128) -> (i128, bool) #link_name "llvm.smul.with.overflow.i128" ---; return op(lhs, rhs); } +overflowing_mul :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) ---; return op(lhs, rhs); } +overflowing_mul :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) ---; return op(lhs, rhs); } +overflowing_mul :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) ---; return op(lhs, rhs); } +overflowing_mul :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) ---; return op(lhs, rhs); } +overflowing_mul :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) ---; return op(lhs, rhs); } +overflowing_mul :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) ---; return op(lhs, rhs); } +overflowing_mul :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) ---; return op(lhs, rhs); } +overflowing_mul :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) ---; return op(lhs, rhs); } +overflowing_mul :: proc(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i128") op :: proc(u128, u128) -> (u128, bool) ---; return op(lhs, rhs); } +overflowing_mul :: proc(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i128") op :: proc(i128, i128) -> (i128, bool) ---; return op(lhs, rhs); } overflowing_mul :: proc(lhs, rhs: uint) -> (uint, bool) { when size_of(uint) == size_of(u32) { x, ok := overflowing_mul(u32(lhs), u32(rhs)); diff --git a/core/c.odin b/core/c.odin index 0737c55ac..77b12fbb7 100644 --- a/core/c.odin +++ b/core/c.odin @@ -1,41 +1,38 @@ CHAR_BIT :: 8; -c_bool :: bool; +c_bool :: #alias bool; +c_char :: #alias u8; +c_byte :: #alias u8; +c_schar :: #alias i8; +c_uchar :: #alias u8; +c_short :: #alias i16; +c_ushort :: #alias u16; +c_int :: #alias i32; +c_uint :: #alias u32; -c_char :: u8; - -c_schar :: i8; -c_uchar :: u8; - -c_short :: i16; -c_ushort :: u16; - -c_int :: i32; -c_uint :: u32; - -when ODIN_OS == "windows" || size_of(int) == 4 { - c_long :: i32; +when ODIN_OS == "windows" || size_of(rawptr) == 4 { + c_long :: #alias i32; } else { - c_long :: i64; + c_long :: #alias i64; } -when ODIN_OS == "windows" || size_of(uint) == 4 { - c_ulong :: u32; +when ODIN_OS == "windows" || size_of(rawptr) == 4 { + c_ulong :: #alias u32; } else { - c_ulong :: u64; + c_ulong :: #alias u64; } -c_longlong :: i64; -c_ulonglong :: u64; +c_longlong :: #alias i64; +c_ulonglong :: #alias u64; +c_float :: #alias f32; +c_double :: #alias f64; +c_complex_float :: #alias complex64; +c_complex_double :: #alias complex128; -c_float :: f32; -c_double :: f64; +_ :: compile_assert(size_of(uintptr) == size_of(int)); -c_complex_float :: complex64; -c_complex_double :: complex128; - -c_size_t :: uint; -c_ssize_t :: int; -c_ptrdiff_t :: int; -c_uintptr_t :: uint; -c_intptr_t :: int; +c_size_t :: #alias uint; +c_ssize_t :: #alias int; +c_ptrdiff_t :: #alias int; +c_uintptr_t :: #alias uintptr; +c_intptr_t :: #alias int; diff --git a/core/fmt.odin b/core/fmt.odin index 9e8b26feb..a83c4c104 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -331,7 +331,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) { _parse_int :: proc(s: string, offset: int) -> (result: int, offset: int, ok: bool) { - is_digit :: proc(r: rune) -> bool #inline { + is_digit :: inline proc(r: rune) -> bool{ return '0' <= r && r <= '9'; } @@ -640,7 +640,7 @@ fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) { fmt_bad_verb(fi, verb); return; } - u := u128(uint(p)); + u := u128(uintptr(p)); if !fi.hash || verb == 'v' { write_string(fi.buf, "0x"); } diff --git a/core/math.odin b/core/math.odin index 23586cce7..0ea41e520 100644 --- a/core/math.odin +++ b/core/math.odin @@ -28,31 +28,34 @@ Mat4 :: [4][4]f32; Complex :: complex64; foreign __llvm_core { - sqrt :: proc(x: f32) -> f32 #link_name "llvm.sqrt.f32" ---; - sqrt :: proc(x: f64) -> f64 #link_name "llvm.sqrt.f64" ---; + @(link_name="llvm.sqrt.f32") + sqrt :: proc(x: f32) -> f32 ---; + @(link_name="llvm.sqrt.f64") + sqrt :: proc(x: f64) -> f64 ---; - sin :: proc(θ: f32) -> f32 #link_name "llvm.sin.f32" ---; - sin :: proc(θ: f64) -> f64 #link_name "llvm.sin.f64" ---; + @(link_name="llvm.sin.f32") + sin :: proc(θ: f32) -> f32 ---; + @(link_name="llvm.sin.f64") + sin :: proc(θ: f64) -> f64 ---; - cos :: proc(θ: f32) -> f32 #link_name "llvm.cos.f32" ---; - cos :: proc(θ: f64) -> f64 #link_name "llvm.cos.f64" ---; + @(link_name="llvm.cos.f32") + cos :: proc(θ: f32) -> f32 ---; + @(link_name="llvm.cos.f64") + cos :: proc(θ: f64) -> f64 ---; - // asin :: proc(x: f32) -> f32 #link_name "llvm.asin.f32" ---; - // asin :: proc(x: f64) -> f64 #link_name "llvm.asin.f64" ---; + @(link_name="llvm.pow.f32") + pow :: proc(x, power: f32) -> f32 ---; + @(link_name="llvm.pow.f64") + pow :: proc(x, power: f64) -> f64 ---; - // acos :: proc(x: f32) -> f32 #link_name "llvm.acos.f32" ---; - // acos :: proc(x: f64) -> f64 #link_name "llvm.acos.f64" ---; - - - pow :: proc(x, power: f32) -> f32 #link_name "llvm.pow.f32" ---; - pow :: proc(x, power: f64) -> f64 #link_name "llvm.pow.f64" ---; - - fmuladd :: proc(a, b, c: f32) -> f32 #link_name "llvm.fmuladd.f32" ---; - fmuladd :: proc(a, b, c: f64) -> f64 #link_name "llvm.fmuladd.f64" ---; + @(link_name="llvm.fmuladd.f32") + fmuladd :: proc(a, b, c: f32) -> f32 ---; + @(link_name="llvm.fmuladd.f64") + fmuladd :: proc(a, b, c: f64) -> f64 ---; } -tan :: proc(θ: f32) -> f32 #inline do return sin(θ)/cos(θ); -tan :: proc(θ: f64) -> f64 #inline do return sin(θ)/cos(θ); +tan :: proc(θ: f32) -> f32 do return sin(θ)/cos(θ); +tan :: proc(θ: f64) -> f64 do return sin(θ)/cos(θ); lerp :: proc(a, b: $T, t: $E) -> (x: T) do return a*(1-t) + b*t; diff --git a/core/mem.odin b/core/mem.odin index 1c841a995..87e0d7740 100644 --- a/core/mem.odin +++ b/core/mem.odin @@ -1,9 +1,9 @@ import "core:raw.odin" foreign __llvm_core { - swap :: proc(b: u16) -> u16 #link_name "llvm.bswap.i16" ---; - swap :: proc(b: u32) -> u32 #link_name "llvm.bswap.i32" ---; - swap :: proc(b: u64) -> u64 #link_name "llvm.bswap.i64" ---; + @(link_name = "llvm.bswap.i16") swap :: proc(b: u16) -> u16 ---; + @(link_name = "llvm.bswap.i32") swap :: proc(b: u32) -> u32 ---; + @(link_name = "llvm.bswap.i64") swap :: proc(b: u64) -> u64 ---; } set :: proc(data: rawptr, value: i32, len: int) -> rawptr #cc_contextless { @@ -42,21 +42,21 @@ slice_to_bytes :: proc(slice: []$T) -> []u8 #cc_contextless { } -kilobytes :: proc(x: int) -> int #inline #cc_contextless { return (x) * 1024; } -megabytes :: proc(x: int) -> int #inline #cc_contextless { return kilobytes(x) * 1024; } -gigabytes :: proc(x: int) -> int #inline #cc_contextless { return megabytes(x) * 1024; } -terabytes :: proc(x: int) -> int #inline #cc_contextless { return gigabytes(x) * 1024; } +kilobytes :: inline proc(x: int) -> int #cc_contextless do return (x) * 1024; +megabytes :: inline proc(x: int) -> int #cc_contextless do return kilobytes(x) * 1024; +gigabytes :: inline proc(x: int) -> int #cc_contextless do return megabytes(x) * 1024; +terabytes :: inline proc(x: int) -> int #cc_contextless do return gigabytes(x) * 1024; -is_power_of_two :: proc(x: int) -> bool { +is_power_of_two :: proc(x: uintptr) -> bool { if x <= 0 do return false; return (x & (x-1)) == 0; } -align_forward :: proc(ptr: rawptr, align: int) -> rawptr { +align_forward :: proc(ptr: rawptr, align: uintptr) -> rawptr { assert(is_power_of_two(align)); - a := uint(align); - p := uint(ptr); + a := uintptr(align); + p := uintptr(ptr); modulo := p & (a-1); if modulo != 0 do p += a - modulo; return rawptr(p); @@ -150,7 +150,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, #no_bounds_check end := &arena.memory[len(arena.memory)]; - ptr := align_forward(end, alignment); + ptr := align_forward(end, uintptr(alignment)); (^raw.Slice)(&arena.memory).len += total_size; return zero(ptr, size); diff --git a/core/opengl.odin b/core/opengl.odin index 816c493d5..2ace5ddcc 100644 --- a/core/opengl.odin +++ b/core/opengl.odin @@ -11,35 +11,35 @@ export "core:opengl_constants.odin" _ := compile_assert(ODIN_OS != "osx"); foreign lib { - Clear :: proc(mask: u32) #link_name "glClear" ---; - ClearColor :: proc(r, g, b, a: f32) #link_name "glClearColor" ---; - Begin :: proc(mode: i32) #link_name "glBegin" ---; - End :: proc() #link_name "glEnd" ---; - Finish :: proc() #link_name "glFinish" ---; - BlendFunc :: proc(sfactor, dfactor: i32) #link_name "glBlendFunc" ---; - Enable :: proc(cap: i32) #link_name "glEnable" ---; - Disable :: proc(cap: i32) #link_name "glDisable" ---; - GenTextures :: proc(count: i32, result: ^u32) #link_name "glGenTextures" ---; - DeleteTextures :: proc(count: i32, result: ^u32) #link_name "glDeleteTextures"---; - TexParameteri :: proc(target, pname, param: i32) #link_name "glTexParameteri" ---; - TexParameterf :: proc(target: i32, pname: i32, param: f32) #link_name "glTexParameterf" ---; - BindTexture :: proc(target: i32, texture: u32) #link_name "glBindTexture" ---; - LoadIdentity :: proc() #link_name "glLoadIdentity" ---; - Viewport :: proc(x, y, width, height: i32) #link_name "glViewport" ---; - Ortho :: proc(left, right, bottom, top, near, far: f64) #link_name "glOrtho" ---; - Color3f :: proc(r, g, b: f32) #link_name "glColor3f" ---; - Vertex3f :: proc(x, y, z: f32) #link_name "glVertex3f" ---; - GetError :: proc() -> i32 #link_name "glGetError" ---; - GetString :: proc(name: i32) -> ^u8 #link_name "glGetString" ---; - GetIntegerv :: proc(name: i32, v: ^i32) #link_name "glGetIntegerv" ---; - TexCoord2f :: proc(x, y: f32) #link_name "glTexCoord2f" ---; - TexImage2D :: proc(target, level, internal_format, - width, height, border, - format, type_: i32, pixels: rawptr) #link_name "glTexImage2D" ---; + @(link_name="glClear") Clear :: proc(mask: u32) ---; + @(link_name="glClearColor") ClearColor :: proc(r, g, b, a: f32) ---; + @(link_name="glBegin") Begin :: proc(mode: i32) ---; + @(link_name="glEnd") End :: proc() ---; + @(link_name="glFinish") Finish :: proc() ---; + @(link_name="glBlendFunc") BlendFunc :: proc(sfactor, dfactor: i32) ---; + @(link_name="glEnable") Enable :: proc(cap: i32) ---; + @(link_name="glDisable") Disable :: proc(cap: i32) ---; + @(link_name="glGenTextures") GenTextures :: proc(count: i32, result: ^u32) ---; + @(link_name="glDeleteTextures") DeleteTextures :: proc(count: i32, result: ^u32) ---; + @(link_name="glTexParameteri") TexParameteri :: proc(target, pname, param: i32) ---; + @(link_name="glTexParameterf") TexParameterf :: proc(target: i32, pname: i32, param: f32) ---; + @(link_name="glBindTexture") BindTexture :: proc(target: i32, texture: u32) ---; + @(link_name="glLoadIdentity") LoadIdentity :: proc() ---; + @(link_name="glViewport") Viewport :: proc(x, y, width, height: i32) ---; + @(link_name="glOrtho") Ortho :: proc(left, right, bottom, top, near, far: f64) ---; + @(link_name="glColor3f") Color3f :: proc(r, g, b: f32) ---; + @(link_name="glVertex3f") Vertex3f :: proc(x, y, z: f32) ---; + @(link_name="glGetError") GetError :: proc() -> i32 ---; + @(link_name="glGetString") GetString :: proc(name: i32) -> ^u8 ---; + @(link_name="glGetIntegerv") GetIntegerv :: proc(name: i32, v: ^i32) ---; + @(link_name="glTexCoord2f") TexCoord2f :: proc(x, y: f32) ---; + @(link_name="glTexImage2D") TexImage2D :: proc(target, level, internal_format, + width, height, border, + format, type_: i32, pixels: rawptr) ---; } -_string_data :: proc(s: string) -> ^u8 #inline { return &s[0]; } +_string_data :: inline proc(s: string) -> ^u8 do return &s[0]; _libgl := win32.load_library_a(_string_data("opengl32.dll\x00")); @@ -119,7 +119,7 @@ get_proc_address :: proc(name: string) -> rawptr { init :: proc() { - set_proc_address :: proc(p: rawptr, name: string) #inline { + set_proc_address :: proc(p: rawptr, name: string) { x := cast(^rawptr)p; x^ = get_proc_address(name); } diff --git a/core/os_linux.odin b/core/os_linux.odin index d3af6e48d..fcc223197 100644 --- a/core/os_linux.odin +++ b/core/os_linux.odin @@ -108,13 +108,13 @@ S_ISGID :: 0002000; // Set group id on execution S_ISVTX :: 0001000; // Directory restrcted delete -S_ISLNK :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFLNK; } -S_ISREG :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFREG; } -S_ISDIR :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFDIR; } -S_ISCHR :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFCHR; } -S_ISBLK :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFBLK; } -S_ISFIFO :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFIFO; } -S_ISSOCK :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFSOCK;} +S_ISLNK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFLNK; +S_ISREG :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFREG; +S_ISDIR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFDIR; +S_ISCHR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFCHR; +S_ISBLK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFBLK; +S_ISFIFO :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFIFO; +S_ISSOCK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFSOCK; F_OK :: 0; // Test for file existance X_OK :: 1; // Test for execute permission @@ -122,28 +122,28 @@ W_OK :: 2; // Test for write permission R_OK :: 4; // Test for read permission foreign libc { - _unix_open :: proc(path: ^u8, mode: int) -> Handle #link_name "open" ---; - _unix_close :: proc(fd: Handle) -> i32 #link_name "close" ---; - _unix_read :: proc(fd: Handle, buf: rawptr, size: int) -> int #link_name "read" ---; - _unix_write :: proc(fd: Handle, buf: rawptr, size: int) -> int #link_name "write" ---; - _unix_seek :: proc(fd: Handle, offset: i64, whence: i32) -> i64 #link_name "lseek64" ---; - _unix_gettid :: proc() -> u64 #link_name "gettid" ---; - _unix_stat :: proc(path: ^u8, stat: ^Stat) -> i32 #link_name "stat" ---; - _unix_access :: proc(path: ^u8, mask: int) -> i32 #link_name "access" ---; + @(link_name="open") _unix_open :: proc(path: ^u8, mode: int) -> Handle ---; + @(link_name="close") _unix_close :: proc(fd: Handle) -> i32 ---; + @(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: int) -> int ---; + @(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: int) -> int ---; + @(link_name="lseek64") _unix_seek :: proc(fd: Handle, offset: i64, whence: i32) -> i64 ---; + @(link_name="gettid") _unix_gettid :: proc() -> u64 ---; + @(link_name="stat") _unix_stat :: proc(path: ^u8, stat: ^Stat) -> i32 ---; + @(link_name="access") _unix_access :: proc(path: ^u8, mask: int) -> i32 ---; - _unix_malloc :: proc(size: int) -> rawptr #link_name "malloc" ---; - _unix_calloc :: proc(num, size: int) -> rawptr #link_name "calloc" ---; - _unix_free :: proc(ptr: rawptr) #link_name "free" ---; - _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr #link_name "realloc" ---; - _unix_getenv :: proc(^u8) -> ^u8 #link_name "getenv" ---; + @(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr ---; + @(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr ---; + @(link_name="free") _unix_free :: proc(ptr: rawptr) ---; + @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr ---; + @(link_name="getenv") _unix_getenv :: proc(^u8) -> ^u8 ---; - _unix_exit :: proc(status: int) #link_name "exit" ---; + @(link_name="exit") _unix_exit :: proc(status: int) ---; } foreign dl { - _unix_dlopen :: proc(filename: ^u8, flags: int) -> rawptr #link_name "dlopen" ---; - _unix_dlsym :: proc(handle: rawptr, symbol: ^u8) -> (proc() #cc_c) #link_name "dlsym" ---; - _unix_dlclose :: proc(handle: rawptr) -> int #link_name "dlclose" ---; - _unix_dlerror :: proc() -> ^u8 #link_name "dlerror" ---; + @(link_name="dlopen") _unix_dlopen :: proc(filename: ^u8, flags: int) -> rawptr ---; + @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: ^u8) -> rawptr ---; + @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> int ---; + @(link_name="dlerror") _unix_dlerror :: proc() -> ^u8 ---; } // TODO(zangent): Change this to just `open` when Bill fixes overloading. @@ -200,7 +200,7 @@ last_write_time :: proc(fd: Handle) -> File_Time {} last_write_time_by_name :: proc(name: string) -> File_Time {} */ -stat :: proc(path: string) -> (Stat, int) #inline { +stat :: inline proc(path: string) -> (Stat, int) { s: Stat; cstr := strings.new_c_string(path); defer free(cstr); @@ -208,7 +208,7 @@ stat :: proc(path: string) -> (Stat, int) #inline { return s, int(ret_int); } -access :: proc(path: string, mask: int) -> bool #inline { +access :: inline proc(path: string, mask: int) -> bool { cstr := strings.new_c_string(path); defer free(cstr); return _unix_access(cstr, mask) == 0; @@ -246,20 +246,20 @@ current_thread_id :: proc() -> int { return 0; } -dlopen :: proc(filename: string, flags: int) -> rawptr #inline { +dlopen :: inline proc(filename: string, flags: int) -> rawptr { cstr := strings.new_c_string(filename); handle := _unix_dlopen(cstr, flags); free(cstr); return handle; } -dlsym :: proc(handle: rawptr, symbol: string) -> (proc() #cc_c) #inline { +dlsym :: inline proc(handle: rawptr, symbol: string) -> (proc() #cc_c) { assert(handle != nil); cstr := strings.new_c_string(symbol); proc_handle := _unix_dlsym(handle, cstr); free(cstr); return proc_handle; } -dlclose :: proc(handle: rawptr) -> bool #inline { +dlclose :: inline proc(handle: rawptr) -> bool { assert(handle != nil); return _unix_dlclose(handle) == 0; } diff --git a/core/os_windows.odin b/core/os_windows.odin index 9910a0b75..0f9e539c6 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -1,11 +1,11 @@ import win32 "core:sys/windows.odin" import "core:mem.odin" -Handle :: int; +Handle :: uintptr; File_Time :: u64; -INVALID_HANDLE: Handle : -1; +INVALID_HANDLE :: ~Handle(0); diff --git a/core/os_x.odin b/core/os_x.odin index eba27fff2..217f5c848 100644 --- a/core/os_x.odin +++ b/core/os_x.odin @@ -108,13 +108,13 @@ S_ISUID :: 0004000; // Set user id on execution S_ISGID :: 0002000; // Set group id on execution S_ISVTX :: 0001000; // Directory restrcted delete -S_ISLNK :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFLNK; -S_ISREG :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFREG; -S_ISDIR :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFDIR; -S_ISCHR :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFCHR; -S_ISBLK :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFBLK; -S_ISFIFO :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFIFO; -S_ISSOCK :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFSOCK; +S_ISLNK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFLNK; +S_ISREG :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFREG; +S_ISDIR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFDIR; +S_ISCHR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFCHR; +S_ISBLK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFBLK; +S_ISFIFO :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFIFO; +S_ISSOCK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFSOCK; R_OK :: 4; // Test for read permission W_OK :: 2; // Test for write permission @@ -122,29 +122,29 @@ X_OK :: 1; // Test for execute permission F_OK :: 0; // Test for file existance foreign libc { - _unix_open :: proc(path: ^u8, mode: int) -> Handle #link_name "open" ---; - _unix_close :: proc(handle: Handle) #link_name "close" ---; - _unix_read :: proc(handle: Handle, buffer: rawptr, count: int) -> int #link_name "read" ---; - _unix_write :: proc(handle: Handle, buffer: rawptr, count: int) -> int #link_name "write" ---; - _unix_lseek :: proc(fs: Handle, offset: int, whence: int) -> int #link_name "lseek" ---; - _unix_gettid :: proc() -> u64 #link_name "gettid" ---; - _unix_stat :: proc(path: ^u8, stat: ^Stat) -> int #link_name "stat" ---; - _unix_access :: proc(path: ^u8, mask: int) -> int #link_name "access" ---; + @(link_name="open") _unix_open :: proc(path: ^u8, mode: int) -> Handle ---; + @(link_name="close") _unix_close :: proc(handle: Handle) ---; + @(link_name="read") _unix_read :: proc(handle: Handle, buffer: rawptr, count: int) -> int ---; + @(link_name="write") _unix_write :: proc(handle: Handle, buffer: rawptr, count: int) -> int ---; + @(link_name="lseek") _unix_lseek :: proc(fs: Handle, offset: int, whence: int) -> int ---; + @(link_name="gettid") _unix_gettid :: proc() -> u64 ---; + @(link_name="stat") _unix_stat :: proc(path: ^u8, stat: ^Stat) -> int ---; + @(link_name="access") _unix_access :: proc(path: ^u8, mask: int) -> int ---; - _unix_malloc :: proc(size: int) -> rawptr #link_name "malloc" ---; - _unix_calloc :: proc(num, size: int) -> rawptr #link_name "calloc" ---; - _unix_free :: proc(ptr: rawptr) #link_name "free" ---; - _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr #link_name "realloc" ---; - _unix_getenv :: proc(^u8) -> ^u8 #link_name "getenv" ---; + @(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr ---; + @(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr ---; + @(link_name="free") _unix_free :: proc(ptr: rawptr) ---; + @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr ---; + @(link_name="getenv") _unix_getenv :: proc(^u8) -> ^u8 ---; - _unix_exit :: proc(status: int) #link_name "exit" ---; + @(link_name="exit") _unix_exit :: proc(status: int) ---; } foreign dl { - _unix_dlopen :: proc(filename: ^u8, flags: int) -> rawptr #link_name "dlopen" ---; - _unix_dlsym :: proc(handle: rawptr, symbol: ^u8) -> (proc() #cc_c) #link_name "dlsym" ---; - _unix_dlclose :: proc(handle: rawptr) -> int #link_name "dlclose" ---; - _unix_dlerror :: proc() -> ^u8 #link_name "dlerror" ---; + @(link_name="dlopen") _unix_dlopen :: proc(filename: ^u8, flags: int) -> rawptr ---; + @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: ^u8) -> (proc() #cc_c) ---; + @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> int ---; + @(link_name="dlerror") _unix_dlerror :: proc() -> ^u8 ---; } // TODO(zangent): Change this to just `open` when Bill fixes overloading. @@ -217,7 +217,7 @@ last_write_time :: proc(fd: Handle) -> File_Time {} last_write_time_by_name :: proc(name: string) -> File_Time {} */ -stat :: proc(path: string) -> (Stat, bool) #inline { +stat :: inline proc(path: string) -> (Stat, bool) { s: Stat; cstr := strings.new_c_string(path); defer free(cstr); @@ -225,20 +225,20 @@ stat :: proc(path: string) -> (Stat, bool) #inline { return s, ret_int==0; } -access :: proc(path: string, mask: int) -> bool #inline { +access :: inline proc(path: string, mask: int) -> bool { cstr := strings.new_c_string(path); defer free(cstr); return _unix_access(cstr, mask) == 0; } -heap_alloc :: proc(size: int) -> rawptr #inline { +heap_alloc :: inline proc(size: int) -> rawptr { assert(size > 0); return _unix_calloc(1, size); } -heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr #inline { +heap_resize :: inline proc(ptr: rawptr, new_size: int) -> rawptr { return _unix_realloc(ptr, new_size); } -heap_free :: proc(ptr: rawptr) #inline { +heap_free :: inline proc(ptr: rawptr) { _unix_free(ptr); } @@ -252,7 +252,7 @@ getenv :: proc(name: string) -> (string, bool) { return strings.to_odin_string(cstr), true; } -exit :: proc(code: int) #inline { +exit :: inline proc(code: int) { _unix_exit(code); } @@ -262,20 +262,20 @@ current_thread_id :: proc() -> int { return 0; } -dlopen :: proc(filename: string, flags: int) -> rawptr #inline { +dlopen :: inline proc(filename: string, flags: int) -> rawptr { cstr := strings.new_c_string(filename); handle := _unix_dlopen(cstr, flags); free(cstr); return handle; } -dlsym :: proc(handle: rawptr, symbol: string) -> (proc() #cc_c) #inline { +dlsym :: inline proc(handle: rawptr, symbol: string) -> (proc() #cc_c) { assert(handle != nil); cstr := strings.new_c_string(symbol); proc_handle := _unix_dlsym(handle, cstr); free(cstr); return proc_handle; } -dlclose :: proc(handle: rawptr) -> bool #inline { +dlclose :: inline proc(handle: rawptr) -> bool { assert(handle != nil); return _unix_dlclose(handle) == 0; } diff --git a/core/sync_linux.odin b/core/sync_linux.odin index 74f5cdc21..b77d51e0a 100644 --- a/core/sync_linux.odin +++ b/core/sync_linux.odin @@ -28,7 +28,7 @@ semaphore_post :: proc(s: ^Semaphore, count: int) { // win32.ReleaseSemaphore(s._handle, cast(i32)count, nil); } -semaphore_release :: proc(s: ^Semaphore) #inline { +semaphore_release :: inline proc(s: ^Semaphore) { semaphore_post(s, 1); } diff --git a/core/sync_windows.odin b/core/sync_windows.odin index 22d441b66..d07687b06 100644 --- a/core/sync_windows.odin +++ b/core/sync_windows.odin @@ -36,7 +36,9 @@ semaphore_post :: proc(s: ^Semaphore, count: int) { win32.release_semaphore(s._handle, i32(count), nil); } -semaphore_release :: proc(s: ^Semaphore) #inline { semaphore_post(s, 1); } +semaphore_release :: inline proc(s: ^Semaphore) { + semaphore_post(s, 1); +} semaphore_wait :: proc(s: ^Semaphore) { win32.wait_for_single_object(s._handle, win32.INFINITE); diff --git a/core/sys/wgl.odin b/core/sys/wgl.odin index deb2b0925..76e7eb1ae 100644 --- a/core/sys/wgl.odin +++ b/core/sys/wgl.odin @@ -66,20 +66,51 @@ Get_Extensions_String_ARB_Type :: #type proc(Hdc) -> ^u8 #cc_c; foreign opengl32 { - create_context :: proc(hdc: Hdc) -> Hglrc #link_name "wglCreateContext" ---; - make_current :: proc(hdc: Hdc, hglrc: Hglrc) -> Bool #link_name "wglMakeCurrent" ---; - get_proc_address :: proc(c_str: ^u8) -> rawptr #link_name "wglGetProcAddress" ---; - delete_context :: proc(hglrc: Hglrc) -> Bool #link_name "wglDeleteContext" ---; - copy_context :: proc(src, dst: Hglrc, mask: u32) -> Bool #link_name "wglCopyContext" ---; - create_layer_context :: proc(hdc: Hdc, layer_plane: i32) -> Hglrc #link_name "wglCreateLayerContext" ---; - describe_layer_plane :: proc(hdc: Hdc, pixel_format, layer_plane: i32, bytes: u32, pd: ^Layer_Plane_Descriptor) -> Bool #link_name "wglDescribeLayerPlane" ---; - get_current_context :: proc() -> Hglrc #link_name "wglGetCurrentContext" ---; - get_current_dc :: proc() -> Hdc #link_name "wglGetCurrentDC" ---; - get_layer_palette_entries :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^Color_Ref) -> i32 #link_name "wglGetLayerPaletteEntries" ---; - realize_layer_palette :: proc(hdc: Hdc, layer_plane: i32, realize: Bool) -> Bool #link_name "wglRealizeLayerPalette" ---; - set_layer_palette_entries :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^Color_Ref) -> i32 #link_name "wglSetLayerPaletteEntries" ---; - share_lists :: proc(hglrc1, hglrc2: Hglrc) -> Bool #link_name "wglShareLists" ---; - swap_layer_buffers :: proc(hdc: Hdc, planes: u32) -> Bool #link_name "wglSwapLayerBuffers" ---; - use_font_bitmaps :: proc(hdc: Hdc, first, count, list_base: u32) -> Bool #link_name "wglUseFontBitmaps" ---; - use_font_outlines :: proc(hdc: Hdc, first, count, list_base: u32, deviation, extrusion: f32, format: i32, gmf: ^Glyph_Metrics_Float) -> Bool #link_name "wglUseFontOutlines" ---; + @(link_name="wglCreateContext") + create_context :: proc(hdc: Hdc) -> Hglrc ---; + + @(link_name="wglMakeCurrent") + make_current :: proc(hdc: Hdc, hglrc: Hglrc) -> Bool ---; + + @(link_name="wglGetProcAddress") + get_proc_address :: proc(c_str: ^u8) -> rawptr ---; + + @(link_name="wglDeleteContext") + delete_context :: proc(hglrc: Hglrc) -> Bool ---; + + @(link_name="wglCopyContext") + copy_context :: proc(src, dst: Hglrc, mask: u32) -> Bool ---; + + @(link_name="wglCreateLayerContext") + create_layer_context :: proc(hdc: Hdc, layer_plane: i32) -> Hglrc ---; + + @(link_name="wglDescribeLayerPlane") + describe_layer_plane :: proc(hdc: Hdc, pixel_format, layer_plane: i32, bytes: u32, pd: ^Layer_Plane_Descriptor) -> Bool ---; + + @(link_name="wglGetCurrentContext") + get_current_context :: proc() -> Hglrc ---; + + @(link_name="wglGetCurrentDC") + get_current_dc :: proc() -> Hdc ---; + + @(link_name="wglGetLayerPaletteEntries") + get_layer_palette_entries :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^Color_Ref) -> i32 ---; + + @(link_name="wglRealizeLayerPalette") + realize_layer_palette :: proc(hdc: Hdc, layer_plane: i32, realize: Bool) -> Bool ---; + + @(link_name="wglSetLayerPaletteEntries") + set_layer_palette_entries :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^Color_Ref) -> i32 ---; + + @(link_name="wglShareLists") + share_lists :: proc(hglrc1, hglrc2: Hglrc) -> Bool ---; + + @(link_name="wglSwapLayerBuffers") + swap_layer_buffers :: proc(hdc: Hdc, planes: u32) -> Bool ---; + + @(link_name="wglUseFontBitmaps") + use_font_bitmaps :: proc(hdc: Hdc, first, count, list_base: u32) -> Bool ---; + + @(link_name="wglUseFontOutlines") + use_font_outlines :: proc(hdc: Hdc, first, count, list_base: u32, deviation, extrusion: f32, format: i32, gmf: ^Glyph_Metrics_Float) -> Bool ---; } diff --git a/core/sys/windows.odin b/core/sys/windows.odin index 1f4751029..0d29fbf42 100644 --- a/core/sys/windows.odin +++ b/core/sys/windows.odin @@ -22,7 +22,7 @@ HKL :: Handle; Wparam :: uint; Lparam :: int; Lresult :: int; -Wnd_Proc :: proc(Hwnd, u32, Wparam, Lparam) -> Lresult #cc_c; +Wnd_Proc :: #type proc(Hwnd, u32, Wparam, Lparam) -> Lresult #cc_c; Long_Ptr :: int; @@ -246,7 +246,7 @@ MAPVK_VSC_TO_VK_EX :: 3; -INVALID_HANDLE :: Handle(~int(0)); +INVALID_HANDLE :: Handle(~uintptr(0)); CREATE_SUSPENDED :: 0x00000004; STACK_SIZE_PARAM_IS_A_RESERVATION :: 0x00010000; @@ -317,7 +317,7 @@ SM_CYSCREEN :: 1; SW_SHOW :: 5; -COLOR_BACKGROUND :: Hbrush(int(1)); +COLOR_BACKGROUND :: Hbrush(uintptr(1)); INVALID_SET_FILE_POINTER :: ~u32(0); HEAP_ZERO_MEMORY :: 0x00000008; @@ -328,7 +328,7 @@ GWLP_ID :: -12; GWL_STYLE :: -16; GWLP_USERDATA :: -21; GWLP_WNDPROC :: -4; -Hwnd_TOP :: Hwnd(uint(0)); +Hwnd_TOP :: Hwnd(uintptr(0)); BI_RGB :: 0; DIB_RGB_COLORS :: 0x00; @@ -433,210 +433,217 @@ GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1; foreign kernel32 { - get_last_error :: proc() -> i32 #cc_std #link_name "GetLastError" ---; - exit_process :: proc(exit_code: u32) #cc_std #link_name "ExitProcess" ---; - get_module_handle_a :: proc(module_name: ^u8) -> Hinstance #cc_std #link_name "GetModuleHandleA" ---; - get_module_handle_w :: proc(module_name: ^u16) -> Hinstance #cc_std #link_name "GetModuleHandleW" ---; - sleep :: proc(ms: i32) -> i32 #cc_std #link_name "Sleep" ---; - query_performance_frequency :: proc(result: ^i64) -> i32 #cc_std #link_name "QueryPerformanceFrequency" ---; - query_performance_counter :: proc(result: ^i64) -> i32 #cc_std #link_name "QueryPerformanceCounter" ---; - output_debug_string_a :: proc(c_str: ^u8) #cc_std #link_name "OutputDebugStringA" ---; + @(link_name="GetLastError") get_last_error :: proc() -> i32 #cc_std ---; + @(link_name="ExitProcess") exit_process :: proc(exit_code: u32) #cc_std ---; + @(link_name="GetModuleHandleA") get_module_handle_a :: proc(module_name: ^u8) -> Hinstance #cc_std ---; + @(link_name="GetModuleHandleW") get_module_handle_w :: proc(module_name: ^u16) -> Hinstance #cc_std ---; + @(link_name="Sleep") sleep :: proc(ms: i32) -> i32 #cc_std ---; + @(link_name="QueryPerformanceFrequency") query_performance_frequency :: proc(result: ^i64) -> i32 #cc_std ---; + @(link_name="QueryPerformanceCounter") query_performance_counter :: proc(result: ^i64) -> i32 #cc_std ---; + @(link_name="OutputDebugStringA") output_debug_string_a :: proc(c_str: ^u8) #cc_std ---; - get_command_line_a :: proc() -> ^u8 #cc_std #link_name "GetCommandLineA" ---; - get_command_line_w :: proc() -> ^u16 #cc_std #link_name "GetCommandLineW" ---; - get_system_metrics :: proc(index: i32) -> i32 #cc_std #link_name "GetSystemMetrics" ---; - get_current_thread_id :: proc() -> u32 #cc_std #link_name "GetCurrentThreadId" ---; + @(link_name="GetCommandLineA") get_command_line_a :: proc() -> ^u8 #cc_std ---; + @(link_name="GetCommandLineW") get_command_line_w :: proc() -> ^u16 #cc_std ---; + @(link_name="GetSystemMetrics") get_system_metrics :: proc(index: i32) -> i32 #cc_std ---; + @(link_name="GetCurrentThreadId") get_current_thread_id :: proc() -> u32 #cc_std ---; - get_system_time_as_file_time :: proc(system_time_as_file_time: ^Filetime) #cc_std #link_name "GetSystemTimeAsFileTime" ---; - file_time_to_local_file_time :: proc(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool #cc_std #link_name "FileTimeToLocalFileTime" ---; - file_time_to_system_time :: proc(file_time: ^Filetime, system_time: ^Systemtime) -> Bool #cc_std #link_name "FileTimeToSystemTime" ---; - system_time_to_file_time :: proc(system_time: ^Systemtime, file_time: ^Filetime) -> Bool #cc_std #link_name "SystemTimeToFileTime" ---; + @(link_name="GetSystemTimeAsFileTime") get_system_time_as_file_time :: proc(system_time_as_file_time: ^Filetime) #cc_std ---; + @(link_name="FileTimeToLocalFileTime") file_time_to_local_file_time :: proc(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool #cc_std ---; + @(link_name="FileTimeToSystemTime") file_time_to_system_time :: proc(file_time: ^Filetime, system_time: ^Systemtime) -> Bool #cc_std ---; + @(link_name="SystemTimeToFileTime") system_time_to_file_time :: proc(system_time: ^Systemtime, file_time: ^Filetime) -> Bool #cc_std ---; - close_handle :: proc(h: Handle) -> i32 #cc_std #link_name "CloseHandle" ---; - get_std_handle :: proc(h: i32) -> Handle #cc_std #link_name "GetStdHandle" ---; - create_file_a :: proc(filename: ^u8, desired_access, share_mode: u32, - security: rawptr, - creation, flags_and_attribs: u32, template_file: Handle) -> Handle #cc_std #link_name "CreateFileA" ---; - read_file :: proc(h: Handle, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> Bool #cc_std #link_name "ReadFile" ---; - write_file :: proc(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool #cc_std #link_name "WriteFile" ---; + @(link_name="CloseHandle") close_handle :: proc(h: Handle) -> i32 #cc_std ---; + @(link_name="GetStdHandle") get_std_handle :: proc(h: i32) -> Handle #cc_std ---; - get_file_size_ex :: proc(file_handle: Handle, file_size: ^i64) -> Bool #cc_std #link_name "GetFileSizeEx" ---; - get_file_attributes_a :: proc(filename: ^u8) -> u32 #cc_std #link_name "GetFileAttributesA" ---; - get_file_attributes_ex_a :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool #cc_std #link_name "GetFileAttributesExA" ---; - get_file_information_by_handle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool #cc_std #link_name "GetFileInformationByHandle" ---; + @(link_name="CreateFileA") + create_file_a :: proc(filename: ^u8, desired_access, share_mode: u32, + security: rawptr, + creation, flags_and_attribs: u32, template_file: Handle) -> Handle #cc_std ---; - get_file_type :: proc(file_handle: Handle) -> u32 #cc_std #link_name "GetFileType" ---; - set_file_pointer :: proc(file_handle: Handle, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #cc_std #link_name "SetFilePointer" ---; + @(link_name="ReadFile") read_file :: proc(h: Handle, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> Bool #cc_std ---; + @(link_name="WriteFile") write_file :: proc(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool #cc_std ---; - set_handle_information :: proc(obj: Handle, mask, flags: u32) -> Bool #cc_std #link_name "SetHandleInformation" ---; + @(link_name="GetFileSizeEx") get_file_size_ex :: proc(file_handle: Handle, file_size: ^i64) -> Bool #cc_std ---; + @(link_name="GetFileAttributesA") get_file_attributes_a :: proc(filename: ^u8) -> u32 #cc_std ---; + @(link_name="GetFileAttributesExA") get_file_attributes_ex_a :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool #cc_std ---; + @(link_name="GetFileInformationByHandle") get_file_information_by_handle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool #cc_std ---; - find_first_file_a :: proc(file_name : ^u8, data : ^Find_Data) -> Handle #cc_std #link_name "FindFirstFileA" ---; - find_next_file_a :: proc(file : Handle, data : ^Find_Data) -> Bool #cc_std #link_name "FindNextFileA" ---; - find_close :: proc(file : Handle) -> Bool #cc_std #link_name "FindClose" ---; + @(link_name="GetFileType") get_file_type :: proc(file_handle: Handle) -> u32 #cc_std ---; + @(link_name="SetFilePointer") set_file_pointer :: proc(file_handle: Handle, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #cc_std ---; + + @(link_name="SetHandleInformation") set_handle_information :: proc(obj: Handle, mask, flags: u32) -> Bool #cc_std ---; + + @(link_name="FindFirstFileA") find_first_file_a :: proc(file_name : ^u8, data : ^Find_Data) -> Handle #cc_std ---; + @(link_name="FindNextFileA") find_next_file_a :: proc(file : Handle, data : ^Find_Data) -> Bool #cc_std ---; + @(link_name="FindClose") find_close :: proc(file : Handle) -> Bool #cc_std ---; - heap_alloc :: proc(h: Handle, flags: u32, bytes: int) -> rawptr #cc_std #link_name "HeapAlloc" ---; - heap_realloc :: proc(h: Handle, flags: u32, memory: rawptr, bytes: int) -> rawptr #cc_std #link_name "HeapReAlloc" ---; - heap_free :: proc(h: Handle, flags: u32, memory: rawptr) -> Bool #cc_std #link_name "HeapFree" ---; - get_process_heap :: proc() -> Handle #cc_std #link_name "GetProcessHeap" ---; + @(link_name="HeapAlloc") heap_alloc :: proc(h: Handle, flags: u32, bytes: int) -> rawptr #cc_std ---; + @(link_name="HeapReAlloc") heap_realloc :: proc(h: Handle, flags: u32, memory: rawptr, bytes: int) -> rawptr #cc_std ---; + @(link_name="HeapFree") heap_free :: proc(h: Handle, flags: u32, memory: rawptr) -> Bool #cc_std ---; + @(link_name="GetProcessHeap") get_process_heap :: proc() -> Handle #cc_std ---; - create_semaphore_a :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #cc_std #link_name "CreateSemaphoreA" ---; - release_semaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #cc_std #link_name "ReleaseSemaphore" ---; - wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32 #cc_std #link_name "WaitForSingleObject" ---; + @(link_name="CreateSemaphoreA") create_semaphore_a :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #cc_std ---; + @(link_name="ReleaseSemaphore") release_semaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #cc_std ---; + @(link_name="WaitForSingleObject") wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32 #cc_std ---; - interlocked_compare_exchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #cc_c #link_name "InterlockedCompareExchange" ---; - interlocked_exchange :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedExchange" ---; - interlocked_exchange_add :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedExchangeAdd" ---; - interlocked_and :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedAnd" ---; - interlocked_or :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedOr" ---; + @(link_name="InterlockedCompareExchange") interlocked_compare_exchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #cc_c ---; + @(link_name="InterlockedExchange") interlocked_exchange :: proc(dst: ^i32, desired: i32) -> i32 #cc_c ---; + @(link_name="InterlockedExchangeAdd") interlocked_exchange_add :: proc(dst: ^i32, desired: i32) -> i32 #cc_c ---; + @(link_name="InterlockedAnd") interlocked_and :: proc(dst: ^i32, desired: i32) -> i32 #cc_c ---; + @(link_name="InterlockedOr") interlocked_or :: proc(dst: ^i32, desired: i32) -> i32 #cc_c ---; - interlocked_compare_exchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64 #cc_c #link_name "InterlockedCompareExchange64" ---; - interlocked_exchange64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedExchange64" ---; - interlocked_exchange_add64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedExchangeAdd64" ---; - interlocked_and64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedAnd64" ---; - interlocked_or64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedOr64" ---; + @(link_name="InterlockedCompareExchange64") interlocked_compare_exchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64 #cc_c ---; + @(link_name="InterlockedExchange64") interlocked_exchange64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c ---; + @(link_name="InterlockedExchangeAdd64") interlocked_exchange_add64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c ---; + @(link_name="InterlockedAnd64") interlocked_and64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c ---; + @(link_name="InterlockedOr64") interlocked_or64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c ---; - mm_pause :: proc() #cc_std #link_name "_mm_pause" ---; - read_write_barrier :: proc() #cc_std #link_name "ReadWriteBarrier" ---; - write_barrier :: proc() #cc_std #link_name "WriteBarrier" ---; - read_barrier :: proc() #cc_std #link_name "ReadBarrier" ---; + @(link_name="_mm_pause") mm_pause :: proc() #cc_std ---; + @(link_name="ReadWriteBarrier") read_write_barrier :: proc() #cc_std ---; + @(link_name="WriteBarrier") write_barrier :: proc() #cc_std ---; + @(link_name="ReadBarrier") read_barrier :: proc() #cc_std ---; - create_thread :: proc(thread_attributes: ^Security_Attributes, stack_size: int, start_routine: rawptr, - parameter: rawptr, creation_flags: u32, thread_id: ^u32) -> Handle #cc_std #link_name "CreateThread" ---; - resume_thread :: proc(thread: Handle) -> u32 #cc_std #link_name "ResumeThread" ---; - get_thread_priority :: proc(thread: Handle) -> i32 #cc_std #link_name "GetThreadPriority" ---; - set_thread_priority :: proc(thread: Handle, priority: i32) -> Bool #cc_std #link_name "SetThreadPriority" ---; - get_exit_code_thread :: proc(thread: Handle, exit_code: ^u32) -> Bool #cc_std #link_name "GetExitCodeThread" ---; + @(link_name="CreateThread") + create_thread :: proc(thread_attributes: ^Security_Attributes, stack_size: int, start_routine: rawptr, + parameter: rawptr, creation_flags: u32, thread_id: ^u32) -> Handle #cc_std ---; + @(link_name="ResumeThread") resume_thread :: proc(thread: Handle) -> u32 #cc_std ---; + @(link_name="GetThreadPriority") get_thread_priority :: proc(thread: Handle) -> i32 #cc_std ---; + @(link_name="SetThreadPriority") set_thread_priority :: proc(thread: Handle, priority: i32) -> Bool #cc_std ---; + @(link_name="GetExitCodeThread") get_exit_code_thread :: proc(thread: Handle, exit_code: ^u32) -> Bool #cc_std ---; - initialize_critical_section :: proc(critical_section: ^Critical_Section) #cc_std #link_name "InitializeCriticalSection" ---; - initialize_critical_section_and_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) #cc_std #link_name "InitializeCriticalSectionAndSpinCount" ---; - delete_critical_section :: proc(critical_section: ^Critical_Section) #cc_std #link_name "DeleteCriticalSection" ---; - set_critical_section_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) -> u32 #cc_std #link_name "SetCriticalSectionSpinCount" ---; - try_enter_critical_section :: proc(critical_section: ^Critical_Section) -> Bool #cc_std #link_name "TryEnterCriticalSection" ---; - enter_critical_section :: proc(critical_section: ^Critical_Section) #cc_std #link_name "EnterCriticalSection" ---; - leave_critical_section :: proc(critical_section: ^Critical_Section) #cc_std #link_name "LeaveCriticalSection" ---; + @(link_name="InitializeCriticalSection") initialize_critical_section :: proc(critical_section: ^Critical_Section) #cc_std ---; + @(link_name="InitializeCriticalSectionAndSpinCount") initialize_critical_section_and_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) #cc_std ---; + @(link_name="DeleteCriticalSection") delete_critical_section :: proc(critical_section: ^Critical_Section) #cc_std ---; + @(link_name="SetCriticalSectionSpinCount") set_critical_section_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) -> u32 #cc_std ---; + @(link_name="TryEnterCriticalSection") try_enter_critical_section :: proc(critical_section: ^Critical_Section) -> Bool #cc_std ---; + @(link_name="EnterCriticalSection") enter_critical_section :: proc(critical_section: ^Critical_Section) #cc_std ---; + @(link_name="LeaveCriticalSection") leave_critical_section :: proc(critical_section: ^Critical_Section) #cc_std ---; - create_event_a :: proc(event_attributes: ^Security_Attributes, manual_reset, initial_state: Bool, name: ^u8) -> Handle #cc_std #link_name "CreateEventA" ---; + @(link_name="CreateEventA") create_event_a :: proc(event_attributes: ^Security_Attributes, manual_reset, initial_state: Bool, name: ^u8) -> Handle #cc_std ---; - load_library_a :: proc(c_str: ^u8) -> Hmodule #cc_std #link_name "LoadLibraryA" ---; - free_library :: proc(h: Hmodule) #cc_std #link_name "FreeLibrary" ---; - get_proc_address :: proc(h: Hmodule, c_str: ^u8) -> rawptr #cc_std #link_name "GetProcAddress" ---; + @(link_name="LoadLibraryA") load_library_a :: proc(c_str: ^u8) -> Hmodule #cc_std ---; + @(link_name="LoadLibraryW") load_library_a :: proc(c_str: ^u16) -> Hmodule #cc_std ---; + @(link_name="FreeLibrary") free_library :: proc(h: Hmodule) #cc_std ---; + @(link_name="GetProcAddress") get_proc_address :: proc(h: Hmodule, c_str: ^u8) -> rawptr #cc_std ---; } foreign user32 { - get_desktop_window :: proc() -> Hwnd #cc_std #link_name "GetDesktopWindow" ---; - show_cursor :: proc(show : Bool) #cc_std #link_name "ShowCursor" ---; - get_cursor_pos :: proc(p: ^Point) -> Bool #cc_std #link_name "GetCursorPos" ---; - set_cursor_pos :: proc(x, y: i32) -> Bool #cc_std #link_name "SetCursorPos" ---; - screen_to_client :: proc(h: Hwnd, p: ^Point) -> Bool #cc_std #link_name "ScreenToClient" ---; - client_to_screen :: proc(h: Hwnd, p: ^Point) -> Bool #cc_std #link_name "ClientToScreen" ---; - post_quit_message :: proc(exit_code: i32) #cc_std #link_name "PostQuitMessage" ---; - set_window_text_a :: proc(hwnd: Hwnd, c_string: ^u8) -> Bool #cc_std #link_name "SetWindowTextA" ---; - register_class_ex_a :: proc(wc: ^Wnd_Class_Ex_A) -> i16 #cc_std #link_name "RegisterClassExA" ---; - register_class_ex_w :: proc(wc: ^Wnd_Class_Ex_W) -> i16 #cc_std #link_name "RegisterClassExW" ---; + @(link_name="GetDesktopWindow") get_desktop_window :: proc() -> Hwnd #cc_std ---; + @(link_name="ShowCursor") show_cursor :: proc(show : Bool) #cc_std ---; + @(link_name="GetCursorPos") get_cursor_pos :: proc(p: ^Point) -> Bool #cc_std ---; + @(link_name="SetCursorPos") set_cursor_pos :: proc(x, y: i32) -> Bool #cc_std ---; + @(link_name="ScreenToClient") screen_to_client :: proc(h: Hwnd, p: ^Point) -> Bool #cc_std ---; + @(link_name="ClientToScreen") client_to_screen :: proc(h: Hwnd, p: ^Point) -> Bool #cc_std ---; + @(link_name="PostQuitMessage") post_quit_message :: proc(exit_code: i32) #cc_std ---; + @(link_name="SetWindowTextA") set_window_text_a :: proc(hwnd: Hwnd, c_string: ^u8) -> Bool #cc_std ---; + @(link_name="RegisterClassExA") register_class_ex_a :: proc(wc: ^Wnd_Class_Ex_A) -> i16 #cc_std ---; + @(link_name="RegisterClassExW") register_class_ex_w :: proc(wc: ^Wnd_Class_Ex_W) -> i16 #cc_std ---; - create_window_ex_a :: proc(ex_style: u32, - class_name, title: ^u8, - style: u32, - x, y, w, h: i32, - parent: Hwnd, menu: Hmenu, instance: Hinstance, - param: rawptr) -> Hwnd #cc_std #link_name "CreateWindowExA" ---; + @(link_name="CreateWindowExA") + create_window_ex_a :: proc(ex_style: u32, + class_name, title: ^u8, + style: u32, + x, y, w, h: i32, + parent: Hwnd, menu: Hmenu, instance: Hinstance, + param: rawptr) -> Hwnd #cc_std ---; - create_window_ex_w :: proc(ex_style: u32, - class_name, title: ^u16, - style: u32, - x, y, w, h: i32, - parent: Hwnd, menu: Hmenu, instance: Hinstance, - param: rawptr) -> Hwnd #cc_std #link_name "CreateWindowExW" ---; + @(link_name="CreateWindowExW") + create_window_ex_w :: proc(ex_style: u32, + class_name, title: ^u16, + style: u32, + x, y, w, h: i32, + parent: Hwnd, menu: Hmenu, instance: Hinstance, + param: rawptr) -> Hwnd #cc_std ---; - show_window :: proc(hwnd: Hwnd, cmd_show: i32) -> Bool #cc_std #link_name "ShowWindow" ---; - translate_message :: proc(msg: ^Msg) -> Bool #cc_std #link_name "TranslateMessage" ---; - dispatch_message_a :: proc(msg: ^Msg) -> Lresult #cc_std #link_name "DispatchMessageA" ---; - dispatch_message_w :: proc(msg: ^Msg) -> Lresult #cc_std #link_name "DispatchMessageW" ---; - update_window :: proc(hwnd: Hwnd) -> Bool #cc_std #link_name "UpdateWindow" ---; - get_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #cc_std #link_name "GetMessageA" ---; - get_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #cc_std #link_name "GetMessageW" ---; - peek_message_a :: proc(msg: ^Msg, hwnd: Hwnd, - msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_std #link_name "PeekMessageA" ---; - peek_message_w :: proc(msg: ^Msg, hwnd: Hwnd, - msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_std #link_name "PeekMessageW" ---; + @(link_name="ShowWindow") show_window :: proc(hwnd: Hwnd, cmd_show: i32) -> Bool #cc_std ---; + @(link_name="TranslateMessage") translate_message :: proc(msg: ^Msg) -> Bool #cc_std ---; + @(link_name="DispatchMessageA") dispatch_message_a :: proc(msg: ^Msg) -> Lresult #cc_std ---; + @(link_name="DispatchMessageW") dispatch_message_w :: proc(msg: ^Msg) -> Lresult #cc_std ---; + @(link_name="UpdateWindow") update_window :: proc(hwnd: Hwnd) -> Bool #cc_std ---; + @(link_name="GetMessageA") get_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #cc_std ---; + @(link_name="GetMessageW") get_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #cc_std ---; + + @(link_name="PeekMessageA") peek_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_std ---; + @(link_name="PeekMessageW") peek_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_std ---; - post_message :: proc(hwnd: Hwnd, msg, wparam, lparam : u32) -> Bool #cc_std #link_name "PostMessageA" ---; + @(link_name="PostMessageA") post_message :: proc(hwnd: Hwnd, msg, wparam, lparam : u32) -> Bool #cc_std ---; - def_window_proc_a :: proc(hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult #cc_std #link_name "DefWindowProcA" ---; + @(link_name="DefWindowProcA") def_window_proc_a :: proc(hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult #cc_std ---; - adjust_window_rect :: proc(rect: ^Rect, style: u32, menu: Bool) -> Bool #cc_std #link_name "AdjustWindowRect" ---; - get_active_window :: proc() -> Hwnd #cc_std #link_name "GetActiveWindow" ---; + @(link_name="AdjustWindowRect") adjust_window_rect :: proc(rect: ^Rect, style: u32, menu: Bool) -> Bool #cc_std ---; + @(link_name="GetActiveWindow") get_active_window :: proc() -> Hwnd #cc_std ---; - destroy_window :: proc(wnd: Hwnd) -> Bool #cc_std #link_name "DestroyWindow" ---; - describe_pixel_format :: proc(dc: Hdc, pixel_format: i32, bytes: u32, pfd: ^Pixel_Format_Descriptor) -> i32 #cc_std #link_name "DescribePixelFormat" ---; + @(link_name="DestroyWindow") destroy_window :: proc(wnd: Hwnd) -> Bool #cc_std ---; + @(link_name="DescribePixelFormat") describe_pixel_format :: proc(dc: Hdc, pixel_format: i32, bytes: u32, pfd: ^Pixel_Format_Descriptor) -> i32 #cc_std ---; - get_monitor_info_a :: proc(monitor: Hmonitor, mi: ^Monitor_Info) -> Bool #cc_std #link_name "GetMonitor_InfoA" ---; - monitor_from_window :: proc(wnd: Hwnd, flags : u32) -> Hmonitor #cc_std #link_name "MonitorFromWindow" ---; + @(link_name="GetMonitor_InfoA") get_monitor_info_a :: proc(monitor: Hmonitor, mi: ^Monitor_Info) -> Bool #cc_std ---; + @(link_name="MonitorFromWindow") monitor_from_window :: proc(wnd: Hwnd, flags : u32) -> Hmonitor #cc_std ---; - set_window_pos :: proc(wnd: Hwnd, wndInsertAfter: Hwnd, x, y, width, height: i32, flags: u32) #cc_std #link_name "SetWindowPos" ---; + @(link_name="SetWindowPos") set_window_pos :: proc(wnd: Hwnd, wndInsertAfter: Hwnd, x, y, width, height: i32, flags: u32) #cc_std ---; - get_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #cc_std #link_name "GetWindowPlacement" ---; - set_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #cc_std #link_name "SetWindowPlacement" ---; - get_window_rect :: proc(wnd: Hwnd, rect: ^Rect) -> Bool #cc_std #link_name "GetWindowRect" ---; + @(link_name="GetWindowPlacement") get_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #cc_std ---; + @(link_name="SetWindowPlacement") set_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #cc_std ---; + @(link_name="GetWindowRect") get_window_rect :: proc(wnd: Hwnd, rect: ^Rect) -> Bool #cc_std ---; - get_window_long_ptr_a :: proc(wnd: Hwnd, index: i32) -> Long_Ptr #cc_std #link_name "GetWindowLongPtrA" ---; - set_window_long_ptr_a :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr #cc_std #link_name "SetWindowLongPtrA" ---; - get_window_long_ptr_w :: proc(wnd: Hwnd, index: i32) -> Long_Ptr #cc_std #link_name "GetWindowLongPtrW" ---; - set_window_long_ptr_w :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr #cc_std #link_name "SetWindowLongPtrW" ---; + @(link_name="GetWindowLongPtrA") get_window_long_ptr_a :: proc(wnd: Hwnd, index: i32) -> Long_Ptr #cc_std ---; + @(link_name="SetWindowLongPtrA") set_window_long_ptr_a :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr #cc_std ---; + @(link_name="GetWindowLongPtrW") get_window_long_ptr_w :: proc(wnd: Hwnd, index: i32) -> Long_Ptr #cc_std ---; + @(link_name="SetWindowLongPtrW") set_window_long_ptr_w :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr #cc_std ---; - get_window_text :: proc(wnd: Hwnd, str: ^u8, maxCount: i32) -> i32 #cc_std #link_name "GetWindowText" ---; + @(link_name="GetWindowText") get_window_text :: proc(wnd: Hwnd, str: ^u8, maxCount: i32) -> i32 #cc_std ---; - get_client_rect :: proc(hwnd: Hwnd, rect: ^Rect) -> Bool #cc_std #link_name "GetClientRect" ---; + @(link_name="GetClientRect") get_client_rect :: proc(hwnd: Hwnd, rect: ^Rect) -> Bool #cc_std ---; - get_dc :: proc(h: Hwnd) -> Hdc #cc_std #link_name "GetDC" ---; - release_dc :: proc(wnd: Hwnd, hdc: Hdc) -> i32 #cc_std #link_name "ReleaseDC" ---; + @(link_name="GetDC") get_dc :: proc(h: Hwnd) -> Hdc #cc_std ---; + @(link_name="ReleaseDC") release_dc :: proc(wnd: Hwnd, hdc: Hdc) -> i32 #cc_std ---; - map_virtual_key_a :: proc(scancode : u32, map_type : u32) -> u32 #cc_std #link_name "MapVirtualKeyA" ---; - map_virtual_key_w :: proc(scancode : u32, map_type : u32) -> u32 #cc_std #link_name "MapVirtualKeyW" ---; + @(link_name="MapVirtualKeyA") map_virtual_key_a :: proc(scancode : u32, map_type : u32) -> u32 #cc_std ---; + @(link_name="MapVirtualKeyW") map_virtual_key_w :: proc(scancode : u32, map_type : u32) -> u32 #cc_std ---; - get_key_state :: proc(v_key: i32) -> i16 #cc_std #link_name "GetKeyState" ---; - get_async_key_state :: proc(v_key: i32) -> i16 #cc_std #link_name "GetAsyncKeyState" ---; + @(link_name="GetKeyState") get_key_state :: proc(v_key: i32) -> i16 #cc_std ---; + @(link_name="GetAsyncKeyState") get_async_key_state :: proc(v_key: i32) -> i16 #cc_std ---; - set_foreground_window :: proc(h: Hwnd) -> Bool #cc_std #link_name "SetForegroundWindow" ---; - set_focus :: proc(h: Hwnd) -> Hwnd #cc_std #link_name "SetFocus" ---; + @(link_name="SetForegroundWindow") set_foreground_window :: proc(h: Hwnd) -> Bool #cc_std ---; + @(link_name="SetFocus") set_focus :: proc(h: Hwnd) -> Hwnd #cc_std ---; - register_raw_input_devices :: proc(raw_input_device: ^Raw_Input_Device, num_devices, size: u32) -> Bool #cc_std #link_name "RegisterRawInputDevices" ---; + @(link_name="RegisterRawInputDevices") register_raw_input_devices :: proc(raw_input_device: ^Raw_Input_Device, num_devices, size: u32) -> Bool #cc_std ---; - get_raw_input_data :: proc(raw_input: Hrawinput, command: u32, data: rawptr, size: ^u32, size_header: u32) -> u32 #cc_std #link_name "GetRawInputData" ---; + @(link_name="GetRawInputData") get_raw_input_data :: proc(raw_input: Hrawinput, command: u32, data: rawptr, size: ^u32, size_header: u32) -> u32 #cc_std ---; - map_virtual_key_ex_w :: proc(code, map_type: u32, hkl: HKL) #cc_std #link_name "MapVirtualKeyExW" ---; - map_virtual_key_ex_a :: proc(code, map_type: u32, hkl: HKL) #cc_std #link_name "MapVirtualKeyExA" ---; + @(link_name="MapVirtualKeyExW") map_virtual_key_ex_w :: proc(code, map_type: u32, hkl: HKL) #cc_std ---; + @(link_name="MapVirtualKeyExA") map_virtual_key_ex_a :: proc(code, map_type: u32, hkl: HKL) #cc_std ---; } foreign gdi32 { - get_stock_object :: proc(fn_object: i32) -> Hgdiobj #cc_std #link_name "GetStockObject" ---; + @(link_name="GetStockObject") get_stock_object :: proc(fn_object: i32) -> Hgdiobj #cc_std ---; - stretch_dibits :: proc(hdc: Hdc, - x_dst, y_dst, width_dst, height_dst: i32, - x_src, y_src, width_src, header_src: i32, - bits: rawptr, bits_info: ^Bitmap_Info, - usage: u32, - rop: u32) -> i32 #cc_std #link_name "StretchDIBits" ---; + @(link_name="StretchDIBits") + stretch_dibits :: proc(hdc: Hdc, + x_dst, y_dst, width_dst, height_dst: i32, + x_src, y_src, width_src, header_src: i32, + bits: rawptr, bits_info: ^Bitmap_Info, + usage: u32, + rop: u32) -> i32 #cc_std ---; - set_pixel_format :: proc(hdc: Hdc, pixel_format: i32, pfd: ^Pixel_Format_Descriptor) -> Bool #cc_std #link_name "SetPixelFormat" ---; - choose_pixel_format :: proc(hdc: Hdc, pfd: ^Pixel_Format_Descriptor) -> i32 #cc_std #link_name "ChoosePixelFormat" ---; - swap_buffers :: proc(hdc: Hdc) -> Bool #cc_std #link_name "SwapBuffers" ---; + @(link_name="SetPixelFormat") set_pixel_format :: proc(hdc: Hdc, pixel_format: i32, pfd: ^Pixel_Format_Descriptor) -> Bool #cc_std ---; + @(link_name="ChoosePixelFormat") choose_pixel_format :: proc(hdc: Hdc, pfd: ^Pixel_Format_Descriptor) -> i32 #cc_std ---; + @(link_name="SwapBuffers") swap_buffers :: proc(hdc: Hdc) -> Bool #cc_std ---; } foreign shell32 { - command_line_to_argv_w :: proc(cmd_list: ^u16, num_args: ^i32) -> ^^u16 #cc_std #link_name "CommandLineToArgvW" ---; + @(link_name="CommandLineToArgvW") command_line_to_argv_w :: proc(cmd_list: ^u16, num_args: ^i32) -> ^^u16 #cc_std ---; } foreign winmm { - time_get_time :: proc() -> u32 #cc_std #link_name "timeGetTime" ---; + @(link_name="timeGetTime") time_get_time :: proc() -> u32 #cc_std ---; } @@ -652,7 +659,7 @@ 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); } -is_key_down :: proc(key: Key_Code) -> bool #inline { return get_async_key_state(i32(key)) < 0; } +is_key_down :: inline proc(key: Key_Code) -> bool do return get_async_key_state(i32(key)) < 0; diff --git a/core/utf8.odin b/core/utf8.odin index 95a340cad..aea10514f 100644 --- a/core/utf8.odin +++ b/core/utf8.odin @@ -92,7 +92,7 @@ encode_rune :: proc(r: rune) -> ([4]u8, int) { return buf, 4; } -decode_rune :: proc(s: string) -> (rune, int) #inline { return decode_rune(cast([]u8)s); } +decode_rune :: inline proc(s: string) -> (rune, int) do return decode_rune(cast([]u8)s); decode_rune :: proc(s: []u8) -> (rune, int) { n := len(s); if n < 1 { @@ -132,7 +132,7 @@ decode_rune :: proc(s: []u8) -> (rune, int) { -decode_last_rune :: proc(s: string) -> (rune, int) #inline { return decode_last_rune(cast([]u8)s); } +decode_last_rune :: inline proc(s: string) -> (rune, int) do return decode_last_rune(cast([]u8)s); decode_last_rune :: proc(s: []u8) -> (rune, int) { r: rune; size: int; @@ -211,9 +211,9 @@ valid_string :: proc(s: string) -> bool { return true; } -rune_start :: proc(b: u8) -> bool #inline { return b&0xc0 != 0x80; } +rune_start :: inline proc(b: u8) -> bool do return b&0xc0 != 0x80; -rune_count :: proc(s: string) -> int #inline { return rune_count(cast([]u8)s); } +rune_count :: inline proc(s: string) -> int do return rune_count(cast([]u8)s); rune_count :: proc(s: []u8) -> int { count := 0; n := len(s); diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 0baf43349..1361ac31c 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -187,8 +187,13 @@ AstNode *remove_type_alias(AstNode *node) { void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool is_alias) { GB_ASSERT(e->type == nullptr); - AstNode *te = remove_type_alias(type_expr); + DeclInfo *decl = decl_info_of_entity(&c->info, e); + if (decl != nullptr && decl->attributes.count > 0) { + error(decl->attributes[0], "Attributes are not allowed on type declarations"); + } + + AstNode *te = remove_type_alias(type_expr); e->type = t_invalid; String name = e->token.string; Type *named = make_type_named(c->allocator, name, nullptr, e); @@ -203,8 +208,11 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool if (is_alias) { if (is_type_named(bt)) { e->type = bt; + e->TypeName.is_type_alias = true; } else { - warning(type_expr, "Type declaration will not be an alias type"); + gbString str = type_to_string(bt); + error(type_expr, "Type alias declaration with a non-named type `%s`", str); + gb_string_free(str); } } } @@ -319,6 +327,12 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init, error(e->token, "Invalid declaration type `%s`", str); gb_string_free(str); } + + + DeclInfo *decl = decl_info_of_entity(&c->info, e); + if (decl != nullptr && decl->attributes.count > 0) { + error(decl->attributes[0], "Attributes are not allowed on constant value declarations"); + } } @@ -436,8 +450,6 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) { defer (check_close_scope(c)); - - auto prev_context = c->context; c->context.allow_polymorphic_types = true; check_procedure_type(c, proc_type, pl->type); @@ -447,11 +459,65 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) { bool is_foreign = e->Procedure.is_foreign; bool is_export = e->Procedure.is_export; - bool is_link_name = (pl->tags & ProcTag_link_name) != 0; bool is_inline = (pl->tags & ProcTag_inline) != 0; bool is_no_inline = (pl->tags & ProcTag_no_inline) != 0; bool is_require_results = (pl->tags & ProcTag_require_results) != 0; + String link_name = {}; + + + if (d != nullptr && d->attributes.count > 0) { + for_array(i, d->attributes) { + AstNode *attr = d->attributes[i]; + if (attr->kind != AstNode_Attribute) continue; + for_array(j, attr->Attribute.elems) { + AstNode *elem = attr->Attribute.elems[j]; + String name = {}; + AstNode *value = nullptr; + + switch (elem->kind) { + case_ast_node(i, Ident, elem); + name = i->token.string; + case_end; + case_ast_node(fv, FieldValue, elem); + GB_ASSERT(fv->field->kind == AstNode_Ident); + name = fv->field->Ident.token.string; + value = fv->value; + case_end; + default: + error(elem, "Invalid attribute element"); + continue; + } + + ExactValue ev = {}; + if (value != nullptr) { + Operand op = {}; + check_expr(c, &op, value); + if (op.mode != Addressing_Constant) { + error(value, "An attribute element must be constant"); + } else { + ev = op.value; + } + } + + if (name == "link_name") { + if (link_name.len > 0) { + error(elem, "Previous declaration of `link_name`"); + } + if (ev.kind == ExactValue_String) { + link_name = ev.value_string; + } else { + error(elem, "Expected a string value for `link_name`"); + } + } else { + error(elem, "Unknown attribute element name `%.*s`", LIT(name)); + } + } + } + } + + + if (d->scope->file != nullptr && e->token.string == "main") { @@ -526,8 +592,8 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) { if (is_foreign) { String name = e->token.string; - if (pl->link_name.len > 0) { - name = pl->link_name; + if (link_name.len > 0) { + name = link_name; } e->Procedure.is_foreign = true; e->Procedure.link_name = name; @@ -562,11 +628,11 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) { } } else { String name = e->token.string; - if (is_link_name) { - name = pl->link_name; + if (link_name.len > 0) { + name = link_name; } - if (is_link_name || is_export) { + if (link_name.len > 0 || is_export) { auto *fp = &c->info.foreigns; e->Procedure.link_name = name; @@ -600,6 +666,11 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count } e->flags |= EntityFlag_Visited; + DeclInfo *decl = decl_info_of_entity(&c->info, e); + if (decl != nullptr && decl->attributes.count > 0) { + error(decl->attributes[0], "Attributes are not allowed on variable declarations, yet"); + } + String context_name = str_lit("variable declaration"); if (type_expr != nullptr) { @@ -692,9 +763,11 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) { case Entity_Constant: check_const_decl(c, e, d->type_expr, d->init_expr, named_type); break; - case Entity_TypeName: - check_type_decl(c, e, d->type_expr, named_type, d->type_expr->kind == AstNode_AliasType); + case Entity_TypeName: { + bool is_alias = unparen_expr(d->type_expr)->kind == AstNode_AliasType; + check_type_decl(c, e, d->type_expr, named_type, is_alias); break; + } case Entity_Procedure: check_proc_decl(c, e, d); break; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 2f3bc4fdf..02c4fbf64 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1238,6 +1238,7 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type case Basic_u64: case Basic_u128: case Basic_uint: + case Basic_uintptr: return !(u128_lt(u, U128_ZERO) || u128_gt(u, umax)); case Basic_UntypedInteger: @@ -1759,10 +1760,10 @@ bool check_is_castable_to(Checker *c, Operand *operand, Type *y) { } // (u)int <-> rawptr - if (is_type_int_or_uint(src) && is_type_rawptr(dst)) { + if (is_type_uintptr(src) && is_type_rawptr(dst)) { return true; } - if (is_type_rawptr(src) && is_type_int_or_uint(dst)) { + if (is_type_rawptr(src) && is_type_uintptr(dst)) { return true; } @@ -2520,7 +2521,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h bool is_declared = entity != nullptr; if (is_declared) { if (entity->kind == Entity_Builtin) { - // NOTE(bill): Builtin's are in the universe scope which is part of every scopes hierarchy + // NOTE(bill): Builtin's are in the universal scope which is part of every scopes hierarchy // This means that we should just ignore the found result through it is_declared = false; } else if (entity->scope->is_global && !import_scope->is_global) { diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index d7caae280..7cbf479e4 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -206,7 +206,7 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) { check_expr(c, &lhs, lhs_node); if (lhs.mode == Addressing_Invalid || - lhs.type == t_invalid) { + (lhs.type == t_invalid && lhs.mode != Addressing_Overload)) { return nullptr; } diff --git a/src/checker.cpp b/src/checker.cpp index d6bbf754d..35744585a 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -182,6 +182,7 @@ struct DeclInfo { AstNode * type_expr; AstNode * init_expr; Array init_expr_list; + Array attributes; AstNode * proc_lit; // AstNode_ProcLit Type * gen_proc_type; // Precalculated @@ -1720,11 +1721,14 @@ void init_preload(Checker *c) { { String _global = str_lit("_global"); - Entity *e = make_entity_import_name(c->allocator, c->global_scope->parent, make_token_ident(_global), t_invalid, - str_lit(""), _global, - c->global_scope); + Entity *type_info_entity = find_core_entity(c, str_lit("Type_Info")); + Scope *preload_scope = type_info_entity->scope; - add_entity(c, c->global_scope, nullptr, e); + Entity *e = make_entity_import_name(c->allocator, preload_scope, make_token_ident(_global), t_invalid, + str_lit(""), _global, + preload_scope); + + add_entity(c, universal_scope, nullptr, e); } c->done_preload = true; @@ -1999,6 +2003,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { d->type_expr = vd->type; d->init_expr = init_expr; } + d->attributes = vd->attributes; add_entity_and_decl_info(c, name, e, d); } @@ -2028,6 +2033,8 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { DeclInfo *d = make_declaration_info(c->allocator, c->context.scope, c->context.decl); Entity *e = nullptr; + d->attributes = vd->attributes; + if (is_ast_node_type(init) || (vd->type != nullptr && vd->type->kind == AstNode_TypeType)) { e = make_entity_type_name(c->allocator, d->scope, token, nullptr); @@ -2069,6 +2076,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { } } + add_entity_and_decl_info(c, name, e, d); } diff --git a/src/ir.cpp b/src/ir.cpp index 9b018a2ea..23dfd081e 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2852,19 +2852,19 @@ String ir_lookup_subtype_polymorphic_field(CheckerInfo *info, Type *dst, Type *s } -irValue *ir_emit_ptr_to_int(irProcedure *proc, irValue *value, Type *t, bool allow_type_type = false) { +irValue *ir_emit_ptr_to_uintptr(irProcedure *proc, irValue *value, Type *t, bool allow_type_type = false) { Type *vt = core_type(ir_type(value)); GB_ASSERT(is_type_pointer(vt)); if (allow_type_type) { - GB_ASSERT(is_type_int_or_uint(core_type(t))); + GB_ASSERT(is_type_uintptr(core_type(t))); } else { - GB_ASSERT(is_type_int_or_uint(core_type(t))); + GB_ASSERT(is_type_uintptr(core_type(t))); } return ir_emit(proc, ir_instr_conv(proc, irConv_ptrtoint, value, vt, t)); } -irValue *ir_emit_int_to_ptr(irProcedure *proc, irValue *value, Type *t) { +irValue *ir_emit_uintptr_to_ptr(irProcedure *proc, irValue *value, Type *t) { Type *vt = core_type(ir_type(value)); - GB_ASSERT(is_type_int_or_uint(vt)); + GB_ASSERT(is_type_uintptr(vt)); GB_ASSERT(is_type_pointer(core_type(t))); return ir_emit(proc, ir_instr_conv(proc, irConv_inttoptr, value, vt, t)); } @@ -3028,11 +3028,11 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { } // Pointer <-> int - if (is_type_pointer(src) && is_type_int_or_uint(dst)) { - return ir_emit_ptr_to_int(proc, value, t); + if (is_type_pointer(src) && is_type_uintptr(dst)) { + return ir_emit_ptr_to_uintptr(proc, value, t); } - if (is_type_int_or_uint(src) && is_type_pointer(dst)) { - return ir_emit_int_to_ptr(proc, value, t); + if (is_type_uintptr(src) && is_type_pointer(dst)) { + return ir_emit_uintptr_to_ptr(proc, value, t); } if (is_type_union(dst)) { @@ -3250,11 +3250,11 @@ irValue *ir_emit_transmute(irProcedure *proc, irValue *value, Type *t) { GB_ASSERT_MSG(sz == dz, "Invalid transmute conversion: `%s` to `%s`", type_to_string(src_type), type_to_string(t)); // NOTE(bill): Casting between an integer and a pointer cannot be done through a bitcast - if (is_type_int_or_uint(src) && is_type_pointer(dst)) { - return ir_emit_int_to_ptr(proc, value, t); + if (is_type_uintptr(src) && is_type_pointer(dst)) { + return ir_emit_uintptr_to_ptr(proc, value, t); } - if (is_type_pointer(src) && is_type_int_or_uint(dst)) { - return ir_emit_ptr_to_int(proc, value, t); + if (is_type_pointer(src) && is_type_uintptr(dst)) { + return ir_emit_ptr_to_uintptr(proc, value, t); } if (ir_is_type_aggregate(src) || ir_is_type_aggregate(dst)) { @@ -5886,8 +5886,8 @@ void ir_build_poly_proc(irProcedure *proc, AstNodeProcLit *pd, Entity *e) { // parent.name-guid String original_name = e->token.string; String pd_name = original_name; - if (pd->link_name.len > 0) { - pd_name = pd->link_name; + if (e->Procedure.link_name.len > 0) { + pd_name = e->Procedure.link_name; } isize name_len = proc->name.len + 1 + pd_name.len + 1 + 10 + 1; @@ -5978,8 +5978,8 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) { // FFI - Foreign function interace String original_name = e->token.string; String name = original_name; - if (pl->link_name.len > 0) { - name = pl->link_name; + if (e->Procedure.link_name.len > 0) { + name = e->Procedure.link_name; } irValue *value = ir_value_procedure(proc->module->allocator, @@ -7749,7 +7749,8 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info case Basic_i128: case Basic_u128: case Basic_int: - case Basic_uint: { + case Basic_uint: + case Basic_uintptr: { tag = ir_emit_conv(proc, variant_ptr, t_type_info_integer_ptr); irValue *is_signed = ir_const_bool(a, (t->Basic.flags & BasicFlag_Unsigned) == 0); ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), is_signed); @@ -8286,8 +8287,8 @@ void ir_gen_tree(irGen *s) { name = e->token.string; // NOTE(bill): Don't use the mangled name ir_add_foreign_library_path(m, e->Procedure.foreign_library); } - if (pl->link_name.len > 0) { - name = pl->link_name; + if (e->Procedure.link_name.len > 0) { + name = e->Procedure.link_name; } AstNode *type_expr = pl->type; diff --git a/src/ir_print.cpp b/src/ir_print.cpp index edf2665c7..725c08d02 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -245,14 +245,15 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { case Basic_f64: ir_write_string(f, "double"); return; // case Basic_complex32: ir_write_string(f, "%%..complex32"); return; - case Basic_complex64: ir_write_string(f, "%..complex64"); return; - case Basic_complex128: ir_write_string(f, "%..complex128"); return; + case Basic_complex64: ir_write_string(f, "%..complex64"); return; + case Basic_complex128: ir_write_string(f, "%..complex128"); return; - case Basic_rawptr: ir_write_string(f, "%..rawptr"); return; - case Basic_string: ir_write_string(f, "%..string"); return; - case Basic_uint: ir_fprintf(f, "i%lld", word_bits); return; - case Basic_int: ir_fprintf(f, "i%lld", word_bits); return; - case Basic_any: ir_write_string(f, "%..any"); return; + case Basic_rawptr: ir_write_string(f, "%..rawptr"); return; + case Basic_string: ir_write_string(f, "%..string"); return; + case Basic_uint: ir_fprintf(f, "i%lld", word_bits); return; + case Basic_int: ir_fprintf(f, "i%lld", word_bits); return; + case Basic_uintptr: ir_fprintf(f, "i%lld", word_bits); return; + case Basic_any: ir_write_string(f, "%..any"); return; } break; case Type_Pointer: { diff --git a/src/parser.cpp b/src/parser.cpp index 94a4e7585..c2a4dc4e4 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -167,10 +167,9 @@ Array make_ast_node_array(AstFile *f, isize init_capacity = 8) { AstNode *expr; \ }) \ AST_NODE_KIND(ProcLit, "procedure literal", struct { \ - AstNode *type; \ - AstNode *body; \ - u64 tags; \ - String link_name; \ + AstNode *type; \ + AstNode *body; \ + u64 tags; \ }) \ AST_NODE_KIND(CompoundLit, "compound literal", struct { \ AstNode *type; \ @@ -347,6 +346,7 @@ AST_NODE_KIND(_DeclBegin, "", i32) \ u64 flags; \ bool is_mutable; \ bool been_handled; \ + Array attributes; \ CommentGroup docs; \ CommentGroup comment; \ }) \ @@ -382,12 +382,18 @@ AST_NODE_KIND(_DeclBegin, "", i32) \ CommentGroup comment; \ }) \ AST_NODE_KIND(_DeclEnd, "", i32) \ + AST_NODE_KIND(Attribute, "attribute", struct { \ + Token token; \ + AstNode *type; \ + Array elems; \ + Token open, close; \ + }) \ AST_NODE_KIND(Field, "field", struct { \ Array names; \ AstNode * type; \ AstNode * default_value; \ u32 flags; \ - CommentGroup docs; \ + CommentGroup docs; \ CommentGroup comment; \ }) \ AST_NODE_KIND(FieldList, "field list", struct { \ @@ -602,6 +608,8 @@ Token ast_node_token(AstNode *node) { case AstNode_ForeignBlockDecl: return node->ForeignBlockDecl.token; + case AstNode_Attribute: + return node->Attribute.token; case AstNode_Field: if (node->Field.names.count > 0) { @@ -842,8 +850,12 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) { n->ValueDecl.names = clone_ast_node_array(a, n->ValueDecl.names); n->ValueDecl.type = clone_ast_node(a, n->ValueDecl.type); n->ValueDecl.values = clone_ast_node_array(a, n->ValueDecl.values); + n->ValueDecl.attributes = clone_ast_node_array(a, n->ValueDecl.attributes); break; + case AstNode_Attribute: + n->Attribute.elems = clone_ast_node_array(a, n->Attribute.elems); + break; case AstNode_Field: n->Field.names = clone_ast_node_array(a, n->Field.names); n->Field.type = clone_ast_node(a, n->Field.type); @@ -937,7 +949,7 @@ void syntax_error(AstNode *node, char *fmt, ...) { bool ast_node_expect(AstNode *node, AstNodeKind kind) { if (node->kind != kind) { - error(node, "Expected %.*s, got %.*s", LIT(ast_node_strings[node->kind])); + syntax_error(node, "Expected %.*s, got %.*s", LIT(ast_node_strings[node->kind])); return false; } return true; @@ -1124,12 +1136,11 @@ AstNode *ast_ellipsis(AstFile *f, Token token, AstNode *expr) { } -AstNode *ast_proc_lit(AstFile *f, AstNode *type, AstNode *body, u64 tags, String link_name) { +AstNode *ast_proc_lit(AstFile *f, AstNode *type, AstNode *body, u64 tags) { AstNode *result = make_ast_node(f, AstNode_ProcLit); result->ProcLit.type = type; result->ProcLit.body = body; result->ProcLit.tags = tags; - result->ProcLit.link_name = link_name; return result; } @@ -1556,6 +1567,8 @@ AstNode *ast_value_decl(AstFile *f, Array names, AstNode *type, Array result->ValueDecl.is_mutable = is_mutable; result->ValueDecl.docs = docs; result->ValueDecl.comment = comment; + + result->ValueDecl.attributes.allocator = heap_allocator(); return result; } @@ -1593,6 +1606,16 @@ AstNode *ast_foreign_import_decl(AstFile *f, Token token, Token filepath, Token } +AstNode *ast_attribute(AstFile *f, Token token, Token open, Token close, Array elems) { + AstNode *result = make_ast_node(f, AstNode_Attribute); + result->Attribute.token = token; + result->Attribute.open = open; + result->Attribute.elems = elems; + result->Attribute.close = close; + return result; +} + + bool next_token0(AstFile *f) { // Token prev = f->curr_token; if (f->curr_token_index+1 < f->tokens.count) { @@ -1831,7 +1854,7 @@ Token expect_closing(AstFile *f, TokenKind kind, String context) { if (f->curr_token.kind != kind && f->curr_token.kind == Token_Semicolon && f->curr_token.string == "\n") { - error(f->curr_token, "Missing `,` before newline in %.*s", LIT(context)); + syntax_error(f->curr_token, "Missing `,` before newline in %.*s", LIT(context)); advance_token(f); } return expect_token(f, kind); @@ -1854,6 +1877,11 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) { case AstNode_TypeSwitchStmt: return true; + case AstNode_HelperType: + return is_semicolon_optional_for_node(f, s->HelperType.type); + case AstNode_AliasType: + return is_semicolon_optional_for_node(f, s->AliasType.type); + case AstNode_PointerType: return is_semicolon_optional_for_node(f, s->PointerType.type); @@ -1925,7 +1953,7 @@ void expect_semicolon(AstFile *f, AstNode *s) { AstNode * parse_expr(AstFile *f, bool lhs); -AstNode * parse_proc_type(AstFile *f, Token proc_token, String *link_name); +AstNode * parse_proc_type(AstFile *f, Token proc_token); Array parse_stmt_list(AstFile *f); AstNode * parse_stmt(AstFile *f); AstNode * parse_body(AstFile *f); @@ -2066,9 +2094,8 @@ bool is_foreign_name_valid(String name) { return true; } -void parse_proc_tags(AstFile *f, u64 *tags, String *link_name, ProcCallingConvention *calling_convention) { - GB_ASSERT(tags != nullptr); - GB_ASSERT(link_name != nullptr); +void parse_proc_tags(AstFile *f, u64 *tags, ProcCallingConvention *calling_convention) { + GB_ASSERT(tags != nullptr); ProcCallingConvention cc = ProcCC_Invalid; @@ -2082,24 +2109,10 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *link_name, ProcCallingConven check_proc_add_tag(f, tag_expr, tags, ProcTag_##name, tag_name); \ } - if (tag_name == "link_name") { - check_proc_add_tag(f, tag_expr, tags, ProcTag_link_name, tag_name); - if (f->curr_token.kind == Token_String) { - *link_name = f->curr_token.string; - if (!is_foreign_name_valid(*link_name)) { - syntax_error(tag_expr, "Invalid alternative link procedure name `%.*s`", LIT(*link_name)); - } - - advance_token(f); - } else { - expect_token(f, Token_String); - } - } + if (false) {} ELSE_IF_ADD_TAG(require_results) ELSE_IF_ADD_TAG(bounds_check) ELSE_IF_ADD_TAG(no_bounds_check) - ELSE_IF_ADD_TAG(inline) - ELSE_IF_ADD_TAG(no_inline) else if (tag_name == "cc_odin") { if (cc == ProcCC_Invalid) { cc = ProcCC_Odin; @@ -2278,7 +2291,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) { AstNode *expr = parse_expr(f, false); operand = ast_run_expr(f, token, name, expr); if (unparen_expr(expr)->kind != AstNode_CallExpr) { - error(expr, "#run can only be applied to procedure calls"); + syntax_error(expr, "#run can only be applied to procedure calls"); operand = ast_bad_expr(f, token, f->curr_token); } warning(token, "#run is not yet implemented"); @@ -2295,11 +2308,27 @@ AstNode *parse_operand(AstFile *f, bool lhs) { return operand; } + case Token_inline: + case Token_no_inline: + { + Token token = advance_token(f); + AstNode *expr = parse_operand(f, false); + if (expr->kind != AstNode_ProcLit) { + syntax_error(expr, "%.*s must be followed by a procedure literal, got %.*s", LIT(token.string), LIT(ast_node_strings[expr->kind])); + return ast_bad_expr(f, token, f->curr_token); + } + if (token.kind == Token_inline) { + expr->ProcLit.tags |= ProcTag_inline; + } else if (token.kind == Token_no_inline) { + expr->ProcLit.tags |= ProcTag_no_inline; + } + return expr; + } break; + // Parse Procedure Type or Literal case Token_proc: { Token token = expect_token(f, Token_proc); - String link_name = {}; - AstNode *type = parse_proc_type(f, token, &link_name); + AstNode *type = parse_proc_type(f, token); if (f->allow_type && f->expr_level < 0) { return type; @@ -2308,7 +2337,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) { u64 tags = type->ProcType.tags; if (allow_token(f, Token_Undef)) { - return ast_proc_lit(f, type, nullptr, tags, link_name); + return ast_proc_lit(f, type, nullptr, tags); } else if (f->curr_token.kind == Token_OpenBrace) { AstNode *curr_proc = f->curr_proc; AstNode *body = nullptr; @@ -2316,7 +2345,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) { body = parse_body(f); f->curr_proc = curr_proc; - return ast_proc_lit(f, type, body, tags, link_name); + return ast_proc_lit(f, type, body, tags); } else if (allow_token(f, Token_do)) { AstNode *curr_proc = f->curr_proc; AstNode *body = nullptr; @@ -2324,7 +2353,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) { body = convert_stmt_to_body(f, parse_stmt(f)); f->curr_proc = curr_proc; - return ast_proc_lit(f, type, body, tags, link_name); + return ast_proc_lit(f, type, body, tags); } if (tags != 0) { @@ -2791,11 +2820,11 @@ AstNode *parse_atom_expr(AstFile *f, AstNode *operand, bool lhs) { index3 = true; // 2nd and 3rd index must be present if (indices[1] == nullptr) { - error(ellipses[0], "2nd index required in 3-index slice expression"); + syntax_error(ellipses[0], "2nd index required in 3-index slice expression"); indices[1] = ast_bad_expr(f, ellipses[0], ellipses[1]); } if (indices[2] == nullptr) { - error(ellipses[1], "3rd index required in 3-index slice expression"); + syntax_error(ellipses[1], "3rd index required in 3-index slice expression"); indices[2] = ast_bad_expr(f, ellipses[1], close); } } @@ -3020,13 +3049,13 @@ void parse_foreign_block_decl(AstFile *f, Array *decls) { case AstNode_BadDecl: return; + case AstNode_WhenStmt: case AstNode_ValueDecl: array_add(decls, decl); return; - /* fallthrough */ default: - error(decl, "Foreign blocks only allow procedure and variable declarations"); + syntax_error(decl, "Foreign blocks only allow procedure and variable declarations"); return; } } @@ -3266,7 +3295,7 @@ AstNode *parse_results(AstFile *f) { return list; } -AstNode *parse_proc_type(AstFile *f, Token proc_token, String *link_name_) { +AstNode *parse_proc_type(AstFile *f, Token proc_token) { AstNode *params = nullptr; AstNode *results = nullptr; @@ -3276,11 +3305,8 @@ AstNode *parse_proc_type(AstFile *f, Token proc_token, String *link_name_) { results = parse_results(f); u64 tags = 0; - String link_name = {}; ProcCallingConvention cc = ProcCC_Invalid; - parse_proc_tags(f, &tags, &link_name, &cc); - - if (link_name_) *link_name_ = link_name; + parse_proc_tags(f, &tags, &cc); bool is_generic = false; @@ -3304,7 +3330,7 @@ AstNode *parse_var_type(AstFile *f, bool allow_ellipsis, bool allow_type_token) Token tok = advance_token(f); AstNode *type = parse_type_or_ident(f); if (type == nullptr) { - error(tok, "variadic field missing type after `...`"); + syntax_error(tok, "variadic field missing type after `...`"); type = ast_bad_expr(f, tok, f->curr_token); } return ast_ellipsis(f, tok, type); @@ -3323,7 +3349,7 @@ AstNode *parse_var_type(AstFile *f, bool allow_ellipsis, bool allow_type_token) } if (type == nullptr) { Token tok = f->curr_token; - error(tok, "Expected a type"); + syntax_error(tok, "Expected a type"); type = ast_bad_expr(f, tok, f->curr_token); } return type; @@ -3426,7 +3452,7 @@ Array convert_to_ident_list(AstFile *f, Array list, if (!ignore_flags) { if (i != 0) { - error(ident, "Illegal use of prefixes in parameter list"); + syntax_error(ident, "Illegal use of prefixes in parameter list"); } } @@ -3435,7 +3461,7 @@ Array convert_to_ident_list(AstFile *f, Array list, case AstNode_BadExpr: break; default: - error(ident, "Expected an identifier"); + syntax_error(ident, "Expected an identifier"); ident = ast_ident(f, blank_token); break; } @@ -3451,7 +3477,7 @@ bool parse_expect_field_separator(AstFile *f, AstNode *param) { return true; } if (token.kind == Token_Semicolon) { - error(f->curr_token, "Expected a comma, got a semicolon"); + syntax_error(f->curr_token, "Expected a comma, got a semicolon"); advance_token(f); return true; } @@ -3465,7 +3491,7 @@ bool parse_expect_struct_separator(AstFile *f, AstNode *param) { } if (token.kind == Token_Colon) { - error(f->curr_token, "Expected a semicolon, got a comma"); + syntax_error(f->curr_token, "Expected a semicolon, got a comma"); advance_token(f); return true; } @@ -3506,7 +3532,7 @@ AstNode *parse_struct_field_list(AstFile *f, isize *name_count_) { case_ast_node(vd, ValueDecl, decl); if (vd->flags&VarDeclFlag_thread_local) { vd->flags &= ~VarDeclFlag_thread_local; - error(decl, "Field values cannot be #thread_local"); + syntax_error(decl, "Field values cannot be #thread_local"); } array_add(&decls, decl); total_name_count += vd->names.count; @@ -3517,7 +3543,7 @@ AstNode *parse_struct_field_list(AstFile *f, isize *name_count_) { break; default: - error(decl, "Expected a value declaration, got %.*s", LIT(ast_node_strings[decl->kind])); + syntax_error(decl, "Expected a value declaration, got %.*s", LIT(ast_node_strings[decl->kind])); break; } } @@ -4209,7 +4235,7 @@ AstNode *parse_for_stmt(AstFile *f) { index = cond->AssignStmt.lhs[1]; break; default: - error(cond, "Expected either 1 or 2 identifiers"); + syntax_error(cond, "Expected either 1 or 2 identifiers"); return ast_bad_stmt(f, token, f->curr_token); } @@ -4566,6 +4592,46 @@ AstNode *parse_stmt(AstFile *f) { return ast_push_context(f, token, expr, body); } break; + case Token_At: { + advance_token(f); + + Array elems = {}; + Token open = expect_token(f, Token_OpenParen); + f->expr_level++; + if (f->curr_token.kind != Token_CloseParen) { + elems = make_ast_node_array(f); + + while (f->curr_token.kind != Token_CloseParen && + f->curr_token.kind != Token_EOF) { + AstNode *elem = parse_ident(f); + if (f->curr_token.kind == Token_Eq) { + Token eq = expect_token(f, Token_Eq); + AstNode *value = parse_value(f); + elem = ast_field_value(f, elem, value, eq); + } + + array_add(&elems, elem); + + if (!allow_token(f, Token_Comma)) { + break; + } + } + } + f->expr_level--; + Token close = expect_closing(f, Token_CloseParen, str_lit("attribute")); + + AstNode *attribute = ast_attribute(f, token, open, close, elems); + + AstNode *decl = parse_stmt(f); + if (decl->kind != AstNode_ValueDecl) { + syntax_error(decl, "Expected a value declaration after an attribute, got %.*s", LIT(ast_node_strings[decl->kind])); + return ast_bad_stmt(f, token, f->curr_token); + } + + array_add(&decl->ValueDecl.attributes, attribute); + return decl; + } + case Token_Hash: { AstNode *s = nullptr; Token hash_token = expect_token(f, Token_Hash); diff --git a/src/ssa.cpp b/src/ssa.cpp index fa83cecb8..3a5e283e2 100644 --- a/src/ssa.cpp +++ b/src/ssa.cpp @@ -2490,8 +2490,8 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) { if (e->Procedure.is_foreign) { name = e->token.string; // NOTE(bill): Don't use the mangled name } - if (pl->link_name.len > 0) { - name = pl->link_name; + if (e->Procedure.link_name.len > 0) { + name = e->Procedure.link_name; } if (e == entry_point) { diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 7d36e2a66..dc0c2a56d 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -114,6 +114,8 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ TOKEN_KIND(Token_cast, "cast"), \ TOKEN_KIND(Token_transmute, "transmute"), \ TOKEN_KIND(Token_using, "using"), \ + TOKEN_KIND(Token_inline, "inline"), \ + TOKEN_KIND(Token_no_inline, "no_inline"), \ TOKEN_KIND(Token_context, "context"), \ TOKEN_KIND(Token_push_context, "push_context"), \ TOKEN_KIND(Token_push_allocator, "push_allocator"), \ diff --git a/src/types.cpp b/src/types.cpp index f30e47869..fcfc91544 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -28,6 +28,7 @@ enum BasicKind { Basic_int, Basic_uint, + Basic_uintptr, Basic_rawptr, Basic_string, // ^u8 + int Basic_any, // ^Type_Info + rawptr @@ -254,6 +255,7 @@ gb_global Type basic_types[] = { {Type_Basic, {Basic_int, BasicFlag_Integer, -1, STR_LIT("int")}}, {Type_Basic, {Basic_uint, BasicFlag_Integer | BasicFlag_Unsigned, -1, STR_LIT("uint")}}, + {Type_Basic, {Basic_uintptr, BasicFlag_Integer | BasicFlag_Unsigned, -1, STR_LIT("uintptr")}}, {Type_Basic, {Basic_rawptr, BasicFlag_Pointer, -1, STR_LIT("rawptr")}}, {Type_Basic, {Basic_string, BasicFlag_String, -1, STR_LIT("string")}}, @@ -299,6 +301,7 @@ gb_global Type *t_complex128 = &basic_types[Basic_complex128]; gb_global Type *t_int = &basic_types[Basic_int]; gb_global Type *t_uint = &basic_types[Basic_uint]; +gb_global Type *t_uintptr = &basic_types[Basic_uintptr]; gb_global Type *t_rawptr = &basic_types[Basic_rawptr]; gb_global Type *t_string = &basic_types[Basic_string]; @@ -745,9 +748,9 @@ bool is_type_tuple(Type *t) { } -bool is_type_int_or_uint(Type *t) { +bool is_type_uintptr(Type *t) { if (t->kind == Type_Basic) { - return (t->Basic.kind == Basic_int) || (t->Basic.kind == Basic_uint); + return (t->Basic.kind == Basic_uintptr); } return false; } @@ -1813,7 +1816,7 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) { case Basic_string: return build_context.word_size; case Basic_any: return build_context.word_size; - case Basic_int: case Basic_uint: case Basic_rawptr: + case Basic_int: case Basic_uint: case Basic_uintptr: case Basic_rawptr: return build_context.word_size; case Basic_complex64: case Basic_complex128: @@ -2023,7 +2026,7 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) { case Basic_string: return 2*build_context.word_size; case Basic_any: return 2*build_context.word_size; - case Basic_int: case Basic_uint: case Basic_rawptr: + case Basic_int: case Basic_uint: case Basic_uintptr: case Basic_rawptr: return build_context.word_size; } } break;