Browse Source

Add: bit32.arshift

AnnulusGames 1 year ago
parent
commit
db2972385a

+ 33 - 0
src/Lua/Standard/Bitwise/ArshiftFunction.cs

@@ -0,0 +1,33 @@
+namespace Lua.Standard.Bitwise;
+
+public sealed class ArshiftFunction : LuaFunction
+{
+    public override string Name => "arshift";
+    public static readonly ArshiftFunction Instance = new();
+
+    protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
+    {
+        var x = context.GetArgument<double>(0);
+        var disp = context.GetArgument<double>(1);
+
+        if (!MathEx.IsInteger(disp))
+        {
+            throw new LuaRuntimeException(context.State.GetTraceback(), "bad argument #2 to 'arshift' (number has no integer representation)");
+        }
+
+        var v = Bit32Helper.ToInt32(x);
+        var a = (int)disp;
+
+        if (a < 0)
+        {
+            v <<= -a;
+        }
+        else
+        {
+            v >>= a;
+        }
+
+        buffer.Span[0] = v;
+        return new(1);
+    }
+}

+ 20 - 0
src/Lua/Standard/Bitwise/Bit32Helper.cs

@@ -0,0 +1,20 @@
+using System.Runtime.CompilerServices;
+
+namespace Lua.Standard.Bitwise;
+
+internal static class Bit32Helper
+{
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    public static uint ToUInt32(double d)
+    {
+        d = Math.IEEERemainder(d, Math.Pow(2.0, 32.0));
+        return (uint)d;
+    }
+
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    public static int ToInt32(double d)
+    {
+        d = Math.IEEERemainder(d, Math.Pow(2.0, 32.0));
+        return (int)d;
+    }
+}

+ 16 - 0
src/Lua/Standard/OpenLibExtensions.cs

@@ -1,4 +1,5 @@
 using Lua.Standard.Basic;
+using Lua.Standard.Bitwise;
 using Lua.Standard.Coroutines;
 using Lua.Standard.IO;
 using Lua.Standard.Mathematics;
@@ -99,6 +100,10 @@ public static class OpenLibExtensions
         TmpNameFunction.Instance,
     ];
 
+    static readonly LuaFunction[] bit32Functions = [
+        ArshiftFunction.Instance,
+    ];
+
     public static void OpenBasicLibrary(this LuaState state)
     {
         // basic
@@ -182,4 +187,15 @@ public static class OpenLibExtensions
 
         state.Environment["os"] = os;
     }
+
+    public static void OpenBitwiseLibrary(this LuaState state)
+    {
+        var bit32 = new LuaTable(0, osFunctions.Length);
+        foreach (var func in bit32Functions)
+        {
+            bit32[func.Name] = func;
+        }
+
+        state.Environment["bit32"] = bit32;
+    }
 }