diff options
| author | Li Jin <dragon-fly@qq.com> | 2020-01-10 16:30:34 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2020-01-10 16:30:34 +0800 |
| commit | 52a6536103f46c26a3ba9b149b0fe7b40d524d8c (patch) | |
| tree | 67e4759f8e1ea922079d0e162d84ecba5e558261 /src/MoonP/moon_compiler.cpp | |
| parent | 975167856ed0b11c2ede03c6eb750ca4e4a6a7fc (diff) | |
| download | yuescript-52a6536103f46c26a3ba9b149b0fe7b40d524d8c.tar.gz yuescript-52a6536103f46c26a3ba9b149b0fe7b40d524d8c.tar.bz2 yuescript-52a6536103f46c26a3ba9b149b0fe7b40d524d8c.zip | |
update.
Diffstat (limited to '')
| -rw-r--r-- | src/MoonP/moon_compiler.cpp (renamed from MoonParser/moon_compiler.cpp) | 154 |
1 files changed, 84 insertions, 70 deletions
diff --git a/MoonParser/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 85b19ff..f9a86a6 100644 --- a/MoonParser/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | /* Copyright (c) 2020 Jin Li, http://www.luvfight.me | ||
| 2 | |||
| 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
| 4 | |||
| 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
| 6 | |||
| 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ | ||
| 8 | |||
| 1 | #include <string> | 9 | #include <string> |
| 2 | #include <unordered_set> | 10 | #include <unordered_set> |
| 3 | #include <unordered_map> | 11 | #include <unordered_map> |
| @@ -8,9 +16,9 @@ | |||
| 8 | #include <sstream> | 16 | #include <sstream> |
| 9 | #include <string_view> | 17 | #include <string_view> |
| 10 | using namespace std::string_view_literals; | 18 | using namespace std::string_view_literals; |
| 11 | #include "parser.hpp" | 19 | #include "MoonP/parser.hpp" |
| 12 | #include "moon_ast.h" | 20 | #include "MoonP/moon_ast.h" |
| 13 | #include "moon_compiler.h" | 21 | #include "MoonP/moon_compiler.h" |
| 14 | 22 | ||
| 15 | namespace MoonP { | 23 | namespace MoonP { |
| 16 | 24 | ||
| @@ -24,12 +32,19 @@ inline std::string s(std::string_view sv) { | |||
| 24 | return std::string(sv); | 32 | return std::string(sv); |
| 25 | } | 33 | } |
| 26 | 34 | ||
| 35 | const char* moonScriptVersion() { | ||
| 36 | return "0.5.0"; | ||
| 37 | } | ||
| 38 | |||
| 27 | class MoonCompliler { | 39 | class MoonCompliler { |
| 28 | public: | 40 | public: |
| 29 | std::pair<std::string,std::string> complile(const std::string& codes, bool lintGlobalVar, bool implicitReturnRoot, bool lineNumber) { | 41 | std::pair<std::string,std::string> complile(const std::string& codes, const MoonConfig& config) { |
| 30 | _lintGlobalVar = lintGlobalVar; | 42 | _config = config; |
| 31 | _lineNumber = lineNumber; | 43 | try { |
| 32 | _input = _converter.from_bytes(codes); | 44 | _input = _converter.from_bytes(codes); |
| 45 | } catch (const std::range_error&) { | ||
| 46 | return {Empty, "Invalid text encoding."}; | ||
| 47 | } | ||
| 33 | error_list el; | 48 | error_list el; |
| 34 | State st; | 49 | State st; |
| 35 | ast_ptr<false, File_t> root; | 50 | ast_ptr<false, File_t> root; |
| @@ -43,7 +58,7 @@ public: | |||
| 43 | try { | 58 | try { |
| 44 | str_list out; | 59 | str_list out; |
| 45 | pushScope(); | 60 | pushScope(); |
| 46 | transformBlock(root->block, out, implicitReturnRoot); | 61 | transformBlock(root->block, out, config.implicitReturnRoot); |
| 47 | popScope(); | 62 | popScope(); |
| 48 | return {std::move(out.back()), Empty}; | 63 | return {std::move(out.back()), Empty}; |
| 49 | } catch (const std::logic_error& error) { | 64 | } catch (const std::logic_error& error) { |
| @@ -82,8 +97,7 @@ public: | |||
| 82 | _input.clear(); | 97 | _input.clear(); |
| 83 | } | 98 | } |
| 84 | private: | 99 | private: |
| 85 | bool _lintGlobalVar = false; | 100 | MoonConfig _config; |
| 86 | bool _lineNumber = false; | ||
| 87 | int _indentOffset = 0; | 101 | int _indentOffset = 0; |
| 88 | Converter _converter; | 102 | Converter _converter; |
| 89 | input _input; | 103 | input _input; |
| @@ -143,12 +157,6 @@ private: | |||
| 143 | Closure | 157 | Closure |
| 144 | }; | 158 | }; |
| 145 | 159 | ||
| 146 | enum class IfUsage { | ||
| 147 | Return, | ||
| 148 | Closure, | ||
| 149 | Common | ||
| 150 | }; | ||
| 151 | |||
| 152 | void pushScope() { | 160 | void pushScope() { |
| 153 | _scopes.emplace_back(); | 161 | _scopes.emplace_back(); |
| 154 | _scopes.back().vars = std::make_unique<std::unordered_set<std::string>>(); | 162 | _scopes.back().vars = std::make_unique<std::unordered_set<std::string>>(); |
| @@ -256,7 +264,7 @@ private: | |||
| 256 | } | 264 | } |
| 257 | 265 | ||
| 258 | const std::string nll(ast_node* node) { | 266 | const std::string nll(ast_node* node) { |
| 259 | if (_lineNumber) { | 267 | if (_config.reserveLineNumber) { |
| 260 | return s(" -- "sv) + std::to_string(node->m_begin.m_line) + _newLine; | 268 | return s(" -- "sv) + std::to_string(node->m_begin.m_line) + _newLine; |
| 261 | } else { | 269 | } else { |
| 262 | return _newLine; | 270 | return _newLine; |
| @@ -264,7 +272,7 @@ private: | |||
| 264 | } | 272 | } |
| 265 | 273 | ||
| 266 | const std::string nlr(ast_node* node) { | 274 | const std::string nlr(ast_node* node) { |
| 267 | if (_lineNumber) { | 275 | if (_config.reserveLineNumber) { |
| 268 | return s(" -- "sv) + std::to_string(node->m_end.m_line) + _newLine; | 276 | return s(" -- "sv) + std::to_string(node->m_end.m_line) + _newLine; |
| 269 | } else { | 277 | } else { |
| 270 | return _newLine; | 278 | return _newLine; |
| @@ -280,11 +288,11 @@ private: | |||
| 280 | } | 288 | } |
| 281 | 289 | ||
| 282 | std::string indent() { | 290 | std::string indent() { |
| 283 | return std::string((_scopes.size() - 1 + _indentOffset) * 2, ' '); | 291 | return _config.spaceOverTab ? std::string((_scopes.size() - 1 + _indentOffset) * 2, ' ') : std::string(_scopes.size() - 1 + _indentOffset, '\t'); |
| 284 | } | 292 | } |
| 285 | 293 | ||
| 286 | std::string indent(int offset) { | 294 | std::string indent(int offset) { |
| 287 | return std::string((_scopes.size() - 1 + _indentOffset + offset) * 2, ' '); | 295 | return _config.spaceOverTab ? std::string((_scopes.size() - 1 + _indentOffset + offset) * 2, ' ') : std::string(_scopes.size() - 1 + _indentOffset + offset, '\t'); |
| 288 | } | 296 | } |
| 289 | 297 | ||
| 290 | std::string clearBuf() { | 298 | std::string clearBuf() { |
| @@ -699,12 +707,16 @@ private: | |||
| 699 | } | 707 | } |
| 700 | } | 708 | } |
| 701 | } | 709 | } |
| 702 | auto assign = x->new_ptr<Assign_t>(); | 710 | if (_config.allowExprNotInTheEndOfBody) { |
| 703 | assign->values.dup(expList->exprs); | 711 | auto assign = x->new_ptr<Assign_t>(); |
| 704 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 712 | assign->values.dup(expList->exprs); |
| 705 | assignment->expList.set(toAst<ExpList_t>("_", ExpList, x)); | 713 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| 706 | assignment->action.set(assign); | 714 | assignment->expList.set(toAst<ExpList_t>("_", ExpList, x)); |
| 707 | transformAssignment(assignment, out); | 715 | assignment->action.set(assign); |
| 716 | transformAssignment(assignment, out); | ||
| 717 | } else { | ||
| 718 | throw std::logic_error(debugInfo("Expression list must appear at the end of body block."sv, expList)); | ||
| 719 | } | ||
| 708 | } | 720 | } |
| 709 | break; | 721 | break; |
| 710 | } | 722 | } |
| @@ -1051,7 +1063,7 @@ private: | |||
| 1051 | void transformAssignItem(ast_node* value, str_list& out) { | 1063 | void transformAssignItem(ast_node* value, str_list& out) { |
| 1052 | switch (value->getId()) { | 1064 | switch (value->getId()) { |
| 1053 | case "With"_id: transformWithClosure(static_cast<With_t*>(value), out); break; | 1065 | case "With"_id: transformWithClosure(static_cast<With_t*>(value), out); break; |
| 1054 | case "If"_id: transformIf(static_cast<If_t*>(value), out, IfUsage::Closure); break; | 1066 | case "If"_id: transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break; |
| 1055 | case "Switch"_id: transformSwitchClosure(static_cast<Switch_t*>(value), out); break; | 1067 | case "Switch"_id: transformSwitchClosure(static_cast<Switch_t*>(value), out); break; |
| 1056 | case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), out); break; | 1068 | case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), out); break; |
| 1057 | case "Exp"_id: transformExp(static_cast<Exp_t*>(value), out); break; | 1069 | case "Exp"_id: transformExp(static_cast<Exp_t*>(value), out); break; |
| @@ -1093,8 +1105,8 @@ private: | |||
| 1093 | s("["sv) + std::to_string(index) + s("]"sv) + p.structure}); | 1105 | s("["sv) + std::to_string(index) + s("]"sv) + p.structure}); |
| 1094 | } | 1106 | } |
| 1095 | } else { | 1107 | } else { |
| 1096 | bool checkGlobal = _lintGlobalVar; | 1108 | bool lintGlobal = _config.lintGlobalVariable; |
| 1097 | _lintGlobalVar = false; | 1109 | _config.lintGlobalVariable = false; |
| 1098 | auto exp = static_cast<Exp_t*>(pair); | 1110 | auto exp = static_cast<Exp_t*>(pair); |
| 1099 | auto varName = singleVariableFrom(exp); | 1111 | auto varName = singleVariableFrom(exp); |
| 1100 | bool isVariable = !varName.empty(); | 1112 | bool isVariable = !varName.empty(); |
| @@ -1103,7 +1115,7 @@ private: | |||
| 1103 | transformExp(exp, temp); | 1115 | transformExp(exp, temp); |
| 1104 | varName = std::move(temp.back()); | 1116 | varName = std::move(temp.back()); |
| 1105 | } | 1117 | } |
| 1106 | _lintGlobalVar = checkGlobal; | 1118 | _config.lintGlobalVariable = lintGlobal; |
| 1107 | pairs.push_back({ | 1119 | pairs.push_back({ |
| 1108 | isVariable, | 1120 | isVariable, |
| 1109 | varName, | 1121 | varName, |
| @@ -1133,8 +1145,8 @@ private: | |||
| 1133 | s("."sv) + toString(key) + p.structure}); | 1145 | s("."sv) + toString(key) + p.structure}); |
| 1134 | } | 1146 | } |
| 1135 | } else { | 1147 | } else { |
| 1136 | bool checkGlobal = _lintGlobalVar; | 1148 | bool lintGlobal = _config.lintGlobalVariable; |
| 1137 | _lintGlobalVar = false; | 1149 | _config.lintGlobalVariable = false; |
| 1138 | auto varName = singleVariableFrom(exp); | 1150 | auto varName = singleVariableFrom(exp); |
| 1139 | bool isVariable = !varName.empty(); | 1151 | bool isVariable = !varName.empty(); |
| 1140 | if (!isVariable) { | 1152 | if (!isVariable) { |
| @@ -1142,7 +1154,7 @@ private: | |||
| 1142 | transformExp(exp, temp); | 1154 | transformExp(exp, temp); |
| 1143 | varName = std::move(temp.back()); | 1155 | varName = std::move(temp.back()); |
| 1144 | } | 1156 | } |
| 1145 | _lintGlobalVar = checkGlobal; | 1157 | _config.lintGlobalVariable = lintGlobal; |
| 1146 | pairs.push_back({ | 1158 | pairs.push_back({ |
| 1147 | isVariable, | 1159 | isVariable, |
| 1148 | varName, | 1160 | varName, |
| @@ -1322,7 +1334,7 @@ private: | |||
| 1322 | } | 1334 | } |
| 1323 | } | 1335 | } |
| 1324 | 1336 | ||
| 1325 | void transformCond(const node_container& nodes, str_list& out, IfUsage usage = IfUsage::Common, bool unless = false) { | 1337 | void transformCond(const node_container& nodes, str_list& out, ExpUsage usage = ExpUsage::Common, bool unless = false) { |
| 1326 | std::vector<ast_ptr<false, ast_node>> ns(false); | 1338 | std::vector<ast_ptr<false, ast_node>> ns(false); |
| 1327 | for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) { | 1339 | for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) { |
| 1328 | ns.push_back(*it); | 1340 | ns.push_back(*it); |
| @@ -1362,7 +1374,7 @@ private: | |||
| 1362 | return; | 1374 | return; |
| 1363 | } | 1375 | } |
| 1364 | str_list temp; | 1376 | str_list temp; |
| 1365 | if (usage == IfUsage::Closure) { | 1377 | if (usage == ExpUsage::Closure) { |
| 1366 | temp.push_back(s("(function()"sv) + nll(nodes.front())); | 1378 | temp.push_back(s("(function()"sv) + nll(nodes.front())); |
| 1367 | pushScope(); | 1379 | pushScope(); |
| 1368 | } | 1380 | } |
| @@ -1389,7 +1401,7 @@ private: | |||
| 1389 | auto var = singleVariableFrom(exp); | 1401 | auto var = singleVariableFrom(exp); |
| 1390 | if (var.empty()) { | 1402 | if (var.empty()) { |
| 1391 | storingValue = true; | 1403 | storingValue = true; |
| 1392 | std::string desVar = getUnusedName("_des_"); | 1404 | auto desVar = getUnusedName("_des_"); |
| 1393 | if (assign->values.objects().size() == 1) { | 1405 | if (assign->values.objects().size() == 1) { |
| 1394 | auto var = singleVariableFrom(assign->values.objects().front()); | 1406 | auto var = singleVariableFrom(assign->values.objects().front()); |
| 1395 | if (!var.empty()) { | 1407 | if (!var.empty()) { |
| @@ -1398,7 +1410,7 @@ private: | |||
| 1398 | } | 1410 | } |
| 1399 | } | 1411 | } |
| 1400 | if (storingValue) { | 1412 | if (storingValue) { |
| 1401 | if (usage != IfUsage::Closure) { | 1413 | if (usage != ExpUsage::Closure) { |
| 1402 | temp.push_back(indent() + s("do"sv) + nll(assign)); | 1414 | temp.push_back(indent() + s("do"sv) + nll(assign)); |
| 1403 | pushScope(); | 1415 | pushScope(); |
| 1404 | } | 1416 | } |
| @@ -1423,7 +1435,7 @@ private: | |||
| 1423 | } else { | 1435 | } else { |
| 1424 | if (!isDefined(var)) { | 1436 | if (!isDefined(var)) { |
| 1425 | storingValue = true; | 1437 | storingValue = true; |
| 1426 | if (usage != IfUsage::Closure) { | 1438 | if (usage != ExpUsage::Closure) { |
| 1427 | temp.push_back(indent() + s("do"sv) + nll(assign)); | 1439 | temp.push_back(indent() + s("do"sv) + nll(assign)); |
| 1428 | pushScope(); | 1440 | pushScope(); |
| 1429 | } | 1441 | } |
| @@ -1467,7 +1479,7 @@ private: | |||
| 1467 | if (pair == ifCondPairs.front() && extraAssignment) { | 1479 | if (pair == ifCondPairs.front() && extraAssignment) { |
| 1468 | transformAssignment(extraAssignment, temp); | 1480 | transformAssignment(extraAssignment, temp); |
| 1469 | } | 1481 | } |
| 1470 | transformBody(pair.second, temp, usage != IfUsage::Common); | 1482 | transformBody(pair.second, temp, usage != ExpUsage::Common); |
| 1471 | popScope(); | 1483 | popScope(); |
| 1472 | } | 1484 | } |
| 1473 | if (!pair.first) { | 1485 | if (!pair.first) { |
| @@ -1475,22 +1487,22 @@ private: | |||
| 1475 | break; | 1487 | break; |
| 1476 | } | 1488 | } |
| 1477 | } | 1489 | } |
| 1478 | if (storingValue && usage != IfUsage::Closure) { | 1490 | if (storingValue && usage != ExpUsage::Closure) { |
| 1479 | popScope(); | 1491 | popScope(); |
| 1480 | temp.push_back(indent() + s("end"sv) + nlr(nodes.front())); | 1492 | temp.push_back(indent() + s("end"sv) + nlr(nodes.front())); |
| 1481 | } | 1493 | } |
| 1482 | if (usage == IfUsage::Closure) { | 1494 | if (usage == ExpUsage::Closure) { |
| 1483 | popScope(); | 1495 | popScope(); |
| 1484 | temp.push_back(indent() + s("end)()"sv)); | 1496 | temp.push_back(indent() + s("end)()"sv)); |
| 1485 | } | 1497 | } |
| 1486 | out.push_back(join(temp)); | 1498 | out.push_back(join(temp)); |
| 1487 | } | 1499 | } |
| 1488 | 1500 | ||
| 1489 | void transformIf(If_t* ifNode, str_list& out, IfUsage usage = IfUsage::Common) { | 1501 | void transformIf(If_t* ifNode, str_list& out, ExpUsage usage = ExpUsage::Common) { |
| 1490 | transformCond(ifNode->nodes.objects(), out, usage); | 1502 | transformCond(ifNode->nodes.objects(), out, usage); |
| 1491 | } | 1503 | } |
| 1492 | 1504 | ||
| 1493 | void transformUnless(Unless_t* unless, str_list& out, IfUsage usage = IfUsage::Common) { | 1505 | void transformUnless(Unless_t* unless, str_list& out, ExpUsage usage = ExpUsage::Common) { |
| 1494 | transformCond(unless->nodes.objects(), out, usage, true); | 1506 | transformCond(unless->nodes.objects(), out, usage, true); |
| 1495 | } | 1507 | } |
| 1496 | 1508 | ||
| @@ -1545,7 +1557,7 @@ private: | |||
| 1545 | switch (item->getId()) { | 1557 | switch (item->getId()) { |
| 1546 | case "Variable"_id: { | 1558 | case "Variable"_id: { |
| 1547 | transformVariable(static_cast<Variable_t*>(item), out); | 1559 | transformVariable(static_cast<Variable_t*>(item), out); |
| 1548 | if (_lintGlobalVar && !isDefined(out.back())) { | 1560 | if (_config.lintGlobalVariable && !isDefined(out.back())) { |
| 1549 | if (_globals.find(out.back()) == _globals.end()) { | 1561 | if (_globals.find(out.back()) == _globals.end()) { |
| 1550 | _globals[out.back()] = {item->m_begin.m_line, item->m_begin.m_col}; | 1562 | _globals[out.back()] = {item->m_begin.m_line, item->m_begin.m_col}; |
| 1551 | } | 1563 | } |
| @@ -1553,7 +1565,7 @@ private: | |||
| 1553 | break; | 1565 | break; |
| 1554 | } | 1566 | } |
| 1555 | case "SelfName"_id: { transformSelfName(static_cast<SelfName_t*>(item), out, invoke); | 1567 | case "SelfName"_id: { transformSelfName(static_cast<SelfName_t*>(item), out, invoke); |
| 1556 | if (_lintGlobalVar) { | 1568 | if (_config.lintGlobalVariable) { |
| 1557 | std::string self("self"sv); | 1569 | std::string self("self"sv); |
| 1558 | if (!isDefined(self)) { | 1570 | if (!isDefined(self)) { |
| 1559 | if (_globals.find(self) == _globals.end()) { | 1571 | if (_globals.find(self) == _globals.end()) { |
| @@ -1579,8 +1591,8 @@ private: | |||
| 1579 | auto value = simpleValue->value.get(); | 1591 | auto value = simpleValue->value.get(); |
| 1580 | switch (value->getId()) { | 1592 | switch (value->getId()) { |
| 1581 | case "const_value"_id: transform_const_value(static_cast<const_value_t*>(value), out); break; | 1593 | case "const_value"_id: transform_const_value(static_cast<const_value_t*>(value), out); break; |
| 1582 | case "If"_id: transformIf(static_cast<If_t*>(value), out, IfUsage::Closure); break; | 1594 | case "If"_id: transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break; |
| 1583 | case "Unless"_id: transformUnless(static_cast<Unless_t*>(value), out, IfUsage::Closure); break; | 1595 | case "Unless"_id: transformUnless(static_cast<Unless_t*>(value), out, ExpUsage::Closure); break; |
| 1584 | case "Switch"_id: transformSwitchClosure(static_cast<Switch_t*>(value), out); break; | 1596 | case "Switch"_id: transformSwitchClosure(static_cast<Switch_t*>(value), out); break; |
| 1585 | case "With"_id: transformWithClosure(static_cast<With_t*>(value), out); break; | 1597 | case "With"_id: transformWithClosure(static_cast<With_t*>(value), out); break; |
| 1586 | case "ClassDecl"_id: transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break; | 1598 | case "ClassDecl"_id: transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break; |
| @@ -1790,10 +1802,10 @@ private: | |||
| 1790 | transformForEachInPlace(static_cast<ForEach_t*>(value), out); | 1802 | transformForEachInPlace(static_cast<ForEach_t*>(value), out); |
| 1791 | return; | 1803 | return; |
| 1792 | case "If"_id: | 1804 | case "If"_id: |
| 1793 | transformIf(static_cast<If_t*>(value), out, IfUsage::Return); | 1805 | transformIf(static_cast<If_t*>(value), out, ExpUsage::Return); |
| 1794 | return; | 1806 | return; |
| 1795 | case "Unless"_id: | 1807 | case "Unless"_id: |
| 1796 | transformUnless(static_cast<Unless_t*>(value), out, IfUsage::Return); | 1808 | transformUnless(static_cast<Unless_t*>(value), out, ExpUsage::Return); |
| 1797 | return; | 1809 | return; |
| 1798 | } | 1810 | } |
| 1799 | } | 1811 | } |
| @@ -2075,7 +2087,7 @@ private: | |||
| 2075 | throw std::logic_error(debugInfo("Colon chain item must be followed by invoke arguments."sv, colonItem)); | 2087 | throw std::logic_error(debugInfo("Colon chain item must be followed by invoke arguments."sv, colonItem)); |
| 2076 | } | 2088 | } |
| 2077 | if (colonItem->name.is<LuaKeyword_t>()) { | 2089 | if (colonItem->name.is<LuaKeyword_t>()) { |
| 2078 | auto callVar = getUnusedName(s("_call_"sv)); | 2090 | std::string callVar; |
| 2079 | auto block = x->new_ptr<Block_t>(); | 2091 | auto block = x->new_ptr<Block_t>(); |
| 2080 | { | 2092 | { |
| 2081 | auto chainValue = x->new_ptr<ChainValue_t>(); | 2093 | auto chainValue = x->new_ptr<ChainValue_t>(); |
| @@ -2092,14 +2104,18 @@ private: | |||
| 2092 | value->item.set(chainValue); | 2104 | value->item.set(chainValue); |
| 2093 | auto exp = x->new_ptr<Exp_t>(); | 2105 | auto exp = x->new_ptr<Exp_t>(); |
| 2094 | exp->value.set(value); | 2106 | exp->value.set(value); |
| 2095 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 2107 | callVar = singleVariableFrom(exp); |
| 2096 | assignment->expList.set(toAst<ExpList_t>(callVar, ExpList, x)); | 2108 | if (callVar.empty()) { |
| 2097 | auto assign = x->new_ptr<Assign_t>(); | 2109 | callVar = getUnusedName(s("_call_"sv)); |
| 2098 | assign->values.push_back(exp); | 2110 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| 2099 | assignment->action.set(assign); | 2111 | assignment->expList.set(toAst<ExpList_t>(callVar, ExpList, x)); |
| 2100 | auto stmt = x->new_ptr<Statement_t>(); | 2112 | auto assign = x->new_ptr<Assign_t>(); |
| 2101 | stmt->content.set(assignment); | 2113 | assign->values.push_back(exp); |
| 2102 | block->statements.push_back(stmt); | 2114 | assignment->action.set(assign); |
| 2115 | auto stmt = x->new_ptr<Statement_t>(); | ||
| 2116 | stmt->content.set(assignment); | ||
| 2117 | block->statements.push_back(stmt); | ||
| 2118 | } | ||
| 2103 | } | 2119 | } |
| 2104 | { | 2120 | { |
| 2105 | auto name = toString(colonItem->name); | 2121 | auto name = toString(colonItem->name); |
| @@ -2226,7 +2242,7 @@ private: | |||
| 2226 | out.push_back(s(colonChainItem->switchToDot ? "."sv : ":"sv) + name); | 2242 | out.push_back(s(colonChainItem->switchToDot ? "."sv : ":"sv) + name); |
| 2227 | } | 2243 | } |
| 2228 | 2244 | ||
| 2229 | void transformSlice(Slice_t* slice, str_list& out) { | 2245 | void transformSlice(Slice_t* slice, str_list&) { |
| 2230 | throw std::logic_error(debugInfo("Slice syntax not supported here."sv, slice)); | 2246 | throw std::logic_error(debugInfo("Slice syntax not supported here."sv, slice)); |
| 2231 | } | 2247 | } |
| 2232 | 2248 | ||
| @@ -2408,7 +2424,8 @@ private: | |||
| 2408 | switch (loopTarget->getId()) { | 2424 | switch (loopTarget->getId()) { |
| 2409 | case "star_exp"_id: { | 2425 | case "star_exp"_id: { |
| 2410 | auto star_exp = static_cast<star_exp_t*>(loopTarget); | 2426 | auto star_exp = static_cast<star_exp_t*>(loopTarget); |
| 2411 | auto listVar = singleVariableFrom(star_exp->value); | 2427 | std::string listVar; |
| 2428 | if (_config.reuseVariable) listVar = singleVariableFrom(star_exp->value); | ||
| 2412 | auto indexVar = getUnusedName("_index_"); | 2429 | auto indexVar = getUnusedName("_index_"); |
| 2413 | varAfter.push_back(indexVar); | 2430 | varAfter.push_back(indexVar); |
| 2414 | auto value = singleValueFrom(star_exp->value); | 2431 | auto value = singleValueFrom(star_exp->value); |
| @@ -3230,7 +3247,7 @@ private: | |||
| 3230 | checkAssignable(with->valueList); | 3247 | checkAssignable(with->valueList); |
| 3231 | auto vars = getAssignVars(with); | 3248 | auto vars = getAssignVars(with); |
| 3232 | if (vars.front().empty()) { | 3249 | if (vars.front().empty()) { |
| 3233 | if (with->assigns->values.objects().size() == 1) { | 3250 | if (_config.reuseVariable && with->assigns->values.objects().size() == 1) { |
| 3234 | auto var = singleVariableFrom(with->assigns->values.objects().front()); | 3251 | auto var = singleVariableFrom(with->assigns->values.objects().front()); |
| 3235 | if (!var.empty()) { | 3252 | if (!var.empty()) { |
| 3236 | withVar = var; | 3253 | withVar = var; |
| @@ -3277,7 +3294,7 @@ private: | |||
| 3277 | transformAssignment(assignment, temp); | 3294 | transformAssignment(assignment, temp); |
| 3278 | } | 3295 | } |
| 3279 | } else { | 3296 | } else { |
| 3280 | withVar = singleVariableFrom(with->valueList); | 3297 | if (_config.reuseVariable) withVar = singleVariableFrom(with->valueList); |
| 3281 | if (withVar.empty()) { | 3298 | if (withVar.empty()) { |
| 3282 | withVar = getUnusedName("_with_"); | 3299 | withVar = getUnusedName("_with_"); |
| 3283 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 3300 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| @@ -3833,19 +3850,16 @@ private: | |||
| 3833 | 3850 | ||
| 3834 | const std::string MoonCompliler::Empty; | 3851 | const std::string MoonCompliler::Empty; |
| 3835 | 3852 | ||
| 3836 | std::pair<std::string,std::string> moonCompile(const std::string& codes, bool implicitReturnRoot, bool lineNumber) { | 3853 | std::tuple<std::string,std::string,GlobalVars> moonCompile(const std::string& codes, const MoonConfig& config) { |
| 3837 | return MoonCompliler{}.complile(codes, false, implicitReturnRoot, lineNumber); | ||
| 3838 | } | ||
| 3839 | |||
| 3840 | std::pair<std::string,std::string> moonCompile(const std::string& codes, std::list<GlobalVar>& globals, bool implicitReturnRoot, bool lineNumber) { | ||
| 3841 | auto compiler = MoonCompliler{}; | 3854 | auto compiler = MoonCompliler{}; |
| 3842 | auto result = compiler.complile(codes, true, implicitReturnRoot, lineNumber); | 3855 | auto result = compiler.complile(codes, config); |
| 3856 | auto globals = std::make_unique<std::list<GlobalVar>>(); | ||
| 3843 | for (const auto& var : compiler.getGlobals()) { | 3857 | for (const auto& var : compiler.getGlobals()) { |
| 3844 | int line,col; | 3858 | int line,col; |
| 3845 | std::tie(line,col) = var.second; | 3859 | std::tie(line,col) = var.second; |
| 3846 | globals.push_back({var.first, line, col}); | 3860 | globals->push_back({var.first, line, col}); |
| 3847 | } | 3861 | } |
| 3848 | return result; | 3862 | return std::make_tuple(std::move(result.first),std::move(result.second),std::move(globals)); |
| 3849 | } | 3863 | } |
| 3850 | 3864 | ||
| 3851 | } // namespace MoonP | 3865 | } // namespace MoonP |
