foreign blocks for procedures

This commit is contained in:
Ginger Bill
2017-06-12 21:21:18 +01:00
parent 83bad13e9e
commit ccda456c0a
16 changed files with 684 additions and 609 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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