-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathFunctionCallExpression.cs
111 lines (98 loc) · 2.97 KB
/
FunctionCallExpression.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
using System.Collections.Generic;
using MoonSharp.Interpreter.DataStructs;
using MoonSharp.Interpreter.Debugging;
using MoonSharp.Interpreter.Execution;
namespace MoonSharp.Interpreter.Tree.Expressions
{
class FunctionCallExpression : Expression
{
List<Expression> m_Arguments;
Expression m_Function;
string m_Name;
string m_DebugErr;
internal SourceRef SourceRef { get; private set; }
public FunctionCallExpression(ScriptLoadingContext lcontext, Expression function, Token thisCallName)
: base(lcontext)
{
Token callToken = thisCallName ?? lcontext.Lexer.Current;
m_Name = thisCallName != null ? thisCallName.Text : null;
m_DebugErr = function.GetFriendlyDebugName();
m_Function = function;
switch (lcontext.Lexer.Current.Type)
{
case TokenType.Brk_Open_Round:
Token openBrk = lcontext.Lexer.Current;
lcontext.Lexer.Next();
Token t = lcontext.Lexer.Current;
if (t.Type == TokenType.Brk_Close_Round)
{
m_Arguments = new List<Expression>();
SourceRef = callToken.GetSourceRef(t);
lcontext.Lexer.Next();
}
else
{
m_Arguments = ExprList(lcontext);
SourceRef = callToken.GetSourceRef(CheckMatch(lcontext, openBrk, TokenType.Brk_Close_Round, ")"));
}
break;
case TokenType.String:
case TokenType.String_Long:
{
m_Arguments = new List<Expression>();
Expression le = new LiteralExpression(lcontext, lcontext.Lexer.Current);
m_Arguments.Add(le);
SourceRef = callToken.GetSourceRef(lcontext.Lexer.Current);
}
break;
case TokenType.Brk_Open_Curly:
case TokenType.Brk_Open_Curly_Shared:
{
m_Arguments = new List<Expression>();
m_Arguments.Add(new TableConstructor(lcontext, lcontext.Lexer.Current.Type == TokenType.Brk_Open_Curly_Shared));
SourceRef = callToken.GetSourceRefUpTo(lcontext.Lexer.Current);
}
break;
default:
throw new SyntaxErrorException(lcontext.Lexer.Current, "function arguments expected")
{
IsPrematureStreamTermination = (lcontext.Lexer.Current.Type == TokenType.Eof)
};
}
}
public override void Compile(Execution.VM.ByteCode bc)
{
m_Function.Compile(bc);
int argslen = m_Arguments.Count;
if (!string.IsNullOrEmpty(m_Name))
{
bc.Emit_Copy(0);
bc.Emit_Index(m_Name, true);
bc.Emit_Swap(0, 1);
++argslen;
}
for (int i = 0; i < m_Arguments.Count; i++)
m_Arguments[i].CompilePossibleLiteral(bc);
if (!string.IsNullOrEmpty(m_Name))
{
bc.Emit_ThisCall(argslen, m_DebugErr);
}
else
{
bc.Emit_Call(argslen, m_DebugErr);
}
if (bc.NilChainTargets.Count > 0) {
bc.SetNumVal(bc.NilChainTargets.Pop(), bc.GetJumpPointForNextInstruction());
}
}
public override bool EvalLiteral(out DynValue dv)
{
dv = DynValue.Nil;
return false;
}
public override DynValue Eval(ScriptExecutionContext context)
{
throw new DynamicExpressionException("Dynamic Expressions cannot call functions.");
}
}
}