TableIterators.cs 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using MoonSharp.Interpreter.Execution;
  6. using MoonSharp.Interpreter.Execution.DataTypes;
  7. namespace MoonSharp.Interpreter.CoreLib
  8. {
  9. [MoonSharpModule]
  10. public class TableIterators
  11. {
  12. // ipairs (t)
  13. // -------------------------------------------------------------------------------------------------------------------
  14. // If t has a metamethod __ipairs, calls it with t as argument and returns the first three results from the call.
  15. // Otherwise, returns three values: an iterator function, the table t, and 0, so that the construction
  16. // for i,v in ipairs(t) do body end
  17. // will iterate over the pairs (1,t[1]), (2,t[2]), ..., up to the first integer key absent from the table.
  18. [MoonSharpMethod]
  19. static RValue ipairs(IExecutionContext executionContext, CallbackArguments args)
  20. {
  21. RValue table = args[0];
  22. RValue meta = executionContext.GetMetamethodTailCall(table, "__ipairs", args.ToArray());
  23. return meta ?? new RValue(new RValue[] { new RValue(new CallbackFunction(__next_i)), table, new RValue(0) });
  24. }
  25. // pairs (t)
  26. // -------------------------------------------------------------------------------------------------------------------
  27. // If t has a metamethod __pairs, calls it with t as argument and returns the first three results from the call.
  28. // Otherwise, returns three values: the next function, the table t, and nil, so that the construction
  29. // for k,v in pairs(t) do body end
  30. // will iterate over all key–value pairs of table t.
  31. // See function next for the caveats of modifying the table during its traversal.
  32. [MoonSharpMethod]
  33. static RValue pairs(IExecutionContext executionContext, CallbackArguments args)
  34. {
  35. RValue table = args[0];
  36. RValue meta = executionContext.GetMetamethodTailCall(table, "__pairs", args.ToArray());
  37. return meta ?? new RValue(new RValue[] { new RValue(new CallbackFunction(next)), table });
  38. }
  39. // next (table [, index])
  40. // -------------------------------------------------------------------------------------------------------------------
  41. // Allows a program to traverse all fields of a table. Its first argument is a table and its second argument is an
  42. // index in this table. next returns the next index of the table and its associated value.
  43. // When called with nil as its second argument, next returns an initial index and its associated value.
  44. // When called with the last index, or with nil in an empty table, next returns nil. If the second argument is absent,
  45. // then it is interpreted as nil. In particular, you can use next(t) to check whether a table is empty.
  46. // The order in which the indices are enumerated is not specified, even for numeric indices.
  47. // (To traverse a table in numeric order, use a numerical for.)
  48. // The behavior of next is undefined if, during the traversal, you assign any value to a non-existent field in the table.
  49. // You may however modify existing fields. In particular, you may clear existing fields.
  50. [MoonSharpMethod]
  51. static RValue next(IExecutionContext executionContext, CallbackArguments args)
  52. {
  53. RValue table = args.AsType(0, "next", DataType.Table);
  54. RValue index = args[1];
  55. TablePair pair = table.Table.NextKey(index);
  56. return new RValue(new RValue[] { pair.Key, pair.Value });
  57. }
  58. // __next_i (table [, index])
  59. // -------------------------------------------------------------------------------------------------------------------
  60. // Allows a program to traverse all fields of an array. index is an integer number
  61. static RValue __next_i(IExecutionContext executionContext, CallbackArguments args)
  62. {
  63. RValue table = args.AsType(0, "!!next_i!!", DataType.Table);
  64. RValue index = args.AsType(1, "!!next_i!!", DataType.Number);
  65. int idx = ((int)index.Number) + 1;
  66. RValue val = table.Table[idx];
  67. if (val.Type != DataType.Nil)
  68. {
  69. return new RValue(new RValue[] { new RValue(idx), val });
  70. }
  71. else
  72. {
  73. return RValue.Nil;
  74. }
  75. }
  76. }
  77. }