FunctionCall.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Antlr4.Runtime.Tree;
  6. using MoonSharp.Interpreter.Execution;
  7. using MoonSharp.Interpreter.Execution.VM;
  8. using MoonSharp.Interpreter.Grammar;
  9. using MoonSharp.Interpreter.Tree.Expressions;
  10. namespace MoonSharp.Interpreter.Tree
  11. {
  12. class FunctionCall : NodeBase
  13. {
  14. Expression[] m_Arguments;
  15. string m_Name;
  16. public FunctionCall(LuaParser.NameAndArgsContext nameAndArgs, ScriptLoadingContext lcontext)
  17. : base(nameAndArgs, lcontext)
  18. {
  19. var name = nameAndArgs.NAME();
  20. m_Name = name != null ? name.GetText().Trim() : null;
  21. m_Arguments = nameAndArgs.args().children.SelectMany(t => NodeFactory.CreateExpressions(t, lcontext)).Where(t => t != null).ToArray();
  22. }
  23. public RValue Invoke(RuntimeScope scope, RValue value)
  24. {
  25. RValue[] args;
  26. if (value.Type == DataType.Table)
  27. {
  28. var method = value.Table[new RValue(m_Name)];
  29. args = new RValue[] { value }.Union(
  30. m_Arguments
  31. .Select(exp => exp.Eval(scope))
  32. .SelectMany(val => val.ToArrayOfValues())
  33. )
  34. .ToArray();
  35. value = method;
  36. }
  37. else
  38. {
  39. args = m_Arguments
  40. .Select(exp => exp.Eval(scope))
  41. .SelectMany(val => val.ToArrayOfValues())
  42. .ToArray();
  43. }
  44. if (value.Type == DataType.ClrFunction)
  45. {
  46. return value.Callback.Invoke(scope, args);
  47. }
  48. else
  49. {
  50. throw RuntimeError("Function was expected, but a {0} was passed.", value.Type.ToString());
  51. }
  52. }
  53. public override void Compile(Execution.VM.Chunk bc)
  54. {
  55. if (!string.IsNullOrEmpty(m_Name))
  56. {
  57. bc.TempOp(OpCode.TmpPeek, 0);
  58. bc.Literal(new RValue(m_Name));
  59. bc.IndexGet();
  60. }
  61. for (int i = m_Arguments.Length - 1; i >= 0; i--)
  62. m_Arguments[i].Compile(bc);
  63. if (string.IsNullOrEmpty(m_Name))
  64. {
  65. bc.Call(m_Arguments.Length);
  66. }
  67. else
  68. {
  69. bc.TempOp(OpCode.TmpPush, 0);
  70. bc.TempOp(OpCode.TmpClear, 0);
  71. bc.Call(m_Arguments.Length + 1);
  72. }
  73. }
  74. }
  75. }