diff options
Diffstat (limited to '')
| -rw-r--r-- | spec/inputs/import.yue | 2 | ||||
| -rw-r--r-- | spec/inputs/unicode/import.yue | 2 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.cpp | 11 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.h | 37 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 181 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 109 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.h | 14 |
7 files changed, 213 insertions, 143 deletions
diff --git a/spec/inputs/import.yue b/spec/inputs/import.yue index 8982e6c..ee1fdfc 100644 --- a/spec/inputs/import.yue +++ b/spec/inputs/import.yue | |||
| @@ -23,7 +23,7 @@ do | |||
| 23 | b, c from z | 23 | b, c from z |
| 24 | 24 | ||
| 25 | do | 25 | do |
| 26 | import a | 26 | import a, |
| 27 | b | 27 | b |
| 28 | c from z | 28 | c from z |
| 29 | 29 | ||
diff --git a/spec/inputs/unicode/import.yue b/spec/inputs/unicode/import.yue index c229edb..a7724ab 100644 --- a/spec/inputs/unicode/import.yue +++ b/spec/inputs/unicode/import.yue | |||
| @@ -23,7 +23,7 @@ do | |||
| 23 | 字段b, 字段c from 对象z | 23 | 字段b, 字段c from 对象z |
| 24 | 24 | ||
| 25 | do | 25 | do |
| 26 | import 字段a | 26 | import 字段a, |
| 27 | 字段b | 27 | 字段b |
| 28 | 字段c from 对象z | 28 | 字段c from 对象z |
| 29 | 29 | ||
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index a2e3403..be0ec45 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp | |||
| @@ -594,7 +594,7 @@ std::string Repeat_t::to_string(void* ud) const { | |||
| 594 | std::string ForStepValue_t::to_string(void* ud) const { | 594 | std::string ForStepValue_t::to_string(void* ud) const { |
| 595 | return value->to_string(ud); | 595 | return value->to_string(ud); |
| 596 | } | 596 | } |
| 597 | std::string For_t::to_string(void* ud) const { | 597 | std::string ForNum_t::to_string(void* ud) const { |
| 598 | auto info = reinterpret_cast<YueFormat*>(ud); | 598 | auto info = reinterpret_cast<YueFormat*>(ud); |
| 599 | auto line = "for "s + varName->to_string(ud) + " = "s + startValue->to_string(ud) + ", "s + stopValue->to_string(ud); | 599 | auto line = "for "s + varName->to_string(ud) + " = "s + startValue->to_string(ud) + ", "s + stopValue->to_string(ud); |
| 600 | if (stepValue) { | 600 | if (stepValue) { |
| @@ -633,6 +633,9 @@ std::string ForEach_t::to_string(void* ud) const { | |||
| 633 | return line + '\n' + block; | 633 | return line + '\n' + block; |
| 634 | } | 634 | } |
| 635 | } | 635 | } |
| 636 | std::string For_t::to_string(void* ud) const { | ||
| 637 | return forLoop->to_string(ud); | ||
| 638 | } | ||
| 636 | std::string Do_t::to_string(void* ud) const { | 639 | std::string Do_t::to_string(void* ud) const { |
| 637 | auto info = reinterpret_cast<YueFormat*>(ud); | 640 | auto info = reinterpret_cast<YueFormat*>(ud); |
| 638 | if (body->content.is<Statement_t>()) { | 641 | if (body->content.is<Statement_t>()) { |
| @@ -784,7 +787,7 @@ static bool isInBlockExp(ast_node* node, bool last = false) { | |||
| 784 | return false; | 787 | return false; |
| 785 | } | 788 | } |
| 786 | std::string Comprehension_t::to_string(void* ud) const { | 789 | std::string Comprehension_t::to_string(void* ud) const { |
| 787 | if (items.size() != 2 || !ast_is<CompInner_t>(items.back())) { | 790 | if (items.size() != 2 || !ast_is<CompFor_t>(items.back())) { |
| 788 | if (items.size() == 1) { | 791 | if (items.size() == 1) { |
| 789 | str_list temp; | 792 | str_list temp; |
| 790 | for (const auto& item : items.objects()) { | 793 | for (const auto& item : items.objects()) { |
| @@ -851,14 +854,14 @@ std::string StarExp_t::to_string(void* ud) const { | |||
| 851 | std::string CompForEach_t::to_string(void* ud) const { | 854 | std::string CompForEach_t::to_string(void* ud) const { |
| 852 | return "for "s + nameList->to_string(ud) + " in "s + loopValue->to_string(ud); | 855 | return "for "s + nameList->to_string(ud) + " in "s + loopValue->to_string(ud); |
| 853 | } | 856 | } |
| 854 | std::string CompFor_t::to_string(void* ud) const { | 857 | std::string CompForNum_t::to_string(void* ud) const { |
| 855 | auto line = "for "s + varName->to_string(ud) + " = "s + startValue->to_string(ud) + ", "s + stopValue->to_string(ud); | 858 | auto line = "for "s + varName->to_string(ud) + " = "s + startValue->to_string(ud) + ", "s + stopValue->to_string(ud); |
| 856 | if (stepValue) { | 859 | if (stepValue) { |
| 857 | line += stepValue->to_string(ud); | 860 | line += stepValue->to_string(ud); |
| 858 | } | 861 | } |
| 859 | return line; | 862 | return line; |
| 860 | } | 863 | } |
| 861 | std::string CompInner_t::to_string(void* ud) const { | 864 | std::string CompFor_t::to_string(void* ud) const { |
| 862 | str_list temp; | 865 | str_list temp; |
| 863 | for (auto item : items.objects()) { | 866 | for (auto item : items.objects()) { |
| 864 | if (ast_is<Exp_t>(item)) { | 867 | if (ast_is<Exp_t>(item)) { |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 97901ec..b7cd73e 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
| @@ -68,7 +68,7 @@ class Statement_t; | |||
| 68 | class Body_t; | 68 | class Body_t; |
| 69 | class AssignableNameList_t; | 69 | class AssignableNameList_t; |
| 70 | class StarExp_t; | 70 | class StarExp_t; |
| 71 | class CompInner_t; | 71 | class CompFor_t; |
| 72 | class AssignableChain_t; | 72 | class AssignableChain_t; |
| 73 | class UnaryExp_t; | 73 | class UnaryExp_t; |
| 74 | class Parens_t; | 74 | class Parens_t; |
| @@ -358,14 +358,14 @@ AST_NODE(ForStepValue) | |||
| 358 | AST_MEMBER(ForStepValue, &value) | 358 | AST_MEMBER(ForStepValue, &value) |
| 359 | AST_END(ForStepValue) | 359 | AST_END(ForStepValue) |
| 360 | 360 | ||
| 361 | AST_NODE(For) | 361 | AST_NODE(ForNum) |
| 362 | ast_ptr<true, Variable_t> varName; | 362 | ast_ptr<true, Variable_t> varName; |
| 363 | ast_ptr<true, Exp_t> startValue; | 363 | ast_ptr<true, Exp_t> startValue; |
| 364 | ast_ptr<true, Exp_t> stopValue; | 364 | ast_ptr<true, Exp_t> stopValue; |
| 365 | ast_ptr<false, ForStepValue_t> stepValue; | 365 | ast_ptr<false, ForStepValue_t> stepValue; |
| 366 | ast_sel<true, Block_t, Statement_t> body; | 366 | ast_sel<true, Block_t, Statement_t> body; |
| 367 | AST_MEMBER(For, &varName, &startValue, &stopValue, &stepValue, &body) | 367 | AST_MEMBER(ForNum, &varName, &startValue, &stopValue, &stepValue, &body) |
| 368 | AST_END(For) | 368 | AST_END(ForNum) |
| 369 | 369 | ||
| 370 | AST_NODE(ForEach) | 370 | AST_NODE(ForEach) |
| 371 | ast_ptr<true, AssignableNameList_t> nameList; | 371 | ast_ptr<true, AssignableNameList_t> nameList; |
| @@ -374,6 +374,11 @@ AST_NODE(ForEach) | |||
| 374 | AST_MEMBER(ForEach, &nameList, &loopValue, &body) | 374 | AST_MEMBER(ForEach, &nameList, &loopValue, &body) |
| 375 | AST_END(ForEach) | 375 | AST_END(ForEach) |
| 376 | 376 | ||
| 377 | AST_NODE(For) | ||
| 378 | ast_sel<true, ForEach_t, ForNum_t> forLoop; | ||
| 379 | AST_MEMBER(For, &forLoop) | ||
| 380 | AST_END(For) | ||
| 381 | |||
| 377 | AST_NODE(Do) | 382 | AST_NODE(Do) |
| 378 | ast_ptr<true, Body_t> body; | 383 | ast_ptr<true, Body_t> body; |
| 379 | AST_MEMBER(Do, &body) | 384 | AST_MEMBER(Do, &body) |
| @@ -394,7 +399,7 @@ AST_END(Try) | |||
| 394 | 399 | ||
| 395 | AST_NODE(Comprehension) | 400 | AST_NODE(Comprehension) |
| 396 | ast_ptr<true, Seperator_t> sep; | 401 | ast_ptr<true, Seperator_t> sep; |
| 397 | ast_sel_list<false, NormalDef_t, SpreadListExp_t, CompInner_t, | 402 | ast_sel_list<false, NormalDef_t, SpreadListExp_t, CompFor_t, |
| 398 | /*non-syntax-rule*/ Statement_t> items; | 403 | /*non-syntax-rule*/ Statement_t> items; |
| 399 | AST_MEMBER(Comprehension, &sep, &items) | 404 | AST_MEMBER(Comprehension, &sep, &items) |
| 400 | AST_END(Comprehension) | 405 | AST_END(Comprehension) |
| @@ -407,7 +412,7 @@ AST_END(CompValue) | |||
| 407 | AST_NODE(TblComprehension) | 412 | AST_NODE(TblComprehension) |
| 408 | ast_ptr<true, Exp_t> key; | 413 | ast_ptr<true, Exp_t> key; |
| 409 | ast_ptr<false, CompValue_t> value; | 414 | ast_ptr<false, CompValue_t> value; |
| 410 | ast_ptr<true, CompInner_t> forLoop; | 415 | ast_ptr<true, CompFor_t> forLoop; |
| 411 | AST_MEMBER(TblComprehension, &key, &value, &forLoop) | 416 | AST_MEMBER(TblComprehension, &key, &value, &forLoop) |
| 412 | AST_END(TblComprehension) | 417 | AST_END(TblComprehension) |
| 413 | 418 | ||
| @@ -422,19 +427,19 @@ AST_NODE(CompForEach) | |||
| 422 | AST_MEMBER(CompForEach, &nameList, &loopValue) | 427 | AST_MEMBER(CompForEach, &nameList, &loopValue) |
| 423 | AST_END(CompForEach) | 428 | AST_END(CompForEach) |
| 424 | 429 | ||
| 425 | AST_NODE(CompFor) | 430 | AST_NODE(CompForNum) |
| 426 | ast_ptr<true, Variable_t> varName; | 431 | ast_ptr<true, Variable_t> varName; |
| 427 | ast_ptr<true, Exp_t> startValue; | 432 | ast_ptr<true, Exp_t> startValue; |
| 428 | ast_ptr<true, Exp_t> stopValue; | 433 | ast_ptr<true, Exp_t> stopValue; |
| 429 | ast_ptr<false, ForStepValue_t> stepValue; | 434 | ast_ptr<false, ForStepValue_t> stepValue; |
| 430 | AST_MEMBER(CompFor, &varName, &startValue, &stopValue, &stepValue) | 435 | AST_MEMBER(CompForNum, &varName, &startValue, &stopValue, &stepValue) |
| 431 | AST_END(CompFor) | 436 | AST_END(CompForNum) |
| 432 | 437 | ||
| 433 | AST_NODE(CompInner) | 438 | AST_NODE(CompFor) |
| 434 | ast_ptr<true, Seperator_t> sep; | 439 | ast_ptr<true, Seperator_t> sep; |
| 435 | ast_sel_list<true, CompFor_t, CompForEach_t, Exp_t> items; | 440 | ast_sel_list<true, CompForNum_t, CompForEach_t, Exp_t> items; |
| 436 | AST_MEMBER(CompInner, &sep, &items) | 441 | AST_MEMBER(CompFor, &sep, &items) |
| 437 | AST_END(CompInner) | 442 | AST_END(CompFor) |
| 438 | 443 | ||
| 439 | AST_NODE(Assign) | 444 | AST_NODE(Assign) |
| 440 | ast_ptr<true, Seperator_t> sep; | 445 | ast_ptr<true, Seperator_t> sep; |
| @@ -553,7 +558,7 @@ AST_NODE(SimpleValue) | |||
| 553 | ast_sel<true, | 558 | ast_sel<true, |
| 554 | TableLit_t, ConstValue_t, | 559 | TableLit_t, ConstValue_t, |
| 555 | If_t, Switch_t, With_t, ClassDecl_t, | 560 | If_t, Switch_t, With_t, ClassDecl_t, |
| 556 | ForEach_t, For_t, While_t, Repeat_t, | 561 | For_t, While_t, Repeat_t, |
| 557 | Do_t, Try_t, UnaryValue_t, | 562 | Do_t, Try_t, UnaryValue_t, |
| 558 | TblComprehension_t, Comprehension_t, | 563 | TblComprehension_t, Comprehension_t, |
| 559 | FunLit_t, Num_t, VarArg_t> value; | 564 | FunLit_t, Num_t, VarArg_t> value; |
| @@ -919,7 +924,7 @@ AST_NODE(PipeBody) | |||
| 919 | AST_END(PipeBody) | 924 | AST_END(PipeBody) |
| 920 | 925 | ||
| 921 | AST_NODE(StatementAppendix) | 926 | AST_NODE(StatementAppendix) |
| 922 | ast_sel<true, IfLine_t, WhileLine_t, CompInner_t> item; | 927 | ast_sel<true, IfLine_t, WhileLine_t, CompFor_t> item; |
| 923 | AST_MEMBER(StatementAppendix, &item) | 928 | AST_MEMBER(StatementAppendix, &item) |
| 924 | AST_END(StatementAppendix) | 929 | AST_END(StatementAppendix) |
| 925 | 930 | ||
| @@ -949,7 +954,7 @@ AST_END(ChainAssign) | |||
| 949 | 954 | ||
| 950 | AST_NODE(Statement) | 955 | AST_NODE(Statement) |
| 951 | ast_sel<true, | 956 | ast_sel<true, |
| 952 | Import_t, While_t, Repeat_t, For_t, ForEach_t, | 957 | Import_t, While_t, Repeat_t, For_t, |
| 953 | Return_t, Local_t, Global_t, Export_t, Macro_t, MacroInPlace_t, | 958 | Return_t, Local_t, Global_t, Export_t, Macro_t, MacroInPlace_t, |
| 954 | BreakLoop_t, Label_t, Goto_t, ShortTabAppending_t, | 959 | BreakLoop_t, Label_t, Goto_t, ShortTabAppending_t, |
| 955 | Backcall_t, LocalAttrib_t, PipeBody_t, ExpListAssign_t, ChainAssign_t | 960 | Backcall_t, LocalAttrib_t, PipeBody_t, ExpListAssign_t, ChainAssign_t |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index bc5215c..753ba7b 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
| 78 | "close"s // Lua 5.4 | 78 | "close"s // Lua 5.4 |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | const std::string_view version = "0.30.2"sv; | 81 | const std::string_view version = "0.30.3"sv; |
| 82 | const std::string_view extension = "yue"sv; | 82 | const std::string_view extension = "yue"sv; |
| 83 | 83 | ||
| 84 | class CompileError : public std::logic_error { | 84 | class CompileError : public std::logic_error { |
| @@ -1474,7 +1474,7 @@ private: | |||
| 1474 | if (simpleValue->value.is<TableLit_t>()) { | 1474 | if (simpleValue->value.is<TableLit_t>()) { |
| 1475 | return true; | 1475 | return true; |
| 1476 | } else if (auto comp = simpleValue->value.as<Comprehension_t>()) { | 1476 | } else if (auto comp = simpleValue->value.as<Comprehension_t>()) { |
| 1477 | if (comp->items.size() != 2 || !ast_is<CompInner_t>(comp->items.back())) { | 1477 | if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) { |
| 1478 | return true; | 1478 | return true; |
| 1479 | } | 1479 | } |
| 1480 | } | 1480 | } |
| @@ -1745,7 +1745,7 @@ private: | |||
| 1745 | throw CompileError("while-loop line decorator is not supported here"sv, appendix->item.get()); | 1745 | throw CompileError("while-loop line decorator is not supported here"sv, appendix->item.get()); |
| 1746 | break; | 1746 | break; |
| 1747 | } | 1747 | } |
| 1748 | case id<CompInner_t>(): { | 1748 | case id<CompFor_t>(): { |
| 1749 | throw CompileError("for-loop line decorator is not supported here"sv, appendix->item.get()); | 1749 | throw CompileError("for-loop line decorator is not supported here"sv, appendix->item.get()); |
| 1750 | break; | 1750 | break; |
| 1751 | } | 1751 | } |
| @@ -1806,8 +1806,8 @@ private: | |||
| 1806 | statement->content.set(expListAssign); | 1806 | statement->content.set(expListAssign); |
| 1807 | break; | 1807 | break; |
| 1808 | } | 1808 | } |
| 1809 | case id<CompInner_t>(): { | 1809 | case id<CompFor_t>(): { |
| 1810 | auto compInner = appendix->item.to<CompInner_t>(); | 1810 | auto compInner = appendix->item.to<CompFor_t>(); |
| 1811 | auto comp = x->new_ptr<Comprehension_t>(); | 1811 | auto comp = x->new_ptr<Comprehension_t>(); |
| 1812 | auto stmt = x->new_ptr<Statement_t>(); | 1812 | auto stmt = x->new_ptr<Statement_t>(); |
| 1813 | stmt->content.set(statement->content); | 1813 | stmt->content.set(statement->content); |
| @@ -1877,7 +1877,7 @@ private: | |||
| 1877 | case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Common); break; | 1877 | case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Common); break; |
| 1878 | case id<Comprehension_t>(): { | 1878 | case id<Comprehension_t>(): { |
| 1879 | auto comp = static_cast<Comprehension_t*>(value); | 1879 | auto comp = static_cast<Comprehension_t*>(value); |
| 1880 | if (comp->items.size() == 2 && ast_is<CompInner_t>(comp->items.back())) { | 1880 | if (comp->items.size() == 2 && ast_is<CompFor_t>(comp->items.back())) { |
| 1881 | transformCompCommon(comp, out); | 1881 | transformCompCommon(comp, out); |
| 1882 | } else { | 1882 | } else { |
| 1883 | specialSingleValue = false; | 1883 | specialSingleValue = false; |
| @@ -2346,7 +2346,7 @@ private: | |||
| 2346 | auto elmVar = getUnusedName("_elm_"sv); | 2346 | auto elmVar = getUnusedName("_elm_"sv); |
| 2347 | _buf << varName << '[' << lenVar << "],"s << lenVar << "="s << elmVar << ',' << lenVar << "+1 for "s << elmVar << " in *nil"s; | 2347 | _buf << varName << '[' << lenVar << "],"s << lenVar << "="s << elmVar << ',' << lenVar << "+1 for "s << elmVar << " in *nil"s; |
| 2348 | auto stmt = toAst<Statement_t>(clearBuf(), spread); | 2348 | auto stmt = toAst<Statement_t>(clearBuf(), spread); |
| 2349 | auto comp = stmt->appendix->item.to<CompInner_t>(); | 2349 | auto comp = stmt->appendix->item.to<CompFor_t>(); |
| 2350 | ast_to<CompForEach_t>(comp->items.front())->loopValue.to<StarExp_t>()->value.set(spread->exp); | 2350 | ast_to<CompForEach_t>(comp->items.front())->loopValue.to<StarExp_t>()->value.set(spread->exp); |
| 2351 | transformStatement(stmt, temp); | 2351 | transformStatement(stmt, temp); |
| 2352 | } else { | 2352 | } else { |
| @@ -2468,7 +2468,7 @@ private: | |||
| 2468 | case id<Comprehension_t>(): { | 2468 | case id<Comprehension_t>(): { |
| 2469 | auto comp = static_cast<Comprehension_t*>(value); | 2469 | auto comp = static_cast<Comprehension_t*>(value); |
| 2470 | auto expList = assignment->expList.get(); | 2470 | auto expList = assignment->expList.get(); |
| 2471 | if (comp->items.size() == 2 && ast_is<CompInner_t>(comp->items.back())) { | 2471 | if (comp->items.size() == 2 && ast_is<CompFor_t>(comp->items.back())) { |
| 2472 | std::string preDefine = getPreDefineLine(assignment); | 2472 | std::string preDefine = getPreDefineLine(assignment); |
| 2473 | transformComprehension(comp, out, ExpUsage::Assignment, expList); | 2473 | transformComprehension(comp, out, ExpUsage::Assignment, expList); |
| 2474 | out.back().insert(0, preDefine); | 2474 | out.back().insert(0, preDefine); |
| @@ -2893,7 +2893,7 @@ private: | |||
| 2893 | if (auto tbA = item->get_by_path<TableLit_t>()) { | 2893 | if (auto tbA = item->get_by_path<TableLit_t>()) { |
| 2894 | tableItems = &tbA->values.objects(); | 2894 | tableItems = &tbA->values.objects(); |
| 2895 | } else if (auto tbB = item->get_by_path<Comprehension_t>()) { | 2895 | } else if (auto tbB = item->get_by_path<Comprehension_t>()) { |
| 2896 | if (tbB->items.size() == 2 && ast_is<CompInner_t>(tbB->items.back())) { | 2896 | if (tbB->items.size() == 2 && ast_is<CompFor_t>(tbB->items.back())) { |
| 2897 | throw CompileError("invalid destructure value"sv, tbB); | 2897 | throw CompileError("invalid destructure value"sv, tbB); |
| 2898 | } | 2898 | } |
| 2899 | tableItems = &tbB->items.objects(); | 2899 | tableItems = &tbB->items.objects(); |
| @@ -2924,7 +2924,7 @@ private: | |||
| 2924 | } | 2924 | } |
| 2925 | case id<Comprehension_t>(): { | 2925 | case id<Comprehension_t>(): { |
| 2926 | auto table = static_cast<Comprehension_t*>(node); | 2926 | auto table = static_cast<Comprehension_t*>(node); |
| 2927 | if (table->items.size() == 2 && ast_is<CompInner_t>(table->items.back())) { | 2927 | if (table->items.size() == 2 && ast_is<CompFor_t>(table->items.back())) { |
| 2928 | throw CompileError("invalid destructure value"sv, table); | 2928 | throw CompileError("invalid destructure value"sv, table); |
| 2929 | } | 2929 | } |
| 2930 | tableItems = &table->items.objects(); | 2930 | tableItems = &table->items.objects(); |
| @@ -3295,7 +3295,7 @@ private: | |||
| 3295 | if (auto tab = sVal->value.as<TableLit_t>()) { | 3295 | if (auto tab = sVal->value.as<TableLit_t>()) { |
| 3296 | destructNode = tab; | 3296 | destructNode = tab; |
| 3297 | } else if (auto comp = sVal->value.as<Comprehension_t>()) { | 3297 | } else if (auto comp = sVal->value.as<Comprehension_t>()) { |
| 3298 | if (comp->items.size() != 2 || !ast_is<CompInner_t>(comp->items.back())) { | 3298 | if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) { |
| 3299 | destructNode = comp; | 3299 | destructNode = comp; |
| 3300 | } | 3300 | } |
| 3301 | } | 3301 | } |
| @@ -4918,7 +4918,7 @@ private: | |||
| 4918 | throw CompileError("while-loop line decorator is not supported here"sv, appendix->item.get()); | 4918 | throw CompileError("while-loop line decorator is not supported here"sv, appendix->item.get()); |
| 4919 | break; | 4919 | break; |
| 4920 | } | 4920 | } |
| 4921 | case id<CompInner_t>(): { | 4921 | case id<CompFor_t>(): { |
| 4922 | throw CompileError("for-loop line decorator is not supported here"sv, appendix->item.get()); | 4922 | throw CompileError("for-loop line decorator is not supported here"sv, appendix->item.get()); |
| 4923 | break; | 4923 | break; |
| 4924 | } | 4924 | } |
| @@ -5259,7 +5259,7 @@ private: | |||
| 5259 | break; | 5259 | break; |
| 5260 | } | 5260 | } |
| 5261 | } | 5261 | } |
| 5262 | bool lastAssignable = (expListFrom(last) || ast_is<For_t, ForEach_t, While_t>(last->content)); | 5262 | bool lastAssignable = (expListFrom(last) || ast_is<For_t, While_t>(last->content)); |
| 5263 | if (lastAssignable) { | 5263 | if (lastAssignable) { |
| 5264 | auto x = last; | 5264 | auto x = last; |
| 5265 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | 5265 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); |
| @@ -5704,10 +5704,7 @@ private: | |||
| 5704 | transformRepeatInPlace(static_cast<Repeat_t*>(value), out); | 5704 | transformRepeatInPlace(static_cast<Repeat_t*>(value), out); |
| 5705 | return; | 5705 | return; |
| 5706 | case id<For_t>(): | 5706 | case id<For_t>(): |
| 5707 | transformForInPlace(static_cast<For_t*>(value), out); | 5707 | transformForInPlace(static_cast<For_t*>(value), out, nullptr); |
| 5708 | return; | ||
| 5709 | case id<ForEach_t>(): | ||
| 5710 | transformForEachInPlace(static_cast<ForEach_t*>(value), out); | ||
| 5711 | return; | 5708 | return; |
| 5712 | case id<If_t>(): | 5709 | case id<If_t>(): |
| 5713 | transformIf(static_cast<If_t*>(value), out, ExpUsage::Return); | 5710 | transformIf(static_cast<If_t*>(value), out, ExpUsage::Return); |
| @@ -7425,7 +7422,7 @@ private: | |||
| 7425 | } | 7422 | } |
| 7426 | } | 7423 | } |
| 7427 | } else if (auto comp = sval->value.as<Comprehension_t>()) { | 7424 | } else if (auto comp = sval->value.as<Comprehension_t>()) { |
| 7428 | if (comp->items.size() != 2 || !ast_is<CompInner_t>(comp->items.back())) { | 7425 | if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) { |
| 7429 | discrete = inExp->new_ptr<ExpList_t>(); | 7426 | discrete = inExp->new_ptr<ExpList_t>(); |
| 7430 | for (ast_node* val : comp->items.objects()) { | 7427 | for (ast_node* val : comp->items.objects()) { |
| 7431 | if (auto def = ast_cast<NormalDef_t>(val)) { | 7428 | if (auto def = ast_cast<NormalDef_t>(val)) { |
| @@ -7844,8 +7841,8 @@ private: | |||
| 7844 | << "\n\t\t"sv << tableVar << "[]="sv << valueVar | 7841 | << "\n\t\t"sv << tableVar << "[]="sv << valueVar |
| 7845 | << "\n\t\t"sv << indexVar << "+=1"sv | 7842 | << "\n\t\t"sv << indexVar << "+=1"sv |
| 7846 | << "\n\telse "sv << tableVar << '[' << keyVar << "]="sv << valueVar; | 7843 | << "\n\telse "sv << tableVar << '[' << keyVar << "]="sv << valueVar; |
| 7847 | auto forEach = toAst<ForEach_t>(clearBuf(), item); | 7844 | auto forNode = toAst<For_t>(clearBuf(), item); |
| 7848 | transformForEach(forEach, temp); | 7845 | transformFor(forNode, temp); |
| 7849 | break; | 7846 | break; |
| 7850 | } | 7847 | } |
| 7851 | case id<SpreadListExp_t>(): { | 7848 | case id<SpreadListExp_t>(): { |
| @@ -7866,8 +7863,8 @@ private: | |||
| 7866 | _buf << "for "sv << valueVar << " in *"sv << objVar | 7863 | _buf << "for "sv << valueVar << " in *"sv << objVar |
| 7867 | << "\n\t"sv << tableVar << '[' << indexVar << "]="sv << valueVar | 7864 | << "\n\t"sv << tableVar << '[' << indexVar << "]="sv << valueVar |
| 7868 | << "\n\t"sv << indexVar << "+=1"sv; | 7865 | << "\n\t"sv << indexVar << "+=1"sv; |
| 7869 | auto forEach = toAst<ForEach_t>(clearBuf(), item); | 7866 | auto forNode = toAst<For_t>(clearBuf(), item); |
| 7870 | transformForEach(forEach, temp); | 7867 | transformFor(forNode, temp); |
| 7871 | break; | 7868 | break; |
| 7872 | } | 7869 | } |
| 7873 | case id<VariablePair_t>(): | 7870 | case id<VariablePair_t>(): |
| @@ -8248,14 +8245,14 @@ private: | |||
| 8248 | void transformCompCommon(Comprehension_t* comp, str_list& out) { | 8245 | void transformCompCommon(Comprehension_t* comp, str_list& out) { |
| 8249 | str_list temp; | 8246 | str_list temp; |
| 8250 | auto x = comp; | 8247 | auto x = comp; |
| 8251 | auto compInner = static_cast<CompInner_t*>(comp->items.back()); | 8248 | auto compFor = static_cast<CompFor_t*>(comp->items.back()); |
| 8252 | for (auto item : compInner->items.objects()) { | 8249 | for (auto item : compFor->items.objects()) { |
| 8253 | switch (item->get_id()) { | 8250 | switch (item->get_id()) { |
| 8254 | case id<CompForEach_t>(): | 8251 | case id<CompForEach_t>(): |
| 8255 | transformCompForEach(static_cast<CompForEach_t*>(item), temp); | 8252 | transformCompForEach(static_cast<CompForEach_t*>(item), temp); |
| 8256 | break; | 8253 | break; |
| 8257 | case id<CompFor_t>(): | 8254 | case id<CompForNum_t>(): |
| 8258 | transformCompFor(static_cast<CompFor_t*>(item), temp); | 8255 | transformCompForNum(static_cast<CompForNum_t*>(item), temp); |
| 8259 | break; | 8256 | break; |
| 8260 | case id<Exp_t>(): | 8257 | case id<Exp_t>(): |
| 8261 | transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); | 8258 | transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); |
| @@ -8279,7 +8276,7 @@ private: | |||
| 8279 | auto value = std::move(temp.back()); | 8276 | auto value = std::move(temp.back()); |
| 8280 | temp.pop_back(); | 8277 | temp.pop_back(); |
| 8281 | _buf << join(temp) << value; | 8278 | _buf << join(temp) << value; |
| 8282 | for (size_t i = 0; i < compInner->items.objects().size(); ++i) { | 8279 | for (size_t i = 0; i < compFor->items.objects().size(); ++i) { |
| 8283 | popScope(); | 8280 | popScope(); |
| 8284 | _buf << indent() << "end"sv << nl(comp); | 8281 | _buf << indent() << "end"sv << nl(comp); |
| 8285 | } | 8282 | } |
| @@ -8288,7 +8285,7 @@ private: | |||
| 8288 | 8285 | ||
| 8289 | void transformComprehension(Comprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 8286 | void transformComprehension(Comprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
| 8290 | auto x = comp; | 8287 | auto x = comp; |
| 8291 | if (comp->items.size() != 2 || !ast_is<CompInner_t>(comp->items.back())) { | 8288 | if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) { |
| 8292 | switch (usage) { | 8289 | switch (usage) { |
| 8293 | case ExpUsage::Assignment: { | 8290 | case ExpUsage::Assignment: { |
| 8294 | auto tableLit = x->new_ptr<TableLit_t>(); | 8291 | auto tableLit = x->new_ptr<TableLit_t>(); |
| @@ -8360,7 +8357,7 @@ private: | |||
| 8360 | default: | 8357 | default: |
| 8361 | break; | 8358 | break; |
| 8362 | } | 8359 | } |
| 8363 | auto compInner = static_cast<CompInner_t*>(comp->items.back()); | 8360 | auto compFor = static_cast<CompFor_t*>(comp->items.back()); |
| 8364 | str_list temp; | 8361 | str_list temp; |
| 8365 | std::string accumVar = getUnusedName("_accum_"sv); | 8362 | std::string accumVar = getUnusedName("_accum_"sv); |
| 8366 | addToScope(accumVar); | 8363 | addToScope(accumVar); |
| @@ -8369,13 +8366,13 @@ private: | |||
| 8369 | lenVar = getUnusedName("_len_"sv); | 8366 | lenVar = getUnusedName("_len_"sv); |
| 8370 | addToScope(lenVar); | 8367 | addToScope(lenVar); |
| 8371 | } | 8368 | } |
| 8372 | for (auto item : compInner->items.objects()) { | 8369 | for (auto item : compFor->items.objects()) { |
| 8373 | switch (item->get_id()) { | 8370 | switch (item->get_id()) { |
| 8374 | case id<CompForEach_t>(): | 8371 | case id<CompForEach_t>(): |
| 8375 | transformCompForEach(static_cast<CompForEach_t*>(item), temp); | 8372 | transformCompForEach(static_cast<CompForEach_t*>(item), temp); |
| 8376 | break; | 8373 | break; |
| 8377 | case id<CompFor_t>(): | 8374 | case id<CompForNum_t>(): |
| 8378 | transformCompFor(static_cast<CompFor_t*>(item), temp); | 8375 | transformCompForNum(static_cast<CompForNum_t*>(item), temp); |
| 8379 | break; | 8376 | break; |
| 8380 | case id<Exp_t>(): | 8377 | case id<Exp_t>(): |
| 8381 | transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); | 8378 | transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); |
| @@ -8396,7 +8393,7 @@ private: | |||
| 8396 | } | 8393 | } |
| 8397 | auto assignStr = std::move(temp.back()); | 8394 | auto assignStr = std::move(temp.back()); |
| 8398 | temp.pop_back(); | 8395 | temp.pop_back(); |
| 8399 | for (size_t i = 0; i < compInner->items.objects().size(); ++i) { | 8396 | for (size_t i = 0; i < compFor->items.objects().size(); ++i) { |
| 8400 | popScope(); | 8397 | popScope(); |
| 8401 | } | 8398 | } |
| 8402 | _buf << indent() << "local "sv << accumVar << " = { }"sv << nl(comp); | 8399 | _buf << indent() << "local "sv << accumVar << " = { }"sv << nl(comp); |
| @@ -8754,7 +8751,7 @@ private: | |||
| 8754 | out.push_back('(' + join(temp, ", "sv) + ')'); | 8751 | out.push_back('(' + join(temp, ", "sv) + ')'); |
| 8755 | } | 8752 | } |
| 8756 | 8753 | ||
| 8757 | void transformForHead(Variable_t* var, Exp_t* startVal, Exp_t* stopVal, ForStepValue_t* stepVal, str_list& out) { | 8754 | void transformForNumHead(Variable_t* var, Exp_t* startVal, Exp_t* stopVal, ForStepValue_t* stepVal, str_list& out) { |
| 8758 | str_list temp; | 8755 | str_list temp; |
| 8759 | std::string varName = variableToString(var); | 8756 | std::string varName = variableToString(var); |
| 8760 | transformExp(startVal, temp, ExpUsage::Closure); | 8757 | transformExp(startVal, temp, ExpUsage::Closure); |
| @@ -8775,8 +8772,8 @@ private: | |||
| 8775 | out.push_back(clearBuf()); | 8772 | out.push_back(clearBuf()); |
| 8776 | } | 8773 | } |
| 8777 | 8774 | ||
| 8778 | void transformForHead(For_t* forNode, str_list& out) { | 8775 | void transformForNumHead(ForNum_t* forNum, str_list& out) { |
| 8779 | transformForHead(forNode->varName, forNode->startValue, forNode->stopValue, forNode->stepValue, out); | 8776 | transformForNumHead(forNum->varName, forNum->startValue, forNum->stopValue, forNum->stepValue, out); |
| 8780 | } | 8777 | } |
| 8781 | 8778 | ||
| 8782 | void transform_plain_body(ast_node* bodyOrStmt, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 8779 | void transform_plain_body(ast_node* bodyOrStmt, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
| @@ -9040,46 +9037,48 @@ private: | |||
| 9040 | return conditionVar; | 9037 | return conditionVar; |
| 9041 | } | 9038 | } |
| 9042 | 9039 | ||
| 9043 | void transformFor(For_t* forNode, str_list& out) { | 9040 | void transformForNum(ForNum_t* forNum, str_list& out) { |
| 9044 | str_list temp; | 9041 | str_list temp; |
| 9045 | transformForHead(forNode, temp); | 9042 | transformForNumHead(forNum, temp); |
| 9046 | auto breakLoopType = getBreakLoopType(forNode->body, Empty); | 9043 | auto breakLoopType = getBreakLoopType(forNum->body, Empty); |
| 9047 | transformLoopBody(forNode->body, temp, breakLoopType, ExpUsage::Common); | 9044 | transformLoopBody(forNum->body, temp, breakLoopType, ExpUsage::Common); |
| 9048 | popScope(); | 9045 | popScope(); |
| 9049 | out.push_back(join(temp) + indent() + "end"s + nl(forNode)); | 9046 | out.push_back(join(temp) + indent() + "end"s + nl(forNum)); |
| 9050 | } | 9047 | } |
| 9051 | 9048 | ||
| 9052 | std::string transformForInner(For_t* forNode, str_list& out) { | 9049 | std::string transformForNumInner(ForNum_t* forNum, str_list& out) { |
| 9053 | auto x = forNode; | 9050 | auto x = forNum; |
| 9054 | std::string accum = getUnusedName("_accum_"sv); | 9051 | std::string accum = getUnusedName("_accum_"sv); |
| 9055 | addToScope(accum); | 9052 | addToScope(accum); |
| 9056 | std::string len = getUnusedName("_len_"sv); | 9053 | std::string len = getUnusedName("_len_"sv); |
| 9057 | addToScope(len); | 9054 | addToScope(len); |
| 9058 | auto breakLoopType = getBreakLoopType(forNode->body, accum); | 9055 | auto breakLoopType = getBreakLoopType(forNum->body, accum); |
| 9059 | _buf << indent() << "local "sv << accum << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nl(forNode); | 9056 | _buf << indent() << "local "sv << accum << (hasBreakWithValue(breakLoopType) ? ""sv : " = { }"sv) << nl(forNum); |
| 9060 | out.emplace_back(clearBuf()); | 9057 | out.emplace_back(clearBuf()); |
| 9061 | _buf << indent() << "local "sv << len << " = 1"sv << nl(forNode); | 9058 | _buf << indent() << "local "sv << len << " = 1"sv << nl(forNum); |
| 9062 | auto& lenAssign = out.emplace_back(clearBuf()); | 9059 | auto& lenAssign = out.emplace_back(clearBuf()); |
| 9063 | transformForHead(forNode, out); | 9060 | transformForNumHead(forNum, out); |
| 9064 | if (hasBreakWithValue(breakLoopType)) { | 9061 | if (hasBreakWithValue(breakLoopType)) { |
| 9065 | lenAssign.clear(); | 9062 | lenAssign.clear(); |
| 9066 | transformLoopBody(forNode->body, out, breakLoopType, ExpUsage::Common); | 9063 | transformLoopBody(forNum->body, out, breakLoopType, ExpUsage::Common); |
| 9067 | } else { | 9064 | } else { |
| 9068 | auto expList = toAst<ExpList_t>(accum + '[' + len + ']', x); | 9065 | auto expList = toAst<ExpList_t>(accum + '[' + len + ']', x); |
| 9069 | auto followStmt = toAst<Statement_t>(len + "+=1"s, forNode->body); | 9066 | auto followStmt = toAst<Statement_t>(len + "+=1"s, forNum->body); |
| 9070 | expList->followStmt = followStmt.get(); | 9067 | expList->followStmt = followStmt.get(); |
| 9071 | transformLoopBody(forNode->body, out, breakLoopType, ExpUsage::Assignment, expList); | 9068 | transformLoopBody(forNum->body, out, breakLoopType, ExpUsage::Assignment, expList); |
| 9072 | if (!expList->followStmtProcessed) { | 9069 | if (!expList->followStmtProcessed) { |
| 9073 | lenAssign.clear(); | 9070 | lenAssign.clear(); |
| 9074 | } | 9071 | } |
| 9075 | } | 9072 | } |
| 9076 | popScope(); | 9073 | popScope(); |
| 9077 | out.push_back(indent() + "end"s + nl(forNode)); | 9074 | out.push_back(indent() + "end"s + nl(forNum)); |
| 9078 | return accum; | 9075 | return accum; |
| 9079 | } | 9076 | } |
| 9080 | 9077 | ||
| 9081 | void transformForClosure(For_t* forNode, str_list& out) { | 9078 | void transformForNumClosure(ForNum_t* forNum, str_list& out) { |
| 9082 | auto simpleValue = forNode->new_ptr<SimpleValue_t>(); | 9079 | auto forNode = forNum->new_ptr<For_t>(); |
| 9080 | forNode->forLoop.set(forNum); | ||
| 9081 | auto simpleValue = forNum->new_ptr<SimpleValue_t>(); | ||
| 9083 | simpleValue->value.set(forNode); | 9082 | simpleValue->value.set(forNode); |
| 9084 | if (transformAsUpValueFunc(newExp(simpleValue, forNode), out)) { | 9083 | if (transformAsUpValueFunc(newExp(simpleValue, forNode), out)) { |
| 9085 | return; | 9084 | return; |
| @@ -9089,26 +9088,26 @@ private: | |||
| 9089 | pushAnonVarArg(); | 9088 | pushAnonVarArg(); |
| 9090 | std::string& funcStart = temp.emplace_back(); | 9089 | std::string& funcStart = temp.emplace_back(); |
| 9091 | pushScope(); | 9090 | pushScope(); |
| 9092 | auto accum = transformForInner(forNode, temp); | 9091 | auto accum = transformForNumInner(forNum, temp); |
| 9093 | temp.push_back(indent() + "return "s + accum + nl(forNode)); | 9092 | temp.push_back(indent() + "return "s + accum + nl(forNum)); |
| 9094 | popScope(); | 9093 | popScope(); |
| 9095 | funcStart = anonFuncStart() + nl(forNode); | 9094 | funcStart = anonFuncStart() + nl(forNum); |
| 9096 | temp.push_back(indent() + anonFuncEnd()); | 9095 | temp.push_back(indent() + anonFuncEnd()); |
| 9097 | popAnonVarArg(); | 9096 | popAnonVarArg(); |
| 9098 | popFunctionScope(); | 9097 | popFunctionScope(); |
| 9099 | out.push_back(join(temp)); | 9098 | out.push_back(join(temp)); |
| 9100 | } | 9099 | } |
| 9101 | 9100 | ||
| 9102 | void transformForInPlace(For_t* forNode, str_list& out, ExpList_t* assignExpList = nullptr) { | 9101 | void transformForNumInPlace(ForNum_t* forNum, str_list& out, ExpList_t* assignExpList) { |
| 9103 | auto x = forNode; | 9102 | auto x = forNum; |
| 9104 | str_list temp; | 9103 | str_list temp; |
| 9105 | bool isScoped = !currentScope().lastStatement; | 9104 | bool isScoped = !currentScope().lastStatement; |
| 9106 | if (assignExpList) { | 9105 | if (assignExpList) { |
| 9107 | if (isScoped) { | 9106 | if (isScoped) { |
| 9108 | _buf << indent() << "do"sv << nl(forNode); | 9107 | _buf << indent() << "do"sv << nl(forNum); |
| 9109 | pushScope(); | 9108 | pushScope(); |
| 9110 | } | 9109 | } |
| 9111 | auto accum = transformForInner(forNode, temp); | 9110 | auto accum = transformForNumInner(forNum, temp); |
| 9112 | auto assign = x->new_ptr<Assign_t>(); | 9111 | auto assign = x->new_ptr<Assign_t>(); |
| 9113 | assign->values.push_back(toAst<Exp_t>(accum, x)); | 9112 | assign->values.push_back(toAst<Exp_t>(accum, x)); |
| 9114 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 9113 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| @@ -9117,10 +9116,10 @@ private: | |||
| 9117 | transformAssignment(assignment, temp); | 9116 | transformAssignment(assignment, temp); |
| 9118 | if (isScoped) { | 9117 | if (isScoped) { |
| 9119 | popScope(); | 9118 | popScope(); |
| 9120 | temp.push_back(indent() + "end"s + nl(forNode)); | 9119 | temp.push_back(indent() + "end"s + nl(forNum)); |
| 9121 | } | 9120 | } |
| 9122 | } else { | 9121 | } else { |
| 9123 | auto accum = transformForInner(forNode, temp); | 9122 | auto accum = transformForNumInner(forNum, temp); |
| 9124 | auto returnNode = x->new_ptr<Return_t>(); | 9123 | auto returnNode = x->new_ptr<Return_t>(); |
| 9125 | returnNode->explicitReturn = false; | 9124 | returnNode->explicitReturn = false; |
| 9126 | auto expListLow = toAst<ExpListLow_t>(accum, x); | 9125 | auto expListLow = toAst<ExpListLow_t>(accum, x); |
| @@ -9191,9 +9190,11 @@ private: | |||
| 9191 | } | 9190 | } |
| 9192 | 9191 | ||
| 9193 | void transformForEachClosure(ForEach_t* forEach, str_list& out) { | 9192 | void transformForEachClosure(ForEach_t* forEach, str_list& out) { |
| 9193 | auto forNode = forEach->new_ptr<For_t>(); | ||
| 9194 | forNode->forLoop.set(forEach); | ||
| 9194 | auto simpleValue = forEach->new_ptr<SimpleValue_t>(); | 9195 | auto simpleValue = forEach->new_ptr<SimpleValue_t>(); |
| 9195 | simpleValue->value.set(forEach); | 9196 | simpleValue->value.set(forNode); |
| 9196 | if (transformAsUpValueFunc(newExp(simpleValue, forEach), out)) { | 9197 | if (transformAsUpValueFunc(newExp(simpleValue, forNode), out)) { |
| 9197 | return; | 9198 | return; |
| 9198 | } | 9199 | } |
| 9199 | str_list temp; | 9200 | str_list temp; |
| @@ -9211,7 +9212,7 @@ private: | |||
| 9211 | out.push_back(join(temp)); | 9212 | out.push_back(join(temp)); |
| 9212 | } | 9213 | } |
| 9213 | 9214 | ||
| 9214 | void transformForEachInPlace(ForEach_t* forEach, str_list& out, ExpList_t* assignExpList = nullptr) { | 9215 | void transformForEachInPlace(ForEach_t* forEach, str_list& out, ExpList_t* assignExpList) { |
| 9215 | auto x = forEach; | 9216 | auto x = forEach; |
| 9216 | str_list temp; | 9217 | str_list temp; |
| 9217 | bool isScoped = !currentScope().lastStatement; | 9218 | bool isScoped = !currentScope().lastStatement; |
| @@ -9242,6 +9243,48 @@ private: | |||
| 9242 | out.push_back(join(temp)); | 9243 | out.push_back(join(temp)); |
| 9243 | } | 9244 | } |
| 9244 | 9245 | ||
| 9246 | void transformFor(For_t* forNode, str_list& out) { | ||
| 9247 | switch (forNode->forLoop->get_id()) { | ||
| 9248 | case id<ForNum_t>(): | ||
| 9249 | transformForNum(static_cast<ForNum_t*>(forNode->forLoop.get()), out); | ||
| 9250 | break; | ||
| 9251 | case id<ForEach_t>(): | ||
| 9252 | transformForEach(static_cast<ForEach_t*>(forNode->forLoop.get()), out); | ||
| 9253 | break; | ||
| 9254 | default: | ||
| 9255 | YUEE("AST node mismatch", forNode->forLoop.get()); | ||
| 9256 | break; | ||
| 9257 | } | ||
| 9258 | } | ||
| 9259 | |||
| 9260 | void transformForClosure(For_t* forNode, str_list& out) { | ||
| 9261 | switch (forNode->forLoop->get_id()) { | ||
| 9262 | case id<ForNum_t>(): | ||
| 9263 | transformForNumClosure(static_cast<ForNum_t*>(forNode->forLoop.get()), out); | ||
| 9264 | break; | ||
| 9265 | case id<ForEach_t>(): | ||
| 9266 | transformForEachClosure(static_cast<ForEach_t*>(forNode->forLoop.get()), out); | ||
| 9267 | break; | ||
| 9268 | default: | ||
| 9269 | YUEE("AST node mismatch", forNode->forLoop.get()); | ||
| 9270 | break; | ||
| 9271 | } | ||
| 9272 | } | ||
| 9273 | |||
| 9274 | void transformForInPlace(For_t* forNode, str_list& out, ExpList_t* assignExpList) { | ||
| 9275 | switch (forNode->forLoop->get_id()) { | ||
| 9276 | case id<ForNum_t>(): | ||
| 9277 | transformForNumInPlace(static_cast<ForNum_t*>(forNode->forLoop.get()), out, assignExpList); | ||
| 9278 | break; | ||
| 9279 | case id<ForEach_t>(): | ||
| 9280 | transformForEachInPlace(static_cast<ForEach_t*>(forNode->forLoop.get()), out, assignExpList); | ||
| 9281 | break; | ||
| 9282 | default: | ||
| 9283 | YUEE("AST node mismatch", forNode->forLoop.get()); | ||
| 9284 | break; | ||
| 9285 | } | ||
| 9286 | } | ||
| 9287 | |||
| 9245 | void transform_variable_pair(VariablePair_t* pair, str_list& out) { | 9288 | void transform_variable_pair(VariablePair_t* pair, str_list& out) { |
| 9246 | auto name = _parser.toString(pair->name); | 9289 | auto name = _parser.toString(pair->name); |
| 9247 | if (pair->name->name.is<UnicodeName_t>()) { | 9290 | if (pair->name->name.is<UnicodeName_t>()) { |
| @@ -10530,8 +10573,8 @@ private: | |||
| 10530 | case id<CompForEach_t>(): | 10573 | case id<CompForEach_t>(): |
| 10531 | transformCompForEach(static_cast<CompForEach_t*>(item), temp); | 10574 | transformCompForEach(static_cast<CompForEach_t*>(item), temp); |
| 10532 | break; | 10575 | break; |
| 10533 | case id<CompFor_t>(): | 10576 | case id<CompForNum_t>(): |
| 10534 | transformCompFor(static_cast<CompFor_t*>(item), temp); | 10577 | transformCompForNum(static_cast<CompForNum_t*>(item), temp); |
| 10535 | break; | 10578 | break; |
| 10536 | case id<Exp_t>(): | 10579 | case id<Exp_t>(): |
| 10537 | transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); | 10580 | transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); |
| @@ -10597,8 +10640,8 @@ private: | |||
| 10597 | } | 10640 | } |
| 10598 | } | 10641 | } |
| 10599 | 10642 | ||
| 10600 | void transformCompFor(CompFor_t* comp, str_list& out) { | 10643 | void transformCompForNum(CompForNum_t* comp, str_list& out) { |
| 10601 | transformForHead(comp->varName, comp->startValue, comp->stopValue, comp->stepValue, out); | 10644 | transformForNumHead(comp->varName, comp->startValue, comp->stopValue, comp->stepValue, out); |
| 10602 | } | 10645 | } |
| 10603 | 10646 | ||
| 10604 | void transformTableBlockIndent(TableBlockIndent_t* table, str_list& out) { | 10647 | void transformTableBlockIndent(TableBlockIndent_t* table, str_list& out) { |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index a7feb83..1b72a8c 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -113,7 +113,7 @@ YueParser::YueParser() { | |||
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| 115 | empty_block_error = expect_error( | 115 | empty_block_error = expect_error( |
| 116 | "must be followed by a statement or an indented block"sv | 116 | "expected a valid statement or indented block"sv |
| 117 | ); | 117 | ); |
| 118 | export_expression_error = expect_error( | 118 | export_expression_error = expect_error( |
| 119 | "invalid export expression"sv | 119 | "invalid export expression"sv |
| @@ -170,7 +170,7 @@ YueParser::YueParser() { | |||
| 170 | "invalid import syntax, expected `import \"X.mod\" as modname` or `import \"X.mod\" as {:name}`"sv | 170 | "invalid import syntax, expected `import \"X.mod\" as modname` or `import \"X.mod\" as {:name}`"sv |
| 171 | ); | 171 | ); |
| 172 | expected_expression_error = expect_error( | 172 | expected_expression_error = expect_error( |
| 173 | "expected expression"sv | 173 | "expected valid expression"sv |
| 174 | ); | 174 | ); |
| 175 | invalid_from_import_error = expect_error( | 175 | invalid_from_import_error = expect_error( |
| 176 | "invalid import syntax, expected `from \"X.mod\" import name` or `from mod import name`"sv | 176 | "invalid import syntax, expected `from \"X.mod\" import name` or `from mod import name`"sv |
| @@ -202,6 +202,9 @@ YueParser::YueParser() { | |||
| 202 | invalid_import_literal_error = expect_error( | 202 | invalid_import_literal_error = expect_error( |
| 203 | "invalid import path literal, expected a dotted path like X.Y.Z"sv | 203 | "invalid import path literal, expected a dotted path like X.Y.Z"sv |
| 204 | ); | 204 | ); |
| 205 | expected_indentifier_error = expect_error( | ||
| 206 | "expected valid identifer"sv | ||
| 207 | ); | ||
| 205 | 208 | ||
| 206 | #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) | 209 | #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) |
| 207 | 210 | ||
| @@ -382,22 +385,24 @@ YueParser::YueParser() { | |||
| 382 | local_const_item = Variable | SimpleTable | TableLit | Comprehension; | 385 | local_const_item = Variable | SimpleTable | TableLit | Comprehension; |
| 383 | LocalAttrib = ( | 386 | LocalAttrib = ( |
| 384 | ConstAttrib >> Seperator >> space >> local_const_item >> *(space >> ',' >> space >> local_const_item) | | 387 | ConstAttrib >> Seperator >> space >> local_const_item >> *(space >> ',' >> space >> local_const_item) | |
| 385 | CloseAttrib >> Seperator >> space >> Variable >> *(space >> ',' >> space >> Variable) | 388 | CloseAttrib >> Seperator >> space >> must_variable >> *(space >> ',' >> space >> must_variable) |
| 386 | ) >> space >> Assign; | 389 | ) >> space >> Assign; |
| 387 | 390 | ||
| 388 | ColonImportName = '\\' >> space >> Variable; | 391 | ColonImportName = '\\' >> must_variable; |
| 389 | import_name = ColonImportName | Variable; | 392 | import_name = not_(key("from")) >> (ColonImportName | must_variable); |
| 390 | import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name); | 393 | import_name_list = Seperator >> *space_break >> space >> import_name >> *( |
| 394 | (+space_break | space >> ',' >> *space_break) >> space >> import_name | ||
| 395 | ); | ||
| 391 | ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> (ImportLiteral | not_(String) >> must_exp); | 396 | ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> (ImportLiteral | not_(String) >> must_exp); |
| 392 | from_import_name_list_line = import_name >> *(space >> ',' >> space >> import_name); | 397 | from_import_name_list_line = import_name >> *(space >> ',' >> space >> not_(line_break) >> import_name); |
| 393 | from_import_name_in_block = +space_break >> advance_match >> ensure(space >> from_import_name_list_line >> *(-(space >> ',') >> +space_break >> check_indent_match >> space >> from_import_name_list_line), pop_indent); | 398 | from_import_name_in_block = +space_break >> advance_match >> ensure(space >> from_import_name_list_line >> *(-(space >> ',') >> +space_break >> check_indent_match >> space >> from_import_name_list_line), pop_indent); |
| 394 | FromImport = key("from") >> space >> ( | 399 | FromImport = key("from") >> space >> ( |
| 395 | ImportLiteral | not_(String) >> Exp | invalid_from_import_error | 400 | ImportLiteral | not_(String) >> Exp | invalid_from_import_error |
| 396 | ) >> *space_break >> space >> ( | 401 | ) >> *space_break >> space >> ( |
| 397 | key("import") | invalid_from_import_error | 402 | key("import") | invalid_from_import_error |
| 398 | ) >> space >> Seperator >> ( | 403 | ) >> space >> Seperator >> ( |
| 399 | from_import_name_list_line >> -(space >> ',') >> -from_import_name_in_block | | ||
| 400 | from_import_name_in_block | | 404 | from_import_name_in_block | |
| 405 | from_import_name_list_line >> -(space >> ',') >> -from_import_name_in_block | | ||
| 401 | invalid_from_import_error | 406 | invalid_from_import_error |
| 402 | ); | 407 | ); |
| 403 | 408 | ||
| @@ -432,16 +437,18 @@ YueParser::YueParser() { | |||
| 432 | -(space >> ',') >> | 437 | -(space >> ',') >> |
| 433 | -import_tab_lines >> | 438 | -import_tab_lines >> |
| 434 | white >> | 439 | white >> |
| 435 | '}' | 440 | end_braces_expression |
| 436 | ) | ( | 441 | ) | ( |
| 437 | Seperator >> import_tab_key_value >> *(space >> ',' >> space >> import_tab_key_value) | 442 | Seperator >> import_tab_key_value >> *(space >> ',' >> space >> import_tab_key_value) |
| 438 | ); | 443 | ); |
| 439 | 444 | ||
| 440 | ImportAs = ImportLiteral >> -(space >> key("as") >> space >> (ImportTabLit | Variable | ImportAllMacro | invalid_import_as_syntax_error)); | 445 | ImportAs = ImportLiteral >> -(space >> key("as") >> space >> ( |
| 446 | ImportTabLit | Variable | ImportAllMacro | invalid_import_as_syntax_error | ||
| 447 | )); | ||
| 441 | 448 | ||
| 442 | ImportGlobal = Seperator >> UnicodeName >> *('.' >> UnicodeName) >> -(space >> key("as") >> space >> Variable); | 449 | ImportGlobal = Seperator >> UnicodeName >> *('.' >> UnicodeName) >> space >> not_(',' | key("from")) >> -(key("as") >> space >> must_variable); |
| 443 | 450 | ||
| 444 | Import = key("import") >> space >> (ImportAs | ImportFrom | ImportGlobal | invalid_import_syntax_error) | FromImport; | 451 | Import = key("import") >> space >> (ImportGlobal | ImportAs | ImportFrom | invalid_import_syntax_error) | FromImport; |
| 445 | 452 | ||
| 446 | Label = "::" >> (and_(LuaKeyword >> "::") >> keyword_as_label_error | UnicodeName >> "::"); | 453 | Label = "::" >> (and_(LuaKeyword >> "::") >> keyword_as_label_error | UnicodeName >> "::"); |
| 447 | 454 | ||
| @@ -511,13 +518,15 @@ YueParser::YueParser() { | |||
| 511 | ForStepValue = ',' >> space >> must_exp; | 518 | ForStepValue = ',' >> space >> must_exp; |
| 512 | for_args = Variable >> space >> '=' >> space >> must_exp >> space >> ',' >> space >> must_exp >> space >> -ForStepValue; | 519 | for_args = Variable >> space >> '=' >> space >> must_exp >> space >> ',' >> space >> must_exp >> space >> -ForStepValue; |
| 513 | 520 | ||
| 514 | For = for_key >> space >> disable_do_chain_arg_table_block_rule(for_args) >> space >> opt_body_with("do"); | 521 | ForNum = disable_do_chain_arg_table_block_rule(for_args) >> space >> opt_body_with("do"); |
| 515 | 522 | ||
| 516 | for_in = StarExp | ExpList | expected_expression_error; | 523 | for_in = StarExp | ExpList | expected_expression_error; |
| 517 | 524 | ||
| 518 | ForEach = for_key >> space >> AssignableNameList >> space >> key("in") >> space >> | 525 | ForEach = AssignableNameList >> space >> key("in") >> space >> |
| 519 | disable_do_chain_arg_table_block_rule(for_in) >> space >> opt_body_with("do"); | 526 | disable_do_chain_arg_table_block_rule(for_in) >> space >> opt_body_with("do"); |
| 520 | 527 | ||
| 528 | For = for_key >> space >> (ForNum | ForEach); | ||
| 529 | |||
| 521 | Do = pl::user(key("do"), [](const item_t& item) { | 530 | Do = pl::user(key("do"), [](const item_t& item) { |
| 522 | State* st = reinterpret_cast<State*>(item.user_data); | 531 | State* st = reinterpret_cast<State*>(item.user_data); |
| 523 | return st->noDoStack.empty() || !st->noDoStack.back(); | 532 | return st->noDoStack.empty() || !st->noDoStack.back(); |
| @@ -599,7 +608,7 @@ YueParser::YueParser() { | |||
| 599 | return true; | 608 | return true; |
| 600 | }); | 609 | }); |
| 601 | 610 | ||
| 602 | CatchBlock = line_break >> *space_break >> check_indent_match >> space >> key("catch") >> space >> (Variable >> space >> in_block | invalid_try_syntax_error); | 611 | CatchBlock = line_break >> *space_break >> check_indent_match >> space >> key("catch") >> space >> must_variable >> space >> (in_block | invalid_try_syntax_error); |
| 603 | Try = key("try") >> -ExistentialOp >> space >> (in_block | Exp | invalid_try_syntax_error) >> -CatchBlock; | 612 | Try = key("try") >> -ExistentialOp >> space >> (in_block | Exp | invalid_try_syntax_error) >> -CatchBlock; |
| 604 | 613 | ||
| 605 | list_value = | 614 | list_value = |
| @@ -622,24 +631,28 @@ YueParser::YueParser() { | |||
| 622 | 631 | ||
| 623 | list_lit_lines = +space_break >> list_lit_line >> *(-(space >> ',') >> space_break >> list_lit_line) >> -(space >> ','); | 632 | list_lit_lines = +space_break >> list_lit_line >> *(-(space >> ',') >> space_break >> list_lit_line) >> -(space >> ','); |
| 624 | 633 | ||
| 634 | end_brackets_expression = ']' | brackets_expression_error; | ||
| 635 | |||
| 625 | Comprehension = '[' >> not_('[') >> | 636 | Comprehension = '[' >> not_('[') >> |
| 626 | Seperator >> space >> ( | 637 | Seperator >> space >> ( |
| 627 | disable_for_rule(list_value) >> space >> ( | 638 | disable_for_rule(list_value) >> space >> ( |
| 628 | CompInner >> space >> ']' | | 639 | CompFor >> space >> end_brackets_expression | |
| 629 | (list_value_list >> -(space >> ',') | space >> ',') >> -list_lit_lines >> white >> ']' | 640 | (list_value_list >> -(space >> ',') | space >> ',') >> -list_lit_lines >> white >> end_brackets_expression |
| 630 | ) | | 641 | ) | |
| 631 | list_lit_lines >> white >> ']' | | 642 | list_lit_lines >> white >> end_brackets_expression | |
| 632 | white >> ']' >> not_(space >> '=') | 643 | white >> ']' >> not_(space >> '=') |
| 633 | ); | 644 | ); |
| 634 | 645 | ||
| 635 | CompValue = ',' >> space >> Exp; | 646 | end_braces_expression = '}' | braces_expression_error; |
| 636 | TblComprehension = and_('{') >> ('{' >> space >> disable_for_rule(Exp >> space >> -(CompValue >> space)) >> CompInner >> space >> '}' | braces_expression_error); | ||
| 637 | 647 | ||
| 638 | CompInner = Seperator >> (CompForEach | CompFor) >> *(space >> comp_clause); | 648 | CompValue = ',' >> space >> must_exp; |
| 649 | TblComprehension = '{' >> space >> disable_for_rule(Exp >> space >> -(CompValue >> space)) >> (CompFor | braces_expression_error) >> space >> end_braces_expression; | ||
| 650 | |||
| 651 | CompFor = key("for") >> space >> Seperator >> (CompForNum | CompForEach) >> *(space >> comp_clause); | ||
| 639 | StarExp = '*' >> space >> must_exp; | 652 | StarExp = '*' >> space >> must_exp; |
| 640 | CompForEach = key("for") >> space >> AssignableNameList >> space >> key("in") >> space >> (StarExp | must_exp); | 653 | CompForEach = AssignableNameList >> space >> key("in") >> space >> (StarExp | must_exp); |
| 641 | CompFor = key("for") >> space >> Variable >> space >> '=' >> space >> must_exp >> space >> ',' >> space >> must_exp >> -ForStepValue; | 654 | CompForNum = Variable >> space >> '=' >> space >> must_exp >> space >> ',' >> space >> must_exp >> -ForStepValue; |
| 642 | comp_clause = CompFor | CompForEach | key("when") >> space >> must_exp; | 655 | comp_clause = key("when") >> space >> must_exp | key("for") >> space >> (CompForNum | CompForEach); |
| 643 | 656 | ||
| 644 | Assign = '=' >> space >> Seperator >> ( | 657 | Assign = '=' >> space >> Seperator >> ( |
| 645 | With | If | Switch | TableBlock | | 658 | With | If | Switch | TableBlock | |
| @@ -794,7 +807,7 @@ YueParser::YueParser() { | |||
| 794 | Metamethod = '<' >> space >> meta_index >> space >> '>'; | 807 | Metamethod = '<' >> space >> meta_index >> space >> '>'; |
| 795 | 808 | ||
| 796 | ExistentialOp = '?' >> not_('?'); | 809 | ExistentialOp = '?' >> not_('?'); |
| 797 | TableAppendingOp = and_('[') >> ("[]" | brackets_expression_error); | 810 | TableAppendingOp = and_('[') >> "[]"; |
| 798 | PlainItem = +any_char; | 811 | PlainItem = +any_char; |
| 799 | 812 | ||
| 800 | chain_call = ( | 813 | chain_call = ( |
| @@ -819,7 +832,7 @@ YueParser::YueParser() { | |||
| 819 | chain_with_colon = +chain_item >> -colon_chain; | 832 | chain_with_colon = +chain_item >> -colon_chain; |
| 820 | chain_items = chain_with_colon | colon_chain; | 833 | chain_items = chain_with_colon | colon_chain; |
| 821 | 834 | ||
| 822 | index = '[' >> not_('[') >> space >> (ReversedIndex >> and_(space >> ']') | Exp) >> space >> (']' | brackets_expression_error); | 835 | index = '[' >> not_('[') >> space >> (ReversedIndex >> and_(space >> ']') | Exp) >> space >> ']'; |
| 823 | ReversedIndex = '#' >> space >> -('-' >> space >> Exp); | 836 | ReversedIndex = '#' >> space >> -('-' >> space >> Exp); |
| 824 | chain_item = | 837 | chain_item = |
| 825 | Invoke >> -ExistentialOp | | 838 | Invoke >> -ExistentialOp | |
| @@ -859,10 +872,8 @@ YueParser::YueParser() { | |||
| 859 | SpreadExp | | 872 | SpreadExp | |
| 860 | NormalDef; | 873 | NormalDef; |
| 861 | 874 | ||
| 862 | table_value_list = table_value >> *(space >> ',' >> space >> table_value); | ||
| 863 | |||
| 864 | table_lit_line = ( | 875 | table_lit_line = ( |
| 865 | push_indent_match >> (space >> table_value_list >> pop_indent | pop_indent) | 876 | push_indent_match >> (space >> not_(line_break | '}') >> (table_value | expected_expression_error) >> *(space >> ',' >> space >> table_value) >> pop_indent | pop_indent) |
| 866 | ) | ( | 877 | ) | ( |
| 867 | space | 878 | space |
| 868 | ); | 879 | ); |
| @@ -871,9 +882,11 @@ YueParser::YueParser() { | |||
| 871 | 882 | ||
| 872 | TableLit = | 883 | TableLit = |
| 873 | '{' >> Seperator >> | 884 | '{' >> Seperator >> |
| 874 | -(space >> table_value_list >> -(space >> ',')) >> | 885 | -(space >> table_value >> *(space >> ',' >> space >> table_value) >> -(space >> ',')) >> |
| 875 | -table_lit_lines >> | 886 | ( |
| 876 | white >> '}'; | 887 | table_lit_lines >> white >> end_braces_expression | |
| 888 | white >> '}' | ||
| 889 | ); | ||
| 877 | 890 | ||
| 878 | table_block_inner = Seperator >> key_value_line >> *(+space_break >> key_value_line); | 891 | table_block_inner = Seperator >> key_value_line >> *(+space_break >> key_value_line); |
| 879 | TableBlock = +space_break >> advance_match >> ensure(table_block_inner, pop_indent); | 892 | TableBlock = +space_break >> advance_match >> ensure(table_block_inner, pop_indent); |
| @@ -955,22 +968,20 @@ YueParser::YueParser() { | |||
| 955 | invalid_export_syntax_error | 968 | invalid_export_syntax_error |
| 956 | ) >> not_(space >> StatementAppendix); | 969 | ) >> not_(space >> StatementAppendix); |
| 957 | 970 | ||
| 958 | check_keyword_as_identifier = and_(LuaKeyword >> not_alpha_num) >> keyword_as_identifier_syntax_error; | 971 | VariablePair = ':' >> Variable; |
| 959 | |||
| 960 | VariablePair = ':' >> (Variable | check_keyword_as_identifier); | ||
| 961 | 972 | ||
| 962 | NormalPair = | 973 | NormalPair = |
| 963 | ( | 974 | ( |
| 964 | KeyName | | 975 | KeyName | |
| 965 | '[' >> not_('[') >> space >> Exp >> space >> ']' | | 976 | '[' >> not_('[') >> space >> Exp >> space >> ']' | |
| 966 | String | 977 | String |
| 967 | ) >> ':' >> not_(':') >> space >> | 978 | ) >> ':' >> not_(':' | '=' >> not_('>')) >> space >> |
| 968 | (Exp | TableBlock | +space_break >> space >> Exp | check_keyword_as_identifier); | 979 | (Exp | TableBlock | +space_break >> space >> Exp | expected_expression_error); |
| 969 | 980 | ||
| 970 | MetaVariablePair = ":<" >> space >> Variable >> space >> '>'; | 981 | MetaVariablePair = ":<" >> space >> must_variable >> space >> '>'; |
| 971 | 982 | ||
| 972 | MetaNormalPair = '<' >> space >> -meta_index >> space >> ">:" >> space >> | 983 | MetaNormalPair = '<' >> space >> -meta_index >> space >> ">:" >> space >> |
| 973 | (Exp | TableBlock | +space_break >> space >> Exp | check_keyword_as_identifier); | 984 | (Exp | TableBlock | +space_break >> space >> Exp | expected_expression_error); |
| 974 | 985 | ||
| 975 | destruct_def = -(space >> '=' >> space >> Exp); | 986 | destruct_def = -(space >> '=' >> space >> Exp); |
| 976 | VariablePairDef = VariablePair >> destruct_def; | 987 | VariablePairDef = VariablePair >> destruct_def; |
| @@ -1010,7 +1021,7 @@ YueParser::YueParser() { | |||
| 1010 | white >> VarArg >> -(space >> '`' >> space >> Name) >> check_vararg_position | 1021 | white >> VarArg >> -(space >> '`' >> space >> Name) >> check_vararg_position |
| 1011 | ); | 1022 | ); |
| 1012 | 1023 | ||
| 1013 | OuterVarShadow = key("using") >> space >> (NameList | key("nil")); | 1024 | OuterVarShadow = key("using") >> space >> (key("nil") | NameList); |
| 1014 | 1025 | ||
| 1015 | FnArgsDef = '(' >> *space_break >> -FnArgDefList >> -(white >> OuterVarShadow) >> white >> -(and_(',') >> unexpected_comma_error) >> ')'; | 1026 | FnArgsDef = '(' >> *space_break >> -FnArgDefList >> -(white >> OuterVarShadow) >> white >> -(and_(',') >> unexpected_comma_error) >> ')'; |
| 1016 | FnArrow = expr("->") | "=>"; | 1027 | FnArrow = expr("->") | "=>"; |
| @@ -1028,13 +1039,15 @@ YueParser::YueParser() { | |||
| 1028 | MacroLit = -(macro_args_def >> space) >> "->" >> space >> Body; | 1039 | MacroLit = -(macro_args_def >> space) >> "->" >> space >> Body; |
| 1029 | MacroFunc = MacroName >> (Invoke | InvokeArgs); | 1040 | MacroFunc = MacroName >> (Invoke | InvokeArgs); |
| 1030 | Macro = key("macro") >> space >> ( | 1041 | Macro = key("macro") >> space >> ( |
| 1031 | UnicodeName >> space >> '=' >> space >> (MacroLit | MacroFunc) | | 1042 | UnicodeName >> space >> '=' >> space >> (MacroLit | MacroFunc | expected_expression_error) | |
| 1032 | invalid_macro_definition_error | 1043 | invalid_macro_definition_error |
| 1033 | ); | 1044 | ); |
| 1034 | MacroInPlace = '$' >> space >> "->" >> space >> Body; | 1045 | MacroInPlace = '$' >> space >> "->" >> space >> Body; |
| 1035 | 1046 | ||
| 1036 | NameList = Seperator >> Variable >> *(space >> ',' >> space >> Variable); | 1047 | must_variable = Variable | and_(LuaKeyword >> not_alpha_num) >> keyword_as_identifier_syntax_error | expected_indentifier_error; |
| 1037 | NameOrDestructure = Variable | TableLit | Comprehension | SimpleTable; | 1048 | |
| 1049 | NameList = Seperator >> must_variable >> *(space >> ',' >> space >> must_variable); | ||
| 1050 | NameOrDestructure = Variable | TableLit | Comprehension | SimpleTable | expected_expression_error; | ||
| 1038 | AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure); | 1051 | AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure); |
| 1039 | 1052 | ||
| 1040 | FnArrowBack = '<' >> set("-="); | 1053 | FnArrowBack = '<' >> set("-="); |
| @@ -1074,7 +1087,7 @@ YueParser::YueParser() { | |||
| 1074 | 1087 | ||
| 1075 | SimpleValue = | 1088 | SimpleValue = |
| 1076 | TableLit | ConstValue | If | Switch | Try | With | | 1089 | TableLit | ConstValue | If | Switch | Try | With | |
| 1077 | ClassDecl | ForEach | For | While | Repeat | Do | | 1090 | ClassDecl | For | While | Repeat | Do | |
| 1078 | UnaryValue | TblComprehension | Comprehension | | 1091 | UnaryValue | TblComprehension | Comprehension | |
| 1079 | FunLit | Num | VarArg; | 1092 | FunLit | Num | VarArg; |
| 1080 | 1093 | ||
| @@ -1085,10 +1098,10 @@ YueParser::YueParser() { | |||
| 1085 | 1098 | ||
| 1086 | ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign; | 1099 | ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign; |
| 1087 | 1100 | ||
| 1088 | StatementAppendix = (IfLine | WhileLine | CompInner) >> space; | 1101 | StatementAppendix = (IfLine | WhileLine | CompFor) >> space; |
| 1089 | Statement = | 1102 | Statement = |
| 1090 | ( | 1103 | ( |
| 1091 | Import | While | Repeat | For | ForEach | | 1104 | Import | While | Repeat | For | |
| 1092 | Return | Local | Global | Export | Macro | | 1105 | Return | Local | Global | Export | Macro | |
| 1093 | MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending | | 1106 | MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending | |
| 1094 | LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign | | 1107 | LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign | |
| @@ -1133,7 +1146,9 @@ YueParser::YueParser() { | |||
| 1133 | BlockEnd = Block >> plain_white >> stop; | 1146 | BlockEnd = Block >> plain_white >> stop; |
| 1134 | File = -shebang >> -Block >> plain_white >> stop; | 1147 | File = -shebang >> -Block >> plain_white >> stop; |
| 1135 | 1148 | ||
| 1136 | lax_line = advance_match >> ensure(*(not_(stop) >> any()), pop_indent) | line >> and_(stop) | check_indent_match >> *(not_(stop) >> any()); | 1149 | lax_line = advance_match >> ensure(*(not_(stop) >> any()), pop_indent) | |
| 1150 | line >> and_(stop) | | ||
| 1151 | check_indent_match >> *(not_(stop) >> any()); | ||
| 1137 | } | 1152 | } |
| 1138 | // clang-format on | 1153 | // clang-format on |
| 1139 | 1154 | ||
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 3a726c3..24ae490 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
| @@ -178,9 +178,15 @@ private: | |||
| 178 | NONE_AST_RULE(invalid_with_syntax_error); | 178 | NONE_AST_RULE(invalid_with_syntax_error); |
| 179 | NONE_AST_RULE(invalid_try_syntax_error); | 179 | NONE_AST_RULE(invalid_try_syntax_error); |
| 180 | NONE_AST_RULE(keyword_as_identifier_syntax_error); | 180 | NONE_AST_RULE(keyword_as_identifier_syntax_error); |
| 181 | NONE_AST_RULE(check_keyword_as_identifier); | ||
| 182 | NONE_AST_RULE(invalid_number_literal_error); | 181 | NONE_AST_RULE(invalid_number_literal_error); |
| 183 | NONE_AST_RULE(invalid_import_literal_error); | 182 | NONE_AST_RULE(invalid_import_literal_error); |
| 183 | NONE_AST_RULE(expected_indentifier_error); | ||
| 184 | |||
| 185 | NONE_AST_RULE(must_exp); | ||
| 186 | NONE_AST_RULE(must_unary_exp); | ||
| 187 | NONE_AST_RULE(must_variable); | ||
| 188 | NONE_AST_RULE(end_braces_expression); | ||
| 189 | NONE_AST_RULE(end_brackets_expression); | ||
| 184 | 190 | ||
| 185 | NONE_AST_RULE(inc_exp_level); | 191 | NONE_AST_RULE(inc_exp_level); |
| 186 | NONE_AST_RULE(dec_exp_level); | 192 | NONE_AST_RULE(dec_exp_level); |
| @@ -290,7 +296,6 @@ private: | |||
| 290 | NONE_AST_RULE(table_value); | 296 | NONE_AST_RULE(table_value); |
| 291 | NONE_AST_RULE(table_lit_lines); | 297 | NONE_AST_RULE(table_lit_lines); |
| 292 | NONE_AST_RULE(table_lit_line); | 298 | NONE_AST_RULE(table_lit_line); |
| 293 | NONE_AST_RULE(table_value_list); | ||
| 294 | NONE_AST_RULE(table_block_inner); | 299 | NONE_AST_RULE(table_block_inner); |
| 295 | NONE_AST_RULE(class_line); | 300 | NONE_AST_RULE(class_line); |
| 296 | NONE_AST_RULE(key_value_line); | 301 | NONE_AST_RULE(key_value_line); |
| @@ -306,8 +311,6 @@ private: | |||
| 306 | NONE_AST_RULE(expo_value); | 311 | NONE_AST_RULE(expo_value); |
| 307 | NONE_AST_RULE(expo_exp); | 312 | NONE_AST_RULE(expo_exp); |
| 308 | NONE_AST_RULE(exp_not_tab); | 313 | NONE_AST_RULE(exp_not_tab); |
| 309 | NONE_AST_RULE(must_exp); | ||
| 310 | NONE_AST_RULE(must_unary_exp); | ||
| 311 | NONE_AST_RULE(local_const_item); | 314 | NONE_AST_RULE(local_const_item); |
| 312 | NONE_AST_RULE(comment_line); | 315 | NONE_AST_RULE(comment_line); |
| 313 | NONE_AST_RULE(yue_line_comment); | 316 | NONE_AST_RULE(yue_line_comment); |
| @@ -370,6 +373,7 @@ private: | |||
| 370 | AST_RULE(Repeat); | 373 | AST_RULE(Repeat); |
| 371 | AST_RULE(ForStepValue); | 374 | AST_RULE(ForStepValue); |
| 372 | AST_RULE(For); | 375 | AST_RULE(For); |
| 376 | AST_RULE(ForNum); | ||
| 373 | AST_RULE(ForEach); | 377 | AST_RULE(ForEach); |
| 374 | AST_RULE(Do); | 378 | AST_RULE(Do); |
| 375 | AST_RULE(CatchBlock); | 379 | AST_RULE(CatchBlock); |
| @@ -379,8 +383,8 @@ private: | |||
| 379 | AST_RULE(TblComprehension); | 383 | AST_RULE(TblComprehension); |
| 380 | AST_RULE(StarExp); | 384 | AST_RULE(StarExp); |
| 381 | AST_RULE(CompForEach); | 385 | AST_RULE(CompForEach); |
| 386 | AST_RULE(CompForNum); | ||
| 382 | AST_RULE(CompFor); | 387 | AST_RULE(CompFor); |
| 383 | AST_RULE(CompInner); | ||
| 384 | AST_RULE(Assign); | 388 | AST_RULE(Assign); |
| 385 | AST_RULE(UpdateOp); | 389 | AST_RULE(UpdateOp); |
| 386 | AST_RULE(Update); | 390 | AST_RULE(Update); |
