Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions src/Lua/Standard/MathematicsLibrary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,23 +224,34 @@ public ValueTask<int> Rad(LuaFunctionExecutionContext context, Memory<LuaValue>
public ValueTask<int> Random(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
{
var rand = context.State.Environment[RandomInstanceKey].Read<RandomUserData>().Random;

// When we call it without arguments, it returns a pseudo-random real number with uniform distribution in the interval [0,1
if (context.ArgumentCount == 0)
{
buffer.Span[0] = rand.NextDouble();
}
// When we call it with only one argument, an integer n, it returns an integer pseudo-random number such that 1 <= x <= n.
// This is different from the C# random functions.
// See: https://www.lua.org/pil/18.html
else if (context.ArgumentCount == 1)
{
var arg0 = context.GetArgument<double>(0);
buffer.Span[0] = rand.NextDouble() * (arg0 - 1) + 1;
var arg0 = context.GetArgument<int>(0);
if (arg0 < 0)
{
LuaRuntimeException.BadArgument(context.State.GetTraceback(), 0, "random");
}
buffer.Span[0] = rand.Next(1, arg0 + 1);
}
// Finally, we can call random with two integer arguments, l and u, to get a pseudo-random integer x such that l <= x <= u.
else
{
var arg0 = context.GetArgument<double>(0);
var arg1 = context.GetArgument<double>(1);
buffer.Span[0] = rand.NextDouble() * (arg1 - arg0) + arg0;
var arg0 = context.GetArgument<int>(0);
var arg1 = context.GetArgument<int>(1);
if (arg0 < 1 || arg1 <= arg0)
{
LuaRuntimeException.BadArgument(context.State.GetTraceback(), 1, "random");
}
buffer.Span[0] = rand.Next(arg0, arg1 + 1);
}

return new(1);
}

Expand Down