mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Deprecate :; in $if etc.
This commit is contained in:
@@ -8,137 +8,137 @@
|
||||
module std::collections::enumset<Enum>;
|
||||
|
||||
|
||||
$if (Enum.elements > 128):
|
||||
$if (Enum.elements > 128)
|
||||
typedef EnumSetType @private = char[(Enum.elements + 7) / 8];
|
||||
const IS_CHAR_ARRAY = true;
|
||||
$elif (Enum.elements > 64):
|
||||
$elif (Enum.elements > 64)
|
||||
typedef EnumSetType @private = uint128;
|
||||
const IS_CHAR_ARRAY = false;
|
||||
$elif (Enum.elements > 32 || $$C_INT_SIZE > 32):
|
||||
$elif (Enum.elements > 32 || $$C_INT_SIZE > 32)
|
||||
typedef EnumSetType @private = ulong;
|
||||
const IS_CHAR_ARRAY = false;
|
||||
$elif (Enum.elements > 16 || $$C_INT_SIZE > 16):
|
||||
$elif (Enum.elements > 16 || $$C_INT_SIZE > 16)
|
||||
typedef EnumSetType @private = uint;
|
||||
const IS_CHAR_ARRAY = false;
|
||||
$elif (Enum.elements > 8 || $$C_INT_SIZE > 8):
|
||||
$elif (Enum.elements > 8 || $$C_INT_SIZE > 8)
|
||||
typedef EnumSetType @private = ushort;
|
||||
const IS_CHAR_ARRAY = false;
|
||||
$else:
|
||||
$else
|
||||
typedef EnumSetType @private = char;
|
||||
const IS_CHAR_ARRAY = false;
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
typedef EnumSet = distinct EnumSetType;
|
||||
|
||||
fn void EnumSet.add(EnumSet* this, Enum v)
|
||||
{
|
||||
$if (IS_CHAR_ARRAY):
|
||||
$if (IS_CHAR_ARRAY)
|
||||
(*this)[v / 8] |= (char)(1u << (v % 8));
|
||||
$else:
|
||||
$else
|
||||
*this = (EnumSet)((EnumSetType)*this | 1u << (EnumSetType)v);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn void EnumSet.clear(EnumSet* this)
|
||||
{
|
||||
$if (IS_CHAR_ARRAY):
|
||||
$if (IS_CHAR_ARRAY)
|
||||
*this = {};
|
||||
$else:
|
||||
$else
|
||||
*this = 0;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn bool EnumSet.remove(EnumSet* this, Enum v)
|
||||
{
|
||||
$if (IS_CHAR_ARRAY):
|
||||
$if (IS_CHAR_ARRAY)
|
||||
if (!this.has(v) @inline) return false;
|
||||
(*this)[v / 8] &= (char)~(1 << (v % 8));
|
||||
return true;
|
||||
$else:
|
||||
$else
|
||||
EnumSetType old = (EnumSetType)*this;
|
||||
EnumSetType new = old & ~(1u << (EnumSetType)v);
|
||||
*this = (EnumSet)new;
|
||||
return old != new;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn bool EnumSet.has(EnumSet* this, Enum v)
|
||||
{
|
||||
$if (IS_CHAR_ARRAY):
|
||||
$if (IS_CHAR_ARRAY)
|
||||
return (bool)(((*this)[v / 8] << (v % 8)) & 0x01);
|
||||
$else:
|
||||
$else
|
||||
return ((EnumSetType)*this & (1u << (EnumSetType)v)) != 0;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn void EnumSet.add_all(EnumSet* this, EnumSet s)
|
||||
{
|
||||
$if (IS_CHAR_ARRAY):
|
||||
$if (IS_CHAR_ARRAY)
|
||||
foreach (i, c : s) (*this)[i] |= c;
|
||||
$else:
|
||||
$else
|
||||
*this = (EnumSet)((EnumSetType)*this | (EnumSetType)s);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn void EnumSet.retain_all(EnumSet* this, EnumSet s)
|
||||
{
|
||||
$if (IS_CHAR_ARRAY):
|
||||
$if (IS_CHAR_ARRAY)
|
||||
foreach (i, c : s) (*this)[i] &= c;
|
||||
$else:
|
||||
$else
|
||||
*this = (EnumSet)((EnumSetType)*this & (EnumSetType)s);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn void EnumSet.remove_all(EnumSet* this, EnumSet s)
|
||||
{
|
||||
$if (IS_CHAR_ARRAY):
|
||||
$if (IS_CHAR_ARRAY)
|
||||
foreach (i, c : s) (*this)[i] &= ~c;
|
||||
$else:
|
||||
$else
|
||||
*this = (EnumSet)((EnumSetType)*this & ~(EnumSetType)s);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn EnumSet EnumSet.and_of(EnumSet* this, EnumSet s)
|
||||
{
|
||||
$if (IS_CHAR_ARRAY):
|
||||
$if (IS_CHAR_ARRAY)
|
||||
EnumSet copy = *this;
|
||||
copy.retain_all(s);
|
||||
return copy;
|
||||
$else:
|
||||
$else
|
||||
return (EnumSet)((EnumSetType)*this & (EnumSetType)s);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn EnumSet EnumSet.or_of(EnumSet* this, EnumSet s)
|
||||
{
|
||||
$if (IS_CHAR_ARRAY):
|
||||
$if (IS_CHAR_ARRAY)
|
||||
EnumSet copy = *this;
|
||||
copy.add_all(s);
|
||||
return copy;
|
||||
$else:
|
||||
$else
|
||||
return (EnumSet)((EnumSetType)*this | (EnumSetType)s);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
|
||||
fn EnumSet EnumSet.diff_of(EnumSet* this, EnumSet s)
|
||||
{
|
||||
$if (IS_CHAR_ARRAY):
|
||||
$if (IS_CHAR_ARRAY)
|
||||
EnumSet copy = *this;
|
||||
copy.remove_all(s);
|
||||
return copy;
|
||||
$else:
|
||||
$else
|
||||
return (EnumSet)((EnumSetType)*this & ~(EnumSetType)s);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn EnumSet EnumSet.xor_of(EnumSet* this, EnumSet s)
|
||||
{
|
||||
$if (IS_CHAR_ARRAY):
|
||||
$if (IS_CHAR_ARRAY)
|
||||
EnumSet copy = *this;
|
||||
foreach (i, c : s) copy[i] ^= c;
|
||||
return copy;
|
||||
$else:
|
||||
$else
|
||||
return (EnumSet)((EnumSetType)*this ^ (EnumSetType)s);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
@@ -205,7 +205,7 @@ fn Value[] HashMap.value_list(HashMap* map, Allocator* using = mem::heap())
|
||||
return list;
|
||||
}
|
||||
|
||||
$if (types::is_equatable(Value)):
|
||||
$if (types::is_equatable(Value))
|
||||
fn bool HashMap.has_value(HashMap* map, Value v)
|
||||
{
|
||||
if (!map.count) return false;
|
||||
@@ -219,7 +219,7 @@ fn bool HashMap.has_value(HashMap* map, Value v)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
// --- private methods
|
||||
|
||||
|
||||
@@ -212,24 +212,24 @@ fn void Object.set_object(Object* o, String key, Object* new_object) @private
|
||||
macro Object* object_from_value(value) @private
|
||||
{
|
||||
var $Type = $typeof(value);
|
||||
$if (types::is_int($Type)):
|
||||
$if (types::is_int($Type))
|
||||
return new_int(value);
|
||||
$elif (types::is_float($Type)):
|
||||
$elif (types::is_float($Type))
|
||||
return new_float(value);
|
||||
$elif ($Type.typeid == String.typeid):
|
||||
$elif ($Type.typeid == String.typeid)
|
||||
return new_string(value);
|
||||
$elif ($Type.typeid == bool.typeid):
|
||||
$elif ($Type.typeid == bool.typeid)
|
||||
return new_bool(value);
|
||||
$elif ($Type.typeid == Object*.typeid):
|
||||
$elif ($Type.typeid == Object*.typeid)
|
||||
return value;
|
||||
$elif ($Type.typeid == void*.typeid):
|
||||
$elif ($Type.typeid == void*.typeid)
|
||||
assert(value == null);
|
||||
return &NULL_OBJECT;
|
||||
$elif ($checks(String s = value)):
|
||||
$elif ($checks(String s = value))
|
||||
return new_string(value);
|
||||
$else:
|
||||
$else
|
||||
$assert(false, "Unsupported object type.");
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro Object* Object.set(Object* o, String key, value)
|
||||
@@ -312,11 +312,11 @@ macro get_integer_value(Object* value, $Type)
|
||||
}
|
||||
if (value.is_string())
|
||||
{
|
||||
$if ($Type.kindof == TypeKind.SIGNED_INT):
|
||||
$if ($Type.kindof == TypeKind.SIGNED_INT)
|
||||
return ($Type)str::to_int128(value.s);
|
||||
$else:
|
||||
$else
|
||||
return ($Type)str::to_uint128(value.s);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
if (!value.is_int()) return NumberConversion.MALFORMED_INTEGER!;
|
||||
return ($Type)value.i;
|
||||
|
||||
@@ -37,11 +37,11 @@ struct AlignedBlock
|
||||
macro void*! @aligned_alloc(#alloc_fn, usz bytes, usz alignment, usz offset)
|
||||
{
|
||||
usz header = mem::aligned_offset(AlignedBlock.sizeof + offset, alignment) - offset;
|
||||
$if ($checks(#alloc_fn(bytes)?)):
|
||||
$if ($checks(#alloc_fn(bytes)?))
|
||||
void* data = #alloc_fn(header + bytes)?;
|
||||
$else:
|
||||
$else
|
||||
void* data = #alloc_fn(header + bytes);
|
||||
$endif;
|
||||
$endif
|
||||
void* mem = mem::aligned_pointer(data + header + offset, alignment) - offset;
|
||||
assert(mem > data);
|
||||
AlignedBlock* desc = (AlignedBlock*)mem - 1;
|
||||
@@ -56,11 +56,11 @@ macro void*! @aligned_alloc(#alloc_fn, usz bytes, usz alignment, usz offset)
|
||||
macro void*! @aligned_calloc(#calloc_fn, usz bytes, usz alignment, usz offset)
|
||||
{
|
||||
usz header = mem::aligned_offset(AlignedBlock.sizeof + offset, alignment) - offset;
|
||||
$if ($checks(#calloc_fn(bytes)?)):
|
||||
$if ($checks(#calloc_fn(bytes)?))
|
||||
void* data = #calloc_fn(header + bytes)?;
|
||||
$else:
|
||||
$else
|
||||
void* data = #calloc_fn(header + bytes);
|
||||
$endif;
|
||||
$endif
|
||||
void* mem = mem::aligned_pointer(data + header + offset, alignment) - offset;
|
||||
AlignedBlock* desc = (AlignedBlock*)mem - 1;
|
||||
assert(mem > data);
|
||||
@@ -78,22 +78,22 @@ macro void*! @aligned_realloc(#calloc_fn, #free_fn, void* old_pointer, usz bytes
|
||||
void* data_start = desc.start;
|
||||
void* new_data = @aligned_calloc(#calloc_fn, bytes, alignment, offset)?;
|
||||
mem::copy(new_data, old_pointer, desc.len > bytes ? desc.len : bytes, mem::DEFAULT_MEM_ALIGNMENT, mem::DEFAULT_MEM_ALIGNMENT);
|
||||
$if ($checks(#free_fn(data_start)?)):
|
||||
$if ($checks(#free_fn(data_start)?))
|
||||
#free_fn(data_start)?;
|
||||
$else:
|
||||
$else
|
||||
#free_fn(data_start);
|
||||
$endif;
|
||||
$endif
|
||||
return new_data;
|
||||
}
|
||||
|
||||
macro void! @aligned_free(#free_fn, void* old_pointer)
|
||||
{
|
||||
AlignedBlock* desc = (AlignedBlock*)old_pointer - 1;
|
||||
$if ($checks(#free_fn(desc.start)?)):
|
||||
$if ($checks(#free_fn(desc.start)?))
|
||||
#free_fn(desc.start)?;
|
||||
$else:
|
||||
$else
|
||||
#free_fn(desc.start);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn void*! libc_allocator_fn(Allocator* unused, usz bytes, usz alignment, usz offset, void* old_pointer, AllocationKind kind) @inline
|
||||
|
||||
@@ -64,7 +64,7 @@ struct CallstackElement
|
||||
fn void default_panic(String message, String file, String function, uint line)
|
||||
{
|
||||
CallstackElement* stack = $$stacktrace();
|
||||
$if ($defined(libc::stderr) && $defined(libc::fprintf)):
|
||||
$if ($defined(libc::stderr) && $defined(libc::fprintf))
|
||||
|
||||
if (stack) stack = stack.prev;
|
||||
if (stack)
|
||||
@@ -84,7 +84,7 @@ fn void default_panic(String message, String file, String function, uint line)
|
||||
stack = stack.prev;
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
$$trap();
|
||||
}
|
||||
|
||||
@@ -122,20 +122,20 @@ macro enum_by_name($Type, String enum_name) @builtin
|
||||
|
||||
macro bool @likely(bool value, $probability = 1.0) @builtin
|
||||
{
|
||||
$if ($probability == 1.0):
|
||||
$if ($probability == 1.0)
|
||||
return $$expect(value, true);
|
||||
$else:
|
||||
$else
|
||||
return $$expect_with_probability(value, true, $probability);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro bool @unlikely(bool value, $probability = 1.0) @builtin
|
||||
{
|
||||
$if ($probability == 1.0):
|
||||
$if ($probability == 1.0)
|
||||
return $$expect(value, false);
|
||||
$else:
|
||||
$else
|
||||
return $$expect_with_probability(value, false, $probability);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,11 +144,11 @@ macro bool @unlikely(bool value, $probability = 1.0) @builtin
|
||||
**/
|
||||
macro @expect(value, expected, $probability = 1.0) @builtin
|
||||
{
|
||||
$if ($probability == 1.0):
|
||||
$if ($probability == 1.0)
|
||||
return $$expect(value, ($typeof(value))expected);
|
||||
$else:
|
||||
$else
|
||||
return $$expect_with_probability(value, expected, $probability);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,13 +8,13 @@ module std::core::builtin;
|
||||
**/
|
||||
macro less(a, b) @builtin
|
||||
{
|
||||
$if ($defined(a.less)):
|
||||
$if ($defined(a.less))
|
||||
return a.less(b);
|
||||
$elif ($defined(a.compare_to)):
|
||||
$elif ($defined(a.compare_to))
|
||||
return a.compare_to(b) < 0;
|
||||
$else:
|
||||
$else
|
||||
return a < b;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -22,13 +22,13 @@ macro less(a, b) @builtin
|
||||
**/
|
||||
macro less_eq(a, b) @builtin
|
||||
{
|
||||
$if ($defined(a.less)):
|
||||
$if ($defined(a.less))
|
||||
return !b.less(a);
|
||||
$elif ($defined(a.compare_to)):
|
||||
$elif ($defined(a.compare_to))
|
||||
return a.compare_to(b) <= 0;
|
||||
$else:
|
||||
$else
|
||||
return a <= b;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,13 +36,13 @@ macro less_eq(a, b) @builtin
|
||||
**/
|
||||
macro greater(a, b) @builtin
|
||||
{
|
||||
$if ($defined(a.less)):
|
||||
$if ($defined(a.less))
|
||||
return b.less(a);
|
||||
$elif ($defined(a.compare_to)):
|
||||
$elif ($defined(a.compare_to))
|
||||
return a.compare_to(b) > 0;
|
||||
$else:
|
||||
$else
|
||||
return a > b;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,13 +50,13 @@ macro greater(a, b) @builtin
|
||||
**/
|
||||
macro greater_eq(a, b) @builtin
|
||||
{
|
||||
$if ($defined(a.less)):
|
||||
$if ($defined(a.less))
|
||||
return !a.less(b);
|
||||
$elif ($defined(a.compare_to)):
|
||||
$elif ($defined(a.compare_to))
|
||||
return a.compare_to(b) >= 0;
|
||||
$else:
|
||||
$else
|
||||
return a >= b;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,46 +64,46 @@ macro greater_eq(a, b) @builtin
|
||||
**/
|
||||
macro bool equals(a, b) @builtin
|
||||
{
|
||||
$if ($defined(a.equals)):
|
||||
$if ($defined(a.equals))
|
||||
return a.equals(b);
|
||||
$elif ($defined(a.compare_to)):
|
||||
$elif ($defined(a.compare_to))
|
||||
return a.compare_to(b) == 0;
|
||||
$elif ($defined(a.less)):
|
||||
$elif ($defined(a.less))
|
||||
return !a.less(b) && !b.less(a);
|
||||
$else:
|
||||
$else
|
||||
return a == b;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro min(x, ...) @builtin
|
||||
{
|
||||
$if ($vacount == 1):
|
||||
$if ($vacount == 1)
|
||||
return less(x, $vaarg(0)) ? x : $vaarg(0);
|
||||
$else:
|
||||
$else
|
||||
var result = x;
|
||||
$for (var $i = 0; $i < $vacount; $i++):
|
||||
$for (var $i = 0; $i < $vacount; $i++)
|
||||
if (less($vaarg($i), result))
|
||||
{
|
||||
result = $vaarg($i);
|
||||
}
|
||||
$endfor;
|
||||
$endfor
|
||||
return result;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro max(x, ...) @builtin
|
||||
{
|
||||
$if ($vacount == 1):
|
||||
$if ($vacount == 1)
|
||||
return greater(x, $vaarg(0)) ? x : $vaarg(0);
|
||||
$else:
|
||||
$else
|
||||
var result = x;
|
||||
$for (var $i = 0; $i < $vacount; $i++):
|
||||
$for (var $i = 0; $i < $vacount; $i++)
|
||||
if (greater($vaarg($i), result))
|
||||
{
|
||||
result = $vaarg($i);
|
||||
}
|
||||
$endfor;
|
||||
$endfor
|
||||
return result;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ $assert (C_SHORT_SIZE <= C_INT_SIZE);
|
||||
$assert (C_INT_SIZE <= C_LONG_SIZE);
|
||||
$assert (C_LONG_SIZE <= C_LONG_LONG_SIZE);
|
||||
|
||||
$switch ($$C_INT_SIZE):
|
||||
$switch ($$C_INT_SIZE)
|
||||
$case 64:
|
||||
typedef CInt = long;
|
||||
typedef CUInt = ulong;
|
||||
@@ -28,9 +28,9 @@ $case 16:
|
||||
typedef CUInt = ushort;
|
||||
$default:
|
||||
$assert(false, "Invalid C int size");
|
||||
$endswitch;
|
||||
$endswitch
|
||||
|
||||
$switch ($$C_LONG_SIZE):
|
||||
$switch ($$C_LONG_SIZE)
|
||||
$case 64:
|
||||
typedef CLong = long;
|
||||
typedef CULong = ulong;
|
||||
@@ -42,9 +42,9 @@ $case 16:
|
||||
typedef CULong = ushort;
|
||||
$default:
|
||||
$assert(false, "Invalid C long size");
|
||||
$endswitch;
|
||||
$endswitch
|
||||
|
||||
$switch ($$C_SHORT_SIZE):
|
||||
$switch ($$C_SHORT_SIZE)
|
||||
$case 32:
|
||||
typedef CShort = int;
|
||||
typedef CUShort = uint;
|
||||
@@ -56,9 +56,9 @@ $case 8:
|
||||
typedef CUShort = char;
|
||||
$default:
|
||||
$assert(false, "Invalid C short size");
|
||||
$endswitch;
|
||||
$endswitch
|
||||
|
||||
$switch ($$C_LONG_LONG_SIZE):
|
||||
$switch ($$C_LONG_LONG_SIZE)
|
||||
$case 128:
|
||||
typedef CLongLong = int128;
|
||||
typedef CULongLong = uint128;
|
||||
@@ -73,15 +73,15 @@ $case 16:
|
||||
typedef CULongLong = ushort;
|
||||
$default:
|
||||
$assert(false, "Invalid C long long size");
|
||||
$endswitch;
|
||||
$endswitch
|
||||
|
||||
|
||||
|
||||
typedef CSChar = ichar;
|
||||
typedef CUChar = char;
|
||||
|
||||
$if ($$C_CHAR_IS_SIGNED):
|
||||
$if ($$C_CHAR_IS_SIGNED)
|
||||
typedef CChar = ichar;
|
||||
$else:
|
||||
$else
|
||||
typedef CChar = char;
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
@@ -291,7 +291,7 @@ fn void DString.append_char(DString* str, char c)
|
||||
macro void DString.append(DString* str, value)
|
||||
{
|
||||
var $Type = $typeof(value);
|
||||
$switch ($Type):
|
||||
$switch ($Type)
|
||||
$case char:
|
||||
$case ichar:
|
||||
str.append_char(value);
|
||||
@@ -302,14 +302,14 @@ macro void DString.append(DString* str, value)
|
||||
$case Char32:
|
||||
str.append_char32(value);
|
||||
$default:
|
||||
$if (@convertible(value, Char32)):
|
||||
$if (@convertible(value, Char32))
|
||||
str.append_char32(value);
|
||||
$elif (@convertible(value, String)):
|
||||
$elif (@convertible(value, String))
|
||||
str.append_chars(value);
|
||||
$else:
|
||||
$else
|
||||
$assert(false, "Unsupported type for append – use printf instead.");
|
||||
$endif;
|
||||
$endswitch;
|
||||
$endif
|
||||
$endswitch
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ macro bool os_is_win32()
|
||||
|
||||
macro bool os_is_darwin()
|
||||
{
|
||||
$switch (OS_TYPE):
|
||||
$switch (OS_TYPE)
|
||||
$case IOS:
|
||||
$case MACOSX:
|
||||
$case TVOS:
|
||||
@@ -143,12 +143,12 @@ macro bool os_is_darwin()
|
||||
return true;
|
||||
$default:
|
||||
return false;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
macro bool os_is_posix()
|
||||
{
|
||||
$switch (OS_TYPE):
|
||||
$switch (OS_TYPE)
|
||||
$case IOS:
|
||||
$case MACOSX:
|
||||
$case NETBSD:
|
||||
@@ -167,7 +167,7 @@ macro bool os_is_posix()
|
||||
$default:
|
||||
$echo("Assuming non-Posix environment");
|
||||
return false;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
|
||||
@@ -177,15 +177,15 @@ macro bool os_is_posix()
|
||||
**/
|
||||
fn String! get_var(String name)
|
||||
{
|
||||
$if (COMPILER_LIBC_AVAILABLE && OS_TYPE != OsType.WIN32):
|
||||
$if (COMPILER_LIBC_AVAILABLE && OS_TYPE != OsType.WIN32)
|
||||
@pool()
|
||||
{
|
||||
ZString val = libc::getenv(name.zstr_tcopy());
|
||||
return val ? val.as_str() : SearchResult.MISSING!;
|
||||
};
|
||||
$else:
|
||||
$else
|
||||
return "";
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ $endif;
|
||||
**/
|
||||
fn void set_var(String name, String value, bool overwrite = true)
|
||||
{
|
||||
$if (COMPILER_LIBC_AVAILABLE && OS_TYPE != OsType.WIN32):
|
||||
$if (COMPILER_LIBC_AVAILABLE && OS_TYPE != OsType.WIN32)
|
||||
@pool()
|
||||
{
|
||||
if (libc::setenv(name.zstr_tcopy(), value.zstr_copy(), (int)overwrite))
|
||||
@@ -204,7 +204,7 @@ $if (COMPILER_LIBC_AVAILABLE && OS_TYPE != OsType.WIN32):
|
||||
unreachable();
|
||||
}
|
||||
};
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,7 +213,7 @@ $endif;
|
||||
**/
|
||||
fn void clear_var(String name)
|
||||
{
|
||||
$if (COMPILER_LIBC_AVAILABLE && OS_TYPE != OsType.WIN32):
|
||||
$if (COMPILER_LIBC_AVAILABLE && OS_TYPE != OsType.WIN32)
|
||||
@pool()
|
||||
{
|
||||
if (libc::unsetenv(name.zstr_tcopy()))
|
||||
@@ -221,6 +221,6 @@ $if (COMPILER_LIBC_AVAILABLE && OS_TYPE != OsType.WIN32):
|
||||
unreachable();
|
||||
}
|
||||
};
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
|
||||
@@ -452,7 +452,7 @@ macro double! hexfloat(char[] chars, int $bits, int $emin, int sign)
|
||||
macro floatparse(String chars, $Type) @private
|
||||
{
|
||||
int sign = 1;
|
||||
$switch ($Type):
|
||||
$switch ($Type)
|
||||
$case float:
|
||||
const int BITS = math::FLOAT_MANT_DIG;
|
||||
const int EMIN = math::FLOAT_MIN_EXP - BITS;
|
||||
@@ -463,7 +463,7 @@ macro floatparse(String chars, $Type) @private
|
||||
$assert(false, "Not yet supported");
|
||||
$default:
|
||||
$assert(false, "Unexpected type");
|
||||
$endswitch;
|
||||
$endswitch
|
||||
|
||||
while (chars.len && chars[0] == ' ') chars = chars[1..];
|
||||
if (!chars.len) return NumberConversion.MALFORMED_FLOAT!;
|
||||
|
||||
@@ -91,20 +91,20 @@ fn bool ptr_is_aligned(void* ptr, usz alignment) @inline
|
||||
|
||||
macro void clear(void* dst, usz len, usz $dst_align = 0, bool $is_volatile = false, bool $inlined = false)
|
||||
{
|
||||
$if ($inlined):
|
||||
$if ($inlined)
|
||||
$$memset_inline(dst, (char)0, len, $is_volatile, $dst_align);
|
||||
$else:
|
||||
$else
|
||||
$$memset(dst, (char)0, len, $is_volatile, $dst_align);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro void copy(void* dst, void* src, usz len, usz $dst_align = 0, usz $src_align = 0, bool $is_volatile = false, bool $inlined = false)
|
||||
{
|
||||
$if ($inlined):
|
||||
$if ($inlined)
|
||||
$$memcpy_inline(dst, src, len, $is_volatile, $dst_align, $src_align);
|
||||
$else:
|
||||
$else
|
||||
$$memcpy(dst, src, len, $is_volatile, $dst_align, $src_align);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro void move(void* dst, void* src, usz len, usz $dst_align = 0, usz $src_align = 0, bool $is_volatile = false)
|
||||
@@ -114,11 +114,11 @@ macro void move(void* dst, void* src, usz len, usz $dst_align = 0, usz $src_alig
|
||||
|
||||
macro void set(void* dst, char val, usz len, usz $dst_align = 0, bool $is_volatile = false, bool $inlined = false)
|
||||
{
|
||||
$if ($inlined):
|
||||
$if ($inlined)
|
||||
$$memset_inline(dst, val, len, $is_volatile, $dst_align);
|
||||
$else:
|
||||
$else
|
||||
$$memset(dst, val, len, $is_volatile, $dst_align);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,25 +130,25 @@ macro void set(void* dst, char val, usz len, usz $dst_align = 0, bool $is_volati
|
||||
**/
|
||||
macro bool equals(a, b, isz len = -1, usz $align = 0)
|
||||
{
|
||||
$if (!$align):
|
||||
$if (!$align)
|
||||
$align = $typeof(a[0]).alignof;
|
||||
$endif;
|
||||
$endif
|
||||
void* x @noinit;
|
||||
void* y @noinit;
|
||||
$if (values::@inner_kind(a) == TypeKind.SUBARRAY):
|
||||
$if (values::@inner_kind(a) == TypeKind.SUBARRAY)
|
||||
len = a.len;
|
||||
if (len != b.len) return false;
|
||||
x = a.ptr;
|
||||
y = b.ptr;
|
||||
$else:
|
||||
$else
|
||||
x = a;
|
||||
y = b;
|
||||
assert(len >= 0, "A zero or positive length must be given when comparing pointers.");
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
if (!len) return true;
|
||||
var $Type;
|
||||
$switch ($align):
|
||||
$switch ($align)
|
||||
$case 1:
|
||||
$Type = char;
|
||||
$case 2:
|
||||
@@ -158,7 +158,7 @@ macro bool equals(a, b, isz len = -1, usz $align = 0)
|
||||
$case 8:
|
||||
$default:
|
||||
$Type = ulong;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
var $step = $Type.sizeof;
|
||||
usz end = len / $step;
|
||||
for (usz i = 0; i < end; i++)
|
||||
@@ -206,18 +206,18 @@ macro malloc(..., Allocator* using = mem::heap(), usz end_padding = 0) @builtin
|
||||
**/
|
||||
macro malloc_checked(..., Allocator* using = mem::heap(), usz end_padding = 0) @builtin
|
||||
{
|
||||
$if ($checks($vatype(0).sizeof)):
|
||||
$if ($checks($vatype(0).sizeof))
|
||||
var $Type = $vatype(0);
|
||||
$assert(!type_alloc_must_be_aligned($vatype(0)), "Type must be allocated with malloc_aligned");
|
||||
$if ($vacount == 2):
|
||||
$if ($vacount == 2)
|
||||
usz size = $vaarg(1);
|
||||
return (($Type*)using.alloc($Type.sizeof * size + end_padding))[:size];
|
||||
$else:
|
||||
$else
|
||||
return ($Type*)using.alloc($Type.sizeof + end_padding);
|
||||
$endif;
|
||||
$else:
|
||||
$endif
|
||||
$else
|
||||
return using.alloc($vaarg(0) + end_padding);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
|
||||
@@ -228,17 +228,17 @@ macro malloc_checked(..., Allocator* using = mem::heap(), usz end_padding = 0) @
|
||||
**/
|
||||
macro malloc_aligned(..., usz alignment = 0, usz end_padding = 0, Allocator* using = mem::heap()) @builtin
|
||||
{
|
||||
$if ($checks($vatype(0).sizeof)):
|
||||
$if ($checks($vatype(0).sizeof))
|
||||
var $Type = $vatype(0);
|
||||
$if ($vacount == 2):
|
||||
$if ($vacount == 2)
|
||||
usz size = $vaarg(1);
|
||||
return (($Type*)using.alloc_aligned($Type.sizeof * size + end_padding, alignment))[:size];
|
||||
$else:
|
||||
$else
|
||||
return ($Type*)using.alloc_aligned($Type.sizeof + end_padding, alignment);
|
||||
$endif;
|
||||
$else:
|
||||
$endif
|
||||
$else
|
||||
return using.alloc_aligned($vaarg(0) + end_padding, alignment);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro alloc($Type) @deprecated => malloc($Type);
|
||||
@@ -260,18 +260,18 @@ macro calloc(..., Allocator* using = mem::heap(), usz end_padding = 0) @builtin
|
||||
**/
|
||||
macro calloc_checked(..., Allocator* using = mem::heap(), usz end_padding = 0) @builtin
|
||||
{
|
||||
$if ($checks($vatype(0).sizeof)):
|
||||
$if ($checks($vatype(0).sizeof))
|
||||
var $Type = $vatype(0);
|
||||
$assert(!type_alloc_must_be_aligned($vatype(0)), "Type must be allocated with calloc_aligned");
|
||||
$if ($vacount == 2):
|
||||
$if ($vacount == 2)
|
||||
usz size = $vaarg(1);
|
||||
return (($Type*)using.calloc($Type.sizeof * size + end_padding))[:size];
|
||||
$else:
|
||||
$else
|
||||
return ($Type*)using.calloc($Type.sizeof + end_padding);
|
||||
$endif;
|
||||
$else:
|
||||
$endif
|
||||
$else
|
||||
return using.calloc($vaarg(0) + end_padding);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
|
||||
@@ -282,17 +282,17 @@ macro calloc_checked(..., Allocator* using = mem::heap(), usz end_padding = 0) @
|
||||
**/
|
||||
macro calloc_aligned(..., usz alignment = 0, Allocator* using = mem::heap(), usz end_padding = 0) @builtin
|
||||
{
|
||||
$if ($checks($vatype(0).sizeof)):
|
||||
$if ($checks($vatype(0).sizeof))
|
||||
var $Type = $vatype(0);
|
||||
$if ($vacount == 2):
|
||||
$if ($vacount == 2)
|
||||
usz size = $vaarg(1);
|
||||
return (($Type*)using.calloc_aligned($Type.sizeof * size + end_padding, alignment))[:size];
|
||||
$else:
|
||||
$else
|
||||
return ($Type*)using.calloc_aligned($Type.sizeof + end_padding, alignment);
|
||||
$endif;
|
||||
$else:
|
||||
$endif
|
||||
$else
|
||||
return using.calloc_aligned($vaarg(0) + end_padding, alignment);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn void* realloc(void *ptr, usz new_size, Allocator* using = mem::heap()) @builtin @inline
|
||||
@@ -337,17 +337,17 @@ macro talloc($Type) @builtin @deprecated => tmalloc($Type);
|
||||
**/
|
||||
macro tmalloc(..., usz end_padding = 0, usz alignment = DEFAULT_MEM_ALIGNMENT) @builtin
|
||||
{
|
||||
$if ($checks($vatype(0).sizeof)):
|
||||
$if ($checks($vatype(0).sizeof))
|
||||
var $Type = $vatype(0);
|
||||
$if ($vacount == 2):
|
||||
$if ($vacount == 2)
|
||||
usz size = $vaarg(1);
|
||||
return (($Type*)temp().alloc_aligned($Type.sizeof * size + end_padding, alignment))[:size]!!;
|
||||
$else:
|
||||
$else
|
||||
return ($Type*)temp().alloc_aligned($Type.sizeof + end_padding, alignment)!!;
|
||||
$endif;
|
||||
$else:
|
||||
$endif
|
||||
$else
|
||||
return temp().alloc_aligned($vaarg(0) + end_padding, alignment)!!;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -356,17 +356,17 @@ macro tmalloc(..., usz end_padding = 0, usz alignment = DEFAULT_MEM_ALIGNMENT) @
|
||||
**/
|
||||
macro tcalloc(..., usz end_padding = 0, usz alignment = mem::DEFAULT_MEM_ALIGNMENT) @builtin
|
||||
{
|
||||
$if ($checks($vatype(0).sizeof)):
|
||||
$if ($checks($vatype(0).sizeof))
|
||||
var $Type = $vatype(0);
|
||||
$if ($vacount == 2):
|
||||
$if ($vacount == 2)
|
||||
usz size = $vaarg(1);
|
||||
return (($Type*)temp().calloc_aligned($Type.sizeof * size + end_padding, alignment))[:size]!!;
|
||||
$else:
|
||||
$else
|
||||
return ($Type*)temp().calloc_aligned($Type.sizeof + end_padding, alignment)!!;
|
||||
$endif;
|
||||
$else:
|
||||
$endif
|
||||
$else
|
||||
return temp().calloc_aligned($vaarg(0) + end_padding, alignment)!!;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn void* trealloc(void* ptr, usz size, usz alignment = mem::DEFAULT_MEM_ALIGNMENT) @builtin @inline
|
||||
@@ -400,7 +400,7 @@ macro TempAllocator* temp()
|
||||
{
|
||||
if (!thread_temp_allocator)
|
||||
{
|
||||
$switch (env::MEMORY_ENV):
|
||||
$switch (env::MEMORY_ENV)
|
||||
$case NORMAL:
|
||||
thread_temp_allocator = allocator::new_temp(1024 * 256, thread_allocator)!!;
|
||||
$case SMALL:
|
||||
@@ -409,7 +409,7 @@ macro TempAllocator* temp()
|
||||
thread_temp_allocator = allocator::new_temp(1024 * 2, thread_allocator)!!;
|
||||
$case NONE:
|
||||
unreachable("Temp allocator must explicitly created when memory-env is set to 'none'.");
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
return thread_temp_allocator;
|
||||
}
|
||||
@@ -417,7 +417,7 @@ macro TempAllocator* temp()
|
||||
macro Allocator* current_allocator() => thread_allocator;
|
||||
macro Allocator* heap() => thread_allocator;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE && env::ARCH_TYPE == ArchType.WASM32 || env::ARCH_TYPE == ArchType.WASM64):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE && env::ARCH_TYPE == ArchType.WASM32 || env::ARCH_TYPE == ArchType.WASM64)
|
||||
|
||||
SimpleHeapAllocator wasm_allocator @private;
|
||||
|
||||
@@ -432,6 +432,6 @@ static initialize @priority(1)
|
||||
wasm_allocator.init(fn (x) => allocator::wasm_memory.allocate_block(x));
|
||||
thread_allocator = &wasm_allocator;
|
||||
}
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ macro int @main_to_void_main_args(#m, int argc, char** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
$if (env::OS_TYPE == OsType.WIN32):
|
||||
$if (env::OS_TYPE == OsType.WIN32)
|
||||
|
||||
extern fn Char16** _win_command_line_to_argv_w(ushort* cmd_line, int* argc_ptr) @extern("CommandLineToArgvW");
|
||||
|
||||
@@ -153,4 +153,4 @@ macro int @wmain_to_void_main_args(#m, int argc, Char16** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -98,7 +98,7 @@ fn bool __run_default_test_runner()
|
||||
return test_runner_create().run();
|
||||
}
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE && env::ARCH_TYPE == ArchType.WASM32 || env::ARCH_TYPE == ArchType.WASM64):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE && env::ARCH_TYPE == ArchType.WASM32 || env::ARCH_TYPE == ArchType.WASM64)
|
||||
|
||||
extern fn void __wasm_call_ctors();
|
||||
fn void wasm_initialize() @extern("_initialize") @wasm
|
||||
@@ -106,4 +106,4 @@ fn void wasm_initialize() @extern("_initialize") @wasm
|
||||
// The linker synthesizes this to call constructors.
|
||||
__wasm_call_ctors();
|
||||
}
|
||||
$endif;
|
||||
$endif
|
||||
@@ -76,12 +76,12 @@ macro variant_to_int(variant v, $Type)
|
||||
macro bool is_numerical($Type)
|
||||
{
|
||||
var $kind = $Type.kindof;
|
||||
$if ($kind == TypeKind.DISTINCT):
|
||||
$if ($kind == TypeKind.DISTINCT)
|
||||
return is_numerical($Type.inner);
|
||||
$else:
|
||||
$else
|
||||
return $kind == TypeKind.SIGNED_INT || $kind == TypeKind.UNSIGNED_INT || $kind == TypeKind.FLOAT
|
||||
|| $kind == TypeKind.VECTOR;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn bool TypeKind.is_int(TypeKind kind) @inline
|
||||
@@ -97,13 +97,13 @@ macro bool is_indexable($Type)
|
||||
macro bool is_comparable($Type)
|
||||
{
|
||||
var $kind = $Type.kindof;
|
||||
$if ($kind == TypeKind.DISTINCT):
|
||||
$if ($kind == TypeKind.DISTINCT)
|
||||
return is_comparable($Type.inner);
|
||||
$else:
|
||||
$else
|
||||
return $kind == TypeKind.SIGNED_INT || $kind == TypeKind.UNSIGNED_INT || $kind == TypeKind.FLOAT
|
||||
|| $kind == TypeKind.VECTOR || $kind == TypeKind.BOOL || $kind == TypeKind.POINTER
|
||||
|| $kind == TypeKind.ENUM;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro bool is_equatable($Type)
|
||||
@@ -113,14 +113,14 @@ macro bool is_equatable($Type)
|
||||
|
||||
macro bool is_subarray_convertable($Type)
|
||||
{
|
||||
$switch ($Type.kindof):
|
||||
$switch ($Type.kindof)
|
||||
$case SUBARRAY:
|
||||
return true;
|
||||
$case POINTER:
|
||||
return $Type.inner.kindof == TypeKind.ARRAY;
|
||||
$default:
|
||||
return false;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
macro bool is_bool($Type) => $Type.kindof == TypeKind.BOOL;
|
||||
@@ -128,7 +128,7 @@ macro bool is_int($Type) => $Type.kindof == TypeKind.SIGNED_INT || $Type.kindof
|
||||
|
||||
macro bool is_intlike($Type)
|
||||
{
|
||||
$switch ($Type.kindof):
|
||||
$switch ($Type.kindof)
|
||||
$case SIGNED_INT:
|
||||
$case UNSIGNED_INT:
|
||||
return true;
|
||||
@@ -136,7 +136,7 @@ macro bool is_intlike($Type)
|
||||
return $Type.inner.kindof == TypeKind.SIGNED_INT || $Type.inner.kindof == TypeKind.UNSIGNED_INT;
|
||||
$default:
|
||||
return false;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
|
||||
@@ -144,14 +144,14 @@ macro bool is_float($Type) => $Type.kindof == TypeKind.FLOAT;
|
||||
|
||||
macro bool is_floatlike($Type)
|
||||
{
|
||||
$switch ($Type.kindof):
|
||||
$switch ($Type.kindof)
|
||||
$case FLOAT:
|
||||
return true;
|
||||
$case VECTOR:
|
||||
return $Type.inner.kindof == TypeKind.FLOAT;
|
||||
$default:
|
||||
return false;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
macro bool is_vector($Type)
|
||||
@@ -161,11 +161,11 @@ macro bool is_vector($Type)
|
||||
|
||||
macro TypeKind inner_kind($Type)
|
||||
{
|
||||
$if ($Type.kindof == TypeKind.DISTINCT):
|
||||
$if ($Type.kindof == TypeKind.DISTINCT)
|
||||
return inner_kind($typefrom($Type.inner));
|
||||
$else:
|
||||
$else
|
||||
return $Type.kindof;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro bool @convertable(#a, $TypeB) @builtin
|
||||
@@ -181,20 +181,20 @@ macro bool is_same($TypeA, $TypeB)
|
||||
macro bool @has_same(#a, #b, ...)
|
||||
{
|
||||
var $type_a = $typeof(#a).typeid;
|
||||
$if ($type_a != $typeof(#b).typeid):
|
||||
$if ($type_a != $typeof(#b).typeid)
|
||||
return false;
|
||||
$endif;
|
||||
$for (var $i = 0; $i < $vacount; $i++):
|
||||
$if ($typeof($vaexpr($i)).typeid != $type_a):
|
||||
$endif
|
||||
$for (var $i = 0; $i < $vacount; $i++)
|
||||
$if ($typeof($vaexpr($i)).typeid != $type_a)
|
||||
return false;
|
||||
$endif;
|
||||
$endfor;
|
||||
$endif
|
||||
$endfor
|
||||
return true;
|
||||
}
|
||||
|
||||
macro bool may_load_atomic($Type)
|
||||
{
|
||||
$switch ($Type.kindof):
|
||||
$switch ($Type.kindof)
|
||||
$case SIGNED_INT:
|
||||
$case UNSIGNED_INT:
|
||||
$case POINTER:
|
||||
@@ -204,7 +204,7 @@ macro bool may_load_atomic($Type)
|
||||
return may_load_atomic($Type.inner);
|
||||
$default:
|
||||
return false;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
macro bool is_promotable_to_floatlike($Type) => types::is_floatlike($Type) || types::is_int($Type);
|
||||
@@ -212,29 +212,29 @@ macro bool is_promotable_to_float($Type) => types::is_float($Type) || types::is_
|
||||
|
||||
macro bool is_same_vector_type($Type1, $Type2)
|
||||
{
|
||||
$if ($Type1.kindof != TypeKind.VECTOR):
|
||||
$if ($Type1.kindof != TypeKind.VECTOR)
|
||||
return $Type2.kindof != TypeKind.VECTOR;
|
||||
$else:
|
||||
$else
|
||||
return $Type1.inner == $Type2.inner && $Type1.len == $Type2.len;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro bool is_equatable_value(value)
|
||||
{
|
||||
$if ($defined(value.less) || $defined(value.compare_to) || $defined(value.equals)):
|
||||
$if ($defined(value.less) || $defined(value.compare_to) || $defined(value.equals))
|
||||
return true;
|
||||
$else:
|
||||
$else
|
||||
return is_equatable($typeof(value));
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro bool is_comparable_value(value)
|
||||
{
|
||||
$if ($defined(value.less) || $defined(value.compare_to)):
|
||||
$if ($defined(value.less) || $defined(value.compare_to))
|
||||
return true;
|
||||
$else:
|
||||
$else
|
||||
return is_comparable($typeof(value));
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
enum TypeKind : char
|
||||
|
||||
@@ -12,11 +12,11 @@ macro bool @is_promotable_to_float(#value) => types::is_promotable_to_float($typ
|
||||
macro bool @is_same_vector_type(#value1, #value2) => types::is_same_vector_type($typeof(#value1), $typeof(#value2));
|
||||
macro promote_int(x)
|
||||
{
|
||||
$if (@is_int(x)):
|
||||
$if (@is_int(x))
|
||||
return (double)x;
|
||||
$else:
|
||||
$else
|
||||
return x;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro TypeKind @inner_kind(#value) => types::inner_kind($typeof(#value));
|
||||
|
||||
@@ -267,7 +267,7 @@ fn void VarString.append_char(VarString* str, char c)
|
||||
macro void VarString.append(VarString* str, value)
|
||||
{
|
||||
var $Type = $typeof(value);
|
||||
$switch ($Type):
|
||||
$switch ($Type)
|
||||
$case char:
|
||||
$case ichar:
|
||||
str.append_char(value);
|
||||
@@ -278,14 +278,14 @@ macro void VarString.append(VarString* str, value)
|
||||
$case Char32:
|
||||
str.append_char32(value);
|
||||
$default:
|
||||
$if (@convertible(value, Char32)):
|
||||
$if (@convertible(value, Char32))
|
||||
str.append_char32(value);
|
||||
$elif (@convertible(value, String)):
|
||||
$elif (@convertible(value, String))
|
||||
str.append_chars(value);
|
||||
$else:
|
||||
$else
|
||||
$assert(false, "Unsupported type for append – use printf instead.");
|
||||
$endif;
|
||||
$endswitch;
|
||||
$endif
|
||||
$endswitch
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -96,12 +96,12 @@ macro @blk(&block, i) @local
|
||||
|
||||
macro @blk0(&block, i) @local
|
||||
{
|
||||
$if (env::BIG_ENDIAN):
|
||||
$if (env::BIG_ENDIAN)
|
||||
return block.l[i];
|
||||
$else:
|
||||
$else
|
||||
return block.l[i] = (block.l[i].rotl(24) & 0xFF00FF00)
|
||||
| (block.l[i].rotl(8) & 0x00FF00FF);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro @r0(&block, v, &w, x, y, &z, i) @local
|
||||
|
||||
@@ -53,7 +53,7 @@ fn void putchar(char c) @inline
|
||||
macro void print(x)
|
||||
{
|
||||
var $Type = $typeof(x);
|
||||
$switch ($Type):
|
||||
$switch ($Type)
|
||||
$case String:
|
||||
catch? stdout().print(x);
|
||||
$case ZString:
|
||||
@@ -63,18 +63,18 @@ macro void print(x)
|
||||
$case VarString:
|
||||
catch? stdout().print(x.str());
|
||||
$default:
|
||||
$if (@convertible(x, String)):
|
||||
$if (@convertible(x, String))
|
||||
catch? stdout().print((String)x);
|
||||
$else:
|
||||
$else
|
||||
catch? stdout().printf("%s", x);
|
||||
$endif;
|
||||
$endswitch;
|
||||
$endif
|
||||
$endswitch
|
||||
}
|
||||
|
||||
macro void printn(x = "")
|
||||
{
|
||||
var $Type = $typeof(x);
|
||||
$switch ($Type):
|
||||
$switch ($Type)
|
||||
$case String:
|
||||
catch? stdout().printn(x);
|
||||
$case ZString:
|
||||
@@ -84,12 +84,12 @@ macro void printn(x = "")
|
||||
$case VarString:
|
||||
catch? stdout().printn(x.str());
|
||||
$default:
|
||||
$if (@convertible(x, String)):
|
||||
$if (@convertible(x, String))
|
||||
catch? stdout().printn((String)x);
|
||||
$else:
|
||||
$else
|
||||
catch? stdout().printfn("%s", x);
|
||||
$endif;
|
||||
$endswitch;
|
||||
$endif
|
||||
$endswitch
|
||||
}
|
||||
|
||||
macro void println(x = "") @deprecated => printn(x);
|
||||
|
||||
@@ -69,12 +69,12 @@ fn uint128! int_from_variant(variant arg, bool *is_neg) @private
|
||||
|
||||
fn FloatType! float_from_variant(variant arg) @private
|
||||
{
|
||||
$if (env::F128_SUPPORT):
|
||||
$if (env::F128_SUPPORT)
|
||||
if (arg.type == float128.typeid) return (FloatType)*((float128*)arg.ptr);
|
||||
$endif;
|
||||
$if (env::F16_SUPPORT):
|
||||
$endif
|
||||
$if (env::F16_SUPPORT)
|
||||
if (arg.type == float16.typeid) return *((float16*)arg.ptr);
|
||||
$endif;
|
||||
$endif
|
||||
if (arg.type.kindof == TypeKind.DISTINCT)
|
||||
{
|
||||
return float_from_variant(variant { arg.ptr, arg.type.inner });
|
||||
|
||||
@@ -127,19 +127,19 @@ fn void Formatter.init(Formatter* this, OutputFn out_fn, void* data = null)
|
||||
*/
|
||||
macro void formatter_register_type($Type)
|
||||
{
|
||||
$if ($checks($Type a, a.to_format(&&Formatter {}))):
|
||||
$if ($checks($Type a, a.to_format(&&Formatter {})))
|
||||
if (!toformat_functions.table.len)
|
||||
{
|
||||
toformat_functions.init(64);
|
||||
}
|
||||
toformat_functions.set($Type.typeid, (ToFormatFunction)&$Type.to_format);
|
||||
$else:
|
||||
$else
|
||||
if (!tostring_functions.table.len)
|
||||
{
|
||||
tostring_functions.init(64);
|
||||
}
|
||||
tostring_functions.set($Type.typeid, (ToStringFunction)&$Type.to_string);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ fn usz! Stream.copy_to(Stream* s, Stream* dst, char[] buffer = {})
|
||||
if (buffer.len) return copy_through_buffer(s, dst, buffer);
|
||||
if (WriteToStreamFn func = s.fns.write_stream_fn) return func(s, dst);
|
||||
if (ReadFromStreamFn func = dst.fns.read_stream_fn) return func(dst, s);
|
||||
$switch (env::MEMORY_ENV):
|
||||
$switch (env::MEMORY_ENV)
|
||||
$case NORMAL:
|
||||
@pool()
|
||||
{
|
||||
@@ -183,7 +183,7 @@ $case SMALL:
|
||||
$case TINY:
|
||||
$case NONE:
|
||||
return copy_through_buffer(s, dst, &&(char[256]{}));
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
macro usz! copy_through_buffer(Stream* s, Stream* dst, char[] buffer) @local
|
||||
|
||||
@@ -2,14 +2,14 @@ module std::io::os;
|
||||
import libc;
|
||||
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
fn void! native_chdir(Path path)
|
||||
{
|
||||
unreachable("'getcwd' not available");
|
||||
}
|
||||
|
||||
$elif (env::OS_TYPE == OsType.WIN32):
|
||||
$elif (env::OS_TYPE == OsType.WIN32)
|
||||
|
||||
macro void! native_chdir(Path path)
|
||||
{
|
||||
@@ -20,7 +20,7 @@ macro void! native_chdir(Path path)
|
||||
return IoError.GENERAL_ERROR!;
|
||||
}
|
||||
|
||||
$else:
|
||||
$else
|
||||
|
||||
extern fn int _chdir(ZString) @extern("chdir");
|
||||
macro void! native_chdir(Path p)
|
||||
@@ -39,4 +39,4 @@ macro void! native_chdir(Path p)
|
||||
}
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -9,27 +9,27 @@ define FtellFn = fn usz!(void*);
|
||||
define FwriteFn = fn usz!(void*, char[] buffer);
|
||||
define FreadFn = fn usz!(void*, char[] buffer);
|
||||
|
||||
$if (!$defined(native_fopen_fn)):
|
||||
$if (!$defined(native_fopen_fn))
|
||||
FopenFn native_fopen_fn @weak;
|
||||
$endif;
|
||||
$if (!$defined(native_fclose_fn)):
|
||||
$endif
|
||||
$if (!$defined(native_fclose_fn))
|
||||
FcloseFn native_fclose_fn @weak;
|
||||
$endif;
|
||||
$if (!$defined(native_freopen_fn)):
|
||||
$endif
|
||||
$if (!$defined(native_freopen_fn))
|
||||
FreopenFn native_freopen_fn @weak;
|
||||
$endif;
|
||||
$if (!$defined(native_fseek_fn)):
|
||||
$endif
|
||||
$if (!$defined(native_fseek_fn))
|
||||
FseekFn native_fseek_fn @weak;
|
||||
$endif;
|
||||
$if (!$defined(native_ftell_fn)):
|
||||
$endif
|
||||
$if (!$defined(native_ftell_fn))
|
||||
FtellFn native_ftell_fn @weak;
|
||||
$endif;
|
||||
$if (!$defined(native_fwrite_fn)):
|
||||
$endif
|
||||
$if (!$defined(native_fwrite_fn))
|
||||
FwriteFn native_fwrite_fn @weak;
|
||||
$endif;
|
||||
$if (!$defined(native_fread_fn)):
|
||||
$endif
|
||||
$if (!$defined(native_fread_fn))
|
||||
FreadFn native_fread_fn @weak;
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
|
||||
/**
|
||||
@@ -38,20 +38,20 @@ $endif;
|
||||
**/
|
||||
fn void*! native_fopen(String filename, String mode) @inline
|
||||
{
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
if (native_fopen_fn) return native_fopen_fn(filename, mode);
|
||||
unreachable("Tried to call fopen without support.");
|
||||
$else:
|
||||
$else
|
||||
@pool()
|
||||
{
|
||||
$if (env::os_is_win32()):
|
||||
$if (env::os_is_win32())
|
||||
void* file = (CFile)_wfopen(filename.to_temp_utf16(), filename.to_temp_utf16())?;
|
||||
$else:
|
||||
$else
|
||||
void* file = libc::fopen(filename.zstr_tcopy(), mode.zstr_tcopy());
|
||||
$endif;
|
||||
$endif
|
||||
return file ?: file_open_errno()!;
|
||||
};
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,71 +60,71 @@ $endif;
|
||||
**/
|
||||
fn void*! native_freopen(void* file, String filename, String mode) @inline
|
||||
{
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
if (native_freopen_fn) return native_freopen_fn(file, filename, mode);
|
||||
unreachable("Tried to call freopen without support.");
|
||||
$else:
|
||||
$else
|
||||
@pool()
|
||||
{
|
||||
$if (env::os_is_win32()):
|
||||
$if (env::os_is_win32())
|
||||
file = _wfreopen(filename.to_temp_utf16(), mode.to_temp_utf16(), file)?;
|
||||
$else:
|
||||
$else
|
||||
file = libc::freopen(filename.zstr_tcopy(), mode.zstr_tcopy(), file);
|
||||
$endif;
|
||||
$endif
|
||||
return file ?: file_open_errno()!;
|
||||
};
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn void! native_fseek(void* file, isz offset, Seek seek_mode) @inline
|
||||
{
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
if (native_fseek_fn) return native_fseek_fn(file, offset, seek_mode);
|
||||
unreachable("Tried to call fseek without support.");
|
||||
$else:
|
||||
$if (env::os_is_win32()):
|
||||
$else
|
||||
$if (env::os_is_win32())
|
||||
bool success = _fseeki64(file, (long)offset, (int)seek_mode) == 0;
|
||||
$else:
|
||||
$else
|
||||
bool success = libc::fseek(file, (SeekIndex)offset, (CInt)seek_mode) == 0;
|
||||
$endif;
|
||||
$endif
|
||||
if (!success) return file_seek_errno()!;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn usz! native_ftell(CFile file) @inline
|
||||
{
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
if (native_ftell_fn) return native_ftell_fn(file);
|
||||
unreachable("Tried to call ftell without support.");
|
||||
$else:
|
||||
$if (env::os_is_win32()):
|
||||
$else
|
||||
$if (env::os_is_win32())
|
||||
long index = _ftelli64(file);
|
||||
return index >= 0 ? index : file_seek_errno()!;
|
||||
$else:
|
||||
$else
|
||||
SeekIndex index = libc::ftell(file);
|
||||
return index >= 0 ? index : file_seek_errno()!;
|
||||
$endif;
|
||||
$endif;
|
||||
$endif
|
||||
$endif
|
||||
}
|
||||
|
||||
fn usz! native_fwrite(CFile file, char[] buffer) @inline
|
||||
{
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
if (native_fwrite_fn) return native_fwrite_fn(file, buffer);
|
||||
unreachable("Tried to call fwrite without support.");
|
||||
$else:
|
||||
$else
|
||||
return libc::fwrite(buffer.ptr, 1, buffer.len, file);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn usz! native_fread(CFile file, char[] buffer) @inline
|
||||
{
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
if (native_fread_fn) return native_fread_fn(file, buffer);
|
||||
unreachable("Tried to call fread without support.");
|
||||
$else:
|
||||
$else
|
||||
return libc::fread(buffer.ptr, 1, buffer.len, file);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro anyerr file_open_errno() @local
|
||||
@@ -175,13 +175,13 @@ macro anyerr file_seek_errno() @local
|
||||
}
|
||||
|
||||
// Win functions
|
||||
$if (env::os_is_win32()):
|
||||
$if (env::os_is_win32())
|
||||
extern fn void* _wfopen(Char16*, Char16*) @local;
|
||||
extern fn void* _wfreopen(Char16*, Char16*, CFile) @local;
|
||||
extern fn int _fseeki64(CFile, long, int) @local;
|
||||
extern fn long _ftelli64(CFile) @local;
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
$if (env::os_is_posix()):
|
||||
$if (env::os_is_posix())
|
||||
extern fn CInt access(ZString path, CInt mode);
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::io::file::os;
|
||||
import libc;
|
||||
|
||||
$if (env::os_is_darwin()):
|
||||
$if (env::os_is_darwin())
|
||||
|
||||
|
||||
struct DarwinTimespec @private
|
||||
@@ -99,4 +99,4 @@ fn void! read_stat(Darwin64Stat* stat, String path) @local
|
||||
}
|
||||
};
|
||||
}
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::io::file::os;
|
||||
|
||||
// native_temp_directory, for non Win32
|
||||
$if (!env::os_is_win32()):
|
||||
$if (!env::os_is_win32())
|
||||
|
||||
fn Path! native_temp_directory(Allocator* using = mem::heap())
|
||||
{
|
||||
@@ -13,7 +13,7 @@ fn Path! native_temp_directory(Allocator* using = mem::heap())
|
||||
return path::new("/tmp", using);
|
||||
}
|
||||
|
||||
$if (env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
extern fn void* opendir(ZString);
|
||||
extern fn void closedir(void*);
|
||||
@@ -48,11 +48,11 @@ fn PathList! native_readdir(Path dir, bool no_dirs, bool no_symlinks, String mas
|
||||
return list;
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
$if (!env::os_is_darwin() && !env::os_is_win32()):
|
||||
$if (!env::os_is_darwin() && !env::os_is_win32())
|
||||
|
||||
fn usz! native_file_size(String path)
|
||||
{
|
||||
@@ -61,7 +61,7 @@ fn usz! native_file_size(String path)
|
||||
return f.seek(0, Seek.END)?;
|
||||
}
|
||||
|
||||
$if (env::os_is_posix() && env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (env::os_is_posix() && env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
fn bool native_file_or_dir_exists(String path)
|
||||
{
|
||||
@@ -83,7 +83,7 @@ fn bool native_is_dir(String path)
|
||||
return native_file_or_dir_exists(path) && !native_is_file(path);
|
||||
}
|
||||
|
||||
$else:
|
||||
$else
|
||||
|
||||
fn bool native_file_or_dir_exists(String path)
|
||||
{
|
||||
@@ -100,11 +100,11 @@ fn bool native_is_file(String path)
|
||||
unreachable("Tried to call is_file without support.");
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
$switch (env::OS_TYPE):
|
||||
$switch (env::OS_TYPE)
|
||||
$case IOS:
|
||||
$case MACOSX:
|
||||
$case TVOS:
|
||||
@@ -140,4 +140,4 @@ struct NativeDirentry
|
||||
char type;
|
||||
char[*] name;
|
||||
}
|
||||
$endswitch;
|
||||
$endswitch
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::io::file::os;
|
||||
import std::os::win32::files;
|
||||
|
||||
$if (env::os_is_win32()):
|
||||
$if (env::os_is_win32())
|
||||
|
||||
fn usz! native_file_size(String path)
|
||||
{
|
||||
@@ -60,4 +60,4 @@ fn Path! native_temp_directory(Allocator* using = mem::heap())
|
||||
}
|
||||
}
|
||||
*/
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,14 +1,14 @@
|
||||
module std::io::os;
|
||||
import libc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
fn String! getcwd(Allocator* using = mem::heap())
|
||||
{
|
||||
unreachable("'getcwd' not available");
|
||||
}
|
||||
|
||||
$elif (env::OS_TYPE == OsType.WIN32):
|
||||
$elif (env::OS_TYPE == OsType.WIN32)
|
||||
|
||||
extern fn Char16* _wgetcwd(Char16* buffer, int maxlen);
|
||||
extern fn usz wcslen(Char16* str);
|
||||
@@ -30,7 +30,7 @@ macro String! getcwd(Allocator* using = mem::heap())
|
||||
return str::utf16to8(str16, using);
|
||||
}
|
||||
|
||||
$else:
|
||||
$else
|
||||
|
||||
extern fn ZString _getcwd(char* pwd, usz len) @extern("getcwd");
|
||||
macro String! getcwd(Allocator* using = mem::heap())
|
||||
@@ -50,4 +50,4 @@ macro String! getcwd(Allocator* using = mem::heap())
|
||||
return res.copy(using);
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -35,7 +35,7 @@ typedef TerminateFunction = fn void();
|
||||
typedef CompareFunction = fn int(void*, void*);
|
||||
typedef JmpBuf = uptr[$$JMP_BUF_SIZE];
|
||||
|
||||
$if (env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
extern fn double atof(char* str);
|
||||
extern fn int atoi(char* str);
|
||||
@@ -59,13 +59,13 @@ extern fn int rand();
|
||||
extern fn void srand(uint seed);
|
||||
|
||||
extern fn void longjmp(JmpBuf* buffer, CInt value);
|
||||
$if (env::OS_TYPE == OsType.WIN32):
|
||||
$if (env::OS_TYPE == OsType.WIN32)
|
||||
// TODO win32 aarch64
|
||||
extern fn CInt _setjmp(void* frameptr, JmpBuf* buffer);
|
||||
macro CInt setjmp(JmpBuf* buffer) => _setjmp($$frameaddress(), buffer);
|
||||
$else:
|
||||
$else
|
||||
extern fn CInt setjmp(JmpBuf* buffer);
|
||||
$endif;
|
||||
$endif
|
||||
// MB functions omitted
|
||||
|
||||
// string
|
||||
@@ -97,7 +97,7 @@ extern fn void* calloc(usz count, usz size);
|
||||
extern fn void* free(void*);
|
||||
extern fn void* realloc(void* ptr, usz size);
|
||||
|
||||
$else:
|
||||
$else
|
||||
|
||||
fn void longjmp(JmpBuf* buffer, CInt value) @weak @extern("longjmp") @nostrip
|
||||
{
|
||||
@@ -144,14 +144,14 @@ fn void* memset(void* dest, CInt value, usz n) @weak @extern("memset") @nostrip
|
||||
return dest;
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
// stdio
|
||||
|
||||
typedef Fpos = long;
|
||||
typedef CFile = void*;
|
||||
|
||||
$if (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.LINUX):
|
||||
$if (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.LINUX)
|
||||
extern CFile __stdin @extern("stdin");
|
||||
extern CFile __stdout @extern("stdout");
|
||||
extern CFile __stderr @extern("stderr");
|
||||
@@ -161,7 +161,7 @@ $if (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.LINUX):
|
||||
macro CFile stdin() { return __stdin; }
|
||||
macro CFile stdout() { return __stdout; }
|
||||
macro CFile stderr() { return __stderr; }
|
||||
$elif (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.MACOSX):
|
||||
$elif (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.MACOSX)
|
||||
extern CFile __stdinp;
|
||||
extern CFile __stdoutp;
|
||||
extern CFile __stderrp;
|
||||
@@ -170,18 +170,18 @@ $elif (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.MACOSX):
|
||||
macro CFile stdin() { return __stdinp; }
|
||||
macro CFile stdout() { return __stdoutp; }
|
||||
macro CFile stderr() { return __stderrp; }
|
||||
$elif (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.WIN32):
|
||||
$elif (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.WIN32)
|
||||
extern fn CFile __acrt_iob_func(CInt c);
|
||||
extern fn usz _msize(void* ptr);
|
||||
macro usz malloc_size(void* ptr) { return _msize(ptr); }
|
||||
macro CFile stdin() { return __acrt_iob_func(0); }
|
||||
macro CFile stdout() { return __acrt_iob_func(1); }
|
||||
macro CFile stderr() { return __acrt_iob_func(2); }
|
||||
$else:
|
||||
$else
|
||||
macro CFile stdin() { return (CFile*)(uptr)0; }
|
||||
macro CFile stdout() { return (CFile*)(uptr)1; }
|
||||
macro CFile stderr() { return (CFile*)(uptr)2; }
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
const HAS_MALLOC_SIZE =
|
||||
env::OS_TYPE == OsType.LINUX
|
||||
@@ -204,7 +204,7 @@ const int FILENAME_MAX = 1024;
|
||||
typedef Errno = distinct CInt;
|
||||
typedef SeekIndex = CLong;
|
||||
|
||||
$if (env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
extern fn int fclose(CFile stream);
|
||||
extern fn void clearerr(CFile stream);
|
||||
@@ -245,7 +245,7 @@ extern fn int ungetc(int c, CFile stream);
|
||||
extern fn void perror(char* str);
|
||||
extern fn isz getline(char** linep, usz* linecapp, CFile stream);
|
||||
|
||||
$else:
|
||||
$else
|
||||
|
||||
fn int fseek(CFile stream, SeekIndex offset, int whence) @weak @extern("fseek") @nostrip
|
||||
{
|
||||
@@ -314,7 +314,7 @@ fn int puts(ZString str) @weak @extern("puts") @nostrip
|
||||
unreachable("'puts' not available.");
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
// vsprintf vprintf not supported
|
||||
|
||||
// time.h
|
||||
@@ -385,11 +385,11 @@ const Errno ENOEXEC = 8; // Exec format error
|
||||
const Errno EBADF = 9; // Bad file number
|
||||
const Errno ECHILD = 10; // No child processes
|
||||
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
$if (env::OS_TYPE == OsType.MACOSX)
|
||||
const Errno EAGAIN = 35; // Try again Macos
|
||||
$else:
|
||||
$else
|
||||
const Errno EAGAIN = 11; // Try again
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
const Errno ENOMEM = 12; // Out of memory
|
||||
const Errno EACCES = 13; // Permission denied
|
||||
@@ -415,7 +415,7 @@ const Errno EPIPE = 32; // Broken pipe
|
||||
const Errno EDOM = 33; // Math argument out of domain of func
|
||||
const Errno ERANGE = 34; // Math result not representable
|
||||
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
$if (env::OS_TYPE == OsType.MACOSX)
|
||||
const Errno EDEADLK = 11; // Resource deadlock would occur MacOS
|
||||
const Errno ENAMETOOLONG = 63; // File name too long MacOS
|
||||
const Errno ELOOP = 62; // Too many symbolic links encountered
|
||||
@@ -426,7 +426,7 @@ const Errno ENETUNREACH = 51; // Network is unreachable MacOS
|
||||
const Errno ENETRESET = 52; // Network dropped connection because of reset MacOS
|
||||
const Errno EOPNOTSUPP = 45; // Operation not supported on transport endpoint
|
||||
|
||||
$elif (env::OS_TYPE == OsType.WIN32):
|
||||
$elif (env::OS_TYPE == OsType.WIN32)
|
||||
const Errno EDEADLK = 36; // Resource deadlock would occur Win32
|
||||
const Errno ENAMETOOLONG = 38; // File name too long Win32
|
||||
const Errno ELOOP = 114; // Too many symbolic links encountered
|
||||
@@ -437,7 +437,7 @@ const Errno ENETUNREACH = 118; // Network is unreachable
|
||||
const Errno ENETRESET = 117; // Network dropped connection because of reset
|
||||
const Errno EOPNOTSUPP = 130; // Operation not supported on transport endpoint
|
||||
|
||||
$else:
|
||||
$else
|
||||
const Errno EDEADLK = 35; // Resource deadlock would occur Linux (others?)
|
||||
const Errno ENAMETOOLONG = 36; // File name too long Linux (others?)
|
||||
const Errno ELOOP = 40; // Too many symbolic links encountered
|
||||
@@ -448,7 +448,7 @@ const Errno ENETUNREACH = 101; // Network is unreachable
|
||||
const Errno ENETRESET = 102; // Network dropped connection because of reset
|
||||
const Errno EOPNOTSUPP = 95; // Operation not supported on transport endpoint
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
|
||||
|
||||
@@ -523,27 +523,27 @@ const Errno ECONNREFUSED = 111; /* Connection refused */
|
||||
const Errno EHOSTDOWN = 112; /* Host is down */
|
||||
const Errno EHOSTUNREACH = 113; /* No route to host */
|
||||
*/
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
$if (env::OS_TYPE == OsType.MACOSX)
|
||||
const Errno ETIMEDOUT = 60; // Connection timed out
|
||||
const Errno EINPROGRESS = 36; // Operation now in progress MacOS
|
||||
const Errno EALREADY = 37; // Operation already in progress MacOS
|
||||
const Errno EDQUOT = 69; // Quota exceeded, MacOS
|
||||
const Errno EWOULDBLOCK = 35; // Operation would block
|
||||
|
||||
$elif (env::OS_TYPE == OsType.WIN32):
|
||||
$elif (env::OS_TYPE == OsType.WIN32)
|
||||
const Errno ETIMEDOUT = 138; // Connection timed out
|
||||
const Errno EALREADY = 103; // Operation already in progress
|
||||
const Errno EINPROGRESS = 112; // Operation now in progress Win32
|
||||
const Errno EDQUOT = -122; // Quota exceeded, not in Win32
|
||||
const Errno EWOULDBLOCK = 140; // Operation would block
|
||||
|
||||
$else:
|
||||
$else
|
||||
const Errno ETIMEDOUT = 110; // Connection timed out
|
||||
const Errno EALREADY = 114; // Operation already in progress
|
||||
const Errno EINPROGRESS = 115; // Operation now in progress
|
||||
const Errno EDQUOT = 122; // Quota exceeded
|
||||
const Errno EWOULDBLOCK = 41; // Operation would block
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
/*
|
||||
const Errno ESTALE = 116; /* Stale NFS file handle */
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
module libc::os;
|
||||
|
||||
$if (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.LINUX):
|
||||
$if (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.LINUX)
|
||||
|
||||
extern fn int* __errno_location();
|
||||
macro int errno() => *__errno_location();
|
||||
macro void errno_set(int err) => *(__errno_location()) = err;
|
||||
|
||||
$elif (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.MACOSX):
|
||||
$elif (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.MACOSX)
|
||||
|
||||
extern fn int* __error();
|
||||
macro int errno() => *__error();
|
||||
macro void errno_set(int err) => *(__error()) = err;
|
||||
|
||||
$elif (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.WIN32):
|
||||
$elif (env::COMPILER_LIBC_AVAILABLE && env::OS_TYPE == OsType.WIN32)
|
||||
|
||||
macro int errno()
|
||||
{
|
||||
@@ -26,10 +26,10 @@ macro void errno_set(int err) => _set_errno(err);
|
||||
extern fn void _get_errno(int* result);
|
||||
extern fn void _set_errno(int err);
|
||||
|
||||
$else:
|
||||
$else
|
||||
|
||||
tlocal int _errno_c3 = 0;
|
||||
fn void errno_set(int err) => _errno_c3 = err;
|
||||
fn int errno() => _errno_c3;
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
@@ -120,11 +120,11 @@ macro abs(x) => $$abs(x);
|
||||
macro sign(x)
|
||||
{
|
||||
var $Type = $typeof(x);
|
||||
$if ($Type.kindof == TypeKind.UNSIGNED_INT):
|
||||
$if ($Type.kindof == TypeKind.UNSIGNED_INT)
|
||||
return ($Type)(x > 0);
|
||||
$else:
|
||||
$else
|
||||
return ($Type)(x > 0) - ($Type)(x < 0);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
|
||||
@@ -134,11 +134,11 @@ macro sign(x)
|
||||
**/
|
||||
macro atan2(x, y)
|
||||
{
|
||||
$if (@typeis(x, float) && @typeis(y, float)):
|
||||
$if (@typeis(x, float) && @typeis(y, float))
|
||||
return _atan2f(x, y);
|
||||
$else:
|
||||
$else
|
||||
return _atan2(x, y);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,11 +148,11 @@ macro atan2(x, y)
|
||||
**/
|
||||
macro @sincos(x, y)
|
||||
{
|
||||
$if ($typeof(y[0]).typeid == float.typeid):
|
||||
$if ($typeof(y[0]).typeid == float.typeid)
|
||||
return _sincosf(x, y);
|
||||
$else:
|
||||
$else
|
||||
return _sincos(x, y);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,11 +161,11 @@ macro @sincos(x, y)
|
||||
**/
|
||||
macro atan(x)
|
||||
{
|
||||
$if ($typeof(x).typeid == float.typeid):
|
||||
$if ($typeof(x).typeid == float.typeid)
|
||||
return _atanf(x);
|
||||
$else:
|
||||
$else
|
||||
return _atan(x);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,15 +276,15 @@ macro log10(x) => $$log10(values::promote_int(x));
|
||||
**/
|
||||
macro max(x, y, ...)
|
||||
{
|
||||
$if ($vacount == 0):
|
||||
$if ($vacount == 0)
|
||||
return $$max(x, y);
|
||||
$else:
|
||||
$else
|
||||
var m = $$max(x, y);
|
||||
$for (var $i = 0; $i < $vacount; $i++):
|
||||
$for (var $i = 0; $i < $vacount; $i++)
|
||||
m = $$max(m, $vaarg($i));
|
||||
$endfor;
|
||||
$endfor
|
||||
return m;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,15 +293,15 @@ macro max(x, y, ...)
|
||||
**/
|
||||
macro min(x, y, ...)
|
||||
{
|
||||
$if ($vacount == 0):
|
||||
$if ($vacount == 0)
|
||||
return $$min(x, y);
|
||||
$else:
|
||||
$else
|
||||
var m = $$min(x, y);
|
||||
$for (var $i = 0; $i < $vacount; $i++):
|
||||
$for (var $i = 0; $i < $vacount; $i++)
|
||||
m = $$min(m, $vaarg($i));
|
||||
$endfor;
|
||||
$endfor
|
||||
return m;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -321,11 +321,11 @@ macro nearbyint(x) => $$nearbyint(x);
|
||||
**/
|
||||
macro pow(x, exp)
|
||||
{
|
||||
$if (types::is_floatlike($typeof(exp))):
|
||||
$if (types::is_floatlike($typeof(exp)))
|
||||
return $$pow(x, ($typeof(x))exp);
|
||||
$else:
|
||||
$else
|
||||
return $$pow_int(x, exp);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -333,13 +333,13 @@ macro pow(x, exp)
|
||||
**/
|
||||
macro frexp(x, int* e)
|
||||
{
|
||||
$switch($typeof(x)):
|
||||
$switch($typeof(x))
|
||||
$case float:
|
||||
$case float16:
|
||||
return _frexpf((float)x, e);
|
||||
$default:
|
||||
return _frexp((double)x, e);
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,13 +347,13 @@ macro frexp(x, int* e)
|
||||
**/
|
||||
macro int signbit(x)
|
||||
{
|
||||
$switch($typeof(x)):
|
||||
$switch($typeof(x))
|
||||
$case float:
|
||||
$case float16:
|
||||
return bitcast((float)x, uint) >> 31;
|
||||
$default:
|
||||
return (int)(bitcast((double)x, ulong) >> 63);
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -407,13 +407,13 @@ macro sqrt(x) => $$sqrt(values::promote_int(x));
|
||||
macro tan(x)
|
||||
{
|
||||
var $Type = $typeof(x);
|
||||
$if (types::is_vector($Type)):
|
||||
$if (types::is_vector($Type))
|
||||
return $$sin(x) / $$cos(x);
|
||||
$elif ($Type.typeid == float.typeid):
|
||||
$elif ($Type.typeid == float.typeid)
|
||||
return _tanf(x);
|
||||
$else:
|
||||
$else
|
||||
return _tan(x);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,13 +421,13 @@ macro tan(x)
|
||||
**/
|
||||
macro bool is_finite(x)
|
||||
{
|
||||
$switch($typeof(x)):
|
||||
$switch($typeof(x))
|
||||
$case float:
|
||||
$case float16:
|
||||
return bitcast((float)x, uint) & 0x7fffffff < 0x7f800000;
|
||||
$default:
|
||||
return bitcast((double)x, ulong) & (~0u64 >> 1) < 0x7ffu64 << 52;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -435,13 +435,13 @@ macro bool is_finite(x)
|
||||
**/
|
||||
macro is_nan(x)
|
||||
{
|
||||
$switch ($typeof(x)):
|
||||
$switch ($typeof(x))
|
||||
$case float:
|
||||
$case float16:
|
||||
return bitcast((float)x, uint) & 0x7fffffff > 0x7f800000;
|
||||
$default:
|
||||
return bitcast((double)x, ulong) & (~0u64 >> 1) > 0x7ff << 52;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -449,13 +449,13 @@ macro is_nan(x)
|
||||
**/
|
||||
macro is_inf(x)
|
||||
{
|
||||
$switch ($typeof(x)):
|
||||
$switch ($typeof(x))
|
||||
$case float:
|
||||
$case float16:
|
||||
return bitcast((float)x, uint) & 0x7fffffff == 0x7f800000;
|
||||
$default:
|
||||
return bitcast((double)x, ulong) & (~0u64 >> 1) == 0x7ff << 52;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -180,7 +180,7 @@ fn int128 __fixsfti(float a) @weak @extern("__fixsfti") @nostrip => fixint(a);
|
||||
macro float_from_i128($Type, a) @private
|
||||
{
|
||||
var $Rep;
|
||||
$switch ($Type):
|
||||
$switch ($Type)
|
||||
$case double:
|
||||
$Rep = ulong;
|
||||
const MANT_DIG = DOUBLE_MANT_DIG;
|
||||
@@ -201,7 +201,7 @@ macro float_from_i128($Type, a) @private
|
||||
$case float128:
|
||||
$Rep = uint128;
|
||||
const MANT_DIG = QUAD_MANT_DIG;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
if (a == 0) return ($Type)0;
|
||||
// Grab and remove sign.
|
||||
int128 sign = a >> 127;
|
||||
@@ -239,7 +239,7 @@ macro float_from_i128($Type, a) @private
|
||||
macro float_from_u128($Type, a) @private
|
||||
{
|
||||
var $Rep;
|
||||
$switch ($Type):
|
||||
$switch ($Type)
|
||||
$case double:
|
||||
$Rep = ulong;
|
||||
const MANT_DIG = DOUBLE_MANT_DIG;
|
||||
@@ -258,7 +258,7 @@ macro float_from_u128($Type, a) @private
|
||||
$case float128:
|
||||
$Rep = uint128;
|
||||
const MANT_DIG = QUAD_MANT_DIG;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
if (a == 0) return ($Type)0;
|
||||
int sd = 128 - (int)$$clz(a); // digits
|
||||
int e = sd - 1; // exponent
|
||||
@@ -294,7 +294,7 @@ macro float_from_u128($Type, a) @private
|
||||
macro fixuint(a) @private
|
||||
{
|
||||
var $Rep;
|
||||
$switch ($typeof(a)):
|
||||
$switch ($typeof(a))
|
||||
$case double:
|
||||
$Rep = ulong;
|
||||
const EXPONENT_BITS = 11;
|
||||
@@ -311,7 +311,7 @@ macro fixuint(a) @private
|
||||
$Rep = uint128;
|
||||
const EXPONENT_BITS = 15;
|
||||
const SIGNIFICANT_BITS = 112;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
const $Rep MAX_EXPONENT = ($Rep)1 << EXPONENT_BITS - 1u;
|
||||
const $Rep EXPONENT_BIAS = MAX_EXPONENT >> 1u;
|
||||
const $Rep ONE_REP =EXPONENT_BIAS << SIGNIFICANT_BITS;
|
||||
@@ -338,7 +338,7 @@ macro fixuint(a) @private
|
||||
macro fixint(a) @private
|
||||
{
|
||||
var $Rep;
|
||||
$switch ($typeof(a)):
|
||||
$switch ($typeof(a))
|
||||
$case double:
|
||||
$Rep = ulong;
|
||||
const EXPONENT_BITS = 11;
|
||||
@@ -355,7 +355,7 @@ macro fixint(a) @private
|
||||
$Rep = uint128;
|
||||
const EXPONENT_BITS = 15;
|
||||
const SIGNIFICANT_BITS = 112;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
const $Rep MAX_EXPONENT = ($Rep)1 << EXPONENT_BITS - 1u;
|
||||
const $Rep EXPONENT_BIAS = MAX_EXPONENT >> 1u;
|
||||
const $Rep ONE_REP = EXPONENT_BIAS << SIGNIFICANT_BITS;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/k_cos.c */
|
||||
/*
|
||||
@@ -31,4 +31,4 @@ fn double __cos(double x, double y) @extern("__cos") @weak @nostrip
|
||||
return w + (((1.0 - w) - hz) + (z * r - x * y));
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/k_cosf.c */
|
||||
/*
|
||||
@@ -33,4 +33,4 @@ fn float __cosdf(double x) @extern("__cosdf") @weak @nostrip
|
||||
return (float)(((1.0f + z * C0) + w * C1) + (w * z) * r);
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/k_sin.c */
|
||||
/*
|
||||
@@ -32,4 +32,4 @@ fn double __sin(double x, double y, int iy) @extern("__sin") @weak @nostrip
|
||||
: x - ((z * (0.5 * y - v * r) - y) - v * S1);
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/k_sinf.c */
|
||||
/*
|
||||
@@ -31,4 +31,4 @@ fn float __sindf(double x) @extern("__sindf") @weak @nostrip
|
||||
return (float)((x + s * (S1F + z * S2F)) + s * w * r);
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/k_tan.c */
|
||||
/*
|
||||
@@ -80,4 +80,4 @@ fn double __tan(double x, double y, int odd) @extern("__tan") @weak @nostrip
|
||||
return a0 + a * (1.0 + a0 * w0 + a0 * v);
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/k_tanf.c */
|
||||
/*
|
||||
@@ -53,4 +53,4 @@ fn float __tandf(double x, int odd) @extern("__tandf") @weak @nostrip
|
||||
return (float)(odd ? -1.0 / r : r);
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc::atan;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
const double[*] ATANHI @private = {
|
||||
4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
|
||||
@@ -321,4 +321,4 @@ fn float _atan2f(float y, float x) @weak @extern("atan2f") @nostrip
|
||||
}
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
fn double _ceil(double x) @weak @extern("ceil") @nostrip
|
||||
{
|
||||
@@ -42,4 +42,4 @@ fn float _ceilf(float x) @weak @extern("ceilf") @nostrip
|
||||
return bitcast(u, float);
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
fn float _cosf(float x) @extern("cosf") @weak @nostrip
|
||||
{
|
||||
@@ -88,4 +88,4 @@ fn double _cos(double x) @extern("cos") @weak @nostrip
|
||||
}
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
macro uint _top12f(float x) @private => bitcast(x, uint) >> 20;
|
||||
|
||||
@@ -141,4 +141,4 @@ fn double _exp2(double x) @extern("exp2") @weak @nostrip
|
||||
is no spurious underflow here even without fma. */
|
||||
return scale + scale * tmp;
|
||||
}
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
fn double _floor(double x) @weak @extern("floor") @nostrip
|
||||
{
|
||||
@@ -42,4 +42,4 @@ fn float _floorf(float x) @weak @extern("floorf") @nostrip
|
||||
return bitcast(u, float);
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
fn float powf_broken(float x, float f) @extern("powf") @weak @nostrip
|
||||
{
|
||||
@@ -12,4 +12,4 @@ fn double pow_broken(double x, double y) @extern("pow") @weak @nostrip
|
||||
unreachable("'pow' not supported");
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::math::nolibc;
|
||||
import std::math;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2f.c */
|
||||
/*
|
||||
@@ -537,4 +537,4 @@ fn int __rem_pio2(double x, double *y)
|
||||
|
||||
|
||||
}
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
fn double _round(double x) @extern("round") @weak @nostrip
|
||||
{
|
||||
@@ -53,4 +53,4 @@ fn float _roundf(float x) @extern("roundf") @weak @nostrip
|
||||
return y;
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
fn double _scalbn(double x, int n) @weak @extern("scalbn") @nostrip
|
||||
{
|
||||
@@ -28,4 +28,4 @@ fn double _scalbn(double x, int n) @weak @extern("scalbn") @nostrip
|
||||
return x * bitcast(((ulong)(0x3ff + n)) << 52, double);
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */
|
||||
/*
|
||||
@@ -119,4 +119,4 @@ fn double sin(double x) @extern("sin") @weak @nostrip
|
||||
}
|
||||
}
|
||||
}
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */
|
||||
/*
|
||||
@@ -156,4 +156,4 @@ fn void sincos(double x, double *sin, double *cos) @extern("sincos") @weak @nost
|
||||
}
|
||||
}
|
||||
}
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/s_tan.c */
|
||||
/*
|
||||
@@ -100,4 +100,4 @@ fn float tanf(float x) @extern("tanf") @weak @nostrip
|
||||
}
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc::trig;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
fn double sincos_broken(double x) @extern("sincos") @weak @nostrip
|
||||
{
|
||||
@@ -8,4 +8,4 @@ fn double sincos_broken(double x) @extern("sincos") @weak @nostrip
|
||||
}
|
||||
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE)
|
||||
|
||||
fn double _trunc(double x) @weak @extern("trunc") @nostrip
|
||||
{
|
||||
@@ -28,4 +28,4 @@ fn float _truncf(float x) @weak @extern("truncf") @nostrip
|
||||
return bitcast(i, float);
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -216,11 +216,11 @@ return v;
|
||||
var view_proj = m1.mul(m2);
|
||||
var invert = view_proj.invert();
|
||||
// Create quaternion from source point
|
||||
$if ($typeof(v[0]).typeid == float.typeid):
|
||||
$if ($typeof(v[0]).typeid == float.typeid)
|
||||
Quaternionf quat = { v.x, v.y, v.z, 1 };
|
||||
$else:
|
||||
$else
|
||||
Quaternion quat = { v.x, v.y, v.z, 1 };
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
// Multiply quat point by unproject matrix
|
||||
var qtransformed = quat.transform(invert);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
module std::net::os;
|
||||
|
||||
$if ($defined(PLATFORM_AF_INET)):
|
||||
$if ($defined(PLATFORM_AF_INET))
|
||||
|
||||
$if (!$defined(PLATFORM_O_NONBLOCK)):
|
||||
$if (!$defined(PLATFORM_O_NONBLOCK))
|
||||
const PLATFORM_O_NONBLOCK = 0;
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
const AI_PASSIVE = 0x1;
|
||||
const AI_CANONNAME = 0x2;
|
||||
@@ -18,4 +18,4 @@ const int AF_INET6 = PLATFORM_AF_INET6;
|
||||
|
||||
const O_NONBLOCK = PLATFORM_O_NONBLOCK;
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::net::os;
|
||||
import libc;
|
||||
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
$if (env::OS_TYPE == OsType.MACOSX)
|
||||
|
||||
const AI_NUMERICSERV = 0x1000;
|
||||
const AI_ALL = 0x100;
|
||||
@@ -64,4 +64,4 @@ const int PLATFORM_AF_MAX = 41;
|
||||
|
||||
const int PLATFORM_O_NONBLOCK = 0x30;
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::net::os;
|
||||
import libc;
|
||||
|
||||
$if (env::OS_TYPE == OsType.LINUX):
|
||||
$if (env::OS_TYPE == OsType.LINUX)
|
||||
|
||||
struct AddrInfo
|
||||
{
|
||||
@@ -28,4 +28,4 @@ const int PLATFORM_AF_INET6 = 10;
|
||||
|
||||
const PLATFORM_O_NONBLOCK = 0o4000;
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::net::os;
|
||||
import libc;
|
||||
|
||||
$if (env::OS_TYPE != OsType.WIN32 && $defined(AddrInfo)):
|
||||
$if (env::OS_TYPE != OsType.WIN32 && $defined(AddrInfo))
|
||||
|
||||
const int F_GETFL = 3;
|
||||
const int F_SETFL = 4;
|
||||
@@ -39,4 +39,4 @@ macro bool NativeSocket.is_non_blocking(NativeSocket this)
|
||||
return fcntl(this, F_GETFL, 0) & O_NONBLOCK == O_NONBLOCK;
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::net::os;
|
||||
|
||||
$if (env::OS_TYPE == OsType.WIN32):
|
||||
$if (env::OS_TYPE == OsType.WIN32)
|
||||
|
||||
const int PLATFORM_AF_INET = 1;
|
||||
const int PLATFORM_AF_IPX = 6;
|
||||
@@ -30,4 +30,4 @@ extern fn int closesocket(NativeSocket);
|
||||
|
||||
macro NativeSocket.close(NativeSocket this) => closesocket(this);
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::os::macos::cf;
|
||||
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
$if (env::OS_TYPE == OsType.MACOSX)
|
||||
|
||||
typedef CFAllocatorRef = distinct void*;
|
||||
typedef CFAllocatorContextRef = distinct void*;
|
||||
@@ -18,4 +18,4 @@ extern fn CFAllocatorRef _macos_CFAllocatorGetDefault() @extern("CFAllocatorGetD
|
||||
extern fn void _macos_CFAllocatorSetDefault(CFAllocatorRef allocator) @extern("CFAllocatorSetDefault");
|
||||
extern fn void* _macos_CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint) @extern("CFAllocatorAllocate");
|
||||
extern fn CFIndex _macos_CFAllocatorGetPreferredSizeForSize(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint) @extern("CFAllocatorGetPreferredSizeForSize");
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::os::macos::cf;
|
||||
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
$if (env::OS_TYPE == OsType.MACOSX)
|
||||
|
||||
typedef CFArrayRef = distinct void*;
|
||||
typedef CFArrayCallBacksRef = distinct void*;
|
||||
@@ -11,4 +11,4 @@ extern fn CFIndex _macos_CFArrayGetCount(CFArrayRef array) @extern("CFArrayGetCo
|
||||
extern fn void _macos_CFArrayAppendArray(CFMutableArrayRef theArray, CFArrayRef otherArray, CFRange otherRange) @extern("CFArrayAppendArray");
|
||||
extern fn CFMutableArrayRef _macos_CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, CFArrayCallBacksRef callBacks) @extern("CFArrayCreateMutable");
|
||||
extern fn void _macos_CFArrayAppendValue(CFMutableArrayRef theArray, void *value) @extern("CFArrayAppendValue");
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::os::macos::cf;
|
||||
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
$if (env::OS_TYPE == OsType.MACOSX)
|
||||
|
||||
typedef CFTypeRef = distinct void*;
|
||||
typedef CFIndex = isz;
|
||||
@@ -13,4 +13,4 @@ struct CFRange
|
||||
extern fn CFTypeRef _macos_CFRetain(CFTypeRef cf) @extern("CFRetain");
|
||||
extern fn void _macos_CFRelease(CFTypeRef cf) @extern("CFRelease");
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::os::macos::objc;
|
||||
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
$if (env::OS_TYPE == OsType.MACOSX)
|
||||
|
||||
typedef Class = distinct void*;
|
||||
typedef Method = distinct void*;
|
||||
@@ -45,5 +45,5 @@ extern fn Method _macos_class_getClassMethod(Class cls, Selector name) @extern("
|
||||
extern fn bool _macos_class_respondsToSelector(Class cls, Selector name) @extern("class_respondsToSelector");
|
||||
extern fn Selector _macos_sel_registerName(char* str) @extern("sel_registerName");
|
||||
extern fn Class _macos_objc_lookUpClass(char* name) @extern("objc_lookUpClass");
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::os::win32::wsa;
|
||||
|
||||
$if (env::OS_TYPE == OsType.WIN32):
|
||||
$if (env::OS_TYPE == OsType.WIN32)
|
||||
extern fn int get_last_error() @extern("WSAGetLastError");
|
||||
extern fn void set_last_error(int error) @extern("WSASetLastError");
|
||||
|
||||
@@ -26,4 +26,4 @@ const int EPROTOTYPE = 10041;
|
||||
const int ENOPROTOOPT = 10042;
|
||||
const int EPROTONOSUPPORT = 10043;
|
||||
const int ESOCKTNOSUPPORT = 10044;
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::os::win32::files;
|
||||
|
||||
$if (env::os_is_win32()):
|
||||
$if (env::os_is_win32())
|
||||
|
||||
enum Win32_GET_FILEEX_INFO_LEVELS
|
||||
{
|
||||
@@ -39,4 +39,4 @@ extern bool _win32_DeleteFileW(Char16* file) @extern("DeleteFileW");
|
||||
extern bool _win32_CopyFileW(Char16* from_file, Char16* to_file, bool no_overwrite) @extern("CopyFileW");
|
||||
extern ulong _win32_GetFullPathNameW(Char16* file_name, ulong buffer_len, Char16* buffer, Char16** file_part) @extern("GetFullPathNameW");
|
||||
*/
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::os::win32::process;
|
||||
|
||||
$if (env::os_is_win32()):
|
||||
$if (env::os_is_win32())
|
||||
|
||||
extern fn bool win32_CreateProcessW(
|
||||
Win32_LPCWSTR lpApplicationName,
|
||||
@@ -15,4 +15,4 @@ extern fn bool win32_CreateProcessW(
|
||||
Win32_LPPROCESS_INFORMATION lpProcessInformation
|
||||
);
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::thread::os;
|
||||
import libc;
|
||||
|
||||
$if (thread::THREAD_MODEL == ThreadModel.POSIX):
|
||||
$if (thread::THREAD_MODEL == ThreadModel.POSIX)
|
||||
|
||||
const PTHREAD_MUTEX_NORMAL = 0;
|
||||
const PTHREAD_MUTEX_ERRORCHECK = 1;
|
||||
@@ -14,21 +14,21 @@ typedef NativeOnceFlag = PthreadOnce;
|
||||
|
||||
typedef Pthread = distinct void*;
|
||||
|
||||
$if (env::OS_TYPE == OsType.LINUX):
|
||||
$if (env::OS_TYPE == OsType.LINUX)
|
||||
typedef PthreadMutex = distinct ulong[5];
|
||||
typedef PthreadAttribute = distinct ulong[7];
|
||||
typedef PthreadMutexAttribute = distinct uint;
|
||||
typedef PthreadCondAttribute = distinct uint;
|
||||
typedef PthreadCond = distinct ulong[6];
|
||||
typedef PthreadOnce = distinct uint;
|
||||
$else:
|
||||
$else
|
||||
typedef PthreadMutex = distinct ulong[8];
|
||||
typedef PthreadMutexAttribute = distinct ulong[2];
|
||||
typedef PthreadAttribute = distinct ulong[8];
|
||||
typedef PthreadCond = distinct ulong[6];
|
||||
typedef PthreadCondAttribute = distinct ulong[8];
|
||||
typedef PthreadOnce = distinct ulong[2];
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
typedef PosixThreadFn = fn void*(void*);
|
||||
|
||||
@@ -236,4 +236,4 @@ fn void! native_sleep(double s)
|
||||
if (libc::nanosleep(&to, null)) return ThreadFault.INTERRUPTED!;
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,6 +1,6 @@
|
||||
module std::thread::os;
|
||||
|
||||
$if (thread::THREAD_MODEL == ThreadModel.WIN32):
|
||||
$if (thread::THREAD_MODEL == ThreadModel.WIN32)
|
||||
|
||||
typedef NativeThread = Win32_HANDLE;
|
||||
|
||||
@@ -346,4 +346,4 @@ fn void! native_sleep_nano(ulong ns)
|
||||
return native_sleep_ms(ns < 1000_000 ? 1 : ns / 1000_000);
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -1,10 +1,10 @@
|
||||
macro int factorial($n)
|
||||
{
|
||||
$if ($n == 0):
|
||||
$if ($n == 0)
|
||||
return 1;
|
||||
$else:
|
||||
$else
|
||||
return $n * factorial($n - 1);
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
extern fn void printf(char *fmt, ...);
|
||||
|
||||
@@ -16,7 +16,7 @@ const uint MaxDepth = 8;
|
||||
|
||||
//#define DEBUG_NODES
|
||||
|
||||
$if (DEBUG_NODES):
|
||||
$if (DEBUG_NODES)
|
||||
|
||||
fn void Blocks.dump(Blocks* b)
|
||||
{
|
||||
@@ -77,7 +77,7 @@ fn void Blocks.dump(Blocks* b)
|
||||
}
|
||||
}
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
/**
|
||||
* @ensure const(a), const(b)
|
||||
@@ -436,7 +436,7 @@ fn const Node* Reader.findNode(const Reader* r, const char* key)
|
||||
Node* node = nil;
|
||||
while (1) {
|
||||
switch (*cp) {
|
||||
case 0:
|
||||
case 0
|
||||
len = cast<u32>(cp - start);
|
||||
mem::copy(name, start, len);
|
||||
name[len] = 0;
|
||||
|
||||
@@ -95,7 +95,7 @@ fn int boo()
|
||||
}
|
||||
switch (eok)
|
||||
{
|
||||
case 1:
|
||||
case 1
|
||||
eok++;
|
||||
next;
|
||||
case 3:
|
||||
|
||||
@@ -143,9 +143,9 @@ $else
|
||||
|
||||
generic boofer2(i, g, eok)
|
||||
{
|
||||
case int, String, type($eoo):
|
||||
case int, String, type($eoo)
|
||||
return "Helo";
|
||||
default:
|
||||
default
|
||||
return 1000;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
module hello_world;
|
||||
import std;
|
||||
import bar;
|
||||
$if (env::OS_TYPE == OsType.WIN32):
|
||||
$if (env::OS_TYPE == OsType.WIN32)
|
||||
fn int test_doubler(int x)
|
||||
{
|
||||
return x * x;
|
||||
}
|
||||
$else:
|
||||
$else
|
||||
extern fn int test_doubler(int);
|
||||
$endif;
|
||||
$endif
|
||||
extern fn void printf(char *, ...);
|
||||
|
||||
fn int main()
|
||||
|
||||
@@ -91,8 +91,10 @@ INLINE bool parse_decl_initializer(ParseContext *c, Decl *decl)
|
||||
*/
|
||||
static inline bool parse_top_level_block(ParseContext *c, Decl ***decls, TokenType end1, TokenType end2, TokenType end3)
|
||||
{
|
||||
// This is the last part consumed by the leading block
|
||||
CONSUME_OR_RET(TOKEN_COLON, false);
|
||||
if (try_consume(c, TOKEN_COLON))
|
||||
{
|
||||
sema_warning_at(c->prev_span, "':' is deprecated here.");
|
||||
}
|
||||
|
||||
// Check whether we reached a terminating token or EOF
|
||||
while (!tok_is(c, end1) && !tok_is(c, end2) && !tok_is(c, end3) && !tok_is(c, TOKEN_EOF))
|
||||
@@ -144,7 +146,10 @@ static inline Decl *parse_ct_if_top_level(ParseContext *c)
|
||||
if (!parse_top_level_block(c, &ct_else->ct_else_decl, TOKEN_CT_ENDIF, TOKEN_CT_ENDIF, TOKEN_CT_ENDIF)) return poisoned_decl;
|
||||
}
|
||||
CONSUME_OR_RET(TOKEN_CT_ENDIF, poisoned_decl);
|
||||
CONSUME_EOS_OR_RET(poisoned_decl);
|
||||
if (try_consume(c, TOKEN_EOS))
|
||||
{
|
||||
sema_warning_at(c->prev_span, "';' is deprecated here.");
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
@@ -174,6 +179,7 @@ static inline Decl *parse_ct_case(ParseContext *c)
|
||||
return poisoned_decl;
|
||||
}
|
||||
// Parse the body
|
||||
CONSUME_OR_RET(TOKEN_COLON, poisoned_decl);
|
||||
if (!parse_top_level_block(c, &decl->ct_case_decl.body, TOKEN_CT_DEFAULT, TOKEN_CT_CASE, TOKEN_CT_ENDSWITCH)) return poisoned_decl;
|
||||
return decl;
|
||||
}
|
||||
@@ -188,14 +194,19 @@ static inline Decl *parse_ct_switch_top_level(ParseContext *c)
|
||||
Decl *ct = decl_new_ct(DECL_CT_SWITCH, c->span);
|
||||
advance_and_verify(c, TOKEN_CT_SWITCH);
|
||||
ASSIGN_EXPR_OR_RET(ct->ct_switch_decl.expr, parse_const_paren_expr(c), poisoned_decl);
|
||||
|
||||
CONSUME_OR_RET(TOKEN_COLON, poisoned_decl);
|
||||
if (try_consume(c, TOKEN_COLON))
|
||||
{
|
||||
sema_warning_at(c->prev_span, "':' is deprecated here.");
|
||||
}
|
||||
while (!try_consume(c, TOKEN_CT_ENDSWITCH))
|
||||
{
|
||||
ASSIGN_DECL_OR_RET(Decl *result, parse_ct_case(c), poisoned_decl);
|
||||
vec_add(ct->ct_switch_decl.cases, result);
|
||||
}
|
||||
CONSUME_EOS_OR_RET(poisoned_decl);
|
||||
if (try_consume(c, TOKEN_EOS))
|
||||
{
|
||||
sema_warning_at(c->prev_span, "';' is deprecated here.");
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
|
||||
@@ -915,7 +915,10 @@ static inline Ast* parse_ct_else_stmt(ParseContext *c)
|
||||
{
|
||||
Ast *ast = new_ast(AST_CT_ELSE_STMT, c->span);
|
||||
advance_and_verify(c, TOKEN_CT_ELSE);
|
||||
TRY_CONSUME_AFTER(TOKEN_COLON, "$else needs a ':', did you forget it?", poisoned_ast);
|
||||
if (try_consume(c, TOKEN_EOS))
|
||||
{
|
||||
sema_warning_at(c->prev_span, "';' is deprecated here.");
|
||||
}
|
||||
if (!parse_ct_compound_stmt(c, &ast->ct_else_stmt)) return poisoned_ast;
|
||||
return ast;
|
||||
}
|
||||
@@ -932,13 +935,9 @@ static inline Ast* parse_ct_if_stmt(ParseContext *c, bool is_elif)
|
||||
Ast *ast = ast_new_curr(c, AST_CT_IF_STMT);
|
||||
advance_and_verify(c, is_elif ? TOKEN_CT_ELIF : TOKEN_CT_IF);
|
||||
ASSIGN_EXPR_OR_RET(ast->ct_if_stmt.expr, parse_const_paren_expr(c), poisoned_ast);
|
||||
if (is_elif)
|
||||
if (try_consume(c, TOKEN_COLON))
|
||||
{
|
||||
TRY_CONSUME_AFTER(TOKEN_COLON, "$elif needs a ':' after the expression, did you forget it?", poisoned_ast);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRY_CONSUME_AFTER(TOKEN_COLON, "$if needs a ':' after the expression, did you forget it?", poisoned_ast);
|
||||
sema_warning_at(c->prev_span, "':' is deprecated here.");
|
||||
}
|
||||
if (!parse_ct_compound_stmt(c, &ast->ct_if_stmt.then)) return poisoned_ast;
|
||||
|
||||
@@ -953,7 +952,10 @@ static inline Ast* parse_ct_if_stmt(ParseContext *c, bool is_elif)
|
||||
if (is_elif) return ast;
|
||||
advance_and_verify(c, TOKEN_CT_ENDIF);
|
||||
RANGE_EXTEND_PREV(ast);
|
||||
CONSUME_EOS_OR_RET(poisoned_ast);
|
||||
if (try_consume(c, TOKEN_EOS))
|
||||
{
|
||||
sema_warning_at(c->prev_span, "';' is deprecated here.");
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
@@ -1007,7 +1009,10 @@ static inline Ast* parse_ct_foreach_stmt(ParseContext *c)
|
||||
TRY_CONSUME_OR_RET(TOKEN_COLON, "Expected ':'.", poisoned_ast);
|
||||
ASSIGN_EXPRID_OR_RET(ast->ct_foreach_stmt.expr, parse_expr(c), poisoned_ast);
|
||||
CONSUME_OR_RET(TOKEN_RPAREN, poisoned_ast);
|
||||
CONSUME_OR_RET(TOKEN_COLON, poisoned_ast);
|
||||
if (try_consume(c, TOKEN_COLON))
|
||||
{
|
||||
sema_warning_at(c->prev_span, "':' is deprecated here.");
|
||||
}
|
||||
Ast *body = new_ast(AST_COMPOUND_STMT, ast->span);
|
||||
ast->ct_foreach_stmt.body = astid(body);
|
||||
AstId *current = &body->compound_stmt.first_stmt;
|
||||
@@ -1017,7 +1022,10 @@ static inline Ast* parse_ct_foreach_stmt(ParseContext *c)
|
||||
*current = astid(stmt);
|
||||
current = &stmt->next;
|
||||
}
|
||||
CONSUME_EOS_OR_RET(poisoned_ast);
|
||||
if (try_consume(c, TOKEN_EOS))
|
||||
{
|
||||
sema_warning_at(c->prev_span, "';' is deprecated here.");
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
@@ -1049,7 +1057,11 @@ static inline Ast* parse_ct_for_stmt(ParseContext *c)
|
||||
|
||||
CONSUME_OR_RET(TOKEN_RPAREN, poisoned_ast);
|
||||
|
||||
CONSUME_OR_RET(TOKEN_COLON, poisoned_ast);
|
||||
if (try_consume(c, TOKEN_COLON))
|
||||
{
|
||||
sema_warning_at(c->prev_span, "':' is deprecated here.");
|
||||
}
|
||||
|
||||
Ast *body = new_ast(AST_COMPOUND_STMT, ast->span);
|
||||
ast->for_stmt.body = astid(body);
|
||||
AstId *current = &body->compound_stmt.first_stmt;
|
||||
@@ -1059,7 +1071,10 @@ static inline Ast* parse_ct_for_stmt(ParseContext *c)
|
||||
*current = astid(stmt);
|
||||
current = &stmt->next;
|
||||
}
|
||||
CONSUME_EOS_OR_RET(poisoned_ast);
|
||||
if (try_consume(c, TOKEN_EOS))
|
||||
{
|
||||
sema_warning_at(c->prev_span, "';' is deprecated here.");
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
@@ -1083,7 +1098,11 @@ static inline Ast* parse_ct_switch_stmt(ParseContext *c)
|
||||
Ast *ast = ast_new_curr(c, AST_CT_SWITCH_STMT);
|
||||
advance_and_verify(c, TOKEN_CT_SWITCH);
|
||||
ASSIGN_EXPRID_OR_RET(ast->ct_switch_stmt.cond, parse_const_paren_expr(c), poisoned_ast);
|
||||
TRY_CONSUME(TOKEN_COLON, "Expected ':' after $switch expression, did you forget it?");
|
||||
if (try_consume(c, TOKEN_COLON))
|
||||
{
|
||||
sema_warning_at(c->prev_span, "':' is deprecated here.");
|
||||
}
|
||||
|
||||
Ast **cases = NULL;
|
||||
while (!try_consume(c, TOKEN_CT_ENDSWITCH))
|
||||
{
|
||||
@@ -1104,14 +1123,9 @@ static inline Ast* parse_ct_switch_stmt(ParseContext *c)
|
||||
}
|
||||
vec_add(cases, result);
|
||||
}
|
||||
do
|
||||
if (try_consume(c, TOKEN_EOS))
|
||||
{
|
||||
if (!tok_is(c, TOKEN_EOS))
|
||||
{
|
||||
sema_error_at_after(c->prev_span, "Expected ';'");
|
||||
return poisoned_ast;
|
||||
}
|
||||
advance(c);
|
||||
sema_warning_at(c->prev_span, "';' is deprecated here.");
|
||||
}
|
||||
while (0);
|
||||
ast->ct_switch_stmt.body = cases;
|
||||
|
||||
@@ -11,9 +11,9 @@ const int* BOB = (int*)16 - 1;
|
||||
const int* BAB = (int*)16 + 1;
|
||||
const isz AO = BAB - BOB;
|
||||
|
||||
$if (ZAB > 100):
|
||||
$if (ZAB > 100)
|
||||
int abc = 123;
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
fn void test()
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ enum Vehicles
|
||||
macro elements($Type)
|
||||
{
|
||||
int x;
|
||||
$foreach ($x : $Type.values):
|
||||
$foreach ($x : $Type.values)
|
||||
x = (int)$x;
|
||||
$endforeach;
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@ extern fn void printf(char*, ...);
|
||||
fn void main()
|
||||
{
|
||||
|
||||
$for (var $i = 0; $i < 3; $i++):
|
||||
$for (var $i = 0; $i < 3; $i++)
|
||||
printf("Foo %d\n", $i);
|
||||
$endfor;
|
||||
|
||||
$for ($i = 0, var $j = 100; $i < 4;):
|
||||
$for ($i = 0, var $j = 100; $i < 4;)
|
||||
printf("Foo %d %d\n", $i++, $j--);
|
||||
$endfor;
|
||||
|
||||
|
||||
@@ -7,22 +7,22 @@ fn void main()
|
||||
{
|
||||
|
||||
var $foo = { 1, 10, 34 };
|
||||
$foreach ($i : $foo):
|
||||
$foreach ($i : $foo)
|
||||
printf("Foo %d\n", $i);
|
||||
$endforeach;
|
||||
|
||||
$foreach ($i, $j : $foo):
|
||||
$foreach ($i, $j : $foo)
|
||||
printf("Bar %d %d\n", $i, $j);
|
||||
$endforeach;
|
||||
|
||||
$foreach ($x : { 123, "abc", 1177, "hello" }):
|
||||
$foreach ($x : { 123, "abc", 1177, "hello" })
|
||||
$typeof($x) z = $x;
|
||||
$switch ($typeof($x)):
|
||||
$switch ($typeof($x))
|
||||
$case int:
|
||||
printf("Bar %d\n", $x);
|
||||
$default:
|
||||
printf("Bar %s\n", $x);
|
||||
$endswitch;
|
||||
$endswitch
|
||||
$endforeach;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,60 +1,60 @@
|
||||
$if (0):
|
||||
$else:
|
||||
$if (0):
|
||||
$elif (0):
|
||||
$elif (0):
|
||||
$else:
|
||||
$if (0)
|
||||
$else
|
||||
$if (0)
|
||||
$elif (0)
|
||||
$elif (0)
|
||||
$else
|
||||
int x = 1;
|
||||
$endif;
|
||||
$endif;
|
||||
$endif
|
||||
$endif
|
||||
|
||||
$if (0):
|
||||
$if (0)
|
||||
$assert(false);
|
||||
$elif (0):
|
||||
$elif (0)
|
||||
$assert(false);
|
||||
$else:
|
||||
$else
|
||||
$assert(true);
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
$if (1):
|
||||
$if (1)
|
||||
$assert(true);
|
||||
int d = 5;
|
||||
$elif (0):
|
||||
$elif (0)
|
||||
$assert(false);
|
||||
$else:
|
||||
$else
|
||||
$assert(false);
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
$if (0):
|
||||
$if (0)
|
||||
$assert(true);
|
||||
$elif (1):
|
||||
$elif (1)
|
||||
$assert(true);
|
||||
int c = 5;
|
||||
$else:
|
||||
$else
|
||||
$assert(false);
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
$if (0):
|
||||
$if (0)
|
||||
$assert(true);
|
||||
$elif (1):
|
||||
$elif (1)
|
||||
$assert(true);
|
||||
int b = 4;
|
||||
$elif (0):
|
||||
$elif (0)
|
||||
$assert(false);
|
||||
$else:
|
||||
$else
|
||||
$assert(false);
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
$if (0):
|
||||
$if (0)
|
||||
$assert(true);
|
||||
$elif (0):
|
||||
$elif (0)
|
||||
$assert(false);
|
||||
$elif (1):
|
||||
$elif (1)
|
||||
$assert(true);
|
||||
int a = 3;
|
||||
$else:
|
||||
$else
|
||||
$assert(false);
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
// #expect: ct_if.ll
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
int x;
|
||||
$if (x > 0):
|
||||
$endif;
|
||||
$if (x > 0)
|
||||
$endif
|
||||
|
||||
$if (0):
|
||||
$if (0)
|
||||
$assert(false);
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
$if (1):
|
||||
$else:
|
||||
$endif;
|
||||
$if (1)
|
||||
$else
|
||||
$endif
|
||||
|
||||
$if (1):
|
||||
$else:
|
||||
$else: // #error: Expected the start of a global declaration here
|
||||
$endif;
|
||||
$if (1)
|
||||
$else
|
||||
$else // #error: Expected the start of a global declaration here
|
||||
$endif
|
||||
|
||||
|
||||
$if (1):
|
||||
$elif (2):
|
||||
$else:
|
||||
$endif;
|
||||
$if (1)
|
||||
$elif (2)
|
||||
$else
|
||||
$endif
|
||||
|
||||
$if (1):
|
||||
$elif (2):
|
||||
$elif (3):
|
||||
$else:
|
||||
$endif;
|
||||
$if (1)
|
||||
$elif (2)
|
||||
$elif (3)
|
||||
$else
|
||||
$endif
|
||||
|
||||
@@ -7,7 +7,7 @@ fn int hell() { return 1; }
|
||||
macro print_args($Type)
|
||||
{
|
||||
var $params = $Type.params;
|
||||
$foreach ($param : $params):
|
||||
$foreach ($param : $params)
|
||||
io::printn($param.nameof);
|
||||
$endforeach;
|
||||
}
|
||||
@@ -35,7 +35,7 @@ macro print_fields($Type)
|
||||
{
|
||||
io::printfn("Type: %s", $Type.nameof);
|
||||
var $params = $Type.membersof;
|
||||
$foreach ($param : $params):
|
||||
$foreach ($param : $params)
|
||||
io::printfn("%s: %s", $param.nameof, $param.typeid.nameof);
|
||||
$endforeach;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ module test;
|
||||
|
||||
macro getisprime($x)
|
||||
{
|
||||
$switch ($x):
|
||||
$switch ($x)
|
||||
$case 1:
|
||||
$case 2:
|
||||
$case 3:
|
||||
@@ -23,7 +23,7 @@ macro getisprime($x)
|
||||
$case 17:
|
||||
$default:
|
||||
return "donnowifprime";
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
extern fn void printf(char*, ...);
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
|
||||
fn void test()
|
||||
{
|
||||
$switch (3):
|
||||
$switch (3)
|
||||
$case 2:
|
||||
return;
|
||||
$default:
|
||||
$default: // #error: More than one $default is not allowed
|
||||
return;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
fn void test1()
|
||||
{
|
||||
$switch (-1):
|
||||
$switch (-1)
|
||||
$case -1:
|
||||
return;
|
||||
$case -1: // #error: '-1' appears more than once
|
||||
return;
|
||||
$default:
|
||||
return;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
|
||||
fn void test3()
|
||||
{
|
||||
$switch (3):
|
||||
$switch (3)
|
||||
$case 3:
|
||||
return;
|
||||
$case 123.0: // #error: 'int'
|
||||
return;
|
||||
$default:
|
||||
return;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
@@ -4,23 +4,23 @@ import std::io;
|
||||
fn void foo()
|
||||
{
|
||||
int a;
|
||||
$switch ($typeof(a)):
|
||||
$switch ($typeof(a))
|
||||
$case int..float: // #error: $case ranges are only allowed for floats
|
||||
io::printn("Hello");
|
||||
$default:
|
||||
io::printn("World");
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
fn void foo2()
|
||||
{
|
||||
int a;
|
||||
$switch ($typeof(a)):
|
||||
$switch ($typeof(a))
|
||||
$case true..false: // #error: $case ranges are only allowed
|
||||
io::printn("Hello");
|
||||
$default:
|
||||
io::printn("World");
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
fn void foo3()
|
||||
@@ -31,18 +31,18 @@ fn void foo3()
|
||||
io::printn("Hello");
|
||||
$default:
|
||||
io::printn("World");
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
int a;
|
||||
$switch ("abc"):
|
||||
$switch ("abc")
|
||||
$case "cde":
|
||||
io::printn("!!!");
|
||||
$case "abc":
|
||||
io::printn("Hello");
|
||||
$default:
|
||||
io::printn("World");
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
@@ -6,21 +6,21 @@ extern fn void printf(char*, ...);
|
||||
macro tester()
|
||||
{
|
||||
var $Type = int;
|
||||
$switch ($Type):
|
||||
$switch ($Type)
|
||||
$case int:
|
||||
printf("Hello\n");
|
||||
int z = 0;
|
||||
$default:
|
||||
int j = 213;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
|
||||
}
|
||||
$switch (bool.typeid):
|
||||
$switch (bool.typeid)
|
||||
$case int:
|
||||
int oefke = 23;
|
||||
$default:
|
||||
int oeoekgokege = 343432;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
|
||||
fn int main()
|
||||
{
|
||||
|
||||
@@ -4,14 +4,14 @@ module test;
|
||||
|
||||
macro get_type($Type)
|
||||
{
|
||||
$switch ($Type.typeid):
|
||||
$switch ($Type.typeid)
|
||||
$case int:
|
||||
return "int";
|
||||
$case double:
|
||||
return "double";
|
||||
$default:
|
||||
return "any other";
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
extern fn void printf(char*, ...);
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
|
||||
fn void test()
|
||||
{
|
||||
$switch (int.typeid):
|
||||
$switch (int.typeid)
|
||||
$case int:
|
||||
return;
|
||||
$default:
|
||||
$default: // #error: More than one $default is not allowed
|
||||
return;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
fn void test1()
|
||||
{
|
||||
$switch (int.typeid):
|
||||
$switch (int.typeid)
|
||||
$case int:
|
||||
return;
|
||||
$case int: // #error: 'int' appears more than once
|
||||
return;
|
||||
$default:
|
||||
return;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
typedef Foo = int;
|
||||
typedef Bar = double;
|
||||
fn void test2()
|
||||
{
|
||||
$switch (int.typeid):
|
||||
$switch (int.typeid)
|
||||
$case int:
|
||||
return;
|
||||
$case Bar:
|
||||
@@ -35,17 +35,17 @@ fn void test2()
|
||||
return;
|
||||
$default:
|
||||
return;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
fn void test3()
|
||||
{
|
||||
$switch (int.typeid):
|
||||
$switch (int.typeid)
|
||||
$case int:
|
||||
return;
|
||||
$case 123: // #error: A type was expected here not 'int'
|
||||
return;
|
||||
$default:
|
||||
return;
|
||||
$endswitch;
|
||||
$endswitch
|
||||
}
|
||||
@@ -8,16 +8,16 @@ macro @timeit(#call)
|
||||
long t = (long)libc::clock();
|
||||
var $Type = $typeof(#call);
|
||||
var $is_void = $Type.typeid == void.typeid;
|
||||
$if ($is_void):
|
||||
$if ($is_void)
|
||||
#call;
|
||||
$else:
|
||||
$else
|
||||
$Type result = #call;
|
||||
$endif;
|
||||
$endif
|
||||
long diff = (long)libc::clock() - t;
|
||||
libc::printf("'%s' took %lld us\n", $stringify(#call), diff);
|
||||
$if (!$is_void):
|
||||
$if (!$is_void)
|
||||
return result;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn void test()
|
||||
|
||||
@@ -17,44 +17,44 @@ fn void main()
|
||||
{
|
||||
int x = 0;
|
||||
var $counter = 0;
|
||||
$if ($defined(x)):
|
||||
$if ($defined(x))
|
||||
x++;
|
||||
$counter++;
|
||||
$endif;
|
||||
$if ($defined(Foo.ab)):
|
||||
$endif
|
||||
$if ($defined(Foo.ab))
|
||||
int y = 10;
|
||||
$counter++;
|
||||
x++;
|
||||
$endif;
|
||||
$if ($defined(Foo.ab.x)):
|
||||
$endif
|
||||
$if ($defined(Foo.ab.x))
|
||||
x = 0;
|
||||
$counter = 0;
|
||||
$endif;
|
||||
$if ($defined(Foo.bob)):
|
||||
$endif
|
||||
$if ($defined(Foo.bob))
|
||||
x++;
|
||||
$counter++;
|
||||
$endif;
|
||||
$if ($defined($eval("x"))):
|
||||
$endif
|
||||
$if ($defined($eval("x")))
|
||||
x++;
|
||||
$counter++;
|
||||
$endif;
|
||||
$if ($defined($evaltype("Foo").$eval("ab"))):
|
||||
$endif
|
||||
$if ($defined($evaltype("Foo").$eval("ab")))
|
||||
x++;
|
||||
$counter++;
|
||||
$endif;
|
||||
$if ($defined($evaltype("mymodule::Foo").$eval("bob"))):
|
||||
$endif
|
||||
$if ($defined($evaltype("mymodule::Foo").$eval("bob")))
|
||||
x++;
|
||||
$counter++;
|
||||
$endif;
|
||||
$if ($defined(y)):
|
||||
$endif
|
||||
$if ($defined(y))
|
||||
x++;
|
||||
$counter++;
|
||||
y = 1;
|
||||
$endif;
|
||||
$if ($defined(z)):
|
||||
$endif
|
||||
$if ($defined(z))
|
||||
$counter = 0;
|
||||
x = 0;
|
||||
$endif;
|
||||
$endif
|
||||
int z = $counter;
|
||||
printf("%d\n", x);
|
||||
}
|
||||
|
||||
@@ -3,18 +3,18 @@ module test;
|
||||
|
||||
macro foo()
|
||||
{
|
||||
$if ($defined(A)):
|
||||
$if ($defined(A))
|
||||
return A + 1;
|
||||
$else:
|
||||
$else
|
||||
return 1;
|
||||
$endif;
|
||||
$endif
|
||||
}
|
||||
|
||||
const Z = foo();
|
||||
|
||||
$if (!$defined(A) && Z == 1):
|
||||
$if (!$defined(A) && Z == 1)
|
||||
const A = 222;
|
||||
$endif;
|
||||
$endif
|
||||
|
||||
const B = foo();
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import std::io;
|
||||
|
||||
macro print_type_info(...)
|
||||
{
|
||||
$for (var $i = 0; $i < $vacount; $i++):
|
||||
$for (var $i = 0; $i < $vacount; $i++)
|
||||
io::printfn("type: %s", $vatype($i).nameof);
|
||||
io::printfn("%s.sizeof = %d", $vatype($i).nameof, $vatype($i).sizeof);
|
||||
io::printfn("%s.min = %s", $vatype($i).nameof, $vatype($i).min);
|
||||
|
||||
@@ -2,8 +2,8 @@ module foo;
|
||||
|
||||
fn void hello() {}
|
||||
|
||||
$if (true):
|
||||
$if (true)
|
||||
|
||||
import bar; // #error: 'import' may not appear inside a compile
|
||||
|
||||
$endif;
|
||||
$endif
|
||||
@@ -11,9 +11,9 @@ macro checker(int x, $i)
|
||||
{
|
||||
for (int i = 0; i < $indent; i++) printf(" ");
|
||||
printf("Helo %d\n", x);
|
||||
$if ($i > 0):
|
||||
$if ($i > 0)
|
||||
checker(x, $i - 1);
|
||||
$endif;
|
||||
$endif
|
||||
if (x % 2 == 0) break FOO;
|
||||
}
|
||||
for (int i = 0; i < $indent; i++) printf(" ");
|
||||
|
||||
@@ -8,14 +8,14 @@ macro @foo(...)
|
||||
{
|
||||
int i = $vaarg(1) + $vaarg(1);
|
||||
int j = $vaexpr(2) + $vaexpr(2);
|
||||
$for (var $i = 0; $i < $vacount; $i++):
|
||||
$for (var $i = 0; $i < $vacount; $i++)
|
||||
io::printfn("%d", $vaarg($i));
|
||||
$endfor;
|
||||
}
|
||||
|
||||
macro foo2(...)
|
||||
{
|
||||
$for (var $i = 0; $i < $vacount; $i++):
|
||||
$for (var $i = 0; $i < $vacount; $i++)
|
||||
{
|
||||
$vatype($i) x;
|
||||
}
|
||||
@@ -26,7 +26,7 @@ macro foo2(...)
|
||||
macro foo3(...)
|
||||
{
|
||||
var $x = 0;
|
||||
$for (var $i = 0; $i < $vacount; $i++):
|
||||
$for (var $i = 0; $i < $vacount; $i++)
|
||||
$x += $vaconst($i);
|
||||
$endfor;
|
||||
return $x;
|
||||
|
||||
@@ -6,35 +6,35 @@ macro testbitcast(expr, $Type)
|
||||
$Type x @noinit;
|
||||
var $size = (usz)($sizeof(expr));
|
||||
|
||||
$if ($alignof(expr) >= 8 && $Type.alignof >= 8):
|
||||
$if ($alignof(expr) >= 8 && $Type.alignof >= 8)
|
||||
ulong *b = (ulong*)(&expr);
|
||||
ulong *to = (ulong*)(&x);
|
||||
for (usz i = 0; i < $size; i += 8)
|
||||
{
|
||||
to[i] = b[i];
|
||||
}
|
||||
$elif ($alignof(expr) >= 4 && $Type.alignof >= 4):
|
||||
$elif ($alignof(expr) >= 4 && $Type.alignof >= 4)
|
||||
uint* b = (uint*)(&expr);
|
||||
uint* to = (uint*)(&x);
|
||||
for (usz i = 0; i < $size; i += 4)
|
||||
{
|
||||
to[i] = b[i];
|
||||
}
|
||||
$elif ($alignof(expr) >= 2 && $Type.alignof >= 2):
|
||||
$elif ($alignof(expr) >= 2 && $Type.alignof >= 2)
|
||||
ushort* b = (ushort*)(&expr);
|
||||
ushort* to = (ushort*)(&x);
|
||||
for (usz i = 0; i < $size; i += 2)
|
||||
{
|
||||
to[i] = b[i];
|
||||
}
|
||||
$else:
|
||||
$else
|
||||
char* b = (char*)(&expr);
|
||||
char* to = (char*)(&x);
|
||||
for (usz i = 0; i < $size; i++)
|
||||
{
|
||||
to[i] = b[i];
|
||||
}
|
||||
$endif;
|
||||
$endif
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user