-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathBuildTimeScope.cs
122 lines (94 loc) · 2.71 KB
/
BuildTimeScope.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
112
113
114
115
116
117
118
119
120
121
122
using System.Collections.Generic;
using System.Linq;
using MoonSharp.Interpreter.Execution.Scopes;
using MoonSharp.Interpreter.Tree;
using MoonSharp.Interpreter.Tree.Statements;
namespace MoonSharp.Interpreter.Execution
{
internal class BuildTimeScope
{
List<BuildTimeScopeFrame> m_Frames = new List<BuildTimeScopeFrame>();
List<IClosureBuilder> m_ClosureBuilders = new List<IClosureBuilder>();
public void PushFunction(IClosureBuilder closureBuilder)
{
m_ClosureBuilders.Add(closureBuilder);
m_Frames.Add(new BuildTimeScopeFrame());
}
public void SetHasVarArgs()
{
m_Frames.Last().HasVarArgs = true;
}
public void PushBlock()
{
m_Frames.Last().PushBlock();
}
public RuntimeScopeBlock PopBlock()
{
return m_Frames.Last().PopBlock();
}
public RuntimeScopeFrame PopFunction()
{
var last = m_Frames.Last();
last.ResolveLRefs();
m_Frames.RemoveAt(m_Frames.Count - 1);
m_ClosureBuilders.RemoveAt(m_ClosureBuilders.Count - 1);
return last.GetRuntimeFrameData();
}
public SymbolRef Find(string name)
{
SymbolRef local = m_Frames.Last().Find(name);
if (local != null)
return local;
for (int i = m_Frames.Count - 2; i >= 0; i--)
{
SymbolRef symb = m_Frames[i].Find(name);
if (symb != null)
{
symb = CreateUpValue(this, symb, i, m_Frames.Count - 2);
if (symb != null)
return symb;
}
}
return CreateGlobalReference(name);
}
public SymbolRef CreateGlobalReference(string name)
{
if (name == WellKnownSymbols.ENV)
throw new InternalErrorException("_ENV passed in CreateGlobalReference");
SymbolRef env = Find(WellKnownSymbols.ENV);
return SymbolRef.Global(name, env);
}
public void ForceEnvUpValue()
{
Find(WellKnownSymbols.ENV);
}
private SymbolRef CreateUpValue(BuildTimeScope buildTimeScope, SymbolRef symb, int closuredFrame, int currentFrame)
{
// it's a 0-level upvalue. Just create it and we're done.
if (closuredFrame == currentFrame)
return m_ClosureBuilders[currentFrame + 1].CreateUpvalue(this, symb);
SymbolRef upvalue = CreateUpValue(buildTimeScope, symb, closuredFrame, currentFrame - 1);
return m_ClosureBuilders[currentFrame + 1].CreateUpvalue(this, upvalue);
}
public SymbolRef DefineLocal(string name)
{
return m_Frames.Last().DefineLocal(name);
}
public SymbolRef TryDefineLocal(string name)
{
return m_Frames.Last().TryDefineLocal(name);
}
public bool CurrentFunctionHasVarArgs()
{
return m_Frames.Last().HasVarArgs;
}
internal void DefineLabel(LabelStatement label)
{
m_Frames.Last().DefineLabel(label);
}
internal void RegisterGoto(GotoStatement gotostat)
{
m_Frames.Last().RegisterGoto(gotostat);
}
}
}