Browse Source

Add: string.sub

AnnulusGames 1 year ago
parent
commit
6a7fa3be5d

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

@@ -81,6 +81,7 @@ public static class OpenLibExtensions
         LowerFunction.Instance,
         LowerFunction.Instance,
         RepFunction.Instance,
         RepFunction.Instance,
         ReverseFunction.Instance,
         ReverseFunction.Instance,
+        SubFunction.Instance,
         UpperFunction.Instance,
         UpperFunction.Instance,
     ];
     ];
 
 

+ 14 - 0
src/Lua/Standard/Text/StringHelper.cs

@@ -1,3 +1,5 @@
+using System.Runtime.CompilerServices;
+
 namespace Lua.Standard.Text;
 namespace Lua.Standard.Text;
 
 
 internal static class StringHelper
 internal static class StringHelper
@@ -7,4 +9,16 @@ internal static class StringHelper
         if (i >= 0 && i <= 255) return i;
         if (i >= 0 && i <= 255) return i;
         throw new ArgumentOutOfRangeException(nameof(i));
         throw new ArgumentOutOfRangeException(nameof(i));
     }
     }
+
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    public static string SubString(string s, int i, int j)
+    {
+        if (i < 0) i = s.Length + i + 1;
+        if (j < 0) i = s.Length + i + 1;
+
+        if (i < 1) i = 1;
+        if (j > s.Length) j = s.Length;
+
+        return i > j ? "" : s.Substring(i - 1, j - 1);
+    }
 }
 }

+ 27 - 0
src/Lua/Standard/Text/SubFunction.cs

@@ -0,0 +1,27 @@
+
+using System.Text;
+
+namespace Lua.Standard.Text;
+
+public sealed class SubFunction : LuaFunction
+{
+    public override string Name => "sub";
+    public static readonly SubFunction Instance = new();
+
+    protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
+    {
+        var s = context.GetArgument<string>(0);
+        var i_arg = context.GetArgument<double>(1);
+        var j_arg = context.HasArgument(2)
+            ? context.GetArgument<double>(2)
+            : -1;
+
+        LuaRuntimeException.ThrowBadArgumentIfNumberIsNotInteger(context.State, this, 2, i_arg);
+        LuaRuntimeException.ThrowBadArgumentIfNumberIsNotInteger(context.State, this, 3, j_arg);
+
+        var i = (int)i_arg;
+        var j = (int)j_arg;
+        buffer.Span[0] = StringHelper.SubString(s, i, j);
+        return new(1);
+    }
+}