mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Order of attribute declaration is changed for `alias`. - Added `LANGUAGE_DEV_VERSION` env constant. - Rename `anyfault` -> `fault`. - Changed `fault` -> `faultdef`. - Added `attrdef` instead of `alias` for attribute aliases.
154 lines
4.8 KiB
Plaintext
154 lines
4.8 KiB
Plaintext
module std::math::random;
|
|
|
|
// Move ODD_PHI into a shared module
|
|
const ODD_PHI128 @local = 0x9e3779b97f4a7c15f39cc0605cedc835;
|
|
const ODD_PHI64 @local = 0x9e3779b97f4a7c15;
|
|
const ODD_PHI32 @local = 0x9e3779b9;
|
|
const ODD_PHI16 @local = 0x9e37;
|
|
const ODD_PHI8 @local = 0x9f;
|
|
|
|
|
|
// Sfc128
|
|
|
|
typedef Sfc128Random (Random) = uint128[4];
|
|
|
|
fn void Sfc128Random.set_seed(&self, char[] input) @dynamic
|
|
{
|
|
*self = (Sfc128Random)random::make_seed(uint128[4], input);
|
|
}
|
|
|
|
fn uint128 Sfc128Random.next_int128(&self) @dynamic // TODO: Find good constant
|
|
{
|
|
uint128* s = (uint128[4]*)self;
|
|
uint128 result = s[0] + s[1] + s[3];
|
|
s[0] = s[1] ^ s[1] >> 11;
|
|
s[1] = s[2] + s[2] << 3;
|
|
s[2] = s[2].rotr(40) + result;
|
|
s[3] += ODD_PHI128;
|
|
return result;
|
|
}
|
|
|
|
<*
|
|
@require bytes.len > 0
|
|
*>
|
|
fn void Sfc128Random.next_bytes(&self, char[] bytes) @dynamic => @random_value_to_bytes(self.next_int128, bytes);
|
|
fn ulong Sfc128Random.next_long(&self) @dynamic => (uint)self.next_int128();
|
|
fn uint Sfc128Random.next_int(&self) @dynamic => (uint)self.next_int128();
|
|
fn ushort Sfc128Random.next_short(&self) @dynamic => (ushort)self.next_int128();
|
|
fn char Sfc128Random.next_byte(&self) @dynamic => (char)self.next_int128();
|
|
|
|
|
|
// -------------------------------- Sfc64 --------------------------------
|
|
|
|
typedef Sfc64Random (Random) = ulong[4];
|
|
|
|
fn void Sfc64Random.set_seed(&self, char[] input) @dynamic
|
|
{
|
|
*self = (Sfc64Random)random::make_seed(ulong[4], input);
|
|
}
|
|
|
|
fn ulong Sfc64Random.next_long(&self) @dynamic
|
|
{
|
|
ulong* s = (ulong[4]*)self;
|
|
ulong result = s[0] + s[1] + s[3];
|
|
s[0] = s[1] ^ s[1] >> 11;
|
|
s[1] = s[2] + s[2] << 3;
|
|
s[2] = s[2].rotr(40) + result;
|
|
s[3] += ODD_PHI64;
|
|
return result;
|
|
}
|
|
|
|
<*
|
|
@require bytes.len > 0
|
|
*>
|
|
fn void Sfc64Random.next_bytes(&self, char[] bytes) @dynamic => @random_value_to_bytes(self.next_long, bytes);
|
|
fn uint128 Sfc64Random.next_int128(&self) @dynamic => @long_to_int128(self.next_long());
|
|
fn uint Sfc64Random.next_int(&self) @dynamic => (uint)self.next_long();
|
|
fn ushort Sfc64Random.next_short(&self) @dynamic => (ushort)self.next_long();
|
|
fn char Sfc64Random.next_byte(&self) @dynamic => (char)self.next_long();
|
|
|
|
// -------------------------------- Sfc32 --------------------------------
|
|
|
|
typedef Sfc32Random (Random) = uint[4];
|
|
|
|
fn void Sfc32Random.set_seed(&self, char[] input) @dynamic
|
|
{
|
|
*self = (Sfc32Random)random::make_seed(uint[4], input);
|
|
}
|
|
|
|
fn uint Sfc32Random.next_int(&sfc) @dynamic
|
|
{
|
|
uint* s = (uint[4]*)sfc;
|
|
uint result = s[0] + s[1] + s[3];
|
|
s[0] = s[1] ^ s[1] >> 9;
|
|
s[1] = s[2] + s[2] << 3;
|
|
s[2] = s[2].rotr(11) + result;
|
|
s[3] += ODD_PHI32;
|
|
return result;
|
|
}
|
|
|
|
<*
|
|
@require bytes.len > 0
|
|
*>
|
|
fn void Sfc32Random.next_bytes(&self, char[] bytes) @dynamic => @random_value_to_bytes(self.next_int, bytes);
|
|
fn uint128 Sfc32Random.next_int128(&self) @dynamic => @long_to_int128(self.next_long());
|
|
fn ulong Sfc32Random.next_long(&self) @dynamic => @int_to_long(self.next_int());
|
|
fn ushort Sfc32Random.next_short(&self) @dynamic => (ushort)self.next_int();
|
|
fn char Sfc32Random.next_byte(&self) @dynamic => (char)self.next_int();
|
|
|
|
// -------------------------------- Sfc16 --------------------------------
|
|
|
|
typedef Sfc16Random (Random) = ushort[4];
|
|
|
|
fn void Sfc16Random.set_seed(&self, char[] input) @dynamic
|
|
{
|
|
*self = (Sfc16Random)random::make_seed(ushort[4], input);
|
|
}
|
|
|
|
|
|
fn ushort Sfc16Random.next_short(&seed) @dynamic
|
|
{
|
|
ushort* s = (ushort[4]*)seed;
|
|
ushort result = s[0] + s[1] + s[3];
|
|
s[0] = s[1] ^ s[1] >> 2;
|
|
s[1] = s[2] + s[2] << 3;
|
|
s[2] = s[2].rotr(12) + result;
|
|
s[3] += ODD_PHI16;
|
|
return result;
|
|
}
|
|
|
|
<*
|
|
@require bytes.len > 0
|
|
*>
|
|
fn void Sfc16Random.next_bytes(&self, char[] bytes) @dynamic => @random_value_to_bytes(self.next_short, bytes);
|
|
fn uint128 Sfc16Random.next_int128(&self) @dynamic => @long_to_int128(self.next_long());
|
|
fn ulong Sfc16Random.next_long(&self) @dynamic => @int_to_long(self.next_int());
|
|
fn uint Sfc16Random.next_int(&self) @dynamic => @short_to_int(self.next_short());
|
|
fn char Sfc16Random.next_byte(&self) @dynamic => (char)self.next_short();
|
|
|
|
// -------------------------------- Sfc8 --------------------------------
|
|
|
|
|
|
typedef Sfc8Random (Random) = char[4];
|
|
|
|
fn void Sfc8Random.set_seed(&self, char[] input) @dynamic
|
|
{
|
|
*self = (Sfc8Random)random::make_seed(char[4], input);
|
|
}
|
|
|
|
fn char Sfc8Random.next_byte(&self) @dynamic // TODO: Find better constants
|
|
{
|
|
char* s = (char[4]*)self;
|
|
char result = s[0] + s[1] + s[3];
|
|
s[0] = s[1] ^ s[1] >> 1;
|
|
s[1] = s[2] + s[2] << 2;
|
|
s[2] = s[2].rotr(3) + result;
|
|
s[3] += ODD_PHI8;
|
|
return result;
|
|
}
|
|
|
|
fn void Sfc8Random.next_bytes(&self, char[] bytes) @dynamic => @random_value_to_bytes(self.next_byte, bytes);
|
|
fn uint128 Sfc8Random.next_int128(&self) @dynamic => @long_to_int128(self.next_long());
|
|
fn ulong Sfc8Random.next_long(&self) @dynamic => @int_to_long(self.next_int());
|
|
fn uint Sfc8Random.next_int(&self) @dynamic => @short_to_int(self.next_short());
|
|
fn ushort Sfc8Random.next_short(&self) @dynamic => @char_to_short(self.next_byte()); |