aboutsummaryrefslogtreecommitdiff
path: root/src/yuescript/yue_compiler.cpp
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-08-19 18:05:31 +0800
committerLi Jin <dragon-fly@qq.com>2022-08-19 18:05:31 +0800
commit2ef8f936224fe8506673561d033142aeddcc44c1 (patch)
tree274c816874b28cf363d3aec0ef7c9a9b1a630c02 /src/yuescript/yue_compiler.cpp
parenta4d4893c77f9c48dedc88472a2e418bfd65e33a1 (diff)
downloadyuescript-2ef8f936224fe8506673561d033142aeddcc44c1.tar.gz
yuescript-2ef8f936224fe8506673561d033142aeddcc44c1.tar.bz2
yuescript-2ef8f936224fe8506673561d033142aeddcc44c1.zip
fix format.
Diffstat (limited to '')
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp353
1 files changed, 173 insertions, 180 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index b730a9f..17979ab 100755
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -6,23 +6,23 @@ The above copyright notice and this permission notice shall be included in all c
6 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.*/ 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 8
9#include <memory>
10#include <optional>
11#include <set>
12#include <stack>
9#include <string> 13#include <string>
10#include <unordered_set>
11#include <unordered_map> 14#include <unordered_map>
12#include <stack> 15#include <unordered_set>
13#include <vector> 16#include <vector>
14#include <memory>
15#include <set>
16#include <optional>
17 17
18#include "yuescript/yue_parser.h"
19#include "yuescript/yue_compiler.h" 18#include "yuescript/yue_compiler.h"
19#include "yuescript/yue_parser.h"
20 20
21#ifndef YUE_NO_MACRO 21#ifndef YUE_NO_MACRO
22 22
23extern "C" { 23extern "C" {
24#include "lua.h"
25#include "lauxlib.h" 24#include "lauxlib.h"
25#include "lua.h"
26#include "lualib.h" 26#include "lualib.h"
27} // extern "C" 27} // extern "C"
28 28
@@ -30,9 +30,9 @@ extern "C" {
30#define YUE_MODULE "__yue_modules__" 30#define YUE_MODULE "__yue_modules__"
31 31
32#if LUA_VERSION_NUM > 501 32#if LUA_VERSION_NUM > 501
33 #ifndef LUA_COMPAT_5_1 33#ifndef LUA_COMPAT_5_1
34 #define lua_objlen lua_rawlen 34#define lua_objlen lua_rawlen
35 #endif // LUA_COMPAT_5_1 35#endif // LUA_COMPAT_5_1
36#endif // LUA_VERSION_NUM 36#endif // LUA_VERSION_NUM
37 37
38#endif // YUE_NO_MACRO 38#endif // YUE_NO_MACRO
@@ -40,17 +40,22 @@ extern "C" {
40namespace yue { 40namespace yue {
41 41
42#define BLOCK_START do { 42#define BLOCK_START do {
43#define BLOCK_END } while (false); 43#define BLOCK_END \
44#define BREAK_IF(cond) if (cond) break 44 } \
45 45 while (false) \
46#define _DEFER(code,line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto){code;}) 46 ;
47#define DEFER(code) _DEFER(code,__LINE__) 47#define BREAK_IF(cond) \
48#define YUEE(msg,node) throw std::logic_error( \ 48 if (cond) break
49
50#define _DEFER(code, line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto) { code; })
51#define DEFER(code) _DEFER(code, __LINE__)
52#define YUEE(msg, node) throw std::logic_error( \
49 _info.errorMessage( \ 53 _info.errorMessage( \
50 "[File] "s + __FILE__ \ 54 "[File] "s + __FILE__ \
51 + ",\n[Func] "s + __FUNCTION__ \ 55 + ",\n[Func] "s + __FUNCTION__ \
52 + ",\n[Line] "s + std::to_string(__LINE__) \ 56 + ",\n[Line] "s + std::to_string(__LINE__) \
53 + ",\n[Error] "s + msg, node)) 57 + ",\n[Error] "s + msg, \
58 node))
54 59
55typedef std::list<std::string> str_list; 60typedef std::list<std::string> str_list;
56 61
@@ -62,9 +67,9 @@ public:
62#ifndef YUE_NO_MACRO 67#ifndef YUE_NO_MACRO
63 YueCompilerImpl(lua_State* sharedState, 68 YueCompilerImpl(lua_State* sharedState,
64 const std::function<void(void*)>& luaOpen, 69 const std::function<void(void*)>& luaOpen,
65 bool sameModule): 70 bool sameModule)
66 L(sharedState), 71 : L(sharedState)
67 _luaOpen(luaOpen) { 72 , _luaOpen(luaOpen) {
68 BLOCK_START 73 BLOCK_START
69 BREAK_IF(!sameModule); 74 BREAK_IF(!sameModule);
70 BREAK_IF(!L); 75 BREAK_IF(!L);
@@ -153,8 +158,7 @@ public:
153 std::tie(line, col) = var.second; 158 std::tie(line, col) = var.second;
154 globals->push_back({var.first, line, col}); 159 globals->push_back({var.first, line, col});
155 } 160 }
156 std::sort(globals->begin(), globals->end(), [](const GlobalVar& varA, const GlobalVar& varB) 161 std::sort(globals->begin(), globals->end(), [](const GlobalVar& varA, const GlobalVar& varB) {
157 {
158 if (varA.line < varB.line) { 162 if (varA.line < varB.line) {
159 return true; 163 return true;
160 } else if (varA.line == varB.line) { 164 } else if (varA.line == varB.line) {
@@ -222,6 +226,7 @@ public:
222 } 226 }
223#endif // YUE_NO_MACRO 227#endif // YUE_NO_MACRO
224 } 228 }
229
225private: 230private:
226#ifndef YUE_NO_MACRO 231#ifndef YUE_NO_MACRO
227 bool _stateOwner = false; 232 bool _stateOwner = false;
@@ -234,22 +239,20 @@ private:
234 YueParser _parser; 239 YueParser _parser;
235 ParseInfo _info; 240 ParseInfo _info;
236 int _indentOffset = 0; 241 int _indentOffset = 0;
237 struct VarArgState 242 struct VarArgState {
238 {
239 bool hasVar; 243 bool hasVar;
240 bool usedVar; 244 bool usedVar;
241 }; 245 };
242 std::stack<VarArgState> _varArgs; 246 std::stack<VarArgState> _varArgs;
243 std::stack<bool> _enableReturn; 247 std::stack<bool> _enableReturn;
244 std::stack<std::string> _withVars; 248 std::stack<std::string> _withVars;
245 struct ContinueVar 249 struct ContinueVar {
246 {
247 std::string var; 250 std::string var;
248 ast_ptr<false, ExpListAssign_t> condAssign; 251 ast_ptr<false, ExpListAssign_t> condAssign;
249 }; 252 };
250 std::stack<ContinueVar> _continueVars; 253 std::stack<ContinueVar> _continueVars;
251 std::list<std::unique_ptr<input>> _codeCache; 254 std::list<std::unique_ptr<input>> _codeCache;
252 std::unordered_map<std::string,std::pair<int, int>> _globals; 255 std::unordered_map<std::string, std::pair<int, int>> _globals;
253 std::ostringstream _buf; 256 std::ostringstream _buf;
254 std::ostringstream _joinBuf; 257 std::ostringstream _joinBuf;
255 const std::string _newLine = "\n"; 258 const std::string _newLine = "\n";
@@ -271,7 +274,7 @@ private:
271 }; 274 };
272 struct Scope { 275 struct Scope {
273 GlobalMode mode = GlobalMode::None; 276 GlobalMode mode = GlobalMode::None;
274 std::unique_ptr<std::unordered_map<std::string,VarType>> vars; 277 std::unique_ptr<std::unordered_map<std::string, VarType>> vars;
275 std::unique_ptr<std::unordered_set<std::string>> allows; 278 std::unique_ptr<std::unordered_set<std::string>> allows;
276 std::unique_ptr<std::unordered_set<std::string>> globals; 279 std::unique_ptr<std::unordered_set<std::string>> globals;
277 }; 280 };
@@ -312,7 +315,7 @@ private:
312 315
313 void pushScope() { 316 void pushScope() {
314 _scopes.emplace_back(); 317 _scopes.emplace_back();
315 _scopes.back().vars = std::make_unique<std::unordered_map<std::string,VarType>>(); 318 _scopes.back().vars = std::make_unique<std::unordered_map<std::string, VarType>>();
316 } 319 }
317 320
318 void popScope() { 321 void popScope() {
@@ -377,7 +380,7 @@ private:
377 bool isConst(const std::string& name) const { 380 bool isConst(const std::string& name) const {
378 bool isConst = false; 381 bool isConst = false;
379 decltype(_scopes.back().allows.get()) allows = nullptr; 382 decltype(_scopes.back().allows.get()) allows = nullptr;
380 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { 383 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
381 if (it->allows) allows = it->allows.get(); 384 if (it->allows) allows = it->allows.get();
382 } 385 }
383 bool checkShadowScopeOnly = false; 386 bool checkShadowScopeOnly = false;
@@ -524,8 +527,10 @@ private:
524 } 527 }
525 528
526 std::string join(const str_list& items) { 529 std::string join(const str_list& items) {
527 if (items.empty()) return Empty; 530 if (items.empty())
528 else if (items.size() == 1) return items.front(); 531 return Empty;
532 else if (items.size() == 1)
533 return items.front();
529 for (const auto& item : items) { 534 for (const auto& item : items) {
530 _joinBuf << item; 535 _joinBuf << item;
531 } 536 }
@@ -536,8 +541,10 @@ private:
536 } 541 }
537 542
538 std::string join(const str_list& items, std::string_view sep) { 543 std::string join(const str_list& items, std::string_view sep) {
539 if (items.empty()) return Empty; 544 if (items.empty())
540 else if (items.size() == 1) return items.front(); 545 return Empty;
546 else if (items.size() == 1)
547 return items.front();
541 std::string sepStr = std::string(sep); 548 std::string sepStr = std::string(sep);
542 auto begin = ++items.begin(); 549 auto begin = ++items.begin();
543 _joinBuf << items.front(); 550 _joinBuf << items.front();
@@ -659,7 +666,8 @@ private:
659 666
660 Statement_t* lastStatementFrom(const node_container& stmts) const { 667 Statement_t* lastStatementFrom(const node_container& stmts) const {
661 if (!stmts.empty()) { 668 if (!stmts.empty()) {
662 auto it = stmts.end(); --it; 669 auto it = stmts.end();
670 --it;
663 while (!static_cast<Statement_t*>(*it)->content && it != stmts.begin()) { 671 while (!static_cast<Statement_t*>(*it)->content && it != stmts.begin()) {
664 --it; 672 --it;
665 } 673 }
@@ -864,15 +872,17 @@ private:
864 case id<SelfName_t>(): 872 case id<SelfName_t>():
865 return true; 873 return true;
866 } 874 }
867 } else switch (firstItem->getId()) { 875 } else
868 case id<DotChainItem_t>(): 876 switch (firstItem->getId()) {
869 case id<Exp_t>(): 877 case id<DotChainItem_t>():
870 return true; 878 case id<Exp_t>():
871 } 879 return true;
880 }
872 } else { 881 } else {
873 if (std::find_if(chainItems.begin(), chainItems.end(), [](ast_node* node) { 882 if (std::find_if(chainItems.begin(), chainItems.end(), [](ast_node* node) {
874 return ast_is<existential_op_t>(node); 883 return ast_is<existential_op_t>(node);
875 }) != chainItems.end()) { 884 })
885 != chainItems.end()) {
876 return false; 886 return false;
877 } 887 }
878 auto lastItem = chainItems.back(); 888 auto lastItem = chainItems.back();
@@ -1155,7 +1165,7 @@ private:
1155 break; 1165 break;
1156 } 1166 }
1157 } 1167 }
1158 } else if (expList->exprs.size() == 1){ 1168 } else if (expList->exprs.size() == 1) {
1159 auto exp = static_cast<Exp_t*>(expList->exprs.back()); 1169 auto exp = static_cast<Exp_t*>(expList->exprs.back());
1160 if (isPureBackcall(exp)) { 1170 if (isPureBackcall(exp)) {
1161 transformExp(exp, out, ExpUsage::Common); 1171 transformExp(exp, out, ExpUsage::Common);
@@ -1277,7 +1287,7 @@ private:
1277 } 1287 }
1278 } 1288 }
1279 } 1289 }
1280 if (!defs.empty()) _buf << indent() << "local "sv << join(defs,", "sv); 1290 if (!defs.empty()) _buf << indent() << "local "sv << join(defs, ", "sv);
1281 } 1291 }
1282 } 1292 }
1283 return clearBuf(); 1293 return clearBuf();
@@ -1392,15 +1402,15 @@ private:
1392 auto j = values.begin(); 1402 auto j = values.begin();
1393 auto je = --values.end(); 1403 auto je = --values.end();
1394 while (j != je) { 1404 while (j != je) {
1395 ++i; ++j; 1405 ++i;
1406 ++j;
1396 } 1407 }
1397 bool holdItem = false; 1408 bool holdItem = false;
1398 for (auto it = i; it != exprs.end(); ++it) { 1409 for (auto it = i; it != exprs.end(); ++it) {
1399 BLOCK_START 1410 BLOCK_START
1400 auto value = singleValueFrom(*it); 1411 auto value = singleValueFrom(*it);
1401 BREAK_IF(!value); 1412 BREAK_IF(!value);
1402 if (value->item.is<simple_table_t>() || 1413 if (value->item.is<simple_table_t>() || value->getByPath<SimpleValue_t, TableLit_t>()) {
1403 value->getByPath<SimpleValue_t, TableLit_t>()) {
1404 holdItem = true; 1414 holdItem = true;
1405 break; 1415 break;
1406 } 1416 }
@@ -1524,7 +1534,8 @@ private:
1524 popScope(); 1534 popScope();
1525 temp.push_back(indent() + "end"s + nlr(x)); 1535 temp.push_back(indent() + "end"s + nlr(x));
1526 } 1536 }
1527 } else break; 1537 } else
1538 break;
1528 auto newExpList = x->new_ptr<ExpList_t>(); 1539 auto newExpList = x->new_ptr<ExpList_t>();
1529 auto newAssign = x->new_ptr<Assign_t>(); 1540 auto newAssign = x->new_ptr<Assign_t>();
1530 auto newAssignment = x->new_ptr<ExpListAssign_t>(); 1541 auto newAssignment = x->new_ptr<ExpListAssign_t>();
@@ -1946,13 +1957,12 @@ private:
1946 switch (pair->getId()) { 1957 switch (pair->getId()) {
1947 case id<Exp_t>(): { 1958 case id<Exp_t>(): {
1948 ++index; 1959 ++index;
1949 if (!isAssignable(static_cast<Exp_t*>(pair))) { 1960 if (!isAssignable(static_cast<Exp_t*>(pair))) {
1950 throw std::logic_error(_info.errorMessage("can't destructure value"sv, pair)); 1961 throw std::logic_error(_info.errorMessage("can't destructure value"sv, pair));
1951 } 1962 }
1952 auto value = singleValueFrom(pair); 1963 auto value = singleValueFrom(pair);
1953 auto item = value->item.get(); 1964 auto item = value->item.get();
1954 if (ast_is<simple_table_t>(item) || 1965 if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) {
1955 item->getByPath<TableLit_t>()) {
1956 auto subPairs = destructFromExp(pair, optional); 1966 auto subPairs = destructFromExp(pair, optional);
1957 for (auto& p : subPairs) { 1967 for (auto& p : subPairs) {
1958 pairs.push_back({p.target, p.targetVar, 1968 pairs.push_back({p.target, p.targetVar,
@@ -1963,12 +1973,10 @@ private:
1963 auto exp = static_cast<Exp_t*>(pair); 1973 auto exp = static_cast<Exp_t*>(pair);
1964 auto varName = singleVariableFrom(exp, false); 1974 auto varName = singleVariableFrom(exp, false);
1965 if (varName == "_"sv) break; 1975 if (varName == "_"sv) break;
1966 pairs.push_back({ 1976 pairs.push_back({exp,
1967 exp,
1968 varName, 1977 varName,
1969 '[' + std::to_string(index) + ']', 1978 '[' + std::to_string(index) + ']',
1970 nullptr 1979 nullptr});
1971 });
1972 } 1980 }
1973 break; 1981 break;
1974 } 1982 }
@@ -1994,37 +2002,30 @@ private:
1994 if (auto exp = np->value.as<Exp_t>()) { 2002 if (auto exp = np->value.as<Exp_t>()) {
1995 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); 2003 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp));
1996 auto item = singleValueFrom(exp)->item.get(); 2004 auto item = singleValueFrom(exp)->item.get();
1997 if (ast_is<simple_table_t>(item) || 2005 if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) {
1998 item->getByPath<TableLit_t>()) {
1999 auto subPairs = destructFromExp(exp, optional); 2006 auto subPairs = destructFromExp(exp, optional);
2000 for (auto& p : subPairs) { 2007 for (auto& p : subPairs) {
2001 pairs.push_back({ 2008 pairs.push_back({p.target,
2002 p.target,
2003 p.targetVar, 2009 p.targetVar,
2004 keyName + sep + p.structure, 2010 keyName + sep + p.structure,
2005 p.defVal 2011 p.defVal});
2006 });
2007 } 2012 }
2008 } else { 2013 } else {
2009 auto varName = singleVariableFrom(exp, false); 2014 auto varName = singleVariableFrom(exp, false);
2010 pairs.push_back({ 2015 pairs.push_back({exp,
2011 exp,
2012 varName, 2016 varName,
2013 keyName, 2017 keyName,
2014 nullptr 2018 nullptr});
2015 });
2016 } 2019 }
2017 break; 2020 break;
2018 } 2021 }
2019 if (np->value.is<TableBlock_t>()) { 2022 if (np->value.is<TableBlock_t>()) {
2020 auto subPairs = destructFromExp(np->value, optional); 2023 auto subPairs = destructFromExp(np->value, optional);
2021 for (auto& p : subPairs) { 2024 for (auto& p : subPairs) {
2022 pairs.push_back({ 2025 pairs.push_back({p.target,
2023 p.target,
2024 p.targetVar, 2026 p.targetVar,
2025 keyName + sep + p.structure, 2027 keyName + sep + p.structure,
2026 p.defVal 2028 p.defVal});
2027 });
2028 } 2029 }
2029 } 2030 }
2030 break; 2031 break;
@@ -2034,16 +2035,14 @@ private:
2034 ++index; 2035 ++index;
2035 auto subPairs = destructFromExp(tb, optional); 2036 auto subPairs = destructFromExp(tb, optional);
2036 for (auto& p : subPairs) { 2037 for (auto& p : subPairs) {
2037 pairs.push_back({ 2038 pairs.push_back({p.target,
2038 p.target,
2039 p.targetVar, 2039 p.targetVar,
2040 '[' + std::to_string(index) + ']' + sep + p.structure, 2040 '[' + std::to_string(index) + ']' + sep + p.structure,
2041 p.defVal 2041 p.defVal});
2042 });
2043 } 2042 }
2044 break; 2043 break;
2045 } 2044 }
2046 case id<default_pair_t>() : { 2045 case id<default_pair_t>(): {
2047 auto dp = static_cast<default_pair_t*>(pair); 2046 auto dp = static_cast<default_pair_t*>(pair);
2048 if (auto exp = dp->key.as<Exp_t>()) { 2047 if (auto exp = dp->key.as<Exp_t>()) {
2049 ++index; 2048 ++index;
@@ -2052,17 +2051,14 @@ private:
2052 } 2051 }
2053 auto value = singleValueFrom(exp); 2052 auto value = singleValueFrom(exp);
2054 auto item = value->item.get(); 2053 auto item = value->item.get();
2055 if (ast_is<simple_table_t>(item) || 2054 if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) {
2056 item->getByPath<TableLit_t>()) {
2057 throw std::logic_error(_info.errorMessage("invalid use of default value"sv, dp->defVal)); 2055 throw std::logic_error(_info.errorMessage("invalid use of default value"sv, dp->defVal));
2058 } else { 2056 } else {
2059 auto varName = singleVariableFrom(exp, false); 2057 auto varName = singleVariableFrom(exp, false);
2060 pairs.push_back({ 2058 pairs.push_back({exp,
2061 exp,
2062 varName, 2059 varName,
2063 '[' + std::to_string(index) + ']', 2060 '[' + std::to_string(index) + ']',
2064 dp->defVal 2061 dp->defVal});
2065 });
2066 } 2062 }
2067 break; 2063 break;
2068 } 2064 }
@@ -2081,19 +2077,15 @@ private:
2081 if (auto exp = dp->value.get()) { 2077 if (auto exp = dp->value.get()) {
2082 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); 2078 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp));
2083 auto varName = singleVariableFrom(exp, false); 2079 auto varName = singleVariableFrom(exp, false);
2084 pairs.push_back({ 2080 pairs.push_back({exp,
2085 exp,
2086 varName, 2081 varName,
2087 keyName, 2082 keyName,
2088 dp->defVal 2083 dp->defVal});
2089 });
2090 } else { 2084 } else {
2091 pairs.push_back({ 2085 pairs.push_back({toAst<Exp_t>(valueStr, dp).get(),
2092 toAst<Exp_t>(valueStr, dp).get(),
2093 valueStr, 2086 valueStr,
2094 keyName, 2087 keyName,
2095 dp->defVal 2088 dp->defVal});
2096 });
2097 } 2089 }
2098 break; 2090 break;
2099 } 2091 }
@@ -2157,12 +2149,10 @@ private:
2157 value->item.set(simpleValue); 2149 value->item.set(simpleValue);
2158 auto subPairs = destructFromExp(newExp(value, subMetaDestruct), optional); 2150 auto subPairs = destructFromExp(newExp(value, subMetaDestruct), optional);
2159 for (const auto& p : subPairs) { 2151 for (const auto& p : subPairs) {
2160 pairs.push_back({ 2152 pairs.push_back({p.target,
2161 p.target,
2162 p.targetVar, 2153 p.targetVar,
2163 ".#"s + (p.structure.empty() ? Empty : sep + p.structure), 2154 ".#"s + (p.structure.empty() ? Empty : sep + p.structure),
2164 p.defVal 2155 p.defVal});
2165 });
2166 } 2156 }
2167 } 2157 }
2168 return pairs; 2158 return pairs;
@@ -2373,8 +2363,7 @@ private:
2373 if (!leftValue) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftExp)); 2363 if (!leftValue) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftExp));
2374 auto chain = leftValue->item.as<ChainValue_t>(); 2364 auto chain = leftValue->item.as<ChainValue_t>();
2375 if (!chain) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftValue)); 2365 if (!chain) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftValue));
2376 BLOCK_START 2366 BLOCK_START {
2377 {
2378 auto dot = ast_cast<DotChainItem_t>(chain->items.back()); 2367 auto dot = ast_cast<DotChainItem_t>(chain->items.back());
2379 if (dot && dot->name.is<Metatable_t>()) { 2368 if (dot && dot->name.is<Metatable_t>()) {
2380 throw std::logic_error(_info.errorMessage("can not apply update to a metatable"sv, leftExp)); 2369 throw std::logic_error(_info.errorMessage("can not apply update to a metatable"sv, leftExp));
@@ -2457,10 +2446,11 @@ private:
2457 right = '(' + right + ')'; 2446 right = '(' + right + ')';
2458 } 2447 }
2459 _buf << join(temp); 2448 _buf << join(temp);
2460 if (!defs.empty()) _buf << defs; 2449 if (!defs.empty())
2461 else _buf << indent() << left; 2450 _buf << defs;
2462 _buf << " = "sv << left << 2451 else
2463 ' ' << op << ' ' << right << nll(assignment); 2452 _buf << indent() << left;
2453 _buf << " = "sv << left << ' ' << op << ' ' << right << nll(assignment);
2464 out.push_back(clearBuf()); 2454 out.push_back(clearBuf());
2465 break; 2455 break;
2466 } 2456 }
@@ -2709,7 +2699,8 @@ private:
2709 } else { 2699 } else {
2710 auto x = values.front(); 2700 auto x = values.front();
2711 auto arg = newExp(static_cast<unary_exp_t*>(x), x); 2701 auto arg = newExp(static_cast<unary_exp_t*>(x), x);
2712 auto begin = values.begin(); begin++; 2702 auto begin = values.begin();
2703 begin++;
2713 for (auto it = begin; it != values.end(); ++it) { 2704 for (auto it = begin; it != values.end(); ++it) {
2714 auto unary = static_cast<unary_exp_t*>(*it); 2705 auto unary = static_cast<unary_exp_t*>(*it);
2715 auto value = static_cast<Value_t*>(singleUnaryExpFrom(unary) ? unary->expos.back() : nullptr); 2706 auto value = static_cast<Value_t*>(singleUnaryExpFrom(unary) ? unary->expos.back() : nullptr);
@@ -2943,7 +2934,7 @@ private:
2943 } 2934 }
2944 } 2935 }
2945 2936
2946 void transformCallable(Callable_t* callable, str_list& out, const ast_sel<false,Invoke_t,InvokeArgs_t>& invoke = {}) { 2937 void transformCallable(Callable_t* callable, str_list& out, const ast_sel<false, Invoke_t, InvokeArgs_t>& invoke = {}) {
2947 auto item = callable->item.get(); 2938 auto item = callable->item.get();
2948 switch (item->getId()) { 2939 switch (item->getId()) {
2949 case id<Variable_t>(): { 2940 case id<Variable_t>(): {
@@ -3042,9 +3033,7 @@ private:
3042 temp.push_back(Empty); 3033 temp.push_back(Empty);
3043 } 3034 }
3044 auto& bodyCodes = temp.back(); 3035 auto& bodyCodes = temp.back();
3045 _buf << "function("sv << 3036 _buf << "function("sv << (isFatArrow ? "self"s : Empty) << ')';
3046 (isFatArrow ? "self"s : Empty) <<
3047 ')';
3048 if (!bodyCodes.empty()) { 3037 if (!bodyCodes.empty()) {
3049 _buf << nll(funLit) << bodyCodes; 3038 _buf << nll(funLit) << bodyCodes;
3050 popScope(); 3039 popScope();
@@ -3077,7 +3066,7 @@ private:
3077 } 3066 }
3078 const auto& nodes = block->statements.objects(); 3067 const auto& nodes = block->statements.objects();
3079 LocalMode mode = LocalMode::None; 3068 LocalMode mode = LocalMode::None;
3080 Local_t* any = nullptr, *capital = nullptr; 3069 Local_t *any = nullptr, *capital = nullptr;
3081 for (auto it = nodes.begin(); it != nodes.end(); ++it) { 3070 for (auto it = nodes.begin(); it != nodes.end(); ++it) {
3082 auto node = *it; 3071 auto node = *it;
3083 auto stmt = static_cast<Statement_t*>(node); 3072 auto stmt = static_cast<Statement_t*>(node);
@@ -3086,7 +3075,8 @@ private:
3086 bool cond = false; 3075 bool cond = false;
3087 BLOCK_START 3076 BLOCK_START
3088 BREAK_IF(it == nodes.begin()); 3077 BREAK_IF(it == nodes.begin());
3089 auto last = it; --last; 3078 auto last = it;
3079 --last;
3090 auto lst = static_cast<Statement_t*>(*last); 3080 auto lst = static_cast<Statement_t*>(*last);
3091 if (lst->appendix) { 3081 if (lst->appendix) {
3092 throw std::logic_error(_info.errorMessage("statement decorator must be placed at the end of pipe chain"sv, lst->appendix.get())); 3082 throw std::logic_error(_info.errorMessage("statement decorator must be placed at the end of pipe chain"sv, lst->appendix.get()));
@@ -3104,7 +3094,8 @@ private:
3104 BLOCK_END 3094 BLOCK_END
3105 if (!cond) throw std::logic_error(_info.errorMessage("pipe chain must be following a value"sv, x)); 3095 if (!cond) throw std::logic_error(_info.errorMessage("pipe chain must be following a value"sv, x));
3106 stmt->content.set(nullptr); 3096 stmt->content.set(nullptr);
3107 auto next = it; ++next; 3097 auto next = it;
3098 ++next;
3108 BLOCK_START 3099 BLOCK_START
3109 BREAK_IF(next == nodes.end()); 3100 BREAK_IF(next == nodes.end());
3110 BREAK_IF(!static_cast<Statement_t*>(*next)->content.as<PipeBody_t>()); 3101 BREAK_IF(!static_cast<Statement_t*>(*next)->content.as<PipeBody_t>());
@@ -3122,7 +3113,8 @@ private:
3122 ast_ptr<false, Exp_t> arg; 3113 ast_ptr<false, Exp_t> arg;
3123 { 3114 {
3124 auto block = x->new_ptr<Block_t>(); 3115 auto block = x->new_ptr<Block_t>();
3125 auto next = it; ++next; 3116 auto next = it;
3117 ++next;
3126 if (next != nodes.end()) { 3118 if (next != nodes.end()) {
3127 for (auto i = next; i != nodes.end(); ++i) { 3119 for (auto i = next; i != nodes.end(); ++i) {
3128 block->statements.push_back(*i); 3120 block->statements.push_back(*i);
@@ -3240,7 +3232,8 @@ private:
3240 for (const auto& destruct : info.destructures) 3232 for (const auto& destruct : info.destructures)
3241 for (const auto& item : destruct.items) 3233 for (const auto& item : destruct.items)
3242 if (!item.targetVar.empty()) { 3234 if (!item.targetVar.empty()) {
3243 if (std::isupper(item.targetVar[0]) && capital) { capital->decls.push_back(item.targetVar); 3235 if (std::isupper(item.targetVar[0]) && capital) {
3236 capital->decls.push_back(item.targetVar);
3244 } else if (any) { 3237 } else if (any) {
3245 any->decls.push_back(item.targetVar); 3238 any->decls.push_back(item.targetVar);
3246 } 3239 }
@@ -3249,7 +3242,8 @@ private:
3249 if (info.assignment) { 3242 if (info.assignment) {
3250 auto defs = transformAssignDefs(info.assignment->expList, DefOp::Get); 3243 auto defs = transformAssignDefs(info.assignment->expList, DefOp::Get);
3251 for (const auto& def : defs) { 3244 for (const auto& def : defs) {
3252 if (std::isupper(def[0]) && capital) { capital->decls.push_back(def); 3245 if (std::isupper(def[0]) && capital) {
3246 capital->decls.push_back(def);
3253 } else if (any) { 3247 } else if (any) {
3254 any->decls.push_back(def); 3248 any->decls.push_back(def);
3255 } 3249 }
@@ -3295,9 +3289,7 @@ private:
3295 BREAK_IF(!last); 3289 BREAK_IF(!last);
3296 auto x = last; 3290 auto x = last;
3297 auto expList = expListFrom(last); 3291 auto expList = expListFrom(last);
3298 BREAK_IF(!expList || 3292 BREAK_IF(!expList || (last->appendix && last->appendix->item.is<CompInner_t>()));
3299 (last->appendix &&
3300 last->appendix->item.is<CompInner_t>()));
3301 auto expListLow = x->new_ptr<ExpListLow_t>(); 3293 auto expListLow = x->new_ptr<ExpListLow_t>();
3302 expListLow->exprs.dup(expList->exprs); 3294 expListLow->exprs.dup(expList->exprs);
3303 auto returnNode = x->new_ptr<Return_t>(); 3295 auto returnNode = x->new_ptr<Return_t>();
@@ -3764,14 +3756,18 @@ private:
3764 _buf << indent() << "end"sv << nll(def); 3756 _buf << indent() << "end"sv << nll(def);
3765 temp.back() = clearBuf(); 3757 temp.back() = clearBuf();
3766 } 3758 }
3767 if (varNames.empty()) varNames = arg.name; 3759 if (varNames.empty())
3768 else varNames.append(", "s + arg.name); 3760 varNames = arg.name;
3761 else
3762 varNames.append(", "s + arg.name);
3769 } 3763 }
3770 if (argDefList->varArg) { 3764 if (argDefList->varArg) {
3771 auto& arg = argItems.emplace_back(); 3765 auto& arg = argItems.emplace_back();
3772 arg.name = "..."sv; 3766 arg.name = "..."sv;
3773 if (varNames.empty()) varNames = arg.name; 3767 if (varNames.empty())
3774 else varNames.append(", "s + arg.name); 3768 varNames = arg.name;
3769 else
3770 varNames.append(", "s + arg.name);
3775 _varArgs.top().hasVar = true; 3771 _varArgs.top().hasVar = true;
3776 } 3772 }
3777 if (assignSelf) { 3773 if (assignSelf) {
@@ -3790,7 +3786,7 @@ private:
3790 out.push_back(join(temp)); 3786 out.push_back(join(temp));
3791 } 3787 }
3792 3788
3793 void transformSelfName(SelfName_t* selfName, str_list& out, const ast_sel<false,Invoke_t,InvokeArgs_t>& invoke = {}) { 3789 void transformSelfName(SelfName_t* selfName, str_list& out, const ast_sel<false, Invoke_t, InvokeArgs_t>& invoke = {}) {
3794 auto x = selfName; 3790 auto x = selfName;
3795 auto name = selfName->name.get(); 3791 auto name = selfName->name.get();
3796 switch (name->getId()) { 3792 switch (name->getId()) {
@@ -3899,7 +3895,7 @@ private:
3899 pushScope(); 3895 pushScope();
3900 } 3896 }
3901 auto partOne = x->new_ptr<ChainValue_t>(); 3897 auto partOne = x->new_ptr<ChainValue_t>();
3902 for (auto it = chainList.begin();it != opIt;++it) { 3898 for (auto it = chainList.begin(); it != opIt; ++it) {
3903 partOne->items.push_back(*it); 3899 partOne->items.push_back(*it);
3904 } 3900 }
3905 BLOCK_START 3901 BLOCK_START
@@ -3972,7 +3968,8 @@ private:
3972 partOne->items.clear(); 3968 partOne->items.clear();
3973 partOne->items.push_back(toAst<Callable_t>(objVar, x)); 3969 partOne->items.push_back(toAst<Callable_t>(objVar, x));
3974 partOne->items.push_back(dotItem); 3970 partOne->items.push_back(dotItem);
3975 auto it = opIt; ++it; 3971 auto it = opIt;
3972 ++it;
3976 if (it != chainList.end() && ast_is<Invoke_t, InvokeArgs_t>(*it)) { 3973 if (it != chainList.end() && ast_is<Invoke_t, InvokeArgs_t>(*it)) {
3977 3974
3978 if (auto invoke = ast_cast<Invoke_t>(*it)) { 3975 if (auto invoke = ast_cast<Invoke_t>(*it)) {
@@ -3999,7 +3996,7 @@ private:
3999 pushScope(); 3996 pushScope();
4000 auto partTwo = x->new_ptr<ChainValue_t>(); 3997 auto partTwo = x->new_ptr<ChainValue_t>();
4001 partTwo->items.push_back(toAst<Callable_t>(objVar, x)); 3998 partTwo->items.push_back(toAst<Callable_t>(objVar, x));
4002 for (auto it = ++opIt;it != chainList.end();++it) { 3999 for (auto it = ++opIt; it != chainList.end(); ++it) {
4003 partTwo->items.push_back(*it); 4000 partTwo->items.push_back(*it);
4004 } 4001 }
4005 switch (usage) { 4002 switch (usage) {
@@ -4248,7 +4245,8 @@ private:
4248 case id<ColonChainItem_t>(): { 4245 case id<ColonChainItem_t>(): {
4249 auto colonItem = static_cast<ColonChainItem_t*>(item); 4246 auto colonItem = static_cast<ColonChainItem_t*>(item);
4250 auto current = it; 4247 auto current = it;
4251 auto next = current; ++next; 4248 auto next = current;
4249 ++next;
4252 auto followItem = next != chainList.end() ? *next : nullptr; 4250 auto followItem = next != chainList.end() ? *next : nullptr;
4253 if (current != chainList.begin()) { 4251 if (current != chainList.begin()) {
4254 --current; 4252 --current;
@@ -4272,7 +4270,7 @@ private:
4272 switch (chainList.front()->getId()) { 4270 switch (chainList.front()->getId()) {
4273 case id<DotChainItem_t>(): 4271 case id<DotChainItem_t>():
4274 case id<ColonChainItem_t>(): 4272 case id<ColonChainItem_t>():
4275 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x)); 4273 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x));
4276 break; 4274 break;
4277 } 4275 }
4278 for (auto i = chainList.begin(); i != current; ++i) { 4276 for (auto i = chainList.begin(); i != current; ++i) {
@@ -4366,7 +4364,8 @@ private:
4366 transformSlice(static_cast<Slice_t*>(item), temp); 4364 transformSlice(static_cast<Slice_t*>(item), temp);
4367 break; 4365 break;
4368 case id<Callable_t>(): { 4366 case id<Callable_t>(): {
4369 auto next = it; ++next; 4367 auto next = it;
4368 ++next;
4370 auto followItem = next != chainList.end() ? *next : nullptr; 4369 auto followItem = next != chainList.end() ? *next : nullptr;
4371 ast_sel<false, Invoke_t, InvokeArgs_t> invoke; 4370 ast_sel<false, Invoke_t, InvokeArgs_t> invoke;
4372 if (ast_is<Invoke_t, InvokeArgs_t>(followItem)) { 4371 if (ast_is<Invoke_t, InvokeArgs_t>(followItem)) {
@@ -4464,7 +4463,7 @@ private:
4464 return Empty; 4463 return Empty;
4465 } 4464 }
4466 4465
4467 std::tuple<std::string,std::string,str_list> expandMacroStr(ChainValue_t* chainValue) { 4466 std::tuple<std::string, std::string, str_list> expandMacroStr(ChainValue_t* chainValue) {
4468 const auto& chainList = chainValue->items.objects(); 4467 const auto& chainList = chainValue->items.objects();
4469 auto x = ast_to<Callable_t>(chainList.front())->item.to<MacroName_t>(); 4468 auto x = ast_to<Callable_t>(chainList.front())->item.to<MacroName_t>();
4470 auto macroName = _parser.toString(x->name); 4469 auto macroName = _parser.toString(x->name);
@@ -4490,7 +4489,7 @@ private:
4490 auto item = *(++chainList.begin()); 4489 auto item = *(++chainList.begin());
4491 if (auto invoke = ast_cast<Invoke_t>(item)) { 4490 if (auto invoke = ast_cast<Invoke_t>(item)) {
4492 args = &invoke->args.objects(); 4491 args = &invoke->args.objects();
4493 } else if (auto invoke = ast_cast<InvokeArgs_t>(item)){ 4492 } else if (auto invoke = ast_cast<InvokeArgs_t>(item)) {
4494 args = &invoke->args.objects(); 4493 args = &invoke->args.objects();
4495 } 4494 }
4496 } 4495 }
@@ -4599,7 +4598,7 @@ private:
4599 return {type, codes, std::move(localVars)}; 4598 return {type, codes, std::move(localVars)};
4600 } 4599 }
4601 4600
4602 std::tuple<ast_ptr<false,ast_node>, std::unique_ptr<input>, std::string, str_list> expandMacro(ChainValue_t* chainValue, ExpUsage usage, bool allowBlockMacroReturn) { 4601 std::tuple<ast_ptr<false, ast_node>, std::unique_ptr<input>, std::string, str_list> expandMacro(ChainValue_t* chainValue, ExpUsage usage, bool allowBlockMacroReturn) {
4603 auto x = ast_to<Callable_t>(chainValue->items.front())->item.to<MacroName_t>(); 4602 auto x = ast_to<Callable_t>(chainValue->items.front())->item.to<MacroName_t>();
4604 const auto& chainList = chainValue->items.objects(); 4603 const auto& chainList = chainValue->items.objects();
4605 std::string type, codes; 4604 std::string type, codes;
@@ -4928,10 +4927,10 @@ private:
4928 forceAddToScope(indexVar); 4927 forceAddToScope(indexVar);
4929 temp.push_back(indent() + "local "s + indexVar + " = 1"s + nll(item)); 4928 temp.push_back(indent() + "local "s + indexVar + " = 1"s + nll(item));
4930 _buf << "for "sv << keyVar << ',' << valueVar << " in pairs "sv << objVar 4929 _buf << "for "sv << keyVar << ',' << valueVar << " in pairs "sv << objVar
4931 << "\n\tif "sv << indexVar << "=="sv << keyVar 4930 << "\n\tif "sv << indexVar << "=="sv << keyVar
4932 << "\n\t\t"sv << tableVar << "[]="sv << valueVar 4931 << "\n\t\t"sv << tableVar << "[]="sv << valueVar
4933 << "\n\t\t"sv << indexVar << "+=1"sv 4932 << "\n\t\t"sv << indexVar << "+=1"sv
4934 << "\n\telse "sv << tableVar << '[' << keyVar << "]="sv << valueVar; 4933 << "\n\telse "sv << tableVar << '[' << keyVar << "]="sv << valueVar;
4935 auto forEach = toAst<ForEach_t>(clearBuf(), item); 4934 auto forEach = toAst<ForEach_t>(clearBuf(), item);
4936 transformForEach(forEach, temp); 4935 transformForEach(forEach, temp);
4937 break; 4936 break;
@@ -4998,7 +4997,7 @@ private:
4998 auto chainValue = value->item.as<ChainValue_t>(); 4997 auto chainValue = value->item.as<ChainValue_t>();
4999 BREAK_IF(!chainValue); 4998 BREAK_IF(!chainValue);
5000 BREAK_IF(chainValue->items.size() != 1); 4999 BREAK_IF(chainValue->items.size() != 1);
5001 BREAK_IF((!chainValue->getByPath<Callable_t,VarArg_t>())); 5000 BREAK_IF((!chainValue->getByPath<Callable_t, VarArg_t>()));
5002 auto indexVar = getUnusedName("_index_"); 5001 auto indexVar = getUnusedName("_index_");
5003 _buf << "for "sv << indexVar << "=1,select '#',...\n\t"sv << tableVar << "[]= select "sv << indexVar << ",..."sv; 5002 _buf << "for "sv << indexVar << "=1,select '#',...\n\t"sv << tableVar << "[]= select "sv << indexVar << ",..."sv;
5004 transformFor(toAst<For_t>(clearBuf(), item), temp); 5003 transformFor(toAst<For_t>(clearBuf(), item), temp);
@@ -5098,8 +5097,7 @@ private:
5098 transformAssignment(assignment, temp); 5097 transformAssignment(assignment, temp);
5099 popScope(); 5098 popScope();
5100 out.push_back(join(temp)); 5099 out.push_back(join(temp));
5101 out.back() = indent() + "do"s + nll(x) + 5100 out.back() = indent() + "do"s + nll(x) + out.back() + indent() + "end"s + nlr(x);
5102 out.back() + indent() + "end"s + nlr(x);
5103 break; 5101 break;
5104 } 5102 }
5105 case ExpUsage::Return: 5103 case ExpUsage::Return:
@@ -5205,14 +5203,15 @@ private:
5205 str_list tmp; 5203 str_list tmp;
5206 if (!metatable->pairs.empty()) { 5204 if (!metatable->pairs.empty()) {
5207 transform_simple_table(metatable, tmp); 5205 transform_simple_table(metatable, tmp);
5208 } else switch (metatableItem->getId()) { 5206 } else
5209 case id<Exp_t>(): 5207 switch (metatableItem->getId()) {
5210 transformExp(static_cast<Exp_t*>(metatableItem.get()), tmp, ExpUsage::Closure); 5208 case id<Exp_t>():
5211 break; 5209 transformExp(static_cast<Exp_t*>(metatableItem.get()), tmp, ExpUsage::Closure);
5212 case id<TableBlock_t>(): 5210 break;
5213 transformTableBlock(static_cast<TableBlock_t*>(metatableItem.get()), tmp); 5211 case id<TableBlock_t>():
5214 break; 5212 transformTableBlock(static_cast<TableBlock_t*>(metatableItem.get()), tmp);
5215 } 5213 break;
5214 }
5216 tabStr += tmp.back(); 5215 tabStr += tmp.back();
5217 tabStr += ')'; 5216 tabStr += ')';
5218 out.push_back(tabStr); 5217 out.push_back(tabStr);
@@ -5349,9 +5348,7 @@ private:
5349 assignment->action.set(assign); 5348 assignment->action.set(assign);
5350 transformAssignment(assignment, temp); 5349 transformAssignment(assignment, temp);
5351 popScope(); 5350 popScope();
5352 out.back() = indent() + "do"s + nll(comp) + 5351 out.back() = indent() + "do"s + nll(comp) + out.back() + temp.back() + indent() + "end"s + nlr(comp);
5353 out.back() + temp.back() +
5354 indent() + "end"s + nlr(comp);
5355 break; 5352 break;
5356 } 5353 }
5357 case ExpUsage::Return: 5354 case ExpUsage::Return:
@@ -5529,7 +5526,7 @@ private:
5529 } 5526 }
5530 5527
5531 void transformInvokeArgs(InvokeArgs_t* invokeArgs, str_list& out) { 5528 void transformInvokeArgs(InvokeArgs_t* invokeArgs, str_list& out) {
5532 if (invokeArgs->args.size() > 1) { 5529 if (invokeArgs->args.size() > 1) {
5533 /* merge all the key-value pairs into one table 5530 /* merge all the key-value pairs into one table
5534 from arguments in the end */ 5531 from arguments in the end */
5535 auto lastArg = invokeArgs->args.back(); 5532 auto lastArg = invokeArgs->args.back();
@@ -5614,18 +5611,18 @@ private:
5614 return traversal::Stop == body->traverse([&](ast_node* node) { 5611 return traversal::Stop == body->traverse([&](ast_node* node) {
5615 if (auto stmt = ast_cast<Statement_t>(node)) { 5612 if (auto stmt = ast_cast<Statement_t>(node)) {
5616 if (stmt->content.is<BreakLoop_t>()) { 5613 if (stmt->content.is<BreakLoop_t>()) {
5617 return _parser.toString(stmt->content) == "continue"sv ? 5614 return _parser.toString(stmt->content) == "continue"sv ? traversal::Stop : traversal::Return;
5618 traversal::Stop : traversal::Return;
5619 } else if (expListFrom(stmt)) { 5615 } else if (expListFrom(stmt)) {
5620 return traversal::Continue; 5616 return traversal::Continue;
5621 } 5617 }
5622 return traversal::Return; 5618 return traversal::Return;
5623 } else switch (node->getId()) { 5619 } else
5624 case id<FunLit_t>(): 5620 switch (node->getId()) {
5625 case id<Invoke_t>(): 5621 case id<FunLit_t>():
5626 case id<InvokeArgs_t>(): 5622 case id<Invoke_t>():
5627 return traversal::Return; 5623 case id<InvokeArgs_t>():
5628 } 5624 return traversal::Return;
5625 }
5629 return traversal::Continue; 5626 return traversal::Continue;
5630 }); 5627 });
5631 } 5628 }
@@ -5781,7 +5778,7 @@ private:
5781 out.push_back(join(temp)); 5778 out.push_back(join(temp));
5782 } 5779 }
5783 5780
5784 void transformForInPlace(For_t* forNode, str_list& out, ExpList_t* assignExpList = nullptr) { 5781 void transformForInPlace(For_t* forNode, str_list& out, ExpList_t* assignExpList = nullptr) {
5785 auto x = forNode; 5782 auto x = forNode;
5786 str_list temp; 5783 str_list temp;
5787 if (assignExpList) { 5784 if (assignExpList) {
@@ -5807,11 +5804,7 @@ private:
5807 } 5804 }
5808 5805
5809 void checkOperatorAvailable(const std::string& op, ast_node* node) { 5806 void checkOperatorAvailable(const std::string& op, ast_node* node) {
5810 if (op == "&"sv || 5807 if (op == "&"sv || op == "~"sv || op == "|"sv || op == ">>"sv || op == "<<"sv) {
5811 op == "~"sv ||
5812 op == "|"sv ||
5813 op == ">>"sv ||
5814 op == "<<"sv) {
5815 if (getLuaTarget(node) < 503) { 5808 if (getLuaTarget(node) < 503) {
5816 throw std::logic_error(_info.errorMessage("bitwise operator is not available when not targeting Lua version 5.3 or higher"sv, node)); 5809 throw std::logic_error(_info.errorMessage("bitwise operator is not available when not targeting Lua version 5.3 or higher"sv, node));
5817 } 5810 }
@@ -5874,7 +5867,7 @@ private:
5874 out.push_back(join(temp)); 5867 out.push_back(join(temp));
5875 } 5868 }
5876 5869
5877 void transformForEachInPlace(ForEach_t* forEach, str_list& out, ExpList_t* assignExpList = nullptr) { 5870 void transformForEachInPlace(ForEach_t* forEach, str_list& out, ExpList_t* assignExpList = nullptr) {
5878 auto x = forEach; 5871 auto x = forEach;
5879 str_list temp; 5872 str_list temp;
5880 if (assignExpList) { 5873 if (assignExpList) {
@@ -5929,10 +5922,12 @@ private:
5929 transformDoubleString(static_cast<DoubleString_t*>(key), temp); 5922 transformDoubleString(static_cast<DoubleString_t*>(key), temp);
5930 temp.back() = '[' + temp.back() + ']'; 5923 temp.back() = '[' + temp.back() + ']';
5931 break; 5924 break;
5932 case id<SingleString_t>(): transformSingleString(static_cast<SingleString_t*>(key), temp); 5925 case id<SingleString_t>():
5926 transformSingleString(static_cast<SingleString_t*>(key), temp);
5933 temp.back() = '[' + temp.back() + ']'; 5927 temp.back() = '[' + temp.back() + ']';
5934 break; 5928 break;
5935 case id<LuaString_t>(): transformLuaString(static_cast<LuaString_t*>(key), temp); 5929 case id<LuaString_t>():
5930 transformLuaString(static_cast<LuaString_t*>(key), temp);
5936 temp.back() = "[ "s + temp.back() + ']'; 5931 temp.back() = "[ "s + temp.back() + ']';
5937 break; 5932 break;
5938 default: YUEE("AST node mismatch", key); break; 5933 default: YUEE("AST node mismatch", key); break;
@@ -6012,7 +6007,7 @@ private:
6012 } 6007 }
6013 } 6008 }
6014 6009
6015 std::pair<std::string,bool> defineClassVariable(Assignable_t* assignable) { 6010 std::pair<std::string, bool> defineClassVariable(Assignable_t* assignable) {
6016 if (auto variable = assignable->item.as<Variable_t>()) { 6011 if (auto variable = assignable->item.as<Variable_t>()) {
6017 auto name = _parser.toString(variable); 6012 auto name = _parser.toString(variable);
6018 if (addToScope(name)) { 6013 if (addToScope(name)) {
@@ -6150,7 +6145,8 @@ private:
6150 case id<class_member_list_t>(): { 6145 case id<class_member_list_t>(): {
6151 size_t inc = transform_class_member_list(static_cast<class_member_list_t*>(content), members, classVar); 6146 size_t inc = transform_class_member_list(static_cast<class_member_list_t*>(content), members, classVar);
6152 auto it = members.end(); 6147 auto it = members.end();
6153 for (size_t i = 0; i < inc; ++i, --it); 6148 for (size_t i = 0; i < inc; ++i, --it)
6149 ;
6154 for (; it != members.end(); ++it) { 6150 for (; it != members.end(); ++it) {
6155 auto& member = *it; 6151 auto& member = *it;
6156 if (member.type == MemType::Property) { 6152 if (member.type == MemType::Property) {
@@ -6164,7 +6160,7 @@ private:
6164 case id<Statement_t>(): 6160 case id<Statement_t>():
6165 transformStatement(static_cast<Statement_t*>(content), statements); 6161 transformStatement(static_cast<Statement_t*>(content), statements);
6166 break; 6162 break;
6167 default:YUEE("AST node mismatch", content); break; 6163 default: YUEE("AST node mismatch", content); break;
6168 } 6164 }
6169 } 6165 }
6170 for (auto& member : members) { 6166 for (auto& member : members) {
@@ -6667,9 +6663,7 @@ private:
6667 } 6663 }
6668 for (auto _exp : expList->exprs.objects()) { 6664 for (auto _exp : expList->exprs.objects()) {
6669 auto exp = static_cast<Exp_t*>(_exp); 6665 auto exp = static_cast<Exp_t*>(_exp);
6670 if (!variableFrom(exp) && 6666 if (!variableFrom(exp) && !exp->getByPath<unary_exp_t, Value_t, SimpleValue_t, TableLit_t>() && !exp->getByPath<unary_exp_t, Value_t, simple_table_t>()) {
6671 !exp->getByPath<unary_exp_t, Value_t, SimpleValue_t, TableLit_t>() &&
6672 !exp->getByPath<unary_exp_t, Value_t, simple_table_t>()) {
6673 throw std::logic_error(_info.errorMessage("left hand expressions must be variables in export statement"sv, x)); 6667 throw std::logic_error(_info.errorMessage("left hand expressions must be variables in export statement"sv, x));
6674 } 6668 }
6675 } 6669 }
@@ -7068,7 +7062,7 @@ private:
7068 if (ast_is<import_all_macro_t, ImportTabLit_t>(import->target)) { 7062 if (ast_is<import_all_macro_t, ImportTabLit_t>(import->target)) {
7069 x = import->target.get(); 7063 x = import->target.get();
7070 bool importAllMacro = import->target.is<import_all_macro_t>(); 7064 bool importAllMacro = import->target.is<import_all_macro_t>();
7071 std::list<std::pair<std::string,std::string>> macroPairs; 7065 std::list<std::pair<std::string, std::string>> macroPairs;
7072 auto newTab = x->new_ptr<ImportTabLit_t>(); 7066 auto newTab = x->new_ptr<ImportTabLit_t>();
7073 if (auto tabLit = import->target.as<ImportTabLit_t>()) { 7067 if (auto tabLit = import->target.as<ImportTabLit_t>()) {
7074 for (auto item : tabLit->items.objects()) { 7068 for (auto item : tabLit->items.objects()) {
@@ -7369,8 +7363,7 @@ private:
7369 for (auto branch_ : branches) { 7363 for (auto branch_ : branches) {
7370 auto branch = static_cast<SwitchCase_t*>(branch_); 7364 auto branch = static_cast<SwitchCase_t*>(branch_);
7371 if (auto value = singleValueFrom(branch->valueList); 7365 if (auto value = singleValueFrom(branch->valueList);
7372 value && (value->item.is<simple_table_t>() || 7366 value && (value->item.is<simple_table_t>() || value->getByPath<SimpleValue_t, TableLit_t>())) {
7373 value->getByPath<SimpleValue_t, TableLit_t>())) {
7374 if (!firstBranch) { 7367 if (!firstBranch) {
7375 temp.push_back(indent() + "else"s + nll(branch)); 7368 temp.push_back(indent() + "else"s + nll(branch));
7376 pushScope(); 7369 pushScope();
@@ -7440,8 +7433,7 @@ private:
7440 if (!singleValueFrom(exp)) { 7433 if (!singleValueFrom(exp)) {
7441 tmp.back() = '(' + tmp.back() + ')'; 7434 tmp.back() = '(' + tmp.back() + ')';
7442 } 7435 }
7443 temp.back().append(' ' + tmp.back() + " == "s + 7436 temp.back().append(' ' + tmp.back() + " == "s + (exp == exprs.back() ? objVar : objVar + " or"s));
7444 (exp == exprs.back() ? objVar : objVar + " or"s));
7445 } 7437 }
7446 temp.back().append(" then"s + nll(branch)); 7438 temp.back().append(" then"s + nll(branch));
7447 pushScope(); 7439 pushScope();
@@ -7674,22 +7666,23 @@ const std::string YueCompilerImpl::Empty;
7674 7666
7675YueCompiler::YueCompiler(void* sharedState, 7667YueCompiler::YueCompiler(void* sharedState,
7676 const std::function<void(void*)>& luaOpen, 7668 const std::function<void(void*)>& luaOpen,
7677 bool sameModule): 7669 bool sameModule)
7670 :
7678#ifndef YUE_NO_MACRO 7671#ifndef YUE_NO_MACRO
7679_compiler(std::make_unique<YueCompilerImpl>(static_cast<lua_State*>(sharedState), luaOpen, sameModule)) {} 7672 _compiler(std::make_unique<YueCompilerImpl>(static_cast<lua_State*>(sharedState), luaOpen, sameModule)) {
7673}
7680#else 7674#else
7681_compiler(std::make_unique<YueCompilerImpl>()) { 7675 _compiler(std::make_unique<YueCompilerImpl>()) {
7682 (void)sharedState; 7676 (void)sharedState;
7683 (void)luaOpen; 7677 (void)luaOpen;
7684 (void)sameModule; 7678 (void)sameModule;
7685} 7679}
7686#endif // YUE_NO_MACRO 7680#endif // YUE_NO_MACRO
7687 7681
7688YueCompiler::~YueCompiler() {} 7682YueCompiler::~YueCompiler() { }
7689 7683
7690CompileInfo YueCompiler::compile(std::string_view codes, const YueConfig& config) { 7684CompileInfo YueCompiler::compile(std::string_view codes, const YueConfig& config) {
7691 return _compiler->compile(codes, config); 7685 return _compiler->compile(codes, config);
7692} 7686}
7693 7687
7694} // namespace yue 7688} // namespace yue
7695