PairsFunction.cs 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. using Lua.Runtime;
  2. namespace Lua.Standard.Basic;
  3. public sealed class PairsFunction : LuaFunction
  4. {
  5. public override string Name => "pairs";
  6. public static readonly PairsFunction Instance = new();
  7. protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
  8. {
  9. var arg0 = context.ReadArgument<LuaTable>(0);
  10. // If table has a metamethod __pairs, calls it with table as argument and returns the first three results from the call.
  11. if (arg0.Metatable != null && arg0.Metatable.TryGetValue(Metamethods.Pairs, out var metamethod))
  12. {
  13. if (!metamethod.TryRead<LuaFunction>(out var function))
  14. {
  15. LuaRuntimeException.AttemptInvalidOperation(context.State.GetTracebacks(), "call", metamethod);
  16. }
  17. return function.InvokeAsync(context, buffer, cancellationToken);
  18. }
  19. buffer.Span[0] = new Iterator(arg0);
  20. return new(1);
  21. }
  22. class Iterator(LuaTable table) : LuaFunction
  23. {
  24. LuaValue key;
  25. protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
  26. {
  27. var kv = table.GetNext(key);
  28. buffer.Span[0] = kv.Key;
  29. buffer.Span[1] = kv.Value;
  30. key = kv.Key;
  31. return new(2);
  32. }
  33. }
  34. }