namespace Lua.Standard; public sealed class MathematicsLibrary { public static readonly MathematicsLibrary Instance = new(); public const string RandomInstanceKey = "__lua_mathematics_library_random_instance"; public MathematicsLibrary() { var libraryName = "math"; Functions = [ new(libraryName, "abs", Abs), new(libraryName, "acos", Acos), new(libraryName, "asin", Asin), new(libraryName, "atan2", Atan2), new(libraryName, "atan", Atan), new(libraryName, "ceil", Ceil), new(libraryName, "cos", Cos), new(libraryName, "cosh", Cosh), new(libraryName, "deg", Deg), new(libraryName, "exp", Exp), new(libraryName, "floor", Floor), new(libraryName, "fmod", Fmod), new(libraryName, "frexp", Frexp), new(libraryName, "ldexp", Ldexp), new(libraryName, "log", Log), new(libraryName, "max", Max), new(libraryName, "min", Min), new(libraryName, "modf", Modf), new(libraryName, "pow", Pow), new(libraryName, "rad", Rad), new(libraryName, "random", Random), new(libraryName, "randomseed", RandomSeed), new(libraryName, "sin", Sin), new(libraryName, "sinh", Sinh), new(libraryName, "sqrt", Sqrt), new(libraryName, "tan", Tan), new(libraryName, "tanh", Tanh) ]; } public readonly LibraryFunction[] Functions; public sealed class RandomUserData(Random random) : ILuaUserData { LuaTable? SharedMetatable; public LuaTable? Metatable { get => SharedMetatable; set => SharedMetatable = value; } public Random Random { get; } = random; } public ValueTask Abs(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Abs(arg0))); } public ValueTask Acos(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Acos(arg0))); } public ValueTask Asin(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Asin(arg0))); } public ValueTask Atan2(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); var arg1 = context.GetArgument(1); return new(context.Return(Math.Atan2(arg0, arg1))); } public ValueTask Atan(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Atan(arg0))); } public ValueTask Ceil(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Ceiling(arg0))); } public ValueTask Cos(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Cos(arg0))); } public ValueTask Cosh(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Cosh(arg0))); } public ValueTask Deg(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(arg0 * (180.0 / Math.PI))); } public ValueTask Exp(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Exp(arg0))); } public ValueTask Floor(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Floor(arg0))); } public ValueTask Fmod(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); var arg1 = context.GetArgument(1); return new(context.Return(arg0 % arg1)); } public ValueTask Frexp(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); var (m, e) = MathEx.Frexp(arg0); return new(context.Return(m, e)); } public ValueTask Ldexp(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); var arg1 = context.GetArgument(1); return new(context.Return(arg0 * Math.Pow(2, arg1))); } public ValueTask Log(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); if (context.ArgumentCount == 1) { return new(context.Return(Math.Log(arg0))); } else { var arg1 = context.GetArgument(1); return new(context.Return(Math.Log(arg0, arg1))); } } public ValueTask Max(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var x = context.GetArgument(0); for (var i = 1; i < context.ArgumentCount; i++) { x = Math.Max(x, context.GetArgument(i)); } return new(context.Return(x)); } public ValueTask Min(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var x = context.GetArgument(0); for (var i = 1; i < context.ArgumentCount; i++) { x = Math.Min(x, context.GetArgument(i)); } return new(context.Return(x)); } public ValueTask Modf(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); var (i, f) = MathEx.Modf(arg0); return new(context.Return(i, f)); } public ValueTask Pow(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); var arg1 = context.GetArgument(1); return new(context.Return(Math.Pow(arg0, arg1))); } public ValueTask Rad(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(arg0 * (Math.PI / 180.0))); } public ValueTask Random(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var rand = context.GlobalState.Environment[RandomInstanceKey].Read().Random; if (context.ArgumentCount == 0) { return new(context.Return(rand.NextDouble())); } else if (context.ArgumentCount == 1) { var arg0 = context.GetArgument(0); return new(context.Return((rand.NextDouble() * (arg0 - 1)) + 1)); } else { var arg0 = context.GetArgument(0); var arg1 = context.GetArgument(1); return new(context.Return((rand.NextDouble() * (arg1 - arg0)) + arg0)); } } public ValueTask RandomSeed(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); context.GlobalState.Environment[RandomInstanceKey] = new(new RandomUserData(new((int)BitConverter.DoubleToInt64Bits(arg0)))); return new(context.Return()); } public ValueTask Sin(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Sin(arg0))); } public ValueTask Sinh(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Sinh(arg0))); } public ValueTask Sqrt(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Sqrt(arg0))); } public ValueTask Tan(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Tan(arg0))); } public ValueTask Tanh(LuaFunctionExecutionContext context, CancellationToken cancellationToken) { var arg0 = context.GetArgument(0); return new(context.Return(Math.Tanh(arg0))); } }