Allow (int[*]) { 1, 2 } cast style initialization. Experimental change from [*] to [?]. Fix issue where compile time declarations in expression list would not be handled properly.

This commit is contained in:
Christoffer Lerno
2025-01-25 22:10:12 +01:00
parent ca91ad4097
commit e40bab2d30
93 changed files with 529 additions and 466 deletions

View File

@@ -10,85 +10,85 @@ macro reverse(i) => $$bitreverse(i);
*> *>
macro bswap(i) @builtin => $$bswap(i); macro bswap(i) @builtin => $$bswap(i);
macro uint[<*>].popcount(self) => $$popcount(self); macro uint[<?>].popcount(self) => $$popcount(self);
macro uint[<*>].ctz(self) => $$ctz(self); macro uint[<?>].ctz(self) => $$ctz(self);
macro uint[<*>].clz(self) => $$clz(self); macro uint[<?>].clz(self) => $$clz(self);
macro uint[<*>] uint[<*>].fshl(hi, uint[<*>] lo, uint[<*>] shift) => $$fshl(hi, lo, shift); macro uint[<?>] uint[<?>].fshl(hi, uint[<?>] lo, uint[<?>] shift) => $$fshl(hi, lo, shift);
macro uint[<*>] uint[<*>].fshr(hi, uint[<*>] lo, uint[<*>] shift) => $$fshr(hi, lo, shift); macro uint[<?>] uint[<?>].fshr(hi, uint[<?>] lo, uint[<?>] shift) => $$fshr(hi, lo, shift);
macro uint[<*>] uint[<*>].rotl(self, uint[<*>] shift) => $$fshl(self, self, shift); macro uint[<?>] uint[<?>].rotl(self, uint[<?>] shift) => $$fshl(self, self, shift);
macro uint[<*>] uint[<*>].rotr(self, uint[<*>] shift) => $$fshr(self, self, shift); macro uint[<?>] uint[<?>].rotr(self, uint[<?>] shift) => $$fshr(self, self, shift);
macro int[<*>].popcount(self) => $$popcount(self); macro int[<?>].popcount(self) => $$popcount(self);
macro int[<*>].ctz(self) => $$ctz(self); macro int[<?>].ctz(self) => $$ctz(self);
macro int[<*>].clz(self) => $$clz(self); macro int[<?>].clz(self) => $$clz(self);
macro int[<*>] int[<*>].fshl(hi, int[<*>] lo, int[<*>] shift) => $$fshl(hi, lo, shift); macro int[<?>] int[<?>].fshl(hi, int[<?>] lo, int[<?>] shift) => $$fshl(hi, lo, shift);
macro int[<*>] int[<*>].fshr(hi, int[<*>] lo, int[<*>] shift) => $$fshr(hi, lo, shift); macro int[<?>] int[<?>].fshr(hi, int[<?>] lo, int[<?>] shift) => $$fshr(hi, lo, shift);
macro int[<*>] int[<*>].rotl(self, int[<*>] shift) => $$fshl(self, self, shift); macro int[<?>] int[<?>].rotl(self, int[<?>] shift) => $$fshl(self, self, shift);
macro int[<*>] int[<*>].rotr(self, int[<*>] shift) => $$fshr(self, self, shift); macro int[<?>] int[<?>].rotr(self, int[<?>] shift) => $$fshr(self, self, shift);
macro ushort[<*>].popcount(self) => $$popcount(self); macro ushort[<?>].popcount(self) => $$popcount(self);
macro ushort[<*>].ctz(self) => $$ctz(self); macro ushort[<?>].ctz(self) => $$ctz(self);
macro ushort[<*>].clz(self) => $$clz(self); macro ushort[<?>].clz(self) => $$clz(self);
macro ushort[<*>] ushort[<*>].fshl(hi, ushort[<*>] lo, ushort[<*>] shift) => $$fshl(hi, lo, shift); macro ushort[<?>] ushort[<?>].fshl(hi, ushort[<?>] lo, ushort[<?>] shift) => $$fshl(hi, lo, shift);
macro ushort[<*>] ushort[<*>].fshr(hi, ushort[<*>] lo, ushort[<*>] shift) => $$fshr(hi, lo, shift); macro ushort[<?>] ushort[<?>].fshr(hi, ushort[<?>] lo, ushort[<?>] shift) => $$fshr(hi, lo, shift);
macro ushort[<*>] ushort[<*>].rotl(self, ushort[<*>] shift) => $$fshl(self, self, shift); macro ushort[<?>] ushort[<?>].rotl(self, ushort[<?>] shift) => $$fshl(self, self, shift);
macro ushort[<*>] ushort[<*>].rotr(self, ushort[<*>] shift) => $$fshr(self, self, shift); macro ushort[<?>] ushort[<?>].rotr(self, ushort[<?>] shift) => $$fshr(self, self, shift);
macro short[<*>].popcount(self) => $$popcount(self); macro short[<?>].popcount(self) => $$popcount(self);
macro short[<*>].ctz(self) => $$ctz(self); macro short[<?>].ctz(self) => $$ctz(self);
macro short[<*>].clz(self) => $$clz(self); macro short[<?>].clz(self) => $$clz(self);
macro short[<*>] short[<*>].fshl(hi, short[<*>] lo, short[<*>] shift) => $$fshl(hi, lo, shift); macro short[<?>] short[<?>].fshl(hi, short[<?>] lo, short[<?>] shift) => $$fshl(hi, lo, shift);
macro short[<*>] short[<*>].fshr(hi, short[<*>] lo, short[<*>] shift) => $$fshr(hi, lo, shift); macro short[<?>] short[<?>].fshr(hi, short[<?>] lo, short[<?>] shift) => $$fshr(hi, lo, shift);
macro short[<*>] short[<*>].rotl(self, short[<*>] shift) => $$fshl(self, self, shift); macro short[<?>] short[<?>].rotl(self, short[<?>] shift) => $$fshl(self, self, shift);
macro short[<*>] short[<*>].rotr(self, short[<*>] shift) => $$fshr(self, self, shift); macro short[<?>] short[<?>].rotr(self, short[<?>] shift) => $$fshr(self, self, shift);
macro char[<*>].popcount(self) => $$popcount(self); macro char[<?>].popcount(self) => $$popcount(self);
macro char[<*>].ctz(self) => $$ctz(self); macro char[<?>].ctz(self) => $$ctz(self);
macro char[<*>].clz(self) => $$clz(self); macro char[<?>].clz(self) => $$clz(self);
macro char[<*>] char[<*>].fshl(hi, char[<*>] lo, char[<*>] shift) => $$fshl(hi, lo, shift); macro char[<?>] char[<?>].fshl(hi, char[<?>] lo, char[<?>] shift) => $$fshl(hi, lo, shift);
macro char[<*>] char[<*>].fshr(hi, char[<*>] lo, char[<*>] shift) => $$fshr(hi, lo, shift); macro char[<?>] char[<?>].fshr(hi, char[<?>] lo, char[<?>] shift) => $$fshr(hi, lo, shift);
macro char[<*>] char[<*>].rotl(self, char[<*>] shift) => $$fshl(self, self, shift); macro char[<?>] char[<?>].rotl(self, char[<?>] shift) => $$fshl(self, self, shift);
macro char[<*>] char[<*>].rotr(self, char[<*>] shift) => $$fshr(self, self, shift); macro char[<?>] char[<?>].rotr(self, char[<?>] shift) => $$fshr(self, self, shift);
macro ichar[<*>].popcount(self) => $$popcount(self); macro ichar[<?>].popcount(self) => $$popcount(self);
macro ichar[<*>].ctz(self) => $$ctz(self); macro ichar[<?>].ctz(self) => $$ctz(self);
macro ichar[<*>].clz(self) => $$clz(self); macro ichar[<?>].clz(self) => $$clz(self);
macro ichar[<*>] ichar[<*>].fshl(hi, ichar[<*>] lo, ichar[<*>] shift) => $$fshl(hi, lo, shift); macro ichar[<?>] ichar[<?>].fshl(hi, ichar[<?>] lo, ichar[<?>] shift) => $$fshl(hi, lo, shift);
macro ichar[<*>] ichar[<*>].fshr(hi, ichar[<*>] lo, ichar[<*>] shift) => $$fshr(hi, lo, shift); macro ichar[<?>] ichar[<?>].fshr(hi, ichar[<?>] lo, ichar[<?>] shift) => $$fshr(hi, lo, shift);
macro ichar[<*>] ichar[<*>].rotl(self, ichar[<*>] shift) => $$fshl(self, self, shift); macro ichar[<?>] ichar[<?>].rotl(self, ichar[<?>] shift) => $$fshl(self, self, shift);
macro ichar[<*>] ichar[<*>].rotr(self, ichar[<*>] shift) => $$fshr(self, self, shift); macro ichar[<?>] ichar[<?>].rotr(self, ichar[<?>] shift) => $$fshr(self, self, shift);
macro ulong[<*>].popcount(self) => $$popcount(self); macro ulong[<?>].popcount(self) => $$popcount(self);
macro ulong[<*>].ctz(self) => $$ctz(self); macro ulong[<?>].ctz(self) => $$ctz(self);
macro ulong[<*>].clz(self) => $$clz(self); macro ulong[<?>].clz(self) => $$clz(self);
macro ulong[<*>] ulong[<*>].fshl(hi, ulong[<*>] lo, ulong[<*>] shift) => $$fshl(hi, lo, shift); macro ulong[<?>] ulong[<?>].fshl(hi, ulong[<?>] lo, ulong[<?>] shift) => $$fshl(hi, lo, shift);
macro ulong[<*>] ulong[<*>].fshr(hi, ulong[<*>] lo, ulong[<*>] shift) => $$fshr(hi, lo, shift); macro ulong[<?>] ulong[<?>].fshr(hi, ulong[<?>] lo, ulong[<?>] shift) => $$fshr(hi, lo, shift);
macro ulong[<*>] ulong[<*>].rotl(self, ulong[<*>] shift) => $$fshl(self, self, shift); macro ulong[<?>] ulong[<?>].rotl(self, ulong[<?>] shift) => $$fshl(self, self, shift);
macro ulong[<*>] ulong[<*>].rotr(self, ulong[<*>] shift) => $$fshr(self, self, shift); macro ulong[<?>] ulong[<?>].rotr(self, ulong[<?>] shift) => $$fshr(self, self, shift);
macro long[<*>].popcount(self) => $$popcount(self); macro long[<?>].popcount(self) => $$popcount(self);
macro long[<*>].ctz(self) => $$ctz(self); macro long[<?>].ctz(self) => $$ctz(self);
macro long[<*>].clz(self) => $$clz(self); macro long[<?>].clz(self) => $$clz(self);
macro long[<*>] long[<*>].fshl(hi, long[<*>] lo, long[<*>] shift) => $$fshl(hi, lo, shift); macro long[<?>] long[<?>].fshl(hi, long[<?>] lo, long[<?>] shift) => $$fshl(hi, lo, shift);
macro long[<*>] long[<*>].fshr(hi, long[<*>] lo, long[<*>] shift) => $$fshr(hi, lo, shift); macro long[<?>] long[<?>].fshr(hi, long[<?>] lo, long[<?>] shift) => $$fshr(hi, lo, shift);
macro long[<*>] long[<*>].rotl(self, long[<*>] shift) => $$fshl(self, self, shift); macro long[<?>] long[<?>].rotl(self, long[<?>] shift) => $$fshl(self, self, shift);
macro long[<*>] long[<*>].rotr(self, long[<*>] shift) => $$fshr(self, self, shift); macro long[<?>] long[<?>].rotr(self, long[<?>] shift) => $$fshr(self, self, shift);
macro uint128[<*>].popcount(self) => $$popcount(self); macro uint128[<?>].popcount(self) => $$popcount(self);
macro uint128[<*>].ctz(self) => $$ctz(self); macro uint128[<?>].ctz(self) => $$ctz(self);
macro uint128[<*>].clz(self) => $$clz(self); macro uint128[<?>].clz(self) => $$clz(self);
macro uint128[<*>] uint128[<*>].fshl(hi, uint128[<*>] lo, uint128[<*>] shift) => $$fshl(hi, lo, shift); macro uint128[<?>] uint128[<?>].fshl(hi, uint128[<?>] lo, uint128[<?>] shift) => $$fshl(hi, lo, shift);
macro uint128[<*>] uint128[<*>].fshr(hi, uint128[<*>] lo, uint128[<*>] shift) => $$fshr(hi, lo, shift); macro uint128[<?>] uint128[<?>].fshr(hi, uint128[<?>] lo, uint128[<?>] shift) => $$fshr(hi, lo, shift);
macro uint128[<*>] uint128[<*>].rotl(self, uint128[<*>] shift) => $$fshl(self, self, shift); macro uint128[<?>] uint128[<?>].rotl(self, uint128[<?>] shift) => $$fshl(self, self, shift);
macro uint128[<*>] uint128[<*>].rotr(self, uint128[<*>] shift) => $$fshr(self, self, shift); macro uint128[<?>] uint128[<?>].rotr(self, uint128[<?>] shift) => $$fshr(self, self, shift);
macro int128[<*>].popcount(self) => $$popcount(self); macro int128[<?>].popcount(self) => $$popcount(self);
macro int128[<*>].ctz(self) => $$ctz(self); macro int128[<?>].ctz(self) => $$ctz(self);
macro int128[<*>].clz(self) => $$clz(self); macro int128[<?>].clz(self) => $$clz(self);
macro int128[<*>] int128[<*>].fshl(hi, int128[<*>] lo, int128[<*>] shift) => $$fshl(hi, lo, shift); macro int128[<?>] int128[<?>].fshl(hi, int128[<?>] lo, int128[<?>] shift) => $$fshl(hi, lo, shift);
macro int128[<*>] int128[<*>].fshr(hi, int128[<*>] lo, int128[<*>] shift) => $$fshr(hi, lo, shift); macro int128[<?>] int128[<?>].fshr(hi, int128[<?>] lo, int128[<?>] shift) => $$fshr(hi, lo, shift);
macro int128[<*>] int128[<*>].rotl(self, int128[<*>] shift) => $$fshl(self, self, shift); macro int128[<?>] int128[<?>].rotl(self, int128[<?>] shift) => $$fshl(self, self, shift);
macro int128[<*>] int128[<*>].rotr(self, int128[<*>] shift) => $$fshr(self, self, shift); macro int128[<?>] int128[<?>].rotr(self, int128[<?>] shift) => $$fshr(self, self, shift);
macro uint.popcount(self) => $$popcount(self); macro uint.popcount(self) => $$popcount(self);
macro uint.ctz(self) => $$ctz(self); macro uint.ctz(self) => $$ctz(self);

View File

@@ -409,7 +409,7 @@ struct Header @packed
char colorspace; // 0 = sRGB with linear alpha, 1 = all channels linear char colorspace; // 0 = sRGB with linear alpha, 1 = all channels linear
} }
const char[*] END_OF_STREAM = {0, 0, 0, 0, 0, 0, 0, 1}; const char[?] END_OF_STREAM = {0, 0, 0, 0, 0, 0, 0, 1};
// inefficient, but it's only run once at a time // inefficient, but it's only run once at a time
macro @enumcast($Type, raw) macro @enumcast($Type, raw)

View File

@@ -28,7 +28,7 @@ fn void ArenaAllocator.clear(&self)
struct ArenaAllocatorHeader @local struct ArenaAllocatorHeader @local
{ {
usz size; usz size;
char[*] data; char[?] data;
} }
<* <*

View File

@@ -52,7 +52,7 @@ fn void OnStackAllocator.free(&self)
struct OnStackAllocatorHeader struct OnStackAllocatorHeader
{ {
usz size; usz size;
char[*] data; char[?] data;
} }
<* <*

View File

