Attributes; @(link_name="foo")

This commit is contained in:
gingerBill
2017-10-29 15:46:23 +00:00
parent a43b89f36e
commit 1eb9994d88
26 changed files with 797 additions and 575 deletions

View File

@@ -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;
}

View File

@@ -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));
}

View File

@@ -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));

View File

@@ -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;

View File

@@ -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");
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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 ---;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -182,6 +182,7 @@ struct DeclInfo {
AstNode * type_expr;
AstNode * init_expr;
Array<AstNode *> init_expr_list;
Array<AstNode *> 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);
}

View File

@@ -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;

View File

@@ -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: {

View File

@@ -167,10 +167,9 @@ Array<AstNode *> 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<AstNode *> 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<AstNode *> elems; \
Token open, close; \
}) \
AST_NODE_KIND(Field, "field", struct { \
Array<AstNode *> 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<AstNode *> 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<AstNode *> 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<AstNode *> 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<AstNode *> *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<AstNode *> convert_to_ident_list(AstFile *f, Array<AstNodeAndFlags> 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<AstNode *> convert_to_ident_list(AstFile *f, Array<AstNodeAndFlags> 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<AstNode *> 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);

View File

@@ -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) {

View File

@@ -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"), \

View File

@@ -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;