aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--spec/inputs/import.yue2
-rw-r--r--spec/inputs/unicode/import.yue2
-rw-r--r--src/yuescript/yue_ast.cpp11
-rw-r--r--src/yuescript/yue_ast.h37
-rw-r--r--src/yuescript/yue_compiler.cpp181
-rw-r--r--src/yuescript/yue_parser.cpp109
-rw-r--r--src/yuescript/yue_parser.h14
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
25do 25do
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
25do 25do
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 {
594std::string ForStepValue_t::to_string(void* ud) const { 594std::string ForStepValue_t::to_string(void* ud) const {
595 return value->to_string(ud); 595 return value->to_string(ud);
596} 596}
597std::string For_t::to_string(void* ud) const { 597std::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}
636std::string For_t::to_string(void* ud) const {
637 return forLoop->to_string(ud);
638}
636std::string Do_t::to_string(void* ud) const { 639std::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}
786std::string Comprehension_t::to_string(void* ud) const { 789std::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 {
851std::string CompForEach_t::to_string(void* ud) const { 854std::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}
854std::string CompFor_t::to_string(void* ud) const { 857std::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}
861std::string CompInner_t::to_string(void* ud) const { 864std::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;
68class Body_t; 68class Body_t;
69class AssignableNameList_t; 69class AssignableNameList_t;
70class StarExp_t; 70class StarExp_t;
71class CompInner_t; 71class CompFor_t;
72class AssignableChain_t; 72class AssignableChain_t;
73class UnaryExp_t; 73class UnaryExp_t;
74class Parens_t; 74class Parens_t;
@@ -358,14 +358,14 @@ AST_NODE(ForStepValue)
358 AST_MEMBER(ForStepValue, &value) 358 AST_MEMBER(ForStepValue, &value)
359AST_END(ForStepValue) 359AST_END(ForStepValue)
360 360
361AST_NODE(For) 361AST_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)
368AST_END(For) 368AST_END(ForNum)
369 369
370AST_NODE(ForEach) 370AST_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)
375AST_END(ForEach) 375AST_END(ForEach)
376 376
377AST_NODE(For)
378 ast_sel<true, ForEach_t, ForNum_t> forLoop;
379 AST_MEMBER(For, &forLoop)
380AST_END(For)
381
377AST_NODE(Do) 382AST_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
395AST_NODE(Comprehension) 400AST_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)
400AST_END(Comprehension) 405AST_END(Comprehension)
@@ -407,7 +412,7 @@ AST_END(CompValue)
407AST_NODE(TblComprehension) 412AST_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)
412AST_END(TblComprehension) 417AST_END(TblComprehension)
413 418
@@ -422,19 +427,19 @@ AST_NODE(CompForEach)
422 AST_MEMBER(CompForEach, &nameList, &loopValue) 427 AST_MEMBER(CompForEach, &nameList, &loopValue)
423AST_END(CompForEach) 428AST_END(CompForEach)
424 429
425AST_NODE(CompFor) 430AST_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)
431AST_END(CompFor) 436AST_END(CompForNum)
432 437
433AST_NODE(CompInner) 438AST_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)
437AST_END(CompInner) 442AST_END(CompFor)
438 443
439AST_NODE(Assign) 444AST_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)
919AST_END(PipeBody) 924AST_END(PipeBody)
920 925
921AST_NODE(StatementAppendix) 926AST_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)
924AST_END(StatementAppendix) 929AST_END(StatementAppendix)
925 930
@@ -949,7 +954,7 @@ AST_END(ChainAssign)
949 954
950AST_NODE(Statement) 955AST_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
81const std::string_view version = "0.30.2"sv; 81const std::string_view version = "0.30.3"sv;
82const std::string_view extension = "yue"sv; 82const std::string_view extension = "yue"sv;
83 83
84class CompileError : public std::logic_error { 84class 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);