mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-01-18 18:46:43 +00:00
Add f:lines()
This commit is contained in:
parent
1d28f07a7e
commit
4b21daa095
2 changed files with 104 additions and 41 deletions
|
@ -18,4 +18,6 @@ namespace Capy64.Runtime;
|
||||||
public class Constants
|
public class Constants
|
||||||
{
|
{
|
||||||
public const int MULTRET = -1;
|
public const int MULTRET = -1;
|
||||||
|
public const int MINSTACK = 20;
|
||||||
|
public const int MAXLENNUM = 200;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,11 @@
|
||||||
using Capy64.API;
|
using Capy64.API;
|
||||||
using KeraLua;
|
using KeraLua;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using static Capy64.Runtime.Constants;
|
||||||
|
|
||||||
namespace Capy64.Runtime.Objects;
|
namespace Capy64.Runtime.Objects;
|
||||||
|
|
||||||
|
@ -134,7 +137,7 @@ public class FileHandle : IComponent
|
||||||
|
|
||||||
private static bool ReadNumber(Lua L, Stream stream)
|
private static bool ReadNumber(Lua L, Stream stream)
|
||||||
{
|
{
|
||||||
var str = ReadNumberHelper.ReadNumber(stream);
|
var str = ReadHelper.ReadNumber(stream);
|
||||||
if (L.StringToNumber(str))
|
if (L.StringToNumber(str))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -197,53 +200,66 @@ public class FileHandle : IComponent
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return G_Read(L, stream, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int G_Read(Lua L, Stream f, int first)
|
||||||
|
{
|
||||||
var nargs = L.GetTop() - 1;
|
var nargs = L.GetTop() - 1;
|
||||||
if (nargs == 0)
|
int n;
|
||||||
{
|
bool success;
|
||||||
L.PushString("l");
|
|
||||||
nargs = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 2; i <= nargs + 1; i++)
|
if (nargs == 0) // no arguments?
|
||||||
{
|
{
|
||||||
bool success;
|
success = ReadLine(L, f, true);
|
||||||
if (L.Type(i) == LuaType.Number)
|
n = first + 1; // to return 1 result
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ensure stack space for all results and for auxlib's buffer
|
||||||
|
L.CheckStack(nargs + MINSTACK, "too many arguments");
|
||||||
|
success = true;
|
||||||
|
for (n = first; (nargs-- > 0) && success; n++)
|
||||||
{
|
{
|
||||||
success = ReadChars(L, stream, (int)L.ToNumber(2));
|
if (L.Type(n) == LuaType.Number)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var p = L.CheckString(i);
|
|
||||||
var mode = CheckMode(p);
|
|
||||||
switch (mode)
|
|
||||||
{
|
{
|
||||||
case 'n':
|
var l = (int)L.CheckInteger(n);
|
||||||
success = ReadNumber(L, stream);
|
success = (l == 0) ? f.Position == f.Length : ReadChars(L, f, l);
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
success = ReadLine(L, stream, true);
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
success = ReadLine(L, stream, false);
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
ReadAll(L, stream);
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return L.ArgumentError(i, "invalid format");
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var p = L.CheckString(n);
|
||||||
|
var mode = CheckMode(p);
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case 'n': // number
|
||||||
|
success = ReadNumber(L, f);
|
||||||
|
break;
|
||||||
|
case 'l': // line
|
||||||
|
success = ReadLine(L, f, true);
|
||||||
|
break;
|
||||||
|
case 'L': // line with end-of-line
|
||||||
|
success = ReadLine(L, f, false);
|
||||||
|
break;
|
||||||
|
case 'a': // file
|
||||||
|
ReadAll(L, f); // read entire file
|
||||||
|
success = true; // always success
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return L.ArgumentError(n, "invalid format");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
L.Pop(1);
|
|
||||||
L.PushNil();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nargs;
|
if (!success)
|
||||||
|
{
|
||||||
|
L.Pop(1);
|
||||||
|
L.PushNil();
|
||||||
|
}
|
||||||
|
|
||||||
|
return n - first;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int L_Write(IntPtr state)
|
private static int L_Write(IntPtr state)
|
||||||
|
@ -278,7 +294,6 @@ public class FileHandle : IComponent
|
||||||
|
|
||||||
private static int L_Lines(IntPtr state)
|
private static int L_Lines(IntPtr state)
|
||||||
{
|
{
|
||||||
return 0;
|
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
var maxargn = 250;
|
var maxargn = 250;
|
||||||
|
|
||||||
|
@ -289,11 +304,51 @@ public class FileHandle : IComponent
|
||||||
L.PushInteger(n);
|
L.PushInteger(n);
|
||||||
L.PushBoolean(false);
|
L.PushBoolean(false);
|
||||||
L.Rotate(2, 3);
|
L.Rotate(2, 3);
|
||||||
L.PushCClosure(null, 3 + n); // todo
|
L.PushCClosure(IO_ReadLine, 3 + n);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int IO_ReadLine(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
var stream = ObjectManager.ToObject<Stream>(L, Lua.UpValueIndex(1), false);
|
||||||
|
int i;
|
||||||
|
int n = (int)L.ToInteger(Lua.UpValueIndex(2));
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
return L.Error("file is already closed");
|
||||||
|
}
|
||||||
|
L.SetTop(1);
|
||||||
|
L.CheckStack(n, "too many arguments");
|
||||||
|
for (i = 1; i <= n; i++)
|
||||||
|
{
|
||||||
|
L.PushCopy(Lua.UpValueIndex(3 + i));
|
||||||
|
}
|
||||||
|
n = G_Read(L, stream, 2);
|
||||||
|
Debug.Assert(n > 0);
|
||||||
|
if (L.ToBoolean(-n))
|
||||||
|
{
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (n > 1)
|
||||||
|
{
|
||||||
|
return L.Error(L.ToString(-n + 1));
|
||||||
|
}
|
||||||
|
if (L.ToBoolean(Lua.UpValueIndex(3)))
|
||||||
|
{
|
||||||
|
L.SetTop(0);
|
||||||
|
L.PushCopy(Lua.UpValueIndex(1));
|
||||||
|
stream.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private static int L_Flush(IntPtr state)
|
private static int L_Flush(IntPtr state)
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
@ -363,7 +418,7 @@ public class FileHandle : IComponent
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ReadNumberHelper
|
private static class ReadHelper
|
||||||
{
|
{
|
||||||
static bool isdigit(char c)
|
static bool isdigit(char c)
|
||||||
{
|
{
|
||||||
|
@ -389,6 +444,12 @@ public class FileHandle : IComponent
|
||||||
}.Contains(c);
|
}.Contains(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool test_eof(Lua L, Stream f)
|
||||||
|
{
|
||||||
|
L.PushString("");
|
||||||
|
return f.Position != f.Length;
|
||||||
|
}
|
||||||
|
|
||||||
static bool nextc(RN rn)
|
static bool nextc(RN rn)
|
||||||
{
|
{
|
||||||
if (rn.n >= 200) // buffer overflow?
|
if (rn.n >= 200) // buffer overflow?
|
||||||
|
|
Loading…
Reference in a new issue