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
+70 -53
View File
@@ -17,8 +17,6 @@ import "core:raw.odin"
// Constant Variables: SCREAMING_SNAKE_CASE // Constant Variables: SCREAMING_SNAKE_CASE
// IMPORTANT NOTE(bill): `type_info_of` cannot be used within a // IMPORTANT NOTE(bill): `type_info_of` cannot be used within a
// #shared_global_scope due to the internals of the compiler. // #shared_global_scope due to the internals of the compiler.
// This could change at a later date if the all these data structures are // 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 { foreign __llvm_core {
assume :: proc(cond: bool) #cc_c #link_name "llvm.assume" ---; @(link_name="llvm.assume")
__debug_trap :: proc() #cc_c #link_name "llvm.debugtrap" ---; assume :: proc(cond: bool) #cc_c ---;
__trap :: proc() #cc_c #link_name "llvm.trap" ---;
read_cycle_counter :: proc() -> u64 #cc_c #link_name "llvm.readcyclecounter" ---; @(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}; 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; a := context.allocator;
return a.procedure(a.data, Allocator_Mode.Alloc, size, alignment, nil, 0, 0); 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 ptr == nil do return;
if a.procedure == nil do return; if a.procedure == nil do return;
a.procedure(a.data, Allocator_Mode.Free, 0, 0, ptr, 0, 0); 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 := context.allocator;
a.procedure(a.data, Allocator_Mode.FreeAll, 0, 0, nil, 0, 0); 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; a := context.allocator;
return a.procedure(a.data, Allocator_Mode.Resize, new_size, alignment, ptr, old_size, 0); 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))); n := max(0, min(len(dst), len(src)));
if n > 0 do __mem_copy(&dst[0], &src[0], n*size_of(E)); if n > 0 do __mem_copy(&dst[0], &src[0], n*size_of(E));
return n; return n;
@@ -384,13 +389,13 @@ pop :: proc(array: ^$T/[dynamic]$E) -> E #cc_contextless {
return res; 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; 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; 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; if m == nil do return;
raw_map := cast(^raw.Map)m; raw_map := cast(^raw.Map)m;
hashes := cast(^raw.Dynamic_Array)&raw_map.hashes; 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 := cast(^T)alloc(size_of(T), align_of(T));
ptr^ = T{}; ptr^ = T{};
return ptr; 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 := cast(^T)alloc(size_of(T), align_of(T));
ptr^ = data; ptr^ = data;
return ptr; 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))); 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_ne :: inline proc(a, b: string) -> bool #cc_contextless { return !__string_eq(a, b); }
__string_lt :: proc(a, b: string) -> bool #cc_contextless #inline { return __string_cmp(a, b) < 0; } __string_lt :: inline proc(a, b: string) -> bool #cc_contextless { return __string_cmp(a, b) < 0; }
__string_gt :: proc(a, b: string) -> bool #cc_contextless #inline { return __string_cmp(a, b) > 0; } __string_gt :: inline proc(a, b: string) -> bool #cc_contextless { return __string_cmp(a, b) > 0; }
__string_le :: proc(a, b: string) -> bool #cc_contextless #inline { return __string_cmp(a, b) <= 0; } __string_le :: inline proc(a, b: string) -> bool #cc_contextless { return __string_cmp(a, b) <= 0; }
__string_ge :: proc(a, b: string) -> bool #cc_contextless #inline { 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_eq :: inline proc (a, b: complex64) -> bool #cc_contextless { 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_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_eq :: inline proc(a, b: complex128) -> bool #cc_contextless { 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_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 { __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(); __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); 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 { __mem_set :: proc(data: rawptr, value: i32, len: int) -> rawptr #cc_contextless {
if data == nil do return nil; if data == nil do return nil;
when size_of(rawptr) == 8 { foreign __llvm_core {
foreign __llvm_core llvm_memset :: proc(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) #link_name "llvm.memset.p0i8.i64" ---; when size_of(rawptr) == 8 {
} else { @(link_name="llvm.memset.p0i8.i64")
foreign __llvm_core llvm_memset :: proc(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) #link_name "llvm.memset.p0i8.i32" ---; 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); llvm_memset(data, u8(value), len, 1, false);
return data; 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 { __mem_copy :: proc(dst, src: rawptr, len: int) -> rawptr #cc_contextless {
if src == nil do return dst; if src == nil do return dst;
// NOTE(bill): This _must_ be implemented like C's memmove // NOTE(bill): This _must_ be implemented like C's memmove
when size_of(rawptr) == 8 { foreign __llvm_core {
foreign __llvm_core llvm_memmove :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memmove.p0i8.p0i8.i64" ---; when size_of(rawptr) == 8 {
} else { @(link_name="llvm.memmove.p0i8.p0i8.i64")
foreign __llvm_core llvm_memmove :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memmove.p0i8.p0i8.i32" ---; 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); llvm_memmove(dst, src, len, 1, false);
return dst; 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 { __mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #cc_contextless {
if src == nil do return dst; if src == nil do return dst;
// NOTE(bill): This _must_ be implemented like C's memcpy // NOTE(bill): This _must_ be implemented like C's memcpy
when size_of(rawptr) == 8 { foreign __llvm_core {
foreign __llvm_core llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memcpy.p0i8.p0i8.i64" ---; when size_of(rawptr) == 8 {
} else { @(link_name="llvm.memcpy.p0i8.p0i8.i64")
foreign __llvm_core llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memcpy.p0i8.p0i8.i32" ---; 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); llvm_memcpy(dst, src, len, 1, false);
return dst; return dst;
@@ -737,26 +754,26 @@ __mem_compare :: proc(a, b: ^u8, n: int) -> int #cc_contextless {
} }
foreign __llvm_core { foreign __llvm_core {
__sqrt_f32 :: proc(x: f32) -> f32 #link_name "llvm.sqrt.f32" ---; @(link_name="llvm.sqrt.f32") __sqrt_f32 :: proc(x: f32) -> f32 ---;
__sqrt_f64 :: proc(x: f64) -> f64 #link_name "llvm.sqrt.f64" ---; @(link_name="llvm.sqrt.f64") __sqrt_f64 :: proc(x: f64) -> f64 ---;
__sin_f32 :: proc(θ: f32) -> f32 #link_name "llvm.sin.f32" ---; @(link_name="llvm.sin.f32") __sin_f32 :: proc(θ: f32) -> f32 ---;
__sin_f64 :: proc(θ: f64) -> f64 #link_name "llvm.sin.f64" ---; @(link_name="llvm.sin.f64") __sin_f64 :: proc(θ: f64) -> f64 ---;
__cos_f32 :: proc(θ: f32) -> f32 #link_name "llvm.cos.f32" ---; @(link_name="llvm.cos.f32") __cos_f32 :: proc(θ: f32) -> f32 ---;
__cos_f64 :: proc(θ: f64) -> f64 #link_name "llvm.cos.f64" ---; @(link_name="llvm.cos.f64") __cos_f64 :: proc(θ: f64) -> f64 ---;
__pow_f32 :: proc(x, power: f32) -> f32 #link_name "llvm.pow.f32" ---; @(link_name="llvm.pow.f32") __pow_f32 :: proc(x, power: f32) -> f32 ---;
__pow_f64 :: proc(x, power: f64) -> f64 #link_name "llvm.pow.f64" ---; @(link_name="llvm.pow.f64") __pow_f64 :: proc(x, power: f64) -> f64 ---;
fmuladd32 :: proc(a, b, c: f32) -> f32 #link_name "llvm.fmuladd.f32" ---; @(link_name="llvm.fmuladd.f32") fmuladd32 :: proc(a, b, c: f32) -> f32 ---;
fmuladd64 :: proc(a, b, c: f64) -> f64 #link_name "llvm.fmuladd.f64" ---; @(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); r, i := real(x), imag(x);
return __sqrt_f32(r*r + i*i); 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); r, i := real(x), imag(x);
return __sqrt_f64(r*r + i*i); 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_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; return int(0.75 * f64(len(m.hashes))) <= m.entries.cap;
} }
+20 -10
View File
@@ -1,6 +1,7 @@
#shared_global_scope #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; bits_in_dword_2 :: size_of(i64) * 4;
lower_mask :: u128(~u64(0) >> bits_in_dword_2); 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; 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; r: u128;
__u128_quo_mod(a, b, &r); __u128_quo_mod(a, b, &r);
return 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); 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; r: i128;
__i128_quo_mod(a, b, &r); __i128_quo_mod(a, b, &r);
return 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); 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: i128;
s = b >> 127; s = b >> 127;
b = (b~s) - s; 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); alo := u64(a);
blo := u64(b); blo := u64(b);
if b == 0 { 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 { when true {
// Source: https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/ // Source: https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/
FP32 :: struct #raw_union {u: u32, f: f32}; 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; 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 { when false {
// Source: https://gist.github.com/rygorous/2156668 // Source: https://gist.github.com/rygorous/2156668
FP16 :: struct #raw_union {u: u16, f: f16}; 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)); return __f32_to_f16(f32(f));
} }
+78 -78
View File
@@ -22,16 +22,16 @@ I32_MAX :: i32(0x7fff_ffff);
I64_MAX :: i64(0x7fff_ffff_ffff_ffff); I64_MAX :: i64(0x7fff_ffff_ffff_ffff);
I128_MAX :: i128(0x7fff_ffff_ffff_ffff_ffff_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: 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 __llvm_ctpop :: proc(i8) -> i8 #link_name "llvm.ctpop.i8" ---; 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 __llvm_ctpop :: proc(u16) -> u16 #link_name "llvm.ctpop.i16" ---; 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 __llvm_ctpop :: proc(i16) -> i16 #link_name "llvm.ctpop.i16" ---; 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 __llvm_ctpop :: proc(u32) -> u32 #link_name "llvm.ctpop.i32" ---; 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 __llvm_ctpop :: proc(i32) -> i32 #link_name "llvm.ctpop.i32" ---; 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 __llvm_ctpop :: proc(u64) -> u64 #link_name "llvm.ctpop.i64" ---; 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 __llvm_ctpop :: proc(i64) -> i64 #link_name "llvm.ctpop.i64" ---; 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 __llvm_ctpop :: proc(u128) -> u128 #link_name "llvm.ctpop.i128" ---;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 __llvm_ctpop :: proc(i128) -> i128 #link_name "llvm.ctpop.i128" ---;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: 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))); } } 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)); } } 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: 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 __llvm_ctlz :: proc(i8, bool) -> i8 #link_name "llvm.ctlz.i8" ---; 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 __llvm_ctlz :: proc(u16, bool) -> u16 #link_name "llvm.ctlz.i16" ---; 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 __llvm_ctlz :: proc(i16, bool) -> i16 #link_name "llvm.ctlz.i16" ---; 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 __llvm_ctlz :: proc(u32, bool) -> u32 #link_name "llvm.ctlz.i32" ---; 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 __llvm_ctlz :: proc(i32, bool) -> i32 #link_name "llvm.ctlz.i32" ---; 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 __llvm_ctlz :: proc(u64, bool) -> u64 #link_name "llvm.ctlz.i64" ---; 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 __llvm_ctlz :: proc(i64, bool) -> i64 #link_name "llvm.ctlz.i64" ---; 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 __llvm_ctlz :: proc(u128, bool) -> u128 #link_name "llvm.ctlz.i128" ---;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 __llvm_ctlz :: proc(i128, bool) -> i128 #link_name "llvm.ctlz.i128" ---;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: 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))); } } 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: 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 __llvm_cttz :: proc(i8, bool) -> i8 #link_name "llvm.cttz.i8" ---; 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 __llvm_cttz :: proc(u16, bool) -> u16 #link_name "llvm.cttz.i16" ---; 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 __llvm_cttz :: proc(i16, bool) -> i16 #link_name "llvm.cttz.i16" ---; 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 __llvm_cttz :: proc(u32, bool) -> u32 #link_name "llvm.cttz.i32" ---; 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 __llvm_cttz :: proc(i32, bool) -> i32 #link_name "llvm.cttz.i32" ---; 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 __llvm_cttz :: proc(u64, bool) -> u64 #link_name "llvm.cttz.i64" ---; 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 __llvm_cttz :: proc(i64, bool) -> i64 #link_name "llvm.cttz.i64" ---; 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 __llvm_cttz :: proc(u128, bool) -> u128 #link_name "llvm.cttz.i128" ---;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 __llvm_cttz :: proc(i128, bool) -> i128 #link_name "llvm.cttz.i128" ---;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: 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))); } } 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: 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 __llvm_bitreverse :: proc(i8) -> i8 #link_name "llvm.bitreverse.i8" ---; 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 __llvm_bitreverse :: proc(u16) -> u16 #link_name "llvm.bitreverse.i16" ---; 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 __llvm_bitreverse :: proc(i16) -> i16 #link_name "llvm.bitreverse.i16" ---; 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 __llvm_bitreverse :: proc(u32) -> u32 #link_name "llvm.bitreverse.i32" ---; 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 __llvm_bitreverse :: proc(i32) -> i32 #link_name "llvm.bitreverse.i32" ---; 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 __llvm_bitreverse :: proc(u64) -> u64 #link_name "llvm.bitreverse.i64" ---; 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 __llvm_bitreverse :: proc(i64) -> i64 #link_name "llvm.bitreverse.i64" ---; 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 __llvm_bitreverse :: proc(u128) -> u128 #link_name "llvm.bitreverse.i128" ---;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 __llvm_bitreverse :: proc(i128) -> i128 #link_name "llvm.bitreverse.i128" ---;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: 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))); } } 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 { foreign __llvm_core {
byte_swap :: proc(u16) -> u16 #link_name "llvm.bswap.i16" ---; @(link_name="llvm.bswap.i16") byte_swap :: proc(u16) -> u16 ---;
byte_swap :: proc(i16) -> i16 #link_name "llvm.bswap.i16" ---; @(link_name="llvm.bswap.i16") byte_swap :: proc(i16) -> i16 ---;
byte_swap :: proc(u32) -> u32 #link_name "llvm.bswap.i32" ---; @(link_name="llvm.bswap.i32") byte_swap :: proc(u32) -> u32 ---;
byte_swap :: proc(i32) -> i32 #link_name "llvm.bswap.i32" ---; @(link_name="llvm.bswap.i32") byte_swap :: proc(i32) -> i32 ---;
byte_swap :: proc(u64) -> u64 #link_name "llvm.bswap.i64" ---; @(link_name="llvm.bswap.i64") byte_swap :: proc(u64) -> u64 ---;
byte_swap :: proc(i64) -> i64 #link_name "llvm.bswap.i64" ---; @(link_name="llvm.bswap.i64") byte_swap :: proc(i64) -> i64 ---;
byte_swap :: proc(u128) -> u128 #link_name "llvm.bswap.i128" ---; @(link_name="llvm.bswap.i128") byte_swap :: proc(u128) -> u128 ---;
byte_swap :: proc(i128) -> i128 #link_name "llvm.bswap.i128" ---; @(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: 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))); } } 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); } } 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: 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 op :: proc(i8, i8) -> (i8, bool) #link_name "llvm.sadd.with.overflow.i8" ---; 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 op :: proc(u16, u16) -> (u16, bool) #link_name "llvm.uadd.with.overflow.i16" ---; 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 op :: proc(i16, i16) -> (i16, bool) #link_name "llvm.sadd.with.overflow.i16" ---; 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 op :: proc(u32, u32) -> (u32, bool) #link_name "llvm.uadd.with.overflow.i32" ---; 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 op :: proc(i32, i32) -> (i32, bool) #link_name "llvm.sadd.with.overflow.i32" ---; 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 op :: proc(u64, u64) -> (u64, bool) #link_name "llvm.uadd.with.overflow.i64" ---; 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 op :: proc(i64, i64) -> (i64, bool) #link_name "llvm.sadd.with.overflow.i64" ---; 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 op :: proc(u128, u128) -> (u128, bool) #link_name "llvm.uadd.with.overflow.i128" ---; 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 op :: proc(i128, i128) -> (i128, bool) #link_name "llvm.sadd.with.overflow.i128" ---; 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) { overflowing_add :: proc(lhs, rhs: uint) -> (uint, bool) {
when size_of(uint) == size_of(u32) { when size_of(uint) == size_of(u32) {
x, ok := overflowing_add(u32(lhs), u32(rhs)); 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: 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 op :: proc(i8, i8) -> (i8, bool) #link_name "llvm.ssub.with.overflow.i8" ---; 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 op :: proc(u16, u16) -> (u16, bool) #link_name "llvm.usub.with.overflow.i16" ---; 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 op :: proc(i16, i16) -> (i16, bool) #link_name "llvm.ssub.with.overflow.i16" ---; 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 op :: proc(u32, u32) -> (u32, bool) #link_name "llvm.usub.with.overflow.i32" ---; 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 op :: proc(i32, i32) -> (i32, bool) #link_name "llvm.ssub.with.overflow.i32" ---; 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 op :: proc(u64, u64) -> (u64, bool) #link_name "llvm.usub.with.overflow.i64" ---; 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 op :: proc(i64, i64) -> (i64, bool) #link_name "llvm.ssub.with.overflow.i64" ---; 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 op :: proc(u128, u128) -> (u128, bool) #link_name "llvm.usub.with.overflow.i128" ---; 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 op :: proc(i128, i128) -> (i128, bool) #link_name "llvm.ssub.with.overflow.i128" ---; 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) { overflowing_sub :: proc(lhs, rhs: uint) -> (uint, bool) {
when size_of(uint) == size_of(u32) { when size_of(uint) == size_of(u32) {
x, ok := overflowing_sub(u32(lhs), u32(rhs)); 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: 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 op :: proc(i8, i8) -> (i8, bool) #link_name "llvm.smul.with.overflow.i8" ---; 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 op :: proc(u16, u16) -> (u16, bool) #link_name "llvm.umul.with.overflow.i16" ---; 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 op :: proc(i16, i16) -> (i16, bool) #link_name "llvm.smul.with.overflow.i16" ---; 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 op :: proc(u32, u32) -> (u32, bool) #link_name "llvm.umul.with.overflow.i32" ---; 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 op :: proc(i32, i32) -> (i32, bool) #link_name "llvm.smul.with.overflow.i32" ---; 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 op :: proc(u64, u64) -> (u64, bool) #link_name "llvm.umul.with.overflow.i64" ---; 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 op :: proc(i64, i64) -> (i64, bool) #link_name "llvm.smul.with.overflow.i64" ---; 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 op :: proc(u128, u128) -> (u128, bool) #link_name "llvm.umul.with.overflow.i128" ---; 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 op :: proc(i128, i128) -> (i128, bool) #link_name "llvm.smul.with.overflow.i128" ---; 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) { overflowing_mul :: proc(lhs, rhs: uint) -> (uint, bool) {
when size_of(uint) == size_of(u32) { when size_of(uint) == size_of(u32) {
x, ok := overflowing_mul(u32(lhs), u32(rhs)); x, ok := overflowing_mul(u32(lhs), u32(rhs));
+27 -30
View File
@@ -1,41 +1,38 @@
CHAR_BIT :: 8; 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; when ODIN_OS == "windows" || size_of(rawptr) == 4 {
c_long :: #alias i32;
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;
} else { } else {
c_long :: i64; c_long :: #alias i64;
} }
when ODIN_OS == "windows" || size_of(uint) == 4 { when ODIN_OS == "windows" || size_of(rawptr) == 4 {
c_ulong :: u32; c_ulong :: #alias u32;
} else { } else {
c_ulong :: u64; c_ulong :: #alias u64;
} }
c_longlong :: i64; c_longlong :: #alias i64;
c_ulonglong :: u64; 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; _ :: compile_assert(size_of(uintptr) == size_of(int));
c_double :: f64;
c_complex_float :: complex64; c_size_t :: #alias uint;
c_complex_double :: complex128; c_ssize_t :: #alias int;
c_ptrdiff_t :: #alias int;
c_size_t :: uint; c_uintptr_t :: #alias uintptr;
c_ssize_t :: int; c_intptr_t :: #alias int;
c_ptrdiff_t :: int;
c_uintptr_t :: uint;
c_intptr_t :: int;
+2 -2
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) { _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'; return '0' <= r && r <= '9';
} }
@@ -640,7 +640,7 @@ fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) {
fmt_bad_verb(fi, verb); fmt_bad_verb(fi, verb);
return; return;
} }
u := u128(uint(p)); u := u128(uintptr(p));
if !fi.hash || verb == 'v' { if !fi.hash || verb == 'v' {
write_string(fi.buf, "0x"); write_string(fi.buf, "0x");
} }
+22 -19
View File
@@ -28,31 +28,34 @@ Mat4 :: [4][4]f32;
Complex :: complex64; Complex :: complex64;
foreign __llvm_core { foreign __llvm_core {
sqrt :: proc(x: f32) -> f32 #link_name "llvm.sqrt.f32" ---; @(link_name="llvm.sqrt.f32")
sqrt :: proc(x: f64) -> f64 #link_name "llvm.sqrt.f64" ---; sqrt :: proc(x: f32) -> f32 ---;
@(link_name="llvm.sqrt.f64")
sqrt :: proc(x: f64) -> f64 ---;
sin :: proc(θ: f32) -> f32 #link_name "llvm.sin.f32" ---; @(link_name="llvm.sin.f32")
sin :: proc(θ: f64) -> f64 #link_name "llvm.sin.f64" ---; sin :: proc(θ: f32) -> f32 ---;
@(link_name="llvm.sin.f64")
sin :: proc(θ: f64) -> f64 ---;
cos :: proc(θ: f32) -> f32 #link_name "llvm.cos.f32" ---; @(link_name="llvm.cos.f32")
cos :: proc(θ: f64) -> f64 #link_name "llvm.cos.f64" ---; cos :: proc(θ: f32) -> f32 ---;
@(link_name="llvm.cos.f64")
cos :: proc(θ: f64) -> f64 ---;
// asin :: proc(x: f32) -> f32 #link_name "llvm.asin.f32" ---; @(link_name="llvm.pow.f32")
// asin :: proc(x: f64) -> f64 #link_name "llvm.asin.f64" ---; 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" ---; @(link_name="llvm.fmuladd.f32")
// acos :: proc(x: f64) -> f64 #link_name "llvm.acos.f64" ---; fmuladd :: proc(a, b, c: f32) -> f32 ---;
@(link_name="llvm.fmuladd.f64")
fmuladd :: proc(a, b, c: f64) -> 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" ---;
} }
tan :: proc(θ: f32) -> f32 #inline do return sin(θ)/cos(θ); tan :: proc(θ: f32) -> f32 do return sin(θ)/cos(θ);
tan :: proc(θ: f64) -> f64 #inline 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; lerp :: proc(a, b: $T, t: $E) -> (x: T) do return a*(1-t) + b*t;
+12 -12
View File
@@ -1,9 +1,9 @@
import "core:raw.odin" import "core:raw.odin"
foreign __llvm_core { foreign __llvm_core {
swap :: proc(b: u16) -> u16 #link_name "llvm.bswap.i16" ---; @(link_name = "llvm.bswap.i16") swap :: proc(b: u16) -> u16 ---;
swap :: proc(b: u32) -> u32 #link_name "llvm.bswap.i32" ---; @(link_name = "llvm.bswap.i32") swap :: proc(b: u32) -> u32 ---;
swap :: proc(b: u64) -> u64 #link_name "llvm.bswap.i64" ---; @(link_name = "llvm.bswap.i64") swap :: proc(b: u64) -> u64 ---;
} }
set :: proc(data: rawptr, value: i32, len: int) -> rawptr #cc_contextless { 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; } kilobytes :: inline proc(x: int) -> int #cc_contextless do return (x) * 1024;
megabytes :: proc(x: int) -> int #inline #cc_contextless { return kilobytes(x) * 1024; } megabytes :: inline proc(x: int) -> int #cc_contextless do return kilobytes(x) * 1024;
gigabytes :: proc(x: int) -> int #inline #cc_contextless { return megabytes(x) * 1024; } gigabytes :: inline proc(x: int) -> int #cc_contextless do return megabytes(x) * 1024;
terabytes :: proc(x: int) -> int #inline #cc_contextless { return gigabytes(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; if x <= 0 do return false;
return (x & (x-1)) == 0; 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)); assert(is_power_of_two(align));
a := uint(align); a := uintptr(align);
p := uint(ptr); p := uintptr(ptr);
modulo := p & (a-1); modulo := p & (a-1);
if modulo != 0 do p += a - modulo; if modulo != 0 do p += a - modulo;
return rawptr(p); 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)]; #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; (^raw.Slice)(&arena.memory).len += total_size;
return zero(ptr, size); return zero(ptr, size);
+27 -27
View File
@@ -11,35 +11,35 @@ export "core:opengl_constants.odin"
_ := compile_assert(ODIN_OS != "osx"); _ := compile_assert(ODIN_OS != "osx");
foreign lib { foreign lib {
Clear :: proc(mask: u32) #link_name "glClear" ---; @(link_name="glClear") Clear :: proc(mask: u32) ---;
ClearColor :: proc(r, g, b, a: f32) #link_name "glClearColor" ---; @(link_name="glClearColor") ClearColor :: proc(r, g, b, a: f32) ---;
Begin :: proc(mode: i32) #link_name "glBegin" ---; @(link_name="glBegin") Begin :: proc(mode: i32) ---;
End :: proc() #link_name "glEnd" ---; @(link_name="glEnd") End :: proc() ---;
Finish :: proc() #link_name "glFinish" ---; @(link_name="glFinish") Finish :: proc() ---;
BlendFunc :: proc(sfactor, dfactor: i32) #link_name "glBlendFunc" ---; @(link_name="glBlendFunc") BlendFunc :: proc(sfactor, dfactor: i32) ---;
Enable :: proc(cap: i32) #link_name "glEnable" ---; @(link_name="glEnable") Enable :: proc(cap: i32) ---;
Disable :: proc(cap: i32) #link_name "glDisable" ---; @(link_name="glDisable") Disable :: proc(cap: i32) ---;
GenTextures :: proc(count: i32, result: ^u32) #link_name "glGenTextures" ---; @(link_name="glGenTextures") GenTextures :: proc(count: i32, result: ^u32) ---;
DeleteTextures :: proc(count: i32, result: ^u32) #link_name "glDeleteTextures"---; @(link_name="glDeleteTextures") DeleteTextures :: proc(count: i32, result: ^u32) ---;
TexParameteri :: proc(target, pname, param: i32) #link_name "glTexParameteri" ---; @(link_name="glTexParameteri") TexParameteri :: proc(target, pname, param: i32) ---;
TexParameterf :: proc(target: i32, pname: i32, param: f32) #link_name "glTexParameterf" ---; @(link_name="glTexParameterf") TexParameterf :: proc(target: i32, pname: i32, param: f32) ---;
BindTexture :: proc(target: i32, texture: u32) #link_name "glBindTexture" ---; @(link_name="glBindTexture") BindTexture :: proc(target: i32, texture: u32) ---;
LoadIdentity :: proc() #link_name "glLoadIdentity" ---; @(link_name="glLoadIdentity") LoadIdentity :: proc() ---;
Viewport :: proc(x, y, width, height: i32) #link_name "glViewport" ---; @(link_name="glViewport") Viewport :: proc(x, y, width, height: i32) ---;
Ortho :: proc(left, right, bottom, top, near, far: f64) #link_name "glOrtho" ---; @(link_name="glOrtho") Ortho :: proc(left, right, bottom, top, near, far: f64) ---;
Color3f :: proc(r, g, b: f32) #link_name "glColor3f" ---; @(link_name="glColor3f") Color3f :: proc(r, g, b: f32) ---;
Vertex3f :: proc(x, y, z: f32) #link_name "glVertex3f" ---; @(link_name="glVertex3f") Vertex3f :: proc(x, y, z: f32) ---;
GetError :: proc() -> i32 #link_name "glGetError" ---; @(link_name="glGetError") GetError :: proc() -> i32 ---;
GetString :: proc(name: i32) -> ^u8 #link_name "glGetString" ---; @(link_name="glGetString") GetString :: proc(name: i32) -> ^u8 ---;
GetIntegerv :: proc(name: i32, v: ^i32) #link_name "glGetIntegerv" ---; @(link_name="glGetIntegerv") GetIntegerv :: proc(name: i32, v: ^i32) ---;
TexCoord2f :: proc(x, y: f32) #link_name "glTexCoord2f" ---; @(link_name="glTexCoord2f") TexCoord2f :: proc(x, y: f32) ---;
TexImage2D :: proc(target, level, internal_format, @(link_name="glTexImage2D") TexImage2D :: proc(target, level, internal_format,
width, height, border, width, height, border,
format, type_: i32, pixels: rawptr) #link_name "glTexImage2D" ---; 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")); _libgl := win32.load_library_a(_string_data("opengl32.dll\x00"));
@@ -119,7 +119,7 @@ get_proc_address :: proc(name: string) -> rawptr {
init :: proc() { init :: proc() {
set_proc_address :: proc(p: rawptr, name: string) #inline { set_proc_address :: proc(p: rawptr, name: string) {
x := cast(^rawptr)p; x := cast(^rawptr)p;
x^ = get_proc_address(name); x^ = get_proc_address(name);
} }
+30 -30
View File
@@ -108,13 +108,13 @@ S_ISGID :: 0002000; // Set group id on execution
S_ISVTX :: 0001000; // Directory restrcted delete S_ISVTX :: 0001000; // Directory restrcted delete
S_ISLNK :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFLNK; } S_ISLNK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFLNK;
S_ISREG :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFREG; } S_ISREG :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFREG;
S_ISDIR :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFDIR; } S_ISDIR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFDIR;
S_ISCHR :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFCHR; } S_ISCHR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFCHR;
S_ISBLK :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFBLK; } S_ISBLK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFBLK;
S_ISFIFO :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFIFO; } S_ISFIFO :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFIFO;
S_ISSOCK :: proc(m: u32) -> bool #inline {return (m & S_IFMT) == S_IFSOCK;} S_ISSOCK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFSOCK;
F_OK :: 0; // Test for file existance F_OK :: 0; // Test for file existance
X_OK :: 1; // Test for execute permission 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 R_OK :: 4; // Test for read permission
foreign libc { foreign libc {
_unix_open :: proc(path: ^u8, mode: int) -> Handle #link_name "open" ---; @(link_name="open") _unix_open :: proc(path: ^u8, mode: int) -> Handle ---;
_unix_close :: proc(fd: Handle) -> i32 #link_name "close" ---; @(link_name="close") _unix_close :: proc(fd: Handle) -> i32 ---;
_unix_read :: proc(fd: Handle, buf: rawptr, size: int) -> int #link_name "read" ---; @(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: int) -> int ---;
_unix_write :: proc(fd: Handle, buf: rawptr, size: int) -> int #link_name "write" ---; @(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: int) -> int ---;
_unix_seek :: proc(fd: Handle, offset: i64, whence: i32) -> i64 #link_name "lseek64" ---; @(link_name="lseek64") _unix_seek :: proc(fd: Handle, offset: i64, whence: i32) -> i64 ---;
_unix_gettid :: proc() -> u64 #link_name "gettid" ---; @(link_name="gettid") _unix_gettid :: proc() -> u64 ---;
_unix_stat :: proc(path: ^u8, stat: ^Stat) -> i32 #link_name "stat" ---; @(link_name="stat") _unix_stat :: proc(path: ^u8, stat: ^Stat) -> i32 ---;
_unix_access :: proc(path: ^u8, mask: int) -> i32 #link_name "access" ---; @(link_name="access") _unix_access :: proc(path: ^u8, mask: int) -> i32 ---;
_unix_malloc :: proc(size: int) -> rawptr #link_name "malloc" ---; @(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr ---;
_unix_calloc :: proc(num, size: int) -> rawptr #link_name "calloc" ---; @(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr ---;
_unix_free :: proc(ptr: rawptr) #link_name "free" ---; @(link_name="free") _unix_free :: proc(ptr: rawptr) ---;
_unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr #link_name "realloc" ---; @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr ---;
_unix_getenv :: proc(^u8) -> ^u8 #link_name "getenv" ---; @(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 { foreign dl {
_unix_dlopen :: proc(filename: ^u8, flags: int) -> rawptr #link_name "dlopen" ---; @(link_name="dlopen") _unix_dlopen :: proc(filename: ^u8, flags: int) -> rawptr ---;
_unix_dlsym :: proc(handle: rawptr, symbol: ^u8) -> (proc() #cc_c) #link_name "dlsym" ---; @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: ^u8) -> rawptr ---;
_unix_dlclose :: proc(handle: rawptr) -> int #link_name "dlclose" ---; @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> int ---;
_unix_dlerror :: proc() -> ^u8 #link_name "dlerror" ---; @(link_name="dlerror") _unix_dlerror :: proc() -> ^u8 ---;
} }
// TODO(zangent): Change this to just `open` when Bill fixes overloading. // 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 {} 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; s: Stat;
cstr := strings.new_c_string(path); cstr := strings.new_c_string(path);
defer free(cstr); defer free(cstr);
@@ -208,7 +208,7 @@ stat :: proc(path: string) -> (Stat, int) #inline {
return s, int(ret_int); 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); cstr := strings.new_c_string(path);
defer free(cstr); defer free(cstr);
return _unix_access(cstr, mask) == 0; return _unix_access(cstr, mask) == 0;
@@ -246,20 +246,20 @@ current_thread_id :: proc() -> int {
return 0; return 0;
} }
dlopen :: proc(filename: string, flags: int) -> rawptr #inline { dlopen :: inline proc(filename: string, flags: int) -> rawptr {
cstr := strings.new_c_string(filename); cstr := strings.new_c_string(filename);
handle := _unix_dlopen(cstr, flags); handle := _unix_dlopen(cstr, flags);
free(cstr); free(cstr);
return handle; 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); assert(handle != nil);
cstr := strings.new_c_string(symbol); cstr := strings.new_c_string(symbol);
proc_handle := _unix_dlsym(handle, cstr); proc_handle := _unix_dlsym(handle, cstr);
free(cstr); free(cstr);
return proc_handle; return proc_handle;
} }
dlclose :: proc(handle: rawptr) -> bool #inline { dlclose :: inline proc(handle: rawptr) -> bool {
assert(handle != nil); assert(handle != nil);
return _unix_dlclose(handle) == 0; return _unix_dlclose(handle) == 0;
} }
+2 -2
View File
@@ -1,11 +1,11 @@
import win32 "core:sys/windows.odin" import win32 "core:sys/windows.odin"
import "core:mem.odin" import "core:mem.odin"
Handle :: int; Handle :: uintptr;
File_Time :: u64; File_Time :: u64;
INVALID_HANDLE: Handle : -1; INVALID_HANDLE :: ~Handle(0);
+34 -34
View File
@@ -108,13 +108,13 @@ S_ISUID :: 0004000; // Set user id on execution
S_ISGID :: 0002000; // Set group id on execution S_ISGID :: 0002000; // Set group id on execution
S_ISVTX :: 0001000; // Directory restrcted delete S_ISVTX :: 0001000; // Directory restrcted delete
S_ISLNK :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFLNK; S_ISLNK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFLNK;
S_ISREG :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFREG; S_ISREG :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFREG;
S_ISDIR :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFDIR; S_ISDIR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFDIR;
S_ISCHR :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFCHR; S_ISCHR :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFCHR;
S_ISBLK :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFBLK; S_ISBLK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFBLK;
S_ISFIFO :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFIFO; S_ISFIFO :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFIFO;
S_ISSOCK :: proc(m: u32) -> bool #inline do return (m & S_IFMT) == S_IFSOCK; S_ISSOCK :: inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFSOCK;
R_OK :: 4; // Test for read permission R_OK :: 4; // Test for read permission
W_OK :: 2; // Test for write 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 F_OK :: 0; // Test for file existance
foreign libc { foreign libc {
_unix_open :: proc(path: ^u8, mode: int) -> Handle #link_name "open" ---; @(link_name="open") _unix_open :: proc(path: ^u8, mode: int) -> Handle ---;
_unix_close :: proc(handle: Handle) #link_name "close" ---; @(link_name="close") _unix_close :: proc(handle: Handle) ---;
_unix_read :: proc(handle: Handle, buffer: rawptr, count: int) -> int #link_name "read" ---; @(link_name="read") _unix_read :: proc(handle: Handle, buffer: rawptr, count: int) -> int ---;
_unix_write :: proc(handle: Handle, buffer: rawptr, count: int) -> int #link_name "write" ---; @(link_name="write") _unix_write :: proc(handle: Handle, buffer: rawptr, count: int) -> int ---;
_unix_lseek :: proc(fs: Handle, offset: int, whence: int) -> int #link_name "lseek" ---; @(link_name="lseek") _unix_lseek :: proc(fs: Handle, offset: int, whence: int) -> int ---;
_unix_gettid :: proc() -> u64 #link_name "gettid" ---; @(link_name="gettid") _unix_gettid :: proc() -> u64 ---;
_unix_stat :: proc(path: ^u8, stat: ^Stat) -> int #link_name "stat" ---; @(link_name="stat") _unix_stat :: proc(path: ^u8, stat: ^Stat) -> int ---;
_unix_access :: proc(path: ^u8, mask: int) -> int #link_name "access" ---; @(link_name="access") _unix_access :: proc(path: ^u8, mask: int) -> int ---;
_unix_malloc :: proc(size: int) -> rawptr #link_name "malloc" ---; @(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr ---;
_unix_calloc :: proc(num, size: int) -> rawptr #link_name "calloc" ---; @(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr ---;
_unix_free :: proc(ptr: rawptr) #link_name "free" ---; @(link_name="free") _unix_free :: proc(ptr: rawptr) ---;
_unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr #link_name "realloc" ---; @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr ---;
_unix_getenv :: proc(^u8) -> ^u8 #link_name "getenv" ---; @(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 { foreign dl {
_unix_dlopen :: proc(filename: ^u8, flags: int) -> rawptr #link_name "dlopen" ---; @(link_name="dlopen") _unix_dlopen :: proc(filename: ^u8, flags: int) -> rawptr ---;
_unix_dlsym :: proc(handle: rawptr, symbol: ^u8) -> (proc() #cc_c) #link_name "dlsym" ---; @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: ^u8) -> (proc() #cc_c) ---;
_unix_dlclose :: proc(handle: rawptr) -> int #link_name "dlclose" ---; @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> int ---;
_unix_dlerror :: proc() -> ^u8 #link_name "dlerror" ---; @(link_name="dlerror") _unix_dlerror :: proc() -> ^u8 ---;
} }
// TODO(zangent): Change this to just `open` when Bill fixes overloading. // 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 {} 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; s: Stat;
cstr := strings.new_c_string(path); cstr := strings.new_c_string(path);
defer free(cstr); defer free(cstr);
@@ -225,20 +225,20 @@ stat :: proc(path: string) -> (Stat, bool) #inline {
return s, ret_int==0; 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); cstr := strings.new_c_string(path);
defer free(cstr); defer free(cstr);
return _unix_access(cstr, mask) == 0; return _unix_access(cstr, mask) == 0;
} }
heap_alloc :: proc(size: int) -> rawptr #inline { heap_alloc :: inline proc(size: int) -> rawptr {
assert(size > 0); assert(size > 0);
return _unix_calloc(1, size); 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); return _unix_realloc(ptr, new_size);
} }
heap_free :: proc(ptr: rawptr) #inline { heap_free :: inline proc(ptr: rawptr) {
_unix_free(ptr); _unix_free(ptr);
} }
@@ -252,7 +252,7 @@ getenv :: proc(name: string) -> (string, bool) {
return strings.to_odin_string(cstr), true; return strings.to_odin_string(cstr), true;
} }
exit :: proc(code: int) #inline { exit :: inline proc(code: int) {
_unix_exit(code); _unix_exit(code);
} }
@@ -262,20 +262,20 @@ current_thread_id :: proc() -> int {
return 0; return 0;
} }
dlopen :: proc(filename: string, flags: int) -> rawptr #inline { dlopen :: inline proc(filename: string, flags: int) -> rawptr {
cstr := strings.new_c_string(filename); cstr := strings.new_c_string(filename);
handle := _unix_dlopen(cstr, flags); handle := _unix_dlopen(cstr, flags);
free(cstr); free(cstr);
return handle; 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); assert(handle != nil);
cstr := strings.new_c_string(symbol); cstr := strings.new_c_string(symbol);
proc_handle := _unix_dlsym(handle, cstr); proc_handle := _unix_dlsym(handle, cstr);
free(cstr); free(cstr);
return proc_handle; return proc_handle;
} }
dlclose :: proc(handle: rawptr) -> bool #inline { dlclose :: inline proc(handle: rawptr) -> bool {
assert(handle != nil); assert(handle != nil);
return _unix_dlclose(handle) == 0; return _unix_dlclose(handle) == 0;
} }
+1 -1
View File
@@ -28,7 +28,7 @@ semaphore_post :: proc(s: ^Semaphore, count: int) {
// win32.ReleaseSemaphore(s._handle, cast(i32)count, nil); // win32.ReleaseSemaphore(s._handle, cast(i32)count, nil);
} }
semaphore_release :: proc(s: ^Semaphore) #inline { semaphore_release :: inline proc(s: ^Semaphore) {
semaphore_post(s, 1); semaphore_post(s, 1);
} }
+3 -1
View File
@@ -36,7 +36,9 @@ semaphore_post :: proc(s: ^Semaphore, count: int) {
win32.release_semaphore(s._handle, i32(count), nil); 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) { semaphore_wait :: proc(s: ^Semaphore) {
win32.wait_for_single_object(s._handle, win32.INFINITE); win32.wait_for_single_object(s._handle, win32.INFINITE);
+47 -16
View File
@@ -66,20 +66,51 @@ Get_Extensions_String_ARB_Type :: #type proc(Hdc) -> ^u8 #cc_c;
foreign opengl32 { foreign opengl32 {
create_context :: proc(hdc: Hdc) -> Hglrc #link_name "wglCreateContext" ---; @(link_name="wglCreateContext")
make_current :: proc(hdc: Hdc, hglrc: Hglrc) -> Bool #link_name "wglMakeCurrent" ---; create_context :: proc(hdc: Hdc) -> Hglrc ---;
get_proc_address :: proc(c_str: ^u8) -> rawptr #link_name "wglGetProcAddress" ---;
delete_context :: proc(hglrc: Hglrc) -> Bool #link_name "wglDeleteContext" ---; @(link_name="wglMakeCurrent")
copy_context :: proc(src, dst: Hglrc, mask: u32) -> Bool #link_name "wglCopyContext" ---; make_current :: proc(hdc: Hdc, hglrc: Hglrc) -> Bool ---;
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" ---; @(link_name="wglGetProcAddress")
get_current_context :: proc() -> Hglrc #link_name "wglGetCurrentContext" ---; get_proc_address :: proc(c_str: ^u8) -> rawptr ---;
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" ---; @(link_name="wglDeleteContext")
realize_layer_palette :: proc(hdc: Hdc, layer_plane: i32, realize: Bool) -> Bool #link_name "wglRealizeLayerPalette" ---; delete_context :: proc(hglrc: Hglrc) -> Bool ---;
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" ---; @(link_name="wglCopyContext")
swap_layer_buffers :: proc(hdc: Hdc, planes: u32) -> Bool #link_name "wglSwapLayerBuffers" ---; copy_context :: proc(src, dst: Hglrc, mask: u32) -> Bool ---;
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="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 ---;
} }
+158 -151
View File
@@ -22,7 +22,7 @@ HKL :: Handle;
Wparam :: uint; Wparam :: uint;
Lparam :: int; Lparam :: int;
Lresult :: 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; 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; CREATE_SUSPENDED :: 0x00000004;
STACK_SIZE_PARAM_IS_A_RESERVATION :: 0x00010000; STACK_SIZE_PARAM_IS_A_RESERVATION :: 0x00010000;
@@ -317,7 +317,7 @@ SM_CYSCREEN :: 1;
SW_SHOW :: 5; SW_SHOW :: 5;
COLOR_BACKGROUND :: Hbrush(int(1)); COLOR_BACKGROUND :: Hbrush(uintptr(1));
INVALID_SET_FILE_POINTER :: ~u32(0); INVALID_SET_FILE_POINTER :: ~u32(0);
HEAP_ZERO_MEMORY :: 0x00000008; HEAP_ZERO_MEMORY :: 0x00000008;
@@ -328,7 +328,7 @@ GWLP_ID :: -12;
GWL_STYLE :: -16; GWL_STYLE :: -16;
GWLP_USERDATA :: -21; GWLP_USERDATA :: -21;
GWLP_WNDPROC :: -4; GWLP_WNDPROC :: -4;
Hwnd_TOP :: Hwnd(uint(0)); Hwnd_TOP :: Hwnd(uintptr(0));
BI_RGB :: 0; BI_RGB :: 0;
DIB_RGB_COLORS :: 0x00; DIB_RGB_COLORS :: 0x00;
@@ -433,210 +433,217 @@ GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1;
foreign kernel32 { foreign kernel32 {
get_last_error :: proc() -> i32 #cc_std #link_name "GetLastError" ---; @(link_name="GetLastError") get_last_error :: proc() -> i32 #cc_std ---;
exit_process :: proc(exit_code: u32) #cc_std #link_name "ExitProcess" ---; @(link_name="ExitProcess") exit_process :: proc(exit_code: u32) #cc_std ---;
get_module_handle_a :: proc(module_name: ^u8) -> Hinstance #cc_std #link_name "GetModuleHandleA" ---; @(link_name="GetModuleHandleA") get_module_handle_a :: proc(module_name: ^u8) -> Hinstance #cc_std ---;
get_module_handle_w :: proc(module_name: ^u16) -> Hinstance #cc_std #link_name "GetModuleHandleW" ---; @(link_name="GetModuleHandleW") get_module_handle_w :: proc(module_name: ^u16) -> Hinstance #cc_std ---;
sleep :: proc(ms: i32) -> i32 #cc_std #link_name "Sleep" ---; @(link_name="Sleep") sleep :: proc(ms: i32) -> i32 #cc_std ---;
query_performance_frequency :: proc(result: ^i64) -> i32 #cc_std #link_name "QueryPerformanceFrequency" ---; @(link_name="QueryPerformanceFrequency") query_performance_frequency :: proc(result: ^i64) -> i32 #cc_std ---;
query_performance_counter :: proc(result: ^i64) -> i32 #cc_std #link_name "QueryPerformanceCounter" ---; @(link_name="QueryPerformanceCounter") query_performance_counter :: proc(result: ^i64) -> i32 #cc_std ---;
output_debug_string_a :: proc(c_str: ^u8) #cc_std #link_name "OutputDebugStringA" ---; @(link_name="OutputDebugStringA") output_debug_string_a :: proc(c_str: ^u8) #cc_std ---;
get_command_line_a :: proc() -> ^u8 #cc_std #link_name "GetCommandLineA" ---; @(link_name="GetCommandLineA") get_command_line_a :: proc() -> ^u8 #cc_std ---;
get_command_line_w :: proc() -> ^u16 #cc_std #link_name "GetCommandLineW" ---; @(link_name="GetCommandLineW") get_command_line_w :: proc() -> ^u16 #cc_std ---;
get_system_metrics :: proc(index: i32) -> i32 #cc_std #link_name "GetSystemMetrics" ---; @(link_name="GetSystemMetrics") get_system_metrics :: proc(index: i32) -> i32 #cc_std ---;
get_current_thread_id :: proc() -> u32 #cc_std #link_name "GetCurrentThreadId" ---; @(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" ---; @(link_name="GetSystemTimeAsFileTime") get_system_time_as_file_time :: proc(system_time_as_file_time: ^Filetime) #cc_std ---;
file_time_to_local_file_time :: proc(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool #cc_std #link_name "FileTimeToLocalFileTime" ---; @(link_name="FileTimeToLocalFileTime") file_time_to_local_file_time :: proc(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool #cc_std ---;
file_time_to_system_time :: proc(file_time: ^Filetime, system_time: ^Systemtime) -> Bool #cc_std #link_name "FileTimeToSystemTime" ---; @(link_name="FileTimeToSystemTime") file_time_to_system_time :: proc(file_time: ^Filetime, system_time: ^Systemtime) -> Bool #cc_std ---;
system_time_to_file_time :: proc(system_time: ^Systemtime, file_time: ^Filetime) -> Bool #cc_std #link_name "SystemTimeToFileTime" ---; @(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" ---; @(link_name="CloseHandle") close_handle :: proc(h: Handle) -> i32 #cc_std ---;
get_std_handle :: proc(h: i32) -> Handle #cc_std #link_name "GetStdHandle" ---; @(link_name="GetStdHandle") get_std_handle :: proc(h: i32) -> Handle #cc_std ---;
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" ---;
get_file_size_ex :: proc(file_handle: Handle, file_size: ^i64) -> Bool #cc_std #link_name "GetFileSizeEx" ---; @(link_name="CreateFileA")
get_file_attributes_a :: proc(filename: ^u8) -> u32 #cc_std #link_name "GetFileAttributesA" ---; create_file_a :: proc(filename: ^u8, desired_access, share_mode: u32,
get_file_attributes_ex_a :: proc(filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool #cc_std #link_name "GetFileAttributesExA" ---; security: rawptr,
get_file_information_by_handle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool #cc_std #link_name "GetFileInformationByHandle" ---; creation, flags_and_attribs: u32, template_file: Handle) -> Handle #cc_std ---;
get_file_type :: proc(file_handle: Handle) -> u32 #cc_std #link_name "GetFileType" ---; @(link_name="ReadFile") read_file :: proc(h: Handle, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> Bool #cc_std ---;
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="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" ---; @(link_name="GetFileType") get_file_type :: proc(file_handle: Handle) -> u32 #cc_std ---;
find_next_file_a :: proc(file : Handle, data : ^Find_Data) -> Bool #cc_std #link_name "FindNextFileA" ---; @(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 ---;
find_close :: proc(file : Handle) -> Bool #cc_std #link_name "FindClose" ---;
@(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" ---; @(link_name="HeapAlloc") heap_alloc :: proc(h: Handle, flags: u32, bytes: int) -> rawptr #cc_std ---;
heap_realloc :: proc(h: Handle, flags: u32, memory: rawptr, bytes: int) -> rawptr #cc_std #link_name "HeapReAlloc" ---; @(link_name="HeapReAlloc") heap_realloc :: proc(h: Handle, flags: u32, memory: rawptr, bytes: int) -> rawptr #cc_std ---;
heap_free :: proc(h: Handle, flags: u32, memory: rawptr) -> Bool #cc_std #link_name "HeapFree" ---; @(link_name="HeapFree") heap_free :: proc(h: Handle, flags: u32, memory: rawptr) -> Bool #cc_std ---;
get_process_heap :: proc() -> Handle #cc_std #link_name "GetProcessHeap" ---; @(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" ---; @(link_name="CreateSemaphoreA") create_semaphore_a :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #cc_std ---;
release_semaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #cc_std #link_name "ReleaseSemaphore" ---; @(link_name="ReleaseSemaphore") release_semaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #cc_std ---;
wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32 #cc_std #link_name "WaitForSingleObject" ---; @(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" ---; @(link_name="InterlockedCompareExchange") interlocked_compare_exchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #cc_c ---;
interlocked_exchange :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedExchange" ---; @(link_name="InterlockedExchange") interlocked_exchange :: proc(dst: ^i32, desired: i32) -> i32 #cc_c ---;
interlocked_exchange_add :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedExchangeAdd" ---; @(link_name="InterlockedExchangeAdd") interlocked_exchange_add :: proc(dst: ^i32, desired: i32) -> i32 #cc_c ---;
interlocked_and :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedAnd" ---; @(link_name="InterlockedAnd") interlocked_and :: proc(dst: ^i32, desired: i32) -> i32 #cc_c ---;
interlocked_or :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedOr" ---; @(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" ---; @(link_name="InterlockedCompareExchange64") interlocked_compare_exchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64 #cc_c ---;
interlocked_exchange64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedExchange64" ---; @(link_name="InterlockedExchange64") interlocked_exchange64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c ---;
interlocked_exchange_add64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedExchangeAdd64" ---; @(link_name="InterlockedExchangeAdd64") interlocked_exchange_add64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c ---;
interlocked_and64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedAnd64" ---; @(link_name="InterlockedAnd64") interlocked_and64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c ---;
interlocked_or64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedOr64" ---; @(link_name="InterlockedOr64") interlocked_or64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c ---;
mm_pause :: proc() #cc_std #link_name "_mm_pause" ---; @(link_name="_mm_pause") mm_pause :: proc() #cc_std ---;
read_write_barrier :: proc() #cc_std #link_name "ReadWriteBarrier" ---; @(link_name="ReadWriteBarrier") read_write_barrier :: proc() #cc_std ---;
write_barrier :: proc() #cc_std #link_name "WriteBarrier" ---; @(link_name="WriteBarrier") write_barrier :: proc() #cc_std ---;
read_barrier :: proc() #cc_std #link_name "ReadBarrier" ---; @(link_name="ReadBarrier") read_barrier :: proc() #cc_std ---;
create_thread :: proc(thread_attributes: ^Security_Attributes, stack_size: int, start_routine: rawptr, @(link_name="CreateThread")
parameter: rawptr, creation_flags: u32, thread_id: ^u32) -> Handle #cc_std #link_name "CreateThread" ---; create_thread :: proc(thread_attributes: ^Security_Attributes, stack_size: int, start_routine: rawptr,
resume_thread :: proc(thread: Handle) -> u32 #cc_std #link_name "ResumeThread" ---; parameter: rawptr, creation_flags: u32, thread_id: ^u32) -> Handle #cc_std ---;
get_thread_priority :: proc(thread: Handle) -> i32 #cc_std #link_name "GetThreadPriority" ---; @(link_name="ResumeThread") resume_thread :: proc(thread: Handle) -> u32 #cc_std ---;
set_thread_priority :: proc(thread: Handle, priority: i32) -> Bool #cc_std #link_name "SetThreadPriority" ---; @(link_name="GetThreadPriority") get_thread_priority :: proc(thread: Handle) -> i32 #cc_std ---;
get_exit_code_thread :: proc(thread: Handle, exit_code: ^u32) -> Bool #cc_std #link_name "GetExitCodeThread" ---; @(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" ---; @(link_name="InitializeCriticalSection") initialize_critical_section :: proc(critical_section: ^Critical_Section) #cc_std ---;
initialize_critical_section_and_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) #cc_std #link_name "InitializeCriticalSectionAndSpinCount" ---; @(link_name="InitializeCriticalSectionAndSpinCount") initialize_critical_section_and_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) #cc_std ---;
delete_critical_section :: proc(critical_section: ^Critical_Section) #cc_std #link_name "DeleteCriticalSection" ---; @(link_name="DeleteCriticalSection") delete_critical_section :: proc(critical_section: ^Critical_Section) #cc_std ---;
set_critical_section_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) -> u32 #cc_std #link_name "SetCriticalSectionSpinCount" ---; @(link_name="SetCriticalSectionSpinCount") set_critical_section_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) -> u32 #cc_std ---;
try_enter_critical_section :: proc(critical_section: ^Critical_Section) -> Bool #cc_std #link_name "TryEnterCriticalSection" ---; @(link_name="TryEnterCriticalSection") try_enter_critical_section :: proc(critical_section: ^Critical_Section) -> Bool #cc_std ---;
enter_critical_section :: proc(critical_section: ^Critical_Section) #cc_std #link_name "EnterCriticalSection" ---; @(link_name="EnterCriticalSection") enter_critical_section :: proc(critical_section: ^Critical_Section) #cc_std ---;
leave_critical_section :: proc(critical_section: ^Critical_Section) #cc_std #link_name "LeaveCriticalSection" ---; @(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" ---; @(link_name="LoadLibraryA") load_library_a :: proc(c_str: ^u8) -> Hmodule #cc_std ---;
free_library :: proc(h: Hmodule) #cc_std #link_name "FreeLibrary" ---; @(link_name="LoadLibraryW") load_library_a :: proc(c_str: ^u16) -> Hmodule #cc_std ---;
get_proc_address :: proc(h: Hmodule, c_str: ^u8) -> rawptr #cc_std #link_name "GetProcAddress" ---; @(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 { foreign user32 {
get_desktop_window :: proc() -> Hwnd #cc_std #link_name "GetDesktopWindow" ---; @(link_name="GetDesktopWindow") get_desktop_window :: proc() -> Hwnd #cc_std ---;
show_cursor :: proc(show : Bool) #cc_std #link_name "ShowCursor" ---; @(link_name="ShowCursor") show_cursor :: proc(show : Bool) #cc_std ---;
get_cursor_pos :: proc(p: ^Point) -> Bool #cc_std #link_name "GetCursorPos" ---; @(link_name="GetCursorPos") get_cursor_pos :: proc(p: ^Point) -> Bool #cc_std ---;
set_cursor_pos :: proc(x, y: i32) -> Bool #cc_std #link_name "SetCursorPos" ---; @(link_name="SetCursorPos") set_cursor_pos :: proc(x, y: i32) -> Bool #cc_std ---;
screen_to_client :: proc(h: Hwnd, p: ^Point) -> Bool #cc_std #link_name "ScreenToClient" ---; @(link_name="ScreenToClient") screen_to_client :: proc(h: Hwnd, p: ^Point) -> Bool #cc_std ---;
client_to_screen :: proc(h: Hwnd, p: ^Point) -> Bool #cc_std #link_name "ClientToScreen" ---; @(link_name="ClientToScreen") client_to_screen :: proc(h: Hwnd, p: ^Point) -> Bool #cc_std ---;
post_quit_message :: proc(exit_code: i32) #cc_std #link_name "PostQuitMessage" ---; @(link_name="PostQuitMessage") post_quit_message :: proc(exit_code: i32) #cc_std ---;
set_window_text_a :: proc(hwnd: Hwnd, c_string: ^u8) -> Bool #cc_std #link_name "SetWindowTextA" ---; @(link_name="SetWindowTextA") set_window_text_a :: proc(hwnd: Hwnd, c_string: ^u8) -> Bool #cc_std ---;
register_class_ex_a :: proc(wc: ^Wnd_Class_Ex_A) -> i16 #cc_std #link_name "RegisterClassExA" ---; @(link_name="RegisterClassExA") register_class_ex_a :: proc(wc: ^Wnd_Class_Ex_A) -> i16 #cc_std ---;
register_class_ex_w :: proc(wc: ^Wnd_Class_Ex_W) -> i16 #cc_std #link_name "RegisterClassExW" ---; @(link_name="RegisterClassExW") register_class_ex_w :: proc(wc: ^Wnd_Class_Ex_W) -> i16 #cc_std ---;
create_window_ex_a :: proc(ex_style: u32, @(link_name="CreateWindowExA")
class_name, title: ^u8, create_window_ex_a :: proc(ex_style: u32,
style: u32, class_name, title: ^u8,
x, y, w, h: i32, style: u32,
parent: Hwnd, menu: Hmenu, instance: Hinstance, x, y, w, h: i32,
param: rawptr) -> Hwnd #cc_std #link_name "CreateWindowExA" ---; parent: Hwnd, menu: Hmenu, instance: Hinstance,
param: rawptr) -> Hwnd #cc_std ---;
create_window_ex_w :: proc(ex_style: u32, @(link_name="CreateWindowExW")
class_name, title: ^u16, create_window_ex_w :: proc(ex_style: u32,
style: u32, class_name, title: ^u16,
x, y, w, h: i32, style: u32,
parent: Hwnd, menu: Hmenu, instance: Hinstance, x, y, w, h: i32,
param: rawptr) -> Hwnd #cc_std #link_name "CreateWindowExW" ---; 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" ---; @(link_name="ShowWindow") show_window :: proc(hwnd: Hwnd, cmd_show: i32) -> Bool #cc_std ---;
translate_message :: proc(msg: ^Msg) -> Bool #cc_std #link_name "TranslateMessage" ---; @(link_name="TranslateMessage") translate_message :: proc(msg: ^Msg) -> Bool #cc_std ---;
dispatch_message_a :: proc(msg: ^Msg) -> Lresult #cc_std #link_name "DispatchMessageA" ---; @(link_name="DispatchMessageA") dispatch_message_a :: proc(msg: ^Msg) -> Lresult #cc_std ---;
dispatch_message_w :: proc(msg: ^Msg) -> Lresult #cc_std #link_name "DispatchMessageW" ---; @(link_name="DispatchMessageW") dispatch_message_w :: proc(msg: ^Msg) -> Lresult #cc_std ---;
update_window :: proc(hwnd: Hwnd) -> Bool #cc_std #link_name "UpdateWindow" ---; @(link_name="UpdateWindow") update_window :: proc(hwnd: Hwnd) -> Bool #cc_std ---;
get_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #cc_std #link_name "GetMessageA" ---; @(link_name="GetMessageA") get_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #cc_std ---;
get_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #cc_std #link_name "GetMessageW" ---; @(link_name="GetMessageW") get_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #cc_std ---;
peek_message_a :: proc(msg: ^Msg, hwnd: Hwnd,
msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_std #link_name "PeekMessageA" ---; @(link_name="PeekMessageA") peek_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_std ---;
peek_message_w :: proc(msg: ^Msg, hwnd: Hwnd, @(link_name="PeekMessageW") peek_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_std ---;
msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #cc_std #link_name "PeekMessageW" ---;
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" ---; @(link_name="AdjustWindowRect") adjust_window_rect :: proc(rect: ^Rect, style: u32, menu: Bool) -> Bool #cc_std ---;
get_active_window :: proc() -> Hwnd #cc_std #link_name "GetActiveWindow" ---; @(link_name="GetActiveWindow") get_active_window :: proc() -> Hwnd #cc_std ---;
destroy_window :: proc(wnd: Hwnd) -> Bool #cc_std #link_name "DestroyWindow" ---; @(link_name="DestroyWindow") destroy_window :: proc(wnd: Hwnd) -> Bool #cc_std ---;
describe_pixel_format :: proc(dc: Hdc, pixel_format: i32, bytes: u32, pfd: ^Pixel_Format_Descriptor) -> i32 #cc_std #link_name "DescribePixelFormat" ---; @(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" ---; @(link_name="GetMonitor_InfoA") get_monitor_info_a :: proc(monitor: Hmonitor, mi: ^Monitor_Info) -> Bool #cc_std ---;
monitor_from_window :: proc(wnd: Hwnd, flags : u32) -> Hmonitor #cc_std #link_name "MonitorFromWindow" ---; @(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" ---; @(link_name="GetWindowPlacement") get_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #cc_std ---;
set_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #cc_std #link_name "SetWindowPlacement" ---; @(link_name="SetWindowPlacement") set_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool #cc_std ---;
get_window_rect :: proc(wnd: Hwnd, rect: ^Rect) -> Bool #cc_std #link_name "GetWindowRect" ---; @(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" ---; @(link_name="GetWindowLongPtrA") get_window_long_ptr_a :: proc(wnd: Hwnd, index: i32) -> Long_Ptr #cc_std ---;
set_window_long_ptr_a :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr #cc_std #link_name "SetWindowLongPtrA" ---; @(link_name="SetWindowLongPtrA") set_window_long_ptr_a :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr #cc_std ---;
get_window_long_ptr_w :: proc(wnd: Hwnd, index: i32) -> Long_Ptr #cc_std #link_name "GetWindowLongPtrW" ---; @(link_name="GetWindowLongPtrW") get_window_long_ptr_w :: proc(wnd: Hwnd, index: i32) -> Long_Ptr #cc_std ---;
set_window_long_ptr_w :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr #cc_std #link_name "SetWindowLongPtrW" ---; @(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" ---; @(link_name="GetDC") get_dc :: proc(h: Hwnd) -> Hdc #cc_std ---;
release_dc :: proc(wnd: Hwnd, hdc: Hdc) -> i32 #cc_std #link_name "ReleaseDC" ---; @(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" ---; @(link_name="MapVirtualKeyA") map_virtual_key_a :: proc(scancode : u32, map_type : u32) -> u32 #cc_std ---;
map_virtual_key_w :: proc(scancode : u32, map_type : u32) -> u32 #cc_std #link_name "MapVirtualKeyW" ---; @(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" ---; @(link_name="GetKeyState") get_key_state :: proc(v_key: i32) -> i16 #cc_std ---;
get_async_key_state :: proc(v_key: i32) -> i16 #cc_std #link_name "GetAsyncKeyState" ---; @(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" ---; @(link_name="SetForegroundWindow") set_foreground_window :: proc(h: Hwnd) -> Bool #cc_std ---;
set_focus :: proc(h: Hwnd) -> Hwnd #cc_std #link_name "SetFocus" ---; @(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" ---; @(link_name="MapVirtualKeyExW") map_virtual_key_ex_w :: proc(code, map_type: u32, hkl: HKL) #cc_std ---;
map_virtual_key_ex_a :: proc(code, map_type: u32, hkl: HKL) #cc_std #link_name "MapVirtualKeyExA" ---; @(link_name="MapVirtualKeyExA") map_virtual_key_ex_a :: proc(code, map_type: u32, hkl: HKL) #cc_std ---;
} }
foreign gdi32 { 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, @(link_name="StretchDIBits")
x_dst, y_dst, width_dst, height_dst: i32, stretch_dibits :: proc(hdc: Hdc,
x_src, y_src, width_src, header_src: i32, x_dst, y_dst, width_dst, height_dst: i32,
bits: rawptr, bits_info: ^Bitmap_Info, x_src, y_src, width_src, header_src: i32,
usage: u32, bits: rawptr, bits_info: ^Bitmap_Info,
rop: u32) -> i32 #cc_std #link_name "StretchDIBits" ---; 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" ---; @(link_name="SetPixelFormat") set_pixel_format :: proc(hdc: Hdc, pixel_format: i32, pfd: ^Pixel_Format_Descriptor) -> Bool #cc_std ---;
choose_pixel_format :: proc(hdc: Hdc, pfd: ^Pixel_Format_Descriptor) -> i32 #cc_std #link_name "ChoosePixelFormat" ---; @(link_name="ChoosePixelFormat") choose_pixel_format :: proc(hdc: Hdc, pfd: ^Pixel_Format_Descriptor) -> i32 #cc_std ---;
swap_buffers :: proc(hdc: Hdc) -> Bool #cc_std #link_name "SwapBuffers" ---; @(link_name="SwapBuffers") swap_buffers :: proc(hdc: Hdc) -> Bool #cc_std ---;
} }
foreign shell32 { 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 { 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(wParam: Wparam) -> u16 { return u16(wParam); }
LOWORD :: proc(lParam: Lparam) -> u16 { return u16(lParam); } 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;
+4 -4
View File
@@ -92,7 +92,7 @@ encode_rune :: proc(r: rune) -> ([4]u8, int) {
return buf, 4; 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) { decode_rune :: proc(s: []u8) -> (rune, int) {
n := len(s); n := len(s);
if n < 1 { 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) { decode_last_rune :: proc(s: []u8) -> (rune, int) {
r: rune; r: rune;
size: int; size: int;
@@ -211,9 +211,9 @@ valid_string :: proc(s: string) -> bool {
return true; 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 { rune_count :: proc(s: []u8) -> int {
count := 0; count := 0;
n := len(s); n := len(s);
+85 -12
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) { void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool is_alias) {
GB_ASSERT(e->type == nullptr); 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; e->type = t_invalid;
String name = e->token.string; String name = e->token.string;
Type *named = make_type_named(c->allocator, name, nullptr, e); 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_alias) {
if (is_type_named(bt)) { if (is_type_named(bt)) {
e->type = bt; e->type = bt;
e->TypeName.is_type_alias = true;
} else { } 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); error(e->token, "Invalid declaration type `%s`", str);
gb_string_free(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)); defer (check_close_scope(c));
auto prev_context = c->context; auto prev_context = c->context;
c->context.allow_polymorphic_types = true; c->context.allow_polymorphic_types = true;
check_procedure_type(c, proc_type, pl->type); 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_foreign = e->Procedure.is_foreign;
bool is_export = e->Procedure.is_export; 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_inline = (pl->tags & ProcTag_inline) != 0;
bool is_no_inline = (pl->tags & ProcTag_no_inline) != 0; bool is_no_inline = (pl->tags & ProcTag_no_inline) != 0;
bool is_require_results = (pl->tags & ProcTag_require_results) != 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") { 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) { if (is_foreign) {
String name = e->token.string; String name = e->token.string;
if (pl->link_name.len > 0) { if (link_name.len > 0) {
name = pl->link_name; name = link_name;
} }
e->Procedure.is_foreign = true; e->Procedure.is_foreign = true;
e->Procedure.link_name = name; e->Procedure.link_name = name;
@@ -562,11 +628,11 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
} }
} else { } else {
String name = e->token.string; String name = e->token.string;
if (is_link_name) { if (link_name.len > 0) {
name = pl->link_name; name = link_name;
} }
if (is_link_name || is_export) { if (link_name.len > 0 || is_export) {
auto *fp = &c->info.foreigns; auto *fp = &c->info.foreigns;
e->Procedure.link_name = name; 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; 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"); String context_name = str_lit("variable declaration");
if (type_expr != nullptr) { if (type_expr != nullptr) {
@@ -692,9 +763,11 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
case Entity_Constant: case Entity_Constant:
check_const_decl(c, e, d->type_expr, d->init_expr, named_type); check_const_decl(c, e, d->type_expr, d->init_expr, named_type);
break; break;
case Entity_TypeName: case Entity_TypeName: {
check_type_decl(c, e, d->type_expr, named_type, d->type_expr->kind == AstNode_AliasType); bool is_alias = unparen_expr(d->type_expr)->kind == AstNode_AliasType;
check_type_decl(c, e, d->type_expr, named_type, is_alias);
break; break;
}
case Entity_Procedure: case Entity_Procedure:
check_proc_decl(c, e, d); check_proc_decl(c, e, d);
break; break;
+4 -3
View File
@@ -1238,6 +1238,7 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
case Basic_u64: case Basic_u64:
case Basic_u128: case Basic_u128:
case Basic_uint: case Basic_uint:
case Basic_uintptr:
return !(u128_lt(u, U128_ZERO) || u128_gt(u, umax)); return !(u128_lt(u, U128_ZERO) || u128_gt(u, umax));
case Basic_UntypedInteger: case Basic_UntypedInteger:
@@ -1759,10 +1760,10 @@ bool check_is_castable_to(Checker *c, Operand *operand, Type *y) {
} }
// (u)int <-> rawptr // (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; return true;
} }
if (is_type_rawptr(src) && is_type_int_or_uint(dst)) { if (is_type_rawptr(src) && is_type_uintptr(dst)) {
return true; return true;
} }
@@ -2520,7 +2521,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
bool is_declared = entity != nullptr; bool is_declared = entity != nullptr;
if (is_declared) { if (is_declared) {
if (entity->kind == Entity_Builtin) { 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 // This means that we should just ignore the found result through it
is_declared = false; is_declared = false;
} else if (entity->scope->is_global && !import_scope->is_global) { } else if (entity->scope->is_global && !import_scope->is_global) {
+1 -1
View File
@@ -206,7 +206,7 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
check_expr(c, &lhs, lhs_node); check_expr(c, &lhs, lhs_node);
if (lhs.mode == Addressing_Invalid || if (lhs.mode == Addressing_Invalid ||
lhs.type == t_invalid) { (lhs.type == t_invalid && lhs.mode != Addressing_Overload)) {
return nullptr; return nullptr;
} }
+12 -4
View File
@@ -182,6 +182,7 @@ struct DeclInfo {
AstNode * type_expr; AstNode * type_expr;
AstNode * init_expr; AstNode * init_expr;
Array<AstNode *> init_expr_list; Array<AstNode *> init_expr_list;
Array<AstNode *> attributes;
AstNode * proc_lit; // AstNode_ProcLit AstNode * proc_lit; // AstNode_ProcLit
Type * gen_proc_type; // Precalculated Type * gen_proc_type; // Precalculated
@@ -1720,11 +1721,14 @@ void init_preload(Checker *c) {
{ {
String _global = str_lit("_global"); String _global = str_lit("_global");
Entity *e = make_entity_import_name(c->allocator, c->global_scope->parent, make_token_ident(_global), t_invalid, Entity *type_info_entity = find_core_entity(c, str_lit("Type_Info"));
str_lit(""), _global, Scope *preload_scope = type_info_entity->scope;
c->global_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; c->done_preload = true;
@@ -1999,6 +2003,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) {
d->type_expr = vd->type; d->type_expr = vd->type;
d->init_expr = init_expr; d->init_expr = init_expr;
} }
d->attributes = vd->attributes;
add_entity_and_decl_info(c, name, e, d); 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); DeclInfo *d = make_declaration_info(c->allocator, c->context.scope, c->context.decl);
Entity *e = nullptr; Entity *e = nullptr;
d->attributes = vd->attributes;
if (is_ast_node_type(init) || if (is_ast_node_type(init) ||
(vd->type != nullptr && vd->type->kind == AstNode_TypeType)) { (vd->type != nullptr && vd->type->kind == AstNode_TypeType)) {
e = make_entity_type_name(c->allocator, d->scope, token, nullptr); 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); add_entity_and_decl_info(c, name, e, d);
} }
+21 -20
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)); Type *vt = core_type(ir_type(value));
GB_ASSERT(is_type_pointer(vt)); GB_ASSERT(is_type_pointer(vt));
if (allow_type_type) { if (allow_type_type) {
GB_ASSERT(is_type_int_or_uint(core_type(t))); GB_ASSERT(is_type_uintptr(core_type(t)));
} else { } 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)); 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)); 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))); GB_ASSERT(is_type_pointer(core_type(t)));
return ir_emit(proc, ir_instr_conv(proc, irConv_inttoptr, value, vt, 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 // Pointer <-> int
if (is_type_pointer(src) && is_type_int_or_uint(dst)) { if (is_type_pointer(src) && is_type_uintptr(dst)) {
return ir_emit_ptr_to_int(proc, value, t); return ir_emit_ptr_to_uintptr(proc, value, t);
} }
if (is_type_int_or_uint(src) && is_type_pointer(dst)) { if (is_type_uintptr(src) && is_type_pointer(dst)) {
return ir_emit_int_to_ptr(proc, value, t); return ir_emit_uintptr_to_ptr(proc, value, t);
} }
if (is_type_union(dst)) { 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)); 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 // 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)) { if (is_type_uintptr(src) && is_type_pointer(dst)) {
return ir_emit_int_to_ptr(proc, value, t); return ir_emit_uintptr_to_ptr(proc, value, t);
} }
if (is_type_pointer(src) && is_type_int_or_uint(dst)) { if (is_type_pointer(src) && is_type_uintptr(dst)) {
return ir_emit_ptr_to_int(proc, value, t); return ir_emit_ptr_to_uintptr(proc, value, t);
} }
if (ir_is_type_aggregate(src) || ir_is_type_aggregate(dst)) { 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 // parent.name-guid
String original_name = e->token.string; String original_name = e->token.string;
String pd_name = original_name; String pd_name = original_name;
if (pd->link_name.len > 0) { if (e->Procedure.link_name.len > 0) {
pd_name = pd->link_name; pd_name = e->Procedure.link_name;
} }
isize name_len = proc->name.len + 1 + pd_name.len + 1 + 10 + 1; 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 // FFI - Foreign function interace
String original_name = e->token.string; String original_name = e->token.string;
String name = original_name; String name = original_name;
if (pl->link_name.len > 0) { if (e->Procedure.link_name.len > 0) {
name = pl->link_name; name = e->Procedure.link_name;
} }
irValue *value = ir_value_procedure(proc->module->allocator, 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_i128:
case Basic_u128: case Basic_u128:
case Basic_int: case Basic_int:
case Basic_uint: { case Basic_uint:
case Basic_uintptr: {
tag = ir_emit_conv(proc, variant_ptr, t_type_info_integer_ptr); 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); 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); 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 name = e->token.string; // NOTE(bill): Don't use the mangled name
ir_add_foreign_library_path(m, e->Procedure.foreign_library); ir_add_foreign_library_path(m, e->Procedure.foreign_library);
} }
if (pl->link_name.len > 0) { if (e->Procedure.link_name.len > 0) {
name = pl->link_name; name = e->Procedure.link_name;
} }
AstNode *type_expr = pl->type; AstNode *type_expr = pl->type;
+8 -7
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_f64: ir_write_string(f, "double"); return;
// case Basic_complex32: ir_write_string(f, "%%..complex32"); return; // case Basic_complex32: ir_write_string(f, "%%..complex32"); return;
case Basic_complex64: ir_write_string(f, "%..complex64"); return; case Basic_complex64: ir_write_string(f, "%..complex64"); return;
case Basic_complex128: ir_write_string(f, "%..complex128"); return; case Basic_complex128: ir_write_string(f, "%..complex128"); return;
case Basic_rawptr: ir_write_string(f, "%..rawptr"); return; case Basic_rawptr: ir_write_string(f, "%..rawptr"); return;
case Basic_string: ir_write_string(f, "%..string"); return; case Basic_string: ir_write_string(f, "%..string"); return;
case Basic_uint: ir_fprintf(f, "i%lld", word_bits); 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_int: ir_fprintf(f, "i%lld", word_bits); return;
case Basic_any: ir_write_string(f, "%..any"); return; case Basic_uintptr: ir_fprintf(f, "i%lld", word_bits); return;
case Basic_any: ir_write_string(f, "%..any"); return;
} }
break; break;
case Type_Pointer: { case Type_Pointer: {
+118 -52
View File
@@ -167,10 +167,9 @@ Array<AstNode *> make_ast_node_array(AstFile *f, isize init_capacity = 8) {
AstNode *expr; \ AstNode *expr; \
}) \ }) \
AST_NODE_KIND(ProcLit, "procedure literal", struct { \ AST_NODE_KIND(ProcLit, "procedure literal", struct { \
AstNode *type; \ AstNode *type; \
AstNode *body; \ AstNode *body; \
u64 tags; \ u64 tags; \
String link_name; \
}) \ }) \
AST_NODE_KIND(CompoundLit, "compound literal", struct { \ AST_NODE_KIND(CompoundLit, "compound literal", struct { \
AstNode *type; \ AstNode *type; \
@@ -347,6 +346,7 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
u64 flags; \ u64 flags; \
bool is_mutable; \ bool is_mutable; \
bool been_handled; \ bool been_handled; \
Array<AstNode *> attributes; \
CommentGroup docs; \ CommentGroup docs; \
CommentGroup comment; \ CommentGroup comment; \
}) \ }) \
@@ -382,12 +382,18 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
CommentGroup comment; \ CommentGroup comment; \
}) \ }) \
AST_NODE_KIND(_DeclEnd, "", i32) \ 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 { \ AST_NODE_KIND(Field, "field", struct { \
Array<AstNode *> names; \ Array<AstNode *> names; \
AstNode * type; \ AstNode * type; \
AstNode * default_value; \ AstNode * default_value; \
u32 flags; \ u32 flags; \
CommentGroup docs; \ CommentGroup docs; \
CommentGroup comment; \ CommentGroup comment; \
}) \ }) \
AST_NODE_KIND(FieldList, "field list", struct { \ 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_ForeignBlockDecl: return node->ForeignBlockDecl.token;
case AstNode_Attribute:
return node->Attribute.token;
case AstNode_Field: case AstNode_Field:
if (node->Field.names.count > 0) { 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.names = clone_ast_node_array(a, n->ValueDecl.names);
n->ValueDecl.type = clone_ast_node(a, n->ValueDecl.type); n->ValueDecl.type = clone_ast_node(a, n->ValueDecl.type);
n->ValueDecl.values = clone_ast_node_array(a, n->ValueDecl.values); n->ValueDecl.values = clone_ast_node_array(a, n->ValueDecl.values);
n->ValueDecl.attributes = clone_ast_node_array(a, n->ValueDecl.attributes);
break; break;
case AstNode_Attribute:
n->Attribute.elems = clone_ast_node_array(a, n->Attribute.elems);
break;
case AstNode_Field: case AstNode_Field:
n->Field.names = clone_ast_node_array(a, n->Field.names); n->Field.names = clone_ast_node_array(a, n->Field.names);
n->Field.type = clone_ast_node(a, n->Field.type); 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) { bool ast_node_expect(AstNode *node, AstNodeKind kind) {
if (node->kind != 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 false;
} }
return true; 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); AstNode *result = make_ast_node(f, AstNode_ProcLit);
result->ProcLit.type = type; result->ProcLit.type = type;
result->ProcLit.body = body; result->ProcLit.body = body;
result->ProcLit.tags = tags; result->ProcLit.tags = tags;
result->ProcLit.link_name = link_name;
return result; 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.is_mutable = is_mutable;
result->ValueDecl.docs = docs; result->ValueDecl.docs = docs;
result->ValueDecl.comment = comment; result->ValueDecl.comment = comment;
result->ValueDecl.attributes.allocator = heap_allocator();
return result; 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) { bool next_token0(AstFile *f) {
// Token prev = f->curr_token; // Token prev = f->curr_token;
if (f->curr_token_index+1 < f->tokens.count) { 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 && if (f->curr_token.kind != kind &&
f->curr_token.kind == Token_Semicolon && f->curr_token.kind == Token_Semicolon &&
f->curr_token.string == "\n") { 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); advance_token(f);
} }
return expect_token(f, kind); return expect_token(f, kind);
@@ -1854,6 +1877,11 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) {
case AstNode_TypeSwitchStmt: case AstNode_TypeSwitchStmt:
return true; 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: case AstNode_PointerType:
return is_semicolon_optional_for_node(f, s->PointerType.type); 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_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); Array<AstNode *> parse_stmt_list(AstFile *f);
AstNode * parse_stmt(AstFile *f); AstNode * parse_stmt(AstFile *f);
AstNode * parse_body(AstFile *f); AstNode * parse_body(AstFile *f);
@@ -2066,9 +2094,8 @@ bool is_foreign_name_valid(String name) {
return true; return true;
} }
void parse_proc_tags(AstFile *f, u64 *tags, String *link_name, ProcCallingConvention *calling_convention) { void parse_proc_tags(AstFile *f, u64 *tags, ProcCallingConvention *calling_convention) {
GB_ASSERT(tags != nullptr); GB_ASSERT(tags != nullptr);
GB_ASSERT(link_name != nullptr);
ProcCallingConvention cc = ProcCC_Invalid; 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); \ check_proc_add_tag(f, tag_expr, tags, ProcTag_##name, tag_name); \
} }
if (tag_name == "link_name") { if (false) {}
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);
}
}
ELSE_IF_ADD_TAG(require_results) ELSE_IF_ADD_TAG(require_results)
ELSE_IF_ADD_TAG(bounds_check) ELSE_IF_ADD_TAG(bounds_check)
ELSE_IF_ADD_TAG(no_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") { else if (tag_name == "cc_odin") {
if (cc == ProcCC_Invalid) { if (cc == ProcCC_Invalid) {
cc = ProcCC_Odin; cc = ProcCC_Odin;
@@ -2278,7 +2291,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
AstNode *expr = parse_expr(f, false); AstNode *expr = parse_expr(f, false);
operand = ast_run_expr(f, token, name, expr); operand = ast_run_expr(f, token, name, expr);
if (unparen_expr(expr)->kind != AstNode_CallExpr) { 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); operand = ast_bad_expr(f, token, f->curr_token);
} }
warning(token, "#run is not yet implemented"); warning(token, "#run is not yet implemented");
@@ -2295,11 +2308,27 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
return operand; 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 // Parse Procedure Type or Literal
case Token_proc: { case Token_proc: {
Token token = expect_token(f, Token_proc); Token token = expect_token(f, Token_proc);
String link_name = {}; AstNode *type = parse_proc_type(f, token);
AstNode *type = parse_proc_type(f, token, &link_name);
if (f->allow_type && f->expr_level < 0) { if (f->allow_type && f->expr_level < 0) {
return type; return type;
@@ -2308,7 +2337,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
u64 tags = type->ProcType.tags; u64 tags = type->ProcType.tags;
if (allow_token(f, Token_Undef)) { 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) { } else if (f->curr_token.kind == Token_OpenBrace) {
AstNode *curr_proc = f->curr_proc; AstNode *curr_proc = f->curr_proc;
AstNode *body = nullptr; AstNode *body = nullptr;
@@ -2316,7 +2345,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
body = parse_body(f); body = parse_body(f);
f->curr_proc = curr_proc; 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)) { } else if (allow_token(f, Token_do)) {
AstNode *curr_proc = f->curr_proc; AstNode *curr_proc = f->curr_proc;
AstNode *body = nullptr; AstNode *body = nullptr;
@@ -2324,7 +2353,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
body = convert_stmt_to_body(f, parse_stmt(f)); body = convert_stmt_to_body(f, parse_stmt(f));
f->curr_proc = curr_proc; 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) { if (tags != 0) {
@@ -2791,11 +2820,11 @@ AstNode *parse_atom_expr(AstFile *f, AstNode *operand, bool lhs) {
index3 = true; index3 = true;
// 2nd and 3rd index must be present // 2nd and 3rd index must be present
if (indices[1] == nullptr) { 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]); indices[1] = ast_bad_expr(f, ellipses[0], ellipses[1]);
} }
if (indices[2] == nullptr) { 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); 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: case AstNode_BadDecl:
return; return;
case AstNode_WhenStmt:
case AstNode_ValueDecl: case AstNode_ValueDecl:
array_add(decls, decl); array_add(decls, decl);
return; return;
/* fallthrough */
default: default:
error(decl, "Foreign blocks only allow procedure and variable declarations"); syntax_error(decl, "Foreign blocks only allow procedure and variable declarations");
return; return;
} }
} }
@@ -3266,7 +3295,7 @@ AstNode *parse_results(AstFile *f) {
return list; 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 *params = nullptr;
AstNode *results = nullptr; AstNode *results = nullptr;
@@ -3276,11 +3305,8 @@ AstNode *parse_proc_type(AstFile *f, Token proc_token, String *link_name_) {
results = parse_results(f); results = parse_results(f);
u64 tags = 0; u64 tags = 0;
String link_name = {};
ProcCallingConvention cc = ProcCC_Invalid; ProcCallingConvention cc = ProcCC_Invalid;
parse_proc_tags(f, &tags, &link_name, &cc); parse_proc_tags(f, &tags, &cc);
if (link_name_) *link_name_ = link_name;
bool is_generic = false; 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); Token tok = advance_token(f);
AstNode *type = parse_type_or_ident(f); AstNode *type = parse_type_or_ident(f);
if (type == nullptr) { 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); type = ast_bad_expr(f, tok, f->curr_token);
} }
return ast_ellipsis(f, tok, type); 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) { if (type == nullptr) {
Token tok = f->curr_token; 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); type = ast_bad_expr(f, tok, f->curr_token);
} }
return type; return type;
@@ -3426,7 +3452,7 @@ Array<AstNode *> convert_to_ident_list(AstFile *f, Array<AstNodeAndFlags> list,
if (!ignore_flags) { if (!ignore_flags) {
if (i != 0) { 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: case AstNode_BadExpr:
break; break;
default: default:
error(ident, "Expected an identifier"); syntax_error(ident, "Expected an identifier");
ident = ast_ident(f, blank_token); ident = ast_ident(f, blank_token);
break; break;
} }
@@ -3451,7 +3477,7 @@ bool parse_expect_field_separator(AstFile *f, AstNode *param) {
return true; return true;
} }
if (token.kind == Token_Semicolon) { 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); advance_token(f);
return true; return true;
} }
@@ -3465,7 +3491,7 @@ bool parse_expect_struct_separator(AstFile *f, AstNode *param) {
} }
if (token.kind == Token_Colon) { 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); advance_token(f);
return true; return true;
} }
@@ -3506,7 +3532,7 @@ AstNode *parse_struct_field_list(AstFile *f, isize *name_count_) {
case_ast_node(vd, ValueDecl, decl); case_ast_node(vd, ValueDecl, decl);
if (vd->flags&VarDeclFlag_thread_local) { if (vd->flags&VarDeclFlag_thread_local) {
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); array_add(&decls, decl);
total_name_count += vd->names.count; total_name_count += vd->names.count;
@@ -3517,7 +3543,7 @@ AstNode *parse_struct_field_list(AstFile *f, isize *name_count_) {
break; break;
default: 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; break;
} }
} }
@@ -4209,7 +4235,7 @@ AstNode *parse_for_stmt(AstFile *f) {
index = cond->AssignStmt.lhs[1]; index = cond->AssignStmt.lhs[1];
break; break;
default: 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); 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); return ast_push_context(f, token, expr, body);
} break; } 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: { case Token_Hash: {
AstNode *s = nullptr; AstNode *s = nullptr;
Token hash_token = expect_token(f, Token_Hash); Token hash_token = expect_token(f, Token_Hash);
+2 -2
View File
@@ -2490,8 +2490,8 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
if (e->Procedure.is_foreign) { if (e->Procedure.is_foreign) {
name = e->token.string; // NOTE(bill): Don't use the mangled name name = e->token.string; // NOTE(bill): Don't use the mangled name
} }
if (pl->link_name.len > 0) { if (e->Procedure.link_name.len > 0) {
name = pl->link_name; name = e->Procedure.link_name;
} }
if (e == entry_point) { if (e == entry_point) {
+2
View File
@@ -114,6 +114,8 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
TOKEN_KIND(Token_cast, "cast"), \ TOKEN_KIND(Token_cast, "cast"), \
TOKEN_KIND(Token_transmute, "transmute"), \ TOKEN_KIND(Token_transmute, "transmute"), \
TOKEN_KIND(Token_using, "using"), \ 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_context, "context"), \
TOKEN_KIND(Token_push_context, "push_context"), \ TOKEN_KIND(Token_push_context, "push_context"), \
TOKEN_KIND(Token_push_allocator, "push_allocator"), \ TOKEN_KIND(Token_push_allocator, "push_allocator"), \
+7 -4
View File
@@ -28,6 +28,7 @@ enum BasicKind {
Basic_int, Basic_int,
Basic_uint, Basic_uint,
Basic_uintptr,
Basic_rawptr, Basic_rawptr,
Basic_string, // ^u8 + int Basic_string, // ^u8 + int
Basic_any, // ^Type_Info + rawptr 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_int, BasicFlag_Integer, -1, STR_LIT("int")}},
{Type_Basic, {Basic_uint, BasicFlag_Integer | BasicFlag_Unsigned, -1, STR_LIT("uint")}}, {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_rawptr, BasicFlag_Pointer, -1, STR_LIT("rawptr")}},
{Type_Basic, {Basic_string, BasicFlag_String, -1, STR_LIT("string")}}, {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_int = &basic_types[Basic_int];
gb_global Type *t_uint = &basic_types[Basic_uint]; 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_rawptr = &basic_types[Basic_rawptr];
gb_global Type *t_string = &basic_types[Basic_string]; 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) { if (t->kind == Type_Basic) {
return (t->Basic.kind == Basic_int) || (t->Basic.kind == Basic_uint); return (t->Basic.kind == Basic_uintptr);
} }
return false; 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_string: return build_context.word_size;
case Basic_any: 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; return build_context.word_size;
case Basic_complex64: case Basic_complex128: 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_string: return 2*build_context.word_size;
case Basic_any: 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; return build_context.word_size;
} }
} break; } break;