Browse Source

Add: input/output, stdio/stdout/stderr

AnnulusGames 1 year ago
parent
commit
86f6c3535b

+ 2 - 2
src/Lua/Standard/IO/FileHandle.cs

@@ -30,7 +30,7 @@ public class FileHandle : LuaUserData
         }
     }
 
-    public FileStream Stream { get; }
+    public Stream Stream { get; }
 
     static readonly LuaTable fileHandleMetatable;
 
@@ -40,7 +40,7 @@ public class FileHandle : LuaUserData
         fileHandleMetatable[Metamethods.Index] = new IndexMetamethod();
     }
 
-    public FileHandle(FileStream stream)
+    public FileHandle(Stream stream)
     {
         Stream = stream;
         Metatable = fileHandleMetatable;

+ 34 - 0
src/Lua/Standard/IO/InputFunction.cs

@@ -0,0 +1,34 @@
+namespace Lua.Standard.IO;
+
+public sealed class InputFunction : LuaFunction
+{
+    public override string Name => "input";
+    public static readonly InputFunction Instance = new();
+
+    protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
+    {
+        var io = context.State.Environment["io"].Read<LuaTable>();
+
+        if (context.ArgumentCount == 0 || context.Arguments[0].Type is LuaValueType.Nil)
+        {
+            buffer.Span[0] = io["stdio"];
+            return new(1);
+        }
+
+        var arg = context.Arguments[0];
+        if (arg.TryRead<FileHandle>(out var file))
+        {
+            io["stdio"] = file;
+            buffer.Span[0] = file;
+            return new(1);
+        }
+        else
+        {
+            var stream = File.Open(arg.ToString()!, FileMode.Open, FileAccess.ReadWrite);
+            var handle = new FileHandle(stream);
+            io["stdio"] = handle;
+            buffer.Span[0] = handle;
+            return new(1);
+        }
+    }
+}

+ 34 - 0
src/Lua/Standard/IO/OutputFunction.cs

@@ -0,0 +1,34 @@
+namespace Lua.Standard.IO;
+
+public sealed class OutputFunction : LuaFunction
+{
+    public override string Name => "output";
+    public static readonly OutputFunction Instance = new();
+
+    protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
+    {
+        var io = context.State.Environment["io"].Read<LuaTable>();
+
+        if (context.ArgumentCount == 0 || context.Arguments[0].Type is LuaValueType.Nil)
+        {
+            buffer.Span[0] = io["stdout"];
+            return new(1);
+        }
+
+        var arg = context.Arguments[0];
+        if (arg.TryRead<FileHandle>(out var file))
+        {
+            io["stdout"] = file;
+            buffer.Span[0] = file;
+            return new(1);
+        }
+        else
+        {
+            var stream = File.Open(arg.ToString()!, FileMode.Open, FileAccess.ReadWrite);
+            var handle = new FileHandle(stream);
+            io["stdout"] = handle;
+            buffer.Span[0] = handle;
+            return new(1);
+        }
+    }
+}

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

@@ -76,6 +76,8 @@ public static class OpenLibExtensions
     static readonly LuaFunction[] ioFunctions = [
         FileOpenFunction.Instance,
         FileCloseFunction.Instance,
+        InputFunction.Instance,
+        OutputFunction.Instance,
     ];
 
     public static void OpenBasicLibrary(this LuaState state)
@@ -143,6 +145,10 @@ public static class OpenLibExtensions
             io[func.Name] = func;
         }
 
+        io["stdio"] = new FileHandle(Console.OpenStandardInput());
+        io["stdout"] = new FileHandle(Console.OpenStandardOutput());
+        io["stderr"] = new FileHandle(Console.OpenStandardError());
+
         state.Environment["io"] = io;
     }
 }