diff options
author | Li Jin <dragon-fly@qq.com> | 2022-03-14 13:46:17 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2022-03-14 13:46:17 +0800 |
commit | 0055f2fdb169788a7796821d20c7fba2230ea9ae (patch) | |
tree | 24ecbf48a03e2d4690a51d66e087f4585d196754 | |
parent | 985761356280bf8625a6568dd83822aae83edc8f (diff) | |
download | yuescript-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.yue | 11 | ||||
-rw-r--r-- | spec/inputs/with.yue | 13 | ||||
-rw-r--r-- | spec/outputs/cond.lua | 22 | ||||
-rw-r--r-- | spec/outputs/with.lua | 37 | ||||
-rwxr-xr-x | src/yuescript/yue_compiler.cpp | 41 |
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 | ||
211 | do | ||
212 | if _M = {} | ||
213 | :Thing = _M | ||
214 | :a, :b = _M | ||
215 | |||
216 | do | ||
217 | global _M | ||
218 | if _M = {} | ||
219 | :Thing = _M | ||
220 | :a, :b = _M | ||
221 | |||
211 | nil | 222 | nil |
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 | |||
125 | do | ||
126 | global mask | ||
127 | with? mask = SolidRect width: w, height: h, color: 0x66000000 | ||
128 | .touchEnabled = true | ||
129 | .swallowTouches = true | ||
130 | |||
131 | do | ||
132 | with? mask = SolidRect width: w, height: h, color: 0x66000000 | ||
133 | .touchEnabled = true | ||
134 | .swallowTouches = true | ||
135 | |||
136 | nil | ||
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 |
315 | end | 315 | end |
316 | do | ||
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 | ||
324 | end | ||
325 | do | ||
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 | ||
337 | end | ||
316 | return nil | 338 | return 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 |
158 | end | 158 | end |
159 | do | 159 | do |
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 | ||
165 | end | ||
166 | do | ||
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 | ||
179 | end | ||
180 | do | ||
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 | ||
164 | end | 192 | end |
193 | return 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 | ||
61 | typedef std::list<std::string> str_list; | 61 | typedef std::list<std::string> str_list; |
62 | 62 | ||
63 | const std::string_view version = "0.10.6"sv; | 63 | const std::string_view version = "0.10.7"sv; |
64 | const std::string_view extension = "yue"sv; | 64 | const std::string_view extension = "yue"sv; |
65 | 65 | ||
66 | class YueCompilerImpl { | 66 | class 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)) { |