Browse Source

Add: insert

AnnulusGames 1 year ago
parent
commit
5f020bc595

+ 25 - 7
src/Lua/LuaTable.cs

@@ -133,25 +133,43 @@ public sealed class LuaTable
         return dictionary.ContainsKey(key);
     }
 
-    public LuaValue RemoveAt(int key)
+    public LuaValue RemoveAt(int index)
     {
-        if (key <= 0 || key > array.Length)
+        if (index <= 0 || index > array.Length)
         {
-            return LuaValue.Nil;
+            throw new IndexOutOfRangeException();
         }
 
-        var index = key - 1;
-        var value = array[index];
+        var arrayIndex = index - 1;
+        var value = array[arrayIndex];
 
-        if (index < array.Length - 1)
+        if (arrayIndex < array.Length - 1)
         {
-            array.AsSpan(index + 1).CopyTo(array.AsSpan(index));
+            array.AsSpan(arrayIndex + 1).CopyTo(array.AsSpan(arrayIndex));
         }
         array[^1] = default;
 
         return value;
     }
 
+    public void Insert(int index, LuaValue value)
+    {
+        if (index <= 0 || index > array.Length + 1)
+        {
+            throw new IndexOutOfRangeException();
+        }
+
+        var arrayIndex = index - 1;
+        EnsureArrayCapacity(array.Length + 1);
+
+        if (arrayIndex != array.Length - 1)
+        {
+            array.AsSpan(arrayIndex, array.Length - arrayIndex - 1).CopyTo(array.AsSpan(arrayIndex + 1));
+        }
+        
+        array[arrayIndex] = value;
+    }
+
     public KeyValuePair<LuaValue, LuaValue> GetNext(LuaValue key)
     {
         var index = -1;

+ 33 - 0
src/Lua/Standard/Table/InsertFunction.cs

@@ -0,0 +1,33 @@
+namespace Lua.Standard.Table;
+
+public sealed class InsertFunction : LuaFunction
+{
+    public override string Name => "insert";
+    public static readonly InsertFunction Instance = new();
+
+    protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
+    {
+        var table = context.ReadArgument<LuaTable>(0);
+
+        var value = context.ArgumentCount >= 3
+            ? context.ReadArgument(2)
+            : context.ReadArgument(1);
+
+        var pos = context.ArgumentCount >= 3
+            ? context.ReadArgument<double>(1)
+            : table.ArrayLength + 1;
+
+        if (!MathEx.IsInteger(pos))
+        {
+            throw new LuaRuntimeException(context.State.GetTraceback(), "bad argument #2 to 'insert' (number has no integer representation)");
+        }
+
+        if (pos <= 0 || pos > table.ArrayLength + 1)
+        {
+            throw new LuaRuntimeException(context.State.GetTraceback(), "bad argument #2 to 'insert' (position out of bounds)");
+        }
+
+        table.Insert((int)pos, value);
+        return new(0);
+    }
+}

+ 5 - 0
src/Lua/Standard/Table/RemoveFunction.cs

@@ -17,6 +17,11 @@ public sealed class RemoveFunction : LuaFunction
             throw new LuaRuntimeException(context.State.GetTraceback(), "bad argument #2 to 'remove' (number has no integer representation)");
         }
 
+        if (arg1 <= 0 || arg1 > arg0.ArrayLength)
+        {
+            throw new LuaRuntimeException(context.State.GetTraceback(), "bad argument #2 to 'remove' (position out of bounds)");
+        }
+
         buffer.Span[0] = arg0.RemoveAt((int)arg1);
         return new(1);
     }