aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2026-01-19 17:11:31 +0800
committerLi Jin <dragon-fly@qq.com>2026-01-19 17:11:31 +0800
commitccfe66f87663e10603e453f02894bb82dd23c93b (patch)
tree78f90066a182978bd74218440d13bd3a4dd1d269 /src
parent8a01e9c4ec201ad7079f6863c9236851d162b864 (diff)
downloadyuescript-ccfe66f87663e10603e453f02894bb82dd23c93b.tar.gz
yuescript-ccfe66f87663e10603e453f02894bb82dd23c93b.tar.bz2
yuescript-ccfe66f87663e10603e453f02894bb82dd23c93b.zip
Made `;` work as statements separator.
Diffstat (limited to 'src')
-rw-r--r--src/yue.cpp2
-rw-r--r--src/yuescript/yue_ast.cpp7
-rw-r--r--src/yuescript/yue_ast.h16
-rw-r--r--src/yuescript/yue_compiler.cpp137
-rw-r--r--src/yuescript/yue_parser.cpp35
-rw-r--r--src/yuescript/yue_parser.h2
6 files changed, 71 insertions, 128 deletions
diff --git a/src/yue.cpp b/src/yue.cpp
index b93f75e..2722c55 100644
--- a/src/yue.cpp
+++ b/src/yue.cpp
@@ -341,7 +341,7 @@ int main(int narg, const char** args) {
341 " -- Read from standard in, print to standard out\n" 341 " -- Read from standard in, print to standard out\n"
342 " (Must be first and only argument)\n\n" 342 " (Must be first and only argument)\n\n"
343 " --target=version Specify the Lua version that codes will be generated to\n" 343 " --target=version Specify the Lua version that codes will be generated to\n"
344 " (version can only be 5.1, 5.2, 5.3 or 5.4)\n" 344 " (version can only be 5.1 to 5.5)\n"
345 " --path=path_str Append an extra Lua search path string to package.path\n\n" 345 " --path=path_str Append an extra Lua search path string to package.path\n\n"
346 " Execute without options to enter REPL, type symbol '$'\n" 346 " Execute without options to enter REPL, type symbol '$'\n"
347 " in a single line to start/stop multi-line mode\n" 347 " in a single line to start/stop multi-line mode\n"
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp
index c9fd23f..bcea4d5 100644
--- a/src/yuescript/yue_ast.cpp
+++ b/src/yuescript/yue_ast.cpp
@@ -370,13 +370,6 @@ std::string PipeBody_t::to_string(void* ud) const {
370 } 370 }
371 return join(temp, "\n"sv); 371 return join(temp, "\n"sv);
372} 372}
373std::string ExpListLow_t::to_string(void* ud) const {
374 str_list temp;
375 for (auto exp : exprs.objects()) {
376 temp.emplace_back(exp->to_string(ud));
377 }
378 return join(temp, "; "sv);
379}
380std::string ExpList_t::to_string(void* ud) const { 373std::string ExpList_t::to_string(void* ud) const {
381 str_list temp; 374 str_list temp;
382 for (auto exp : exprs.objects()) { 375 for (auto exp : exprs.objects()) {
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index af2355a..5043526 100644
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -50,7 +50,7 @@ std::string_view ast_name() { return {}; }
50// clang-format off 50// clang-format off
51 51
52namespace yue { 52namespace yue {
53class ExpListLow_t; 53class ExpList_t;
54class TableBlock_t; 54class TableBlock_t;
55class SimpleTable_t; 55class SimpleTable_t;
56class TableLit_t; 56class TableLit_t;
@@ -156,7 +156,7 @@ AST_END(NameList)
156 156
157AST_NODE(LocalValues) 157AST_NODE(LocalValues)
158 ast_ptr<true, NameList_t> nameList; 158 ast_ptr<true, NameList_t> nameList;
159 ast_sel<false, TableBlock_t, ExpListLow_t> valueList; 159 ast_sel<false, TableBlock_t, ExpList_t> valueList;
160 AST_MEMBER(LocalValues, &nameList, &valueList) 160 AST_MEMBER(LocalValues, &nameList, &valueList)
161AST_END(LocalValues) 161AST_END(LocalValues)
162 162
@@ -273,12 +273,6 @@ AST_NODE(Backcall)
273 AST_MEMBER(Backcall, &argsDef, &arrow, &value) 273 AST_MEMBER(Backcall, &argsDef, &arrow, &value)
274AST_END(Backcall) 274AST_END(Backcall)
275 275
276AST_NODE(ExpListLow)
277 ast_ptr<true, Seperator_t> sep;
278 ast_list<true, Exp_t> exprs;
279 AST_MEMBER(ExpListLow, &sep, &exprs)
280AST_END(ExpListLow)
281
282AST_NODE(ExpList) 276AST_NODE(ExpList)
283 ast_ptr<true, Seperator_t> sep; 277 ast_ptr<true, Seperator_t> sep;
284 ast_list<true, Exp_t> exprs; 278 ast_list<true, Exp_t> exprs;
@@ -290,7 +284,7 @@ AST_END(ExpList)
290AST_NODE(Return) 284AST_NODE(Return)
291 bool allowBlockMacroReturn = false; 285 bool allowBlockMacroReturn = false;
292 bool explicitReturn = true; 286 bool explicitReturn = true;
293 ast_sel<false, TableBlock_t, ExpListLow_t> valueList; 287 ast_sel<false, TableBlock_t, ExpList_t> valueList;
294 AST_MEMBER(Return, &valueList) 288 AST_MEMBER(Return, &valueList)
295AST_END(Return) 289AST_END(Return)
296 290
@@ -764,7 +758,7 @@ AST_END(ClassDecl)
764 758
765AST_NODE(GlobalValues) 759AST_NODE(GlobalValues)
766 ast_ptr<true, NameList_t> nameList; 760 ast_ptr<true, NameList_t> nameList;
767 ast_sel<false, TableBlock_t, ExpListLow_t> valueList; 761 ast_sel<false, TableBlock_t, ExpList_t> valueList;
768 AST_MEMBER(GlobalValues, &nameList, &valueList) 762 AST_MEMBER(GlobalValues, &nameList, &valueList)
769AST_END(GlobalValues) 763AST_END(GlobalValues)
770 764
@@ -819,7 +813,7 @@ AST_END(FnArrow)
819 813
820AST_NODE(FunLit) 814AST_NODE(FunLit)
821 ast_ptr<false, FnArgsDef_t> argsDef; 815 ast_ptr<false, FnArgsDef_t> argsDef;
822 ast_sel<false, ExpListLow_t, DefaultValue_t> defaultReturn; 816 ast_sel<false, ExpList_t, DefaultValue_t> defaultReturn;
823 ast_ptr<true, FnArrow_t> arrow; 817 ast_ptr<true, FnArrow_t> arrow;
824 ast_ptr<false, Body_t> body; 818 ast_ptr<false, Body_t> body;
825 bool noRecursion = false; 819 bool noRecursion = false;
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index a2d49af..c7802b6 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.31.1"sv; 81const std::string_view version = "0.32.0"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 {
@@ -1057,13 +1057,6 @@ private:
1057 } 1057 }
1058 break; 1058 break;
1059 } 1059 }
1060 case id<ExpListLow_t>(): {
1061 auto expList = static_cast<ExpListLow_t*>(item);
1062 if (expList->exprs.size() == 1) {
1063 exp = static_cast<Exp_t*>(expList->exprs.front());
1064 }
1065 break;
1066 }
1067 case id<SwitchList_t>(): { 1060 case id<SwitchList_t>(): {
1068 auto expList = static_cast<SwitchList_t*>(item); 1061 auto expList = static_cast<SwitchList_t*>(item);
1069 if (expList->exprs.size() == 1) { 1062 if (expList->exprs.size() == 1) {
@@ -1092,12 +1085,12 @@ private:
1092 return nullptr; 1085 return nullptr;
1093 } 1086 }
1094 1087
1095 Value_t* singleValueFrom(ast_node* item) const { 1088 Value_t* singleValueFrom(ast_node* item, bool forceUnparened = false) const {
1096 if (auto unary = singleUnaryExpFrom(item)) { 1089 if (auto unary = singleUnaryExpFrom(item)) {
1097 if (unary->ops.empty()) { 1090 if (unary->ops.empty()) {
1098 Value_t* value = static_cast<Value_t*>(unary->expos.back()); 1091 Value_t* value = static_cast<Value_t*>(unary->expos.back());
1099 if (auto chain = ast_cast<ChainValue_t>(value->item); chain && chain->items.size() == 1) { 1092 if (auto chain = ast_cast<ChainValue_t>(value->item); chain && chain->items.size() == 1) {
1100 if (auto parens = chain->get_by_path<Callable_t, Parens_t>(); parens && parens->extra) { 1093 if (auto parens = chain->get_by_path<Callable_t, Parens_t>(); parens && (forceUnparened || parens->extra)) {
1101 if (auto insideValue = singleValueFrom(parens->expr)) { 1094 if (auto insideValue = singleValueFrom(parens->expr)) {
1102 return insideValue; 1095 return insideValue;
1103 } 1096 }
@@ -1157,6 +1150,22 @@ private:
1157 return exp; 1150 return exp;
1158 } 1151 }
1159 1152
1153 ast_ptr<false, Return_t> newReturn(Exp_t* value) {
1154 auto returnNode = value->new_ptr<Return_t>();
1155 returnNode->explicitReturn = false;
1156 auto expList = value->new_ptr<ExpList_t>();
1157 expList->exprs.push_back(value);
1158 returnNode->valueList.set(expList);
1159 return returnNode;
1160 }
1161
1162 ast_ptr<false, Return_t> newReturn(ExpList_t* valueList) {
1163 auto returnNode = valueList->new_ptr<Return_t>();
1164 returnNode->explicitReturn = false;
1165 returnNode->valueList.set(valueList);
1166 return returnNode;
1167 }
1168
1160 SimpleValue_t* simpleSingleValueFrom(ast_node* node) const { 1169 SimpleValue_t* simpleSingleValueFrom(ast_node* node) const {
1161 auto value = singleValueFrom(node); 1170 auto value = singleValueFrom(node);
1162 if (value && value->item.is<SimpleValue_t>()) { 1171 if (value && value->item.is<SimpleValue_t>()) {
@@ -1264,7 +1273,7 @@ private:
1264 } 1273 }
1265 case id<Local_t>(): { 1274 case id<Local_t>(): {
1266 if (auto localValues = static_cast<Local_t*>(stmt->content.get())->item.as<LocalValues_t>()) { 1275 if (auto localValues = static_cast<Local_t*>(stmt->content.get())->item.as<LocalValues_t>()) {
1267 if (auto expList = localValues->valueList.as<ExpListLow_t>()) { 1276 if (auto expList = localValues->valueList.as<ExpList_t>()) {
1268 return static_cast<Exp_t*>(expList->exprs.back()); 1277 return static_cast<Exp_t*>(expList->exprs.back());
1269 } 1278 }
1270 } 1279 }
@@ -1272,7 +1281,7 @@ private:
1272 } 1281 }
1273 case id<Global_t>(): { 1282 case id<Global_t>(): {
1274 if (auto globalValues = static_cast<Global_t*>(stmt->content.get())->item.as<GlobalValues_t>()) { 1283 if (auto globalValues = static_cast<Global_t*>(stmt->content.get())->item.as<GlobalValues_t>()) {
1275 if (auto expList = globalValues->valueList.as<ExpListLow_t>()) { 1284 if (auto expList = globalValues->valueList.as<ExpList_t>()) {
1276 return static_cast<Exp_t*>(expList->exprs.back()); 1285 return static_cast<Exp_t*>(expList->exprs.back());
1277 } 1286 }
1278 } 1287 }
@@ -3717,7 +3726,7 @@ private:
3717 bool oneLined = defs.size() == expList->exprs.objects().size(); 3726 bool oneLined = defs.size() == expList->exprs.objects().size();
3718 bool nonRecursionFunLit = false; 3727 bool nonRecursionFunLit = false;
3719 for (auto val : assign->values.objects()) { 3728 for (auto val : assign->values.objects()) {
3720 if (auto value = singleValueFrom(val)) { 3729 if (auto value = singleValueFrom(val, true)) {
3721 if (auto spValue = value->item.as<SimpleValue_t>()) { 3730 if (auto spValue = value->item.as<SimpleValue_t>()) {
3722 if (auto funLit = spValue->value.as<FunLit_t>()) { 3731 if (auto funLit = spValue->value.as<FunLit_t>()) {
3723 if (funLit->noRecursion) { 3732 if (funLit->noRecursion) {
@@ -3981,14 +3990,6 @@ private:
3981 out.push_back(join(temp, ", "sv)); 3990 out.push_back(join(temp, ", "sv));
3982 } 3991 }
3983 3992
3984 void transformExpListLow(ExpListLow_t* expListLow, str_list& out) {
3985 str_list temp;
3986 for (auto exp : expListLow->exprs.objects()) {
3987 transformExp(static_cast<Exp_t*>(exp), temp, ExpUsage::Closure);
3988 }
3989 out.push_back(join(temp, ", "sv));
3990 }
3991
3992 void transform_pipe_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 3993 void transform_pipe_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
3993 if (values.size() == 1 && usage == ExpUsage::Closure) { 3994 if (values.size() == 1 && usage == ExpUsage::Closure) {
3994 transformUnaryExp(static_cast<UnaryExp_t*>(values.front()), out, ExpUsage::Closure); 3995 transformUnaryExp(static_cast<UnaryExp_t*>(values.front()), out, ExpUsage::Closure);
@@ -4060,11 +4061,7 @@ private:
4060 return; 4061 return;
4061 } 4062 }
4062 case ExpUsage::Return: { 4063 case ExpUsage::Return: {
4063 auto ret = x->new_ptr<Return_t>(); 4064 auto ret = newReturn(arg);
4064 ret->explicitReturn = false;
4065 auto expListLow = x->new_ptr<ExpListLow_t>();
4066 expListLow->exprs.push_back(arg);
4067 ret->valueList.set(expListLow);
4068 transformReturn(ret, out); 4065 transformReturn(ret, out);
4069 return; 4066 return;
4070 } 4067 }
@@ -4289,11 +4286,7 @@ private:
4289 break; 4286 break;
4290 } 4287 }
4291 case ExpUsage::Return: { 4288 case ExpUsage::Return: {
4292 auto expListLow = exp->new_ptr<ExpListLow_t>(); 4289 auto returnNode = newReturn(e);
4293 expListLow->exprs.push_back(e);
4294 auto returnNode = exp->new_ptr<Return_t>();
4295 returnNode->explicitReturn = false;
4296 returnNode->valueList.set(expListLow);
4297 transformReturn(returnNode, out); 4290 transformReturn(returnNode, out);
4298 break; 4291 break;
4299 } 4292 }
@@ -4470,11 +4463,7 @@ private:
4470 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false, blockRewrite); 4463 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false, blockRewrite);
4471 } 4464 }
4472 } 4465 }
4473 auto returnNode = exp->new_ptr<Return_t>(); 4466 auto returnNode = newReturn(exp);
4474 returnNode->explicitReturn = false;
4475 auto returnList = exp->new_ptr<ExpListLow_t>();
4476 returnList->exprs.push_back(exp);
4477 returnNode->valueList.set(returnList);
4478 auto stmt = exp->new_ptr<Statement_t>(); 4467 auto stmt = exp->new_ptr<Statement_t>();
4479 stmt->content.set(returnNode); 4468 stmt->content.set(returnNode);
4480 block->statementOrComments.push_back(stmt); 4469 block->statementOrComments.push_back(stmt);
@@ -4561,12 +4550,8 @@ private:
4561 _buf << indent(1) << "return "s << objVar << nl(x); 4550 _buf << indent(1) << "return "s << objVar << nl(x);
4562 _buf << indent() << "else"s << nl(x); 4551 _buf << indent() << "else"s << nl(x);
4563 temp.push_back(clearBuf()); 4552 temp.push_back(clearBuf());
4564 auto ret = x->new_ptr<Return_t>();
4565 ret->explicitReturn = false;
4566 auto retList = x->new_ptr<ExpListLow_t>();
4567 retList->exprs.push_back(exp->nilCoalesed);
4568 ret->valueList.set(retList);
4569 incIndentOffset(); 4553 incIndentOffset();
4554 auto ret = newReturn(exp->nilCoalesed);
4570 transformReturn(ret, temp); 4555 transformReturn(ret, temp);
4571 decIndentOffset(); 4556 decIndentOffset();
4572 temp.push_back(indent() + "end"s + nl(x)); 4557 temp.push_back(indent() + "end"s + nl(x));
@@ -4727,10 +4712,8 @@ private:
4727 default: YUEE("AST node mismatch", content); break; 4712 default: YUEE("AST node mismatch", content); break;
4728 } 4713 }
4729 } 4714 }
4730 if (funLit->defaultReturn.is<ExpListLow_t>()) { 4715 if (auto defaultReturn = funLit->defaultReturn.as<ExpList_t>()) {
4731 auto returnNode = newBlock->new_ptr<Return_t>(); 4716 auto returnNode = newReturn(defaultReturn);
4732 returnNode->explicitReturn = false;
4733 returnNode->valueList.set(funLit->defaultReturn);
4734 auto stmt = newBlock->new_ptr<Statement_t>(); 4717 auto stmt = newBlock->new_ptr<Statement_t>();
4735 stmt->content.set(returnNode); 4718 stmt->content.set(returnNode);
4736 newBlock->statementOrComments.push_back(stmt); 4719 newBlock->statementOrComments.push_back(stmt);
@@ -5264,11 +5247,9 @@ private:
5264 auto expList = expListFrom(last); 5247 auto expList = expListFrom(last);
5265 BREAK_IF(!expList); 5248 BREAK_IF(!expList);
5266 BREAK_IF(last->appendix && !last->appendix->item.is<IfLine_t>()); 5249 BREAK_IF(last->appendix && !last->appendix->item.is<IfLine_t>());
5267 auto expListLow = x->new_ptr<ExpListLow_t>();
5268 expListLow->exprs.dup(expList->exprs);
5269 auto returnNode = x->new_ptr<Return_t>(); 5250 auto returnNode = x->new_ptr<Return_t>();
5270 returnNode->explicitReturn = false; 5251 returnNode->explicitReturn = false;
5271 returnNode->valueList.set(expListLow); 5252 returnNode->valueList.set(expList);
5272 returnNode->allowBlockMacroReturn = true; 5253 returnNode->allowBlockMacroReturn = true;
5273 last->content.set(returnNode); 5254 last->content.set(returnNode);
5274 BLOCK_END 5255 BLOCK_END
@@ -5713,7 +5694,7 @@ private:
5713 if (!target) target = returnNode; 5694 if (!target) target = returnNode;
5714 throw CompileError("explicit return statement is not allowed in this context"sv, target); 5695 throw CompileError("explicit return statement is not allowed in this context"sv, target);
5715 } 5696 }
5716 if (auto valueList = returnNode->valueList.as<ExpListLow_t>()) { 5697 if (auto valueList = returnNode->valueList.as<ExpList_t>()) {
5717 if (valueList->exprs.size() == 1) { 5698 if (valueList->exprs.size() == 1) {
5718 auto exp = static_cast<Exp_t*>(valueList->exprs.back()); 5699 auto exp = static_cast<Exp_t*>(valueList->exprs.back());
5719 if (isPurePipeChain(exp)) { 5700 if (isPurePipeChain(exp)) {
@@ -5783,7 +5764,7 @@ private:
5783 return; 5764 return;
5784 } else { 5765 } else {
5785 str_list temp; 5766 str_list temp;
5786 transformExpListLow(valueList, temp); 5767 transformExpList(valueList, temp);
5787 out.push_back(indent() + "return "s + temp.back() + nl(returnNode)); 5768 out.push_back(indent() + "return "s + temp.back() + nl(returnNode));
5788 } 5769 }
5789 } else if (auto tableBlock = returnNode->valueList.as<TableBlock_t>()) { 5770 } else if (auto tableBlock = returnNode->valueList.as<TableBlock_t>()) {
@@ -6250,11 +6231,7 @@ private:
6250 case ExpUsage::Return: 6231 case ExpUsage::Return:
6251 case ExpUsage::Closure: { 6232 case ExpUsage::Closure: {
6252 auto exp = newExp(partTwo, x); 6233 auto exp = newExp(partTwo, x);
6253 auto ret = x->new_ptr<Return_t>(); 6234 auto ret = newReturn(exp);
6254 ret->explicitReturn = false;
6255 auto expListLow = x->new_ptr<ExpListLow_t>();
6256 expListLow->exprs.push_back(exp);
6257 ret->valueList.set(expListLow);
6258 transformReturn(ret, temp); 6235 transformReturn(ret, temp);
6259 break; 6236 break;
6260 } 6237 }
@@ -6349,11 +6326,7 @@ private:
6349 switch (usage) { 6326 switch (usage) {
6350 case ExpUsage::Closure: 6327 case ExpUsage::Closure:
6351 case ExpUsage::Return: { 6328 case ExpUsage::Return: {
6352 auto returnNode = x->new_ptr<Return_t>(); 6329 auto returnNode = newReturn(funLit);
6353 returnNode->explicitReturn = false;
6354 auto expListLow = x->new_ptr<ExpListLow_t>();
6355 expListLow->exprs.push_back(funLit);
6356 returnNode->valueList.set(expListLow);
6357 transformReturn(returnNode, temp); 6330 transformReturn(returnNode, temp);
6358 break; 6331 break;
6359 } 6332 }
@@ -6484,11 +6457,7 @@ private:
6484 } 6457 }
6485 switch (usage) { 6458 switch (usage) {
6486 case ExpUsage::Closure: { 6459 case ExpUsage::Closure: {
6487 auto returnNode = x->new_ptr<Return_t>(); 6460 auto returnNode = newReturn(newChainExp);
6488 returnNode->explicitReturn = false;
6489 auto values = x->new_ptr<ExpListLow_t>();
6490 values->exprs.push_back(newChainExp);
6491 returnNode->valueList.set(values);
6492 transformReturn(returnNode, temp); 6461 transformReturn(returnNode, temp);
6493 popScope(); 6462 popScope();
6494 *funcStart = anonFuncStart() + nl(x); 6463 *funcStart = anonFuncStart() + nl(x);
@@ -6498,11 +6467,7 @@ private:
6498 break; 6467 break;
6499 } 6468 }
6500 case ExpUsage::Return: { 6469 case ExpUsage::Return: {
6501 auto returnNode = x->new_ptr<Return_t>(); 6470 auto returnNode = newReturn(newChainExp);
6502 returnNode->explicitReturn = false;
6503 auto values = x->new_ptr<ExpListLow_t>();
6504 values->exprs.push_back(newChainExp);
6505 returnNode->valueList.set(values);
6506 transformReturn(returnNode, temp); 6471 transformReturn(returnNode, temp);
6507 break; 6472 break;
6508 } 6473 }
@@ -7361,11 +7326,7 @@ private:
7361 break; 7326 break;
7362 } 7327 }
7363 case ExpUsage::Return: { 7328 case ExpUsage::Return: {
7364 auto expListLow = x->new_ptr<ExpListLow_t>(); 7329 auto returnNode = newReturn(node.to<Exp_t>());
7365 expListLow->exprs.push_back(node);
7366 auto returnNode = x->new_ptr<Return_t>();
7367 returnNode->explicitReturn = false;
7368 returnNode->valueList.set(expListLow);
7369 transformReturn(returnNode, out); 7330 transformReturn(returnNode, out);
7370 break; 7331 break;
7371 } 7332 }
@@ -8377,11 +8338,7 @@ private:
8377 auto simpleValue = x->new_ptr<SimpleValue_t>(); 8338 auto simpleValue = x->new_ptr<SimpleValue_t>();
8378 simpleValue->value.set(tableLit); 8339 simpleValue->value.set(tableLit);
8379 auto exp = newExp(simpleValue, x); 8340 auto exp = newExp(simpleValue, x);
8380 auto returnNode = x->new_ptr<Return_t>(); 8341 auto returnNode = newReturn(exp);
8381 returnNode->explicitReturn = false;
8382 auto expList = x->new_ptr<ExpListLow_t>();
8383 expList->exprs.push_back(exp);
8384 returnNode->valueList.set(expList);
8385 transformReturn(returnNode, out); 8342 transformReturn(returnNode, out);
8386 break; 8343 break;
8387 } 8344 }
@@ -9190,10 +9147,7 @@ private:
9190 } 9147 }
9191 } else { 9148 } else {
9192 auto accum = transformForNumInner(forNum, temp); 9149 auto accum = transformForNumInner(forNum, temp);
9193 auto returnNode = x->new_ptr<Return_t>(); 9150 auto returnNode = newReturn(toAst<Exp_t>(accum, forNum));
9194 returnNode->explicitReturn = false;
9195 auto expListLow = toAst<ExpListLow_t>(accum, x);
9196 returnNode->valueList.set(expListLow);
9197 transformReturn(returnNode, temp); 9151 transformReturn(returnNode, temp);
9198 } 9152 }
9199 out.push_back(join(temp)); 9153 out.push_back(join(temp));
@@ -9304,10 +9258,7 @@ private:
9304 } 9258 }
9305 } else { 9259 } else {
9306 auto accum = transformForEachInner(forEach, temp); 9260 auto accum = transformForEachInner(forEach, temp);
9307 auto returnNode = x->new_ptr<Return_t>(); 9261 auto returnNode = newReturn(toAst<Exp_t>(accum, forEach));
9308 returnNode->explicitReturn = false;
9309 auto expListLow = toAst<ExpListLow_t>(accum, x);
9310 returnNode->valueList.set(expListLow);
9311 transformReturn(returnNode, temp); 9262 transformReturn(returnNode, temp);
9312 } 9263 }
9313 out.push_back(join(temp)); 9264 out.push_back(join(temp));
@@ -10393,8 +10344,8 @@ private:
10393 auto assignment = x->new_ptr<ExpListAssign_t>(); 10344 auto assignment = x->new_ptr<ExpListAssign_t>();
10394 assignment->expList.set(expList); 10345 assignment->expList.set(expList);
10395 auto assign = x->new_ptr<Assign_t>(); 10346 auto assign = x->new_ptr<Assign_t>();
10396 if (auto expListLow = values->valueList.as<ExpListLow_t>()) { 10347 if (auto expList = values->valueList.as<ExpList_t>()) {
10397 assign->values.dup(expListLow->exprs); 10348 assign->values.dup(expList->exprs);
10398 } else { 10349 } else {
10399 auto tableBlock = values->valueList.to<TableBlock_t>(); 10350 auto tableBlock = values->valueList.to<TableBlock_t>();
10400 assign->values.push_back(tableBlock); 10351 assign->values.push_back(tableBlock);
@@ -11897,8 +11848,8 @@ private:
11897 auto assignment = x->new_ptr<ExpListAssign_t>(); 11848 auto assignment = x->new_ptr<ExpListAssign_t>();
11898 assignment->expList.set(expList); 11849 assignment->expList.set(expList);
11899 auto assign = x->new_ptr<Assign_t>(); 11850 auto assign = x->new_ptr<Assign_t>();
11900 if (auto expListLow = values->valueList.as<ExpListLow_t>()) { 11851 if (auto expList = values->valueList.as<ExpList_t>()) {
11901 assign->values.dup(expListLow->exprs); 11852 assign->values.dup(expList->exprs);
11902 } else { 11853 } else {
11903 auto tableBlock = values->valueList.to<TableBlock_t>(); 11854 auto tableBlock = values->valueList.to<TableBlock_t>();
11904 assign->values.push_back(tableBlock); 11855 assign->values.push_back(tableBlock);
@@ -11906,7 +11857,7 @@ private:
11906 assignment->action.set(assign); 11857 assignment->action.set(assign);
11907 bool oneLined = transformAssignment(assignment, temp); 11858 bool oneLined = transformAssignment(assignment, temp);
11908 for (auto val : assign->values.objects()) { 11859 for (auto val : assign->values.objects()) {
11909 if (auto value = singleValueFrom(val)) { 11860 if (auto value = singleValueFrom(val, true)) {
11910 if (auto spValue = value->item.as<SimpleValue_t>()) { 11861 if (auto spValue = value->item.as<SimpleValue_t>()) {
11911 if (auto funLit = spValue->value.as<FunLit_t>()) { 11862 if (auto funLit = spValue->value.as<FunLit_t>()) {
11912 if (!funLit->noRecursion) { 11863 if (!funLit->noRecursion) {
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index ab1ba7a..b032826 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -393,7 +393,7 @@ YueParser::YueParser() {
393 in_block = space_break >> *(*set(" \t") >> line_break) >> advance_match >> ensure(Block, pop_indent); 393 in_block = space_break >> *(*set(" \t") >> line_break) >> advance_match >> ensure(Block, pop_indent);
394 394
395 LocalFlag = expr('*') | '^'; 395 LocalFlag = expr('*') | '^';
396 LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow | expected_expression_error)); 396 LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpList | expected_expression_error));
397 Local = key("local") >> space >> (LocalFlag | LocalValues | invalid_local_declaration_error); 397 Local = key("local") >> space >> (LocalFlag | LocalValues | invalid_local_declaration_error);
398 398
399 ConstAttrib = key("const"); 399 ConstAttrib = key("const");
@@ -478,7 +478,7 @@ YueParser::YueParser() {
478 Continue = key("continue"); 478 Continue = key("continue");
479 BreakLoop = (Break >> -(space >> Exp) | Continue) >> not_alpha_num; 479 BreakLoop = (Break >> -(space >> Exp) | Continue) >> not_alpha_num;
480 480
481 Return = key("return") >> -(space >> (TableBlock | ExpListLow)); 481 Return = key("return") >> -(space >> (TableBlock | ExpList));
482 482
483 must_exp = Exp | expected_expression_error; 483 must_exp = Exp | expected_expression_error;
484 484
@@ -674,7 +674,7 @@ YueParser::YueParser() {
674 674
675 Assign = '=' >> space >> Seperator >> ( 675 Assign = '=' >> space >> Seperator >> (
676 With | If | Switch | TableBlock | 676 With | If | Switch | TableBlock |
677 (SpreadListExp | Exp) >> *(space >> set(",;") >> space >> (SpreadListExp | Exp)) | 677 (SpreadListExp | Exp) >> *(space >> set(",") >> space >> (SpreadListExp | Exp)) |
678 expected_expression_error 678 expected_expression_error
679 ); 679 );
680 680
@@ -927,7 +927,7 @@ YueParser::YueParser() {
927 -(space >> key("using") >> prevent_indent >> space >> ensure(ExpList | expected_expression_error, pop_indent)) 927 -(space >> key("using") >> prevent_indent >> space >> ensure(ExpList | expected_expression_error, pop_indent))
928 ) >> -ClassBlock; 928 ) >> -ClassBlock;
929 929
930 GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow | expected_expression_error)); 930 GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpList | expected_expression_error));
931 GlobalOp = expr('*') | '^'; 931 GlobalOp = expr('*') | '^';
932 Global = key("global") >> space >> ( 932 Global = key("global") >> space >> (
933 -(ConstAttrib >> space) >> ClassDecl | 933 -(ConstAttrib >> space) >> ClassDecl |
@@ -1056,7 +1056,7 @@ YueParser::YueParser() {
1056 return st->fnArrowAvailable; 1056 return st->fnArrowAvailable;
1057 }) >> -(FnArgsDef >> 1057 }) >> -(FnArgsDef >>
1058 -(':' >> space >> 1058 -(':' >> space >>
1059 disable_fun_lit >> ensure(ExpListLow | DefaultValue, enable_fun_lit) 1059 disable_fun_lit >> ensure(ExpList | DefaultValue, enable_fun_lit)
1060 ) 1060 )
1061 ) >> space >> FnArrow >> -(space >> Body); 1061 ) >> space >> FnArrow >> -(space >> Body);
1062 1062
@@ -1087,7 +1087,6 @@ YueParser::YueParser() {
1087 *(+space_break >> check_indent_match >> space >> pipe_operator >> space >> must_unary_exp); 1087 *(+space_break >> check_indent_match >> space >> pipe_operator >> space >> must_unary_exp);
1088 1088
1089 ExpList = Seperator >> Exp >> *(space >> ',' >> space >> Exp); 1089 ExpList = Seperator >> Exp >> *(space >> ',' >> space >> Exp);
1090 ExpListLow = Seperator >> Exp >> *(space >> set(",;") >> space >> Exp);
1091 1090
1092 arg_line = check_indent_match >> space >> Exp >> *(space >> ',' >> space >> Exp); 1091 arg_line = check_indent_match >> space >> Exp >> *(space >> ',' >> space >> Exp);
1093 arg_block = arg_line >> *(space >> ',' >> space_break >> arg_line) >> pop_indent; 1092 arg_block = arg_line >> *(space >> ',' >> space_break >> arg_line) >> pop_indent;
@@ -1124,17 +1123,18 @@ YueParser::YueParser() {
1124 1123
1125 ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign; 1124 ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign;
1126 1125
1127 StatementAppendix = (IfLine | WhileLine | CompFor) >> space; 1126 StatementAppendix = IfLine | WhileLine | CompFor;
1128 Statement = 1127 Statement = (
1129 ( 1128 (
1130 Import | Export | Global | Macro | MacroInPlace | Label 1129 Import | Export | Global | Macro | MacroInPlace | Label
1131 ) >> space | ( 1130 ) | (
1132 Local | While | Repeat | For | Return | 1131 Local | While | Repeat | For | Return |
1133 BreakLoop | Goto | ShortTabAppending | 1132 BreakLoop | Goto | ShortTabAppending |
1134 LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign | 1133 LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign |
1135 StatementAppendix >> empty_block_error | 1134 StatementAppendix >> empty_block_error |
1136 and_(key("else") | key("elseif") | key("when")) >> dangling_clause_error 1135 and_(key("else") | key("elseif") | key("when")) >> dangling_clause_error
1137 ) >> space >> -StatementAppendix; 1136 ) >> space >> -StatementAppendix
1137 ) >> space;
1138 1138
1139 StatementSep = white >> (set("('\"") | "[[" | "[="); 1139 StatementSep = white >> (set("('\"") | "[[" | "[=");
1140 1140
@@ -1158,15 +1158,20 @@ YueParser::YueParser() {
1158 return false; 1158 return false;
1159 }); 1159 });
1160 1160
1161 is_lax = pl::user(true_(), [](const item_t& item) {
1162 State* st = reinterpret_cast<State*>(item.user_data);
1163 return st->lax;
1164 });
1165
1161 line = *(EmptyLine >> line_break) >> ( 1166 line = *(EmptyLine >> line_break) >> (
1162 check_indent_match >> space >> Statement | 1167 check_indent_match >> space >> Statement >> *(';' >> -(space >> Statement)) |
1163 YueComment | 1168 YueComment |
1164 advance_match >> ensure(space >> (indentation_error | Statement), pop_indent) 1169 advance_match >> ensure(space >> (indentation_error | Statement), pop_indent)
1165 ); 1170 );
1166 Block = Seperator >> (pl::user(true_(), [](const item_t& item) { 1171 Block = Seperator >> (
1167 State* st = reinterpret_cast<State*>(item.user_data); 1172 is_lax >> lax_line >> *(line_break >> lax_line) |
1168 return st->lax; 1173 line >> *(line_break >> line)
1169 }) >> lax_line >> *(line_break >> lax_line) | line >> *(line_break >> line)); 1174 );
1170 1175
1171 shebang = "#!" >> *(not_(stop) >> any_char); 1176 shebang = "#!" >> *(not_(stop) >> any_char);
1172 BlockEnd = Block >> plain_white >> stop; 1177 BlockEnd = Block >> plain_white >> stop;
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index c516ccd..df9f39c 100644
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -319,6 +319,7 @@ private:
319 NONE_AST_RULE(yue_multiline_comment); 319 NONE_AST_RULE(yue_multiline_comment);
320 NONE_AST_RULE(line); 320 NONE_AST_RULE(line);
321 NONE_AST_RULE(shebang); 321 NONE_AST_RULE(shebang);
322 NONE_AST_RULE(is_lax);
322 NONE_AST_RULE(lax_line); 323 NONE_AST_RULE(lax_line);
323 324
324 AST_RULE(Num); 325 AST_RULE(Num);
@@ -361,7 +362,6 @@ private:
361 AST_RULE(Backcall); 362 AST_RULE(Backcall);
362 AST_RULE(SubBackcall); 363 AST_RULE(SubBackcall);
363 AST_RULE(PipeBody); 364 AST_RULE(PipeBody);
364 AST_RULE(ExpListLow);
365 AST_RULE(ExpList); 365 AST_RULE(ExpList);
366 AST_RULE(Return); 366 AST_RULE(Return);
367 AST_RULE(With); 367 AST_RULE(With);