diff options
Diffstat (limited to '')
| -rwxr-xr-x | src/yuescript/yue_compiler.cpp | 41 |
1 files changed, 25 insertions, 16 deletions
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)) { |
