summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-03-14 13:46:17 +0800
committerLi Jin <dragon-fly@qq.com>2022-03-14 13:46:17 +0800
commit0055f2fdb169788a7796821d20c7fba2230ea9ae (patch)
tree24ecbf48a03e2d4690a51d66e087f4585d196754
parent985761356280bf8625a6568dd83822aae83edc8f (diff)
downloadyuescript-0055f2fdb169788a7796821d20c7fba2230ea9ae.tar.gz
yuescript-0055f2fdb169788a7796821d20c7fba2230ea9ae.tar.bz2
yuescript-0055f2fdb169788a7796821d20c7fba2230ea9ae.zip
fix more cases that global values are not being cached.
-rw-r--r--spec/inputs/cond.yue11
-rw-r--r--spec/inputs/with.yue13
-rw-r--r--spec/outputs/cond.lua22
-rw-r--r--spec/outputs/with.lua37
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp41
5 files changed, 104 insertions, 20 deletions
diff --git a/spec/inputs/cond.yue b/spec/inputs/cond.yue
index 42b22a7..773ef91 100644
--- a/spec/inputs/cond.yue
+++ b/spec/inputs/cond.yue
@@ -208,6 +208,17 @@ do
208 if :pi = math 208 if :pi = math
209 print pi 209 print pi
210 210
211do
212 if _M = {}
213 :Thing = _M
214 :a, :b = _M
215
216do
217 global _M
218 if _M = {}
219 :Thing = _M
220 :a, :b = _M
221
211nil 222nil
212 223
213 224
diff --git a/spec/inputs/with.yue b/spec/inputs/with.yue
index d88e109..fe140ac 100644
--- a/spec/inputs/with.yue
+++ b/spec/inputs/with.yue
@@ -121,3 +121,16 @@ do
121 with dad 121 with dad
122 .if "yes" 122 .if "yes"
123 y = .end.of.function 123 y = .end.of.function
124
125do
126 global mask
127 with? mask = SolidRect width: w, height: h, color: 0x66000000
128 .touchEnabled = true
129 .swallowTouches = true
130
131do
132 with? mask = SolidRect width: w, height: h, color: 0x66000000
133 .touchEnabled = true
134 .swallowTouches = true
135
136nil
diff --git a/spec/outputs/cond.lua b/spec/outputs/cond.lua
index 4dc5aa5..178bf9b 100644
--- a/spec/outputs/cond.lua
+++ b/spec/outputs/cond.lua
@@ -313,4 +313,26 @@ do
313 print(pi) 313 print(pi)
314 end 314 end
315end 315end
316do
317 do
318 local _M = { }
319 if _M then
320 local Thing = _M.Thing
321 a, b = _M.a, _M.b
322 end
323 end
324end
325do
326 do
327 local _des_0 = { }
328 if _des_0 then
329 _M = _des_0
330 local Thing = _M.Thing
331 do
332 local _obj_0 = _M
333 a, b = _obj_0.a, _obj_0.b
334 end
335 end
336 end
337end
316return nil 338return nil
diff --git a/spec/outputs/with.lua b/spec/outputs/with.lua
index e1497c6..f172b01 100644
--- a/spec/outputs/with.lua
+++ b/spec/outputs/with.lua
@@ -157,8 +157,37 @@ do
157 end 157 end
158end 158end
159do 159do
160 local _with_0 = dad 160 do
161 _with_0["if"]("yes") 161 local _with_0 = dad
162 local y = _with_0["end"].of["function"] 162 _with_0["if"]("yes")
163 return _with_0 163 local y = _with_0["end"].of["function"]
164 end
165end
166do
167 do
168 local _with_0 = SolidRect({
169 width = w,
170 height = h,
171 color = 0x66000000
172 })
173 mask = _with_0
174 if _with_0 ~= nil then
175 _with_0.touchEnabled = true
176 _with_0.swallowTouches = true
177 end
178 end
179end
180do
181 do
182 local mask = SolidRect({
183 width = w,
184 height = h,
185 color = 0x66000000
186 })
187 if mask ~= nil then
188 mask.touchEnabled = true
189 mask.swallowTouches = true
190 end
191 end
164end 192end
193return nil
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 66130fa..047b2ab 100755
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -60,7 +60,7 @@ using namespace parserlib;
60 60
61typedef std::list<std::string> str_list; 61typedef std::list<std::string> str_list;
62 62
63const std::string_view version = "0.10.6"sv; 63const std::string_view version = "0.10.7"sv;
64const std::string_view extension = "yue"sv; 64const std::string_view extension = "yue"sv;
65 65
66class YueCompilerImpl { 66class YueCompilerImpl {
@@ -279,12 +279,7 @@ private:
279 int mode = int(std::isupper(name[0]) ? GlobalMode::Capital : GlobalMode::Any); 279 int mode = int(std::isupper(name[0]) ? GlobalMode::Capital : GlobalMode::Any);
280 const auto& current = _scopes.back(); 280 const auto& current = _scopes.back();
281 if (int(current.mode) >= mode) { 281 if (int(current.mode) >= mode) {
282 if (current.globals) { 282 if (!current.globals) {
283 if (current.globals->find(name) != current.globals->end()) {
284 isDefined = true;
285 current.vars->insert_or_assign(name, VarType::Global);
286 }
287 } else {
288 isDefined = true; 283 isDefined = true;
289 current.vars->insert_or_assign(name, VarType::Global); 284 current.vars->insert_or_assign(name, VarType::Global);
290 } 285 }
@@ -309,16 +304,29 @@ private:
309 } 304 }
310 305
311 bool isLocal(const std::string& name) const { 306 bool isLocal(const std::string& name) const {
312 bool isDefined = false; 307 bool local = false;
313 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { 308 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
314 auto vars = it->vars.get(); 309 auto vars = it->vars.get();
315 auto vit = vars->find(name); 310 auto vit = vars->find(name);
316 if (vit != vars->end() && vit->second != VarType::Global) { 311 if (vit != vars->end() && vit->second != VarType::Global) {
317 isDefined = true; 312 local = true;
318 break; 313 break;
319 } 314 }
320 } 315 }
321 return isDefined; 316 return local;
317 }
318
319 bool isGlobal(const std::string& name) const {
320 bool global = false;
321 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
322 auto vars = it->vars.get();
323 auto vit = vars->find(name);
324 if (vit != vars->end() && vit->second == VarType::Global) {
325 global = true;
326 break;
327 }
328 }
329 return global;
322 } 330 }
323 331
324 bool isConst(const std::string& name) const { 332 bool isConst(const std::string& name) const {
@@ -371,6 +379,7 @@ private:
371 scope.globals = std::make_unique<std::unordered_set<std::string>>(); 379 scope.globals = std::make_unique<std::unordered_set<std::string>>();
372 } 380 }
373 scope.globals->insert(name); 381 scope.globals->insert(name);
382 scope.vars->insert_or_assign(name, VarType::Global);
374 } 383 }
375 384
376 void addToAllowList(const std::string& name) { 385 void addToAllowList(const std::string& name) {
@@ -1399,9 +1408,9 @@ private:
1399 _buf << indent() << "local "sv << pair.name << nll(assignment); 1408 _buf << indent() << "local "sv << pair.name << nll(assignment);
1400 } 1409 }
1401 } 1410 }
1402 bool valueDefined = isDefined(destruct.value); 1411 bool isLocalValue = isLocal(destruct.value);
1403 std::string objVar; 1412 std::string objVar;
1404 if (valueDefined) { 1413 if (isLocalValue) {
1405 objVar = destruct.value; 1414 objVar = destruct.value;
1406 } else { 1415 } else {
1407 _buf << indent() << "do"sv << nll(assignment); 1416 _buf << indent() << "do"sv << nll(assignment);
@@ -1414,7 +1423,7 @@ private:
1414 auto valueExp = toAst<Exp_t>(objVar + pair.structure, assignment); 1423 auto valueExp = toAst<Exp_t>(objVar + pair.structure, assignment);
1415 transformExp(valueExp, temp, ExpUsage::Closure); 1424 transformExp(valueExp, temp, ExpUsage::Closure);
1416 _buf << indent() << pair.name << " = "sv << temp.back() << nll(assignment); 1425 _buf << indent() << pair.name << " = "sv << temp.back() << nll(assignment);
1417 if (!valueDefined) { 1426 if (!isLocalValue) {
1418 popScope(); 1427 popScope();
1419 _buf << indent() << "end"sv << nlr(assignment); 1428 _buf << indent() << "end"sv << nlr(assignment);
1420 } 1429 }
@@ -1428,7 +1437,7 @@ private:
1428 _buf << pair.name << " = "sv << destruct.value << pair.structure << nll(assignment); 1437 _buf << pair.name << " = "sv << destruct.value << pair.structure << nll(assignment);
1429 temp.push_back(clearBuf()); 1438 temp.push_back(clearBuf());
1430 } 1439 }
1431 } else if (_parser.match<Name_t>(destruct.value) && isDefined(destruct.value)) { 1440 } else if (_parser.match<Name_t>(destruct.value) && isLocal(destruct.value)) {
1432 str_list defs, names, values; 1441 str_list defs, names, values;
1433 bool isMetatable = false; 1442 bool isMetatable = false;
1434 for (auto& item : destruct.items) { 1443 for (auto& item : destruct.items) {
@@ -2223,7 +2232,7 @@ private:
2223 _config.lintGlobalVariable = false; 2232 _config.lintGlobalVariable = false;
2224 auto var = singleVariableFrom(exp); 2233 auto var = singleVariableFrom(exp);
2225 _config.lintGlobalVariable = lintGlobal; 2234 _config.lintGlobalVariable = lintGlobal;
2226 if (var.empty()) { 2235 if (var.empty() || isGlobal(var)) {
2227 storingValue = true; 2236 storingValue = true;
2228 auto desVar = getUnusedName("_des_"sv); 2237 auto desVar = getUnusedName("_des_"sv);
2229 if (asmt->assign->values.objects().size() == 1) { 2238 if (asmt->assign->values.objects().size() == 1) {
@@ -5547,7 +5556,7 @@ private:
5547 bool scoped = false; 5556 bool scoped = false;
5548 if (with->assigns) { 5557 if (with->assigns) {
5549 auto vars = getAssignVars(with); 5558 auto vars = getAssignVars(with);
5550 if (vars.front().empty()) { 5559 if (vars.front().empty() || isGlobal(vars.front())) {
5551 if (with->assigns->values.objects().size() == 1) { 5560 if (with->assigns->values.objects().size() == 1) {
5552 auto var = singleVariableFrom(with->assigns->values.objects().front()); 5561 auto var = singleVariableFrom(with->assigns->values.objects().front());
5553 if (!var.empty() && isLocal(var)) { 5562 if (!var.empty() && isLocal(var)) {