-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathFunction.cpp
More file actions
188 lines (153 loc) · 3.25 KB
/
Function.cpp
File metadata and controls
188 lines (153 loc) · 3.25 KB
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include "Function.h"
#include "Stack.h"
#include "State.h"
InstructionValue::InstructionValue():
_parentInsVal(nullptr), _insSet(nullptr),
_hasFor(false), _breaked(false)
{
}
void InstructionValue::clearInsSet()
{
if (_insSet) {
_insSet->clearInstructions();
}
}
Function::Function()
{
}
Function::~Function()
{
}
Closure* Function::generateClosure(State* s)
{
Closure* cl = new Closure(s);
cl->setPrototype(this);
return cl;
}
Closure::Closure(State* s)
:_state(s), _actParamNum(0),
_actRetNum(0), _needRetNum(0),
_prototype(nullptr),
_parentClosure(nullptr),
_upTables(nullptr)
{
}
void Closure::initClosure()
{
clearClosure();
_nest_tables.push_back(new Table());
}
void Closure::clearClosure()
{
_nest_tables.clear();
}
void Closure::balanceStack()
{
if (_needRetNum != -1) { //为-1时,表示无法计算需要的返回值,例如在f1(f2())
int n = _actRetNum - _needRetNum; //真实返回值个数-需要返回值个数
if (n > 0) { //f() + 2,如果f()真实返回了2个,但是这里只需要一个,故栈要弹出一个
while (n > 0) {
_state->getStack()->popValue();
n--;
}
}
else {
while (n < 0) { //f() + 2, 如果f()真实返回0个,但是这里需要一个,故要压入栈一个(貌似不压也行,因为后面赋值时会平衡)
_state->getStack()->Push(new Nil());
n++;
}
}
}
_actRetNum = 0;
_needRetNum = 0;
}
void Closure::addBlockTable()
{
_nest_tables.push_back(new Table());
}
void Closure::removeBlockTable()
{
Table* top = getTopTable();
if (top) {
delete top;
}
_nest_tables.pop_back();
}
Closure* Closure::clone()
{
Closure* cl = new Closure(_state);
cl->_needRetNum = _needRetNum;
cl->_actParamNum = _actRetNum;
cl->_actRetNum = _actRetNum;
cl->_parentClosure = _parentClosure;
cl->_prototype = _prototype;
if (_upTables) {
cl->_upTables = _upTables->clone();
}
return cl;
}
Table* Closure::getTopTable()
{
return getLevelTable(_nest_tables.size() - 1);
}
Table* Closure::getLevelTable(unsigned int i)
{
if (_nest_tables.size() == 0 || i >= _nest_tables.size()) {
return nullptr;
}
return _nest_tables[i];
}
void Closure::setParentClosure(Closure* c)
{
_parentClosure = c;
if (c) {
Table* topTab = c->getTopTable(); //只需拷贝最外层的局部变量,for循环里面的局部变量,子函数是不可见的
if (topTab) {
_upTables = topTab->clone();
}
}
}
int Closure::findInNestTables(Value* key, Value** val)
{
int num = _nest_tables.size();
Value* temp = nullptr;
for (int i = num - 1; i >= 0; i--) {
temp = _nest_tables[i]->GetValue(key);
if (temp) {
if (val) *val = temp;
return i;
}
}
return -1;
}
int Closure::findUpTables(Value* key, Value** val, Table** tab)
{
Closure* cl = this;
while (cl) {
int level = cl->findInNestTables(key, val);
if (level != -1) { //在当前闭包中找到
if (tab) *tab = cl->getLevelTable(level);
return 1;
}
cl = cl->_parentClosure;
}
if (_upTables) { //在其上值中找
Value* temp = _upTables->GetValue(key);
if (temp) {
if (val) *val = temp;
if (tab) *tab = _upTables;
return 2;
}
}
Table* table = getState()->getGlobalTable(); //已到了最顶层
Value* temp = table->GetValue(key);
if (temp) {
if (val) *val = temp;
if (tab) *tab = table;
return 0;
}
else {
return -1;
}
return -1;
}