diff options
| author | Li Jin <dragon-fly@qq.com> | 2022-08-19 18:05:31 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2022-08-19 18:05:31 +0800 |
| commit | 2ef8f936224fe8506673561d033142aeddcc44c1 (patch) | |
| tree | 274c816874b28cf363d3aec0ef7c9a9b1a630c02 /src/yuescript/yue_compiler.cpp | |
| parent | a4d4893c77f9c48dedc88472a2e418bfd65e33a1 (diff) | |
| download | yuescript-2ef8f936224fe8506673561d033142aeddcc44c1.tar.gz yuescript-2ef8f936224fe8506673561d033142aeddcc44c1.tar.bz2 yuescript-2ef8f936224fe8506673561d033142aeddcc44c1.zip | |
fix format.
Diffstat (limited to '')
| -rwxr-xr-x | src/yuescript/yue_compiler.cpp | 353 |
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 | ||
| 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.*/ | 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 | 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 | ||
| 23 | extern "C" { | 23 | extern "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" { | |||
| 40 | namespace yue { | 40 | namespace 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 | ||
| 55 | typedef std::list<std::string> str_list; | 60 | typedef 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 | |||
| 225 | private: | 230 | private: |
| 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 | ||
| 7675 | YueCompiler::YueCompiler(void* sharedState, | 7667 | YueCompiler::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 | ||
| 7688 | YueCompiler::~YueCompiler() {} | 7682 | YueCompiler::~YueCompiler() { } |
| 7689 | 7683 | ||
| 7690 | CompileInfo YueCompiler::compile(std::string_view codes, const YueConfig& config) { | 7684 | CompileInfo 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 | |||
