mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-09 11:58:10 +00:00
foreign blocks for procedures
This commit is contained in:
@@ -147,12 +147,12 @@ proc type_info_base_without_enum(info: ^TypeInfo) -> ^TypeInfo {
|
||||
|
||||
|
||||
|
||||
proc assume(cond: bool) #foreign __llvm_core "llvm.assume";
|
||||
|
||||
proc __debug_trap () #foreign __llvm_core "llvm.debugtrap";
|
||||
proc __trap () #foreign __llvm_core "llvm.trap";
|
||||
proc read_cycle_counter() -> u64 #foreign __llvm_core "llvm.readcyclecounter";
|
||||
|
||||
foreign __llvm_core {
|
||||
proc assume (cond: bool) #link_name "llvm.assume";
|
||||
proc __debug_trap () #link_name "llvm.debugtrap";
|
||||
proc __trap () #link_name "llvm.trap";
|
||||
proc read_cycle_counter() -> u64 #link_name "llvm.readcyclecounter";
|
||||
}
|
||||
|
||||
// IMPORTANT NOTE(bill): Must be in this order (as the compiler relies upon it)
|
||||
type (
|
||||
@@ -382,7 +382,7 @@ proc __string_decode_rune(s: string) -> (rune, int) #inline {
|
||||
|
||||
|
||||
proc __mem_set(data: rawptr, value: i32, len: int) -> rawptr {
|
||||
proc llvm_memset_64bit(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) #foreign __llvm_core "llvm.memset.p0i8.i64";
|
||||
foreign __llvm_core proc llvm_memset_64bit(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) #link_name "llvm.memset.p0i8.i64";
|
||||
llvm_memset_64bit(data, u8(value), len, 1, false);
|
||||
return data;
|
||||
}
|
||||
@@ -391,13 +391,13 @@ proc __mem_zero(data: rawptr, len: int) -> rawptr {
|
||||
}
|
||||
proc __mem_copy(dst, src: rawptr, len: int) -> rawptr {
|
||||
// NOTE(bill): This _must_ be implemented like C's memmove
|
||||
proc llvm_memmove_64bit(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #foreign __llvm_core "llvm.memmove.p0i8.p0i8.i64";
|
||||
foreign __llvm_core proc llvm_memmove_64bit(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memmove.p0i8.p0i8.i64";
|
||||
llvm_memmove_64bit(dst, src, len, 1, false);
|
||||
return dst;
|
||||
}
|
||||
proc __mem_copy_non_overlapping(dst, src: rawptr, len: int) -> rawptr {
|
||||
// NOTE(bill): This _must_ be implemented like C's memcpy
|
||||
proc llvm_memcpy_64bit(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #foreign __llvm_core "llvm.memcpy.p0i8.p0i8.i64";
|
||||
foreign __llvm_core proc llvm_memcpy_64bit(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memcpy.p0i8.p0i8.i64";
|
||||
llvm_memcpy_64bit(dst, src, len, 1, false);
|
||||
return dst;
|
||||
}
|
||||
@@ -414,8 +414,10 @@ proc __mem_compare(a, b: ^u8, n: int) -> int {
|
||||
return 0;
|
||||
}
|
||||
|
||||
proc __sqrt_f32(x: f32) -> f32 #foreign __llvm_core "llvm.sqrt.f32";
|
||||
proc __sqrt_f64(x: f64) -> f64 #foreign __llvm_core "llvm.sqrt.f64";
|
||||
foreign __llvm_core {
|
||||
proc __sqrt_f32(x: f32) -> f32 #link_name "llvm.sqrt.f32";
|
||||
proc __sqrt_f64(x: f64) -> f64 #link_name "llvm.sqrt.f64";
|
||||
}
|
||||
proc __abs_complex64(x: complex64) -> f32 #inline {
|
||||
var r, i = real(x), imag(x);
|
||||
return __sqrt_f32(r*r + i*i);
|
||||
|
||||
160
core/bits.odin
160
core/bits.odin
@@ -24,16 +24,16 @@ const (
|
||||
I128_MAX = i128(0x7fff_ffff_ffff_ffff_ffff_ffff_ffff_ffff);
|
||||
)
|
||||
|
||||
proc count_ones(i: u8) -> u8 { proc __llvm_ctpop(u8) -> u8 #foreign __llvm_core "llvm.ctpop.i8"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: i8) -> i8 { proc __llvm_ctpop(i8) -> i8 #foreign __llvm_core "llvm.ctpop.i8"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: u16) -> u16 { proc __llvm_ctpop(u16) -> u16 #foreign __llvm_core "llvm.ctpop.i16"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: i16) -> i16 { proc __llvm_ctpop(i16) -> i16 #foreign __llvm_core "llvm.ctpop.i16"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: u32) -> u32 { proc __llvm_ctpop(u32) -> u32 #foreign __llvm_core "llvm.ctpop.i32"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: i32) -> i32 { proc __llvm_ctpop(i32) -> i32 #foreign __llvm_core "llvm.ctpop.i32"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: u64) -> u64 { proc __llvm_ctpop(u64) -> u64 #foreign __llvm_core "llvm.ctpop.i64"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: i64) -> i64 { proc __llvm_ctpop(i64) -> i64 #foreign __llvm_core "llvm.ctpop.i64"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: u128) -> u128 { proc __llvm_ctpop(u128) -> u128 #foreign __llvm_core "llvm.ctpop.i128";return __llvm_ctpop(i); }
|
||||
proc count_ones(i: i128) -> i128 { proc __llvm_ctpop(i128) -> i128 #foreign __llvm_core "llvm.ctpop.i128";return __llvm_ctpop(i); }
|
||||
proc count_ones(i: u8) -> u8 { foreign __llvm_core proc __llvm_ctpop(u8) -> u8 #link_name "llvm.ctpop.i8"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: i8) -> i8 { foreign __llvm_core proc __llvm_ctpop(i8) -> i8 #link_name "llvm.ctpop.i8"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: u16) -> u16 { foreign __llvm_core proc __llvm_ctpop(u16) -> u16 #link_name "llvm.ctpop.i16"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: i16) -> i16 { foreign __llvm_core proc __llvm_ctpop(i16) -> i16 #link_name "llvm.ctpop.i16"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: u32) -> u32 { foreign __llvm_core proc __llvm_ctpop(u32) -> u32 #link_name "llvm.ctpop.i32"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: i32) -> i32 { foreign __llvm_core proc __llvm_ctpop(i32) -> i32 #link_name "llvm.ctpop.i32"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: u64) -> u64 { foreign __llvm_core proc __llvm_ctpop(u64) -> u64 #link_name "llvm.ctpop.i64"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: i64) -> i64 { foreign __llvm_core proc __llvm_ctpop(i64) -> i64 #link_name "llvm.ctpop.i64"; return __llvm_ctpop(i); }
|
||||
proc count_ones(i: u128) -> u128 { foreign __llvm_core proc __llvm_ctpop(u128) -> u128 #link_name "llvm.ctpop.i128";return __llvm_ctpop(i); }
|
||||
proc count_ones(i: i128) -> i128 { foreign __llvm_core proc __llvm_ctpop(i128) -> i128 #link_name "llvm.ctpop.i128";return __llvm_ctpop(i); }
|
||||
proc count_ones(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(count_ones(u32(i))); } else { return uint(count_ones(u64(i))); } }
|
||||
proc count_ones(i: int) -> int { when size_of(int) == size_of(i32) { return int(count_ones(i32(i))); } else { return int(count_ones(i64(i))); } }
|
||||
|
||||
@@ -79,59 +79,59 @@ proc rotate_right(i: uint, s: uint) -> uint { when size_of(uint) == size_of(u32)
|
||||
proc rotate_right(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)); } }
|
||||
|
||||
|
||||
proc leading_zeros(i: u8) -> u8 { proc __llvm_ctlz(u8, bool) -> u8 #foreign __llvm_core "llvm.ctlz.i8"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: i8) -> i8 { proc __llvm_ctlz(i8, bool) -> i8 #foreign __llvm_core "llvm.ctlz.i8"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: u16) -> u16 { proc __llvm_ctlz(u16, bool) -> u16 #foreign __llvm_core "llvm.ctlz.i16"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: i16) -> i16 { proc __llvm_ctlz(i16, bool) -> i16 #foreign __llvm_core "llvm.ctlz.i16"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: u32) -> u32 { proc __llvm_ctlz(u32, bool) -> u32 #foreign __llvm_core "llvm.ctlz.i32"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: i32) -> i32 { proc __llvm_ctlz(i32, bool) -> i32 #foreign __llvm_core "llvm.ctlz.i32"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: u64) -> u64 { proc __llvm_ctlz(u64, bool) -> u64 #foreign __llvm_core "llvm.ctlz.i64"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: i64) -> i64 { proc __llvm_ctlz(i64, bool) -> i64 #foreign __llvm_core "llvm.ctlz.i64"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: u128) -> u128 { proc __llvm_ctlz(u128, bool) -> u128 #foreign __llvm_core "llvm.ctlz.i128";return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: i128) -> i128 { proc __llvm_ctlz(i128, bool) -> i128 #foreign __llvm_core "llvm.ctlz.i128";return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: u8) -> u8 { foreign __llvm_core proc __llvm_ctlz(u8, bool) -> u8 #link_name "llvm.ctlz.i8"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: i8) -> i8 { foreign __llvm_core proc __llvm_ctlz(i8, bool) -> i8 #link_name "llvm.ctlz.i8"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: u16) -> u16 { foreign __llvm_core proc __llvm_ctlz(u16, bool) -> u16 #link_name "llvm.ctlz.i16"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: i16) -> i16 { foreign __llvm_core proc __llvm_ctlz(i16, bool) -> i16 #link_name "llvm.ctlz.i16"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: u32) -> u32 { foreign __llvm_core proc __llvm_ctlz(u32, bool) -> u32 #link_name "llvm.ctlz.i32"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: i32) -> i32 { foreign __llvm_core proc __llvm_ctlz(i32, bool) -> i32 #link_name "llvm.ctlz.i32"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: u64) -> u64 { foreign __llvm_core proc __llvm_ctlz(u64, bool) -> u64 #link_name "llvm.ctlz.i64"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: i64) -> i64 { foreign __llvm_core proc __llvm_ctlz(i64, bool) -> i64 #link_name "llvm.ctlz.i64"; return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: u128) -> u128 { foreign __llvm_core proc __llvm_ctlz(u128, bool) -> u128 #link_name "llvm.ctlz.i128";return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: i128) -> i128 { foreign __llvm_core proc __llvm_ctlz(i128, bool) -> i128 #link_name "llvm.ctlz.i128";return __llvm_ctlz(i, false); }
|
||||
proc leading_zeros(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(leading_zeros(u32(i))); } else { return uint(leading_zeros(u64(i))); } }
|
||||
proc leading_zeros(i: int) -> int { when size_of(int) == size_of(i32) { return int(leading_zeros(i32(i))); } else { return int(leading_zeros(i64(i))); } }
|
||||
|
||||
proc trailing_zeros(i: u8) -> u8 { proc __llvm_cttz(u8, bool) -> u8 #foreign __llvm_core "llvm.cttz.i8"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: i8) -> i8 { proc __llvm_cttz(i8, bool) -> i8 #foreign __llvm_core "llvm.cttz.i8"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: u16) -> u16 { proc __llvm_cttz(u16, bool) -> u16 #foreign __llvm_core "llvm.cttz.i16"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: i16) -> i16 { proc __llvm_cttz(i16, bool) -> i16 #foreign __llvm_core "llvm.cttz.i16"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: u32) -> u32 { proc __llvm_cttz(u32, bool) -> u32 #foreign __llvm_core "llvm.cttz.i32"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: i32) -> i32 { proc __llvm_cttz(i32, bool) -> i32 #foreign __llvm_core "llvm.cttz.i32"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: u64) -> u64 { proc __llvm_cttz(u64, bool) -> u64 #foreign __llvm_core "llvm.cttz.i64"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: i64) -> i64 { proc __llvm_cttz(i64, bool) -> i64 #foreign __llvm_core "llvm.cttz.i64"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: u128) -> u128 { proc __llvm_cttz(u128, bool) -> u128 #foreign __llvm_core "llvm.cttz.i128";return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: i128) -> i128 { proc __llvm_cttz(i128, bool) -> i128 #foreign __llvm_core "llvm.cttz.i128";return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: u8) -> u8 { foreign __llvm_core proc __llvm_cttz(u8, bool) -> u8 #link_name "llvm.cttz.i8"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: i8) -> i8 { foreign __llvm_core proc __llvm_cttz(i8, bool) -> i8 #link_name "llvm.cttz.i8"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: u16) -> u16 { foreign __llvm_core proc __llvm_cttz(u16, bool) -> u16 #link_name "llvm.cttz.i16"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: i16) -> i16 { foreign __llvm_core proc __llvm_cttz(i16, bool) -> i16 #link_name "llvm.cttz.i16"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: u32) -> u32 { foreign __llvm_core proc __llvm_cttz(u32, bool) -> u32 #link_name "llvm.cttz.i32"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: i32) -> i32 { foreign __llvm_core proc __llvm_cttz(i32, bool) -> i32 #link_name "llvm.cttz.i32"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: u64) -> u64 { foreign __llvm_core proc __llvm_cttz(u64, bool) -> u64 #link_name "llvm.cttz.i64"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: i64) -> i64 { foreign __llvm_core proc __llvm_cttz(i64, bool) -> i64 #link_name "llvm.cttz.i64"; return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: u128) -> u128 { foreign __llvm_core proc __llvm_cttz(u128, bool) -> u128 #link_name "llvm.cttz.i128";return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: i128) -> i128 { foreign __llvm_core proc __llvm_cttz(i128, bool) -> i128 #link_name "llvm.cttz.i128";return __llvm_cttz(i, false); }
|
||||
proc trailing_zeros(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(trailing_zeros(u32(i))); } else { return uint(trailing_zeros(u64(i))); } }
|
||||
proc trailing_zeros(i: int) -> int { when size_of(int) == size_of(i32) { return int(trailing_zeros(i32(i))); } else { return int(trailing_zeros(i64(i))); } }
|
||||
|
||||
|
||||
proc reverse_bits(i: u8) -> u8 { proc __llvm_bitreverse(u8) -> u8 #foreign __llvm_core "llvm.bitreverse.i8"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: i8) -> i8 { proc __llvm_bitreverse(i8) -> i8 #foreign __llvm_core "llvm.bitreverse.i8"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: u16) -> u16 { proc __llvm_bitreverse(u16) -> u16 #foreign __llvm_core "llvm.bitreverse.i16"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: i16) -> i16 { proc __llvm_bitreverse(i16) -> i16 #foreign __llvm_core "llvm.bitreverse.i16"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: u32) -> u32 { proc __llvm_bitreverse(u32) -> u32 #foreign __llvm_core "llvm.bitreverse.i32"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: i32) -> i32 { proc __llvm_bitreverse(i32) -> i32 #foreign __llvm_core "llvm.bitreverse.i32"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: u64) -> u64 { proc __llvm_bitreverse(u64) -> u64 #foreign __llvm_core "llvm.bitreverse.i64"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: i64) -> i64 { proc __llvm_bitreverse(i64) -> i64 #foreign __llvm_core "llvm.bitreverse.i64"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: u128) -> u128 { proc __llvm_bitreverse(u128) -> u128 #foreign __llvm_core "llvm.bitreverse.i128";return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: i128) -> i128 { proc __llvm_bitreverse(i128) -> i128 #foreign __llvm_core "llvm.bitreverse.i128";return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: u8) -> u8 { foreign __llvm_core proc __llvm_bitreverse(u8) -> u8 #link_name "llvm.bitreverse.i8"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: i8) -> i8 { foreign __llvm_core proc __llvm_bitreverse(i8) -> i8 #link_name "llvm.bitreverse.i8"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: u16) -> u16 { foreign __llvm_core proc __llvm_bitreverse(u16) -> u16 #link_name "llvm.bitreverse.i16"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: i16) -> i16 { foreign __llvm_core proc __llvm_bitreverse(i16) -> i16 #link_name "llvm.bitreverse.i16"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: u32) -> u32 { foreign __llvm_core proc __llvm_bitreverse(u32) -> u32 #link_name "llvm.bitreverse.i32"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: i32) -> i32 { foreign __llvm_core proc __llvm_bitreverse(i32) -> i32 #link_name "llvm.bitreverse.i32"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: u64) -> u64 { foreign __llvm_core proc __llvm_bitreverse(u64) -> u64 #link_name "llvm.bitreverse.i64"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: i64) -> i64 { foreign __llvm_core proc __llvm_bitreverse(i64) -> i64 #link_name "llvm.bitreverse.i64"; return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: u128) -> u128 { foreign __llvm_core proc __llvm_bitreverse(u128) -> u128 #link_name "llvm.bitreverse.i128";return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: i128) -> i128 { foreign __llvm_core proc __llvm_bitreverse(i128) -> i128 #link_name "llvm.bitreverse.i128";return __llvm_bitreverse(i); }
|
||||
proc reverse_bits(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(reverse_bits(u32(i))); } else { return uint(reverse_bits(u64(i))); } }
|
||||
proc reverse_bits(i: int) -> int { when size_of(int) == size_of(i32) { return int(reverse_bits(i32(i))); } else { return int(reverse_bits(i64(i))); } }
|
||||
|
||||
|
||||
proc byte_swap(u16) -> u16 #foreign __llvm_core "llvm.bswap.i16";
|
||||
proc byte_swap(i16) -> i16 #foreign __llvm_core "llvm.bswap.i16";
|
||||
proc byte_swap(u32) -> u32 #foreign __llvm_core "llvm.bswap.i32";
|
||||
proc byte_swap(i32) -> i32 #foreign __llvm_core "llvm.bswap.i32";
|
||||
proc byte_swap(u64) -> u64 #foreign __llvm_core "llvm.bswap.i64";
|
||||
proc byte_swap(i64) -> i64 #foreign __llvm_core "llvm.bswap.i64";
|
||||
proc byte_swap(u128) -> u128 #foreign __llvm_core "llvm.bswap.i128";
|
||||
proc byte_swap(i128) -> i128 #foreign __llvm_core "llvm.bswap.i128";
|
||||
foreign __llvm_core {
|
||||
proc byte_swap(u16) -> u16 #link_name "llvm.bswap.i16";
|
||||
proc byte_swap(i16) -> i16 #link_name "llvm.bswap.i16";
|
||||
proc byte_swap(u32) -> u32 #link_name "llvm.bswap.i32";
|
||||
proc byte_swap(i32) -> i32 #link_name "llvm.bswap.i32";
|
||||
proc byte_swap(u64) -> u64 #link_name "llvm.bswap.i64";
|
||||
proc byte_swap(i64) -> i64 #link_name "llvm.bswap.i64";
|
||||
proc byte_swap(u128) -> u128 #link_name "llvm.bswap.i128";
|
||||
proc byte_swap(i128) -> i128 #link_name "llvm.bswap.i128";
|
||||
}
|
||||
proc byte_swap(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(byte_swap(u32(i))); } else { return uint(byte_swap(u64(i))); } }
|
||||
proc byte_swap(i: int) -> int { when size_of(int) == size_of(i32) { return int(byte_swap(i32(i))); } else { return int(byte_swap(i64(i))); } }
|
||||
|
||||
|
||||
proc from_be(i: u8) -> u8 { return i; }
|
||||
proc from_be(i: i8) -> i8 { return i; }
|
||||
proc from_be(i: u16) -> u16 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
|
||||
@@ -186,16 +186,16 @@ proc to_le(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i; } else {
|
||||
proc to_le(i: int) -> int { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
|
||||
|
||||
|
||||
proc overflowing_add(lhs, rhs: u8) -> (u8, bool) { proc op(u8, u8) -> (u8, bool) #foreign __llvm_core "llvm.uadd.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: i8) -> (i8, bool) { proc op(i8, i8) -> (i8, bool) #foreign __llvm_core "llvm.sadd.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: u16) -> (u16, bool) { proc op(u16, u16) -> (u16, bool) #foreign __llvm_core "llvm.uadd.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: i16) -> (i16, bool) { proc op(i16, i16) -> (i16, bool) #foreign __llvm_core "llvm.sadd.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: u32) -> (u32, bool) { proc op(u32, u32) -> (u32, bool) #foreign __llvm_core "llvm.uadd.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: i32) -> (i32, bool) { proc op(i32, i32) -> (i32, bool) #foreign __llvm_core "llvm.sadd.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: u64) -> (u64, bool) { proc op(u64, u64) -> (u64, bool) #foreign __llvm_core "llvm.uadd.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: i64) -> (i64, bool) { proc op(i64, i64) -> (i64, bool) #foreign __llvm_core "llvm.sadd.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: u128) -> (u128, bool) { proc op(u128, u128) -> (u128, bool) #foreign __llvm_core "llvm.uadd.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: i128) -> (i128, bool) { proc op(i128, i128) -> (i128, bool) #foreign __llvm_core "llvm.sadd.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core proc op(u8, u8) -> (u8, bool) #link_name "llvm.uadd.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core proc op(i8, i8) -> (i8, bool) #link_name "llvm.sadd.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core proc op(u16, u16) -> (u16, bool) #link_name "llvm.uadd.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core proc op(i16, i16) -> (i16, bool) #link_name "llvm.sadd.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core proc op(u32, u32) -> (u32, bool) #link_name "llvm.uadd.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core proc op(i32, i32) -> (i32, bool) #link_name "llvm.sadd.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core proc op(u64, u64) -> (u64, bool) #link_name "llvm.uadd.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core proc op(i64, i64) -> (i64, bool) #link_name "llvm.sadd.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core proc op(u128, u128) -> (u128, bool) #link_name "llvm.uadd.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core proc op(i128, i128) -> (i128, bool) #link_name "llvm.sadd.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_add(lhs, rhs: uint) -> (uint, bool) {
|
||||
when size_of(uint) == size_of(u32) {
|
||||
var x, ok = overflowing_add(u32(lhs), u32(rhs));
|
||||
@@ -215,16 +215,16 @@ proc overflowing_add(lhs, rhs: int) -> (int, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
proc overflowing_sub(lhs, rhs: u8) -> (u8, bool) { proc op(u8, u8) -> (u8, bool) #foreign __llvm_core "llvm.usub.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: i8) -> (i8, bool) { proc op(i8, i8) -> (i8, bool) #foreign __llvm_core "llvm.ssub.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: u16) -> (u16, bool) { proc op(u16, u16) -> (u16, bool) #foreign __llvm_core "llvm.usub.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: i16) -> (i16, bool) { proc op(i16, i16) -> (i16, bool) #foreign __llvm_core "llvm.ssub.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: u32) -> (u32, bool) { proc op(u32, u32) -> (u32, bool) #foreign __llvm_core "llvm.usub.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: i32) -> (i32, bool) { proc op(i32, i32) -> (i32, bool) #foreign __llvm_core "llvm.ssub.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: u64) -> (u64, bool) { proc op(u64, u64) -> (u64, bool) #foreign __llvm_core "llvm.usub.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: i64) -> (i64, bool) { proc op(i64, i64) -> (i64, bool) #foreign __llvm_core "llvm.ssub.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: u128) -> (u128, bool) { proc op(u128, u128) -> (u128, bool) #foreign __llvm_core "llvm.usub.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: i128) -> (i128, bool) { proc op(i128, i128) -> (i128, bool) #foreign __llvm_core "llvm.ssub.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core proc op(u8, u8) -> (u8, bool) #link_name "llvm.usub.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core proc op(i8, i8) -> (i8, bool) #link_name "llvm.ssub.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core proc op(u16, u16) -> (u16, bool) #link_name "llvm.usub.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core proc op(i16, i16) -> (i16, bool) #link_name "llvm.ssub.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core proc op(u32, u32) -> (u32, bool) #link_name "llvm.usub.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core proc op(i32, i32) -> (i32, bool) #link_name "llvm.ssub.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core proc op(u64, u64) -> (u64, bool) #link_name "llvm.usub.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core proc op(i64, i64) -> (i64, bool) #link_name "llvm.ssub.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core proc op(u128, u128) -> (u128, bool) #link_name "llvm.usub.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core proc op(i128, i128) -> (i128, bool) #link_name "llvm.ssub.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_sub(lhs, rhs: uint) -> (uint, bool) {
|
||||
when size_of(uint) == size_of(u32) {
|
||||
var x, ok = overflowing_sub(u32(lhs), u32(rhs));
|
||||
@@ -244,16 +244,16 @@ proc overflowing_sub(lhs, rhs: int) -> (int, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
proc overflowing_mul(lhs, rhs: u8) -> (u8, bool) { proc op(u8, u8) -> (u8, bool) #foreign __llvm_core "llvm.umul.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: i8) -> (i8, bool) { proc op(i8, i8) -> (i8, bool) #foreign __llvm_core "llvm.smul.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: u16) -> (u16, bool) { proc op(u16, u16) -> (u16, bool) #foreign __llvm_core "llvm.umul.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: i16) -> (i16, bool) { proc op(i16, i16) -> (i16, bool) #foreign __llvm_core "llvm.smul.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: u32) -> (u32, bool) { proc op(u32, u32) -> (u32, bool) #foreign __llvm_core "llvm.umul.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: i32) -> (i32, bool) { proc op(i32, i32) -> (i32, bool) #foreign __llvm_core "llvm.smul.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: u64) -> (u64, bool) { proc op(u64, u64) -> (u64, bool) #foreign __llvm_core "llvm.umul.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: i64) -> (i64, bool) { proc op(i64, i64) -> (i64, bool) #foreign __llvm_core "llvm.smul.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: u128) -> (u128, bool) { proc op(u128, u128) -> (u128, bool) #foreign __llvm_core "llvm.umul.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: i128) -> (i128, bool) { proc op(i128, i128) -> (i128, bool) #foreign __llvm_core "llvm.smul.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core proc op(u8, u8) -> (u8, bool) #link_name "llvm.umul.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core proc op(i8, i8) -> (i8, bool) #link_name "llvm.smul.with.overflow.i8"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core proc op(u16, u16) -> (u16, bool) #link_name "llvm.umul.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core proc op(i16, i16) -> (i16, bool) #link_name "llvm.smul.with.overflow.i16"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core proc op(u32, u32) -> (u32, bool) #link_name "llvm.umul.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core proc op(i32, i32) -> (i32, bool) #link_name "llvm.smul.with.overflow.i32"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core proc op(u64, u64) -> (u64, bool) #link_name "llvm.umul.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core proc op(i64, i64) -> (i64, bool) #link_name "llvm.smul.with.overflow.i64"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core proc op(u128, u128) -> (u128, bool) #link_name "llvm.umul.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core proc op(i128, i128) -> (i128, bool) #link_name "llvm.smul.with.overflow.i128"; return op(lhs, rhs); }
|
||||
proc overflowing_mul(lhs, rhs: uint) -> (uint, bool) {
|
||||
when size_of(uint) == size_of(u32) {
|
||||
var x, ok = overflowing_mul(u32(lhs), u32(rhs));
|
||||
|
||||
@@ -30,21 +30,26 @@ type (
|
||||
Complex complex64;
|
||||
)
|
||||
|
||||
proc sqrt(x: f32) -> f32 #foreign __llvm_core "llvm.sqrt.f32";
|
||||
proc sqrt(x: f64) -> f64 #foreign __llvm_core "llvm.sqrt.f64";
|
||||
foreign __llvm_core {
|
||||
proc sqrt(x: f32) -> f32 #link_name "llvm.sqrt.f32";
|
||||
proc sqrt(x: f64) -> f64 #link_name "llvm.sqrt.f64";
|
||||
|
||||
proc sin (θ: f32) -> f32 #foreign __llvm_core "llvm.sin.f32";
|
||||
proc sin (θ: f64) -> f64 #foreign __llvm_core "llvm.sin.f64";
|
||||
proc sin (θ: f32) -> f32 #link_name "llvm.sin.f32";
|
||||
proc sin (θ: f64) -> f64 #link_name "llvm.sin.f64";
|
||||
|
||||
proc cos (θ: f32) -> f32 #foreign __llvm_core "llvm.cos.f32";
|
||||
proc cos (θ: f64) -> f64 #foreign __llvm_core "llvm.cos.f64";
|
||||
proc cos (θ: f32) -> f32 #link_name "llvm.cos.f32";
|
||||
proc cos (θ: f64) -> f64 #link_name "llvm.cos.f64";
|
||||
|
||||
proc pow (x, power: f32) -> f32 #link_name "llvm.pow.f32";
|
||||
proc pow (x, power: f64) -> f64 #link_name "llvm.pow.f64";
|
||||
|
||||
proc fmuladd(a, b, c: f32) -> f32 #link_name "llvm.fmuladd.f32";
|
||||
proc fmuladd(a, b, c: f64) -> f64 #link_name "llvm.fmuladd.f64";
|
||||
}
|
||||
|
||||
proc tan (θ: f32) -> f32 #inline { return sin(θ)/cos(θ); }
|
||||
proc tan (θ: f64) -> f64 #inline { return sin(θ)/cos(θ); }
|
||||
|
||||
proc pow (x, power: f32) -> f32 #foreign __llvm_core "llvm.pow.f32";
|
||||
proc pow (x, power: f64) -> f64 #foreign __llvm_core "llvm.pow.f64";
|
||||
|
||||
|
||||
proc lerp (a, b, t: f32) -> (x: f32) { return a*(1-t) + b*t; }
|
||||
proc lerp (a, b, t: f64) -> (x: f64) { return a*(1-t) + b*t; }
|
||||
@@ -55,8 +60,6 @@ proc unlerp(a, b, x: f64) -> (t: f64) { return (x-a)/(b-a); }
|
||||
proc sign(x: f32) -> f32 { return x >= 0 ? +1 : -1; }
|
||||
proc sign(x: f64) -> f64 { return x >= 0 ? +1 : -1; }
|
||||
|
||||
proc fmuladd(a, b, c: f32) -> f32 #foreign __llvm_core "llvm.fmuladd.f32";
|
||||
proc fmuladd(a, b, c: f64) -> f64 #foreign __llvm_core "llvm.fmuladd.f64";
|
||||
|
||||
|
||||
proc copy_sign(x, y: f32) -> f32 {
|
||||
|
||||
@@ -2,11 +2,11 @@ import (
|
||||
"fmt.odin";
|
||||
"os.odin";
|
||||
)
|
||||
|
||||
proc swap(b: u16) -> u16 #foreign __llvm_core "llvm.bswap.i16";
|
||||
proc swap(b: u32) -> u32 #foreign __llvm_core "llvm.bswap.i32";
|
||||
proc swap(b: u64) -> u64 #foreign __llvm_core "llvm.bswap.i64";
|
||||
|
||||
foreign __llvm_core {
|
||||
proc swap(b: u16) -> u16 #link_name "llvm.bswap.i16";
|
||||
proc swap(b: u32) -> u32 #link_name "llvm.bswap.i32";
|
||||
proc swap(b: u64) -> u64 #link_name "llvm.bswap.i64";
|
||||
}
|
||||
|
||||
proc set(data: rawptr, value: i32, len: int) -> rawptr {
|
||||
return __mem_set(data, value, len);
|
||||
|
||||
@@ -8,31 +8,33 @@ import (
|
||||
)
|
||||
import_load "opengl_constants.odin";
|
||||
|
||||
proc Clear (mask: u32) #foreign lib "glClear";
|
||||
proc ClearColor (r, g, b, a: f32) #foreign lib "glClearColor";
|
||||
proc Begin (mode: i32) #foreign lib "glBegin";
|
||||
proc End () #foreign lib "glEnd";
|
||||
proc Finish () #foreign lib "glFinish";
|
||||
proc BlendFunc (sfactor, dfactor: i32) #foreign lib "glBlendFunc";
|
||||
proc Enable (cap: i32) #foreign lib "glEnable";
|
||||
proc Disable (cap: i32) #foreign lib "glDisable";
|
||||
proc GenTextures (count: i32, result: ^u32) #foreign lib "glGenTextures";
|
||||
proc DeleteTextures(count: i32, result: ^u32) #foreign lib "glDeleteTextures";
|
||||
proc TexParameteri (target, pname, param: i32) #foreign lib "glTexParameteri";
|
||||
proc TexParameterf (target: i32, pname: i32, param: f32) #foreign lib "glTexParameterf";
|
||||
proc BindTexture (target: i32, texture: u32) #foreign lib "glBindTexture";
|
||||
proc LoadIdentity () #foreign lib "glLoadIdentity";
|
||||
proc Viewport (x, y, width, height: i32) #foreign lib "glViewport";
|
||||
proc Ortho (left, right, bottom, top, near, far: f64) #foreign lib "glOrtho";
|
||||
proc Color3f (r, g, b: f32) #foreign lib "glColor3f";
|
||||
proc Vertex3f (x, y, z: f32) #foreign lib "glVertex3f";
|
||||
proc GetError () -> i32 #foreign lib "glGetError";
|
||||
proc GetString (name: i32) -> ^u8 #foreign lib "glGetString";
|
||||
proc GetIntegerv (name: i32, v: ^i32) #foreign lib "glGetIntegerv";
|
||||
proc TexCoord2f (x, y: f32) #foreign lib "glTexCoord2f";
|
||||
proc TexImage2D (target, level, internal_format,
|
||||
width, height, border,
|
||||
format, type_: i32, pixels: rawptr) #foreign lib "glTexImage2D";
|
||||
foreign lib {
|
||||
proc Clear (mask: u32) #link_name "glClear";
|
||||
proc ClearColor (r, g, b, a: f32) #link_name "glClearColor";
|
||||
proc Begin (mode: i32) #link_name "glBegin";
|
||||
proc End () #link_name "glEnd";
|
||||
proc Finish () #link_name "glFinish";
|
||||
proc BlendFunc (sfactor, dfactor: i32) #link_name "glBlendFunc";
|
||||
proc Enable (cap: i32) #link_name "glEnable";
|
||||
proc Disable (cap: i32) #link_name "glDisable";
|
||||
proc GenTextures (count: i32, result: ^u32) #link_name "glGenTextures";
|
||||
proc DeleteTextures(count: i32, result: ^u32) #link_name "glDeleteTextures";
|
||||
proc TexParameteri (target, pname, param: i32) #link_name "glTexParameteri";
|
||||
proc TexParameterf (target: i32, pname: i32, param: f32) #link_name "glTexParameterf";
|
||||
proc BindTexture (target: i32, texture: u32) #link_name "glBindTexture";
|
||||
proc LoadIdentity () #link_name "glLoadIdentity";
|
||||
proc Viewport (x, y, width, height: i32) #link_name "glViewport";
|
||||
proc Ortho (left, right, bottom, top, near, far: f64) #link_name "glOrtho";
|
||||
proc Color3f (r, g, b: f32) #link_name "glColor3f";
|
||||
proc Vertex3f (x, y, z: f32) #link_name "glVertex3f";
|
||||
proc GetError () -> i32 #link_name "glGetError";
|
||||
proc GetString (name: i32) -> ^u8 #link_name "glGetString";
|
||||
proc GetIntegerv (name: i32, v: ^i32) #link_name "glGetIntegerv";
|
||||
proc TexCoord2f (x, y: f32) #link_name "glTexCoord2f";
|
||||
proc TexImage2D (target, level, internal_format,
|
||||
width, height, border,
|
||||
format, type_: i32, pixels: rawptr) #link_name "glTexImage2D";
|
||||
}
|
||||
|
||||
|
||||
proc _string_data(s: string) -> ^u8 #inline { return &s[0]; }
|
||||
|
||||
@@ -125,26 +125,29 @@ const (
|
||||
F_OK = 0; // Test for file existance
|
||||
)
|
||||
|
||||
proc _unix_open (path: ^u8, mode: int) -> Handle #foreign libc "open";
|
||||
proc _unix_close (fd: Handle) -> i32 #foreign libc "close";
|
||||
proc _unix_read (fd: Handle, buf: rawptr, size: int) -> int #foreign libc "read";
|
||||
proc _unix_write (fd: Handle, buf: rawptr, size: int) -> int #foreign libc "write";
|
||||
proc _unix_seek (fd: Handle, offset: i64, whence: i32) -> i64 #foreign libc "lseek64";
|
||||
proc _unix_gettid() -> u64 #foreign libc "gettid";
|
||||
proc _unix_stat (path: ^u8, stat: ^Stat) -> i32 #foreign libc "stat";
|
||||
proc _unix_access(path: ^u8, mask: int) -> i32 #foreign libc "access";
|
||||
foreign libc {
|
||||
proc _unix_open (path: ^u8, mode: int) -> Handle #link_name "open";
|
||||
proc _unix_close (fd: Handle) -> i32 #link_name "close";
|
||||
proc _unix_read (fd: Handle, buf: rawptr, size: int) -> int #link_name "read";
|
||||
proc _unix_write (fd: Handle, buf: rawptr, size: int) -> int #link_name "write";
|
||||
proc _unix_seek (fd: Handle, offset: i64, whence: i32) -> i64 #link_name "lseek64";
|
||||
proc _unix_gettid() -> u64 #link_name "gettid";
|
||||
proc _unix_stat (path: ^u8, stat: ^Stat) -> i32 #link_name "stat";
|
||||
proc _unix_access(path: ^u8, mask: int) -> i32 #link_name "access";
|
||||
|
||||
proc _unix_malloc (size: int) -> rawptr #foreign libc "malloc";
|
||||
proc _unix_free (ptr: rawptr) #foreign libc "free";
|
||||
proc _unix_realloc(ptr: rawptr, size: int) -> rawptr #foreign libc "realloc";
|
||||
proc _unix_getenv (^u8) -> ^u8 #foreign libc "getenv";
|
||||
proc _unix_malloc (size: int) -> rawptr #link_name "malloc";
|
||||
proc _unix_free (ptr: rawptr) #link_name "free";
|
||||
proc _unix_realloc(ptr: rawptr, size: int) -> rawptr #link_name "realloc";
|
||||
proc _unix_getenv (^u8) -> ^u8 #link_name "getenv";
|
||||
|
||||
proc _unix_exit(status: int) #foreign libc "exit";
|
||||
|
||||
proc _unix_dlopen (filename: ^u8, flags: int) -> rawptr #foreign dl "dlopen";
|
||||
proc _unix_dlsym (handle: rawptr, symbol: ^u8) -> (proc() #cc_c) #foreign dl "dlsym";
|
||||
proc _unix_dlclose(handle: rawptr) -> int #foreign dl "dlclose";
|
||||
proc _unix_dlerror() -> ^u8 #foreign dl "dlerror";
|
||||
proc _unix_exit(status: int) #link_name "exit";
|
||||
}
|
||||
foreign dl {
|
||||
proc _unix_dlopen (filename: ^u8, flags: int) -> rawptr #link_name "dlopen";
|
||||
proc _unix_dlsym (handle: rawptr, symbol: ^u8) -> (proc() #cc_c) #link_name "dlsym";
|
||||
proc _unix_dlclose(handle: rawptr) -> int #link_name "dlclose";
|
||||
proc _unix_dlerror() -> ^u8 #link_name "dlerror";
|
||||
}
|
||||
|
||||
// TODO(zangent): Change this to just `open` when Bill fixes overloading.
|
||||
proc open_simple(path: string, mode: int) -> (Handle, Errno) {
|
||||
|
||||
@@ -125,27 +125,30 @@ const (
|
||||
F_OK = 0; // Test for file existance
|
||||
)
|
||||
|
||||
proc unix_open (path: ^u8, mode: int) -> Handle #foreign libc "open";
|
||||
proc unix_close (handle: Handle) #foreign libc "close";
|
||||
proc unix_read (handle: Handle, buffer: rawptr, count: int) -> AddressSize #foreign libc "read";
|
||||
proc unix_write (handle: Handle, buffer: rawptr, count: int) -> AddressSize #foreign libc "write";
|
||||
proc unix_lseek (fs: Handle, offset: AddressSize, whence: int) -> AddressSize #foreign libc "lseek";
|
||||
proc unix_gettid() -> u64 #foreign libc "gettid";
|
||||
proc unix_stat (path: ^u8, stat: ^Stat) -> int #foreign libc "stat";
|
||||
proc unix_access(path: ^u8, mask: int) -> int #foreign libc "access";
|
||||
foreign libc {
|
||||
proc unix_open (path: ^u8, mode: int) -> Handle #link_name "open";
|
||||
proc unix_close (handle: Handle) #link_name "close";
|
||||
proc unix_read (handle: Handle, buffer: rawptr, count: int) -> AddressSize #link_name "read";
|
||||
proc unix_write (handle: Handle, buffer: rawptr, count: int) -> AddressSize #link_name "write";
|
||||
proc unix_lseek (fs: Handle, offset: AddressSize, whence: int) -> AddressSize #link_name "lseek";
|
||||
proc unix_gettid() -> u64 #link_name "gettid";
|
||||
proc unix_stat (path: ^u8, stat: ^Stat) -> int #link_name "stat";
|
||||
proc unix_access(path: ^u8, mask: int) -> int #link_name "access";
|
||||
|
||||
proc unix_malloc (size: int) -> rawptr #foreign libc "malloc";
|
||||
proc unix_free (ptr: rawptr) #foreign libc "free";
|
||||
proc unix_realloc(ptr: rawptr, size: int) -> rawptr #foreign libc "realloc";
|
||||
proc unix_getenv (^u8) -> ^u8 #foreign libc "getenv";
|
||||
proc unix_malloc (size: int) -> rawptr #link_name "malloc";
|
||||
proc unix_free (ptr: rawptr) #link_name "free";
|
||||
proc unix_realloc(ptr: rawptr, size: int) -> rawptr #link_name "realloc";
|
||||
proc unix_getenv (^u8) -> ^u8 #link_name "getenv";
|
||||
|
||||
proc unix_exit(status: int) #foreign libc "exit";
|
||||
|
||||
proc unix_dlopen (filename: ^u8, flags: int) -> rawptr #foreign dl "dlopen";
|
||||
proc unix_dlsym (handle: rawptr, symbol: ^u8) -> (proc() #cc_c) #foreign dl "dlsym";
|
||||
proc unix_dlclose(handle: rawptr) -> int #foreign dl "dlclose";
|
||||
proc unix_dlerror() -> ^u8 #foreign dl "dlerror";
|
||||
proc unix_exit(status: int) #link_name "exit";
|
||||
}
|
||||
|
||||
foreign dl {
|
||||
proc unix_dlopen (filename: ^u8, flags: int) -> rawptr #link_name "dlopen";
|
||||
proc unix_dlsym (handle: rawptr, symbol: ^u8) -> (proc() #cc_c) #link_name "dlsym";
|
||||
proc unix_dlclose(handle: rawptr) -> int #link_name "dlclose";
|
||||
proc unix_dlerror() -> ^u8 #link_name "dlerror";
|
||||
}
|
||||
|
||||
// TODO(zangent): Change this to just `open` when Bill fixes overloading.
|
||||
proc open_simple(path: string, mode: int) -> (Handle, Errno) {
|
||||
|
||||
@@ -70,19 +70,21 @@ var (
|
||||
)
|
||||
|
||||
|
||||
proc create_context (hdc: Hdc) -> Hglrc #foreign opengl32 "wglCreateContext";
|
||||
proc make_current (hdc: Hdc, hglrc: Hglrc) -> Bool #foreign opengl32 "wglMakeCurrent";
|
||||
proc get_proc_address (c_str: ^u8) -> Proc #foreign opengl32 "wglGetProcAddress";
|
||||
proc delete_context (hglrc: Hglrc) -> Bool #foreign opengl32 "wglDeleteContext";
|
||||
proc copy_context (src, dst: Hglrc, mask: u32) -> Bool #foreign opengl32 "wglCopyContext";
|
||||
proc create_layer_context (hdc: Hdc, layer_plane: i32) -> Hglrc #foreign opengl32 "wglCreateLayerContext";
|
||||
proc describe_layer_plane (hdc: Hdc, pixel_format, layer_plane: i32, bytes: u32, pd: ^LayerPlaneDescriptor) -> Bool #foreign opengl32 "wglDescribeLayerPlane";
|
||||
proc get_current_context () -> Hglrc #foreign opengl32 "wglGetCurrentContext";
|
||||
proc get_current_dc () -> Hdc #foreign opengl32 "wglGetCurrentDC";
|
||||
proc get_layer_palette_entries(hdc: Hdc, layer_plane, start, entries: i32, cr: ^ColorRef) -> i32 #foreign opengl32 "wglGetLayerPaletteEntries";
|
||||
proc realize_layer_palette (hdc: Hdc, layer_plane: i32, realize: Bool) -> Bool #foreign opengl32 "wglRealizeLayerPalette";
|
||||
proc set_layer_palette_entries(hdc: Hdc, layer_plane, start, entries: i32, cr: ^ColorRef) -> i32 #foreign opengl32 "wglSetLayerPaletteEntries";
|
||||
proc share_lists (hglrc1, hglrc2: Hglrc) -> Bool #foreign opengl32 "wglShareLists";
|
||||
proc swap_layer_buffers (hdc: Hdc, planes: u32) -> Bool #foreign opengl32 "wglSwapLayerBuffers";
|
||||
proc use_font_bitmaps (hdc: Hdc, first, count, list_base: u32) -> Bool #foreign opengl32 "wglUseFontBitmaps";
|
||||
proc use_font_outlines (hdc: Hdc, first, count, list_base: u32, deviation, extrusion: f32, format: i32, gmf: ^Glyph_MetricsFloat) -> Bool #foreign opengl32 "wglUseFontOutlines";
|
||||
foreign opengl32 {
|
||||
proc create_context (hdc: Hdc) -> Hglrc #link_name "wglCreateContext";
|
||||
proc make_current (hdc: Hdc, hglrc: Hglrc) -> Bool #link_name "wglMakeCurrent";
|
||||
proc get_proc_address (c_str: ^u8) -> Proc #link_name "wglGetProcAddress";
|
||||
proc delete_context (hglrc: Hglrc) -> Bool #link_name "wglDeleteContext";
|
||||
proc copy_context (src, dst: Hglrc, mask: u32) -> Bool #link_name "wglCopyContext";
|
||||
proc create_layer_context (hdc: Hdc, layer_plane: i32) -> Hglrc #link_name "wglCreateLayerContext";
|
||||
proc describe_layer_plane (hdc: Hdc, pixel_format, layer_plane: i32, bytes: u32, pd: ^LayerPlaneDescriptor) -> Bool #link_name "wglDescribeLayerPlane";
|
||||
proc get_current_context () -> Hglrc #link_name "wglGetCurrentContext";
|
||||
proc get_current_dc () -> Hdc #link_name "wglGetCurrentDC";
|
||||
proc get_layer_palette_entries(hdc: Hdc, layer_plane, start, entries: i32, cr: ^ColorRef) -> i32 #link_name "wglGetLayerPaletteEntries";
|
||||
proc realize_layer_palette (hdc: Hdc, layer_plane: i32, realize: Bool) -> Bool #link_name "wglRealizeLayerPalette";
|
||||
proc set_layer_palette_entries(hdc: Hdc, layer_plane, start, entries: i32, cr: ^ColorRef) -> i32 #link_name "wglSetLayerPaletteEntries";
|
||||
proc share_lists (hglrc1, hglrc2: Hglrc) -> Bool #link_name "wglShareLists";
|
||||
proc swap_layer_buffers (hdc: Hdc, planes: u32) -> Bool #link_name "wglSwapLayerBuffers";
|
||||
proc use_font_bitmaps (hdc: Hdc, first, count, list_base: u32) -> Bool #link_name "wglUseFontBitmaps";
|
||||
proc use_font_outlines (hdc: Hdc, first, count, list_base: u32, deviation, extrusion: f32, format: i32, gmf: ^Glyph_MetricsFloat) -> Bool #link_name "wglUseFontOutlines";
|
||||
}
|
||||
|
||||
@@ -17,82 +17,15 @@ type (
|
||||
Hbrush Handle;
|
||||
Hgdiobj Handle;
|
||||
Hmodule Handle;
|
||||
Hmonitor Handle;
|
||||
Wparam uint;
|
||||
Lparam int;
|
||||
Lresult int;
|
||||
Bool i32;
|
||||
WndProc proc(Hwnd, u32, Wparam, Lparam) -> Lresult #cc_c;
|
||||
|
||||
)
|
||||
|
||||
const INVALID_HANDLE = Handle(~int(0));
|
||||
const (
|
||||
FALSE: Bool = 0;
|
||||
TRUE = 1;
|
||||
)
|
||||
|
||||
const (
|
||||
CS_VREDRAW = 0x0001;
|
||||
CS_HREDRAW = 0x0002;
|
||||
CS_OWNDC = 0x0020;
|
||||
CW_USEDEFAULT = -0x80000000;
|
||||
|
||||
WS_OVERLAPPED = 0;
|
||||
WS_MAXIMIZEBOX = 0x00010000;
|
||||
WS_MINIMIZEBOX = 0x00020000;
|
||||
WS_THICKFRAME = 0x00040000;
|
||||
WS_SYSMENU = 0x00080000;
|
||||
WS_BORDER = 0x00800000;
|
||||
WS_CAPTION = 0x00C00000;
|
||||
WS_VISIBLE = 0x10000000;
|
||||
WS_POPUP = 0x80000000;
|
||||
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
|
||||
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU;
|
||||
|
||||
WM_DESTROY = 0x0002;
|
||||
WM_SIZE = 0x0005;
|
||||
WM_CLOSE = 0x0010;
|
||||
WM_ACTIVATEAPP = 0x001C;
|
||||
WM_QUIT = 0x0012;
|
||||
WM_KEYDOWN = 0x0100;
|
||||
WM_KEYUP = 0x0101;
|
||||
WM_SIZING = 0x0214;
|
||||
WM_SYSKEYDOWN = 0x0104;
|
||||
WM_SYSKEYUP = 0x0105;
|
||||
WM_WINDOWPOSCHANGED = 0x0047;
|
||||
WM_SETCURSOR = 0x0020;
|
||||
WM_CHAR = 0x0102;
|
||||
WM_ACTIVATE = 0x0006;
|
||||
WM_SETFOCUS = 0x0007;
|
||||
WM_KILLFOCUS = 0x0008;
|
||||
WM_USER = 0x0400;
|
||||
|
||||
WM_MOUSEWHEEL = 0x020A;
|
||||
WM_MOUSEMOVE = 0x0200;
|
||||
WM_LBUTTONDOWN = 0x0201;
|
||||
WM_LBUTTONUP = 0x0202;
|
||||
WM_LBUTTONDBLCLK = 0x0203;
|
||||
WM_RBUTTONDOWN = 0x0204;
|
||||
WM_RBUTTONUP = 0x0205;
|
||||
WM_RBUTTONDBLCLK = 0x0206;
|
||||
WM_MBUTTONDOWN = 0x0207;
|
||||
WM_MBUTTONUP = 0x0208;
|
||||
WM_MBUTTONDBLCLK = 0x0209;
|
||||
|
||||
PM_NOREMOVE = 0x0000;
|
||||
PM_REMOVE = 0x0001;
|
||||
PM_NOYIELD = 0x0002;
|
||||
|
||||
BLACK_BRUSH = 4;
|
||||
|
||||
SM_CXSCREEN = 0;
|
||||
SM_CYSCREEN = 1;
|
||||
|
||||
SW_SHOW = 5;
|
||||
)
|
||||
|
||||
const COLOR_BACKGROUND = Hbrush(int(1));
|
||||
|
||||
|
||||
type Point struct #ordered {
|
||||
x, y: i32,
|
||||
}
|
||||
@@ -170,6 +103,179 @@ type FindData struct #ordered {
|
||||
alternate_file_name: [14]u8,
|
||||
}
|
||||
|
||||
type Security_Attributes struct #ordered {
|
||||
length: u32,
|
||||
security_descriptor: rawptr,
|
||||
inherit_handle: Bool,
|
||||
}
|
||||
|
||||
|
||||
|
||||
type PixelFormatDescriptor struct #ordered {
|
||||
size,
|
||||
version,
|
||||
flags: u32,
|
||||
|
||||
pixel_type,
|
||||
color_bits,
|
||||
red_bits,
|
||||
red_shift,
|
||||
green_bits,
|
||||
green_shift,
|
||||
blue_bits,
|
||||
blue_shift,
|
||||
alpha_bits,
|
||||
alpha_shift,
|
||||
accum_bits,
|
||||
accum_red_bits,
|
||||
accum_green_bits,
|
||||
accum_blue_bits,
|
||||
accum_alpha_bits,
|
||||
depth_bits,
|
||||
stencil_bits,
|
||||
aux_buffers,
|
||||
layer_type,
|
||||
reserved: u8,
|
||||
|
||||
layer_mask,
|
||||
visible_mask,
|
||||
damage_mask: u32,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
type Proc proc() #cc_c;
|
||||
|
||||
const (
|
||||
MAPVK_VK_TO_CHAR = 2;
|
||||
MAPVK_VK_TO_VSC = 0;
|
||||
MAPVK_VSC_TO_VK = 1;
|
||||
MAPVK_VSC_TO_VK_EX = 3;
|
||||
)
|
||||
|
||||
|
||||
|
||||
const INVALID_HANDLE = Handle(~int(0));
|
||||
const (
|
||||
FALSE: Bool = 0;
|
||||
TRUE = 1;
|
||||
)
|
||||
|
||||
const (
|
||||
CS_VREDRAW = 0x0001;
|
||||
CS_HREDRAW = 0x0002;
|
||||
CS_OWNDC = 0x0020;
|
||||
CW_USEDEFAULT = -0x80000000;
|
||||
|
||||
WS_OVERLAPPED = 0;
|
||||
WS_MAXIMIZEBOX = 0x00010000;
|
||||
WS_MINIMIZEBOX = 0x00020000;
|
||||
WS_THICKFRAME = 0x00040000;
|
||||
WS_SYSMENU = 0x00080000;
|
||||
WS_BORDER = 0x00800000;
|
||||
WS_CAPTION = 0x00C00000;
|
||||
WS_VISIBLE = 0x10000000;
|
||||
WS_POPUP = 0x80000000;
|
||||
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
|
||||
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU;
|
||||
|
||||
WM_DESTROY = 0x0002;
|
||||
WM_SIZE = 0x0005;
|
||||
WM_CLOSE = 0x0010;
|
||||
WM_ACTIVATEAPP = 0x001C;
|
||||
WM_QUIT = 0x0012;
|
||||
WM_KEYDOWN = 0x0100;
|
||||
WM_KEYUP = 0x0101;
|
||||
WM_SIZING = 0x0214;
|
||||
WM_SYSKEYDOWN = 0x0104;
|
||||
WM_SYSKEYUP = 0x0105;
|
||||
WM_WINDOWPOSCHANGED = 0x0047;
|
||||
WM_SETCURSOR = 0x0020;
|
||||
WM_CHAR = 0x0102;
|
||||
WM_ACTIVATE = 0x0006;
|
||||
WM_SETFOCUS = 0x0007;
|
||||
WM_KILLFOCUS = 0x0008;
|
||||
WM_USER = 0x0400;
|
||||
|
||||
WM_MOUSEWHEEL = 0x020A;
|
||||
WM_MOUSEMOVE = 0x0200;
|
||||
WM_LBUTTONDOWN = 0x0201;
|
||||
WM_LBUTTONUP = 0x0202;
|
||||
WM_LBUTTONDBLCLK = 0x0203;
|
||||
WM_RBUTTONDOWN = 0x0204;
|
||||
WM_RBUTTONUP = 0x0205;
|
||||
WM_RBUTTONDBLCLK = 0x0206;
|
||||
WM_MBUTTONDOWN = 0x0207;
|
||||
WM_MBUTTONUP = 0x0208;
|
||||
WM_MBUTTONDBLCLK = 0x0209;
|
||||
|
||||
PM_NOREMOVE = 0x0000;
|
||||
PM_REMOVE = 0x0001;
|
||||
PM_NOYIELD = 0x0002;
|
||||
|
||||
BLACK_BRUSH = 4;
|
||||
|
||||
SM_CXSCREEN = 0;
|
||||
SM_CYSCREEN = 1;
|
||||
|
||||
SW_SHOW = 5;
|
||||
)
|
||||
|
||||
const COLOR_BACKGROUND = Hbrush(int(1));
|
||||
|
||||
const INVALID_SET_FILE_POINTER = ~u32(0);
|
||||
const HEAP_ZERO_MEMORY = 0x00000008;
|
||||
const INFINITE = 0xffffffff;
|
||||
const GWL_STYLE = -16;
|
||||
const Hwnd_TOP = Hwnd(uint(0));
|
||||
|
||||
const BI_RGB = 0;
|
||||
const DIB_RGB_COLORS = 0x00;
|
||||
const SRCCOPY: u32 = 0x00cc0020;
|
||||
|
||||
const (
|
||||
MONITOR_DEFAULTTONULL = 0x00000000;
|
||||
MONITOR_DEFAULTTOPRIMARY = 0x00000001;
|
||||
MONITOR_DEFAULTTONEAREST = 0x00000002;
|
||||
)
|
||||
const (
|
||||
SWP_FRAMECHANGED = 0x0020;
|
||||
SWP_NOOWNERZORDER = 0x0200;
|
||||
SWP_NOZORDER = 0x0004;
|
||||
SWP_NOSIZE = 0x0001;
|
||||
SWP_NOMOVE = 0x0002;
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
// Windows OpenGL
|
||||
const (
|
||||
PFD_TYPE_RGBA = 0;
|
||||
PFD_TYPE_COLORINDEX = 1;
|
||||
PFD_MAIN_PLANE = 0;
|
||||
PFD_OVERLAY_PLANE = 1;
|
||||
PFD_UNDERLAY_PLANE = -1;
|
||||
PFD_DOUBLEBUFFER = 1;
|
||||
PFD_STEREO = 2;
|
||||
PFD_DRAW_TO_WINDOW = 4;
|
||||
PFD_DRAW_TO_BITMAP = 8;
|
||||
PFD_SUPPORT_GDI = 16;
|
||||
PFD_SUPPORT_OPENGL = 32;
|
||||
PFD_GENERIC_FORMAT = 64;
|
||||
PFD_NEED_PALETTE = 128;
|
||||
PFD_NEED_SYSTEM_PALETTE = 0x00000100;
|
||||
PFD_SWAP_EXCHANGE = 0x00000200;
|
||||
PFD_SWAP_COPY = 0x00000400;
|
||||
PFD_SWAP_LAYER_BUFFERS = 0x00000800;
|
||||
PFD_GENERIC_ACCELERATED = 0x00001000;
|
||||
PFD_DEPTH_DONTCARE = 0x20000000;
|
||||
PFD_DOUBLEBUFFER_DONTCARE = 0x40000000;
|
||||
PFD_STEREO_DONTCARE = 0x80000000;
|
||||
)
|
||||
|
||||
|
||||
|
||||
type GET_FILEEX_INFO_LEVELS i32;
|
||||
const (
|
||||
@@ -177,50 +283,167 @@ const (
|
||||
GetFileExMaxInfoLevel = 1;
|
||||
)
|
||||
|
||||
proc get_last_error () -> i32 #foreign kernel32 "GetLastError";
|
||||
proc exit_process (exit_code: u32) #foreign kernel32 "ExitProcess";
|
||||
proc get_desktop_window () -> Hwnd #foreign user32 "GetDesktopWindow";
|
||||
proc show_cursor (show : Bool) #foreign user32 "ShowCursor";
|
||||
proc get_cursor_pos (p: ^Point) -> i32 #foreign user32 "GetCursorPos";
|
||||
proc screen_to_client (h: Hwnd, p: ^Point) -> i32 #foreign user32 "ScreenToClient";
|
||||
proc get_module_handle_a(module_name: ^u8) -> Hinstance #foreign kernel32 "GetModuleHandleA";
|
||||
proc get_stock_object (fn_object: i32) -> Hgdiobj #foreign gdi32 "GetStockObject";
|
||||
proc post_quit_message (exit_code: i32) #foreign user32 "PostQuitMessage";
|
||||
proc set_window_text_a (hwnd: Hwnd, c_string: ^u8) -> Bool #foreign user32 "SetWindowTextA";
|
||||
foreign kernel32 {
|
||||
proc get_last_error () -> i32 #link_name "GetLastError";
|
||||
proc exit_process (exit_code: u32) #link_name "ExitProcess";
|
||||
proc get_module_handle_a(module_name: ^u8) -> Hinstance #link_name "GetModuleHandleA";
|
||||
proc sleep(ms: i32) -> i32 #link_name "Sleep";
|
||||
proc query_performance_frequency(result: ^i64) -> i32 #link_name "QueryPerformanceFrequency";
|
||||
proc query_performance_counter (result: ^i64) -> i32 #link_name "QueryPerformanceCounter";
|
||||
proc output_debug_string_a(c_str: ^u8) #link_name "OutputDebugStringA";
|
||||
|
||||
proc query_performance_frequency(result: ^i64) -> i32 #foreign kernel32 "QueryPerformanceFrequency";
|
||||
proc query_performance_counter (result: ^i64) -> i32 #foreign kernel32 "QueryPerformanceCounter";
|
||||
proc get_command_line_a () -> ^u8 #link_name "GetCommandLineA";
|
||||
proc get_command_line_w () -> ^u16 #link_name "GetCommandLineW";
|
||||
proc get_system_metrics (index: i32) -> i32 #link_name "GetSystemMetrics";
|
||||
proc get_current_thread_id () -> u32 #link_name "GetCurrentThreadId";
|
||||
|
||||
proc sleep(ms: i32) -> i32 #foreign kernel32 "Sleep";
|
||||
proc get_system_time_as_file_time(system_time_as_file_time: ^Filetime) #link_name "GetSystemTimeAsFileTime";
|
||||
proc file_time_to_local_file_time(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool #link_name "FileTimeToLocalFileTime";
|
||||
proc file_time_to_system_time (file_time: ^Filetime, system_time: ^Systemtime) -> Bool #link_name "FileTimeToSystemTime";
|
||||
proc system_time_to_file_time (system_time: ^Systemtime, file_time: ^Filetime) -> Bool #link_name "SystemTimeToFileTime";
|
||||
|
||||
proc output_debug_string_a(c_str: ^u8) #foreign kernel32 "OutputDebugStringA";
|
||||
proc close_handle (h: Handle) -> i32 #link_name "CloseHandle";
|
||||
proc get_std_handle(h: i32) -> Handle #link_name "GetStdHandle";
|
||||
proc create_file_a (filename: ^u8, desired_access, share_mode: u32,
|
||||
security: rawptr,
|
||||
creation, flags_and_attribs: u32, template_file: Handle) -> Handle #link_name "CreateFileA";
|
||||
proc read_file (h: Handle, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> Bool #link_name "ReadFile";
|
||||
proc write_file(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool #link_name "WriteFile";
|
||||
|
||||
proc get_file_size_ex (file_handle: Handle, file_size: ^i64) -> Bool #link_name "GetFileSizeEx";
|
||||
proc get_file_attributes_a (filename: ^u8) -> u32 #link_name "GetFileAttributesA";
|
||||
proc get_file_attributes_ex_a (filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool #link_name "GetFileAttributesExA";
|
||||
proc get_file_information_by_handle(file_handle: Handle, file_info: ^ByHandleFileInformation) -> Bool #link_name "GetFileInformationByHandle";
|
||||
|
||||
proc get_file_type (file_handle: Handle) -> u32 #link_name "GetFileType";
|
||||
proc set_file_pointer(file_handle: Handle, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #link_name "SetFilePointer";
|
||||
|
||||
proc set_handle_information(obj: Handle, mask, flags: u32) -> Bool #link_name "SetHandleInformation";
|
||||
|
||||
proc find_first_file_a(file_name : ^u8, data : ^FindData) -> Handle #link_name "FindFirstFileA";
|
||||
proc find_next_file_a (file : Handle, data : ^FindData) -> Bool #link_name "FindNextFileA";
|
||||
proc find_close (file : Handle) -> Bool #link_name "FindClose";
|
||||
|
||||
|
||||
proc register_class_ex_a(wc: ^WndClassExA) -> i16 #foreign user32 "RegisterClassExA";
|
||||
proc create_window_ex_a (ex_style: u32,
|
||||
class_name, title: ^u8,
|
||||
style: u32,
|
||||
x, y, w, h: i32,
|
||||
parent: Hwnd, menu: Hmenu, instance: Hinstance,
|
||||
param: rawptr) -> Hwnd #foreign user32 "CreateWindowExA";
|
||||
proc heap_alloc (h: Handle, flags: u32, bytes: int) -> rawptr #link_name "HeapAlloc";
|
||||
proc heap_realloc (h: Handle, flags: u32, memory: rawptr, bytes: int) -> rawptr #link_name "HeapReAlloc";
|
||||
proc heap_free (h: Handle, flags: u32, memory: rawptr) -> Bool #link_name "HeapFree";
|
||||
proc get_process_heap() -> Handle #link_name "GetProcessHeap";
|
||||
|
||||
proc show_window (hwnd: Hwnd, cmd_show: i32) -> Bool #foreign user32 "ShowWindow";
|
||||
proc translate_message (msg: ^Msg) -> Bool #foreign user32 "TranslateMessage";
|
||||
proc dispatch_message_a(msg: ^Msg) -> Lresult #foreign user32 "DispatchMessageA";
|
||||
proc update_window (hwnd: Hwnd) -> Bool #foreign user32 "UpdateWindow";
|
||||
proc get_message_a (msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #foreign user32 "GetMessageA";
|
||||
proc peek_message_a (msg: ^Msg, hwnd: Hwnd,
|
||||
msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #foreign user32 "PeekMessageA";
|
||||
|
||||
proc post_message(hwnd: Hwnd, msg, wparam, lparam : u32) -> Bool #foreign user32 "PostMessageA";
|
||||
proc create_semaphore_a (attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #link_name "CreateSemaphoreA";
|
||||
proc release_semaphore (semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #link_name "ReleaseSemaphore";
|
||||
proc wait_for_single_object(handle: Handle, milliseconds: u32) -> u32 #link_name "WaitForSingleObject";
|
||||
|
||||
proc def_window_proc_a(hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult #foreign user32 "DefWindowProcA";
|
||||
|
||||
proc adjust_window_rect(rect: ^Rect, style: u32, menu: Bool) -> Bool #foreign user32 "AdjustWindowRect";
|
||||
proc get_active_window () -> Hwnd #foreign user32 "GetActiveWindow";
|
||||
proc interlocked_compare_exchange (dst: ^i32, exchange, comparand: i32) -> i32 #link_name "InterlockedCompareExchange";
|
||||
proc interlocked_exchange (dst: ^i32, desired: i32) -> i32 #link_name "InterlockedExchange";
|
||||
proc interlocked_exchange_add (dst: ^i32, desired: i32) -> i32 #link_name "InterlockedExchangeAdd";
|
||||
proc interlocked_and (dst: ^i32, desired: i32) -> i32 #link_name "InterlockedAnd";
|
||||
proc interlocked_or (dst: ^i32, desired: i32) -> i32 #link_name "InterlockedOr";
|
||||
|
||||
proc interlocked_compare_exchange64(dst: ^i64, exchange, comparand: i64) -> i64 #link_name "InterlockedCompareExchange64";
|
||||
proc interlocked_exchange64 (dst: ^i64, desired: i64) -> i64 #link_name "InterlockedExchange64";
|
||||
proc interlocked_exchange_add64 (dst: ^i64, desired: i64) -> i64 #link_name "InterlockedExchangeAdd64";
|
||||
proc interlocked_and64 (dst: ^i64, desired: i64) -> i64 #link_name "InterlockedAnd64";
|
||||
proc interlocked_or64 (dst: ^i64, desired: i64) -> i64 #link_name "InterlockedOr64";
|
||||
|
||||
proc mm_pause () #link_name "_mm_pause";
|
||||
proc read_write_barrier() #link_name "ReadWriteBarrier";
|
||||
proc write_barrier () #link_name "WriteBarrier";
|
||||
proc read_barrier () #link_name "ReadBarrier";
|
||||
|
||||
|
||||
proc load_library_a (c_str: ^u8) -> Hmodule #link_name "LoadLibraryA";
|
||||
proc free_library (h: Hmodule) #link_name "FreeLibrary";
|
||||
proc get_proc_address(h: Hmodule, c_str: ^u8) -> Proc #link_name "GetProcAddress";
|
||||
|
||||
}
|
||||
|
||||
foreign user32 {
|
||||
proc get_desktop_window () -> Hwnd #link_name "GetDesktopWindow";
|
||||
proc show_cursor (show : Bool) #link_name "ShowCursor";
|
||||
proc get_cursor_pos (p: ^Point) -> i32 #link_name "GetCursorPos";
|
||||
proc screen_to_client (h: Hwnd, p: ^Point) -> i32 #link_name "ScreenToClient";
|
||||
proc post_quit_message (exit_code: i32) #link_name "PostQuitMessage";
|
||||
proc set_window_text_a (hwnd: Hwnd, c_string: ^u8) -> Bool #link_name "SetWindowTextA";
|
||||
proc register_class_ex_a (wc: ^WndClassExA) -> i16 #link_name "RegisterClassExA";
|
||||
|
||||
proc create_window_ex_a (ex_style: u32,
|
||||
class_name, title: ^u8,
|
||||
style: u32,
|
||||
x, y, w, h: i32,
|
||||
parent: Hwnd, menu: Hmenu, instance: Hinstance,
|
||||
param: rawptr) -> Hwnd #link_name "CreateWindowExA";
|
||||
|
||||
proc show_window (hwnd: Hwnd, cmd_show: i32) -> Bool #link_name "ShowWindow";
|
||||
proc translate_message (msg: ^Msg) -> Bool #link_name "TranslateMessage";
|
||||
proc dispatch_message_a (msg: ^Msg) -> Lresult #link_name "DispatchMessageA";
|
||||
proc update_window (hwnd: Hwnd) -> Bool #link_name "UpdateWindow";
|
||||
proc get_message_a (msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool #link_name "GetMessageA";
|
||||
proc peek_message_a (msg: ^Msg, hwnd: Hwnd,
|
||||
msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool #link_name "PeekMessageA";
|
||||
|
||||
|
||||
proc post_message (hwnd: Hwnd, msg, wparam, lparam : u32) -> Bool #link_name "PostMessageA";
|
||||
|
||||
proc def_window_proc_a (hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult #link_name "DefWindowProcA";
|
||||
|
||||
proc adjust_window_rect (rect: ^Rect, style: u32, menu: Bool) -> Bool #link_name "AdjustWindowRect";
|
||||
proc get_active_window () -> Hwnd #link_name "GetActiveWindow";
|
||||
|
||||
proc destroy_window (wnd: Hwnd) -> Bool #link_name "DestroyWindow";
|
||||
proc describe_pixel_format(dc: Hdc, pixel_format: i32, bytes : u32, pfd: ^PixelFormatDescriptor) -> i32 #link_name "DescribePixelFormat";
|
||||
|
||||
proc get_monitor_info_a (monitor: Hmonitor, mi: ^MonitorInfo) -> Bool #link_name "GetMonitorInfoA";
|
||||
proc monitor_from_window (wnd: Hwnd, flags : u32) -> Hmonitor #link_name "MonitorFromWindow";
|
||||
|
||||
proc set_window_pos (wnd: Hwnd, wndInsertAfter: Hwnd, x, y, width, height: i32, flags: u32) #link_name "SetWindowPos";
|
||||
|
||||
proc get_window_placement (wnd: Hwnd, wndpl: ^WindowPlacement) -> Bool #link_name "GetWindowPlacement";
|
||||
proc set_window_placement (wnd: Hwnd, wndpl: ^WindowPlacement) -> Bool #link_name "SetWindowPlacement";
|
||||
proc get_window_rect (wnd: Hwnd, rect: ^Rect) -> Bool #link_name "GetWindowRect";
|
||||
|
||||
proc get_window_long_ptr_a(wnd: Hwnd, index: i32) -> i64 #link_name "GetWindowLongPtrA";
|
||||
proc set_window_long_ptr_a(wnd: Hwnd, index: i32, new: i64) -> i64 #link_name "SetWindowLongPtrA";
|
||||
|
||||
proc get_window_text (wnd: Hwnd, str: ^u8, maxCount: i32) -> i32 #link_name "GetWindowText";
|
||||
|
||||
proc get_client_rect (hwnd: Hwnd, rect: ^Rect) -> Bool #link_name "GetClientRect";
|
||||
|
||||
proc get_dc (h: Hwnd) -> Hdc #link_name "GetDC";
|
||||
proc release_dc (wnd: Hwnd, hdc: Hdc) -> i32 #link_name "ReleaseDC";
|
||||
|
||||
proc map_virtual_key(scancode : u32, map_type : u32) -> u32 #link_name "MapVirtualKeyA";
|
||||
|
||||
proc get_key_state (v_key: i32) -> i16 #link_name "GetKeyState";
|
||||
proc get_async_key_state(v_key: i32) -> i16 #link_name "GetAsyncKeyState";
|
||||
}
|
||||
|
||||
foreign gdi32 {
|
||||
proc get_stock_object(fn_object: i32) -> Hgdiobj #link_name "GetStockObject";
|
||||
|
||||
proc stretch_dibits( hdc: Hdc,
|
||||
x_dst, y_dst, width_dst, height_dst: i32,
|
||||
x_src, y_src, width_src, header_src: i32,
|
||||
bits: rawptr, bits_info: ^BitmapInfo,
|
||||
usage: u32,
|
||||
rop: u32) -> i32 #link_name "StretchDIBits";
|
||||
|
||||
proc set_pixel_format (hdc: Hdc, pixel_format: i32, pfd: ^PixelFormatDescriptor) -> Bool #link_name "SetPixelFormat";
|
||||
proc choose_pixel_format(hdc: Hdc, pfd: ^PixelFormatDescriptor) -> i32 #link_name "ChoosePixelFormat";
|
||||
proc swap_buffers (hdc: Hdc) -> Bool #link_name "SwapBuffers";
|
||||
|
||||
}
|
||||
|
||||
foreign shell32 {
|
||||
proc command_line_to_argv_w(cmd_list: ^u16, num_args: ^i32) -> ^^u16 #link_name "CommandLineToArgvW";
|
||||
}
|
||||
|
||||
foreign winmm {
|
||||
proc time_get_time() -> u32 #link_name "timeGetTime";
|
||||
}
|
||||
|
||||
proc destroy_window (wnd: Hwnd) -> Bool #foreign user32 "DestroyWindow";
|
||||
proc describe_pixel_format(dc: Hdc, pixel_format: i32, bytes : u32, pfd: ^PixelFormatDescriptor) -> i32 #foreign user32 "DescribePixelFormat";
|
||||
|
||||
|
||||
proc get_query_performance_frequency() -> i64 {
|
||||
@@ -229,41 +452,14 @@ proc get_query_performance_frequency() -> i64 {
|
||||
return r;
|
||||
}
|
||||
|
||||
proc get_command_line_a () -> ^u8 #foreign kernel32 "GetCommandLineA";
|
||||
proc get_command_line_w () -> ^u16 #foreign kernel32 "GetCommandLineW";
|
||||
proc get_system_metrics (index: i32) -> i32 #foreign kernel32 "GetSystemMetrics";
|
||||
proc get_current_thread_id () -> u32 #foreign kernel32 "GetCurrentThreadId";
|
||||
proc command_line_to_argv_w(cmd_list: ^u16, num_args: ^i32) -> ^^u16 #foreign shell32 "CommandLineToArgvW";
|
||||
proc HIWORD(wParam: Wparam) -> u16 { return u16((u32(wParam) >> 16) & 0xffff); }
|
||||
proc HIWORD(lParam: Lparam) -> u16 { return u16((u32(lParam) >> 16) & 0xffff); }
|
||||
proc LOWORD(wParam: Wparam) -> u16 { return u16(wParam); }
|
||||
proc LOWORD(lParam: Lparam) -> u16 { return u16(lParam); }
|
||||
|
||||
proc time_get_time () -> u32 #foreign winmm "timeGetTime";
|
||||
proc get_system_time_as_file_time(system_time_as_file_time: ^Filetime) #foreign kernel32 "GetSystemTimeAsFileTime";
|
||||
proc file_time_to_local_file_time(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool #foreign kernel32 "FileTimeToLocalFileTime";
|
||||
proc file_time_to_system_time (file_time: ^Filetime, system_time: ^Systemtime) -> Bool #foreign kernel32 "FileTimeToSystemTime";
|
||||
proc system_time_to_file_time (system_time: ^Systemtime, file_time: ^Filetime) -> Bool #foreign kernel32 "SystemTimeToFileTime";
|
||||
proc is_key_down(key: KeyCode) -> bool #inline { return get_async_key_state(i32(key)) < 0; }
|
||||
|
||||
// File Stuff
|
||||
|
||||
proc close_handle (h: Handle) -> i32 #foreign kernel32 "CloseHandle";
|
||||
proc get_std_handle(h: i32) -> Handle #foreign kernel32 "GetStdHandle";
|
||||
proc create_file_a (filename: ^u8, desired_access, share_mode: u32,
|
||||
security: rawptr,
|
||||
creation, flags_and_attribs: u32, template_file: Handle) -> Handle #foreign kernel32 "CreateFileA";
|
||||
proc read_file (h: Handle, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> Bool #foreign kernel32 "ReadFile";
|
||||
proc write_file(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool #foreign kernel32 "WriteFile";
|
||||
|
||||
proc get_file_size_ex (file_handle: Handle, file_size: ^i64) -> Bool #foreign kernel32 "GetFileSizeEx";
|
||||
proc get_file_attributes_a (filename: ^u8) -> u32 #foreign kernel32 "GetFileAttributesA";
|
||||
proc get_file_attributes_ex_a (filename: ^u8, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool #foreign kernel32 "GetFileAttributesExA";
|
||||
proc get_file_information_by_handle(file_handle: Handle, file_info: ^ByHandleFileInformation) -> Bool #foreign kernel32 "GetFileInformationByHandle";
|
||||
|
||||
proc get_file_type (file_handle: Handle) -> u32 #foreign kernel32 "GetFileType";
|
||||
proc set_file_pointer(file_handle: Handle, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 #foreign kernel32 "SetFilePointer";
|
||||
|
||||
proc set_handle_information(obj: Handle, mask, flags: u32) -> Bool #foreign kernel32 "SetHandleInformation";
|
||||
|
||||
proc find_first_file_a(file_name : ^u8, data : ^FindData) -> Handle #foreign kernel32 "FindFirstFileA";
|
||||
proc find_next_file_a (file : Handle, data : ^FindData) -> Bool #foreign kernel32 "FindNextFileA";
|
||||
proc find_close (file : Handle) -> Bool #foreign kernel32 "FindClose";
|
||||
|
||||
|
||||
const (
|
||||
@@ -318,73 +514,6 @@ const (
|
||||
FILE_TYPE_PIPE = 0x0003;
|
||||
)
|
||||
|
||||
const INVALID_SET_FILE_POINTER = ~u32(0);
|
||||
|
||||
|
||||
|
||||
|
||||
proc heap_alloc ( h: Handle, flags: u32, bytes: int) -> rawptr #foreign kernel32 "HeapAlloc";
|
||||
proc heap_realloc ( h: Handle, flags: u32, memory: rawptr, bytes: int) -> rawptr #foreign kernel32 "HeapReAlloc";
|
||||
proc heap_free ( h: Handle, flags: u32, memory: rawptr) -> Bool #foreign kernel32 "HeapFree";
|
||||
proc get_process_heap( ) -> Handle #foreign kernel32 "GetProcessHeap";
|
||||
|
||||
|
||||
const HEAP_ZERO_MEMORY = 0x00000008;
|
||||
|
||||
// Synchronization
|
||||
|
||||
type Security_Attributes struct #ordered {
|
||||
length: u32,
|
||||
security_descriptor: rawptr,
|
||||
inherit_handle: Bool,
|
||||
}
|
||||
|
||||
const INFINITE = 0xffffffff;
|
||||
|
||||
proc create_semaphore_a (attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #foreign kernel32 "CreateSemaphoreA";
|
||||
proc release_semaphore (semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #foreign kernel32 "ReleaseSemaphore";
|
||||
proc wait_for_single_object(handle: Handle, milliseconds: u32) -> u32 #foreign kernel32 "WaitForSingleObject";
|
||||
|
||||
|
||||
proc interlocked_compare_exchange (dst: ^i32, exchange, comparand: i32) -> i32 #foreign kernel32 "InterlockedCompareExchange";
|
||||
proc interlocked_exchange (dst: ^i32, desired: i32) -> i32 #foreign kernel32 "InterlockedExchange";
|
||||
proc interlocked_exchange_add (dst: ^i32, desired: i32) -> i32 #foreign kernel32 "InterlockedExchangeAdd";
|
||||
proc interlocked_and (dst: ^i32, desired: i32) -> i32 #foreign kernel32 "InterlockedAnd";
|
||||
proc interlocked_or (dst: ^i32, desired: i32) -> i32 #foreign kernel32 "InterlockedOr";
|
||||
|
||||
proc interlocked_compare_exchange64(dst: ^i64, exchange, comparand: i64) -> i64 #foreign kernel32 "InterlockedCompareExchange64";
|
||||
proc interlocked_exchange64 (dst: ^i64, desired: i64) -> i64 #foreign kernel32 "InterlockedExchange64";
|
||||
proc interlocked_exchange_add64 (dst: ^i64, desired: i64) -> i64 #foreign kernel32 "InterlockedExchangeAdd64";
|
||||
proc interlocked_and64 (dst: ^i64, desired: i64) -> i64 #foreign kernel32 "InterlockedAnd64";
|
||||
proc interlocked_or64 (dst: ^i64, desired: i64) -> i64 #foreign kernel32 "InterlockedOr64";
|
||||
|
||||
proc mm_pause () #foreign kernel32 "_mm_pause";
|
||||
proc read_write_barrier() #foreign kernel32 "ReadWriteBarrier";
|
||||
proc write_barrier () #foreign kernel32 "WriteBarrier";
|
||||
proc read_barrier () #foreign kernel32 "ReadBarrier";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
type Hmonitor Handle;
|
||||
|
||||
const GWL_STYLE = -16;
|
||||
|
||||
const Hwnd_TOP = Hwnd(uint(0));
|
||||
|
||||
const (
|
||||
MONITOR_DEFAULTTONULL = 0x00000000;
|
||||
MONITOR_DEFAULTTOPRIMARY = 0x00000001;
|
||||
MONITOR_DEFAULTTONEAREST = 0x00000002;
|
||||
)
|
||||
const (
|
||||
SWP_FRAMECHANGED = 0x0020;
|
||||
SWP_NOOWNERZORDER = 0x0200;
|
||||
SWP_NOZORDER = 0x0004;
|
||||
SWP_NOSIZE = 0x0001;
|
||||
SWP_NOMOVE = 0x0002;
|
||||
)
|
||||
|
||||
type MonitorInfo struct #ordered {
|
||||
size: u32,
|
||||
@@ -402,34 +531,6 @@ type WindowPlacement struct #ordered {
|
||||
normal_pos: Rect,
|
||||
}
|
||||
|
||||
proc get_monitor_info_a (monitor: Hmonitor, mi: ^MonitorInfo) -> Bool #foreign user32 "GetMonitorInfoA";
|
||||
proc monitor_from_window (wnd: Hwnd, flags : u32) -> Hmonitor #foreign user32 "MonitorFromWindow";
|
||||
|
||||
proc set_window_pos (wnd: Hwnd, wndInsertAfter: Hwnd, x, y, width, height: i32, flags: u32) #foreign user32 "SetWindowPos";
|
||||
|
||||
proc get_window_placement (wnd: Hwnd, wndpl: ^WindowPlacement) -> Bool #foreign user32 "GetWindowPlacement";
|
||||
proc set_window_placement (wnd: Hwnd, wndpl: ^WindowPlacement) -> Bool #foreign user32 "SetWindowPlacement";
|
||||
proc get_window_rect (wnd: Hwnd, rect: ^Rect) -> Bool #foreign user32 "GetWindowRect";
|
||||
|
||||
proc get_window_long_ptr_a(wnd: Hwnd, index: i32) -> i64 #foreign user32 "GetWindowLongPtrA";
|
||||
proc set_window_long_ptr_a(wnd: Hwnd, index: i32, new: i64) -> i64 #foreign user32 "SetWindowLongPtrA";
|
||||
|
||||
proc get_window_text (wnd: Hwnd, str: ^u8, maxCount: i32) -> i32 #foreign user32 "GetWindowText";
|
||||
|
||||
proc HIWORD(wParam: Wparam) -> u16 { return u16((u32(wParam) >> 16) & 0xffff); }
|
||||
proc HIWORD(lParam: Lparam) -> u16 { return u16((u32(lParam) >> 16) & 0xffff); }
|
||||
proc LOWORD(wParam: Wparam) -> u16 { return u16(wParam); }
|
||||
proc LOWORD(lParam: Lparam) -> u16 { return u16(lParam); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
type BitmapInfoHeader struct #ordered {
|
||||
size: u32,
|
||||
width, height: i32,
|
||||
@@ -449,104 +550,6 @@ type BitmapInfo struct #ordered {
|
||||
|
||||
type RgbQuad struct #ordered { blue, green, red, reserved: u8 }
|
||||
|
||||
const BI_RGB = 0;
|
||||
const DIB_RGB_COLORS = 0x00;
|
||||
const SRCCOPY: u32 = 0x00cc0020;
|
||||
|
||||
|
||||
proc stretch_dibits( hdc: Hdc,
|
||||
x_dst, y_dst, width_dst, height_dst: i32,
|
||||
x_src, y_src, width_src, header_src: i32,
|
||||
bits: rawptr, bits_info: ^BitmapInfo,
|
||||
usage: u32,
|
||||
rop: u32) -> i32 #foreign gdi32 "StretchDIBits";
|
||||
|
||||
|
||||
|
||||
proc load_library_a ( c_str: ^u8) -> Hmodule #foreign kernel32 "LoadLibraryA";
|
||||
proc free_library ( h: Hmodule) #foreign kernel32 "FreeLibrary";
|
||||
proc get_proc_address( h: Hmodule, c_str: ^u8) -> Proc #foreign kernel32 "GetProcAddress";
|
||||
|
||||
proc get_client_rect (hwnd: Hwnd, rect: ^Rect) -> Bool #foreign user32 "GetClientRect";
|
||||
|
||||
// Windows OpenGL
|
||||
const (
|
||||
PFD_TYPE_RGBA = 0;
|
||||
PFD_TYPE_COLORINDEX = 1;
|
||||
PFD_MAIN_PLANE = 0;
|
||||
PFD_OVERLAY_PLANE = 1;
|
||||
PFD_UNDERLAY_PLANE = -1;
|
||||
PFD_DOUBLEBUFFER = 1;
|
||||
PFD_STEREO = 2;
|
||||
PFD_DRAW_TO_WINDOW = 4;
|
||||
PFD_DRAW_TO_BITMAP = 8;
|
||||
PFD_SUPPORT_GDI = 16;
|
||||
PFD_SUPPORT_OPENGL = 32;
|
||||
PFD_GENERIC_FORMAT = 64;
|
||||
PFD_NEED_PALETTE = 128;
|
||||
PFD_NEED_SYSTEM_PALETTE = 0x00000100;
|
||||
PFD_SWAP_EXCHANGE = 0x00000200;
|
||||
PFD_SWAP_COPY = 0x00000400;
|
||||
PFD_SWAP_LAYER_BUFFERS = 0x00000800;
|
||||
PFD_GENERIC_ACCELERATED = 0x00001000;
|
||||
PFD_DEPTH_DONTCARE = 0x20000000;
|
||||
PFD_DOUBLEBUFFER_DONTCARE = 0x40000000;
|
||||
PFD_STEREO_DONTCARE = 0x80000000;
|
||||
)
|
||||
|
||||
type PixelFormatDescriptor struct #ordered {
|
||||
size,
|
||||
version,
|
||||
flags: u32,
|
||||
|
||||
pixel_type,
|
||||
color_bits,
|
||||
red_bits,
|
||||
red_shift,
|
||||
green_bits,
|
||||
green_shift,
|
||||
blue_bits,
|
||||
blue_shift,
|
||||
alpha_bits,
|
||||
alpha_shift,
|
||||
accum_bits,
|
||||
accum_red_bits,
|
||||
accum_green_bits,
|
||||
accum_blue_bits,
|
||||
accum_alpha_bits,
|
||||
depth_bits,
|
||||
stencil_bits,
|
||||
aux_buffers,
|
||||
layer_type,
|
||||
reserved: u8,
|
||||
|
||||
layer_mask,
|
||||
visible_mask,
|
||||
damage_mask: u32,
|
||||
}
|
||||
|
||||
proc get_dc (h: Hwnd) -> Hdc #foreign user32 "GetDC";
|
||||
proc set_pixel_format (hdc: Hdc, pixel_format: i32, pfd: ^PixelFormatDescriptor) -> Bool #foreign gdi32 "SetPixelFormat";
|
||||
proc choose_pixel_format(hdc: Hdc, pfd: ^PixelFormatDescriptor) -> i32 #foreign gdi32 "ChoosePixelFormat";
|
||||
proc swap_buffers (hdc: Hdc) -> Bool #foreign gdi32 "SwapBuffers";
|
||||
proc release_dc (wnd: Hwnd, hdc: Hdc) -> i32 #foreign user32 "ReleaseDC";
|
||||
|
||||
|
||||
type Proc proc() #cc_c;
|
||||
|
||||
const (
|
||||
MAPVK_VK_TO_CHAR = 2;
|
||||
MAPVK_VK_TO_VSC = 0;
|
||||
MAPVK_VSC_TO_VK = 1;
|
||||
MAPVK_VSC_TO_VK_EX = 3;
|
||||
)
|
||||
|
||||
proc map_virtual_key(scancode : u32, map_type : u32) -> u32 #foreign user32 "MapVirtualKeyA";
|
||||
|
||||
proc get_key_state (v_key: i32) -> i16 #foreign user32 "GetKeyState";
|
||||
proc get_async_key_state(v_key: i32) -> i16 #foreign user32 "GetAsyncKeyState";
|
||||
|
||||
proc is_key_down(key: KeyCode) -> bool #inline { return get_async_key_state(i32(key)) < 0; }
|
||||
|
||||
type KeyCode enum i32 {
|
||||
Lbutton = 0x01,
|
||||
|
||||
@@ -292,16 +292,14 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
error_node(pd->type, "You cannot apply both `inline` and `no_inline` to a procedure");
|
||||
}
|
||||
|
||||
if (is_foreign && is_link_name) {
|
||||
error_node(pd->type, "You cannot apply both `foreign` and `link_name` to a procedure");
|
||||
} else if (is_foreign && is_export) {
|
||||
if (is_foreign && is_export) {
|
||||
error_node(pd->type, "You cannot apply both `foreign` and `export` to a procedure");
|
||||
}
|
||||
|
||||
|
||||
if (pd->body != NULL) {
|
||||
if (is_foreign) {
|
||||
error_node(pd->body, "A procedure tagged as `#foreign` cannot have a body");
|
||||
error_node(pd->body, "A procedure tagged as `foreign` cannot have a body");
|
||||
}
|
||||
|
||||
d->scope = c->context.scope;
|
||||
@@ -323,15 +321,15 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
if (is_foreign) {
|
||||
auto *fp = &c->info.foreigns;
|
||||
String name = e->token.string;
|
||||
if (pd->foreign_name.len > 0) {
|
||||
name = pd->foreign_name;
|
||||
if (pd->link_name.len > 0) {
|
||||
name = pd->link_name;
|
||||
}
|
||||
|
||||
AstNode *foreign_library = d->proc_decl->ProcDecl.foreign_library;
|
||||
AstNode *foreign_library = e->Procedure.foreign_library_ident;
|
||||
if (foreign_library == NULL) {
|
||||
error(e->token, "#foreign procedures must declare which library they are from");
|
||||
error(e->token, "foreign procedures must declare which library they are from");
|
||||
} else if (foreign_library->kind != AstNode_Ident) {
|
||||
error_node(foreign_library, "#foreign library names must be an identifier");
|
||||
error_node(foreign_library, "foreign library names must be an identifier");
|
||||
} else {
|
||||
String name = foreign_library->Ident.string;
|
||||
Entity *found = scope_lookup_entity(c->context.scope, name);
|
||||
@@ -342,7 +340,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
error_node(foreign_library, "Undeclared name: %.*s", LIT(name));
|
||||
}
|
||||
} else if (found->kind != Entity_LibraryName) {
|
||||
error_node(foreign_library, "`_` cannot be used as a library name");
|
||||
error_node(foreign_library, "`%.*s` cannot be used as a library name", LIT(name));
|
||||
} else {
|
||||
// TODO(bill): Extra stuff to do with library names?
|
||||
e->Procedure.foreign_library = found;
|
||||
@@ -352,6 +350,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
|
||||
e->Procedure.is_foreign = true;
|
||||
e->Procedure.foreign_name = name;
|
||||
e->Procedure.link_name = name;
|
||||
|
||||
HashKey key = hash_string(name);
|
||||
Entity **found = map_get(fp, key);
|
||||
|
||||
@@ -270,6 +270,7 @@ struct CheckerContext {
|
||||
String proc_name;
|
||||
Type * type_hint;
|
||||
DeclInfo * curr_proc_decl;
|
||||
AstNode * curr_foreign_library;
|
||||
};
|
||||
|
||||
// CheckerInfo stores all the symbol information for a type-checked program
|
||||
@@ -1626,6 +1627,24 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(fb, ForeignBlockDecl, decl);
|
||||
AstNode *foreign_library = fb->foreign_library;
|
||||
bool ok = true;
|
||||
if (foreign_library->kind != AstNode_Ident) {
|
||||
error_node(foreign_library, "foreign library name must be an identifier");
|
||||
ok = false;
|
||||
}
|
||||
|
||||
CheckerContext prev_context = c->context;
|
||||
if (ok) {
|
||||
c->context.curr_foreign_library = foreign_library;
|
||||
}
|
||||
|
||||
check_collect_entities(c, fb->decls, is_file_scope);
|
||||
|
||||
c->context = prev_context;
|
||||
case_end;
|
||||
|
||||
case_ast_node(pd, ProcDecl, decl);
|
||||
AstNode *name = pd->name;
|
||||
if (name->kind != AstNode_Ident) {
|
||||
@@ -1638,6 +1657,12 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
Entity *e = NULL;
|
||||
|
||||
e = make_entity_procedure(c->allocator, d->scope, name->Ident, NULL, pd->tags);
|
||||
AstNode *fl = c->context.curr_foreign_library;
|
||||
if (fl != NULL) {
|
||||
GB_ASSERT(fl->kind == AstNode_Ident);
|
||||
e->Procedure.foreign_library_ident = fl;
|
||||
pd->tags |= ProcTag_foreign;
|
||||
}
|
||||
d->proc_decl = decl;
|
||||
d->type_expr = pd->type;
|
||||
e->identifier = name;
|
||||
@@ -1652,14 +1677,14 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_sco
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(bill): `when` stmts need to be handled after the other as the condition may refer to something
|
||||
// declared after this stmt in source
|
||||
if (!c->context.scope->is_file) {
|
||||
// NOTE(bill): `when` stmts need to be handled after the other as the condition may refer to something
|
||||
// declared after this stmt in source
|
||||
for_array(i, nodes) {
|
||||
AstNode *node = nodes[i];
|
||||
switch (node->kind) {
|
||||
case_ast_node(ws, WhenStmt, node);
|
||||
check_collect_entities_from_when_stmt(c, ws, is_file_scope);
|
||||
check_collect_entities_from_when_stmt(c, ws, is_file_scope);
|
||||
case_end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ struct Entity {
|
||||
bool is_foreign;
|
||||
String foreign_name;
|
||||
Entity * foreign_library;
|
||||
AstNode * foreign_library_ident;
|
||||
String link_name;
|
||||
u64 tags;
|
||||
OverloadKind overload_kind;
|
||||
|
||||
14
src/ir.cpp
14
src/ir.cpp
@@ -5790,6 +5790,12 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
case_ast_node(bs, EmptyStmt, node);
|
||||
case_end;
|
||||
|
||||
case_ast_node(fb, ForeignBlockDecl, node);
|
||||
for_array(i, fb->decls) {
|
||||
ir_build_stmt(proc, fb->decls[i]);
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(us, UsingStmt, node);
|
||||
for_array(i, us->list) {
|
||||
AstNode *decl = unparen_expr(us->list[i]);
|
||||
@@ -5943,8 +5949,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
// FFI - Foreign function interace
|
||||
String original_name = e->token.string;
|
||||
String name = original_name;
|
||||
if (pd->foreign_name.len > 0) {
|
||||
name = pd->foreign_name;
|
||||
if (pd->link_name.len > 0) {
|
||||
name = pd->link_name;
|
||||
}
|
||||
|
||||
irValue *value = ir_value_procedure(proc->module->allocator,
|
||||
@@ -7251,9 +7257,7 @@ void ir_gen_tree(irGen *s) {
|
||||
name = e->token.string; // NOTE(bill): Don't use the mangled name
|
||||
ir_add_foreign_library_path(m, e->Procedure.foreign_library);
|
||||
}
|
||||
if (pd->foreign_name.len > 0) {
|
||||
name = pd->foreign_name;
|
||||
} else if (pd->link_name.len > 0) {
|
||||
if (pd->link_name.len > 0) {
|
||||
name = pd->link_name;
|
||||
}
|
||||
|
||||
|
||||
181
src/parser.cpp
181
src/parser.cpp
@@ -139,8 +139,6 @@ Array<AstNode *> make_ast_node_array(AstFile *f) {
|
||||
AstNode *type; \
|
||||
AstNode *body; \
|
||||
u64 tags; \
|
||||
AstNode *foreign_library; \
|
||||
String foreign_name; \
|
||||
String link_name; \
|
||||
}) \
|
||||
AST_NODE_KIND(CompoundLit, "compound literal", struct { \
|
||||
@@ -302,16 +300,13 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
|
||||
AstNode *type; \
|
||||
AstNode *body; \
|
||||
u64 tags; \
|
||||
AstNode *foreign_library; \
|
||||
String foreign_name; \
|
||||
String link_name; \
|
||||
}) \
|
||||
AST_NODE_KIND(ForeignLibrarySpec, "foreign library specification", struct { \
|
||||
Token filepath; \
|
||||
Token library_name; \
|
||||
String base_dir; \
|
||||
AstNode *cond; \
|
||||
bool is_system; \
|
||||
AST_NODE_KIND(ForeignBlockDecl, "foreign block declaration", struct { \
|
||||
Token token; \
|
||||
AstNode * foreign_library; \
|
||||
Token open, close; \
|
||||
Array<AstNode *> decls; \
|
||||
}) \
|
||||
AST_NODE_KIND(Label, "label", struct { \
|
||||
Token token; \
|
||||
@@ -340,12 +335,19 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
|
||||
Token import_name; \
|
||||
AstNode *cond; \
|
||||
}) \
|
||||
AST_NODE_KIND(ForeignLibrarySpec, "foreign library specification", struct { \
|
||||
Token filepath; \
|
||||
Token library_name; \
|
||||
String base_dir; \
|
||||
AstNode *cond; \
|
||||
bool is_system; \
|
||||
}) \
|
||||
AST_NODE_KIND(_DeclEnd, "", i32) \
|
||||
AST_NODE_KIND(Field, "field", struct { \
|
||||
Array<AstNode *> names; \
|
||||
AstNode * type; \
|
||||
AstNode * default_value; \
|
||||
u32 flags; \
|
||||
AstNode * type; \
|
||||
AstNode * default_value; \
|
||||
u32 flags; \
|
||||
}) \
|
||||
AST_NODE_KIND(FieldList, "field list", struct { \
|
||||
Token token; \
|
||||
@@ -609,7 +611,6 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
||||
case AstNode_ProcLit:
|
||||
n->ProcLit.type = clone_ast_node(a, n->ProcLit.type);
|
||||
n->ProcLit.body = clone_ast_node(a, n->ProcLit.body);
|
||||
n->ProcLit.foreign_library = clone_ast_node(a, n->ProcLit.foreign_library);
|
||||
break;
|
||||
case AstNode_CompoundLit:
|
||||
n->CompoundLit.type = clone_ast_node(a, n->CompoundLit.type);
|
||||
@@ -1040,13 +1041,11 @@ AstNode *ast_ellipsis(AstFile *f, Token token, AstNode *expr) {
|
||||
}
|
||||
|
||||
|
||||
AstNode *ast_proc_lit(AstFile *f, AstNode *type, AstNode *body, u64 tags, AstNode *foreign_library, String foreign_name, String link_name) {
|
||||
AstNode *ast_proc_lit(AstFile *f, AstNode *type, AstNode *body, u64 tags, String link_name) {
|
||||
AstNode *result = make_ast_node(f, AstNode_ProcLit);
|
||||
result->ProcLit.type = type;
|
||||
result->ProcLit.body = body;
|
||||
result->ProcLit.tags = tags;
|
||||
result->ProcLit.foreign_library = foreign_library;
|
||||
result->ProcLit.foreign_name = foreign_name;
|
||||
result->ProcLit.link_name = link_name;
|
||||
return result;
|
||||
}
|
||||
@@ -1424,25 +1423,24 @@ AstNode *ast_map_type(AstFile *f, Token token, AstNode *count, AstNode *key, Ast
|
||||
|
||||
|
||||
AstNode *ast_proc_decl(AstFile *f, Token token, AstNode *name, AstNode *type, AstNode *body,
|
||||
u64 tags, AstNode *foreign_library, String foreign_name, String link_name) {
|
||||
u64 tags, String link_name) {
|
||||
AstNode *result = make_ast_node(f, AstNode_ProcDecl);
|
||||
result->ProcDecl.token = token;
|
||||
result->ProcDecl.name = name;
|
||||
result->ProcDecl.type = type;
|
||||
result->ProcDecl.body = body;
|
||||
result->ProcDecl.tags = tags;
|
||||
result->ProcDecl.foreign_library = foreign_library;
|
||||
result->ProcDecl.foreign_name = foreign_name;
|
||||
result->ProcDecl.link_name = link_name;
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *ast_foreign_library_spec(AstFile *f, Token filepath, Token library_name, AstNode *cond, bool is_system) {
|
||||
AstNode *result = make_ast_node(f, AstNode_ForeignLibrarySpec);
|
||||
result->ForeignLibrarySpec.filepath = filepath;
|
||||
result->ForeignLibrarySpec.library_name = library_name;
|
||||
result->ForeignLibrarySpec.cond = cond;
|
||||
result->ForeignLibrarySpec.is_system = is_system;
|
||||
AstNode *ast_foreign_block_decl(AstFile *f, Token token, AstNode *foreign_library, Token open, Token close, Array<AstNode *> decls) {
|
||||
AstNode *result = make_ast_node(f, AstNode_ForeignBlockDecl);
|
||||
result->ForeignBlockDecl.token = token;
|
||||
result->ForeignBlockDecl.foreign_library = foreign_library;
|
||||
result->ForeignBlockDecl.open = open;
|
||||
result->ForeignBlockDecl.close = close;
|
||||
result->ForeignBlockDecl.decls = decls;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1486,6 +1484,15 @@ AstNode *ast_import_spec(AstFile *f, bool is_import, Token relpath, Token import
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *ast_foreign_library_spec(AstFile *f, Token filepath, Token library_name, AstNode *cond, bool is_system) {
|
||||
AstNode *result = make_ast_node(f, AstNode_ForeignLibrarySpec);
|
||||
result->ForeignLibrarySpec.filepath = filepath;
|
||||
result->ForeignLibrarySpec.library_name = library_name;
|
||||
result->ForeignLibrarySpec.cond = cond;
|
||||
result->ForeignLibrarySpec.is_system = is_system;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1731,11 +1738,11 @@ void expect_semicolon(AstFile *f, AstNode *s) {
|
||||
}
|
||||
|
||||
|
||||
AstNode * parse_expr(AstFile *f, bool lhs);
|
||||
AstNode * parse_proc_type(AstFile *f, Token proc_token, AstNode **foreign_library, String *foreign_name, String *link_name);
|
||||
AstNode * parse_expr(AstFile *f, bool lhs);
|
||||
AstNode * parse_proc_type(AstFile *f, Token proc_token, String *link_name);
|
||||
Array<AstNode *> parse_stmt_list(AstFile *f);
|
||||
AstNode * parse_stmt(AstFile *f);
|
||||
AstNode * parse_body(AstFile *f);
|
||||
AstNode * parse_stmt(AstFile *f);
|
||||
AstNode * parse_body(AstFile *f);
|
||||
|
||||
|
||||
|
||||
@@ -1753,7 +1760,12 @@ AstNode *parse_ident(AstFile *f) {
|
||||
|
||||
AstNode *parse_tag_expr(AstFile *f, AstNode *expression) {
|
||||
Token token = expect_token(f, Token_Hash);
|
||||
Token name = expect_token(f, Token_Ident);
|
||||
Token name = {};
|
||||
if (f->curr_token.kind == Token_foreign) {
|
||||
name = expect_token(f, Token_foreign);
|
||||
} else {
|
||||
name = expect_token(f, Token_Ident);
|
||||
}
|
||||
return ast_tag_expr(f, token, name, expression);
|
||||
}
|
||||
|
||||
@@ -1873,11 +1885,10 @@ bool is_foreign_name_valid(String name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void parse_proc_tags(AstFile *f, u64 *tags, AstNode **foreign_library_token, String *foreign_name, String *link_name, ProcCallingConvention *calling_convention) {
|
||||
void parse_proc_tags(AstFile *f, u64 *tags, String *link_name, ProcCallingConvention *calling_convention) {
|
||||
// TODO(bill): Add this to procedure literals too
|
||||
GB_ASSERT(tags != NULL);
|
||||
GB_ASSERT(link_name != NULL);
|
||||
GB_ASSERT(link_name != NULL);
|
||||
|
||||
ProcCallingConvention cc = ProcCC_Invalid;
|
||||
|
||||
@@ -1891,19 +1902,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, AstNode **foreign_library_token, Str
|
||||
check_proc_add_tag(f, tag_expr, tags, ProcTag_##name, tag_name); \
|
||||
}
|
||||
|
||||
if (tag_name == "foreign") {
|
||||
check_proc_add_tag(f, tag_expr, tags, ProcTag_foreign, tag_name);
|
||||
*foreign_library_token = parse_ident(f);
|
||||
if (f->curr_token.kind == Token_String) {
|
||||
*foreign_name = f->curr_token.string;
|
||||
// TODO(bill): Check if valid string
|
||||
if (!is_foreign_name_valid(*foreign_name)) {
|
||||
syntax_error_node(tag_expr, "Invalid alternative foreign procedure name: `%.*s`", LIT(*foreign_name));
|
||||
}
|
||||
|
||||
next_token(f);
|
||||
}
|
||||
} else if (tag_name == "link_name") {
|
||||
if (tag_name == "link_name") {
|
||||
check_proc_add_tag(f, tag_expr, tags, ProcTag_link_name, tag_name);
|
||||
if (f->curr_token.kind == Token_String) {
|
||||
*link_name = f->curr_token.string;
|
||||
@@ -2081,7 +2080,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
} else if (name.string == "file") { return ast_basic_directive(f, token, name.string);
|
||||
} else if (name.string == "line") { return ast_basic_directive(f, token, name.string);
|
||||
} else if (name.string == "procedure") { return ast_basic_directive(f, token, name.string);
|
||||
} else if (!lhs && name.string == "alias") { return ast_alias(f, token, parse_expr(f, false));
|
||||
// } else if (!lhs && name.string == "alias") { return ast_alias(f, token, parse_expr(f, false));
|
||||
} else {
|
||||
operand = ast_tag_expr(f, token, name, parse_expr(f, false));
|
||||
}
|
||||
@@ -2091,10 +2090,8 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
// Parse Procedure Type or Literal
|
||||
case Token_proc: {
|
||||
Token token = expect_token(f, Token_proc);
|
||||
AstNode *foreign_library = NULL;
|
||||
String foreign_name = {};
|
||||
String link_name = {};
|
||||
AstNode *type = parse_proc_type(f, token, &foreign_library, &foreign_name, &link_name);
|
||||
AstNode *type = parse_proc_type(f, token, &link_name);
|
||||
u64 tags = type->ProcType.tags;
|
||||
|
||||
if (f->curr_token.kind == Token_OpenBrace) {
|
||||
@@ -2107,11 +2104,11 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
body = parse_body(f);
|
||||
f->curr_proc = curr_proc;
|
||||
|
||||
return ast_proc_lit(f, type, body, tags, foreign_library, foreign_name, link_name);
|
||||
return ast_proc_lit(f, type, body, tags, link_name);
|
||||
}
|
||||
|
||||
if ((tags & ProcTag_foreign) != 0) {
|
||||
return ast_proc_lit(f, type, NULL, tags, foreign_library, foreign_name, link_name);
|
||||
return ast_proc_lit(f, type, NULL, tags, link_name);
|
||||
}
|
||||
if (tags != 0) {
|
||||
// syntax_error(token, "A procedure type cannot have tags");
|
||||
@@ -2526,13 +2523,11 @@ AstNode *parse_proc_decl(AstFile *f) {
|
||||
|
||||
Token token = expect_token(f, Token_proc);
|
||||
AstNode *body = NULL;
|
||||
AstNode *foreign_library = NULL;
|
||||
String foreign_name = {};
|
||||
String link_name = {};
|
||||
|
||||
|
||||
AstNode *name = parse_ident(f);
|
||||
AstNode *type = parse_proc_type(f, token, &foreign_library, &foreign_name, &link_name);
|
||||
AstNode *type = parse_proc_type(f, token, &link_name);
|
||||
u64 tags = type->ProcType.tags;
|
||||
|
||||
if (f->curr_token.kind == Token_OpenBrace) {
|
||||
@@ -2545,7 +2540,9 @@ AstNode *parse_proc_decl(AstFile *f) {
|
||||
f->curr_proc = curr_proc;
|
||||
}
|
||||
|
||||
return ast_proc_decl(f, token, name, type, body, tags, foreign_library, foreign_name, link_name);
|
||||
AstNode *decl = ast_proc_decl(f, token, name, type, body, tags, link_name);
|
||||
expect_semicolon(f, decl);
|
||||
return decl;
|
||||
}
|
||||
|
||||
|
||||
@@ -2791,7 +2788,7 @@ AstNode *parse_decl(AstFile *f) {
|
||||
default: {
|
||||
Token tok = f->curr_token;
|
||||
fix_advance_to_next_stmt(f);
|
||||
syntax_error(tok, "Expected a declaration");
|
||||
syntax_error(tok, "Expected a declaration got %.*s", LIT(token_strings[tok.kind]));
|
||||
return ast_bad_decl(f, tok, f->curr_token);
|
||||
}
|
||||
}
|
||||
@@ -2940,7 +2937,7 @@ AstNode *parse_results(AstFile *f) {
|
||||
return list;
|
||||
}
|
||||
|
||||
AstNode *parse_proc_type(AstFile *f, Token proc_token, AstNode **foreign_library_, String *foreign_name_, String *link_name_) {
|
||||
AstNode *parse_proc_type(AstFile *f, Token proc_token, String *link_name_) {
|
||||
AstNode *params = {};
|
||||
AstNode *results = {};
|
||||
|
||||
@@ -2950,15 +2947,11 @@ AstNode *parse_proc_type(AstFile *f, Token proc_token, AstNode **foreign_library
|
||||
results = parse_results(f);
|
||||
|
||||
u64 tags = 0;
|
||||
String foreign_name = {};
|
||||
String link_name = {};
|
||||
AstNode *foreign_library = NULL;
|
||||
ProcCallingConvention cc = ProcCC_Odin;
|
||||
|
||||
parse_proc_tags(f, &tags, &foreign_library, &foreign_name, &link_name, &cc);
|
||||
parse_proc_tags(f, &tags, &link_name, &cc);
|
||||
|
||||
if (foreign_library_) *foreign_library_ = foreign_library;
|
||||
if (foreign_name_) *foreign_name_ = foreign_name;
|
||||
if (link_name_) *link_name_ = link_name;
|
||||
|
||||
return ast_proc_type(f, proc_token, params, results, tags, cc);
|
||||
@@ -3245,18 +3238,6 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
||||
return e;
|
||||
}
|
||||
|
||||
case Token_Hash: {
|
||||
Token hash_token = expect_token(f, Token_Hash);
|
||||
Token name = expect_token(f, Token_Ident);
|
||||
String tag = name.string;
|
||||
if (tag == "type") {
|
||||
AstNode *type = parse_type(f);
|
||||
return ast_helper_type(f, hash_token, type);
|
||||
}
|
||||
syntax_error(name, "Expected `type` after #");
|
||||
return ast_bad_expr(f, hash_token, f->curr_token);
|
||||
}
|
||||
|
||||
case Token_Pointer: {
|
||||
Token token = expect_token(f, Token_Pointer);
|
||||
AstNode *elem = parse_type(f);
|
||||
@@ -3501,7 +3482,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
||||
|
||||
case Token_proc: {
|
||||
Token token = f->curr_token; next_token(f);
|
||||
AstNode *pt = parse_proc_type(f, token, NULL, NULL, NULL);
|
||||
AstNode *pt = parse_proc_type(f, token, NULL);
|
||||
if (pt->ProcType.tags != 0) {
|
||||
syntax_error(token, "A procedure type cannot have tags");
|
||||
}
|
||||
@@ -3866,6 +3847,29 @@ AstNode *parse_asm_stmt(AstFile *f) {
|
||||
|
||||
}
|
||||
|
||||
void parse_foreign_block_decl(AstFile *f, Array<AstNode *> *decls) {
|
||||
AstNode *decl = parse_decl(f);
|
||||
switch (decl->kind) {
|
||||
case AstNode_BadDecl:
|
||||
break;
|
||||
|
||||
case AstNode_ProcDecl:
|
||||
array_add(decls, decl);
|
||||
break;
|
||||
|
||||
// case AstNode_GenDecl:
|
||||
// if (decl->GenDecl.token.kind == Token_var) {
|
||||
// array_add(decls, decl);
|
||||
// break;
|
||||
// }
|
||||
|
||||
/* fallthrough */
|
||||
default:
|
||||
error_node(decl, "Only procedures declarations are allowed within a foreign block at the moment");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AstNode *parse_stmt(AstFile *f) {
|
||||
AstNode *s = NULL;
|
||||
@@ -3902,6 +3906,31 @@ AstNode *parse_stmt(AstFile *f) {
|
||||
case Token_foreign_system_library:
|
||||
return parse_decl(f);
|
||||
|
||||
case Token_foreign: {
|
||||
Token token = expect_token(f, Token_foreign);
|
||||
AstNode *foreign_library = parse_ident(f);
|
||||
Token open = {};
|
||||
Token close = {};
|
||||
Array<AstNode *> decls = make_ast_node_array(f);
|
||||
|
||||
if (f->curr_token.kind != Token_OpenBrace) {
|
||||
parse_foreign_block_decl(f, &decls);
|
||||
} else {
|
||||
open = expect_token(f, Token_OpenBrace);
|
||||
|
||||
while (f->curr_token.kind != Token_CloseBrace &&
|
||||
f->curr_token.kind != Token_EOF) {
|
||||
parse_foreign_block_decl(f, &decls);
|
||||
}
|
||||
|
||||
close = expect_token(f, Token_CloseBrace);
|
||||
}
|
||||
|
||||
|
||||
return ast_foreign_block_decl(f, token, foreign_library, open, close, decls);
|
||||
} break;
|
||||
|
||||
|
||||
case Token_if: return parse_if_stmt(f);
|
||||
case Token_when: return parse_when_stmt(f);
|
||||
case Token_for: return parse_for_stmt(f);
|
||||
|
||||
@@ -2504,9 +2504,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
|
||||
if (e->Procedure.is_foreign) {
|
||||
name = e->token.string; // NOTE(bill): Don't use the mangled name
|
||||
}
|
||||
if (pd->foreign_name.len > 0) {
|
||||
name = pd->foreign_name;
|
||||
} else if (pd->link_name.len > 0) {
|
||||
if (pd->link_name.len > 0) {
|
||||
name = pd->link_name;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
TOKEN_KIND(Token_type, "type"), \
|
||||
TOKEN_KIND(Token_import, "import"), \
|
||||
TOKEN_KIND(Token_import_load, "import_load"), \
|
||||
TOKEN_KIND(Token_foreign, "foreign"), \
|
||||
TOKEN_KIND(Token_foreign_library, "foreign_library"), \
|
||||
TOKEN_KIND(Token_foreign_system_library, "foreign_system_library"), \
|
||||
TOKEN_KIND(Token_when, "when"), \
|
||||
|
||||
Reference in New Issue
Block a user