From 0055f2fdb169788a7796821d20c7fba2230ea9ae Mon Sep 17 00:00:00 2001 From: Li Jin Date: Mon, 14 Mar 2022 13:46:17 +0800 Subject: fix more cases that global values are not being cached. --- spec/inputs/cond.yue | 11 +++++++++++ spec/inputs/with.yue | 13 +++++++++++++ spec/outputs/cond.lua | 22 ++++++++++++++++++++++ spec/outputs/with.lua | 37 +++++++++++++++++++++++++++++++++---- 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 if :pi = math print pi +do + if _M = {} + :Thing = _M + :a, :b = _M + +do + global _M + if _M = {} + :Thing = _M + :a, :b = _M + nil 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 with dad .if "yes" y = .end.of.function + +do + global mask + with? mask = SolidRect width: w, height: h, color: 0x66000000 + .touchEnabled = true + .swallowTouches = true + +do + with? mask = SolidRect width: w, height: h, color: 0x66000000 + .touchEnabled = true + .swallowTouches = true + +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 print(pi) end end +do + do + local _M = { } + if _M then + local Thing = _M.Thing + a, b = _M.a, _M.b + end + end +end +do + do + local _des_0 = { } + if _des_0 then + _M = _des_0 + local Thing = _M.Thing + do + local _obj_0 = _M + a, b = _obj_0.a, _obj_0.b + end + end + end +end 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 end end do - local _with_0 = dad - _with_0["if"]("yes") - local y = _with_0["end"].of["function"] - return _with_0 + do + local _with_0 = dad + _with_0["if"]("yes") + local y = _with_0["end"].of["function"] + end +end +do + do + local _with_0 = SolidRect({ + width = w, + height = h, + color = 0x66000000 + }) + mask = _with_0 + if _with_0 ~= nil then + _with_0.touchEnabled = true + _with_0.swallowTouches = true + end + end +end +do + do + local mask = SolidRect({ + width = w, + height = h, + color = 0x66000000 + }) + if mask ~= nil then + mask.touchEnabled = true + mask.swallowTouches = true + end + end end +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; typedef std::list str_list; -const std::string_view version = "0.10.6"sv; +const std::string_view version = "0.10.7"sv; const std::string_view extension = "yue"sv; class YueCompilerImpl { @@ -279,12 +279,7 @@ private: int mode = int(std::isupper(name[0]) ? GlobalMode::Capital : GlobalMode::Any); const auto& current = _scopes.back(); if (int(current.mode) >= mode) { - if (current.globals) { - if (current.globals->find(name) != current.globals->end()) { - isDefined = true; - current.vars->insert_or_assign(name, VarType::Global); - } - } else { + if (!current.globals) { isDefined = true; current.vars->insert_or_assign(name, VarType::Global); } @@ -309,16 +304,29 @@ private: } bool isLocal(const std::string& name) const { - bool isDefined = false; + bool local = false; for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { auto vars = it->vars.get(); auto vit = vars->find(name); if (vit != vars->end() && vit->second != VarType::Global) { - isDefined = true; + local = true; break; } } - return isDefined; + return local; + } + + bool isGlobal(const std::string& name) const { + bool global = false; + for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { + auto vars = it->vars.get(); + auto vit = vars->find(name); + if (vit != vars->end() && vit->second == VarType::Global) { + global = true; + break; + } + } + return global; } bool isConst(const std::string& name) const { @@ -371,6 +379,7 @@ private: scope.globals = std::make_unique>(); } scope.globals->insert(name); + scope.vars->insert_or_assign(name, VarType::Global); } void addToAllowList(const std::string& name) { @@ -1399,9 +1408,9 @@ private: _buf << indent() << "local "sv << pair.name << nll(assignment); } } - bool valueDefined = isDefined(destruct.value); + bool isLocalValue = isLocal(destruct.value); std::string objVar; - if (valueDefined) { + if (isLocalValue) { objVar = destruct.value; } else { _buf << indent() << "do"sv << nll(assignment); @@ -1414,7 +1423,7 @@ private: auto valueExp = toAst(objVar + pair.structure, assignment); transformExp(valueExp, temp, ExpUsage::Closure); _buf << indent() << pair.name << " = "sv << temp.back() << nll(assignment); - if (!valueDefined) { + if (!isLocalValue) { popScope(); _buf << indent() << "end"sv << nlr(assignment); } @@ -1428,7 +1437,7 @@ private: _buf << pair.name << " = "sv << destruct.value << pair.structure << nll(assignment); temp.push_back(clearBuf()); } - } else if (_parser.match(destruct.value) && isDefined(destruct.value)) { + } else if (_parser.match(destruct.value) && isLocal(destruct.value)) { str_list defs, names, values; bool isMetatable = false; for (auto& item : destruct.items) { @@ -2223,7 +2232,7 @@ private: _config.lintGlobalVariable = false; auto var = singleVariableFrom(exp); _config.lintGlobalVariable = lintGlobal; - if (var.empty()) { + if (var.empty() || isGlobal(var)) { storingValue = true; auto desVar = getUnusedName("_des_"sv); if (asmt->assign->values.objects().size() == 1) { @@ -5547,7 +5556,7 @@ private: bool scoped = false; if (with->assigns) { auto vars = getAssignVars(with); - if (vars.front().empty()) { + if (vars.front().empty() || isGlobal(vars.front())) { if (with->assigns->values.objects().size() == 1) { auto var = singleVariableFrom(with->assigns->values.objects().front()); if (!var.empty() && isLocal(var)) { -- cgit v1.2.3-55-g6feb