@@ -4,7 +4,7 @@ import std::io, std::math;
struct TempAllocatorChunk @local struct TempAllocatorChunk @local
{ {
usz size; usz size;
char[*] data; char[?] data;
} }
struct TempAllocator (Allocator) struct TempAllocator (Allocator)
@@ -13,7 +13,7 @@ struct TempAllocator (Allocator)
TempAllocatorPage* last_page; TempAllocatorPage* last_page;
usz used; usz used;
usz capacity; usz capacity;
char[*] data; char[?] data;
} }
const usz PAGE_IS_ALIGNED @private = (usz)isz.max + 1u; const usz PAGE_IS_ALIGNED @private = (usz)isz.max + 1u;
@@ -26,7 +26,7 @@ struct TempAllocatorPage
usz mark; usz mark;
usz size; usz size;
usz ident; usz ident;
char[*] data; char[?] data;
} }
macro usz TempAllocatorPage.pagesize(&self) => self.size & ~PAGE_IS_ALIGNED; macro usz TempAllocatorPage.pagesize(&self) => self.size & ~PAGE_IS_ALIGNED;

View File

@@ -660,5 +660,5 @@ struct StringData @private
Allocator allocator; Allocator allocator;
usz len; usz len;
usz capacity; usz capacity;
char[*] chars; char[?] chars;
} }

View File

@@ -25,7 +25,7 @@ macro bool @constant_is_power_of_2($x) @const @private
@return "A vector with the loaded values where the mask is true, passthru where the mask is false" @return "A vector with the loaded values where the mask is true, passthru where the mask is false"
*> *>
macro masked_load(ptr, bool[<*>] mask, passthru) macro masked_load(ptr, bool[<?>] mask, passthru)
{ {
return $$masked_load(ptr, mask, passthru, 0); return $$masked_load(ptr, mask, passthru, 0);
} }
@@ -45,7 +45,7 @@ macro masked_load(ptr, bool[<*>] mask, passthru)
@return "A vector with the loaded values where the mask is true, passthru where the mask is false" @return "A vector with the loaded values where the mask is true, passthru where the mask is false"
*> *>
macro @masked_load_aligned(ptr, bool[<*>] mask, passthru, usz $alignment) macro @masked_load_aligned(ptr, bool[<?>] mask, passthru, usz $alignment)
{ {
return $$masked_load(ptr, mask, passthru, $alignment); return $$masked_load(ptr, mask, passthru, $alignment);
} }
@@ -65,7 +65,7 @@ macro @masked_load_aligned(ptr, bool[<*>] mask, passthru, usz $alignment)
@return "A vector with the loaded values where the mask is true, passthru where the mask is false" @return "A vector with the loaded values where the mask is true, passthru where the mask is false"
*> *>
macro gather(ptrvec, bool[<*>] mask, passthru) macro gather(ptrvec, bool[<?>] mask, passthru)
{ {
return $$gather(ptrvec, mask, passthru, 0); return $$gather(ptrvec, mask, passthru, 0);
} }
@@ -88,7 +88,7 @@ macro gather(ptrvec, bool[<*>] mask, passthru)
@return "A vector with the loaded values where the mask is true, passthru where the mask is false" @return "A vector with the loaded values where the mask is true, passthru where the mask is false"
*> *>
macro @gather_aligned(ptrvec, bool[<*>] mask, passthru, usz $alignment) macro @gather_aligned(ptrvec, bool[<?>] mask, passthru, usz $alignment)
{ {
return $$gather(ptrvec, mask, passthru, $alignment); return $$gather(ptrvec, mask, passthru, $alignment);
} }
@@ -105,7 +105,7 @@ macro @gather_aligned(ptrvec, bool[<*>] mask, passthru, usz $alignment)
@require @typekind(value) == VECTOR : "Expected value to be a vector" @require @typekind(value) == VECTOR : "Expected value to be a vector"
@require value.len == mask.len : "Mask and value must have the same length" @require value.len == mask.len : "Mask and value must have the same length"
*> *>
macro masked_store(ptr, value, bool[<*>] mask) macro masked_store(ptr, value, bool[<?>] mask)
{ {
return $$masked_store(ptr, value, mask, 0); return $$masked_store(ptr, value, mask, 0);
} }
@@ -122,7 +122,7 @@ macro masked_store(ptr, value, bool[<*>] mask)
@require @constant_is_power_of_2($alignment) : "The alignment must be a power of two" @require @constant_is_power_of_2($alignment) : "The alignment must be a power of two"
*> *>
macro @masked_store_aligned(ptr, value, bool[<*>] mask, usz $alignment) macro @masked_store_aligned(ptr, value, bool[<?>] mask, usz $alignment)
{ {
return $$masked_store(ptr, value, mask, $alignment); return $$masked_store(ptr, value, mask, $alignment);
} }
@@ -138,7 +138,7 @@ macro @masked_store_aligned(ptr, value, bool[<*>] mask, usz $alignment)
@require mask.len == ptrvec.len : "Mask and ptrvec must have the same length" @require mask.len == ptrvec.len : "Mask and ptrvec must have the same length"
*> *>
macro scatter(ptrvec, value, bool[<*>] mask) macro scatter(ptrvec, value, bool[<?>] mask)
{ {
return $$scatter(ptrvec, value, mask, 0); return $$scatter(ptrvec, value, mask, 0);
} }
@@ -156,7 +156,7 @@ macro scatter(ptrvec, value, bool[<*>] mask)
@require mask.len == ptrvec.len : "Mask and ptrvec must have the same length" @require mask.len == ptrvec.len : "Mask and ptrvec must have the same length"
@require @constant_is_power_of_2($alignment) : "The alignment must be a power of two" @require @constant_is_power_of_2($alignment) : "The alignment must be a power of two"
*> *>
macro @scatter_aligned(ptrvec, value, bool[<*>] mask, usz $alignment) macro @scatter_aligned(ptrvec, value, bool[<?>] mask, usz $alignment)
{ {
return $$scatter(ptrvec, value, mask, $alignment); return $$scatter(ptrvec, value, mask, $alignment);
} }

View File

@@ -214,7 +214,7 @@ struct TypeId
usz sizeof; usz sizeof;
TypeId* inner; TypeId* inner;
usz len; usz len;
typeid[*] additional; typeid[?] additional;
} }
fn void dl_reg_callback(MachHeader* mh, isz vmaddr_slide) fn void dl_reg_callback(MachHeader* mh, isz vmaddr_slide)

View File

@@ -40,7 +40,7 @@ macro double! decfloat(char[] chars, int $bits, int $emin, int sign)
const uint[2] TH = B1B_MAX; const uint[2] TH = B1B_MAX;
int emax = - $emin - $bits + 3; int emax = - $emin - $bits + 3;
const int[*] P10S = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; const int[?] P10S = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
usz index; usz index;
bool got_digit = chars[0] == '0'; bool got_digit = chars[0] == '0';
bool got_rad; bool got_rad;

View File

@@ -89,8 +89,8 @@ fn usz! decode_bytes(char[] src, char[] dst)
return i; return i;
} }
const char[*] HEXALPHABET @private = "0123456789abcdef"; const char[?] HEXALPHABET @private = "0123456789abcdef";
const char[*] HEXREVERSE @private = const char[?] HEXREVERSE @private =
x`ffffffffffffffffffffffffffffffff x`ffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff

View File

@@ -240,7 +240,7 @@ fn usz! Formatter.out_str(&self, any arg) @private
self.width = 0; self.width = 0;
return self.out_substr("0x")! + self.ntoa_any(arg, 16); return self.out_substr("0x")! + self.ntoa_any(arg, 16);
case ARRAY: case ARRAY:
// this is SomeType[*] so grab the "SomeType" // this is SomeType[?] so grab the "SomeType"
PrintFlags flags = self.flags; PrintFlags flags = self.flags;
uint width = self.width; uint width = self.width;
defer defer
@@ -274,7 +274,7 @@ fn usz! Formatter.out_str(&self, any arg) @private
} }
self.flags = {}; self.flags = {};
self.width = 0; self.width = 0;
// this is SomeType[*] so grab the "SomeType" // this is SomeType[?] so grab the "SomeType"
typeid inner = arg.type.inner; typeid inner = arg.type.inner;
usz size = inner.sizeof; usz size = inner.sizeof;
usz vlen = arg.type.len; usz vlen = arg.type.len;

View File

@@ -208,7 +208,7 @@ macro usz! copy_through_buffer(InStream in, OutStream dst, char[] buffer) @local
} }
} }
const char[*] MAX_VARS @private = { [2] = 3, [4] = 5, [8] = 10 }; const char[?] MAX_VARS @private = { [2] = 3, [4] = 5, [8] = 10 };
<* <*
@require @is_instream(stream) @require @is_instream(stream)

View File

