aboutsummaryrefslogtreecommitdiff
path: root/src/MoonP/moon_compiler.cpp
diff options
context:
space:
mode:
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
3Permission 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
5The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
7THE 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>
10using namespace std::string_view_literals; 18using 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
15namespace MoonP { 23namespace 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
35const char* moonScriptVersion() {
36 return "0.5.0";
37}
38
27class MoonCompliler { 39class MoonCompliler {
28public: 40public:
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 }
84private: 99private:
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
3834const std::string MoonCompliler::Empty; 3851const std::string MoonCompliler::Empty;
3835 3852
3836std::pair<std::string,std::string> moonCompile(const std::string& codes, bool implicitReturnRoot, bool lineNumber) { 3853std::tuple<std::string,std::string,GlobalVars> moonCompile(const std::string& codes, const MoonConfig& config) {
3837 return MoonCompliler{}.complile(codes, false, implicitReturnRoot, lineNumber);
3838}
3839
3840std::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