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.
Diffstat (limited to '')
| -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)) { |