@@ -520,7 +520,7 @@ fn String BigInt.to_string_with_radix(&self, int radix, Allocator allocator)
{ {
if (self.is_zero()) return "0".copy(allocator); if (self.is_zero()) return "0".copy(allocator);
const char[*] CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char[?] CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
@stack_mem(4100; Allocator mem) @stack_mem(4100; Allocator mem)
{ {
BigInt a = *self; BigInt a = *self;

View File

@@ -629,7 +629,7 @@ macro normalize(x) @private
@return "a vector of the same type as then/else" @return "a vector of the same type as then/else"
*> *>
macro select(bool[<*>] mask, then_value, else_value) macro select(bool[<?>] mask, then_value, else_value)
{ {
return $$select(mask, then_value, else_value); return $$select(mask, then_value, else_value);
} }
@@ -647,35 +647,35 @@ macro float float.round(float x) => $$round(x);
macro float float.roundeven(float x) => $$roundeven(x); macro float float.roundeven(float x) => $$roundeven(x);
macro float float.trunc(float x) => $$trunc(x); macro float float.trunc(float x) => $$trunc(x);
macro float float[<*>].sum(float[<*>] x, float start = 0.0) => $$reduce_fadd(x, start); macro float float[<?>].sum(float[<?>] x, float start = 0.0) => $$reduce_fadd(x, start);
macro float float[<*>].product(float[<*>] x, float start = 1.0) => $$reduce_fmul(x, start); macro float float[<?>].product(float[<?>] x, float start = 1.0) => $$reduce_fmul(x, start);
macro float float[<*>].max(float[<*>] x) => $$reduce_max(x); macro float float[<?>].max(float[<?>] x) => $$reduce_max(x);
macro float float[<*>].min(float[<*>] x) => $$reduce_min(x); macro float float[<?>].min(float[<?>] x) => $$reduce_min(x);
macro float[<*>] float[<*>].ceil(float[<*>] x) => $$ceil(x); macro float[<?>] float[<?>].ceil(float[<?>] x) => $$ceil(x);
macro float[<*>] float[<*>].clamp(float[<*>] x, float[<*>] lower, float[<*>] upper) => $$max(lower, $$min(x, upper)); macro float[<?>] float[<?>].clamp(float[<?>] x, float[<?>] lower, float[<?>] upper) => $$max(lower, $$min(x, upper));
macro float[<*>] float[<*>].copysign(float[<*>] mag, float[<*>] sgn) => $$copysign(mag, sgn); macro float[<?>] float[<?>].copysign(float[<?>] mag, float[<?>] sgn) => $$copysign(mag, sgn);
macro float[<*>] float[<*>].fma(float[<*>] a, float[<*>] b, float[<*>] c) => $$fma(a, b, c); macro float[<?>] float[<?>].fma(float[<?>] a, float[<?>] b, float[<?>] c) => $$fma(a, b, c);
macro float[<*>] float[<*>].floor(float[<*>] x) => $$floor(x); macro float[<?>] float[<?>].floor(float[<?>] x) => $$floor(x);
macro float[<*>] float[<*>].nearbyint(float[<*>] x) => $$nearbyint(x); macro float[<?>] float[<?>].nearbyint(float[<?>] x) => $$nearbyint(x);
macro float[<*>] float[<*>].pow(float[<*>] x, exp) => pow(x, exp); macro float[<?>] float[<?>].pow(float[<?>] x, exp) => pow(x, exp);
macro float[<*>] float[<*>].rint(float[<*>] x) => $$rint(x); macro float[<?>] float[<?>].rint(float[<?>] x) => $$rint(x);
macro float[<*>] float[<*>].round(float[<*>] x) => $$round(x); macro float[<?>] float[<?>].round(float[<?>] x) => $$round(x);
macro float[<*>] float[<*>].roundeven(float[<*>] x) => $$roundeven(x); macro float[<?>] float[<?>].roundeven(float[<?>] x) => $$roundeven(x);
macro float[<*>] float[<*>].trunc(float[<*>] x) => $$trunc(x); macro float[<?>] float[<?>].trunc(float[<?>] x) => $$trunc(x);
macro float float[<*>].dot(float[<*>] x, float[<*>] y) => (x * y).sum(); macro float float[<?>].dot(float[<?>] x, float[<?>] y) => (x * y).sum();
macro float float[<*>].length(float[<*>] x) => $$sqrt(x.dot(x)); macro float float[<?>].length(float[<?>] x) => $$sqrt(x.dot(x));
macro float float[<*>].distance(float[<*>] x, float[<*>] y) => (x - y).length(); macro float float[<?>].distance(float[<?>] x, float[<?>] y) => (x - y).length();
macro float[<*>] float[<*>].normalize(float[<*>] x) => normalize(x); macro float[<?>] float[<?>].normalize(float[<?>] x) => normalize(x);
macro float[<*>] float[<*>].lerp(float[<*>] x, float[<*>] y, float amount) => lerp(x, y, amount); macro float[<?>] float[<?>].lerp(float[<?>] x, float[<?>] y, float amount) => lerp(x, y, amount);
macro float[<*>] float[<*>].reflect(float[<*>] x, float[<*>] y) => reflect(x, y); macro float[<?>] float[<?>].reflect(float[<?>] x, float[<?>] y) => reflect(x, y);
macro bool float[<*>].equals(float[<*>] x, float[<*>] y) => equals_vec(x, y); macro bool float[<?>].equals(float[<?>] x, float[<?>] y) => equals_vec(x, y);
macro bool[<*>] float[<*>].comp_lt(float[<*>] x, float[<*>] y) => $$veccomplt(x, y); macro bool[<?>] float[<?>].comp_lt(float[<?>] x, float[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] float[<*>].comp_le(float[<*>] x, float[<*>] y) => $$veccomple(x, y); macro bool[<?>] float[<?>].comp_le(float[<?>] x, float[<?>] y) => $$veccomple(x, y);
macro bool[<*>] float[<*>].comp_eq(float[<*>] x, float[<*>] y) => $$veccompeq(x, y); macro bool[<?>] float[<?>].comp_eq(float[<?>] x, float[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] float[<*>].comp_gt(float[<*>] x, float[<*>] y) => $$veccompgt(x, y); macro bool[<?>] float[<?>].comp_gt(float[<?>] x, float[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] float[<*>].comp_ge(float[<*>] x, float[<*>] y) => $$veccompge(x, y); macro bool[<?>] float[<?>].comp_ge(float[<?>] x, float[<?>] y) => $$veccompge(x, y);
macro bool[<*>] float[<*>].comp_ne(float[<*>] x, float[<*>] y) => $$veccompne(x, y); macro bool[<?>] float[<?>].comp_ne(float[<?>] x, float[<?>] y) => $$veccompne(x, y);
macro double double.ceil(double x) => $$ceil(x); macro double double.ceil(double x) => $$ceil(x);
macro double double.clamp(double x, double lower, double upper) => $$max(lower, $$min(x, upper)); macro double double.clamp(double x, double lower, double upper) => $$max(lower, $$min(x, upper));
@@ -690,208 +690,208 @@ macro double double.round(double x) => $$round(x);
macro double double.roundeven(double x) => $$roundeven(x); macro double double.roundeven(double x) => $$roundeven(x);
macro double double.trunc(double x) => $$trunc(x); macro double double.trunc(double x) => $$trunc(x);
macro double double[<*>].sum(double[<*>] x, double start = 0.0) => $$reduce_fadd(x, start); macro double double[<?>].sum(double[<?>] x, double start = 0.0) => $$reduce_fadd(x, start);
macro double double[<*>].product(double[<*>] x, double start = 1.0) => $$reduce_fmul(x, start); macro double double[<?>].product(double[<?>] x, double start = 1.0) => $$reduce_fmul(x, start);
macro double double[<*>].max(double[<*>] x) => $$reduce_fmax(x); macro double double[<?>].max(double[<?>] x) => $$reduce_fmax(x);
macro double double[<*>].min(double[<*>] x) => $$reduce_fmin(x); macro double double[<?>].min(double[<?>] x) => $$reduce_fmin(x);
macro double[<*>] double[<*>].ceil(double[<*>] x) => $$ceil(x); macro double[<?>] double[<?>].ceil(double[<?>] x) => $$ceil(x);
macro double[<*>] double[<*>].clamp(double[<*>] x, double[<*>] lower, double[<*>] upper) => $$max(lower, $$min(x, upper)); macro double[<?>] double[<?>].clamp(double[<?>] x, double[<?>] lower, double[<?>] upper) => $$max(lower, $$min(x, upper));
macro double[<*>] double[<*>].copysign(double[<*>] mag, double[<*>] sgn) => $$copysign(mag, sgn); macro double[<?>] double[<?>].copysign(double[<?>] mag, double[<?>] sgn) => $$copysign(mag, sgn);
macro double[<*>] double[<*>].floor(double[<*>] x) => $$floor(x); macro double[<?>] double[<?>].floor(double[<?>] x) => $$floor(x);
macro double[<*>] double[<*>].fma(double[<*>] a, double[<*>] b, double[<*>] c) => $$fma(a, b, c); macro double[<?>] double[<?>].fma(double[<?>] a, double[<?>] b, double[<?>] c) => $$fma(a, b, c);
macro double[<*>] double[<*>].nearbyint(double[<*>] x) => $$nearbyint(x); macro double[<?>] double[<?>].nearbyint(double[<?>] x) => $$nearbyint(x);
macro double[<*>] double[<*>].pow(double[<*>] x, exp) => pow(x, exp); macro double[<?>] double[<?>].pow(double[<?>] x, exp) => pow(x, exp);
macro double[<*>] double[<*>].rint(double[<*>] x) => $$rint(x); macro double[<?>] double[<?>].rint(double[<?>] x) => $$rint(x);
macro double[<*>] double[<*>].round(double[<*>] x) => $$round(x); macro double[<?>] double[<?>].round(double[<?>] x) => $$round(x);
macro double[<*>] double[<*>].roundeven(double[<*>] x) => $$roundeven(x); macro double[<?>] double[<?>].roundeven(double[<?>] x) => $$roundeven(x);
macro double[<*>] double[<*>].trunc(double[<*>] x) => $$trunc(x); macro double[<?>] double[<?>].trunc(double[<?>] x) => $$trunc(x);
macro double double[<*>].dot(double[<*>] x, double[<*>] y) => (x * y).sum(); macro double double[<?>].dot(double[<?>] x, double[<?>] y) => (x * y).sum();
macro double double[<*>].length(double[<*>] x) => $$sqrt(x.dot(x)); macro double double[<?>].length(double[<?>] x) => $$sqrt(x.dot(x));
macro double double[<*>].distance(double[<*>] x, double[<*>] y) => (x - y).length(); macro double double[<?>].distance(double[<?>] x, double[<?>] y) => (x - y).length();
macro double[<*>] double[<*>].normalize(double[<*>] x) => normalize(x); macro double[<?>] double[<?>].normalize(double[<?>] x) => normalize(x);
macro double[<*>] double[<*>].reflect(double[<*>] x, double[<*>] y) => reflect(x, y); macro double[<?>] double[<?>].reflect(double[<?>] x, double[<?>] y) => reflect(x, y);
macro double[<*>] double[<*>].lerp(double[<*>] x, double[<*>] y, double amount) => lerp(x, y, amount); macro double[<?>] double[<?>].lerp(double[<?>] x, double[<?>] y, double amount) => lerp(x, y, amount);
macro bool double[<*>].equals(double[<*>] x, double[<*>] y) => equals_vec(x, y); macro bool double[<?>].equals(double[<?>] x, double[<?>] y) => equals_vec(x, y);
macro bool[<*>] double[<*>].comp_lt(double[<*>] x, double[<*>] y) => $$veccomplt(x, y); macro bool[<?>] double[<?>].comp_lt(double[<?>] x, double[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] double[<*>].comp_le(double[<*>] x, double[<*>] y) => $$veccomple(x, y); macro bool[<?>] double[<?>].comp_le(double[<?>] x, double[<?>] y) => $$veccomple(x, y);
macro bool[<*>] double[<*>].comp_eq(double[<*>] x, double[<*>] y) => $$veccompeq(x, y); macro bool[<?>] double[<?>].comp_eq(double[<?>] x, double[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] double[<*>].comp_gt(double[<*>] x, double[<*>] y) => $$veccompgt(x, y); macro bool[<?>] double[<?>].comp_gt(double[<?>] x, double[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] double[<*>].comp_ge(double[<*>] x, double[<*>] y) => $$veccompge(x, y); macro bool[<?>] double[<?>].comp_ge(double[<?>] x, double[<?>] y) => $$veccompge(x, y);
macro bool[<*>] double[<*>].comp_ne(double[<*>] x, double[<*>] y) => $$veccompne(x, y); macro bool[<?>] double[<?>].comp_ne(double[<?>] x, double[<?>] y) => $$veccompne(x, y);
macro bool[<*>] ichar[<*>].comp_lt(ichar[<*>] x, ichar[<*>] y) => $$veccomplt(x, y); macro bool[<?>] ichar[<?>].comp_lt(ichar[<?>] x, ichar[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] ichar[<*>].comp_le(ichar[<*>] x, ichar[<*>] y) => $$veccomple(x, y); macro bool[<?>] ichar[<?>].comp_le(ichar[<?>] x, ichar[<?>] y) => $$veccomple(x, y);
macro bool[<*>] ichar[<*>].comp_eq(ichar[<*>] x, ichar[<*>] y) => $$veccompeq(x, y); macro bool[<?>] ichar[<?>].comp_eq(ichar[<?>] x, ichar[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] ichar[<*>].comp_gt(ichar[<*>] x, ichar[<*>] y) => $$veccompgt(x, y); macro bool[<?>] ichar[<?>].comp_gt(ichar[<?>] x, ichar[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] ichar[<*>].comp_ge(ichar[<*>] x, ichar[<*>] y) => $$veccompge(x, y); macro bool[<?>] ichar[<?>].comp_ge(ichar[<?>] x, ichar[<?>] y) => $$veccompge(x, y);
macro bool[<*>] ichar[<*>].comp_ne(ichar[<*>] x, ichar[<*>] y) => $$veccompne(x, y); macro bool[<?>] ichar[<?>].comp_ne(ichar[<?>] x, ichar[<?>] y) => $$veccompne(x, y);
macro ichar ichar[<*>].sum(ichar[<*>] x) => $$reduce_add(x); macro ichar ichar[<?>].sum(ichar[<?>] x) => $$reduce_add(x);
macro ichar ichar[<*>].product(ichar[<*>] x) => $$reduce_mul(x); macro ichar ichar[<?>].product(ichar[<?>] x) => $$reduce_mul(x);
macro ichar ichar[<*>].and(ichar[<*>] x) => $$reduce_and(x); macro ichar ichar[<?>].and(ichar[<?>] x) => $$reduce_and(x);
macro ichar ichar[<*>].or(ichar[<*>] x) => $$reduce_or(x); macro ichar ichar[<?>].or(ichar[<?>] x) => $$reduce_or(x);
macro ichar ichar[<*>].xor(ichar[<*>] x) => $$reduce_xor(x); macro ichar ichar[<?>].xor(ichar[<?>] x) => $$reduce_xor(x);
macro ichar ichar[<*>].max(ichar[<*>] x) => $$reduce_max(x); macro ichar ichar[<?>].max(ichar[<?>] x) => $$reduce_max(x);
macro ichar ichar[<*>].min(ichar[<*>] x) => $$reduce_min(x); macro ichar ichar[<?>].min(ichar[<?>] x) => $$reduce_min(x);
macro ichar ichar[<*>].dot(ichar[<*>] x, ichar[<*>] y) => (x * y).sum(); macro ichar ichar[<?>].dot(ichar[<?>] x, ichar[<?>] y) => (x * y).sum();
macro bool[<*>] short[<*>].comp_lt(short[<*>] x, short[<*>] y) => $$veccomplt(x, y); macro bool[<?>] short[<?>].comp_lt(short[<?>] x, short[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] short[<*>].comp_le(short[<*>] x, short[<*>] y) => $$veccomple(x, y); macro bool[<?>] short[<?>].comp_le(short[<?>] x, short[<?>] y) => $$veccomple(x, y);
macro bool[<*>] short[<*>].comp_eq(short[<*>] x, short[<*>] y) => $$veccompeq(x, y); macro bool[<?>] short[<?>].comp_eq(short[<?>] x, short[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] short[<*>].comp_gt(short[<*>] x, short[<*>] y) => $$veccompgt(x, y); macro bool[<?>] short[<?>].comp_gt(short[<?>] x, short[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] short[<*>].comp_ge(short[<*>] x, short[<*>] y) => $$veccompge(x, y); macro bool[<?>] short[<?>].comp_ge(short[<?>] x, short[<?>] y) => $$veccompge(x, y);
macro bool[<*>] short[<*>].comp_ne(short[<*>] x, short[<*>] y) => $$veccompne(x, y); macro bool[<?>] short[<?>].comp_ne(short[<?>] x, short[<?>] y) => $$veccompne(x, y);
macro short short[<*>].sum(short[<*>] x) => $$reduce_add(x); macro short short[<?>].sum(short[<?>] x) => $$reduce_add(x);
macro short short[<*>].product(short[<*>] x) => $$reduce_mul(x); macro short short[<?>].product(short[<?>] x) => $$reduce_mul(x);
macro short short[<*>].and(short[<*>] x) => $$reduce_and(x); macro short short[<?>].and(short[<?>] x) => $$reduce_and(x);
macro short short[<*>].or(short[<*>] x) => $$reduce_or(x); macro short short[<?>].or(short[<?>] x) => $$reduce_or(x);
macro short short[<*>].xor(short[<*>] x) => $$reduce_xor(x); macro short short[<?>].xor(short[<?>] x) => $$reduce_xor(x);
macro short short[<*>].max(short[<*>] x) => $$reduce_max(x); macro short short[<?>].max(short[<?>] x) => $$reduce_max(x);
macro short short[<*>].min(short[<*>] x) => $$reduce_min(x); macro short short[<?>].min(short[<?>] x) => $$reduce_min(x);
macro short short[<*>].dot(short[<*>] x, short[<*>] y) => (x * y).sum(); macro short short[<?>].dot(short[<?>] x, short[<?>] y) => (x * y).sum();
macro bool[<*>] int[<*>].comp_lt(int[<*>] x, int[<*>] y) => $$veccomplt(x, y); macro bool[<?>] int[<?>].comp_lt(int[<?>] x, int[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] int[<*>].comp_le(int[<*>] x, int[<*>] y) => $$veccomple(x, y); macro bool[<?>] int[<?>].comp_le(int[<?>] x, int[<?>] y) => $$veccomple(x, y);
macro bool[<*>] int[<*>].comp_eq(int[<*>] x, int[<*>] y) => $$veccompeq(x, y); macro bool[<?>] int[<?>].comp_eq(int[<?>] x, int[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] int[<*>].comp_gt(int[<*>] x, int[<*>] y) => $$veccompgt(x, y); macro bool[<?>] int[<?>].comp_gt(int[<?>] x, int[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] int[<*>].comp_ge(int[<*>] x, int[<*>] y) => $$veccompge(x, y); macro bool[<?>] int[<?>].comp_ge(int[<?>] x, int[<?>] y) => $$veccompge(x, y);
macro bool[<*>] int[<*>].comp_ne(int[<*>] x, int[<*>] y) => $$veccompne(x, y); macro bool[<?>] int[<?>].comp_ne(int[<?>] x, int[<?>] y) => $$veccompne(x, y);
macro int int[<*>].sum(int[<*>] x) => $$reduce_add(x); macro int int[<?>].sum(int[<?>] x) => $$reduce_add(x);
macro int int[<*>].product(int[<*>] x) => $$reduce_mul(x); macro int int[<?>].product(int[<?>] x) => $$reduce_mul(x);
macro int int[<*>].and(int[<*>] x) => $$reduce_and(x); macro int int[<?>].and(int[<?>] x) => $$reduce_and(x);
macro int int[<*>].or(int[<*>] x) => $$reduce_or(x); macro int int[<?>].or(int[<?>] x) => $$reduce_or(x);
macro int int[<*>].xor(int[<*>] x) => $$reduce_xor(x); macro int int[<?>].xor(int[<?>] x) => $$reduce_xor(x);
macro int int[<*>].max(int[<*>] x) => $$reduce_max(x); macro int int[<?>].max(int[<?>] x) => $$reduce_max(x);
macro int int[<*>].min(int[<*>] x) => $$reduce_min(x); macro int int[<?>].min(int[<?>] x) => $$reduce_min(x);
macro int int[<*>].dot(int[<*>] x, int[<*>] y) => (x * y).sum(); macro int int[<?>].dot(int[<?>] x, int[<?>] y) => (x * y).sum();
macro bool[<*>] long[<*>].comp_lt(long[<*>] x, long[<*>] y) => $$veccomplt(x, y); macro bool[<?>] long[<?>].comp_lt(long[<?>] x, long[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] long[<*>].comp_le(long[<*>] x, long[<*>] y) => $$veccomple(x, y); macro bool[<?>] long[<?>].comp_le(long[<?>] x, long[<?>] y) => $$veccomple(x, y);
macro bool[<*>] long[<*>].comp_eq(long[<*>] x, long[<*>] y) => $$veccompeq(x, y); macro bool[<?>] long[<?>].comp_eq(long[<?>] x, long[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] long[<*>].comp_gt(long[<*>] x, long[<*>] y) => $$veccompgt(x, y); macro bool[<?>] long[<?>].comp_gt(long[<?>] x, long[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] long[<*>].comp_ge(long[<*>] x, long[<*>] y) => $$veccompge(x, y); macro bool[<?>] long[<?>].comp_ge(long[<?>] x, long[<?>] y) => $$veccompge(x, y);
macro bool[<*>] long[<*>].comp_ne(long[<*>] x, long[<*>] y) => $$veccompne(x, y); macro bool[<?>] long[<?>].comp_ne(long[<?>] x, long[<?>] y) => $$veccompne(x, y);
macro long long[<*>].sum(long[<*>] x) => $$reduce_add(x); macro long long[<?>].sum(long[<?>] x) => $$reduce_add(x);
macro long long[<*>].product(long[<*>] x) => $$reduce_mul(x); macro long long[<?>].product(long[<?>] x) => $$reduce_mul(x);
macro long long[<*>].and(long[<*>] x) => $$reduce_and(x); macro long long[<?>].and(long[<?>] x) => $$reduce_and(x);
macro long long[<*>].or(long[<*>] x) => $$reduce_or(x); macro long long[<?>].or(long[<?>] x) => $$reduce_or(x);
macro long long[<*>].xor(long[<*>] x) => $$reduce_xor(x); macro long long[<?>].xor(long[<?>] x) => $$reduce_xor(x);
macro long long[<*>].max(long[<*>] x) => $$reduce_max(x); macro long long[<?>].max(long[<?>] x) => $$reduce_max(x);
macro long long[<*>].min(long[<*>] x) => $$reduce_min(x); macro long long[<?>].min(long[<?>] x) => $$reduce_min(x);
macro long long[<*>].dot(long[<*>] x, long[<*>] y) => (x * y).sum(); macro long long[<?>].dot(long[<?>] x, long[<?>] y) => (x * y).sum();
macro bool[<*>] int128[<*>].comp_lt(int128[<*>] x, int128[<*>] y) => $$veccomplt(x, y); macro bool[<?>] int128[<?>].comp_lt(int128[<?>] x, int128[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] int128[<*>].comp_le(int128[<*>] x, int128[<*>] y) => $$veccomple(x, y); macro bool[<?>] int128[<?>].comp_le(int128[<?>] x, int128[<?>] y) => $$veccomple(x, y);
macro bool[<*>] int128[<*>].comp_eq(int128[<*>] x, int128[<*>] y) => $$veccompeq(x, y); macro bool[<?>] int128[<?>].comp_eq(int128[<?>] x, int128[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] int128[<*>].comp_gt(int128[<*>] x, int128[<*>] y) => $$veccompgt(x, y); macro bool[<?>] int128[<?>].comp_gt(int128[<?>] x, int128[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] int128[<*>].comp_ge(int128[<*>] x, int128[<*>] y) => $$veccompge(x, y); macro bool[<?>] int128[<?>].comp_ge(int128[<?>] x, int128[<?>] y) => $$veccompge(x, y);
macro bool[<*>] int128[<*>].comp_ne(int128[<*>] x, int128[<*>] y) => $$veccompne(x, y); macro bool[<?>] int128[<?>].comp_ne(int128[<?>] x, int128[<?>] y) => $$veccompne(x, y);
macro int128 int128[<*>].sum(int128[<*>] x) => $$reduce_add(x); macro int128 int128[<?>].sum(int128[<?>] x) => $$reduce_add(x);
macro int128 int128[<*>].product(int128[<*>] x) => $$reduce_mul(x); macro int128 int128[<?>].product(int128[<?>] x) => $$reduce_mul(x);
macro int128 int128[<*>].and(int128[<*>] x) => $$reduce_and(x); macro int128 int128[<?>].and(int128[<?>] x) => $$reduce_and(x);
macro int128 int128[<*>].or(int128[<*>] x) => $$reduce_or(x); macro int128 int128[<?>].or(int128[<?>] x) => $$reduce_or(x);
macro int128 int128[<*>].xor(int128[<*>] x) => $$reduce_xor(x); macro int128 int128[<?>].xor(int128[<?>] x) => $$reduce_xor(x);
macro int128 int128[<*>].max(int128[<*>] x) => $$reduce_max(x); macro int128 int128[<?>].max(int128[<?>] x) => $$reduce_max(x);
macro int128 int128[<*>].min(int128[<*>] x) => $$reduce_min(x); macro int128 int128[<?>].min(int128[<?>] x) => $$reduce_min(x);
macro int128 int128[<*>].dot(int128[<*>] x, int128[<*>] y) => (x * y).sum(); macro int128 int128[<?>].dot(int128[<?>] x, int128[<?>] y) => (x * y).sum();
macro bool[<*>] bool[<*>].comp_lt(bool[<*>] x, bool[<*>] y) => $$veccomplt(x, y); macro bool[<?>] bool[<?>].comp_lt(bool[<?>] x, bool[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] bool[<*>].comp_le(bool[<*>] x, bool[<*>] y) => $$veccomple(x, y); macro bool[<?>] bool[<?>].comp_le(bool[<?>] x, bool[<?>] y) => $$veccomple(x, y);
macro bool[<*>] bool[<*>].comp_eq(bool[<*>] x, bool[<*>] y) => $$veccompeq(x, y); macro bool[<?>] bool[<?>].comp_eq(bool[<?>] x, bool[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] bool[<*>].comp_gt(bool[<*>] x, bool[<*>] y) => $$veccompgt(x, y); macro bool[<?>] bool[<?>].comp_gt(bool[<?>] x, bool[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] bool[<*>].comp_ge(bool[<*>] x, bool[<*>] y) => $$veccompge(x, y); macro bool[<?>] bool[<?>].comp_ge(bool[<?>] x, bool[<?>] y) => $$veccompge(x, y);
macro bool[<*>] bool[<*>].comp_ne(bool[<*>] x, bool[<*>] y) => $$veccompne(x, y); macro bool[<?>] bool[<?>].comp_ne(bool[<?>] x, bool[<?>] y) => $$veccompne(x, y);
macro bool bool[<*>].sum(bool[<*>] x) => $$reduce_add(x); macro bool bool[<?>].sum(bool[<?>] x) => $$reduce_add(x);
macro bool bool[<*>].product(bool[<*>] x) => $$reduce_mul(x); macro bool bool[<?>].product(bool[<?>] x) => $$reduce_mul(x);
macro bool bool[<*>].and(bool[<*>] x) => $$reduce_and(x); macro bool bool[<?>].and(bool[<?>] x) => $$reduce_and(x);
macro bool bool[<*>].or(bool[<*>] x) => $$reduce_or(x); macro bool bool[<?>].or(bool[<?>] x) => $$reduce_or(x);
macro bool bool[<*>].xor(bool[<*>] x) => $$reduce_xor(x); macro bool bool[<?>].xor(bool[<?>] x) => $$reduce_xor(x);
macro bool bool[<*>].max(bool[<*>] x) => $$reduce_max(x); macro bool bool[<?>].max(bool[<?>] x) => $$reduce_max(x);
macro bool bool[<*>].min(bool[<*>] x) => $$reduce_min(x); macro bool bool[<?>].min(bool[<?>] x) => $$reduce_min(x);
macro bool[<*>] char[<*>].comp_lt(char[<*>] x, char[<*>] y) => $$veccomplt(x, y); macro bool[<?>] char[<?>].comp_lt(char[<?>] x, char[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] char[<*>].comp_le(char[<*>] x, char[<*>] y) => $$veccomple(x, y); macro bool[<?>] char[<?>].comp_le(char[<?>] x, char[<?>] y) => $$veccomple(x, y);
macro bool[<*>] char[<*>].comp_eq(char[<*>] x, char[<*>] y) => $$veccompeq(x, y); macro bool[<?>] char[<?>].comp_eq(char[<?>] x, char[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] char[<*>].comp_gt(char[<*>] x, char[<*>] y) => $$veccompgt(x, y); macro bool[<?>] char[<?>].comp_gt(char[<?>] x, char[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] char[<*>].comp_ge(char[<*>] x, char[<*>] y) => $$veccompge(x, y); macro bool[<?>] char[<?>].comp_ge(char[<?>] x, char[<?>] y) => $$veccompge(x, y);
macro bool[<*>] char[<*>].comp_ne(char[<*>] x, char[<*>] y) => $$veccompne(x, y); macro bool[<?>] char[<?>].comp_ne(char[<?>] x, char[<?>] y) => $$veccompne(x, y);
macro char char[<*>].sum(char[<*>] x) => $$reduce_add(x); macro char char[<?>].sum(char[<?>] x) => $$reduce_add(x);
macro char char[<*>].product(char[<*>] x) => $$reduce_mul(x); macro char char[<?>].product(char[<?>] x) => $$reduce_mul(x);
macro char char[<*>].and(char[<*>] x) => $$reduce_and(x); macro char char[<?>].and(char[<?>] x) => $$reduce_and(x);
macro char char[<*>].or(char[<*>] x) => $$reduce_or(x); macro char char[<?>].or(char[<?>] x) => $$reduce_or(x);
macro char char[<*>].xor(char[<*>] x) => $$reduce_xor(x); macro char char[<?>].xor(char[<?>] x) => $$reduce_xor(x);
macro char char[<*>].max(char[<*>] x) => $$reduce_max(x); macro char char[<?>].max(char[<?>] x) => $$reduce_max(x);
macro char char[<*>].min(char[<*>] x) => $$reduce_min(x); macro char char[<?>].min(char[<?>] x) => $$reduce_min(x);
macro char char[<*>].dot(char[<*>] x, char[<*>] y) => (x * y).sum(); macro char char[<?>].dot(char[<?>] x, char[<?>] y) => (x * y).sum();
macro bool[<*>] ushort[<*>].comp_lt(ushort[<*>] x, ushort[<*>] y) => $$veccomplt(x, y); macro bool[<?>] ushort[<?>].comp_lt(ushort[<?>] x, ushort[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] ushort[<*>].comp_le(ushort[<*>] x, ushort[<*>] y) => $$veccomple(x, y); macro bool[<?>] ushort[<?>].comp_le(ushort[<?>] x, ushort[<?>] y) => $$veccomple(x, y);
macro bool[<*>] ushort[<*>].comp_eq(ushort[<*>] x, ushort[<*>] y) => $$veccompeq(x, y); macro bool[<?>] ushort[<?>].comp_eq(ushort[<?>] x, ushort[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] ushort[<*>].comp_gt(ushort[<*>] x, ushort[<*>] y) => $$veccompgt(x, y); macro bool[<?>] ushort[<?>].comp_gt(ushort[<?>] x, ushort[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] ushort[<*>].comp_ge(ushort[<*>] x, ushort[<*>] y) => $$veccompge(x, y); macro bool[<?>] ushort[<?>].comp_ge(ushort[<?>] x, ushort[<?>] y) => $$veccompge(x, y);
macro bool[<*>] ushort[<*>].comp_ne(ushort[<*>] x, ushort[<*>] y) => $$veccompne(x, y); macro bool[<?>] ushort[<?>].comp_ne(ushort[<?>] x, ushort[<?>] y) => $$veccompne(x, y);
macro ushort ushort[<*>].sum(ushort[<*>] x) => $$reduce_add(x); macro ushort ushort[<?>].sum(ushort[<?>] x) => $$reduce_add(x);
macro ushort ushort[<*>].product(ushort[<*>] x) => $$reduce_mul(x); macro ushort ushort[<?>].product(ushort[<?>] x) => $$reduce_mul(x);
macro ushort ushort[<*>].and(ushort[<*>] x) => $$reduce_and(x); macro ushort ushort[<?>].and(ushort[<?>] x) => $$reduce_and(x);
macro ushort ushort[<*>].or(ushort[<*>] x) => $$reduce_or(x); macro ushort ushort[<?>].or(ushort[<?>] x) => $$reduce_or(x);
macro ushort ushort[<*>].xor(ushort[<*>] x) => $$reduce_xor(x); macro ushort ushort[<?>].xor(ushort[<?>] x) => $$reduce_xor(x);
macro ushort ushort[<*>].max(ushort[<*>] x) => $$reduce_max(x); macro ushort ushort[<?>].max(ushort[<?>] x) => $$reduce_max(x);
macro ushort ushort[<*>].min(ushort[<*>] x) => $$reduce_min(x); macro ushort ushort[<?>].min(ushort[<?>] x) => $$reduce_min(x);
macro ushort ushort[<*>].dot(ushort[<*>] x, ushort[<*>] y) => (x * y).sum(); macro ushort ushort[<?>].dot(ushort[<?>] x, ushort[<?>] y) => (x * y).sum();
macro bool[<*>] uint[<*>].comp_lt(uint[<*>] x, uint[<*>] y) => $$veccomplt(x, y); macro bool[<?>] uint[<?>].comp_lt(uint[<?>] x, uint[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] uint[<*>].comp_le(uint[<*>] x, uint[<*>] y) => $$veccomple(x, y); macro bool[<?>] uint[<?>].comp_le(uint[<?>] x, uint[<?>] y) => $$veccomple(x, y);
macro bool[<*>] uint[<*>].comp_eq(uint[<*>] x, uint[<*>] y) => $$veccompeq(x, y); macro bool[<?>] uint[<?>].comp_eq(uint[<?>] x, uint[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] uint[<*>].comp_gt(uint[<*>] x, uint[<*>] y) => $$veccompgt(x, y); macro bool[<?>] uint[<?>].comp_gt(uint[<?>] x, uint[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] uint[<*>].comp_ge(uint[<*>] x, uint[<*>] y) => $$veccompge(x, y); macro bool[<?>] uint[<?>].comp_ge(uint[<?>] x, uint[<?>] y) => $$veccompge(x, y);
macro bool[<*>] uint[<*>].comp_ne(uint[<*>] x, uint[<*>] y) => $$veccompne(x, y); macro bool[<?>] uint[<?>].comp_ne(uint[<?>] x, uint[<?>] y) => $$veccompne(x, y);
macro uint uint[<*>].sum(uint[<*>] x) => $$reduce_add(x); macro uint uint[<?>].sum(uint[<?>] x) => $$reduce_add(x);
macro uint uint[<*>].product(uint[<*>] x) => $$reduce_mul(x); macro uint uint[<?>].product(uint[<?>] x) => $$reduce_mul(x);
macro uint uint[<*>].and(uint[<*>] x) => $$reduce_and(x); macro uint uint[<?>].and(uint[<?>] x) => $$reduce_and(x);
macro uint uint[<*>].or(uint[<*>] x) => $$reduce_or(x); macro uint uint[<?>].or(uint[<?>] x) => $$reduce_or(x);
macro uint uint[<*>].xor(uint[<*>] x) => $$reduce_xor(x); macro uint uint[<?>].xor(uint[<?>] x) => $$reduce_xor(x);
macro uint uint[<*>].max(uint[<*>] x) => $$reduce_max(x); macro uint uint[<?>].max(uint[<?>] x) => $$reduce_max(x);
macro uint uint[<*>].min(uint[<*>] x) => $$reduce_min(x); macro uint uint[<?>].min(uint[<?>] x) => $$reduce_min(x);
macro uint uint[<*>].dot(uint[<*>] x, uint[<*>] y) => (x * y).sum(); macro uint uint[<?>].dot(uint[<?>] x, uint[<?>] y) => (x * y).sum();
macro bool[<*>] ulong[<*>].comp_lt(ulong[<*>] x, ulong[<*>] y) => $$veccomplt(x, y); macro bool[<?>] ulong[<?>].comp_lt(ulong[<?>] x, ulong[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] ulong[<*>].comp_le(ulong[<*>] x, ulong[<*>] y) => $$veccomple(x, y); macro bool[<?>] ulong[<?>].comp_le(ulong[<?>] x, ulong[<?>] y) => $$veccomple(x, y);
macro bool[<*>] ulong[<*>].comp_eq(ulong[<*>] x, ulong[<*>] y) => $$veccompeq(x, y); macro bool[<?>] ulong[<?>].comp_eq(ulong[<?>] x, ulong[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] ulong[<*>].comp_gt(ulong[<*>] x, ulong[<*>] y) => $$veccompgt(x, y); macro bool[<?>] ulong[<?>].comp_gt(ulong[<?>] x, ulong[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] ulong[<*>].comp_ge(ulong[<*>] x, ulong[<*>] y) => $$veccompge(x, y); macro bool[<?>] ulong[<?>].comp_ge(ulong[<?>] x, ulong[<?>] y) => $$veccompge(x, y);
macro bool[<*>] ulong[<*>].comp_ne(ulong[<*>] x, ulong[<*>] y) => $$veccompne(x, y); macro bool[<?>] ulong[<?>].comp_ne(ulong[<?>] x, ulong[<?>] y) => $$veccompne(x, y);
macro ulong ulong[<*>].sum(ulong[<*>] x) => $$reduce_add(x); macro ulong ulong[<?>].sum(ulong[<?>] x) => $$reduce_add(x);
macro ulong ulong[<*>].product(ulong[<*>] x) => $$reduce_mul(x); macro ulong ulong[<?>].product(ulong[<?>] x) => $$reduce_mul(x);
macro ulong ulong[<*>].and(ulong[<*>] x) => $$reduce_and(x); macro ulong ulong[<?>].and(ulong[<?>] x) => $$reduce_and(x);
macro ulong ulong[<*>].or(ulong[<*>] x) => $$reduce_or(x); macro ulong ulong[<?>].or(ulong[<?>] x) => $$reduce_or(x);
macro ulong ulong[<*>].xor(ulong[<*>] x) => $$reduce_xor(x); macro ulong ulong[<?>].xor(ulong[<?>] x) => $$reduce_xor(x);
macro ulong ulong[<*>].max(ulong[<*>] x) => $$reduce_max(x); macro ulong ulong[<?>].max(ulong[<?>] x) => $$reduce_max(x);
macro ulong ulong[<*>].min(ulong[<*>] x) => $$reduce_min(x); macro ulong ulong[<?>].min(ulong[<?>] x) => $$reduce_min(x);
macro ulong ulong[<*>].dot(ulong[<*>] x, ulong[<*>] y) => (x * y).sum(); macro ulong ulong[<?>].dot(ulong[<?>] x, ulong[<?>] y) => (x * y).sum();
macro bool[<*>] uint128[<*>].comp_lt(uint128[<*>] x, uint128[<*>] y) => $$veccomplt(x, y); macro bool[<?>] uint128[<?>].comp_lt(uint128[<?>] x, uint128[<?>] y) => $$veccomplt(x, y);
macro bool[<*>] uint128[<*>].comp_le(uint128[<*>] x, uint128[<*>] y) => $$veccomple(x, y); macro bool[<?>] uint128[<?>].comp_le(uint128[<?>] x, uint128[<?>] y) => $$veccomple(x, y);
macro bool[<*>] uint128[<*>].comp_eq(uint128[<*>] x, uint128[<*>] y) => $$veccompeq(x, y); macro bool[<?>] uint128[<?>].comp_eq(uint128[<?>] x, uint128[<?>] y) => $$veccompeq(x, y);
macro bool[<*>] uint128[<*>].comp_gt(uint128[<*>] x, uint128[<*>] y) => $$veccompgt(x, y); macro bool[<?>] uint128[<?>].comp_gt(uint128[<?>] x, uint128[<?>] y) => $$veccompgt(x, y);
macro bool[<*>] uint128[<*>].comp_ge(uint128[<*>] x, uint128[<*>] y) => $$veccompge(x, y); macro bool[<?>] uint128[<?>].comp_ge(uint128[<?>] x, uint128[<?>] y) => $$veccompge(x, y);
macro bool[<*>] uint128[<*>].comp_ne(uint128[<*>] x, uint128[<*>] y) => $$veccompne(x, y); macro bool[<?>] uint128[<?>].comp_ne(uint128[<?>] x, uint128[<?>] y) => $$veccompne(x, y);
macro uint128 uint128[<*>].sum(uint128[<*>] x) => $$reduce_add(x); macro uint128 uint128[<?>].sum(uint128[<?>] x) => $$reduce_add(x);
macro uint128 uint128[<*>].product(uint128[<*>] x) => $$reduce_mul(x); macro uint128 uint128[<?>].product(uint128[<?>] x) => $$reduce_mul(x);
macro uint128 uint128[<*>].and(uint128[<*>] x) => $$reduce_and(x); macro uint128 uint128[<?>].and(uint128[<?>] x) => $$reduce_and(x);
macro uint128 uint128[<*>].or(uint128[<*>] x) => $$reduce_or(x); macro uint128 uint128[<?>].or(uint128[<?>] x) => $$reduce_or(x);
macro uint128 uint128[<*>].xor(uint128[<*>] x) => $$reduce_xor(x); macro uint128 uint128[<?>].xor(uint128[<?>] x) => $$reduce_xor(x);
macro uint128 uint128[<*>].max(uint128[<*>] x) => $$reduce_max(x); macro uint128 uint128[<?>].max(uint128[<?>] x) => $$reduce_max(x);
macro uint128 uint128[<*>].min(uint128[<*>] x) => $$reduce_min(x); macro uint128 uint128[<?>].min(uint128[<?>] x) => $$reduce_min(x);
macro uint128 uint128[<*>].dot(uint128[<*>] x, uint128[<*>] y) => (x * y).sum(); macro uint128 uint128[<?>].dot(uint128[<?>] x, uint128[<?>] y) => (x * y).sum();
macro char char.sat_add(char x, char y) => $$sat_add(x, y); macro char char.sat_add(char x, char y) => $$sat_add(x, y);
macro char char.sat_sub(char x, char y) => $$sat_sub(x, y); macro char char.sat_sub(char x, char y) => $$sat_sub(x, y);
@@ -1178,49 +1178,49 @@ macro bool @is_same_vector_or_scalar(#vector_value, #vector_or_scalar) @private
@require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar`
@require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar`
*> *>
macro char[<*>] char[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); macro char[<?>] char[<?>].muldiv(self, mul, div) => mul_div_helper(self, mul, div);
<* <*
@require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar`
@require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar`
*> *>
macro ichar[<*>] ichar[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); macro ichar[<?>] ichar[<?>].muldiv(self, mul, div) => mul_div_helper(self, mul, div);
<* <*
@require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar`
@require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar`
*> *>
macro short[<*>] short[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); macro short[<?>] short[<?>].muldiv(self, mul, div) => mul_div_helper(self, mul, div);
<* <*
@require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar`
@require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar`
*> *>
macro ushort[<*>] ushort[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); macro ushort[<?>] ushort[<?>].muldiv(self, mul, div) => mul_div_helper(self, mul, div);
<* <*
@require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar`
@require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar`
*> *>
macro int[<*>] int[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); macro int[<?>] int[<?>].muldiv(self, mul, div) => mul_div_helper(self, mul, div);
<* <*
@require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar`
@require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar`
*> *>
macro uint[<*>] uint[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); macro uint[<?>] uint[<?>].muldiv(self, mul, div) => mul_div_helper(self, mul, div);
<* <*
@require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar`
@require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar`
*> *>
macro long[<*>] long[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); macro long[<?>] long[<?>].muldiv(self, mul, div) => mul_div_helper(self, mul, div);
<* <*
@require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar`
@require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar`
*> *>
macro ulong[<*>] ulong[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); macro ulong[<?>] ulong[<?>].muldiv(self, mul, div) => mul_div_helper(self, mul, div);
<* <*
@require types::is_int($typeof(a)) `The input must be an integer` @require types::is_int($typeof(a)) `The input must be an integer`

View File

@@ -11,7 +11,7 @@ module std::math::nolibc @if(env::NO_LIBC || $feature(C3_MATH));
* ==================================================== * ====================================================
*/ */
const double[*] TAN_T = { const double[?] TAN_T = {
3.33333333333334091986e-01, /* 3FD55555, 55555563 */ 3.33333333333334091986e-01, /* 3FD55555, 55555563 */
1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */ 1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */
5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */ 5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */

View File

@@ -16,7 +16,7 @@ module std::math::nolibc @if(env::NO_LIBC || $feature(C3_MATH));
*/ */
// |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). // |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]).
const double[*] TANDF = { const double[?] TANDF = {
0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */ 0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */
0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */ 0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */
0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */ 0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */

View File

@@ -12,21 +12,21 @@ module std::math::nolibc @if(env::NO_LIBC || $feature(C3_MATH));
* ==================================================== * ====================================================
*/ */
const double[*] ATANHI @private = { const double[?] ATANHI @private = {
4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
}; };
const double[*] ATANLO @private = { const double[?] ATANLO @private = {
2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
}; };
const double[*] AT @private = { const double[?] AT @private = {
3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
-1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
@@ -116,21 +116,21 @@ fn double _atan(double x) @weak @extern("atan") @nostrip
* ==================================================== * ====================================================
*/ */
const float[*] ATANHIF @private = { const float[?] ATANHIF @private = {
4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */ 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */
7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */ 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */
9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */ 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */
1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */ 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */
}; };
const float[*] ATANLOF @private = { const float[?] ATANLOF @private = {
5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */ 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */
3.7748947079e-08, /* atan(1.0)lo 0x33222168 */ 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */
3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */ 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */
7.5497894159e-08, /* atan(inf)lo 0x33a22168 */ 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */
}; };
const float[*] ATF @private = { const float[?] ATF @private = {
3.3333328366e-01, 3.3333328366e-01,
-1.9999158382e-01, -1.9999158382e-01,
1.4253635705e-01, 1.4253635705e-01,

View File

@@ -94,9 +94,9 @@ fn int __rem_pio2f(float x, double *y)
* ==================================================== * ====================================================
*/ */
const int[*] INIT_JK = {3,4,4,6}; /* initial value for jk */ const int[?] INIT_JK = {3,4,4,6}; /* initial value for jk */
const int[*] IPIO2 = { const int[?] IPIO2 = {
0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
@@ -109,7 +109,7 @@ const int[*] IPIO2 = {
0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, }; 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, };
const double[*] PIO2 = { const double[?] PIO2 = {
1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */

View File

@@ -22,7 +22,7 @@ struct Posix_dirent
char[255+1] name @if(env::FREEBSD || env::OPENBSD); char[255+1] name @if(env::FREEBSD || env::OPENBSD);
char[511+1] name @if(env::NETBSD); char[511+1] name @if(env::NETBSD);
char[1024] name @if(env::DARWIN); char[1024] name @if(env::DARWIN);
char[*] name @if(!env::DARWIN && !env::BSD_FAMILY); char[?] name @if(!env::DARWIN && !env::BSD_FAMILY);
} }
extern fn int rmdir(ZString); extern fn int rmdir(ZString);

View File

@@ -18,7 +18,7 @@ struct BufferedChannelImpl @private
usz read_waiting; usz read_waiting;
ConditionVariable read_cond; ConditionVariable read_cond;
Type[*] buf; Type[?] buf;
} }
fn void! BufferedChannel.new_init(&self, usz size = 1) fn void! BufferedChannel.new_init(&self, usz size = 1)

View File

@@ -10,6 +10,8 @@
- VERY experimental `<[ ]>` syntax for generics. - VERY experimental `<[ ]>` syntax for generics.
- Compile time array assignment #1806. - Compile time array assignment #1806.
- Allow `+++` to work on all types of arrays. - Allow `+++` to work on all types of arrays.
- Allow `(int[*]) { 1, 2 }` cast style initialization.
- Experimental change from `[*]` to `[?]`
### Fixes ### Fixes
- Fix issue requiring prefix on a generic interface declaration. - Fix issue requiring prefix on a generic interface declaration.
@@ -25,6 +27,7 @@
- Fixes to `"exec" use, including issue when compiling with MinGW. - Fixes to `"exec" use, including issue when compiling with MinGW.
- Correctly check jump table size and be generous when compiling it #1877. - Correctly check jump table size and be generous when compiling it #1877.
- Fix bug where .min/.max would fail on a distinct int #1888. - Fix bug where .min/.max would fail on a distinct int #1888.
- Fix issue where compile time declarations in expression list would not be handled properly.
### Stdlib changes ### Stdlib changes
- Added '%h' and '%H' for printing out binary data in hexadecimal using the formatter. - Added '%h' and '%H' for printing out binary data in hexadecimal using the formatter.

View File

@@ -127,7 +127,7 @@ fn void main()
encode(helloworld[0..12], &buffer); encode(helloworld[0..12], &buffer);
printf("Result: %s\n", &buffer); printf("Result: %s\n", &buffer);
char *to_decode = "aGVsbG8gd29ybGRcMA=="; char *to_decode = "aGVsbG8gd29ybGRcMA==";
char[*] result = b64"aGVsbG8gd29ybGRcMA=="; char[?] result = b64"aGVsbG8gd29ybGRcMA==";
decode((String)to_decode[0..19], &buffer)!!; decode((String)to_decode[0..19], &buffer)!!;
printf("Result: %s\n", &buffer); printf("Result: %s\n", &buffer);
printf("Result direct: %.*s\n", 13, &result); printf("Result direct: %.*s\n", 13, &result);

View File

@@ -81,7 +81,7 @@ fn void offset_momentum(Planet[] bodies)
bodies[0].vz = - pz / SOLAR_MASS; bodies[0].vz = - pz / SOLAR_MASS;
} }
Planet[*] planet_bodies = { Planet[?] planet_bodies = {
{ /* sun */ { /* sun */
0, 0, 0, 0, 0, 0, SOLAR_MASS 0, 0, 0, 0, 0, 0, SOLAR_MASS
}, },

View File

@@ -289,7 +289,7 @@ struct Type_
Decl *decl; Decl *decl;
// int, float, bool // int, float, bool
TypeBuiltin builtin; TypeBuiltin builtin;
// Type[], Type[*], Type[123], Type[<123>] or Type<[123]> // Type[], Type[?], Type[123] or Type[<123>]
TypeArray array; TypeArray array;
// fn TypeR Type1(Type2, Type3, ...) // fn TypeR Type1(Type2, Type3, ...)
TypeFunction function; TypeFunction function;

View File

@@ -158,11 +158,11 @@ void print_type(FILE *file, TypeInfo *type)
break; break;
case TYPE_INFO_INFERRED_ARRAY: case TYPE_INFO_INFERRED_ARRAY:
print_type(file, type->array.base); print_type(file, type->array.base);
fputs("[*]", file); fputs("[?]", file);
break; break;
case TYPE_INFO_INFERRED_VECTOR: case TYPE_INFO_INFERRED_VECTOR:
print_type(file, type->array.base); print_type(file, type->array.base);
fputs("[<*>]", file); fputs("[<?>]", file);
break; break;
case TYPE_INFO_SLICE: case TYPE_INFO_SLICE:
print_type(file, type->array.base); print_type(file, type->array.base);

View File

@@ -522,7 +522,7 @@ static inline TypeInfo *parse_array_type_index(ParseContext *c, TypeInfo *type)
ASSERT(type_info_ok(type)); ASSERT(type_info_ok(type));
advance_and_verify(c, TOKEN_LBRACKET); advance_and_verify(c, TOKEN_LBRACKET);
if (try_consume(c, TOKEN_STAR)) if (try_consume(c, TOKEN_STAR) || try_consume(c, TOKEN_QUESTION))
{ {
CONSUME_OR_RET(TOKEN_RBRACKET, poisoned_type_info); CONSUME_OR_RET(TOKEN_RBRACKET, poisoned_type_info);
TypeInfo *inferred_array = type_info_new(TYPE_INFO_INFERRED_ARRAY, type->span); TypeInfo *inferred_array = type_info_new(TYPE_INFO_INFERRED_ARRAY, type->span);
@@ -582,7 +582,7 @@ static inline TypeInfo *parse_vector_type_index(ParseContext *c, TypeInfo *type)
advance_and_verify(c, TOKEN_LVEC); advance_and_verify(c, TOKEN_LVEC);
TypeInfo *vector = type_info_new(TYPE_INFO_VECTOR, type->span); TypeInfo *vector = type_info_new(TYPE_INFO_VECTOR, type->span);
vector->array.base = type; vector->array.base = type;
if (try_consume(c, TOKEN_STAR)) if (try_consume(c, TOKEN_STAR) || try_consume(c, TOKEN_QUESTION))
{ {
CONSUME_OR_RET(TOKEN_RVEC, poisoned_type_info); CONSUME_OR_RET(TOKEN_RVEC, poisoned_type_info);
vector->kind = TYPE_INFO_INFERRED_VECTOR; vector->kind = TYPE_INFO_INFERRED_VECTOR;
@@ -684,7 +684,7 @@ typedef enum DiscardedSubscript_
static DiscardedSubscript parse_discarded_subscript(ParseContext *c, TokenType end) static DiscardedSubscript parse_discarded_subscript(ParseContext *c, TokenType end)
{ {
if (end == TOKEN_RBRACKET && try_consume(c, end)) return DISCARD_SLICE; if (end == TOKEN_RBRACKET && try_consume(c, end)) return DISCARD_SLICE;
if (try_consume(c, TOKEN_STAR)) if (try_consume(c, TOKEN_STAR) || try_consume(c, TOKEN_QUESTION))
{ {
CONSUME_OR_RET(end, DISCARD_ERR); CONSUME_OR_RET(end, DISCARD_ERR);
return DISCARD_WILDCARD; return DISCARD_WILDCARD;
@@ -704,7 +704,7 @@ INLINE bool parse_rethrow_bracket(ParseContext *c, SourceSpan start)
case DISCARD_ERR: case DISCARD_ERR:
return false; return false;
case DISCARD_WILDCARD: case DISCARD_WILDCARD:
print_error_at(extend_span_with_token(start, c->prev_span), "When declaring an optional array, the '[*]' should appear before the '!', e.g 'Foo[*]!'."); print_error_at(extend_span_with_token(start, c->prev_span), "When declaring an optional array, the '[?]' should appear before the '!', e.g 'Foo[?]!'.");
return false; return false;
case DISCARD_SLICE: case DISCARD_SLICE:
print_error_at(extend_span_with_token(start, c->prev_span), print_error_at(extend_span_with_token(start, c->prev_span),
@@ -723,7 +723,7 @@ INLINE bool parse_rethrow_bracket(ParseContext *c, SourceSpan start)
case DISCARD_ERR: case DISCARD_ERR:
return false; return false;
case DISCARD_WILDCARD: case DISCARD_WILDCARD:
print_error_at(extend_span_with_token(start, c->span), "When declaring an optional vector, the '[<*>]' should appear before the '!', e.g 'Foo[<*>]!'."); print_error_at(extend_span_with_token(start, c->span), "When declaring an optional vector, the '[<?>]' should appear before the '!', e.g 'Foo[<?>]!'.");
return false; return false;
case DISCARD_SLICE: case DISCARD_SLICE:
UNREACHABLE UNREACHABLE

View File

@@ -226,10 +226,10 @@ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type)
// if so we assume the original type // if so we assume the original type
if (!type_len_is_inferred(to_infer)) return to_infer; if (!type_len_is_inferred(to_infer)) return to_infer;
// Handle int[*]! a = { ... } by stripping the optional. // Handle int[?]! a = { ... } by stripping the optional.
bool is_optional = type_is_optional(to_infer); bool is_optional = type_is_optional(to_infer);
assert((is_optional || !type_is_optional(actual_type)) && "int[*] x = { may_fail } should have been caught."); assert((is_optional || !type_is_optional(actual_type)) && "int[?] x = { may_fail } should have been caught.");
// Strip the optional // Strip the optional
if (is_optional) to_infer = to_infer->optional; if (is_optional) to_infer = to_infer->optional;
@@ -241,7 +241,7 @@ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type)
if (!actual) return actual_type; if (!actual) return actual_type;
// Grab the underlying indexed type, // Grab the underlying indexed type,
// because we can only have [*] [] [<*>] [<>] * here // because we can only have [?] [] [<?>] [<>] * here
Type *indexed = type_get_indexed_type(to_infer); Type *indexed = type_get_indexed_type(to_infer);
// We should always have indexed types. // We should always have indexed types.
@@ -251,7 +251,7 @@ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type)
// In this case, infer it. // In this case, infer it.
if (type_len_is_inferred(indexed)) if (type_len_is_inferred(indexed))
{ {
// if we have int[*][*] => the inner is int[*], we cast it here. // if we have int[?][?] => the inner is int[?], we cast it here.
indexed = type_infer_len_from_actual_type(indexed, actual); indexed = type_infer_len_from_actual_type(indexed, actual);
} }
@@ -259,10 +259,10 @@ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type)
switch (to_infer->type_kind) switch (to_infer->type_kind)
{ {
case TYPE_POINTER: case TYPE_POINTER:
// The case of int[*]* x = ... // The case of int[?]* x = ...
return type_add_optional(type_get_ptr(indexed), is_optional); return type_add_optional(type_get_ptr(indexed), is_optional);
case TYPE_ARRAY: case TYPE_ARRAY:
// The case of int[*][2] x = ... // The case of int[?][2] x = ...
return type_add_optional(type_get_array(indexed, to_infer->array.len), is_optional); return type_add_optional(type_get_array(indexed, to_infer->array.len), is_optional);
case TYPE_INFERRED_ARRAY: case TYPE_INFERRED_ARRAY:
ASSERT(type_is_arraylike(type_flatten(actual_type))); ASSERT(type_is_arraylike(type_flatten(actual_type)));
@@ -273,7 +273,7 @@ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type)
case TYPE_SLICE: case TYPE_SLICE:
return type_add_optional(type_get_slice(indexed), is_optional); return type_add_optional(type_get_slice(indexed), is_optional);
case TYPE_VECTOR: case TYPE_VECTOR:
// The case of int[*]*[<2>] x = ... // The case of int[?]*[<2>] x = ...
return type_add_optional(type_get_vector(indexed, to_infer->array.len), is_optional); return type_add_optional(type_get_vector(indexed, to_infer->array.len), is_optional);
default: default:
UNREACHABLE UNREACHABLE
@@ -852,7 +852,11 @@ static bool rule_ulist_to_inferred(CastContext *cc, bool is_explicit, bool is_si
Type *base = cc->to->array.base; Type *base = cc->to->array.base;
FOREACH(Expr *, expr, expressions) FOREACH(Expr *, expr, expressions)
{ {
if (!may_cast(cc->context, expr, base, false, is_silent)) return false; if (!may_cast(cc->context, expr, base, false, true))
{
RETURN_CAST_ERROR(cc->expr, "This untyped list contains an element of type %s which cannot be converted to %s.",
type_quoted_error_string(expr->type), type_quoted_error_string(base));
}
} }
return true; return true;
} }
@@ -2181,7 +2185,7 @@ static void cast_typeid_to_bool(SemaContext *context, Expr *expr, Type *to_type)
#define RINPT &rule_int_to_ptr /* Int -> ptr (explicit + size match) */ #define RINPT &rule_int_to_ptr /* Int -> ptr (explicit + size match) */
#define RPTIN &rule_ptr_to_int /* Ptr -> int (explicit + size match) */ #define RPTIN &rule_ptr_to_int /* Ptr -> int (explicit + size match) */
#define RINBS &rule_int_to_bits /* Int -> bits (explicit + int + size match) */ #define RINBS &rule_int_to_bits /* Int -> bits (explicit + int + size match) */
#define RARBS &rule_arr_to_bits /* Char[*] -> bits (explicit + base match) */ #define RARBS &rule_arr_to_bits /* Char[?] -> bits (explicit + base match) */
#define RINEN &rule_int_to_enum /* Int -> enum (explicit, range check const) */ #define RINEN &rule_int_to_enum /* Int -> enum (explicit, range check const) */
#define RPTPT &rule_ptr_to_ptr /* Ptr -> ptr (explicit or ptr match) */ #define RPTPT &rule_ptr_to_ptr /* Ptr -> ptr (explicit or ptr match) */
#define RAPSL &rule_arrptr_to_slice /* Arrptr -> Slice (explicit flattens distinct, pointer match) */ #define RAPSL &rule_arrptr_to_slice /* Arrptr -> Slice (explicit flattens distinct, pointer match) */

View File

@@ -238,7 +238,7 @@ static inline bool sema_analyse_struct_member(SemaContext *context, Decl *parent
{ {
ASSERT(decl->var.kind == VARDECL_MEMBER); ASSERT(decl->var.kind == VARDECL_MEMBER);
decl->resolve_status = RESOLVE_RUNNING; decl->resolve_status = RESOLVE_RUNNING;
// Inferred types are not strictly allowed, but we use the int[*] for the flexible array member. // Inferred types are not strictly allowed, but we use the int[?] for the flexible array member.
ASSERT(type_infoptrzero(decl->var.type_info)); ASSERT(type_infoptrzero(decl->var.type_info));
TypeInfo *type_info = type_infoptr(decl->var.type_info); TypeInfo *type_info = type_infoptr(decl->var.type_info);
if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_ALLOW_FLEXIBLE)) return decl_poison(decl); if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_ALLOW_FLEXIBLE)) return decl_poison(decl);
@@ -513,9 +513,9 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl)
Type *member_type = type_flatten(member->type); Type *member_type = type_flatten(member->type);
// If this is a struct and it has a variable array ending, then it must also be the last struct. // If this is a struct and it has a variable array ending, then it must also be the last struct.
// So this is ok: // So this is ok:
// struct Foo { int x; struct { int x; int[*] y; } } // struct Foo { int x; struct { int x; int[?] y; } }
// But not this: // But not this:
// struct Bar { struct { int x; int[*] y; } int x; } // struct Bar { struct { int x; int[?] y; } int x; }
if (member_type->type_kind == TYPE_STRUCT && member_type->decl->has_variable_array) if (member_type->type_kind == TYPE_STRUCT && member_type->decl->has_variable_array)
{ {
if (i != member_count - 1) if (i != member_count - 1)

View File

@@ -5660,7 +5660,7 @@ static inline bool sema_expr_analyse_cast(SemaContext *context, Expr *expr, bool
if (invalid_cast_ref) *invalid_cast_ref = false; if (invalid_cast_ref) *invalid_cast_ref = false;
Expr *inner = exprptr(expr->cast_expr.expr); Expr *inner = exprptr(expr->cast_expr.expr);
TypeInfo *type_info = type_infoptr(expr->cast_expr.type_info); TypeInfo *type_info = type_infoptr(expr->cast_expr.type_info);
bool success = sema_resolve_type_info(context, type_info, RESOLVE_TYPE_DEFAULT); bool success = sema_resolve_type_info(context, type_info, RESOLVE_TYPE_ALLOW_INFER);
if (!sema_analyse_expr(context, inner) || !success) return false; if (!sema_analyse_expr(context, inner) || !success) return false;
Type *target_type = type_info->type; Type *target_type = type_info->type;
@@ -9808,9 +9808,25 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr,
if (!sema_expr_analyse_ct_stringify(context, expr)) return false; if (!sema_expr_analyse_ct_stringify(context, expr)) return false;
return true; return true;
case EXPR_DECL: case EXPR_DECL:
if (!sema_analyse_var_decl(context, expr->decl_expr, true)) return false; {
expr->type = expr->decl_expr->type; Decl *decl = expr->decl_expr;
bool erase = decl->var.kind == VARDECL_LOCAL_CT_TYPE || decl->var.kind == VARDECL_LOCAL_CT;
if (!sema_analyse_var_decl(context, decl, true)) return false;
if (erase)
{
Expr *init = decl->var.init_expr;
if (init)
{
expr_replace(expr, copy_expr_single(decl->var.init_expr));
return true;
}
expr->expr_kind = EXPR_NOP;
expr->type = type_void;
return true;
}
expr->type = decl->type;
return true; return true;
}
case EXPR_LAST_FAULT: case EXPR_LAST_FAULT:
expr->type = type_anyfault; expr->type = type_anyfault;
return true; return true;

View File

@@ -326,7 +326,7 @@ static inline bool sema_expr_analyse_array_plain_initializer(SemaContext *contex
Expr **elements = initializer->initializer_list; Expr **elements = initializer->initializer_list;
bool inferred_len = type_len_is_inferred(flattened); bool inferred_len = type_len_is_inferred(flattened);
// We have the case where "Foo = int[*]" // We have the case where "Foo = int[?]"
if (inferred_len && !type_len_is_inferred(assigned)) if (inferred_len && !type_len_is_inferred(assigned))
{ {
ASSERT(assigned->type_kind == TYPE_TYPEDEF); ASSERT(assigned->type_kind == TYPE_TYPEDEF);

View File

@@ -145,7 +145,7 @@ void type_append_name_to_scratch(Type *type)
break; break;
case TYPE_FLEXIBLE_ARRAY: case TYPE_FLEXIBLE_ARRAY:
type_append_name_to_scratch(type->array.base); type_append_name_to_scratch(type->array.base);
scratch_buffer_append("[*]"); scratch_buffer_append("[?]");
break; break;
case TYPE_VOID: case TYPE_VOID:
case TYPE_BOOL: case TYPE_BOOL:
@@ -277,7 +277,7 @@ const char *type_to_error_string(Type *type)
type_append_func_to_scratch(type->function.prototype); type_append_func_to_scratch(type->function.prototype);
return scratch_buffer_copy(); return scratch_buffer_copy();
case TYPE_INFERRED_VECTOR: case TYPE_INFERRED_VECTOR:
return str_printf("%s[<*>]", type_to_error_string(type->array.base)); return str_printf("%s[<?>]", type_to_error_string(type->array.base));
case TYPE_VECTOR: case TYPE_VECTOR:
return str_printf("%s[<%llu>]", type_to_error_string(type->array.base), (unsigned long long)type->array.len); return str_printf("%s[<%llu>]", type_to_error_string(type->array.base), (unsigned long long)type->array.len);
case TYPE_TYPEINFO: case TYPE_TYPEINFO:
@@ -293,7 +293,7 @@ const char *type_to_error_string(Type *type)
return str_printf("%s[%llu]", type_to_error_string(type->array.base), (unsigned long long)type->array.len); return str_printf("%s[%llu]", type_to_error_string(type->array.base), (unsigned long long)type->array.len);
case TYPE_INFERRED_ARRAY: case TYPE_INFERRED_ARRAY:
case TYPE_FLEXIBLE_ARRAY: case TYPE_FLEXIBLE_ARRAY:
return str_printf("%s[*]", type_to_error_string(type->array.base)); return str_printf("%s[?]", type_to_error_string(type->array.base));
case TYPE_SLICE: case TYPE_SLICE:
return str_printf("%s[]", type_to_error_string(type->array.base)); return str_printf("%s[]", type_to_error_string(type->array.base));
} }
@@ -839,7 +839,7 @@ static Type *type_generate_inferred_array(Type *arr_type, bool canonical)
Type *arr = arr_type->type_cache[INFERRED_ARRAY_OFFSET]; Type *arr = arr_type->type_cache[INFERRED_ARRAY_OFFSET];
if (arr == NULL) if (arr == NULL)
{ {
arr = type_new(TYPE_INFERRED_ARRAY, str_printf("%s[*]", arr_type->name)); arr = type_new(TYPE_INFERRED_ARRAY, str_printf("%s[?]", arr_type->name));
arr->array.base = arr_type; arr->array.base = arr_type;
arr_type->type_cache[INFERRED_ARRAY_OFFSET] = arr; arr_type->type_cache[INFERRED_ARRAY_OFFSET] = arr;
if (arr_type == arr_type->canonical) if (arr_type == arr_type->canonical)
@@ -865,7 +865,7 @@ static Type *type_generate_inferred_vector(Type *arr_type, bool canonical)
Type *arr = arr_type->type_cache[INFERRED_VECTOR_OFFSET]; Type *arr = arr_type->type_cache[INFERRED_VECTOR_OFFSET];
if (arr == NULL) if (arr == NULL)
{ {
arr = type_new(TYPE_INFERRED_VECTOR, str_printf("%s[<*>]", arr_type->name)); arr = type_new(TYPE_INFERRED_VECTOR, str_printf("%s[<?>]", arr_type->name));
arr->array.base = arr_type; arr->array.base = arr_type;
arr_type->type_cache[INFERRED_VECTOR_OFFSET] = arr; arr_type->type_cache[INFERRED_VECTOR_OFFSET] = arr;
if (arr_type == arr_type->canonical) if (arr_type == arr_type->canonical)
@@ -891,7 +891,7 @@ static Type *type_generate_flexible_array(Type *arr_type, bool canonical)
Type *arr = arr_type->type_cache[FLEXIBLE_ARRAY_OFFSET]; Type *arr = arr_type->type_cache[FLEXIBLE_ARRAY_OFFSET];
if (arr == NULL) if (arr == NULL)
{ {
arr = type_new(TYPE_FLEXIBLE_ARRAY, str_printf("%s[*]", arr_type->name)); arr = type_new(TYPE_FLEXIBLE_ARRAY, str_printf("%s[?]", arr_type->name));
arr->array.base = arr_type; arr->array.base = arr_type;
arr->array.len = 0; arr->array.len = 0;
arr_type->type_cache[FLEXIBLE_ARRAY_OFFSET] = arr; arr_type->type_cache[FLEXIBLE_ARRAY_OFFSET] = arr;

View File

@@ -3,8 +3,8 @@ module test;
fn void main() fn void main()
{ {
int[*][*][2][*]! y = { {{{1}, {2}}, { {3}, {4}}}}; int[?][?][2][?]! y = { {{{1}, {2}}, { {3}, {4}}}};
int[*][*][2][*] x = { {{{1}, {2}}, { {3}, {4}}}}; int[?][?][2][?] x = { {{{1}, {2}}, { {3}, {4}}}};
} }
/* #expect: test.ll /* #expect: test.ll

View File

@@ -1,7 +1,7 @@
fn int[*] hello() // #error: Inferred array types can only be used in declarations with initializers fn int[?] hello() // #error: Inferred array types can only be used in declarations with initializers
{ {
return int[3] { 1, 2, 3}; return int[3] { 1, 2, 3};
} }
int[*] c; // #error: Inferred array types can only be used in declarations with initializers int[?] c; // #error: Inferred array types can only be used in declarations with initializers

View File

@@ -1,5 +1,5 @@
fn void test() fn void test()
{ {
int[3] z; int[3] z;
(int[*])(z); // #error: Inferred array types can only be used in declarations with initializers (int[?])(z);
} }

View File

@@ -5,10 +5,10 @@ fn int! foo() => 1;
fn int main() fn int main()
{ {
int[*]! x = { 1, 2 }; int[?]! x = { 1, 2 };
int[*]! y = { foo(), foo() }; int[?]! y = { foo(), foo() };
int[<*>]! x2 = { 1, 2 }; int[<?>]! x2 = { 1, 2 };
int[<*>]! y2 = { foo(), foo() }; int[<?>]! y2 = { foo(), foo() };
return 1; return 1;
} }

View File

@@ -1,5 +1,5 @@
fn void main() fn void main()
{ {
int[*][*][] x = int[2][1][] { { { 1, 2 } } }; int[?][?][] x = int[2][1][] { { { 1, 2 } } };
int[*][*][*] y = int[2][1][] { { { 1, 2 } } }; int[?][?][?] y = int[2][1][] { { { 1, 2 } } };
} }

View File

@@ -1,6 +1,6 @@
import std; import std;
fn void main() fn void main()
{ {
char[*]* x = "abc"; // #error: You cannot cast 'String' to 'char[*]*' char[?]* x = "abc"; // #error: You cannot cast 'String' to 'char[?]*'
io::printn($typeof(x).nameof); io::printn($typeof(x).nameof);
} }

View File

@@ -1,19 +1,19 @@
// #target: macos-x64 // #target: macos-x64
module test; module test;
macro int test(int[*][*]* y) macro int test(int[?][?]* y)
{ {
$typeof(*y) z = *y; $typeof(*y) z = *y;
return z[1][1]; return z[1][1];
} }
fn void main() fn void main()
{ {
int[2][*] x = { { 2, 3}, { 5, 6 }}; int[2][?] x = { { 2, 3}, { 5, 6 }};
int[<2>][*] y = { { 1, 3 }}; int[<2>][?] y = { { 1, 3 }};
int[<*>][*] z = y; int[<?>][?] z = y;
int[<2>][1] w = z; int[<2>][1] w = z;
int[<2>][] aa = { { 1, 3 }}; int[<2>][] aa = { { 1, 3 }};
int[][*] bb = { { 1, 3 } }; int[][?] bb = { { 1, 3 } };
test(&x); test(&x);
} }
/* #expect: test.ll /* #expect: test.ll

View File

@@ -125,11 +125,11 @@ double afoo = 17;
double abar = 12.0; double abar = 12.0;
float axx = 12.0f; float axx = 12.0f;
char*[*] procnames = { char*[?] procnames = {
"EXIT" "EXIT"
}; };
void *[*] data = { &afoo, &abar, &axx }; void *[?] data = { &afoo, &abar, &axx };
/* #expect: test.ll /* #expect: test.ll

View File

@@ -3,7 +3,7 @@ module test;
import std; import std;
def @TaggedAttr(value) = { def @TaggedAttr(value) = {
@tag("foo", ValueHere[*]{ value }) @tag("foo", ValueHere[?]{ value })
}; };
const FOO_STR = "foo"; const FOO_STR = "foo";

View File

@@ -3,7 +3,7 @@ module test;
macro foo() macro foo()
{ {
var c = "hello" +++ " world"; var c = "hello" +++ " world";
String[*] a = String[1] { "hello" } +++ String[1] { " world" }; String[?] a = String[1] { "hello" } +++ String[1] { " world" };
int[2] $a = { 1, 2 }; int[2] $a = { 1, 2 };
$a = $a +++ 100; $a = $a +++ 100;
int z = $typeof($a).len; int z = $typeof($a).len;

View File

@@ -0,0 +1,40 @@
// #target: macos-x64
module test;
import std;
struct Vector3
{
float x, y, z;
}
macro @printVecs(Vector3... vectors)
{
for (int $i = 0; $i < vectors.len; ++$i)
{
// do something
}
}
fn void main()
{
@printVecs(Vector3{10, 5, 3}, Vector3{9, 6, 4}, Vector3{5, 4, 3});
}
/* #expect: test.ll
define void @test.main() #0 {
entry:
%literal = alloca [3 x %Vector3], align 16
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal, ptr align 16 @.__const, i32 36, i1 false)
%0 = insertvalue %"Vector3[]" undef, ptr %literal, 0
%1 = insertvalue %"Vector3[]" %0, i64 3, 1
br label %loop.cond
loop.cond: ; preds = %loop.inc, %entry
%2 = extractvalue %"Vector3[]" %1, 1
%lt = icmp ult i64 0, %2
br i1 %lt, label %loop.inc, label %loop.exit
loop.inc: ; preds = %loop.cond
br label %loop.cond
loop.exit: ; preds = %loop.cond
ret void
}

View File

@@ -5,7 +5,7 @@ import std::io;
fn void main() fn void main()
{ {
var $s1 = $stringify(1 + 2); var $s1 = $stringify(1 + 2);
char[*] s2 = $stringify($s1); char[?] s2 = $stringify($s1);
char[] s3 = $s1; char[] s3 = $s1;
io::printfn("$s1 == %s", $s1); io::printfn("$s1 == %s", $s1);

View File

@@ -2,5 +2,5 @@
fn void main() fn void main()
{ {
var $x = { 1, 1.0 }; var $x = { 1, 1.0 };
double[*] z = $x; double[?] z = $x;
} }

View File

@@ -19,7 +19,7 @@ fn void test3()
$assert $defined(Foo[1]); $assert $defined(Foo[1]);
$assert $defined(Foo*); $assert $defined(Foo*);
$assert $defined(Foo[]); $assert $defined(Foo[]);
$assert $defined(Foo[*]); $assert $defined(Foo[?]);
bool x = $defined(Foo[y]); // #error: 'y' could not be found, did you spell it right? bool x = $defined(Foo[y]); // #error: 'y' could not be found, did you spell it right?
} }

View File

@@ -6,7 +6,7 @@ fn void testme(int a, double b)
fn void main() fn void main()
{ {
ReflectedParam[*] z = $typeof(testme).paramsof; ReflectedParam[?] z = $typeof(testme).paramsof;
foreach (r : z) foreach (r : z)
{ {
io::printn(r); io::printn(r);

View File

@@ -1 +1 @@
char[*] foo64 = b64"SGVsbG8g!V29ybGQ="; // #error: '!' is not a valid base64 character char[?] foo64 = b64"SGVsbG8g!V29ybGQ="; // #error: '!' is not a valid base64 character

View File

@@ -1 +1 @@
char[*] foo64 = b64"SGVsbG8gV29y=bGQ="; // #error: 'b' can't be placed after an ending '=' char[?] foo64 = b64"SGVsbG8gV29y=bGQ="; // #error: 'b' can't be placed after an ending '='

View File

@@ -1 +1 @@
char[*] foo64 = b64"SGVsbG8gV29ybGQ==="; // #error: There cannot be more than char[?] foo64 = b64"SGVsbG8gV29ybGQ==="; // #error: There cannot be more than

View File

@@ -1 +1 @@
char[*] foo64 = x"abc def ^"; // #error: '^' isn't a valid hexadecimal digit, all digits should be a-z, A-Z and 0-9. char[?] foo64 = x"abc def ^"; // #error: '^' isn't a valid hexadecimal digit, all digits should be a-z, A-Z and 0-9.

View File

@@ -1,8 +1,8 @@
char[*] foob = x"a0"; char[?] foob = x"a0";
char[*] fooz = x"00aabbccddeeff"; char[?] fooz = x"00aabbccddeeff";
char[*] fooy = x'dead beef'; char[?] fooy = x'dead beef';
char[*] foow = x"4549234d e d"; char[?] foow = x"4549234d e d";
char[*] foo64 = b64"SGVsbG8gV29ybGQ="; char[?] foo64 = b64"SGVsbG8gV29ybGQ=";
/* #expect: byte_literals.ll /* #expect: byte_literals.ll

View File

@@ -3,6 +3,6 @@ import std;
fn void main() fn void main()
{ {
char[] cd = {}; char[] cd = {};
char[*] b = x""; // #error: must be at least 1 byte char[?] b = x""; // #error: must be at least 1 byte
io::printfn("%d", b.len); io::printfn("%d", b.len);
} }

View File

@@ -1,3 +1,3 @@
def Abc = int[*]; // #error: Inferred array types can only def Abc = int[?]; // #error: Inferred array types can only
def Bcd = anyfault; def Bcd = anyfault;
def Efd = any; def Efd = any;

View File

@@ -3,7 +3,7 @@ module testing;
fn void main() fn void main()
{ {
char[*] data = $embed("embed_basic.c3"); char[?] data = $embed("embed_basic.c3");
char* data2 = $embed("embed_basic.c3"); char* data2 = $embed("embed_basic.c3");
char[] data3 = $embed("embed_basic.c3"); char[] data3 = $embed("embed_basic.c3");
char* data4 = $embed("fiek") ?? null; char* data4 = $embed("fiek") ?? null;
@@ -13,9 +13,9 @@ fn void main()
/* #expect: testing.ll /* #expect: testing.ll
@.bytes = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[*] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*! data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1 @.bytes = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[?] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*! data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1
@.bytes.1 = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[*] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*! data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1 @.bytes.1 = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[?] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*! data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1
@.bytes.2 = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[*] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*! data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1 @.bytes.2 = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[?] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*! data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1
define void @testing.main() #0 { define void @testing.main() #0 {
entry: entry:

View File

@@ -7,7 +7,7 @@ fn void! test1()
fn void! test2() fn void! test2()
{ {
CallbackResult![*] result = 123; // #error: Foo[*]! CallbackResult![?] result = 123; // #error: Foo[?]!
} }
fn void! test3() fn void! test3()
@@ -17,7 +17,7 @@ fn void! test3()
fn void! test4() fn void! test4()
{ {
CallbackResult![<*>] result = 123; // #error: Foo[<*>]! CallbackResult![<?>] result = 123; // #error: Foo[<?>]!
} }
fn void! test5() fn void! test5()

View File

@@ -4,20 +4,20 @@ distinct Foo = int;
fn void test1() fn void test1()
{ {
int[2][*] x = { { 2, 3}, { 5, 6 }}; int[2][?] x = { { 2, 3}, { 5, 6 }};
Foo[2][2] y = x; // #error: explicit cast Foo[2][2] y = x; // #error: explicit cast
} }
fn void test2() fn void test2()
{ {
int[2][*] x = { { 2, 3}, { 5, 6 }}; int[2][?] x = { { 2, 3}, { 5, 6 }};
Foo[2][2] y = (Foo[2][2])x; Foo[2][2] y = (Foo[2][2])x;
} }
fn void test3() fn void test3()
{ {
int[2][*] x = { { 2, 3}, { 5, 6 }}; int[2][?] x = { { 2, 3}, { 5, 6 }};
Foo[2][2]* y = &x; // #error: explicit cast Foo[2][2]* y = &x; // #error: explicit cast
} }
@@ -27,6 +27,6 @@ struct Baz { int x; }
fn void test4() fn void test4()
{ {
Baz[2][*] x = { { { 2 } , { 3 } }, {{5}, {6} }}; Baz[2][?] x = { { { 2 } , { 3 } }, {{5}, {6} }};
Bar[*][*] y = (Bar[2][2])x; Bar[?][?] y = (Bar[2][2])x;
} }

View File

@@ -1,4 +1,4 @@
int[*] foo = {1,2,3}; int[?] foo = {1,2,3};
fn int* bar(int index) fn int* bar(int index)
{ {
int* array = &foo; int* array = &foo;

View File

@@ -7,7 +7,7 @@ int[2] a1 = { 1, 2 };
int[2] a2 = 30; // #error: 'int' to 'int[2]' int[2] a2 = 30; // #error: 'int' to 'int[2]'
ichar[*] a; // #error: Inferred array types can only be used in declarations with initializers ichar[?] a; // #error: Inferred array types can only be used in declarations with initializers
ichar ca = 0; ichar ca = 0;
ichar cb = 1; ichar cb = 1;

View File

@@ -2,7 +2,7 @@ fn void test()
{ {
char* hello = "123"; char* hello = "123";
String a = { '1', '2', '3' }; String a = { '1', '2', '3' };
char[*] b = { '1', '2', '3' }; char[?] b = { '1', '2', '3' };
char[3] c = { '1', '2', '3' }; char[3] c = { '1', '2', '3' };
char* d = { '1', '2', '3' }; // #error: Pointers cannot be initialized using an initializer list, instead you need to take the address of an array char* d = { '1', '2', '3' }; // #error: Pointers cannot be initialized using an initializer list, instead you need to take the address of an array
} }

View File

@@ -1,11 +1,11 @@
// #target: windows-x64 // #target: windows-x64
module test; module test;
const int[*] X = int[*] { 1, 2, 3 }; const int[?] X = int[?] { 1, 2, 3 };
int[*] y = int[*] { 1, 2, 3 }; int[?] y = int[?] { 1, 2, 3 };
fn void main() fn void main()
{ {
int x = $typeof(int[*] { 1, 2, 3}).len; int x = $typeof(int[?] { 1, 2, 3}).len;
int z = X.len; int z = X.len;
int w = y.len; int w = y.len;
} }

View File

@@ -1,4 +1,4 @@
fn void test() fn void test()
{ {
int[*] a = {}; // #error: Zero length int[?] a = {}; // #error: Zero length
} }

View File

@@ -4,41 +4,41 @@ import std::io;
macro @hello(...) macro @hello(...)
{ {
int[*] a = { 1, $vasplat, 3 }; int[?] a = { 1, $vasplat, 3 };
foreach (i, x : a) io::printfn("%d: %d", i, x); foreach (i, x : a) io::printfn("%d: %d", i, x);
} }
macro @hello1(...) macro @hello1(...)
{ {
int[*] a = { 1, $vasplat }; int[?] a = { 1, $vasplat };
foreach (i, x : a) io::printfn("x:%d: %d", i, x); foreach (i, x : a) io::printfn("x:%d: %d", i, x);
} }
macro @hello2(...) macro @hello2(...)
{ {
int[*] a = { $vasplat, 888 }; int[?] a = { $vasplat, 888 };
foreach (i, x : a) io::printfn("x:%d: %d", i, x); foreach (i, x : a) io::printfn("x:%d: %d", i, x);
} }
macro @hello3(...) macro @hello3(...)
{ {
int[*] a = { $vasplat }; int[?] a = { $vasplat };
foreach (i, x : a) io::printfn("x:%d: %d", i, x); foreach (i, x : a) io::printfn("x:%d: %d", i, x);
} }
macro @hello4(...) macro @hello4(...)
{ {
int[*] a = { 5, $vasplat[2..4], 77 }; int[?] a = { 5, $vasplat[2..4], 77 };
foreach (i, x : a) io::printfn("y:%d: %d", i, x); foreach (i, x : a) io::printfn("y:%d: %d", i, x);
} }
macro @hello5(...) macro @hello5(...)
{ {
int[*] a = { 5, $vasplat[2..], 77 }; int[?] a = { 5, $vasplat[2..], 77 };
foreach (i, x : a) io::printfn("y:%d: %d", i, x); foreach (i, x : a) io::printfn("y:%d: %d", i, x);
int[*] b = { 55, $vasplat[2..^2], 88 }; int[?] b = { 55, $vasplat[2..^2], 88 };
foreach (i, x : b) io::printfn("z:%d: %d", i, x); foreach (i, x : b) io::printfn("z:%d: %d", i, x);
int[*] c = { 55, $vasplat[0:^2], 88 }; int[?] c = { 55, $vasplat[0:^2], 88 };
foreach (i, x : c) io::printfn("zz:%d: %d", i, x); foreach (i, x : c) io::printfn("zz:%d: %d", i, x);
} }

View File

@@ -1,7 +1,7 @@
// #target: macos-x64 // #target: macos-x64
module test; module test;
const int[*] X = int[*] { 1, 2, 3 }; const int[?] X = int[?] { 1, 2, 3 };
int[*] y = int[*] { 1, 2, 3 }; int[?] y = int[?] { 1, 2, 3 };
fn int main() fn int main()
{ {

View File

@@ -3,6 +3,6 @@ import std;
fn void main() fn void main()
{ {
char[*] z = { 1, 2 }; char[?] z = { 1, 2 };
char[] y = z; // #error: Conversions from arrays or vectors char[] y = z; // #error: Conversions from arrays or vectors
} }

View File

@@ -68,7 +68,7 @@ fn void test10()
struct Abc struct Abc
{ {
int a; int a;
char[*] z; char[?] z;
} }
fn void test105() fn void test105()

View File

@@ -4,7 +4,7 @@ import std::io;
fn void main() fn void main()
{ {
int[*] z = { 1, 2, 3, 4, 5, 6, 7 }; int[?] z = { 1, 2, 3, 4, 5, 6, 7 };
int[6] y; int[6] y;
y[1..3] = z[3..5]; y[1..3] = z[3..5];
io::printfn("%s %s", y, z); io::printfn("%s %s", y, z);

View File

@@ -4,7 +4,7 @@ import std::io;
fn void main() fn void main()
{ {
int[<*>] z = { 1, 2, 3, 4, 5, 6, 7 }; int[<?>] z = { 1, 2, 3, 4, 5, 6, 7 };
int[<6>] y; int[<6>] y;
y[1..3] = z[3..5]; y[1..3] = z[3..5];
io::printfn("%s %s", y, z); io::printfn("%s %s", y, z);

View File

@@ -16,7 +16,7 @@ fn void test()
} }
fn int main() fn int main()
{ {
int[*] $x = { 1, 2, 3, 4 }; int[?] $x = { 1, 2, 3, 4 };
var $y = $x[1..3]; var $y = $x[1..3];
int[] y = { 1, 2 }; int[] y = { 1, 2 };
io::printn(y.ptr); io::printn(y.ptr);

View File

@@ -18,7 +18,7 @@ macro usz Foo.@operator_len(Foo* &foo) @operator(len)
fn void main() fn void main()
{ {
int[*] i = { 1, 3, 10 }; int[?] i = { 1, 3, 10 };
Foo x = { &i }; Foo x = { &i };
foreach FOO: (int f : x) { foreach FOO: (int f : x) {
printf("%d\n", f); printf("%d\n", f);

View File

@@ -17,7 +17,7 @@ macro usz Foo.@operator_len(Foo* &foo) @operator(len)
fn void main() fn void main()
{ {
int[*] i = { 1, 3, 10 }; int[?] i = { 1, 3, 10 };
Foo x = { &i }; Foo x = { &i };
foreach FOO: (int f : x) { foreach FOO: (int f : x) {
printf("%d\n", f); printf("%d\n", f);

View File

@@ -18,7 +18,7 @@ macro usz Foo.@operator_len(Foo* &foo) @operator(len)
fn void main() fn void main()
{ {
int[*] i = { 1, 3, 10 }; int[?] i = { 1, 3, 10 };
Foo x = { &i }; Foo x = { &i };
foreach_r FOO: (int f : x) { foreach_r FOO: (int f : x) {
printf("%d\n", f); printf("%d\n", f);

View File

@@ -17,7 +17,7 @@ macro usz Foo.@operator_len(Foo* &foo) @operator(len)
fn void main() fn void main()
{ {
int[*] i = { 1, 3, 10 }; int[?] i = { 1, 3, 10 };
Foo x = { &i }; Foo x = { &i };
foreach_r FOO: (int f : x) { foreach_r FOO: (int f : x) {
printf("%d\n", f); printf("%d\n", f);

View File

@@ -2,12 +2,12 @@
module foo; module foo;
char[2] g = "ab"; char[2] g = "ab";
char[*] h = "abc"; char[?] h = "abc";
fn int main() fn int main()
{ {
char[2] x = "ab"; char[2] x = "ab";
char[*] y = "abc"; char[?] y = "abc";
return 0; return 0;
} }

View File

@@ -3,7 +3,7 @@ module test;
struct Abc struct Abc
{ {
int x; int x;
int[*] y; int[?] y;
} }

View File

@@ -1,19 +1,19 @@
struct Foo struct Foo
{ {
int x; int x;
int[*] y; // #error: flexible array member must be the last element int[?] y; // #error: flexible array member must be the last element
int z; int z;
} }
struct Bar struct Bar
{ {
int[*] y; // #error: flexible array member cannot be the only element int[?] y; // #error: flexible array member cannot be the only element
} }
struct Baz struct Baz
{ {
int y; int y;
int[*] z; int[?] z;
} }
struct BazContainerOk struct BazContainerOk

View File

@@ -6,11 +6,11 @@ struct Abc
struct Foo struct Foo
{ {
int a; int a;
int[*] x; int[?] x;
} }
struct Foo2 struct Foo2
{ {
int a; int a;
int[*] x, y; // #error: must be the last element int[?] x, y; // #error: must be the last element
} }

View File

@@ -8,7 +8,7 @@ struct Bar
int y; int y;
} }
int ufe; int ufe;
int[*] z; int[?] z;
} }

View File

@@ -1,5 +1,5 @@
union Zee union Zee
{ {
int z; int z;
int[*] y; // #error: Flexible array members not allowed in unions. int[?] y; // #error: Flexible array members not allowed in unions.
} }

View File

@@ -1,4 +1,4 @@
union Foo union Foo
{ {
int[<*>] x; // #error: Inferred vector types can only int[<?>] x; // #error: Inferred vector types can only
} }

View File

@@ -4,10 +4,10 @@ fn void main()
{ {
int[<2>] x = { 4, 7 }; int[<2>] x = { 4, 7 };
int[2] y = x; int[2] y = x;
int[*] y1 = y; int[?] y1 = y;
int[*] y2 = x; int[?] y2 = x;
int[<*>] z = x; int[<?>] z = x;
int[<*>] w = y; int[<?>] w = y;
double[<2>] ww = x; double[<2>] ww = x;
short[<2>] www = y; // #error: Implicitly casting 'int[2]' to 'short[<2>]' short[<2>] www = y; // #error: Implicitly casting 'int[2]' to 'short[<2>]'
} }

View File

@@ -21,7 +21,7 @@ struct Test
int fa : 1..6; int fa : 1..6;
} }
Abc y; Abc y;
int[*] x; int[?] x;
} }
/* #expect: test.ll /* #expect: test.ll

View File

@@ -7,7 +7,7 @@ fn void assignable()
assert(!$assignable("12", int)); assert(!$assignable("12", int));
assert($assignable("12", String)); assert($assignable("12", String));
assert($assignable("12", char*)); assert($assignable("12", char*));
assert($assignable("12", char[*])); assert($assignable("12", char[?]));
assert($assignable("12", char[2])); assert($assignable("12", char[2]));
assert($assignable("12", char[3])); assert($assignable("12", char[3]));
} }

View File

@@ -30,6 +30,6 @@ fn void pointer_add_sub_diff()
assert(w == { -1, 2 }); assert(w == { -1, 2 });
int*[<2>] zz = y - (y - yy); int*[<2>] zz = y - (y - yy);
assert(zz[0] == &a[1] && zz[1] == &a[2]); assert(zz[0] == &a[1] && zz[1] == &a[2]);
int[*]*[<2>] g = int[2]*[<2>] { null, null }; int[?]*[<2>] g = int[2]*[<2>] { null, null };
int[*]*[<*>] g2 = int[2]*[<2>] { null, null }; int[?]*[<?>] g2 = int[2]*[<2>] { null, null };
} }

View File

@@ -4,10 +4,10 @@ fn void vector_array_inferred()
{ {
int[<2>] x = { 4, 7 }; int[<2>] x = { 4, 7 };
int[2] y = x; int[2] y = x;
int[*] y1 = y; int[?] y1 = y;
int[*] y2 = x; int[?] y2 = x;
int[<*>] z = x; int[<?>] z = x;
int[<*>] w = y; int[<?>] w = y;
double[<2>] ww = x; double[<2>] ww = x;
assert((int[<2>])y == int[<2>]{ 4, 7}); assert((int[<2>])y == int[<2>]{ 4, 7});
assert((int[<2>])y1 == int[<2>] { 4, 7 }); assert((int[<2>])y1 == int[<2>] { 4, 7 });

View File

@@ -3,7 +3,7 @@ import std::math;
fn void vector_method_reduce() @test fn void vector_method_reduce() @test
{ {
float[<3>] x = { 1, 2.0, 4.0 }; float[<3>] x = { 1, 2.0, 4.0 };
int[<*>] y = { -23, 1, 4 }; int[<?>] y = { -23, 1, 4 };
assert(y.sum() == -18); assert(y.sum() == -18);
assert(y.product() == -92); assert(y.product() == -92);
assert(y.max() == 4); assert(y.max() == 4);

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@ module std::core::bitorder @test;
fn void test_read() fn void test_read()
{ {
char[*] bytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; char[?] bytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
assert(bitorder::read(bytes, UShortBE) == 0x0102); assert(bitorder::read(bytes, UShortBE) == 0x0102);
assert(bitorder::read(bytes, UShortLE) == 0x0201); assert(bitorder::read(bytes, UShortLE) == 0x0201);
@@ -28,7 +28,7 @@ fn void test_read()
fn void test_write() fn void test_write()
{ {
char[*] bytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; char[?] bytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
char[8] buf; char[8] buf;
ushort x1 = bitorder::read(bytes, UShortBE); ushort x1 = bitorder::read(bytes, UShortBE);

View File

@@ -8,7 +8,7 @@ fn void rc_crypt() @test
char[200] x; char[200] x;
String text = "The quick brown fox jumps over the lazy dog."; String text = "The quick brown fox jumps over the lazy dog.";
rc.crypt(text, &x); rc.crypt(text, &x);
char[*] res = x'2ac2fecdd8fbb84638e3a4 char[?] res = x'2ac2fecdd8fbb84638e3a4
820eb205cc8e29c28b9d5d 820eb205cc8e29c28b9d5d
6b2ef974f311964971c90e 6b2ef974f311964971c90e
8b9ca16467ef2dc6fc3520'; 8b9ca16467ef2dc6fc3520';

View File

@@ -9,7 +9,7 @@ struct TestCase
char[] enc; char[] enc;
} }
TestCase[*] std_tests = { TestCase[?] std_tests = {
{ "", "" }, { "", "" },
{ "f", "MY======" }, { "f", "MY======" },
{ "fo", "MZXQ====" }, { "fo", "MZXQ====" },
@@ -19,7 +19,7 @@ TestCase[*] std_tests = {
{ "foobar", "MZXW6YTBOI======" }, { "foobar", "MZXW6YTBOI======" },
}; };
TestCase[*] hex_tests = { TestCase[?] hex_tests = {
{ "", "" }, { "", "" },
{ "f", "CO======" }, { "f", "CO======" },
{ "fo", "CPNG====" }, { "fo", "CPNG====" },

View File

@@ -11,7 +11,7 @@ struct EncodeTest
UrlEncodingMode mode; UrlEncodingMode mode;
} }
EncodeTest[*] decode_with_error_tests @local = { EncodeTest[?] decode_with_error_tests @local = {
{ {
"", "",
"", "",
@@ -111,7 +111,7 @@ fn void test_decoding_with_error()
}; };
} }
EncodeTest[*] encode_tests @local = { EncodeTest[?] encode_tests @local = {
{ {
"", "",
"", "",
@@ -205,7 +205,7 @@ struct ShouldEncodeTest
bool escape; bool escape;
} }
ShouldEncodeTest[*] should_encode_tests = { ShouldEncodeTest[?] should_encode_tests = {
{'a', UrlEncodingMode.PATH, false}, {'a', UrlEncodingMode.PATH, false},
{'a', UrlEncodingMode.USERPASS, false}, {'a', UrlEncodingMode.USERPASS, false},
{'a', UrlEncodingMode.QUERY, false}, {'a', UrlEncodingMode.QUERY, false},

View File

@@ -56,7 +56,7 @@ fn void insertionsort_with_value()
fn void insertionsort_with_array() fn void insertionsort_with_array()
{ {
int[*] a = { 4, 8, 100, 1, 2 }; int[?] a = { 4, 8, 100, 1, 2 };
sort::insertionsort(&a); sort::insertionsort(&a);
assert(a == { 1, 2, 4, 8, 100 }); assert(a == { 1, 2, 4, 8, 100 });
} }

View File

@@ -39,7 +39,7 @@ fn void quicksort_with_ref()
fn void quicksort_with_array() fn void quicksort_with_array()
{ {
int[*] a = { 4, 8, 100, 1, 2 }; int[?] a = { 4, 8, 100, 1, 2 };
sort::quicksort(&a); sort::quicksort(&a);
assert(a == { 1, 2, 4, 8, 100 }); assert(a == { 1, 2, 4, 8, 100 });
} }

View File

@@ -7,7 +7,7 @@ def FormatTestSpec = Triple(<DateTime, DateTimeFormat, String>);
fn void test_with_tz() fn void test_with_tz()
{ {
FormatTzTestSpec[*] tests = { FormatTzTestSpec[?] tests = {
{ datetime::from_date(1970, Month.JANUARY, 1, 0, 0, 0).with_gmt_offset(0), RFC1123, "Thu, 01 Jan 1970 00:00:00 GMT" }, { datetime::from_date(1970, Month.JANUARY, 1, 0, 0, 0).with_gmt_offset(0), RFC1123, "Thu, 01 Jan 1970 00:00:00 GMT" },
{ datetime::from_date(1994, Month.from_ordinal(10), 6, 8, 49, 37).with_gmt_offset(0), RFC1123, "Sun, 06 Nov 1994 08:49:37 GMT" }, { datetime::from_date(1994, Month.from_ordinal(10), 6, 8, 49, 37).with_gmt_offset(0), RFC1123, "Sun, 06 Nov 1994 08:49:37 GMT" },
{ datetime::from_date(2020, Month.JANUARY, 1, 0, 0, 0).with_gmt_offset(0), RFC1123, "Wed, 01 Jan 2020 00:00:00 GMT" }, { datetime::from_date(2020, Month.JANUARY, 1, 0, 0, 0).with_gmt_offset(0), RFC1123, "Wed, 01 Jan 2020 00:00:00 GMT" },
@@ -34,7 +34,7 @@ fn void test_with_tz()
fn void test_without_tz() fn void test_without_tz()
{ {
FormatTestSpec[*] tests = { FormatTestSpec[?] tests = {
{ datetime::from_date(2006, Month.JANUARY, 2, 15, 4, 05), ANSIC, "Mon Jan 2 15:04:05 2006" }, { datetime::from_date(2006, Month.JANUARY, 2, 15, 4, 05), ANSIC, "Mon Jan 2 15:04:05 2006" },
{ datetime::from_date(2006, Month.JANUARY, 2, 15, 4, 05), DATETIME, "2006-01-02 15:04:05" }, { datetime::from_date(2006, Month.JANUARY, 2, 15, 4, 05), DATETIME, "2006-01-02 15:04:05" },
{ datetime::from_date(2006, Month.JANUARY, 2, 15, 4, 05), DATEONLY, "2006-01-02" }, { datetime::from_date(2006, Month.JANUARY, 2, 15, 4, 05), DATEONLY, "2006-01-02" },