diff options
| author | Li Jin <dragon-fly@qq.com> | 2020-03-11 00:21:33 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2020-03-11 00:21:33 +0800 |
| commit | 1ee056eedf773ac6166247755439092e0e0a9bca (patch) | |
| tree | 1b8863338d37fe6ded7fbaecd92d76cdb3801ab3 /src/MoonP | |
| parent | 015af4b70cd751e1c1580fd542997a796e1ca225 (diff) | |
| download | yuescript-1ee056eedf773ac6166247755439092e0e0a9bca.tar.gz yuescript-1ee056eedf773ac6166247755439092e0e0a9bca.tar.bz2 yuescript-1ee056eedf773ac6166247755439092e0e0a9bca.zip | |
add macro functions.
Diffstat (limited to 'src/MoonP')
| -rw-r--r-- | src/MoonP/moon_ast.h | 62 | ||||
| -rw-r--r-- | src/MoonP/moon_compiler.cpp | 661 | ||||
| -rw-r--r-- | src/MoonP/moon_compiler.h | 6 | ||||
| -rw-r--r-- | src/MoonP/moon_parser.cpp | 68 | ||||
| -rw-r--r-- | src/MoonP/moon_parser.h | 13 |
5 files changed, 723 insertions, 87 deletions
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index 9fab215..0725bda 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h | |||
| @@ -92,11 +92,19 @@ AST_NODE(NameList) | |||
| 92 | AST_MEMBER(NameList, &sep, &names) | 92 | AST_MEMBER(NameList, &sep, &names) |
| 93 | AST_END(NameList) | 93 | AST_END(NameList) |
| 94 | 94 | ||
| 95 | class ExpListLow_t; | ||
| 96 | |||
| 97 | AST_NODE(local_values) | ||
| 98 | ast_ptr<true, NameList_t> nameList; | ||
| 99 | ast_ptr<false, ExpListLow_t> valueList; | ||
| 100 | AST_MEMBER(local_values, &nameList, &valueList) | ||
| 101 | AST_END(local_values) | ||
| 102 | |||
| 95 | AST_NODE(Local) | 103 | AST_NODE(Local) |
| 96 | ast_sel<true, local_flag_t, NameList_t> name; | 104 | ast_sel<true, local_flag_t, local_values_t> item; |
| 97 | std::list<std::string> forceDecls; | 105 | std::list<std::string> forceDecls; |
| 98 | std::list<std::string> decls; | 106 | std::list<std::string> decls; |
| 99 | AST_MEMBER(Local, &name) | 107 | AST_MEMBER(Local, &item) |
| 100 | AST_END(Local) | 108 | AST_END(Local) |
| 101 | 109 | ||
| 102 | AST_NODE(colon_import_name) | 110 | AST_NODE(colon_import_name) |
| @@ -116,12 +124,6 @@ AST_NODE(ImportLiteral) | |||
| 116 | AST_MEMBER(ImportLiteral, &sep, &inners) | 124 | AST_MEMBER(ImportLiteral, &sep, &inners) |
| 117 | AST_END(ImportLiteral) | 125 | AST_END(ImportLiteral) |
| 118 | 126 | ||
| 119 | AST_NODE(ImportAs) | ||
| 120 | ast_ptr<true, ImportLiteral_t> literal; | ||
| 121 | ast_sel<false, Variable_t, TableLit_t> target; | ||
| 122 | AST_MEMBER(ImportAs, &literal, &target) | ||
| 123 | AST_END(ImportAs) | ||
| 124 | |||
| 125 | AST_NODE(ImportFrom) | 127 | AST_NODE(ImportFrom) |
| 126 | ast_ptr<true, Seperator_t> sep; | 128 | ast_ptr<true, Seperator_t> sep; |
| 127 | ast_sel_list<true, colon_import_name_t, Variable_t> names; | 129 | ast_sel_list<true, colon_import_name_t, Variable_t> names; |
| @@ -129,6 +131,12 @@ AST_NODE(ImportFrom) | |||
| 129 | AST_MEMBER(ImportFrom, &sep, &names, &exp) | 131 | AST_MEMBER(ImportFrom, &sep, &names, &exp) |
| 130 | AST_END(ImportFrom) | 132 | AST_END(ImportFrom) |
| 131 | 133 | ||
| 134 | AST_NODE(ImportAs) | ||
| 135 | ast_ptr<true, ImportLiteral_t> literal; | ||
| 136 | ast_sel<false, Variable_t, TableLit_t> target; | ||
| 137 | AST_MEMBER(ImportAs, &literal, &target) | ||
| 138 | AST_END(ImportAs) | ||
| 139 | |||
| 132 | AST_NODE(Import) | 140 | AST_NODE(Import) |
| 133 | ast_sel<true, ImportAs_t, ImportFrom_t> content; | 141 | ast_sel<true, ImportAs_t, ImportFrom_t> content; |
| 134 | AST_MEMBER(Import, &content) | 142 | AST_MEMBER(Import, &content) |
| @@ -333,9 +341,10 @@ AST_NODE(Exp) | |||
| 333 | AST_END(Exp) | 341 | AST_END(Exp) |
| 334 | 342 | ||
| 335 | class Parens_t; | 343 | class Parens_t; |
| 344 | class MacroName_t; | ||
| 336 | 345 | ||
| 337 | AST_NODE(Callable) | 346 | AST_NODE(Callable) |
| 338 | ast_sel<true, Variable_t, SelfName_t, VarArg_t, Parens_t> item; | 347 | ast_sel<true, Variable_t, SelfName_t, VarArg_t, Parens_t, MacroName_t> item; |
| 339 | AST_MEMBER(Callable, &item) | 348 | AST_MEMBER(Callable, &item) |
| 340 | AST_END(Callable) | 349 | AST_END(Callable) |
| 341 | 350 | ||
| @@ -469,9 +478,15 @@ AST_END(Value) | |||
| 469 | AST_LEAF(default_value) | 478 | AST_LEAF(default_value) |
| 470 | AST_END(default_value) | 479 | AST_END(default_value) |
| 471 | 480 | ||
| 481 | AST_NODE(macro_name_pair) | ||
| 482 | ast_ptr<true, MacroName_t> key; | ||
| 483 | ast_ptr<true, MacroName_t> value; | ||
| 484 | AST_MEMBER(macro_name_pair, &key, &value) | ||
| 485 | AST_END(macro_name_pair) | ||
| 486 | |||
| 472 | AST_NODE(TableLit) | 487 | AST_NODE(TableLit) |
| 473 | ast_ptr<true, Seperator_t> sep; | 488 | ast_ptr<true, Seperator_t> sep; |
| 474 | ast_sel_list<false, variable_pair_t, normal_pair_t, Exp_t> values; | 489 | ast_sel_list<false, variable_pair_t, normal_pair_t, Exp_t, MacroName_t, macro_name_pair_t> values; |
| 475 | AST_MEMBER(TableLit, &sep, &values) | 490 | AST_MEMBER(TableLit, &sep, &values) |
| 476 | AST_END(TableLit) | 491 | AST_END(TableLit) |
| 477 | 492 | ||
| @@ -517,9 +532,11 @@ AST_END(Global) | |||
| 517 | AST_LEAF(export_default) | 532 | AST_LEAF(export_default) |
| 518 | AST_END(export_default) | 533 | AST_END(export_default) |
| 519 | 534 | ||
| 535 | class Macro_t; | ||
| 536 | |||
| 520 | AST_NODE(Export) | 537 | AST_NODE(Export) |
| 521 | ast_ptr<false, export_default_t> def; | 538 | ast_ptr<false, export_default_t> def; |
| 522 | ast_sel<true, ExpList_t, Exp_t> target; | 539 | ast_sel<true, ExpList_t, Exp_t, Macro_t> target; |
| 523 | ast_ptr<false, Assign_t> assign; | 540 | ast_ptr<false, Assign_t> assign; |
| 524 | AST_MEMBER(Export, &def, &target, &assign) | 541 | AST_MEMBER(Export, &def, &target, &assign) |
| 525 | AST_END(Export) | 542 | AST_END(Export) |
| @@ -558,6 +575,27 @@ AST_NODE(FunLit) | |||
| 558 | AST_MEMBER(FunLit, &argsDef, &arrow, &body) | 575 | AST_MEMBER(FunLit, &argsDef, &arrow, &body) |
| 559 | AST_END(FunLit) | 576 | AST_END(FunLit) |
| 560 | 577 | ||
| 578 | AST_LEAF(macro_type) | ||
| 579 | AST_END(macro_type) | ||
| 580 | |||
| 581 | AST_NODE(MacroName) | ||
| 582 | ast_ptr<true, Name_t> name; | ||
| 583 | AST_MEMBER(MacroName, &name) | ||
| 584 | AST_END(MacroName) | ||
| 585 | |||
| 586 | AST_NODE(MacroLit) | ||
| 587 | ast_ptr<false, FnArgDefList_t> argsDef; | ||
| 588 | ast_ptr<true, Body_t> body; | ||
| 589 | AST_MEMBER(MacroLit, &argsDef, &body) | ||
| 590 | AST_END(MacroLit) | ||
| 591 | |||
| 592 | AST_NODE(Macro) | ||
| 593 | ast_ptr<true, macro_type_t> type; | ||
| 594 | ast_ptr<true, Name_t> name; | ||
| 595 | ast_ptr<true, MacroLit_t> macroLit; | ||
| 596 | AST_MEMBER(Macro, &type, &name, ¯oLit) | ||
| 597 | AST_END(Macro) | ||
| 598 | |||
| 561 | AST_NODE(NameOrDestructure) | 599 | AST_NODE(NameOrDestructure) |
| 562 | ast_sel<true, Variable_t, TableLit_t> item; | 600 | ast_sel<true, Variable_t, TableLit_t> item; |
| 563 | AST_MEMBER(NameOrDestructure, &item) | 601 | AST_MEMBER(NameOrDestructure, &item) |
| @@ -611,7 +649,7 @@ AST_END(BreakLoop) | |||
| 611 | 649 | ||
| 612 | AST_NODE(Statement) | 650 | AST_NODE(Statement) |
| 613 | ast_sel<true, Import_t, While_t, For_t, ForEach_t, | 651 | ast_sel<true, Import_t, While_t, For_t, ForEach_t, |
| 614 | Return_t, Local_t, Global_t, Export_t, BreakLoop_t, | 652 | Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t, |
| 615 | Backcall_t, ExpListAssign_t> content; | 653 | Backcall_t, ExpListAssign_t> content; |
| 616 | ast_ptr<false, statement_appendix_t> appendix; | 654 | ast_ptr<false, statement_appendix_t> appendix; |
| 617 | AST_MEMBER(Statement, &content, &appendix) | 655 | AST_MEMBER(Statement, &content, &appendix) |
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 1adfec9..046bf28 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
| @@ -17,6 +17,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
| 17 | #include "MoonP/moon_parser.h" | 17 | #include "MoonP/moon_parser.h" |
| 18 | #include "MoonP/moon_compiler.h" | 18 | #include "MoonP/moon_compiler.h" |
| 19 | 19 | ||
| 20 | extern "C" { | ||
| 21 | |||
| 22 | #include "lua.h" | ||
| 23 | #include "lauxlib.h" | ||
| 24 | #include "lualib.h" | ||
| 25 | |||
| 26 | } // extern "C" | ||
| 27 | |||
| 20 | namespace MoonP { | 28 | namespace MoonP { |
| 21 | using namespace std::string_view_literals; | 29 | using namespace std::string_view_literals; |
| 22 | using namespace parserlib; | 30 | using namespace parserlib; |
| @@ -32,11 +40,44 @@ inline std::string s(std::string_view sv) { | |||
| 32 | } | 40 | } |
| 33 | 41 | ||
| 34 | const char* moonScriptVersion() { | 42 | const char* moonScriptVersion() { |
| 35 | return "0.5.0-r0.2.0"; | 43 | return "0.5.0-r0.3.0"; |
| 36 | } | 44 | } |
| 37 | 45 | ||
| 46 | // name of table stored in lua registry | ||
| 47 | #define MOONP_MODULE "_modules_" | ||
| 48 | |||
| 38 | class MoonCompilerImpl { | 49 | class MoonCompilerImpl { |
| 39 | public: | 50 | public: |
| 51 | MoonCompilerImpl(lua_State* sharedState, | ||
| 52 | const std::function<void(void*)>& luaOpen, | ||
| 53 | bool sameModule, | ||
| 54 | std::string_view moduleName = {}): | ||
| 55 | L(sharedState), | ||
| 56 | _luaOpen(luaOpen), | ||
| 57 | _moduleName(moduleName) { | ||
| 58 | int top = -1; | ||
| 59 | BLOCK_START | ||
| 60 | BREAK_IF(!sameModule); | ||
| 61 | BREAK_IF(!L); | ||
| 62 | top = lua_gettop(L); | ||
| 63 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE | ||
| 64 | lua_rawget(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE], tb | ||
| 65 | BREAK_IF(lua_istable(L, -1) == 0); | ||
| 66 | int idx = static_cast<int>(lua_objlen(L, -1)); // idx = #tb, tb | ||
| 67 | BREAK_IF(idx == 0); | ||
| 68 | _useModule = true; | ||
| 69 | _sameModule = true; | ||
| 70 | BLOCK_END | ||
| 71 | if (top != -1) lua_settop(L, top); | ||
| 72 | } | ||
| 73 | |||
| 74 | ~MoonCompilerImpl() { | ||
| 75 | if (L && _stateOwner) { | ||
| 76 | lua_close(L); | ||
| 77 | L = nullptr; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 40 | std::tuple<std::string,std::string,GlobalVars> compile(std::string_view codes, const MoonConfig& config) { | 81 | std::tuple<std::string,std::string,GlobalVars> compile(std::string_view codes, const MoonConfig& config) { |
| 41 | _config = config; | 82 | _config = config; |
| 42 | _info = _parser.parse<File_t>(codes); | 83 | _info = _parser.parse<File_t>(codes); |
| @@ -83,8 +124,23 @@ public: | |||
| 83 | _joinBuf.str(""); | 124 | _joinBuf.str(""); |
| 84 | _joinBuf.clear(); | 125 | _joinBuf.clear(); |
| 85 | _globals.clear(); | 126 | _globals.clear(); |
| 127 | if (_useModule) { | ||
| 128 | _useModule = false; | ||
| 129 | if (!_sameModule) { | ||
| 130 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE | ||
| 131 | lua_rawget(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE], tb | ||
| 132 | int idx = static_cast<int>(lua_objlen(L, -1)); | ||
| 133 | lua_pushnil(L); // tb nil | ||
| 134 | lua_rawseti(L, -2, idx); // tb[idx] = nil, tb | ||
| 135 | lua_pop(L, 1); // empty | ||
| 136 | } | ||
| 137 | } | ||
| 86 | } | 138 | } |
| 87 | private: | 139 | private: |
| 140 | bool _stateOwner = false; | ||
| 141 | bool _useModule = false; | ||
| 142 | bool _sameModule = false; | ||
| 143 | lua_State* L = nullptr; | ||
| 88 | MoonConfig _config; | 144 | MoonConfig _config; |
| 89 | MoonParser _parser; | 145 | MoonParser _parser; |
| 90 | ParseInfo _info; | 146 | ParseInfo _info; |
| @@ -97,6 +153,9 @@ private: | |||
| 97 | std::ostringstream _buf; | 153 | std::ostringstream _buf; |
| 98 | std::ostringstream _joinBuf; | 154 | std::ostringstream _joinBuf; |
| 99 | const std::string _newLine = "\n"; | 155 | const std::string _newLine = "\n"; |
| 156 | std::function<void(void*)> _luaOpen; | ||
| 157 | std::string _moduleName; | ||
| 158 | |||
| 100 | enum class LocalMode { | 159 | enum class LocalMode { |
| 101 | None = 0, | 160 | None = 0, |
| 102 | Capital = 1, | 161 | Capital = 1, |
| @@ -254,7 +313,7 @@ private: | |||
| 254 | 313 | ||
| 255 | const std::string nll(ast_node* node) const { | 314 | const std::string nll(ast_node* node) const { |
| 256 | if (_config.reserveLineNumber) { | 315 | if (_config.reserveLineNumber) { |
| 257 | return s(" -- "sv) + std::to_string(node->m_begin.m_line) + _newLine; | 316 | return s(" -- "sv) + std::to_string(node->m_begin.m_line + _config.lineOffset) + _newLine; |
| 258 | } else { | 317 | } else { |
| 259 | return _newLine; | 318 | return _newLine; |
| 260 | } | 319 | } |
| @@ -262,7 +321,7 @@ private: | |||
| 262 | 321 | ||
| 263 | const std::string nlr(ast_node* node) const { | 322 | const std::string nlr(ast_node* node) const { |
| 264 | if (_config.reserveLineNumber) { | 323 | if (_config.reserveLineNumber) { |
| 265 | return s(" -- "sv) + std::to_string(node->m_end.m_line) + _newLine; | 324 | return s(" -- "sv) + std::to_string(node->m_end.m_line + _config.lineOffset) + _newLine; |
| 266 | } else { | 325 | } else { |
| 267 | return _newLine; | 326 | return _newLine; |
| 268 | } | 327 | } |
| @@ -383,9 +442,13 @@ private: | |||
| 383 | template <class T> | 442 | template <class T> |
| 384 | ast_ptr<false, T> toAst(std::string_view codes, ast_node* parent) { | 443 | ast_ptr<false, T> toAst(std::string_view codes, ast_node* parent) { |
| 385 | auto res = _parser.parse<T>(s(codes)); | 444 | auto res = _parser.parse<T>(s(codes)); |
| 445 | int line = parent->m_begin.m_line; | ||
| 446 | int col = parent->m_begin.m_line; | ||
| 386 | res.node->traverse([&](ast_node* node) { | 447 | res.node->traverse([&](ast_node* node) { |
| 387 | node->m_begin.m_line = parent->m_begin.m_line; | 448 | node->m_begin.m_line = line; |
| 388 | node->m_end.m_line = parent->m_begin.m_line; | 449 | node->m_end.m_line = line; |
| 450 | node->m_begin.m_col = col; | ||
| 451 | node->m_end.m_col = col; | ||
| 389 | return traversal::Continue; | 452 | return traversal::Continue; |
| 390 | }); | 453 | }); |
| 391 | _codeCache.push_back(std::move(res.codes)); | 454 | _codeCache.push_back(std::move(res.codes)); |
| @@ -401,10 +464,14 @@ private: | |||
| 401 | EndWithColon, | 464 | EndWithColon, |
| 402 | EndWithEOP, | 465 | EndWithEOP, |
| 403 | HasEOP, | 466 | HasEOP, |
| 404 | HasKeyword | 467 | HasKeyword, |
| 468 | Macro | ||
| 405 | }; | 469 | }; |
| 406 | 470 | ||
| 407 | ChainType specialChainValue(ChainValue_t* chainValue) const { | 471 | ChainType specialChainValue(ChainValue_t* chainValue) const { |
| 472 | if (isMacroChain(chainValue)) { | ||
| 473 | return ChainType::Macro; | ||
| 474 | } | ||
| 408 | if (ast_is<ColonChainItem_t>(chainValue->items.back())) { | 475 | if (ast_is<ColonChainItem_t>(chainValue->items.back())) { |
| 409 | return ChainType::EndWithColon; | 476 | return ChainType::EndWithColon; |
| 410 | } | 477 | } |
| @@ -531,7 +598,7 @@ private: | |||
| 531 | for (auto exp_ : expList->exprs.objects()) { | 598 | for (auto exp_ : expList->exprs.objects()) { |
| 532 | Exp_t* exp = static_cast<Exp_t*>(exp_); | 599 | Exp_t* exp = static_cast<Exp_t*>(exp_); |
| 533 | if (!isAssignable(exp)) { | 600 | if (!isAssignable(exp)) { |
| 534 | throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, exp)); | 601 | throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, exp)); |
| 535 | } | 602 | } |
| 536 | } | 603 | } |
| 537 | } | 604 | } |
| @@ -551,6 +618,21 @@ private: | |||
| 551 | return backcall; | 618 | return backcall; |
| 552 | } | 619 | } |
| 553 | 620 | ||
| 621 | bool isMacroChain(ChainValue_t* chainValue) const { | ||
| 622 | const auto& chainList = chainValue->items.objects(); | ||
| 623 | BLOCK_START | ||
| 624 | auto callable = ast_cast<Callable_t>(chainList.front()); | ||
| 625 | BREAK_IF(!callable); | ||
| 626 | BREAK_IF(!callable->item.is<MacroName_t>()); | ||
| 627 | if (chainList.size() == 1 || | ||
| 628 | !ast_is<Invoke_t,InvokeArgs_t>(*(++chainList.begin()))) { | ||
| 629 | throw std::logic_error(_info.errorMessage("macro expression must be followed by argument list"sv, callable)); | ||
| 630 | } | ||
| 631 | return true; | ||
| 632 | BLOCK_END | ||
| 633 | return false; | ||
| 634 | } | ||
| 635 | |||
| 554 | void transformStatement(Statement_t* statement, str_list& out) { | 636 | void transformStatement(Statement_t* statement, str_list& out) { |
| 555 | auto x = statement; | 637 | auto x = statement; |
| 556 | if (statement->appendix) { | 638 | if (statement->appendix) { |
| @@ -667,6 +749,7 @@ private: | |||
| 667 | case id<Local_t>(): transformLocal(static_cast<Local_t*>(content), out); break; | 749 | case id<Local_t>(): transformLocal(static_cast<Local_t*>(content), out); break; |
| 668 | case id<Global_t>(): transformGlobal(static_cast<Global_t*>(content), out); break; | 750 | case id<Global_t>(): transformGlobal(static_cast<Global_t*>(content), out); break; |
| 669 | case id<Export_t>(): transformExport(static_cast<Export_t*>(content), out); break; | 751 | case id<Export_t>(): transformExport(static_cast<Export_t*>(content), out); break; |
| 752 | case id<Macro_t>(): transformMacro(static_cast<Macro_t*>(content), out, false); break; | ||
| 670 | case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break; | 753 | case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break; |
| 671 | case id<ExpListAssign_t>(): { | 754 | case id<ExpListAssign_t>(): { |
| 672 | auto expListAssign = static_cast<ExpListAssign_t*>(content); | 755 | auto expListAssign = static_cast<ExpListAssign_t*>(content); |
| @@ -712,7 +795,7 @@ private: | |||
| 712 | break; | 795 | break; |
| 713 | } | 796 | } |
| 714 | } | 797 | } |
| 715 | throw std::logic_error(_info.errorMessage("Expression list is not supported here."sv, expList)); | 798 | throw std::logic_error(_info.errorMessage("expression list is not supported here"sv, expList)); |
| 716 | } | 799 | } |
| 717 | break; | 800 | break; |
| 718 | } | 801 | } |
| @@ -762,7 +845,7 @@ private: | |||
| 762 | BLOCK_END | 845 | BLOCK_END |
| 763 | } | 846 | } |
| 764 | } else { | 847 | } else { |
| 765 | throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, exp)); | 848 | throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, exp)); |
| 766 | } | 849 | } |
| 767 | } | 850 | } |
| 768 | return preDefs; | 851 | return preDefs; |
| @@ -791,7 +874,7 @@ private: | |||
| 791 | BLOCK_END | 874 | BLOCK_END |
| 792 | } | 875 | } |
| 793 | } else { | 876 | } else { |
| 794 | throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, exp)); | 877 | throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, exp)); |
| 795 | } | 878 | } |
| 796 | } | 879 | } |
| 797 | return defs; | 880 | return defs; |
| @@ -950,6 +1033,7 @@ private: | |||
| 950 | return; | 1033 | return; |
| 951 | } | 1034 | } |
| 952 | case ChainType::HasKeyword: | 1035 | case ChainType::HasKeyword: |
| 1036 | case ChainType::Macro: | ||
| 953 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); | 1037 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); |
| 954 | return; | 1038 | return; |
| 955 | case ChainType::Common: | 1039 | case ChainType::Common: |
| @@ -1041,7 +1125,7 @@ private: | |||
| 1041 | const node_container* tableItems = nullptr; | 1125 | const node_container* tableItems = nullptr; |
| 1042 | if (ast_is<Exp_t>(node)) { | 1126 | if (ast_is<Exp_t>(node)) { |
| 1043 | auto item = singleValueFrom(node)->item.get(); | 1127 | auto item = singleValueFrom(node)->item.get(); |
| 1044 | if (!item) throw std::logic_error(_info.errorMessage("Invalid destructure value."sv, node)); | 1128 | if (!item) throw std::logic_error(_info.errorMessage("invalid destructure value"sv, node)); |
| 1045 | auto tbA = item->getByPath<TableLit_t>(); | 1129 | auto tbA = item->getByPath<TableLit_t>(); |
| 1046 | if (tbA) { | 1130 | if (tbA) { |
| 1047 | tableItems = &tbA->values.objects(); | 1131 | tableItems = &tbA->values.objects(); |
| @@ -1059,7 +1143,7 @@ private: | |||
| 1059 | case id<Exp_t>(): { | 1143 | case id<Exp_t>(): { |
| 1060 | ++index; | 1144 | ++index; |
| 1061 | if (!isAssignable(static_cast<Exp_t*>(pair))) { | 1145 | if (!isAssignable(static_cast<Exp_t*>(pair))) { |
| 1062 | throw std::logic_error(_info.errorMessage("Can't destructure value."sv, pair)); | 1146 | throw std::logic_error(_info.errorMessage("can't destructure value"sv, pair)); |
| 1063 | } | 1147 | } |
| 1064 | auto value = singleValueFrom(pair); | 1148 | auto value = singleValueFrom(pair); |
| 1065 | auto item = value->item.get(); | 1149 | auto item = value->item.get(); |
| @@ -1103,9 +1187,9 @@ private: | |||
| 1103 | case id<normal_pair_t>(): { | 1187 | case id<normal_pair_t>(): { |
| 1104 | auto np = static_cast<normal_pair_t*>(pair); | 1188 | auto np = static_cast<normal_pair_t*>(pair); |
| 1105 | auto key = np->key->getByPath<Name_t>(); | 1189 | auto key = np->key->getByPath<Name_t>(); |
| 1106 | if (!key) throw std::logic_error(_info.errorMessage("Invalid key for destructure."sv, np)); | 1190 | if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, np)); |
| 1107 | if (auto exp = np->value.as<Exp_t>()) { | 1191 | if (auto exp = np->value.as<Exp_t>()) { |
| 1108 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("Can't destructure value."sv, exp)); | 1192 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); |
| 1109 | auto item = singleValueFrom(exp)->item.get(); | 1193 | auto item = singleValueFrom(exp)->item.get(); |
| 1110 | if (ast_is<simple_table_t>(item) || | 1194 | if (ast_is<simple_table_t>(item) || |
| 1111 | item->getByPath<TableLit_t>()) { | 1195 | item->getByPath<TableLit_t>()) { |
| @@ -1227,11 +1311,11 @@ private: | |||
| 1227 | auto action = assignment->action.get(); | 1311 | auto action = assignment->action.get(); |
| 1228 | switch (action->getId()) { | 1312 | switch (action->getId()) { |
| 1229 | case id<Update_t>(): { | 1313 | case id<Update_t>(): { |
| 1230 | if (expList->exprs.size() > 1) throw std::logic_error(_info.errorMessage("Can not apply update to multiple values."sv, expList)); | 1314 | if (expList->exprs.size() > 1) throw std::logic_error(_info.errorMessage("can not apply update to multiple values"sv, expList)); |
| 1231 | auto update = static_cast<Update_t*>(action); | 1315 | auto update = static_cast<Update_t*>(action); |
| 1232 | auto leftExp = static_cast<Exp_t*>(expList->exprs.objects().front()); | 1316 | auto leftExp = static_cast<Exp_t*>(expList->exprs.objects().front()); |
| 1233 | auto leftValue = singleValueFrom(leftExp); | 1317 | auto leftValue = singleValueFrom(leftExp); |
| 1234 | if (!leftValue) throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, leftExp)); | 1318 | if (!leftValue) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftExp)); |
| 1235 | if (auto chain = leftValue->getByPath<ChainValue_t>()) { | 1319 | if (auto chain = leftValue->getByPath<ChainValue_t>()) { |
| 1236 | auto tmpChain = x->new_ptr<ChainValue_t>(); | 1320 | auto tmpChain = x->new_ptr<ChainValue_t>(); |
| 1237 | for (auto item : chain->items.objects()) { | 1321 | for (auto item : chain->items.objects()) { |
| @@ -1544,7 +1628,7 @@ private: | |||
| 1544 | args->swap(a, arg); | 1628 | args->swap(a, arg); |
| 1545 | findPlaceHolder = true; | 1629 | findPlaceHolder = true; |
| 1546 | } else { | 1630 | } else { |
| 1547 | throw std::logic_error(_info.errorMessage("backcall placeholder can be used only in one place."sv, a)); | 1631 | throw std::logic_error(_info.errorMessage("backcall placeholder can be used only in one place"sv, a)); |
| 1548 | } | 1632 | } |
| 1549 | } | 1633 | } |
| 1550 | } | 1634 | } |
| @@ -1576,7 +1660,7 @@ private: | |||
| 1576 | } | 1660 | } |
| 1577 | return; | 1661 | return; |
| 1578 | } else { | 1662 | } else { |
| 1579 | throw std::logic_error(_info.errorMessage("Backcall operator must be followed by chain value."sv, opValue->value)); | 1663 | throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, opValue->value)); |
| 1580 | } | 1664 | } |
| 1581 | } | 1665 | } |
| 1582 | } | 1666 | } |
| @@ -1789,7 +1873,7 @@ private: | |||
| 1789 | args->swap(a, arg); | 1873 | args->swap(a, arg); |
| 1790 | findPlaceHolder = true; | 1874 | findPlaceHolder = true; |
| 1791 | } else { | 1875 | } else { |
| 1792 | throw std::logic_error(_info.errorMessage("Backcall placeholder can be used only in one place."sv, a)); | 1876 | throw std::logic_error(_info.errorMessage("backcall placeholder can be used only in one place"sv, a)); |
| 1793 | } | 1877 | } |
| 1794 | } | 1878 | } |
| 1795 | } | 1879 | } |
| @@ -1820,21 +1904,27 @@ private: | |||
| 1820 | return; | 1904 | return; |
| 1821 | } | 1905 | } |
| 1822 | if (auto local = stmt->content.as<Local_t>()) { | 1906 | if (auto local = stmt->content.as<Local_t>()) { |
| 1823 | if (auto flag = local->name.as<local_flag_t>()) { | 1907 | switch (local->item->getId()) { |
| 1824 | LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; | 1908 | case id<local_flag_t>(): { |
| 1825 | if (int(newMode) > int(mode)) { | 1909 | auto flag = local->item.to<local_flag_t>(); |
| 1826 | mode = newMode; | 1910 | LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; |
| 1827 | } | 1911 | if (int(newMode) > int(mode)) { |
| 1828 | if (mode == LocalMode::Any) { | 1912 | mode = newMode; |
| 1829 | if (!any) any = local; | 1913 | } |
| 1830 | if (!capital) capital = local; | 1914 | if (mode == LocalMode::Any) { |
| 1831 | } else { | 1915 | if (!any) any = local; |
| 1832 | if (!capital) capital = local; | 1916 | if (!capital) capital = local; |
| 1917 | } else { | ||
| 1918 | if (!capital) capital = local; | ||
| 1919 | } | ||
| 1920 | break; | ||
| 1833 | } | 1921 | } |
| 1834 | } else { | 1922 | case id<local_values_t>(): { |
| 1835 | auto names = local->name.to<NameList_t>(); | 1923 | auto values = local->item.to<local_values_t>(); |
| 1836 | for (auto name : names->names.objects()) { | 1924 | for (auto name : values->nameList->names.objects()) { |
| 1837 | local->forceDecls.push_back(_parser.toString(name)); | 1925 | local->forceDecls.push_back(_parser.toString(name)); |
| 1926 | } | ||
| 1927 | break; | ||
| 1838 | } | 1928 | } |
| 1839 | } | 1929 | } |
| 1840 | } else if (mode != LocalMode::None) { | 1930 | } else if (mode != LocalMode::None) { |
| @@ -1960,11 +2050,190 @@ private: | |||
| 1960 | } | 2050 | } |
| 1961 | } | 2051 | } |
| 1962 | 2052 | ||
| 2053 | void pushCurrentModule() { | ||
| 2054 | if (_useModule) { | ||
| 2055 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE | ||
| 2056 | lua_rawget(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE], tb | ||
| 2057 | int idx = static_cast<int>(lua_objlen(L, -1)); // idx = #tb, tb | ||
| 2058 | lua_rawgeti(L, -1, idx); // tb[idx], tb cur | ||
| 2059 | lua_remove(L, -2); // cur | ||
| 2060 | return; | ||
| 2061 | } | ||
| 2062 | _useModule = true; | ||
| 2063 | if (!L) { | ||
| 2064 | L = luaL_newstate(); | ||
| 2065 | if (_luaOpen) { | ||
| 2066 | _luaOpen(static_cast<void*>(L)); | ||
| 2067 | } | ||
| 2068 | _stateOwner = true; | ||
| 2069 | } | ||
| 2070 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE | ||
| 2071 | lua_rawget(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE], tb | ||
| 2072 | if (lua_isnil(L, -1) != 0) { // tb == nil | ||
| 2073 | lua_pop(L, 1); | ||
| 2074 | lua_newtable(L); // tb | ||
| 2075 | lua_pushliteral(L, MOONP_MODULE); // tb MOONP_MODULE | ||
| 2076 | lua_pushvalue(L, -2); // tb MOONP_MODULE tb | ||
| 2077 | lua_rawset(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE] = tb, tb | ||
| 2078 | } // tb | ||
| 2079 | int idx = static_cast<int>(lua_objlen(L, -1)); // idx = #tb, tb | ||
| 2080 | lua_newtable(L); // tb cur | ||
| 2081 | lua_pushvalue(L, -1); // tb cur cur | ||
| 2082 | lua_rawseti(L, -3, idx + 1); // tb[idx + 1] = cur, tb cur | ||
| 2083 | lua_remove(L, -2); // cur | ||
| 2084 | } | ||
| 2085 | |||
| 2086 | void pushMoonp(std::string_view name) { | ||
| 2087 | lua_getglobal(L, "package"); // package | ||
| 2088 | lua_getfield(L, -1, "loaded"); // package loaded | ||
| 2089 | lua_getfield(L, -1, "moonp"); // package loaded moonp | ||
| 2090 | lua_pushlstring(L, &name.front(), name.size()); // package loaded moonp name | ||
| 2091 | lua_gettable(L, -2); // loaded[name], package loaded moonp item | ||
| 2092 | lua_insert(L, -4); // item package loaded moonp | ||
| 2093 | lua_pop(L, 3); // item | ||
| 2094 | } | ||
| 2095 | |||
| 2096 | void hideStackTrace(bool hide) { | ||
| 2097 | lua_getglobal(L, "package"); // package | ||
| 2098 | lua_getfield(L, -1, "loaded"); // package loaded | ||
| 2099 | lua_getfield(L, -1, "moonp"); // package loaded moonp | ||
| 2100 | if (hide) { | ||
| 2101 | lua_pushboolean(L, 1); // package loaded moonp true | ||
| 2102 | } else { | ||
| 2103 | lua_pushnil(L); // package loaded moonp nil | ||
| 2104 | } | ||
| 2105 | lua_setfield(L, -2, "_hide_stacktrace_"); | ||
| 2106 | lua_pop(L, 3); // empty | ||
| 2107 | } | ||
| 2108 | |||
| 2109 | bool isModuleLoaded(std::string_view name) { | ||
| 2110 | int top = lua_gettop(L); | ||
| 2111 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE | ||
| 2112 | lua_rawget(L, LUA_REGISTRYINDEX); // modules | ||
| 2113 | lua_pushlstring(L, &name.front(), name.size()); | ||
| 2114 | lua_rawget(L, -2); // modules module | ||
| 2115 | if (lua_isnil(L, -1) != 0) { | ||
| 2116 | lua_settop(L, top); | ||
| 2117 | return false; | ||
| 2118 | } | ||
| 2119 | lua_settop(L, top); | ||
| 2120 | return true; | ||
| 2121 | } | ||
| 2122 | |||
| 2123 | void pushModuleTable(std::string_view name) { | ||
| 2124 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE | ||
| 2125 | lua_rawget(L, LUA_REGISTRYINDEX); // modules | ||
| 2126 | lua_pushlstring(L, &name.front(), name.size()); | ||
| 2127 | lua_rawget(L, -2); // modules module | ||
| 2128 | if (lua_isnil(L, -1) != 0) { | ||
| 2129 | lua_pop(L, 1); | ||
| 2130 | lua_newtable(L); // modules module | ||
| 2131 | lua_pushlstring(L, &name.front(), name.size()); | ||
| 2132 | lua_pushvalue(L, -2); // modules module name module | ||
| 2133 | lua_rawset(L, -4); // modules[name] = module, modules module | ||
| 2134 | } | ||
| 2135 | lua_remove(L, -2); // module | ||
| 2136 | } | ||
| 2137 | |||
| 2138 | void pushOptions(int lineOffset) { | ||
| 2139 | lua_newtable(L); | ||
| 2140 | lua_pushliteral(L, "lint_global"); | ||
| 2141 | lua_pushboolean(L, 0); | ||
| 2142 | lua_rawset(L, -3); | ||
| 2143 | lua_pushliteral(L, "implicit_return_root"); | ||
| 2144 | lua_pushboolean(L, 1); | ||
| 2145 | lua_rawset(L, -3); | ||
| 2146 | lua_pushliteral(L, "reserve_line_number"); | ||
| 2147 | lua_pushboolean(L, 1); | ||
| 2148 | lua_rawset(L, -3); | ||
| 2149 | lua_pushliteral(L, "same_module"); | ||
| 2150 | lua_pushboolean(L, 1); | ||
| 2151 | lua_rawset(L, -3); | ||
| 2152 | lua_pushliteral(L, "line_offset"); | ||
| 2153 | lua_pushinteger(L, lineOffset); | ||
| 2154 | lua_rawset(L, -3); | ||
| 2155 | } | ||
| 2156 | |||
| 2157 | void transformMacro(Macro_t* macro, str_list& out, bool exporting) { | ||
| 2158 | auto type = _parser.toString(macro->type); | ||
| 2159 | auto macroName = _parser.toString(macro->name); | ||
| 2160 | auto argsDef = macro->macroLit->argsDef.get(); | ||
| 2161 | str_list newArgs; | ||
| 2162 | if (argsDef) { | ||
| 2163 | for (auto def_ : argsDef->definitions.objects()) { | ||
| 2164 | auto def = static_cast<FnArgDef_t*>(def_); | ||
| 2165 | if (def->name.is<SelfName_t>()) { | ||
| 2166 | throw std::logic_error(_info.errorMessage("self name is not supported here"sv, def->name)); | ||
| 2167 | } else { | ||
| 2168 | std::string defVal; | ||
| 2169 | if (def->defaultValue) { | ||
| 2170 | defVal = _parser.toString(def->defaultValue); | ||
| 2171 | Utils::trim(defVal); | ||
| 2172 | defVal.insert(0, "=[==========["sv); | ||
| 2173 | defVal.append("]==========]"sv); | ||
| 2174 | } | ||
| 2175 | newArgs.emplace_back(_parser.toString(def->name) + defVal); | ||
| 2176 | } | ||
| 2177 | } | ||
| 2178 | if (argsDef->varArg) { | ||
| 2179 | newArgs.emplace_back(_parser.toString(argsDef->varArg)); | ||
| 2180 | } | ||
| 2181 | } | ||
| 2182 | _buf << "fmacro = ("sv << join(newArgs, ","sv) << ")->"sv; | ||
| 2183 | _buf << _parser.toString(macro->macroLit->body) << '\n'; | ||
| 2184 | _buf << "{fmacro, \"" << type << "\"}"sv; | ||
| 2185 | auto macroCodes = clearBuf(); | ||
| 2186 | _buf << "=(macro "sv << macroName << ")"; | ||
| 2187 | auto chunkName = clearBuf(); | ||
| 2188 | pushCurrentModule(); // cur | ||
| 2189 | int top = lua_gettop(L) - 1; | ||
| 2190 | pushMoonp("loadstring"sv); // cur loadstring | ||
| 2191 | lua_pushlstring(L, macroCodes.c_str(), macroCodes.size()); // cur loadstring codes | ||
| 2192 | lua_pushlstring(L, chunkName.c_str(), chunkName.size()); // cur loadstring codes chunk | ||
| 2193 | pushOptions(macro->m_begin.m_line - 1); // cur loadstring codes chunk options | ||
| 2194 | if (lua_pcall(L, 3, 2, 0) != 0) { // loadstring(codes,chunk,options), cur f err | ||
| 2195 | std::string err = lua_tostring(L, -1); | ||
| 2196 | lua_settop(L, top); | ||
| 2197 | throw std::logic_error(_info.errorMessage(s("fail to load macro codes\n"sv) + err, macro->macroLit)); | ||
| 2198 | } // cur f err | ||
| 2199 | if (lua_isnil(L, -2) != 0) { // f == nil, cur f err | ||
| 2200 | std::string err = lua_tostring(L, -1); | ||
| 2201 | lua_settop(L, top); | ||
| 2202 | throw std::logic_error(_info.errorMessage(s("fail to load macro codes, at (macro "sv) + macroName + s("): "sv) + err, macro->macroLit)); | ||
| 2203 | } | ||
| 2204 | lua_pop(L, 1); // cur f | ||
| 2205 | pushMoonp("pcall"sv); // cur f pcall | ||
| 2206 | lua_insert(L, -2); // cur pcall f | ||
| 2207 | if (lua_pcall(L, 1, 2, 0) != 0) { // f(), cur success macro | ||
| 2208 | std::string err = lua_tostring(L, -1); | ||
| 2209 | lua_settop(L, top); | ||
| 2210 | throw std::logic_error(_info.errorMessage(s("fail to generate macro function\n"sv) + err, macro->macroLit)); | ||
| 2211 | } // cur success res | ||
| 2212 | if (lua_toboolean(L, -2) == 0) { | ||
| 2213 | std::string err = lua_tostring(L, -1); | ||
| 2214 | lua_settop(L, top); | ||
| 2215 | throw std::logic_error(_info.errorMessage(s("fail to generate macro function\n"sv) + err, macro->macroLit)); | ||
| 2216 | } // cur true macro | ||
| 2217 | lua_remove(L, -2); // cur macro | ||
| 2218 | if (exporting && !_moduleName.empty()) { | ||
| 2219 | pushModuleTable(_moduleName); // cur macro module | ||
| 2220 | lua_pushlstring(L, macroName.c_str(), macroName.size()); // cur macro module name | ||
| 2221 | lua_pushvalue(L, -3); // cur macro module name macro | ||
| 2222 | lua_rawset(L, -3); // cur macro module | ||
| 2223 | lua_pop(L, 1); | ||
| 2224 | } // cur macro | ||
| 2225 | lua_pushlstring(L, macroName.c_str(), macroName.size()); // cur macro name | ||
| 2226 | lua_insert(L, -2); // cur name macro | ||
| 2227 | lua_rawset(L, -3); // cur[name] = macro, cur | ||
| 2228 | lua_settop(L, top); | ||
| 2229 | out.push_back(Empty); | ||
| 2230 | } | ||
| 2231 | |||
| 1963 | void transformReturn(Return_t* returnNode, str_list& out) { | 2232 | void transformReturn(Return_t* returnNode, str_list& out) { |
| 1964 | if (!enableReturn.top()) { | 2233 | if (!enableReturn.top()) { |
| 1965 | ast_node* target = returnNode->valueList.get(); | 2234 | ast_node* target = returnNode->valueList.get(); |
| 1966 | if (!target) target = returnNode; | 2235 | if (!target) target = returnNode; |
| 1967 | throw std::logic_error(_info.errorMessage("Illegal return statement here."sv, target)); | 2236 | throw std::logic_error(_info.errorMessage("illegal return statement here"sv, target)); |
| 1968 | } | 2237 | } |
| 1969 | if (auto valueList = returnNode->valueList.get()) { | 2238 | if (auto valueList = returnNode->valueList.get()) { |
| 1970 | if (valueList->exprs.size() == 1) { | 2239 | if (valueList->exprs.size() == 1) { |
| @@ -2286,7 +2555,7 @@ private: | |||
| 2286 | chainValue->items.pop_back(); | 2555 | chainValue->items.pop_back(); |
| 2287 | if (chainValue->items.empty()) { | 2556 | if (chainValue->items.empty()) { |
| 2288 | if (_withVars.empty()) { | 2557 | if (_withVars.empty()) { |
| 2289 | throw std::logic_error(_info.errorMessage("Short dot/colon syntax must be called within a with block."sv, x)); | 2558 | throw std::logic_error(_info.errorMessage("short dot/colon syntax must be called within a with block"sv, x)); |
| 2290 | } | 2559 | } |
| 2291 | chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x)); | 2560 | chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x)); |
| 2292 | } | 2561 | } |
| @@ -2417,7 +2686,7 @@ private: | |||
| 2417 | case id<DotChainItem_t>(): | 2686 | case id<DotChainItem_t>(): |
| 2418 | case id<ColonChainItem_t>(): | 2687 | case id<ColonChainItem_t>(): |
| 2419 | if (_withVars.empty()) { | 2688 | if (_withVars.empty()) { |
| 2420 | throw std::logic_error(_info.errorMessage("Short dot/colon syntax must be called within a with block."sv, chainList.front())); | 2689 | throw std::logic_error(_info.errorMessage("short dot/colon syntax must be called within a with block"sv, chainList.front())); |
| 2421 | } else { | 2690 | } else { |
| 2422 | baseChain->items.push_back(toAst<Callable_t>(_withVars.top(), x)); | 2691 | baseChain->items.push_back(toAst<Callable_t>(_withVars.top(), x)); |
| 2423 | } | 2692 | } |
| @@ -2499,7 +2768,7 @@ private: | |||
| 2499 | case id<DotChainItem_t>(): | 2768 | case id<DotChainItem_t>(): |
| 2500 | case id<ColonChainItem_t>(): | 2769 | case id<ColonChainItem_t>(): |
| 2501 | if (_withVars.empty()) { | 2770 | if (_withVars.empty()) { |
| 2502 | throw std::logic_error(_info.errorMessage("Short dot/colon syntax must be called within a with block."sv, x)); | 2771 | throw std::logic_error(_info.errorMessage("short dot/colon syntax must be called within a with block"sv, x)); |
| 2503 | } else { | 2772 | } else { |
| 2504 | temp.push_back(_withVars.top()); | 2773 | temp.push_back(_withVars.top()); |
| 2505 | } | 2774 | } |
| @@ -2531,7 +2800,7 @@ private: | |||
| 2531 | --next; | 2800 | --next; |
| 2532 | } | 2801 | } |
| 2533 | if (!ast_is<Invoke_t, InvokeArgs_t>(followItem)) { | 2802 | if (!ast_is<Invoke_t, InvokeArgs_t>(followItem)) { |
| 2534 | throw std::logic_error(_info.errorMessage("Colon chain item must be followed by invoke arguments."sv, colonItem)); | 2803 | throw std::logic_error(_info.errorMessage("colon chain item must be followed by invoke arguments"sv, colonItem)); |
| 2535 | } | 2804 | } |
| 2536 | if (colonItem->name.is<LuaKeyword_t>()) { | 2805 | if (colonItem->name.is<LuaKeyword_t>()) { |
| 2537 | std::string callVar; | 2806 | std::string callVar; |
| @@ -2667,7 +2936,172 @@ private: | |||
| 2667 | } | 2936 | } |
| 2668 | } | 2937 | } |
| 2669 | 2938 | ||
| 2939 | std::pair<std::string,std::string> expandMacroStr(ChainValue_t* chainValue) { | ||
| 2940 | const auto& chainList = chainValue->items.objects(); | ||
| 2941 | auto callable = ast_cast<Callable_t>(chainList.front()); | ||
| 2942 | auto macroName = _parser.toString(callable->item.to<MacroName_t>()->name); | ||
| 2943 | if (!_useModule) { | ||
| 2944 | throw std::logic_error(_info.errorMessage("can not resolve macro", callable->item)); | ||
| 2945 | } | ||
| 2946 | pushCurrentModule(); // cur | ||
| 2947 | int top = lua_gettop(L) - 1; | ||
| 2948 | lua_pushlstring(L, macroName.c_str(), macroName.size()); // cur macroName | ||
| 2949 | lua_rawget(L, -2); // cur[macroName], cur macro | ||
| 2950 | if (lua_istable(L, -1) == 0) { | ||
| 2951 | lua_settop(L, top); | ||
| 2952 | throw std::logic_error(_info.errorMessage("can not resolve macro", callable->item)); | ||
| 2953 | } | ||
| 2954 | lua_rawgeti(L, -1, 1); // cur macro func | ||
| 2955 | pushMoonp("pcall"sv); // cur macro func pcall | ||
| 2956 | lua_insert(L, -2); // cur macro pcall func | ||
| 2957 | auto item = *(++chainList.begin()); | ||
| 2958 | const node_container* args = nullptr; | ||
| 2959 | if (auto invoke = ast_cast<Invoke_t>(item)) { | ||
| 2960 | args = &invoke->args.objects(); | ||
| 2961 | } else { | ||
| 2962 | args = &ast_to<InvokeArgs_t>(item)->args.objects(); | ||
| 2963 | } | ||
| 2964 | for (auto arg : *args) { | ||
| 2965 | std::string str; | ||
| 2966 | if (auto exp = ast_cast<Exp_t>(arg)) { | ||
| 2967 | // patch for backcall operator support | ||
| 2968 | BLOCK_START | ||
| 2969 | BREAK_IF(arg->m_begin.m_line != arg->m_end.m_line || | ||
| 2970 | arg->m_begin.m_col != arg->m_end.m_col); | ||
| 2971 | BREAK_IF(!exp->opValues.empty()); | ||
| 2972 | auto chainValue = exp->getByPath<Value_t, ChainValue_t>(); | ||
| 2973 | BREAK_IF(!chainValue); | ||
| 2974 | BREAK_IF(!isMacroChain(chainValue)); | ||
| 2975 | BREAK_IF(chainValue->items.size() != 2); | ||
| 2976 | std::string type, codes; | ||
| 2977 | std::tie(type, codes) = expandMacroStr(chainValue); | ||
| 2978 | str = codes; | ||
| 2979 | BLOCK_END | ||
| 2980 | if (str.empty()) { | ||
| 2981 | str = _parser.toString(exp->value); | ||
| 2982 | for (auto opVal : exp->opValues.objects()) { | ||
| 2983 | str += _parser.toString(opVal); | ||
| 2984 | } | ||
| 2985 | } | ||
| 2986 | } else str = _parser.toString(arg); | ||
| 2987 | Utils::trim(str); | ||
| 2988 | lua_pushlstring(L, str.c_str(), str.size()); | ||
| 2989 | } // cur macro pcall func args... | ||
| 2990 | hideStackTrace(true); | ||
| 2991 | bool success = lua_pcall(L, static_cast<int>(args->size()) + 1, 2, 0) == 0; | ||
| 2992 | if (!success) { // cur macro err | ||
| 2993 | std::string err = lua_tostring(L, -1); | ||
| 2994 | lua_settop(L, top); | ||
| 2995 | throw std::logic_error(_info.errorMessage(s("fail to expand macro\n"sv) + err, callable)); | ||
| 2996 | } // cur macro success res | ||
| 2997 | hideStackTrace(false); | ||
| 2998 | if (lua_toboolean(L, -2) == 0) { | ||
| 2999 | std::string err = lua_tostring(L, -1); | ||
| 3000 | lua_settop(L, top); | ||
| 3001 | throw std::logic_error(_info.errorMessage(s("fail to expand macro\n"sv) + err, callable)); | ||
| 3002 | } | ||
| 3003 | lua_remove(L, -2); // cur macro res | ||
| 3004 | if (lua_isstring(L, -1) == 0) { | ||
| 3005 | lua_settop(L, top); | ||
| 3006 | throw std::logic_error(_info.errorMessage(s("macro function must return string with expanded codes"sv), callable)); | ||
| 3007 | } // cur macro codes | ||
| 3008 | lua_rawgeti(L, -2, 2); // cur macro codes type | ||
| 3009 | std::string type = lua_tostring(L, -1); | ||
| 3010 | std::string codes = lua_tostring(L, -2); | ||
| 3011 | lua_settop(L, top); | ||
| 3012 | return {type, codes}; | ||
| 3013 | } | ||
| 3014 | |||
| 3015 | std::pair<ast_ptr<false,ast_node>, std::unique_ptr<input>> expandMacro(ChainValue_t* chainValue, ExpUsage usage) { | ||
| 3016 | auto x = chainValue; | ||
| 3017 | const auto& chainList = chainValue->items.objects(); | ||
| 3018 | std::string type, codes; | ||
| 3019 | std::tie(type, codes) = expandMacroStr(chainValue); | ||
| 3020 | std::string targetType(usage == ExpUsage::Common ? "block"sv : "expr"sv); | ||
| 3021 | if (type != targetType) { | ||
| 3022 | throw std::logic_error(_info.errorMessage(s("macro type mismatch, "sv) + targetType + s(" expected, got "sv) + type + '.', x)); | ||
| 3023 | } | ||
| 3024 | ParseInfo info; | ||
| 3025 | if (usage == ExpUsage::Common) { | ||
| 3026 | if (codes.empty()) { | ||
| 3027 | return {x->new_ptr<Block_t>().get(),std::move(info.codes)}; | ||
| 3028 | } | ||
| 3029 | info = _parser.parse<Block_t>(codes); | ||
| 3030 | } else { | ||
| 3031 | info = _parser.parse<Exp_t>(codes); | ||
| 3032 | } | ||
| 3033 | if (!info.node) { | ||
| 3034 | throw std::logic_error(_info.errorMessage("fail to expand macro: " + info.error, x)); | ||
| 3035 | } | ||
| 3036 | int line = x->m_begin.m_line; | ||
| 3037 | int col = x->m_begin.m_col; | ||
| 3038 | info.node->traverse([&](ast_node* node) { | ||
| 3039 | node->m_begin.m_line = line; | ||
| 3040 | node->m_end.m_line = line; | ||
| 3041 | node->m_begin.m_col = col; | ||
| 3042 | node->m_end.m_col = col; | ||
| 3043 | return traversal::Continue; | ||
| 3044 | }); | ||
| 3045 | if (usage == ExpUsage::Common) { | ||
| 3046 | return {info.node,std::move(info.codes)}; | ||
| 3047 | } else { | ||
| 3048 | ast_ptr<false, Exp_t> exp; | ||
| 3049 | exp.set(info.node); | ||
| 3050 | if (!exp->opValues.empty() || chainList.size() > 2) { | ||
| 3051 | auto paren = x->new_ptr<Parens_t>(); | ||
| 3052 | paren->expr.set(exp); | ||
| 3053 | auto callable = x->new_ptr<Callable_t>(); | ||
| 3054 | callable->item.set(paren); | ||
| 3055 | auto newChain = x->new_ptr<ChainValue_t>(); | ||
| 3056 | newChain->items.push_back(callable); | ||
| 3057 | auto it = chainList.begin(); | ||
| 3058 | it++; it++; | ||
| 3059 | for (; it != chainList.end(); ++it) { | ||
| 3060 | newChain->items.push_back(*it); | ||
| 3061 | } | ||
| 3062 | auto value = x->new_ptr<Value_t>(); | ||
| 3063 | value->item.set(newChain); | ||
| 3064 | exp = x->new_ptr<Exp_t>(); | ||
| 3065 | exp->value.set(value); | ||
| 3066 | } | ||
| 3067 | return {exp.get(),std::move(info.codes)}; | ||
| 3068 | } | ||
| 3069 | } | ||
| 3070 | |||
| 2670 | void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 3071 | void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
| 3072 | if (isMacroChain(chainValue)) { | ||
| 3073 | ast_ptr<false,ast_node> node; | ||
| 3074 | std::unique_ptr<input> codes; | ||
| 3075 | std::tie(node,codes) = expandMacro(chainValue, usage); | ||
| 3076 | if (usage == ExpUsage::Common) { | ||
| 3077 | transformBlock(node.to<Block_t>(), out, usage, assignList); | ||
| 3078 | } else { | ||
| 3079 | auto x = chainValue; | ||
| 3080 | switch (usage) { | ||
| 3081 | case ExpUsage::Assignment: { | ||
| 3082 | auto assign = x->new_ptr<Assign_t>(); | ||
| 3083 | assign->values.push_back(node); | ||
| 3084 | auto assignment = x->new_ptr<ExpListAssign_t>(); | ||
| 3085 | assignment->expList.set(assignList); | ||
| 3086 | assignment->action.set(assign); | ||
| 3087 | transformAssignment(assignment, out); | ||
| 3088 | break; | ||
| 3089 | } | ||
| 3090 | case ExpUsage::Return: { | ||
| 3091 | auto expListLow = x->new_ptr<ExpListLow_t>(); | ||
| 3092 | expListLow->exprs.push_back(node); | ||
| 3093 | auto returnNode = x->new_ptr<Return_t>(); | ||
| 3094 | returnNode->valueList.set(expListLow); | ||
| 3095 | transformReturn(returnNode, out); | ||
| 3096 | break; | ||
| 3097 | } | ||
| 3098 | default: | ||
| 3099 | transformExp(node.to<Exp_t>(), out, usage); | ||
| 3100 | break; | ||
| 3101 | } | ||
| 3102 | } | ||
| 3103 | return; | ||
| 3104 | } | ||
| 2671 | const auto& chainList = chainValue->items.objects(); | 3105 | const auto& chainList = chainValue->items.objects(); |
| 2672 | if (transformChainEndWithColonItem(chainList, out, usage, assignList)) { | 3106 | if (transformChainEndWithColonItem(chainList, out, usage, assignList)) { |
| 2673 | return; | 3107 | return; |
| @@ -2700,7 +3134,7 @@ private: | |||
| 2700 | } | 3134 | } |
| 2701 | 3135 | ||
| 2702 | void transformSlice(Slice_t* slice, str_list&) { | 3136 | void transformSlice(Slice_t* slice, str_list&) { |
| 2703 | throw std::logic_error(_info.errorMessage("Slice syntax not supported here."sv, slice)); | 3137 | throw std::logic_error(_info.errorMessage("slice syntax not supported here"sv, slice)); |
| 2704 | } | 3138 | } |
| 2705 | 3139 | ||
| 2706 | void transformInvoke(Invoke_t* invoke, str_list& out) { | 3140 | void transformInvoke(Invoke_t* invoke, str_list& out) { |
| @@ -2895,7 +3329,7 @@ private: | |||
| 2895 | auto indexVar = getUnusedName("_index_"sv); | 3329 | auto indexVar = getUnusedName("_index_"sv); |
| 2896 | varAfter.push_back(indexVar); | 3330 | varAfter.push_back(indexVar); |
| 2897 | auto value = singleValueFrom(star_exp->value); | 3331 | auto value = singleValueFrom(star_exp->value); |
| 2898 | if (!value) throw std::logic_error(_info.errorMessage("Invalid star syntax."sv, star_exp)); | 3332 | if (!value) throw std::logic_error(_info.errorMessage("invalid star syntax"sv, star_exp)); |
| 2899 | bool endWithSlice = false; | 3333 | bool endWithSlice = false; |
| 2900 | BLOCK_START | 3334 | BLOCK_START |
| 2901 | auto chainValue = value->item.as<ChainValue_t>(); | 3335 | auto chainValue = value->item.as<ChainValue_t>(); |
| @@ -3345,7 +3779,7 @@ private: | |||
| 3345 | std::string assignItem; | 3779 | std::string assignItem; |
| 3346 | if (assignable) { | 3780 | if (assignable) { |
| 3347 | if (!isAssignable(assignable)) { | 3781 | if (!isAssignable(assignable)) { |
| 3348 | throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, assignable)); | 3782 | throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, assignable)); |
| 3349 | } | 3783 | } |
| 3350 | bool newDefined = false; | 3784 | bool newDefined = false; |
| 3351 | std::tie(className, newDefined) = defineClassVariable(assignable); | 3785 | std::tie(className, newDefined) = defineClassVariable(assignable); |
| @@ -3586,7 +4020,7 @@ private: | |||
| 3586 | if (selfName) { | 4020 | if (selfName) { |
| 3587 | type = MemType::Property; | 4021 | type = MemType::Property; |
| 3588 | auto name = ast_cast<self_name_t>(selfName->name); | 4022 | auto name = ast_cast<self_name_t>(selfName->name); |
| 3589 | if (!name) throw std::logic_error(_info.errorMessage("Invalid class poperty name."sv, selfName->name)); | 4023 | if (!name) throw std::logic_error(_info.errorMessage("invalid class poperty name"sv, selfName->name)); |
| 3590 | newSuperCall = classVar + s(".__parent."sv) + _parser.toString(name->name); | 4024 | newSuperCall = classVar + s(".__parent."sv) + _parser.toString(name->name); |
| 3591 | } else { | 4025 | } else { |
| 3592 | auto x = keyName; | 4026 | auto x = keyName; |
| @@ -3897,19 +4331,19 @@ private: | |||
| 3897 | void transformExport(Export_t* exportNode, str_list& out) { | 4331 | void transformExport(Export_t* exportNode, str_list& out) { |
| 3898 | auto x = exportNode; | 4332 | auto x = exportNode; |
| 3899 | if (_scopes.size() > 1) { | 4333 | if (_scopes.size() > 1) { |
| 3900 | throw std::logic_error(_info.errorMessage("Can not do module export outside root block."sv, x)); | 4334 | throw std::logic_error(_info.errorMessage("can not do module export outside root block"sv, x)); |
| 3901 | } | 4335 | } |
| 3902 | if (exportNode->assign) { | 4336 | if (exportNode->assign) { |
| 3903 | auto expList = exportNode->target.to<ExpList_t>(); | 4337 | auto expList = exportNode->target.to<ExpList_t>(); |
| 3904 | if (expList->exprs.size() != exportNode->assign->values.size()) { | 4338 | if (expList->exprs.size() != exportNode->assign->values.size()) { |
| 3905 | throw std::logic_error(_info.errorMessage("Left and right expressions must be matched in export statement."sv, x)); | 4339 | throw std::logic_error(_info.errorMessage("left and right expressions must be matched in export statement"sv, x)); |
| 3906 | } | 4340 | } |
| 3907 | for (auto _exp : expList->exprs.objects()) { | 4341 | for (auto _exp : expList->exprs.objects()) { |
| 3908 | auto exp = static_cast<Exp_t*>(_exp); | 4342 | auto exp = static_cast<Exp_t*>(_exp); |
| 3909 | if (!variableFrom(exp) && | 4343 | if (!variableFrom(exp) && |
| 3910 | !exp->getByPath<Value_t, SimpleValue_t, TableLit_t>() && | 4344 | !exp->getByPath<Value_t, SimpleValue_t, TableLit_t>() && |
| 3911 | !exp->getByPath<Value_t, simple_table_t>()) { | 4345 | !exp->getByPath<Value_t, simple_table_t>()) { |
| 3912 | throw std::logic_error(_info.errorMessage("Left hand expressions must be variables in export statement."sv, x)); | 4346 | throw std::logic_error(_info.errorMessage("left hand expressions must be variables in export statement"sv, x)); |
| 3913 | } | 4347 | } |
| 3914 | } | 4348 | } |
| 3915 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 4349 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| @@ -3935,7 +4369,9 @@ private: | |||
| 3935 | out.back().append(indent() + join(lefts,", "sv) + s(" = "sv) + join(rights, ", "sv) + nlr(exportNode)); | 4369 | out.back().append(indent() + join(lefts,", "sv) + s(" = "sv) + join(rights, ", "sv) + nlr(exportNode)); |
| 3936 | } | 4370 | } |
| 3937 | } else { | 4371 | } else { |
| 3938 | if (_info.exportDefault) { | 4372 | if (auto macro = exportNode->target.as<Macro_t>()) { |
| 4373 | transformMacro(macro, out, true); | ||
| 4374 | } else if (_info.exportDefault) { | ||
| 3939 | auto exp = exportNode->target.to<Exp_t>(); | 4375 | auto exp = exportNode->target.to<Exp_t>(); |
| 3940 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 4376 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| 3941 | assignment->expList.set(toAst<ExpList_t>(_info.moduleName, x)); | 4377 | assignment->expList.set(toAst<ExpList_t>(_info.moduleName, x)); |
| @@ -4218,14 +4654,102 @@ private: | |||
| 4218 | out.push_back(join(temp)); | 4654 | out.push_back(join(temp)); |
| 4219 | } | 4655 | } |
| 4220 | 4656 | ||
| 4657 | std::string moduleNameFrom(ImportLiteral_t* literal) { | ||
| 4658 | auto name = _parser.toString(literal->inners.back()); | ||
| 4659 | Utils::replace(name, "-"sv, "_"sv); | ||
| 4660 | Utils::replace(name, " "sv, "_"sv); | ||
| 4661 | return name; | ||
| 4662 | } | ||
| 4663 | |||
| 4221 | void transformImportAs(ImportAs_t* import, str_list& out) { | 4664 | void transformImportAs(ImportAs_t* import, str_list& out) { |
| 4222 | auto x = import; | 4665 | auto x = import; |
| 4223 | if (!import->target) { | 4666 | if (!import->target) { |
| 4224 | auto name = _parser.toString(import->literal->inners.back()); | 4667 | auto name = moduleNameFrom(import->literal); |
| 4225 | Utils::replace(name, "-"sv, "_"sv); | ||
| 4226 | Utils::replace(name, " "sv, "_"sv); | ||
| 4227 | import->target.set(toAst<Variable_t>(name, x)); | 4668 | import->target.set(toAst<Variable_t>(name, x)); |
| 4228 | } | 4669 | } |
| 4670 | if (auto tableLit = import->target.as<TableLit_t>()) { | ||
| 4671 | auto newTab = x->new_ptr<TableLit_t>(); | ||
| 4672 | std::list<std::pair<std::string,std::string>> macroPairs; | ||
| 4673 | for (auto item : tableLit->values.objects()) { | ||
| 4674 | switch (item->getId()) { | ||
| 4675 | case id<MacroName_t>(): { | ||
| 4676 | auto macroName = static_cast<MacroName_t*>(item); | ||
| 4677 | auto name = _parser.toString(macroName->name); | ||
| 4678 | macroPairs.emplace_back(name, name); | ||
| 4679 | break; | ||
| 4680 | } | ||
| 4681 | case id<macro_name_pair_t>(): { | ||
| 4682 | auto pair = static_cast<macro_name_pair_t*>(item); | ||
| 4683 | macroPairs.emplace_back(_parser.toString(pair->value->name), _parser.toString(pair->key->name)); | ||
| 4684 | break; | ||
| 4685 | } | ||
| 4686 | default: | ||
| 4687 | newTab->values.push_back(item); | ||
| 4688 | break; | ||
| 4689 | } | ||
| 4690 | } | ||
| 4691 | if (!macroPairs.empty()) { | ||
| 4692 | auto moduleName = _parser.toString(import->literal); | ||
| 4693 | Utils::replace(moduleName, "'"sv, ""sv); | ||
| 4694 | Utils::replace(moduleName, "\""sv, ""sv); | ||
| 4695 | Utils::trim(moduleName); | ||
| 4696 | pushCurrentModule(); // cur | ||
| 4697 | int top = lua_gettop(L) - 1; | ||
| 4698 | pushMoonp("find_modulepath"sv); // cur find_modulepath | ||
| 4699 | lua_pushlstring(L, moduleName.c_str(), moduleName.size()); // cur find_modulepath moduleName | ||
| 4700 | if (lua_pcall(L, 1, 1, 0) != 0) { | ||
| 4701 | std::string err = lua_tostring(L, -1); | ||
| 4702 | lua_settop(L, top); | ||
| 4703 | throw std::logic_error(_info.errorMessage(s("fail to resolve module path\n"sv) + err, x)); | ||
| 4704 | } | ||
| 4705 | if (lua_isnil(L, -1) != 0) { | ||
| 4706 | lua_settop(L, top); | ||
| 4707 | throw std::logic_error(_info.errorMessage(s("fail to find module '"sv) + moduleName + '\'', x)); | ||
| 4708 | } | ||
| 4709 | std::string moduleFullName = lua_tostring(L, -1); | ||
| 4710 | lua_pop(L, 1); // cur | ||
| 4711 | if (!isModuleLoaded(moduleFullName)) { | ||
| 4712 | pushMoonp("read_file"sv); // cur read_file | ||
| 4713 | lua_pushlstring(L, moduleFullName.c_str(), moduleFullName.size()); // cur load_text moduleFullName | ||
| 4714 | if (lua_pcall(L, 1, 1, 0) != 0) { | ||
| 4715 | std::string err = lua_tostring(L, -1); | ||
| 4716 | lua_settop(L, top); | ||
| 4717 | throw std::logic_error(_info.errorMessage(s("fail to read module file\n"sv) + err, x)); | ||
| 4718 | } // cur text | ||
| 4719 | if (lua_isnil(L, -1) != 0) { | ||
| 4720 | lua_settop(L, top); | ||
| 4721 | throw std::logic_error(_info.errorMessage("fail to get module text"sv, x)); | ||
| 4722 | } // cur text | ||
| 4723 | std::string text = lua_tostring(L, -1); | ||
| 4724 | auto compiler = MoonCompilerImpl(L, _luaOpen, false, moduleFullName); | ||
| 4725 | MoonConfig config; | ||
| 4726 | config.lineOffset = 0; | ||
| 4727 | config.lintGlobalVariable = false; | ||
| 4728 | config.reserveLineNumber = false; | ||
| 4729 | config.implicitReturnRoot = _config.implicitReturnRoot; | ||
| 4730 | std::string codes, err; | ||
| 4731 | GlobalVars globals; | ||
| 4732 | std::tie(codes, err, globals) = compiler.compile(text, config); | ||
| 4733 | if (codes.empty() && !err.empty()) { | ||
| 4734 | lua_settop(L, top); | ||
| 4735 | throw std::logic_error(_info.errorMessage(s("fail to compile module '"sv) + moduleName + s("\': "sv) + err, x)); | ||
| 4736 | } | ||
| 4737 | lua_pop(L, 1); // cur | ||
| 4738 | } | ||
| 4739 | pushModuleTable(moduleFullName); // cur module | ||
| 4740 | for (const auto& pair : macroPairs) { | ||
| 4741 | lua_getfield(L, -1, pair.first.c_str()); | ||
| 4742 | lua_setfield(L, -3, pair.second.c_str()); | ||
| 4743 | } | ||
| 4744 | lua_settop(L, top); | ||
| 4745 | } | ||
| 4746 | if (newTab->values.empty()) { | ||
| 4747 | out.push_back(Empty); | ||
| 4748 | return; | ||
| 4749 | } else { | ||
| 4750 | import->target.set(newTab); | ||
| 4751 | } | ||
| 4752 | } | ||
| 4229 | auto target = import->target.get(); | 4753 | auto target = import->target.get(); |
| 4230 | auto value = x->new_ptr<Value_t>(); | 4754 | auto value = x->new_ptr<Value_t>(); |
| 4231 | if (auto var = ast_cast<Variable_t>(target)) { | 4755 | if (auto var = ast_cast<Variable_t>(target)) { |
| @@ -4389,6 +4913,7 @@ private: | |||
| 4389 | } | 4913 | } |
| 4390 | 4914 | ||
| 4391 | void transformLocal(Local_t* local, str_list& out) { | 4915 | void transformLocal(Local_t* local, str_list& out) { |
| 4916 | str_list temp; | ||
| 4392 | if (!local->forceDecls.empty() || !local->decls.empty()) { | 4917 | if (!local->forceDecls.empty() || !local->decls.empty()) { |
| 4393 | str_list defs; | 4918 | str_list defs; |
| 4394 | for (const auto& decl : local->forceDecls) { | 4919 | for (const auto& decl : local->forceDecls) { |
| @@ -4402,9 +4927,33 @@ private: | |||
| 4402 | } | 4927 | } |
| 4403 | auto preDefine = getPredefine(defs); | 4928 | auto preDefine = getPredefine(defs); |
| 4404 | if (!preDefine.empty()) { | 4929 | if (!preDefine.empty()) { |
| 4405 | out.push_back(preDefine + nll(local)); | 4930 | temp.push_back(preDefine + nll(local)); |
| 4931 | } | ||
| 4932 | } | ||
| 4933 | if (auto values = local->item.as<local_values_t>()) { | ||
| 4934 | if (values->valueList) { | ||
| 4935 | auto x = local; | ||
| 4936 | auto expList = x->new_ptr<ExpList_t>(); | ||
| 4937 | for (auto name : values->nameList->names.objects()) { | ||
| 4938 | auto callable = x->new_ptr<Callable_t>(); | ||
| 4939 | callable->item.set(name); | ||
| 4940 | auto chainValue = x->new_ptr<ChainValue_t>(); | ||
| 4941 | chainValue->items.push_back(callable); | ||
| 4942 | auto value = x->new_ptr<Value_t>(); | ||
| 4943 | value->item.set(chainValue); | ||
| 4944 | auto exp = x->new_ptr<Exp_t>(); | ||
| 4945 | exp->value.set(value); | ||
| 4946 | expList->exprs.push_back(exp); | ||
| 4947 | } | ||
| 4948 | auto assignment = x->new_ptr<ExpListAssign_t>(); | ||
| 4949 | assignment->expList.set(expList); | ||
| 4950 | auto assign = x->new_ptr<Assign_t>(); | ||
| 4951 | assign->values.dup(values->valueList->exprs); | ||
| 4952 | assignment->action.set(assign); | ||
| 4953 | transformAssignment(assignment, temp); | ||
| 4406 | } | 4954 | } |
| 4407 | } | 4955 | } |
| 4956 | out.push_back(join(temp)); | ||
| 4408 | } | 4957 | } |
| 4409 | 4958 | ||
| 4410 | void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) { | 4959 | void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) { |
| @@ -4413,7 +4962,7 @@ private: | |||
| 4413 | out.push_back(indent() + keyword + nll(breakLoop)); | 4962 | out.push_back(indent() + keyword + nll(breakLoop)); |
| 4414 | return; | 4963 | return; |
| 4415 | } | 4964 | } |
| 4416 | if (_continueVars.empty()) throw std::logic_error(_info.errorMessage("Continue is not inside a loop."sv, breakLoop)); | 4965 | if (_continueVars.empty()) throw std::logic_error(_info.errorMessage("continue is not inside a loop"sv, breakLoop)); |
| 4417 | _buf << indent() << _continueVars.top() << " = true"sv << nll(breakLoop); | 4966 | _buf << indent() << _continueVars.top() << " = true"sv << nll(breakLoop); |
| 4418 | _buf << indent() << "break"sv << nll(breakLoop); | 4967 | _buf << indent() << "break"sv << nll(breakLoop); |
| 4419 | out.push_back(clearBuf()); | 4968 | out.push_back(clearBuf()); |
| @@ -4422,12 +4971,12 @@ private: | |||
| 4422 | 4971 | ||
| 4423 | const std::string MoonCompilerImpl::Empty; | 4972 | const std::string MoonCompilerImpl::Empty; |
| 4424 | 4973 | ||
| 4425 | MoonCompiler::MoonCompiler(): | 4974 | MoonCompiler::MoonCompiler(void* sharedState, |
| 4426 | _compiler(std::make_unique<MoonCompilerImpl>()) | 4975 | const std::function<void(void*)>& luaOpen, |
| 4427 | { } | 4976 | bool sameModule): |
| 4977 | _compiler(std::make_unique<MoonCompilerImpl>(static_cast<lua_State*>(sharedState), luaOpen, sameModule)) {} | ||
| 4428 | 4978 | ||
| 4429 | MoonCompiler::~MoonCompiler() | 4979 | MoonCompiler::~MoonCompiler() {} |
| 4430 | { } | ||
| 4431 | 4980 | ||
| 4432 | std::tuple<std::string,std::string,GlobalVars> MoonCompiler::compile(std::string_view codes, const MoonConfig& config) { | 4981 | std::tuple<std::string,std::string,GlobalVars> MoonCompiler::compile(std::string_view codes, const MoonConfig& config) { |
| 4433 | return _compiler->compile(codes, config); | 4982 | return _compiler->compile(codes, config); |
diff --git a/src/MoonP/moon_compiler.h b/src/MoonP/moon_compiler.h index 36fd77a..573f130 100644 --- a/src/MoonP/moon_compiler.h +++ b/src/MoonP/moon_compiler.h | |||
| @@ -13,6 +13,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
| 13 | #include <tuple> | 13 | #include <tuple> |
| 14 | #include <list> | 14 | #include <list> |
| 15 | #include <memory> | 15 | #include <memory> |
| 16 | #include <functional> | ||
| 16 | 17 | ||
| 17 | namespace MoonP { | 18 | namespace MoonP { |
| 18 | 19 | ||
| @@ -22,6 +23,7 @@ struct MoonConfig { | |||
| 22 | bool lintGlobalVariable = false; | 23 | bool lintGlobalVariable = false; |
| 23 | bool implicitReturnRoot = true; | 24 | bool implicitReturnRoot = true; |
| 24 | bool reserveLineNumber = true; | 25 | bool reserveLineNumber = true; |
| 26 | int lineOffset = 0; | ||
| 25 | }; | 27 | }; |
| 26 | 28 | ||
| 27 | struct GlobalVar { | 29 | struct GlobalVar { |
| @@ -36,7 +38,9 @@ class MoonCompilerImpl; | |||
| 36 | 38 | ||
| 37 | class MoonCompiler { | 39 | class MoonCompiler { |
| 38 | public: | 40 | public: |
| 39 | MoonCompiler(); | 41 | MoonCompiler(void* luaState = nullptr, |
| 42 | const std::function<void(void*)>& luaOpen = nullptr, | ||
| 43 | bool sameModule = false); | ||
| 40 | virtual ~MoonCompiler(); | 44 | virtual ~MoonCompiler(); |
| 41 | std::tuple<std::string,std::string,GlobalVars> compile(std::string_view codes, const MoonConfig& config = {}); | 45 | std::tuple<std::string,std::string,GlobalVars> compile(std::string_view codes, const MoonConfig& config = {}); |
| 42 | private: | 46 | private: |
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index baa8eff..f0269d7 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp | |||
| @@ -28,8 +28,8 @@ std::unordered_set<std::string> Keywords = { | |||
| 28 | "repeat", "return", "then", "true", "until", | 28 | "repeat", "return", "then", "true", "until", |
| 29 | "while", // Lua keywords | 29 | "while", // Lua keywords |
| 30 | "as", "class", "continue", "export", "extends", | 30 | "as", "class", "continue", "export", "extends", |
| 31 | "from", "global", "import", "switch", "unless", | 31 | "from", "global", "import", "macro", "switch", |
| 32 | "using", "when", "with" // Moon keywords | 32 | "unless", "using", "when", "with" // Moon keywords |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | MoonParser::MoonParser() { | 35 | MoonParser::MoonParser() { |
| @@ -98,9 +98,9 @@ MoonParser::MoonParser() { | |||
| 98 | self_class = expr("@@"); | 98 | self_class = expr("@@"); |
| 99 | self_class_name = "@@" >> Name; | 99 | self_class_name = "@@" >> Name; |
| 100 | 100 | ||
| 101 | SelfName = Space >> (self_class_name | self_class | self_name | self); | 101 | SelfName = self_class_name | self_class | self_name | self; |
| 102 | KeyName = SelfName | Space >> Name; | 102 | KeyName = Space >> (SelfName | Name); |
| 103 | VarArg = Space >> "..."; | 103 | VarArg = expr("..."); |
| 104 | 104 | ||
| 105 | check_indent = pl::user(Indent, [](const item_t& item) { | 105 | check_indent = pl::user(Indent, [](const item_t& item) { |
| 106 | int indent = 0; | 106 | int indent = 0; |
| @@ -162,7 +162,8 @@ MoonParser::MoonParser() { | |||
| 162 | InBlock = Advance >> ensure(Block, PopIndent); | 162 | InBlock = Advance >> ensure(Block, PopIndent); |
| 163 | 163 | ||
| 164 | local_flag = expr('*') | expr('^'); | 164 | local_flag = expr('*') | expr('^'); |
| 165 | Local = key("local") >> ((Space >> local_flag) | NameList); | 165 | local_values = NameList >> -(sym('=') >> ExpListLow); |
| 166 | Local = key("local") >> (Space >> local_flag | local_values); | ||
| 166 | 167 | ||
| 167 | colon_import_name = sym('\\') >> Space >> Variable; | 168 | colon_import_name = sym('\\') >> Space >> Variable; |
| 168 | ImportName = colon_import_name | Space >> Variable; | 169 | ImportName = colon_import_name | Space >> Variable; |
| @@ -173,9 +174,23 @@ MoonParser::MoonParser() { | |||
| 173 | ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"'); | 174 | ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"'); |
| 174 | 175 | ||
| 175 | ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp; | 176 | ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp; |
| 176 | ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | TableLit)); | 177 | |
| 178 | EnableMacroPair = pl::user(true_(), [](const item_t& item) { | ||
| 179 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 180 | st->macroPairEnabled = true; | ||
| 181 | return true; | ||
| 182 | }); | ||
| 183 | |||
| 184 | DiableMacroPair = pl::user(true_(), [](const item_t& item) { | ||
| 185 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 186 | st->macroPairEnabled = false; | ||
| 187 | return true; | ||
| 188 | }); | ||
| 189 | |||
| 190 | ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | EnableMacroPair >> ensure(TableLit, DiableMacroPair))); | ||
| 177 | 191 | ||
| 178 | Import = key("import") >> (ImportAs | ImportFrom); | 192 | Import = key("import") >> (ImportAs | ImportFrom); |
| 193 | |||
| 179 | BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); | 194 | BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); |
| 180 | 195 | ||
| 181 | Return = key("return") >> -ExpListLow; | 196 | Return = key("return") >> -ExpListLow; |
| @@ -278,7 +293,7 @@ MoonParser::MoonParser() { | |||
| 278 | 293 | ||
| 279 | BackcallOperator = expr("|>"); | 294 | BackcallOperator = expr("|>"); |
| 280 | 295 | ||
| 281 | Assignable = AssignableChain | Space >> Variable | SelfName; | 296 | Assignable = AssignableChain | Space >> Variable | Space >> SelfName; |
| 282 | 297 | ||
| 283 | exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value; | 298 | exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value; |
| 284 | Exp = Value >> *exp_op_value; | 299 | Exp = Value >> *exp_op_value; |
| @@ -317,8 +332,8 @@ MoonParser::MoonParser() { | |||
| 317 | 332 | ||
| 318 | LuaString = LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose; | 333 | LuaString = LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose; |
| 319 | 334 | ||
| 320 | Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); | 335 | Parens = symx('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); |
| 321 | Callable = Space >> Variable | SelfName | VarArg | Parens; | 336 | Callable = Space >> (Variable | SelfName | MacroName | VarArg | Parens); |
| 322 | FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); | 337 | FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); |
| 323 | 338 | ||
| 324 | FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) | | 339 | FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) | |
| @@ -414,7 +429,8 @@ MoonParser::MoonParser() { | |||
| 414 | } else { | 429 | } else { |
| 415 | return true; | 430 | return true; |
| 416 | } | 431 | } |
| 417 | }) >> ExpList >> -Assign)) >> not_(Space >> statement_appendix); | 432 | }) >> ExpList >> -Assign) |
| 433 | | Macro) >> not_(Space >> statement_appendix); | ||
| 418 | 434 | ||
| 419 | variable_pair = sym(':') >> Variable; | 435 | variable_pair = sym(':') >> Variable; |
| 420 | 436 | ||
| @@ -427,14 +443,19 @@ MoonParser::MoonParser() { | |||
| 427 | symx(':') >> | 443 | symx(':') >> |
| 428 | (Exp | TableBlock | +(SpaceBreak) >> Exp); | 444 | (Exp | TableBlock | +(SpaceBreak) >> Exp); |
| 429 | 445 | ||
| 430 | KeyValue = variable_pair | normal_pair; | 446 | macro_name_pair = Space >> MacroName >> Space >> symx(':') >> Space >> MacroName; |
| 447 | |||
| 448 | KeyValue = variable_pair | normal_pair | pl::user(sym(':') >> MacroName | macro_name_pair, [](const item_t& item) { | ||
| 449 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 450 | return st->macroPairEnabled; | ||
| 451 | }); | ||
| 431 | 452 | ||
| 432 | KeyValueList = KeyValue >> *(sym(',') >> KeyValue); | 453 | KeyValueList = KeyValue >> *(sym(',') >> KeyValue); |
| 433 | KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); | 454 | KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); |
| 434 | 455 | ||
| 435 | FnArgDef = (Space >> Variable | SelfName) >> -(sym('=') >> Exp); | 456 | FnArgDef = (Variable | SelfName) >> -(sym('=') >> Space >> Exp); |
| 436 | 457 | ||
| 437 | FnArgDefList = Seperator >> ( | 458 | FnArgDefList = Space >> Seperator >> ( |
| 438 | ( | 459 | ( |
| 439 | FnArgDef >> | 460 | FnArgDef >> |
| 440 | *((sym(',') | Break) >> White >> FnArgDef) >> | 461 | *((sym(',') | Break) >> White >> FnArgDef) >> |
| @@ -450,6 +471,12 @@ MoonParser::MoonParser() { | |||
| 450 | fn_arrow = expr("->") | expr("=>"); | 471 | fn_arrow = expr("->") | expr("=>"); |
| 451 | FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body; | 472 | FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body; |
| 452 | 473 | ||
| 474 | MacroName = expr('$') >> Name; | ||
| 475 | macro_type = expr("expr") | expr("block"); | ||
| 476 | macro_args_def = sym('(') >> White >> -FnArgDefList >> White >> sym(')'); | ||
| 477 | MacroLit = -macro_args_def >> Space >> expr("->") >> Body; | ||
| 478 | Macro = key("macro") >> Space >> macro_type >> Space >> Name >> sym('=') >> MacroLit; | ||
| 479 | |||
| 453 | NameList = Seperator >> Space >> Variable >> *(sym(',') >> White >> Variable); | 480 | NameList = Seperator >> Space >> Variable >> *(sym(',') >> White >> Variable); |
| 454 | NameOrDestructure = Space >> Variable | TableLit; | 481 | NameOrDestructure = Space >> Variable | TableLit; |
| 455 | AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> White >> NameOrDestructure); | 482 | AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> White >> NameOrDestructure); |
| @@ -499,7 +526,8 @@ MoonParser::MoonParser() { | |||
| 499 | statement_appendix = (if_else_line | unless_line | CompInner) >> Space; | 526 | statement_appendix = (if_else_line | unless_line | CompInner) >> Space; |
| 500 | Statement = ( | 527 | Statement = ( |
| 501 | Import | While | For | ForEach | | 528 | Import | While | For | ForEach | |
| 502 | Return | Local | Global | Export | Space >> BreakLoop | | 529 | Return | Local | Global | Export | |
| 530 | Macro | Space >> BreakLoop | | ||
| 503 | Backcall | ExpListAssign | 531 | Backcall | ExpListAssign |
| 504 | ) >> Space >> | 532 | ) >> Space >> |
| 505 | -statement_appendix; | 533 | -statement_appendix; |
| @@ -541,10 +569,10 @@ ParseInfo MoonParser::parse(std::string_view codes, rule& r) { | |||
| 541 | const error& err = *it; | 569 | const error& err = *it; |
| 542 | switch (err.m_type) { | 570 | switch (err.m_type) { |
| 543 | case ERROR_TYPE::ERROR_SYNTAX_ERROR: | 571 | case ERROR_TYPE::ERROR_SYNTAX_ERROR: |
| 544 | buf << res.errorMessage("Syntax error."sv, &err); | 572 | buf << res.errorMessage("syntax error"sv, &err); |
| 545 | break; | 573 | break; |
| 546 | case ERROR_TYPE::ERROR_INVALID_EOF: | 574 | case ERROR_TYPE::ERROR_INVALID_EOF: |
| 547 | buf << res.errorMessage("Invalid EOF."sv, &err); | 575 | buf << res.errorMessage("invalid EOF"sv, &err); |
| 548 | break; | 576 | break; |
| 549 | } | 577 | } |
| 550 | } | 578 | } |
| @@ -577,6 +605,12 @@ namespace Utils { | |||
| 577 | start_pos += to.size(); | 605 | start_pos += to.size(); |
| 578 | } | 606 | } |
| 579 | } | 607 | } |
| 608 | |||
| 609 | void trim(std::string& str) { | ||
| 610 | if (str.empty()) return; | ||
| 611 | str.erase(0, str.find_first_not_of(" \t")); | ||
| 612 | str.erase(str.find_last_not_of(" \t") + 1); | ||
| 613 | } | ||
| 580 | } | 614 | } |
| 581 | 615 | ||
| 582 | std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc) const { | 616 | std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc) const { |
diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h index eefcba5..4d67696 100644 --- a/src/MoonP/moon_parser.h +++ b/src/MoonP/moon_parser.h | |||
| @@ -12,7 +12,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
| 12 | #include <unordered_set> | 12 | #include <unordered_set> |
| 13 | #include <stack> | 13 | #include <stack> |
| 14 | #include <algorithm> | 14 | #include <algorithm> |
| 15 | #include <vector> | 15 | #include <list> |
| 16 | #include <sstream> | 16 | #include <sstream> |
| 17 | #include <string_view> | 17 | #include <string_view> |
| 18 | 18 | ||
| @@ -75,6 +75,7 @@ protected: | |||
| 75 | State() { | 75 | State() { |
| 76 | indents.push(0); | 76 | indents.push(0); |
| 77 | } | 77 | } |
| 78 | bool macroPairEnabled = false; | ||
| 78 | bool exportDefault = false; | 79 | bool exportDefault = false; |
| 79 | int exportCount = 0; | 80 | int exportCount = 0; |
| 80 | int moduleFix = 0; | 81 | int moduleFix = 0; |
| @@ -131,6 +132,8 @@ private: | |||
| 131 | rule WithExp; | 132 | rule WithExp; |
| 132 | rule DisableDo; | 133 | rule DisableDo; |
| 133 | rule PopDo; | 134 | rule PopDo; |
| 135 | rule EnableMacroPair; | ||
| 136 | rule DiableMacroPair; | ||
| 134 | rule SwitchElse; | 137 | rule SwitchElse; |
| 135 | rule SwitchBlock; | 138 | rule SwitchBlock; |
| 136 | rule IfElseIf; | 139 | rule IfElseIf; |
| @@ -147,6 +150,7 @@ private: | |||
| 147 | rule lua_string_close; | 150 | rule lua_string_close; |
| 148 | rule FnArgsExpList; | 151 | rule FnArgsExpList; |
| 149 | rule FnArgs; | 152 | rule FnArgs; |
| 153 | rule macro_args_def; | ||
| 150 | rule chain_call; | 154 | rule chain_call; |
| 151 | rule chain_item; | 155 | rule chain_item; |
| 152 | rule ChainItems; | 156 | rule ChainItems; |
| @@ -189,6 +193,7 @@ private: | |||
| 189 | AST_RULE(Seperator) | 193 | AST_RULE(Seperator) |
| 190 | AST_RULE(NameList) | 194 | AST_RULE(NameList) |
| 191 | AST_RULE(local_flag) | 195 | AST_RULE(local_flag) |
| 196 | AST_RULE(local_values) | ||
| 192 | AST_RULE(Local) | 197 | AST_RULE(Local) |
| 193 | AST_RULE(colon_import_name) | 198 | AST_RULE(colon_import_name) |
| 194 | AST_RULE(import_literal_inner) | 199 | AST_RULE(import_literal_inner) |
| @@ -261,12 +266,17 @@ private: | |||
| 261 | AST_RULE(Export) | 266 | AST_RULE(Export) |
| 262 | AST_RULE(variable_pair) | 267 | AST_RULE(variable_pair) |
| 263 | AST_RULE(normal_pair) | 268 | AST_RULE(normal_pair) |
| 269 | AST_RULE(macro_name_pair) | ||
| 264 | AST_RULE(FnArgDef) | 270 | AST_RULE(FnArgDef) |
| 265 | AST_RULE(FnArgDefList) | 271 | AST_RULE(FnArgDefList) |
| 266 | AST_RULE(outer_var_shadow) | 272 | AST_RULE(outer_var_shadow) |
| 267 | AST_RULE(FnArgsDef) | 273 | AST_RULE(FnArgsDef) |
| 268 | AST_RULE(fn_arrow) | 274 | AST_RULE(fn_arrow) |
| 269 | AST_RULE(FunLit) | 275 | AST_RULE(FunLit) |
| 276 | AST_RULE(macro_type) | ||
| 277 | AST_RULE(MacroName) | ||
| 278 | AST_RULE(MacroLit) | ||
| 279 | AST_RULE(Macro) | ||
| 270 | AST_RULE(NameOrDestructure) | 280 | AST_RULE(NameOrDestructure) |
| 271 | AST_RULE(AssignableNameList) | 281 | AST_RULE(AssignableNameList) |
| 272 | AST_RULE(InvokeArgs) | 282 | AST_RULE(InvokeArgs) |
| @@ -285,6 +295,7 @@ private: | |||
| 285 | 295 | ||
| 286 | namespace Utils { | 296 | namespace Utils { |
| 287 | void replace(std::string& str, std::string_view from, std::string_view to); | 297 | void replace(std::string& str, std::string_view from, std::string_view to); |
| 298 | void trim(std::string& str); | ||
| 288 | }; | 299 | }; |
| 289 | 300 | ||
| 290 | } // namespace MoonP | 301 | } // namespace MoonP |
