Added @rnd() compile time random function (using the $$rnd() builtin). #2078

This commit is contained in:
Christoffer Lerno
2025-05-15 00:51:33 +02:00
parent 24ebe975d8
commit b83e57b952
7 changed files with 31 additions and 0 deletions

View File

@@ -30,6 +30,14 @@ typedef EmptySlot = void*;
macro @is_empty_macro_slot(#arg) @const @builtin => @typeis(#arg, EmptySlot);
macro @is_valid_macro_slot(#arg) @const @builtin => !@typeis(#arg, EmptySlot);
<*
Returns a random value at compile time.
@ensure return >= 0.0 && return < 1.0
@return "A compile time random"
*>
macro @rnd() @const @builtin => $$rnd();
/*
Use `IteratorResult` when reading the end of an iterator, or accessing a result out of bounds.
*/

View File

@@ -8,6 +8,7 @@
- Deprecate uXX and iXX bit suffixes.
- Add experimental LL / ULL suffixes for int128 and uint128 literals.
- Allow the right hand side of `|||` and `&&&` be runtime values.
- Added `@rnd()` compile time random function (using the `$$rnd()` builtin). #2078
### Fixes
- Assert triggered when casting from `int[2]` to `uint[2]` #2115

View File

@@ -487,6 +487,7 @@ typedef enum
BUILTIN_REVERSE,
BUILTIN_RETURNADDRESS,
BUILTIN_RINT,
BUILTIN_RND,
BUILTIN_ROUND,
BUILTIN_ROUNDEVEN,
BUILTIN_SAT_ADD,

View File

@@ -1009,6 +1009,7 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
case BUILTIN_STR_FIND:
case BUILTIN_WIDESTRING_16:
case BUILTIN_WIDESTRING_32:
case BUILTIN_RND:
UNREACHABLE
case BUILTIN_NONE:
UNREACHABLE

View File

@@ -289,6 +289,20 @@ static bool sema_expr_analyse_syscall(SemaContext *context, Expr *expr)
return true;
}
uint64_t rand_u64()
{
return ((uint64_t)rand() << 48) ^ ((uint64_t)rand() << 32) ^ ((uint64_t)rand() << 16) ^ rand();
}
bool sema_expr_analyse_rnd(SemaContext *context UNUSED, Expr *expr)
{
uint64_t r = rand_u64();
uint64_t mantissa = r >> 11;
double val = (double)mantissa / (double)(1ULL << 53); // Not secure random but...
expr_rewrite_const_float(expr, type_double, val);
return true;
}
bool sema_expr_analyse_str_hash(SemaContext *context, Expr *expr)
{
Expr *inner = expr->call_expr.arguments[0];
@@ -516,6 +530,8 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
switch (func)
{
case BUILTIN_RND:
return sema_expr_analyse_rnd(context, expr);
case BUILTIN_STR_HASH:
return sema_expr_analyse_str_hash(context, expr);
case BUILTIN_STR_UPPER:
@@ -1124,6 +1140,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
case BUILTIN_TRAP:
case BUILTIN_BREAKPOINT:
case BUILTIN_UNREACHABLE:
case BUILTIN_RND:
UNREACHABLE
}
expr->type = type_add_optional(rtype, optional);
@@ -1147,6 +1164,7 @@ static inline int builtin_expected_args(BuiltinFunction func)
case BUILTIN_TRAP:
case BUILTIN_BREAKPOINT:
case BUILTIN_UNREACHABLE:
case BUILTIN_RND:
return 0;
case BUILTIN_ABS:
case BUILTIN_BITREVERSE:

View File

@@ -261,6 +261,7 @@ void symtab_init(uint32_t capacity)
builtin_list[BUILTIN_REVERSE] = KW_DEF("reverse");
builtin_list[BUILTIN_RETURNADDRESS] = KW_DEF("returnaddress");
builtin_list[BUILTIN_RINT] = KW_DEF("rint");
builtin_list[BUILTIN_RND] = KW_DEF("rnd");
builtin_list[BUILTIN_ROUND] = KW_DEF("round");
builtin_list[BUILTIN_ROUNDEVEN] = KW_DEF("roundeven");
builtin_list[BUILTIN_SAT_ADD] = KW_DEF("sat_add");

View File

@@ -25,6 +25,7 @@ const char *compiler_exe_name;
int main_real(int argc, const char *argv[])
{
srand((unsigned int)time(NULL));
compiler_exe_name = argv[0];
bench_begin();