From 9717142b4e713e25e0afdf655b1a7c42699ff32e Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Sat, 21 Sep 2024 15:35:13 +0900 Subject: [PATCH] Add: mathematics library --- src/Lua/Internal/MathEx.cs | 38 +++++++++++++++ src/Lua/Standard/Mathematics/AbsFunction.cs | 16 +++++++ src/Lua/Standard/Mathematics/AcosFuncion.cs | 16 +++++++ src/Lua/Standard/Mathematics/AsinFuncion.cs | 16 +++++++ src/Lua/Standard/Mathematics/Atan2Function.cs | 18 ++++++++ src/Lua/Standard/Mathematics/AtanFuncion.cs | 16 +++++++ src/Lua/Standard/Mathematics/CeilFuncion.cs | 16 +++++++ src/Lua/Standard/Mathematics/CosFuncion.cs | 16 +++++++ src/Lua/Standard/Mathematics/CoshFuncion.cs | 16 +++++++ src/Lua/Standard/Mathematics/DegFunction.cs | 16 +++++++ src/Lua/Standard/Mathematics/ExpFuncion.cs | 16 +++++++ src/Lua/Standard/Mathematics/FloorFuncion.cs | 16 +++++++ src/Lua/Standard/Mathematics/FmodFunction.cs | 17 +++++++ src/Lua/Standard/Mathematics/FrexpFunction.cs | 19 ++++++++ src/Lua/Standard/Mathematics/LdexpFunction.cs | 18 ++++++++ src/Lua/Standard/Mathematics/LogFunction.cs | 26 +++++++++++ src/Lua/Standard/Mathematics/MaxFunction.cs | 22 +++++++++ src/Lua/Standard/Mathematics/MinFunction.cs | 22 +++++++++ src/Lua/Standard/Mathematics/ModfFunction.cs | 18 ++++++++ src/Lua/Standard/Mathematics/PowFunction.cs | 18 ++++++++ src/Lua/Standard/Mathematics/RadFunction.cs | 16 +++++++ .../Standard/Mathematics/RandomFunction.cs | 33 +++++++++++++ .../Mathematics/RandomSeedFunction.cs | 16 +++++++ src/Lua/Standard/Mathematics/SinFuncion.cs | 16 +++++++ src/Lua/Standard/Mathematics/SinhFuncion.cs | 15 ++++++ src/Lua/Standard/Mathematics/SqrtFunction.cs | 16 +++++++ src/Lua/Standard/Mathematics/TanFunction.cs | 16 +++++++ src/Lua/Standard/Mathematics/TanhFunction.cs | 16 +++++++ src/Lua/Standard/OpenLibExtensions.cs | 46 +++++++++++++++++++ 29 files changed, 566 insertions(+) create mode 100644 src/Lua/Standard/Mathematics/AbsFunction.cs create mode 100644 src/Lua/Standard/Mathematics/AcosFuncion.cs create mode 100644 src/Lua/Standard/Mathematics/AsinFuncion.cs create mode 100644 src/Lua/Standard/Mathematics/Atan2Function.cs create mode 100644 src/Lua/Standard/Mathematics/AtanFuncion.cs create mode 100644 src/Lua/Standard/Mathematics/CeilFuncion.cs create mode 100644 src/Lua/Standard/Mathematics/CosFuncion.cs create mode 100644 src/Lua/Standard/Mathematics/CoshFuncion.cs create mode 100644 src/Lua/Standard/Mathematics/DegFunction.cs create mode 100644 src/Lua/Standard/Mathematics/ExpFuncion.cs create mode 100644 src/Lua/Standard/Mathematics/FloorFuncion.cs create mode 100644 src/Lua/Standard/Mathematics/FmodFunction.cs create mode 100644 src/Lua/Standard/Mathematics/FrexpFunction.cs create mode 100644 src/Lua/Standard/Mathematics/LdexpFunction.cs create mode 100644 src/Lua/Standard/Mathematics/LogFunction.cs create mode 100644 src/Lua/Standard/Mathematics/MaxFunction.cs create mode 100644 src/Lua/Standard/Mathematics/MinFunction.cs create mode 100644 src/Lua/Standard/Mathematics/ModfFunction.cs create mode 100644 src/Lua/Standard/Mathematics/PowFunction.cs create mode 100644 src/Lua/Standard/Mathematics/RadFunction.cs create mode 100644 src/Lua/Standard/Mathematics/RandomFunction.cs create mode 100644 src/Lua/Standard/Mathematics/RandomSeedFunction.cs create mode 100644 src/Lua/Standard/Mathematics/SinFuncion.cs create mode 100644 src/Lua/Standard/Mathematics/SinhFuncion.cs create mode 100644 src/Lua/Standard/Mathematics/SqrtFunction.cs create mode 100644 src/Lua/Standard/Mathematics/TanFunction.cs create mode 100644 src/Lua/Standard/Mathematics/TanhFunction.cs diff --git a/src/Lua/Internal/MathEx.cs b/src/Lua/Internal/MathEx.cs index 9b26a7f5..a2bce1ca 100644 --- a/src/Lua/Internal/MathEx.cs +++ b/src/Lua/Internal/MathEx.cs @@ -48,4 +48,42 @@ public static int NewArrayCapacity(int size) return newSize; } + + const long DBL_EXP_MASK = 0x7ff0000000000000L; + const int DBL_MANT_BITS = 52; + const long DBL_SGN_MASK = -1 - 0x7fffffffffffffffL; + const long DBL_MANT_MASK = 0x000fffffffffffffL; + const long DBL_EXP_CLR_MASK = DBL_SGN_MASK | DBL_MANT_MASK; + + public static (double m, int e) Frexp(double d) + { + var bits = BitConverter.DoubleToInt64Bits(d); + var exp = (int)((bits & DBL_EXP_MASK) >> DBL_MANT_BITS); + var e = 0; + + if (exp == 0x7ff || d == 0D) + d += d; + else + { + // Not zero and finite. + e = exp - 1022; + if (exp == 0) + { + // Subnormal, scale d so that it is in [1, 2). + d *= BitConverter.Int64BitsToDouble(0x4350000000000000L); // 2^54 + bits = BitConverter.DoubleToInt64Bits(d); + exp = (int)((bits & DBL_EXP_MASK) >> DBL_MANT_BITS); + e = exp - 1022 - 54; + } + // Set exponent to -1 so that d is in [0.5, 1). + d = BitConverter.Int64BitsToDouble((bits & DBL_EXP_CLR_MASK) | 0x3fe0000000000000L); + } + + return (d, e); + } + + public static (int i, double f) Modf(double d) + { + return ((int)Math.Truncate(d), d % 1.0); + } } \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/AbsFunction.cs b/src/Lua/Standard/Mathematics/AbsFunction.cs new file mode 100644 index 00000000..2cdf553c --- /dev/null +++ b/src/Lua/Standard/Mathematics/AbsFunction.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class AbsFunction : LuaFunction +{ + public static readonly AbsFunction Instance = new(); + + public override string Name => "abs"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Abs(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/AcosFuncion.cs b/src/Lua/Standard/Mathematics/AcosFuncion.cs new file mode 100644 index 00000000..8644dee1 --- /dev/null +++ b/src/Lua/Standard/Mathematics/AcosFuncion.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class AcosFunction : LuaFunction +{ + public static readonly AcosFunction Instance = new(); + + public override string Name => "acos"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Acos(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/AsinFuncion.cs b/src/Lua/Standard/Mathematics/AsinFuncion.cs new file mode 100644 index 00000000..36e74c39 --- /dev/null +++ b/src/Lua/Standard/Mathematics/AsinFuncion.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class AsinFunction : LuaFunction +{ + public static readonly AsinFunction Instance = new(); + + public override string Name => "asin"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Asin(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/Atan2Function.cs b/src/Lua/Standard/Mathematics/Atan2Function.cs new file mode 100644 index 00000000..afcd9a03 --- /dev/null +++ b/src/Lua/Standard/Mathematics/Atan2Function.cs @@ -0,0 +1,18 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class Atan2Function : LuaFunction +{ + public static readonly Atan2Function Instance = new(); + + public override string Name => "atan2"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + var arg1 = context.ReadArgument(1); + + buffer.Span[0] = Math.Atan2(arg0, arg1); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/AtanFuncion.cs b/src/Lua/Standard/Mathematics/AtanFuncion.cs new file mode 100644 index 00000000..63fc524b --- /dev/null +++ b/src/Lua/Standard/Mathematics/AtanFuncion.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class AtanFunction : LuaFunction +{ + public static readonly AtanFunction Instance = new(); + + public override string Name => "atan"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Atan(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/CeilFuncion.cs b/src/Lua/Standard/Mathematics/CeilFuncion.cs new file mode 100644 index 00000000..c0c60446 --- /dev/null +++ b/src/Lua/Standard/Mathematics/CeilFuncion.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class CeilFunction : LuaFunction +{ + public static readonly CeilFunction Instance = new(); + + public override string Name => "ceil"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Ceiling(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/CosFuncion.cs b/src/Lua/Standard/Mathematics/CosFuncion.cs new file mode 100644 index 00000000..a95fc686 --- /dev/null +++ b/src/Lua/Standard/Mathematics/CosFuncion.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class CosFunction : LuaFunction +{ + public static readonly CosFunction Instance = new(); + + public override string Name => "cos"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Cos(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/CoshFuncion.cs b/src/Lua/Standard/Mathematics/CoshFuncion.cs new file mode 100644 index 00000000..7aaa9dad --- /dev/null +++ b/src/Lua/Standard/Mathematics/CoshFuncion.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class CoshFunction : LuaFunction +{ + public static readonly CoshFunction Instance = new(); + + public override string Name => "cosh"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Cosh(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/DegFunction.cs b/src/Lua/Standard/Mathematics/DegFunction.cs new file mode 100644 index 00000000..0491cd80 --- /dev/null +++ b/src/Lua/Standard/Mathematics/DegFunction.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class DegFunction : LuaFunction +{ + public static readonly DegFunction Instance = new(); + + public override string Name => "deg"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = arg0 * (180.0 / Math.PI); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/ExpFuncion.cs b/src/Lua/Standard/Mathematics/ExpFuncion.cs new file mode 100644 index 00000000..a8db97bf --- /dev/null +++ b/src/Lua/Standard/Mathematics/ExpFuncion.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class ExpFunction : LuaFunction +{ + public static readonly ExpFunction Instance = new(); + + public override string Name => "exp"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Exp(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/FloorFuncion.cs b/src/Lua/Standard/Mathematics/FloorFuncion.cs new file mode 100644 index 00000000..1194a32a --- /dev/null +++ b/src/Lua/Standard/Mathematics/FloorFuncion.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class FloorFunction : LuaFunction +{ + public static readonly FloorFunction Instance = new(); + + public override string Name => "floor"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Floor(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/FmodFunction.cs b/src/Lua/Standard/Mathematics/FmodFunction.cs new file mode 100644 index 00000000..d86dc0fb --- /dev/null +++ b/src/Lua/Standard/Mathematics/FmodFunction.cs @@ -0,0 +1,17 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class FmodFunction : LuaFunction +{ + public static readonly FmodFunction Instance = new(); + + public override string Name => "fmod"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + var arg1 = context.ReadArgument(1); + buffer.Span[0] = arg0 % arg1; + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/FrexpFunction.cs b/src/Lua/Standard/Mathematics/FrexpFunction.cs new file mode 100644 index 00000000..0c5d0514 --- /dev/null +++ b/src/Lua/Standard/Mathematics/FrexpFunction.cs @@ -0,0 +1,19 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class FrexpFunction : LuaFunction +{ + public static readonly FrexpFunction Instance = new(); + + public override string Name => "frexp"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + + var (m, e) = MathEx.Frexp(arg0); + buffer.Span[0] = m; + buffer.Span[1] = e; + return new(2); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/LdexpFunction.cs b/src/Lua/Standard/Mathematics/LdexpFunction.cs new file mode 100644 index 00000000..4d995577 --- /dev/null +++ b/src/Lua/Standard/Mathematics/LdexpFunction.cs @@ -0,0 +1,18 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class LdexpFunction : LuaFunction +{ + public static readonly LdexpFunction Instance = new(); + + public override string Name => "ldexp"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + var arg1 = context.ReadArgument(1); + + buffer.Span[0] = arg0 * Math.Pow(2, arg1); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/LogFunction.cs b/src/Lua/Standard/Mathematics/LogFunction.cs new file mode 100644 index 00000000..07f58911 --- /dev/null +++ b/src/Lua/Standard/Mathematics/LogFunction.cs @@ -0,0 +1,26 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class LogFunction : LuaFunction +{ + public static readonly LogFunction Instance = new(); + + public override string Name => "log"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + + if (context.ArgumentCount == 1) + { + buffer.Span[0] = Math.Log(arg0); + } + else + { + var arg1 = context.ReadArgument(1); + buffer.Span[0] = Math.Log(arg0, arg1); + } + + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/MaxFunction.cs b/src/Lua/Standard/Mathematics/MaxFunction.cs new file mode 100644 index 00000000..be7e46e9 --- /dev/null +++ b/src/Lua/Standard/Mathematics/MaxFunction.cs @@ -0,0 +1,22 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class MaxFunction : LuaFunction +{ + public static readonly MaxFunction Instance = new(); + + public override string Name => "max"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var x = context.ReadArgument(0); + for (int i = 1; i < context.ArgumentCount; i++) + { + x = Math.Max(x, context.ReadArgument(i)); + } + + buffer.Span[0] = x; + + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/MinFunction.cs b/src/Lua/Standard/Mathematics/MinFunction.cs new file mode 100644 index 00000000..01f36fa4 --- /dev/null +++ b/src/Lua/Standard/Mathematics/MinFunction.cs @@ -0,0 +1,22 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class MinFunction : LuaFunction +{ + public static readonly MinFunction Instance = new(); + + public override string Name => "min"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var x = context.ReadArgument(0); + for (int i = 1; i < context.ArgumentCount; i++) + { + x = Math.Min(x, context.ReadArgument(i)); + } + + buffer.Span[0] = x; + + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/ModfFunction.cs b/src/Lua/Standard/Mathematics/ModfFunction.cs new file mode 100644 index 00000000..5fdd13a1 --- /dev/null +++ b/src/Lua/Standard/Mathematics/ModfFunction.cs @@ -0,0 +1,18 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class ModfFunction : LuaFunction +{ + public static readonly ModfFunction Instance = new(); + + public override string Name => "modf"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + var (i, f) = MathEx.Modf(arg0); + buffer.Span[0] = i; + buffer.Span[1] = f; + return new(2); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/PowFunction.cs b/src/Lua/Standard/Mathematics/PowFunction.cs new file mode 100644 index 00000000..4377029a --- /dev/null +++ b/src/Lua/Standard/Mathematics/PowFunction.cs @@ -0,0 +1,18 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class PowFunction : LuaFunction +{ + public static readonly PowFunction Instance = new(); + + public override string Name => "pow"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + var arg1 = context.ReadArgument(1); + + buffer.Span[0] = Math.Pow(arg0, arg1); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/RadFunction.cs b/src/Lua/Standard/Mathematics/RadFunction.cs new file mode 100644 index 00000000..a0921294 --- /dev/null +++ b/src/Lua/Standard/Mathematics/RadFunction.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class RadFunction : LuaFunction +{ + public static readonly RadFunction Instance = new(); + + public override string Name => "rad"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = arg0 * (Math.PI / 180.0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/RandomFunction.cs b/src/Lua/Standard/Mathematics/RandomFunction.cs new file mode 100644 index 00000000..98f8e546 --- /dev/null +++ b/src/Lua/Standard/Mathematics/RandomFunction.cs @@ -0,0 +1,33 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class RandomFunction : LuaFunction +{ + public const string RandomInstanceKey = "__lua_mathematics_library_random_instance"; + public static readonly RandomFunction Instance = new(); + + public override string Name => "random"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var rand = context.State.Environment[RandomInstanceKey].Read(); + + if (context.ArgumentCount == 0) + { + buffer.Span[0] = rand.NextDouble(); + } + else if (context.ArgumentCount == 1) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = rand.NextDouble() * (arg0 - 1) + 1; + } + else + { + var arg0 = context.ReadArgument(0); + var arg1 = context.ReadArgument(1); + buffer.Span[0] = rand.NextDouble() * (arg1 - arg0) + arg0; + } + + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/RandomSeedFunction.cs b/src/Lua/Standard/Mathematics/RandomSeedFunction.cs new file mode 100644 index 00000000..914da470 --- /dev/null +++ b/src/Lua/Standard/Mathematics/RandomSeedFunction.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class RandomSeedFunction : LuaFunction +{ + public static readonly RandomSeedFunction Instance = new(); + + public override string Name => "randomseed"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + context.State.Environment[RandomFunction.RandomInstanceKey] = new(new Random((int)BitConverter.DoubleToInt64Bits(arg0))); + return new(0); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/SinFuncion.cs b/src/Lua/Standard/Mathematics/SinFuncion.cs new file mode 100644 index 00000000..6fa70b45 --- /dev/null +++ b/src/Lua/Standard/Mathematics/SinFuncion.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class SinFunction : LuaFunction +{ + public static readonly SinFunction Instance = new(); + + public override string Name => "sin"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Sin(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/SinhFuncion.cs b/src/Lua/Standard/Mathematics/SinhFuncion.cs new file mode 100644 index 00000000..61b324c0 --- /dev/null +++ b/src/Lua/Standard/Mathematics/SinhFuncion.cs @@ -0,0 +1,15 @@ + +namespace Lua.Standard.Mathematics; +public sealed class SinhFunction : LuaFunction +{ + public static readonly SinhFunction Instance = new(); + + public override string Name => "sinh"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Sinh(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/SqrtFunction.cs b/src/Lua/Standard/Mathematics/SqrtFunction.cs new file mode 100644 index 00000000..5fdc6c9f --- /dev/null +++ b/src/Lua/Standard/Mathematics/SqrtFunction.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class SqrtFunction : LuaFunction +{ + public static readonly SqrtFunction Instance = new(); + + public override string Name => "sqrt"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Sqrt(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/TanFunction.cs b/src/Lua/Standard/Mathematics/TanFunction.cs new file mode 100644 index 00000000..a9a59f91 --- /dev/null +++ b/src/Lua/Standard/Mathematics/TanFunction.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class TanFunction : LuaFunction +{ + public static readonly TanFunction Instance = new(); + + public override string Name => "tan"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Tan(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/Mathematics/TanhFunction.cs b/src/Lua/Standard/Mathematics/TanhFunction.cs new file mode 100644 index 00000000..c2ec727b --- /dev/null +++ b/src/Lua/Standard/Mathematics/TanhFunction.cs @@ -0,0 +1,16 @@ + +namespace Lua.Standard.Mathematics; + +public sealed class TanhFunction : LuaFunction +{ + public static readonly TanhFunction Instance = new(); + + public override string Name => "tanh"; + + protected override ValueTask InvokeAsyncCore(LuaFunctionExecutionContext context, Memory buffer, CancellationToken cancellationToken) + { + var arg0 = context.ReadArgument(0); + buffer.Span[0] = Math.Tanh(arg0); + return new(1); + } +} \ No newline at end of file diff --git a/src/Lua/Standard/OpenLibExtensions.cs b/src/Lua/Standard/OpenLibExtensions.cs index 1b092fc6..21995920 100644 --- a/src/Lua/Standard/OpenLibExtensions.cs +++ b/src/Lua/Standard/OpenLibExtensions.cs @@ -1,4 +1,5 @@ using Lua.Standard.Base; +using Lua.Standard.Mathematics; namespace Lua.Standard; @@ -15,6 +16,36 @@ public static class OpenLibExtensions ToStringFunction.Instance ]; + static readonly LuaFunction[] mathFunctions = [ + AbsFunction.Instance, + AcosFunction.Instance, + AsinFunction.Instance, + Atan2Function.Instance, + AtanFunction.Instance, + CeilFunction.Instance, + CosFunction.Instance, + CoshFunction.Instance, + DegFunction.Instance, + ExpFunction.Instance, + FloorFunction.Instance, + FmodFunction.Instance, + FrexpFunction.Instance, + LdexpFunction.Instance, + LogFunction.Instance, + MaxFunction.Instance, + MinFunction.Instance, + ModfFunction.Instance, + PowFunction.Instance, + RadFunction.Instance, + RandomFunction.Instance, + RandomSeedFunction.Instance, + SinFunction.Instance, + SinhFunction.Instance, + SqrtFunction.Instance, + TanFunction.Instance, + TanhFunction.Instance, + ]; + public static void OpenBaseLibrary(this LuaState state) { state.Environment["_G"] = state.Environment; @@ -24,4 +55,19 @@ public static void OpenBaseLibrary(this LuaState state) state.Environment[func.Name] = func; } } + + public static void OpenMathLibrary(this LuaState state) + { + state.Environment[RandomFunction.RandomInstanceKey] = new(new Random()); + state.Environment["pi"] = Math.PI; + state.Environment["huge"] = double.PositiveInfinity; + + var table = new LuaTable(0, mathFunctions.Length); + foreach (var func in mathFunctions) + { + table[func.Name] = func; + } + + state.Environment["math"] = table; + } } \ No newline at end of file