aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-04-25 13:19:26 +0800
committerLi Jin <dragon-fly@qq.com>2022-04-25 13:19:45 +0800
commit10afeaf30bfe03774c12908235520eebf0c192ee (patch)
treeca266b04aaea63ea0710a51708d6ef806008b34e /src
parent249e1de1d32dda2b60b9116c5a4e538475de0192 (diff)
downloadyuescript-10afeaf30bfe03774c12908235520eebf0c192ee.tar.gz
yuescript-10afeaf30bfe03774c12908235520eebf0c192ee.tar.bz2
yuescript-10afeaf30bfe03774c12908235520eebf0c192ee.zip
add spread syntax support for table block. fix a gcc compiler issue. update doc.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/yuescript/yue_ast.h6
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp351
-rwxr-xr-xsrc/yuescript/yue_parser.cpp9
-rwxr-xr-xsrc/yuescript/yue_parser.h1
4 files changed, 227 insertions, 140 deletions
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index ed6f7d2..06896b8 100755
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -221,9 +221,11 @@ AST_NODE(ExpList)
221 AST_MEMBER(ExpList, &sep, &exprs) 221 AST_MEMBER(ExpList, &sep, &exprs)
222AST_END(ExpList) 222AST_END(ExpList)
223 223
224class TableBlock_t;
225
224AST_NODE(Return) 226AST_NODE(Return)
225 bool allowBlockMacroReturn = false; 227 bool allowBlockMacroReturn = false;
226 ast_ptr<false, ExpListLow_t> valueList; 228 ast_sel<false, TableBlock_t, ExpListLow_t> valueList;
227 AST_MEMBER(Return, &valueList) 229 AST_MEMBER(Return, &valueList)
228AST_END(Return) 230AST_END(Return)
229 231
@@ -628,7 +630,7 @@ AST_END(TableBlockIndent)
628 630
629AST_NODE(TableBlock) 631AST_NODE(TableBlock)
630 ast_ptr<true, Seperator_t> sep; 632 ast_ptr<true, Seperator_t> sep;
631 ast_sel_list<false, variable_pair_t, normal_pair_t, TableBlockIndent_t, Exp_t, TableBlock_t, default_pair_t, 633 ast_sel_list<false, variable_pair_t, normal_pair_t, TableBlockIndent_t, Exp_t, TableBlock_t, SpreadExp_t, default_pair_t,
632 meta_variable_pair_t, meta_normal_pair_t, meta_default_pair_t> values; 634 meta_variable_pair_t, meta_normal_pair_t, meta_default_pair_t> values;
633 AST_MEMBER(TableBlock, &sep, &values) 635 AST_MEMBER(TableBlock, &sep, &values)
634AST_END(TableBlock) 636AST_END(TableBlock)
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 6a0fba6..476494e 100755
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -60,7 +60,7 @@ using namespace parserlib;
60 60
61typedef std::list<std::string> str_list; 61typedef std::list<std::string> str_list;
62 62
63const std::string_view version = "0.10.14"sv; 63const std::string_view version = "0.10.15"sv;
64const std::string_view extension = "yue"sv; 64const std::string_view extension = "yue"sv;
65 65
66class YueCompilerImpl { 66class YueCompilerImpl {
@@ -1355,10 +1355,20 @@ private:
1355 } 1355 }
1356 case id<TableLit_t>(): { 1356 case id<TableLit_t>(): {
1357 auto tableLit = static_cast<TableLit_t*>(value); 1357 auto tableLit = static_cast<TableLit_t*>(value);
1358 if (hasSpreadExp(tableLit)) { 1358 if (hasSpreadExp(tableLit->values.objects())) {
1359 auto expList = assignment->expList.get(); 1359 auto expList = assignment->expList.get();
1360 std::string preDefine = getPredefine(assignment); 1360 std::string preDefine = getPredefine(assignment);
1361 transformSpreadTableLit(tableLit, out, ExpUsage::Assignment, expList); 1361 transformSpreadTable(tableLit->values.objects(), out, ExpUsage::Assignment, expList);
1362 out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment));
1363 return;
1364 }
1365 }
1366 case id<TableBlock_t>(): {
1367 auto tableBlock = static_cast<TableBlock_t*>(value);
1368 if (hasSpreadExp(tableBlock->values.objects())) {
1369 auto expList = assignment->expList.get();
1370 std::string preDefine = getPredefine(assignment);
1371 transformSpreadTable(tableBlock->values.objects(), out, ExpUsage::Assignment, expList);
1362 out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment)); 1372 out.back().insert(0, preDefine.empty() ? Empty : preDefine + nll(assignment));
1363 return; 1373 return;
1364 } 1374 }
@@ -3239,7 +3249,7 @@ private:
3239 if (!target) target = returnNode; 3249 if (!target) target = returnNode;
3240 throw std::logic_error(_info.errorMessage("illegal return statement here"sv, target)); 3250 throw std::logic_error(_info.errorMessage("illegal return statement here"sv, target));
3241 } 3251 }
3242 if (auto valueList = returnNode->valueList.get()) { 3252 if (auto valueList = returnNode->valueList.as<ExpListLow_t>()) {
3243 if (valueList->exprs.size() == 1) { 3253 if (valueList->exprs.size() == 1) {
3244 auto exp = static_cast<Exp_t*>(valueList->exprs.back()); 3254 auto exp = static_cast<Exp_t*>(valueList->exprs.back());
3245 if (isPureBackcall(exp)) { 3255 if (isPureBackcall(exp)) {
@@ -3286,8 +3296,8 @@ private:
3286 return; 3296 return;
3287 case id<TableLit_t>(): { 3297 case id<TableLit_t>(): {
3288 auto tableLit = static_cast<TableLit_t*>(value); 3298 auto tableLit = static_cast<TableLit_t*>(value);
3289 if (hasSpreadExp(tableLit)) { 3299 if (hasSpreadExp(tableLit->values.objects())) {
3290 transformSpreadTableLit(tableLit, out, ExpUsage::Return); 3300 transformSpreadTable(tableLit->values.objects(), out, ExpUsage::Return);
3291 return; 3301 return;
3292 } 3302 }
3293 } 3303 }
@@ -3306,6 +3316,14 @@ private:
3306 transformExpListLow(valueList, temp); 3316 transformExpListLow(valueList, temp);
3307 out.push_back(indent() + "return "s + temp.back() + nlr(returnNode)); 3317 out.push_back(indent() + "return "s + temp.back() + nlr(returnNode));
3308 } 3318 }
3319 } else if (auto tableBlock = returnNode->valueList.as<TableBlock_t>()) {
3320 const auto& values = tableBlock->values.objects();
3321 if (hasSpreadExp(values)) {
3322 transformSpreadTable(values, out, ExpUsage::Return);
3323 } else {
3324 transformTable(values, out);
3325 out.back() = indent() + "return "s + out.back() + nlr(returnNode);
3326 }
3309 } else { 3327 } else {
3310 out.push_back(indent() + "return"s + nll(returnNode)); 3328 out.push_back(indent() + "return"s + nll(returnNode));
3311 } 3329 }
@@ -4495,23 +4513,15 @@ private:
4495 out.push_back(_parser.toString(num)); 4513 out.push_back(_parser.toString(num));
4496 } 4514 }
4497 4515
4498 bool hasSpreadExp(TableLit_t* table) { 4516 bool hasSpreadExp(const node_container& items) {
4499 for (auto item : table->values.objects()) { 4517 for (auto item : items) {
4500 if (ast_is<SpreadExp_t>(item)) return true; 4518 if (ast_is<SpreadExp_t>(item)) return true;
4501 } 4519 }
4502 return false; 4520 return false;
4503 } 4521 }
4504 4522
4505 void transformTableLit(TableLit_t* table, str_list& out) { 4523 void transformSpreadTable(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
4506 if (hasSpreadExp(table)) { 4524 auto x = values.front();
4507 transformSpreadTableLit(table, out, ExpUsage::Closure);
4508 } else {
4509 transformTable(table, table->values.objects(), out);
4510 }
4511 }
4512
4513 void transformSpreadTableLit(TableLit_t* table, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
4514 auto x = table;
4515 switch (usage) { 4525 switch (usage) {
4516 case ExpUsage::Closure: 4526 case ExpUsage::Closure:
4517 _enableReturn.push(true); 4527 _enableReturn.push(true);
@@ -4527,19 +4537,19 @@ private:
4527 str_list temp; 4537 str_list temp;
4528 std::string tableVar = getUnusedName("_tab_"sv); 4538 std::string tableVar = getUnusedName("_tab_"sv);
4529 forceAddToScope(tableVar); 4539 forceAddToScope(tableVar);
4530 auto it = table->values.objects().begin(); 4540 auto it = values.begin();
4531 if (ast_is<SpreadExp_t>(*it)) { 4541 if (ast_is<SpreadExp_t>(*it)) {
4532 temp.push_back(indent() + "local "s + tableVar + " = { }"s + nll(x)); 4542 temp.push_back(indent() + "local "s + tableVar + " = { }"s + nll(x));
4533 } else { 4543 } else {
4534 auto initialTab = x->new_ptr<TableLit_t>(); 4544 auto initialTab = x->new_ptr<TableLit_t>();
4535 while (it != table->values.objects().end() && !ast_is<SpreadExp_t>(*it)) { 4545 while (it != values.end() && !ast_is<SpreadExp_t>(*it)) {
4536 initialTab->values.push_back(*it); 4546 initialTab->values.push_back(*it);
4537 ++it; 4547 ++it;
4538 } 4548 }
4539 transformTable(table, initialTab->values.objects(), temp); 4549 transformTable(initialTab->values.objects(), temp);
4540 temp.back() = indent() + "local "s + tableVar + " = "s + temp.back() + nll(*it); 4550 temp.back() = indent() + "local "s + tableVar + " = "s + temp.back() + nll(*it);
4541 } 4551 }
4542 for (; it != table->values.objects().end(); ++it) { 4552 for (; it != values.end(); ++it) {
4543 auto item = *it; 4553 auto item = *it;
4544 switch (item->getId()) { 4554 switch (item->getId()) {
4545 case id<SpreadExp_t>(): { 4555 case id<SpreadExp_t>(): {
@@ -4623,7 +4633,7 @@ private:
4623 case id<Exp_t>(): { 4633 case id<Exp_t>(): {
4624 bool lastVarArg = false; 4634 bool lastVarArg = false;
4625 BLOCK_START 4635 BLOCK_START
4626 BREAK_IF(item != table->values.back()); 4636 BREAK_IF(item != values.back());
4627 auto value = singleValueFrom(item); 4637 auto value = singleValueFrom(item);
4628 BREAK_IF(!value); 4638 BREAK_IF(!value);
4629 auto chainValue = value->item.as<ChainValue_t>(); 4639 auto chainValue = value->item.as<ChainValue_t>();
@@ -4644,6 +4654,66 @@ private:
4644 } 4654 }
4645 break; 4655 break;
4646 } 4656 }
4657 case id<TableBlockIndent_t>(): {
4658 auto tbIndent = static_cast<TableBlockIndent_t*>(item);
4659 auto tableBlock = item->new_ptr<TableBlock_t>();
4660 tableBlock->values.dup(tbIndent->values);
4661 auto assignment = toAst<ExpListAssign_t>(tableVar + "[]=nil"s, item);
4662 auto assign = assignment->action.to<Assign_t>();
4663 assign->values.clear();
4664 assign->values.push_back(tableBlock);
4665 transformAssignment(assignment, temp);
4666 break;
4667 }
4668 case id<TableBlock_t>(): {
4669 auto assignment = toAst<ExpListAssign_t>(tableVar + "[]=nil"s, item);
4670 auto assign = assignment->action.to<Assign_t>();
4671 assign->values.clear();
4672 assign->values.push_back(item);
4673 transformAssignment(assignment, temp);
4674 break;
4675 }
4676 case id<meta_variable_pair_t>(): {
4677 auto metaVarPair = static_cast<meta_variable_pair_t*>(item);
4678 auto nameStr = _parser.toString(metaVarPair->name);
4679 auto assignment = toAst<ExpListAssign_t>(tableVar + '.' + nameStr + "#="s + nameStr, item);
4680 transformAssignment(assignment, temp);
4681 break;
4682 }
4683 case id<meta_normal_pair_t>(): {
4684 auto metaNormalPair = static_cast<meta_normal_pair_t*>(item);
4685 auto assignment = toAst<ExpListAssign_t>(tableVar + "=nil"s, item);
4686 auto chainValue = singleValueFrom(ast_to<Exp_t>(assignment->expList->exprs.front()))->item.to<ChainValue_t>();
4687 auto key = metaNormalPair->key.get();
4688 switch (key->getId()) {
4689 case id<Name_t>(): {
4690 auto dotItem = x->new_ptr<DotChainItem_t>();
4691 dotItem->name.set(key);
4692 chainValue->items.push_back(dotItem);
4693 break;
4694 }
4695 case id<Exp_t>(): {
4696 auto dotItem = toAst<DotChainItem_t>(".#"sv, key);
4697 chainValue->items.push_back(dotItem);
4698 chainValue->items.push_back(key);
4699 break;
4700 }
4701 default: YUEE("AST node mismatch", key); break;
4702 }
4703 auto assign = assignment->action.to<Assign_t>();
4704 assign->values.clear();
4705 assign->values.push_back(metaNormalPair->value);
4706 transformAssignment(assignment, temp);
4707 break;
4708 }
4709 case id<default_pair_t>(): {
4710 throw std::logic_error(_info.errorMessage("invalid default value"sv, static_cast<default_pair_t*>(item)->defVal));
4711 break;
4712 }
4713 case id<meta_default_pair_t>(): {
4714 throw std::logic_error(_info.errorMessage("invalid default value"sv, static_cast<meta_default_pair_t*>(item)->defVal));
4715 break;
4716 }
4647 default: YUEE("AST node mismatch", item); break; 4717 default: YUEE("AST node mismatch", item); break;
4648 } 4718 }
4649 } 4719 }
@@ -4682,6 +4752,123 @@ private:
4682 } 4752 }
4683 } 4753 }
4684 4754
4755 void transformTable(const node_container& values, str_list& out) {
4756 if (values.empty()) {
4757 out.push_back("{ }"s);
4758 return;
4759 }
4760 auto x = values.front();
4761 str_list temp;
4762 incIndentOffset();
4763 auto metatable = x->new_ptr<simple_table_t>();
4764 ast_sel<false, Exp_t, TableBlock_t> metatableItem;
4765 for (auto item : values) {
4766 bool isMetamethod = false;
4767 switch (item->getId()) {
4768 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); break;
4769 case id<variable_pair_t>(): transform_variable_pair(static_cast<variable_pair_t*>(item), temp); break;
4770 case id<normal_pair_t>(): transform_normal_pair(static_cast<normal_pair_t*>(item), temp, false); break;
4771 case id<TableBlockIndent_t>(): transformTableBlockIndent(static_cast<TableBlockIndent_t*>(item), temp); break;
4772 case id<TableBlock_t>(): transformTableBlock(static_cast<TableBlock_t*>(item), temp); break;
4773 case id<meta_variable_pair_t>(): {
4774 isMetamethod = true;
4775 auto mp = static_cast<meta_variable_pair_t*>(item);
4776 if (metatableItem) {
4777 throw std::logic_error(_info.errorMessage("too many metatable declarations"sv, mp->name));
4778 }
4779 auto name = _parser.toString(mp->name);
4780 _buf << "__"sv << name << ':' << name;
4781 auto newPair = toAst<normal_pair_t>(clearBuf(), item);
4782 metatable->pairs.push_back(newPair);
4783 break;
4784 }
4785 case id<meta_normal_pair_t>(): {
4786 isMetamethod = true;
4787 auto mp = static_cast<meta_normal_pair_t*>(item);
4788 auto newPair = item->new_ptr<normal_pair_t>();
4789 if (mp->key) {
4790 if (metatableItem) {
4791 throw std::logic_error(_info.errorMessage("too many metatable declarations"sv, mp->key));
4792 }
4793 switch (mp->key->getId()) {
4794 case id<Name_t>(): {
4795 auto key = _parser.toString(mp->key);
4796 _buf << "__"sv << key;
4797 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key);
4798 newPair->key.set(newKey);
4799 break;
4800 }
4801 case id<Exp_t>():
4802 newPair->key.set(mp->key);
4803 break;
4804 default: YUEE("AST node mismatch", mp->key); break;
4805 }
4806 newPair->value.set(mp->value);
4807 metatable->pairs.push_back(newPair);
4808 } else {
4809 if (!metatable->pairs.empty()) {
4810 throw std::logic_error(_info.errorMessage("too many metatable declarations"sv, mp->value));
4811 }
4812 metatableItem.set(mp->value);
4813 }
4814 break;
4815 }
4816 case id<default_pair_t>(): {
4817 throw std::logic_error(_info.errorMessage("invalid default value"sv, static_cast<default_pair_t*>(item)->defVal));
4818 break;
4819 }
4820 case id<meta_default_pair_t>(): {
4821 throw std::logic_error(_info.errorMessage("invalid default value"sv, static_cast<meta_default_pair_t*>(item)->defVal));
4822 break;
4823 }
4824 default: YUEE("AST node mismatch", item); break;
4825 }
4826 if (!isMetamethod) {
4827 temp.back() = indent() + (item == values.back() ? temp.back() : temp.back() + ',') + nll(item);
4828 }
4829 }
4830 if (metatable->pairs.empty() && !metatableItem) {
4831 out.push_back('{' + nll(x) + join(temp));
4832 decIndentOffset();
4833 out.back() += (indent() + '}');
4834 } else {
4835 auto tabStr = globalVar("setmetatable"sv, x);
4836 tabStr += '(';
4837 if (temp.empty()) {
4838 decIndentOffset();
4839 tabStr += "{ }"sv;
4840 } else {
4841 tabStr += ('{' + nll(x) + join(temp));
4842 decIndentOffset();
4843 tabStr += (indent() + '}');
4844 }
4845 tabStr += ", "sv;
4846 str_list tmp;
4847 if (!metatable->pairs.empty()) {
4848 transform_simple_table(metatable, tmp);
4849 } else switch (metatableItem->getId()) {
4850 case id<Exp_t>():
4851 transformExp(static_cast<Exp_t*>(metatableItem.get()), tmp, ExpUsage::Closure);
4852 break;
4853 case id<TableBlock_t>():
4854 transformTableBlock(static_cast<TableBlock_t*>(metatableItem.get()), tmp);
4855 break;
4856 }
4857 tabStr += tmp.back();
4858 tabStr += ')';
4859 out.push_back(tabStr);
4860 }
4861 }
4862
4863 void transformTableLit(TableLit_t* table, str_list& out) {
4864 const auto& values = table->values.objects();
4865 if (hasSpreadExp(values)) {
4866 transformSpreadTable(values, out, ExpUsage::Closure);
4867 } else {
4868 transformTable(values, out);
4869 }
4870 }
4871
4685 void transformCompCommon(Comprehension_t* comp, str_list& out) { 4872 void transformCompCommon(Comprehension_t* comp, str_list& out) {
4686 str_list temp; 4873 str_list temp;
4687 auto x = comp; 4874 auto x = comp;
@@ -6079,115 +6266,8 @@ private:
6079 } 6266 }
6080 } 6267 }
6081 6268
6082 void transformTable(ast_node* table, const node_container& pairs, str_list& out) {
6083 if (pairs.empty()) {
6084 out.push_back("{ }"s);
6085 return;
6086 }
6087 str_list temp;
6088 incIndentOffset();
6089 auto metatable = table->new_ptr<simple_table_t>();
6090 ast_sel<false, Exp_t, TableBlock_t> metatableItem;
6091 for (auto pair : pairs) {
6092 bool isMetamethod = false;
6093 switch (pair->getId()) {
6094 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(pair), temp, ExpUsage::Closure); break;
6095 case id<variable_pair_t>(): transform_variable_pair(static_cast<variable_pair_t*>(pair), temp); break;
6096 case id<normal_pair_t>(): transform_normal_pair(static_cast<normal_pair_t*>(pair), temp, false); break;
6097 case id<TableBlockIndent_t>(): transformTableBlockIndent(static_cast<TableBlockIndent_t*>(pair), temp); break;
6098 case id<TableBlock_t>(): transformTableBlock(static_cast<TableBlock_t*>(pair), temp); break;
6099 case id<meta_variable_pair_t>(): {
6100 isMetamethod = true;
6101 auto mp = static_cast<meta_variable_pair_t*>(pair);
6102 if (metatableItem) {
6103 throw std::logic_error(_info.errorMessage("too many metatable declarations"sv, mp->name));
6104 }
6105 auto name = _parser.toString(mp->name);
6106 _buf << "__"sv << name << ':' << name;
6107 auto newPair = toAst<normal_pair_t>(clearBuf(), pair);
6108 metatable->pairs.push_back(newPair);
6109 break;
6110 }
6111 case id<meta_normal_pair_t>(): {
6112 isMetamethod = true;
6113 auto mp = static_cast<meta_normal_pair_t*>(pair);
6114 auto newPair = pair->new_ptr<normal_pair_t>();
6115 if (mp->key) {
6116 if (metatableItem) {
6117 throw std::logic_error(_info.errorMessage("too many metatable declarations"sv, mp->key));
6118 }
6119 switch (mp->key->getId()) {
6120 case id<Name_t>(): {
6121 auto key = _parser.toString(mp->key);
6122 _buf << "__"sv << key;
6123 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key);
6124 newPair->key.set(newKey);
6125 break;
6126 }
6127 case id<Exp_t>():
6128 newPair->key.set(mp->key);
6129 break;
6130 default: YUEE("AST node mismatch", mp->key); break;
6131 }
6132 newPair->value.set(mp->value);
6133 metatable->pairs.push_back(newPair);
6134 } else {
6135 if (!metatable->pairs.empty()) {
6136 throw std::logic_error(_info.errorMessage("too many metatable declarations"sv, mp->value));
6137 }
6138 metatableItem.set(mp->value);
6139 }
6140 break;
6141 }
6142 case id<default_pair_t>(): {
6143 throw std::logic_error(_info.errorMessage("invalid use of default value"sv, static_cast<default_pair_t*>(pair)->defVal));
6144 break;
6145 }
6146 case id<meta_default_pair_t>(): {
6147 throw std::logic_error(_info.errorMessage("invalid use of default value"sv, static_cast<meta_default_pair_t*>(pair)->defVal));
6148 break;
6149 }
6150 default: YUEE("AST node mismatch", pair); break;
6151 }
6152 if (!isMetamethod) {
6153 temp.back() = indent() + (pair == pairs.back() ? temp.back() : temp.back() + ',') + nll(pair);
6154 }
6155 }
6156 if (metatable->pairs.empty() && !metatableItem) {
6157 out.push_back('{' + nll(table) + join(temp));
6158 decIndentOffset();
6159 out.back() += (indent() + '}');
6160 } else {
6161 auto tabStr = globalVar("setmetatable"sv, table);
6162 tabStr += '(';
6163 if (temp.empty()) {
6164 decIndentOffset();
6165 tabStr += "{ }"sv;
6166 } else {
6167 tabStr += ('{' + nll(table) + join(temp));
6168 decIndentOffset();
6169 tabStr += (indent() + '}');
6170 }
6171 tabStr += ", "sv;
6172 str_list tmp;
6173 if (!metatable->pairs.empty()) {
6174 transform_simple_table(metatable, tmp);
6175 } else switch (metatableItem->getId()) {
6176 case id<Exp_t>():
6177 transformExp(static_cast<Exp_t*>(metatableItem.get()), tmp, ExpUsage::Closure);
6178 break;
6179 case id<TableBlock_t>():
6180 transformTableBlock(static_cast<TableBlock_t*>(metatableItem.get()), tmp);
6181 break;
6182 }
6183 tabStr += tmp.back();
6184 tabStr += ')';
6185 out.push_back(tabStr);
6186 }
6187 }
6188
6189 void transform_simple_table(simple_table_t* table, str_list& out) { 6269 void transform_simple_table(simple_table_t* table, str_list& out) {
6190 transformTable(table, table->pairs.objects(), out); 6270 transformTable(table->pairs.objects(), out);
6191 } 6271 }
6192 6272
6193 void transformTblComprehension(TblComprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 6273 void transformTblComprehension(TblComprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
@@ -6284,11 +6364,16 @@ private:
6284 } 6364 }
6285 6365
6286 void transformTableBlockIndent(TableBlockIndent_t* table, str_list& out) { 6366 void transformTableBlockIndent(TableBlockIndent_t* table, str_list& out) {
6287 transformTable(table, table->values.objects(), out); 6367 transformTable(table->values.objects(), out);
6288 } 6368 }
6289 6369
6290 void transformTableBlock(TableBlock_t* table, str_list& out) { 6370 void transformTableBlock(TableBlock_t* table, str_list& out) {
6291 transformTable(table, table->values.objects(), out); 6371 const auto& values = table->values.objects();
6372 if (hasSpreadExp(values)) {
6373 transformSpreadTable(values, out, ExpUsage::Closure);
6374 } else {
6375 transformTable(values, out);
6376 }
6292 } 6377 }
6293 6378
6294 void transformDo(Do_t* doNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 6379 void transformDo(Do_t* doNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index 0c08d4f..1f1b57c 100755
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -28,9 +28,8 @@ std::unordered_set<std::string> Keywords = {
28 "or", "repeat", "return", "then", "true", 28 "or", "repeat", "return", "then", "true",
29 "until", "while", // Lua keywords 29 "until", "while", // Lua keywords
30 "as", "class", "continue", "export", "extends", 30 "as", "class", "continue", "export", "extends",
31 "from", "global", "import", "is", "macro", 31 "from", "global", "import", "macro", "switch",
32 "switch", "try", "unless", "using", "when", 32 "try", "unless", "using", "when", "with" // Yue keywords
33 "with" // Yue keywords
34}; 33};
35 34
36YueParser::YueParser() { 35YueParser::YueParser() {
@@ -219,7 +218,7 @@ YueParser::YueParser() {
219 218
220 BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); 219 BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum);
221 220
222 Return = key("return") >> -ExpListLow; 221 Return = key("return") >> -(TableBlock | ExpListLow);
223 222
224 WithExp = ExpList >> -Assign; 223 WithExp = ExpList >> -Assign;
225 224
@@ -556,7 +555,7 @@ YueParser::YueParser() {
556 555
557 KeyValue = variable_pair | normal_pair | meta_variable_pair | meta_normal_pair; 556 KeyValue = variable_pair | normal_pair | meta_variable_pair | meta_normal_pair;
558 KeyValueList = KeyValue >> *(sym(',') >> KeyValue); 557 KeyValueList = KeyValue >> *(sym(',') >> KeyValue);
559 KeyValueLine = CheckIndent >> (KeyValueList >> -sym(',') | TableBlockIndent | Space >> expr('*') >> (Exp | TableBlock)); 558 KeyValueLine = CheckIndent >> (KeyValueList >> -sym(',') | TableBlockIndent | Space >> expr('*') >> (SpreadExp | Exp | TableBlock));
560 559
561 FnArgDef = (Variable | SelfName >> -existential_op) >> -(sym('=') >> Space >> Exp); 560 FnArgDef = (Variable | SelfName >> -existential_op) >> -(sym('=') >> Space >> Exp);
562 561
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index eeadaf6..159bbca 100755
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -15,6 +15,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
15#include <list> 15#include <list>
16#include <sstream> 16#include <sstream>
17#include <string_view> 17#include <string_view>
18#include <memory>
18 19
19#include "yuescript/ast.hpp" 20#include "yuescript/ast.hpp"
20#include "yuescript/yue_ast.h" 21#include "yuescript/yue_ast.h"