aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-09-08 09:26:49 +0800
committerLi Jin <dragon-fly@qq.com>2022-09-08 09:26:49 +0800
commitd4af1fa275b1d27229fc995f4a45137380040933 (patch)
tree955c76511d7021e6d1a0f06b46de3852eeac4176 /src
parentdf85ad2e7f975026ca1e6bd84b26fff81c8d99c8 (diff)
downloadyuescript-d4af1fa275b1d27229fc995f4a45137380040933.tar.gz
yuescript-d4af1fa275b1d27229fc995f4a45137380040933.tar.bz2
yuescript-d4af1fa275b1d27229fc995f4a45137380040933.zip
redesigned metatable syntax. add support for destructuring a field with string and expression
Diffstat (limited to 'src')
-rwxr-xr-xsrc/yuescript/yue_ast.h17
-rwxr-xr-xsrc/yuescript/yue_compiler.cpp556
-rwxr-xr-xsrc/yuescript/yue_parser.cpp32
-rwxr-xr-xsrc/yuescript/yue_parser.h1
4 files changed, 388 insertions, 218 deletions
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index 386fa28..d8f6c95 100755
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -459,18 +459,16 @@ AST_NODE(variable_pair)
459 AST_MEMBER(variable_pair, &name) 459 AST_MEMBER(variable_pair, &name)
460AST_END(variable_pair, "variable_pair"sv) 460AST_END(variable_pair, "variable_pair"sv)
461 461
462class DoubleString_t; 462class String_t;
463class SingleString_t;
464class LuaString_t;
465 463
466AST_NODE(normal_pair) 464AST_NODE(normal_pair)
467 ast_sel<true, KeyName_t, Exp_t, DoubleString_t, SingleString_t, LuaString_t> key; 465 ast_sel<true, KeyName_t, Exp_t, String_t> key;
468 ast_sel<true, Exp_t, TableBlock_t> value; 466 ast_sel<true, Exp_t, TableBlock_t> value;
469 AST_MEMBER(normal_pair, &key, &value) 467 AST_MEMBER(normal_pair, &key, &value)
470AST_END(normal_pair, "normal_pair"sv) 468AST_END(normal_pair, "normal_pair"sv)
471 469
472AST_NODE(default_pair) 470AST_NODE(default_pair)
473 ast_sel<true, Variable_t, KeyName_t, Exp_t> key; 471 ast_sel<true, Variable_t, KeyName_t, Exp_t, String_t> key;
474 ast_ptr<true, Seperator_t> sep; 472 ast_ptr<true, Seperator_t> sep;
475 ast_ptr<false, Exp_t> value; 473 ast_ptr<false, Exp_t> value;
476 ast_ptr<true, Exp_t> defVal; 474 ast_ptr<true, Exp_t> defVal;
@@ -483,13 +481,13 @@ AST_NODE(meta_variable_pair)
483AST_END(meta_variable_pair, "meta_variable_pair"sv) 481AST_END(meta_variable_pair, "meta_variable_pair"sv)
484 482
485AST_NODE(meta_normal_pair) 483AST_NODE(meta_normal_pair)
486 ast_sel<false, Name_t, Exp_t> key; 484 ast_sel<false, Name_t, Exp_t, String_t> key;
487 ast_sel<true, Exp_t, TableBlock_t> value; 485 ast_sel<true, Exp_t, TableBlock_t> value;
488 AST_MEMBER(meta_normal_pair, &key, &value) 486 AST_MEMBER(meta_normal_pair, &key, &value)
489AST_END(meta_normal_pair, "meta_normal_pair"sv) 487AST_END(meta_normal_pair, "meta_normal_pair"sv)
490 488
491AST_NODE(meta_default_pair) 489AST_NODE(meta_default_pair)
492 ast_sel<false, Variable_t, Name_t> key; 490 ast_sel<false, Variable_t, Name_t, Exp_t, String_t> key;
493 ast_ptr<true, Seperator_t> sep; 491 ast_ptr<true, Seperator_t> sep;
494 ast_ptr<false, Exp_t> value; 492 ast_ptr<false, Exp_t> value;
495 ast_ptr<true, Exp_t> defVal; 493 ast_ptr<true, Exp_t> defVal;
@@ -502,7 +500,6 @@ AST_NODE(simple_table)
502 AST_MEMBER(simple_table, &sep, &pairs) 500 AST_MEMBER(simple_table, &sep, &pairs)
503AST_END(simple_table, "simple_table"sv) 501AST_END(simple_table, "simple_table"sv)
504 502
505class String_t;
506class const_value_t; 503class const_value_t;
507class ClassDecl_t; 504class ClassDecl_t;
508class unary_value_t; 505class unary_value_t;
@@ -560,8 +557,8 @@ AST_LEAF(Metatable)
560AST_END(Metatable, "metatable"sv) 557AST_END(Metatable, "metatable"sv)
561 558
562AST_NODE(Metamethod) 559AST_NODE(Metamethod)
563 ast_ptr<true, Name_t> name; 560 ast_sel<true, Name_t, Exp_t, String_t> item;
564 AST_MEMBER(Metamethod, &name) 561 AST_MEMBER(Metamethod, &item)
565AST_END(Metamethod, "metamethod"sv) 562AST_END(Metamethod, "metamethod"sv)
566 563
567AST_NODE(DotChainItem) 564AST_NODE(DotChainItem)
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 17979ab..73b4ae9 100755
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -59,7 +59,7 @@ namespace yue {
59 59
60typedef std::list<std::string> str_list; 60typedef std::list<std::string> str_list;
61 61
62const std::string_view version = "0.14.5"sv; 62const std::string_view version = "0.15.1"sv;
63const std::string_view extension = "yue"sv; 63const std::string_view extension = "yue"sv;
64 64
65class YueCompilerImpl { 65class YueCompilerImpl {
@@ -296,7 +296,7 @@ private:
296 struct DestructItem { 296 struct DestructItem {
297 ast_ptr<true, Exp_t> target; 297 ast_ptr<true, Exp_t> target;
298 std::string targetVar; 298 std::string targetVar;
299 std::string structure; 299 ast_ptr<false, ChainValue_t> structure;
300 ast_ptr<true, Exp_t> defVal; 300 ast_ptr<true, Exp_t> defVal;
301 }; 301 };
302 302
@@ -304,6 +304,7 @@ private:
304 ast_ptr<true, ast_node> value; 304 ast_ptr<true, ast_node> value;
305 std::string valueVar; 305 std::string valueVar;
306 std::list<DestructItem> items; 306 std::list<DestructItem> items;
307 ast_ptr<false, ExpListAssign_t> inlineAssignment;
307 }; 308 };
308 309
309 enum class ExpUsage { 310 enum class ExpUsage {
@@ -614,6 +615,24 @@ private:
614 return nullptr; 615 return nullptr;
615 } 616 }
616 617
618 ast_ptr<false, Exp_t> newExp(SimpleValue_t* simpleValue, ast_node* x) {
619 auto value = x->new_ptr<Value_t>();
620 value->item.set(simpleValue);
621 return newExp(value, x);
622 }
623
624 ast_ptr<false, Exp_t> newExp(String_t* string, ast_node* x) {
625 auto value = x->new_ptr<Value_t>();
626 value->item.set(string);
627 return newExp(value, x);
628 }
629
630 ast_ptr<false, Exp_t> newExp(ChainValue_t* chainValue, ast_node* x) {
631 auto value = x->new_ptr<Value_t>();
632 value->item.set(chainValue);
633 return newExp(value, x);
634 }
635
617 ast_ptr<false, Exp_t> newExp(Value_t* value, ast_node* x) { 636 ast_ptr<false, Exp_t> newExp(Value_t* value, ast_node* x) {
618 auto unary = x->new_ptr<unary_exp_t>(); 637 auto unary = x->new_ptr<unary_exp_t>();
619 unary->expos.push_back(value); 638 unary->expos.push_back(value);
@@ -772,7 +791,8 @@ private:
772 HasEOP, 791 HasEOP,
773 HasKeyword, 792 HasKeyword,
774 Macro, 793 Macro,
775 Metatable 794 Metatable,
795 MetaFieldInvocation
776 }; 796 };
777 797
778 ChainType specialChainValue(ChainValue_t* chainValue) const { 798 ChainType specialChainValue(ChainValue_t* chainValue) const {
@@ -795,6 +815,8 @@ private:
795 if (auto colonChain = ast_cast<ColonChainItem_t>(item)) { 815 if (auto colonChain = ast_cast<ColonChainItem_t>(item)) {
796 if (ast_is<LuaKeyword_t>(colonChain->name)) { 816 if (ast_is<LuaKeyword_t>(colonChain->name)) {
797 type = ChainType::HasKeyword; 817 type = ChainType::HasKeyword;
818 } else if (auto meta = colonChain->name.as<Metamethod_t>(); meta && !meta->item.is<Name_t>()) {
819 return ChainType::MetaFieldInvocation;
798 } 820 }
799 } else if (ast_is<existential_op_t>(item)) { 821 } else if (ast_is<existential_op_t>(item)) {
800 return ChainType::HasEOP; 822 return ChainType::HasEOP;
@@ -1013,9 +1035,7 @@ private:
1013 case id<With_t>(): { 1035 case id<With_t>(): {
1014 auto simpleValue = x->new_ptr<SimpleValue_t>(); 1036 auto simpleValue = x->new_ptr<SimpleValue_t>();
1015 simpleValue->value.set(val); 1037 simpleValue->value.set(val);
1016 auto value = x->new_ptr<Value_t>(); 1038 auto exp = newExp(simpleValue, x);
1017 value->item.set(simpleValue);
1018 auto exp = newExp(value, x);
1019 expList->exprs.push_back(exp); 1039 expList->exprs.push_back(exp);
1020 break; 1040 break;
1021 } 1041 }
@@ -1025,9 +1045,7 @@ private:
1025 tabLit->values.dup(tableBlock->values); 1045 tabLit->values.dup(tableBlock->values);
1026 auto simpleValue = x->new_ptr<SimpleValue_t>(); 1046 auto simpleValue = x->new_ptr<SimpleValue_t>();
1027 simpleValue->value.set(tabLit); 1047 simpleValue->value.set(tabLit);
1028 auto value = x->new_ptr<Value_t>(); 1048 auto exp = newExp(simpleValue, x);
1029 value->item.set(simpleValue);
1030 auto exp = newExp(value, x);
1031 expList->exprs.push_back(exp); 1049 expList->exprs.push_back(exp);
1032 break; 1050 break;
1033 } 1051 }
@@ -1072,9 +1090,7 @@ private:
1072 statement->appendix.set(nullptr); 1090 statement->appendix.set(nullptr);
1073 auto simpleValue = x->new_ptr<SimpleValue_t>(); 1091 auto simpleValue = x->new_ptr<SimpleValue_t>();
1074 simpleValue->value.set(ifNode); 1092 simpleValue->value.set(ifNode);
1075 auto value = x->new_ptr<Value_t>(); 1093 auto exp = newExp(simpleValue, x);
1076 value->item.set(simpleValue);
1077 auto exp = newExp(value, x);
1078 auto expList = x->new_ptr<ExpList_t>(); 1094 auto expList = x->new_ptr<ExpList_t>();
1079 expList->exprs.push_back(exp); 1095 expList->exprs.push_back(exp);
1080 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 1096 auto expListAssign = x->new_ptr<ExpListAssign_t>();
@@ -1091,9 +1107,7 @@ private:
1091 comp->value.set(stmt); 1107 comp->value.set(stmt);
1092 auto simpleValue = x->new_ptr<SimpleValue_t>(); 1108 auto simpleValue = x->new_ptr<SimpleValue_t>();
1093 simpleValue->value.set(comp); 1109 simpleValue->value.set(comp);
1094 auto value = x->new_ptr<Value_t>(); 1110 auto exp = newExp(simpleValue, x);
1095 value->item.set(simpleValue);
1096 auto exp = newExp(value, x);
1097 auto expList = x->new_ptr<ExpList_t>(); 1111 auto expList = x->new_ptr<ExpList_t>();
1098 expList->exprs.push_back(exp); 1112 expList->exprs.push_back(exp);
1099 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 1113 auto expListAssign = x->new_ptr<ExpListAssign_t>();
@@ -1483,9 +1497,7 @@ private:
1483 args.push_back(_withVars.top()); 1497 args.push_back(_withVars.top());
1484 } 1498 }
1485 } else { 1499 } else {
1486 auto value = tmpChain->new_ptr<Value_t>(); 1500 transformExp(newExp(tmpChain, tmpChain), args, ExpUsage::Closure);
1487 value->item.set(tmpChain);
1488 transformExp(newExp(value, tmpChain), args, ExpUsage::Closure);
1489 } 1501 }
1490 if (vit == values.end()) { 1502 if (vit == values.end()) {
1491 throw std::logic_error(_info.errorMessage("right value missing"sv, values.front())); 1503 throw std::logic_error(_info.errorMessage("right value missing"sv, values.front()));
@@ -1514,9 +1526,7 @@ private:
1514 auto newAssignment = x->new_ptr<ExpListAssign_t>(); 1526 auto newAssignment = x->new_ptr<ExpListAssign_t>();
1515 newAssignment->expList.set(toAst<ExpList_t>(objVar, x)); 1527 newAssignment->expList.set(toAst<ExpList_t>(objVar, x));
1516 auto assign = x->new_ptr<Assign_t>(); 1528 auto assign = x->new_ptr<Assign_t>();
1517 auto value = tmpChain->new_ptr<Value_t>(); 1529 assign->values.push_back(newExp(tmpChain, tmpChain));
1518 value->item.set(tmpChain);
1519 assign->values.push_back(newExp(value, tmpChain));
1520 newAssignment->action.set(assign); 1530 newAssignment->action.set(assign);
1521 transformAssignment(newAssignment, temp); 1531 transformAssignment(newAssignment, temp);
1522 varName = objVar; 1532 varName = objVar;
@@ -1685,7 +1695,8 @@ private:
1685 auto expList = assignment->expList.get(); 1695 auto expList = assignment->expList.get();
1686 switch (type) { 1696 switch (type) {
1687 case ChainType::HasEOP: 1697 case ChainType::HasEOP:
1688 case ChainType::EndWithColon: { 1698 case ChainType::EndWithColon:
1699 case ChainType::MetaFieldInvocation: {
1689 std::string preDefine = getPreDefineLine(assignment); 1700 std::string preDefine = getPreDefineLine(assignment);
1690 transformChainValue(chainValue, out, ExpUsage::Assignment, expList); 1701 transformChainValue(chainValue, out, ExpUsage::Assignment, expList);
1691 out.back().insert(0, preDefine); 1702 out.back().insert(0, preDefine);
@@ -1714,7 +1725,7 @@ private:
1714 for (auto& destruct : info.destructures) { 1725 for (auto& destruct : info.destructures) {
1715 std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs; 1726 std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs;
1716 bool extraScope = false; 1727 bool extraScope = false;
1717 if (destruct.items.size() == 1) { 1728 if (!destruct.inlineAssignment && destruct.items.size() == 1) {
1718 auto& pair = destruct.items.front(); 1729 auto& pair = destruct.items.front();
1719 if (pair.targetVar.empty() && pair.defVal) { 1730 if (pair.targetVar.empty() && pair.defVal) {
1720 extraScope = true; 1731 extraScope = true;
@@ -1725,21 +1736,13 @@ private:
1725 pair.targetVar = objVar; 1736 pair.targetVar = objVar;
1726 } else if (auto val = singleValueFrom(destruct.value); val->item.is<ChainValue_t>()) { 1737 } else if (auto val = singleValueFrom(destruct.value); val->item.is<ChainValue_t>()) {
1727 auto chainValue = static_cast<ChainValue_t*>(val->item.get()); 1738 auto chainValue = static_cast<ChainValue_t*>(val->item.get());
1728 int added = 0; 1739 auto newChain = val->item->new_ptr<ChainValue_t>();
1729 if (!pair.structure.empty()) { 1740 newChain->items.dup(chainValue->items);
1730 auto appendChain = toAst<ChainValue_t>("x"s + pair.structure, x); 1741 if (pair.structure) {
1731 appendChain->items.pop_front(); 1742 newChain->items.dup(pair.structure->items);
1732 for (auto item : appendChain->items.objects()) {
1733 chainValue->items.push_back(item);
1734 added++;
1735 }
1736 } 1743 }
1737 auto newAssignment = assignmentFrom(pair.target, destruct.value, x); 1744 auto newAssignment = assignmentFrom(pair.target, newExp(newChain, val->item), x);
1738 transformAssignment(newAssignment, temp); 1745 transformAssignment(newAssignment, temp);
1739 while (added > 0) {
1740 chainValue->items.pop_back();
1741 added--;
1742 }
1743 if (pair.defVal) { 1746 if (pair.defVal) {
1744 bool isNil = false; 1747 bool isNil = false;
1745 if (auto v1 = singleValueFrom(pair.defVal)) { 1748 if (auto v1 = singleValueFrom(pair.defVal)) {
@@ -1782,7 +1785,10 @@ private:
1782 auto newAssignment = assignmentFrom(toAst<Exp_t>(objVar, x), destruct.value, x); 1785 auto newAssignment = assignmentFrom(toAst<Exp_t>(objVar, x), destruct.value, x);
1783 transformAssignment(newAssignment, temp); 1786 transformAssignment(newAssignment, temp);
1784 } 1787 }
1785 auto valueExp = toAst<Exp_t>(objVar + pair.structure, x); 1788 auto chain = pair.target->new_ptr<ChainValue_t>();
1789 chain->items.push_back(toAst<Callable_t>(objVar, chain));
1790 chain->items.dup(pair.structure->items);
1791 auto valueExp = newExp(chain, pair.target);
1786 auto newAssignment = assignmentFrom(pair.target, valueExp, x); 1792 auto newAssignment = assignmentFrom(pair.target, valueExp, x);
1787 transformAssignment(newAssignment, temp); 1793 transformAssignment(newAssignment, temp);
1788 if (!isLocalValue) { 1794 if (!isLocalValue) {
@@ -1791,7 +1797,8 @@ private:
1791 temp.push_back(clearBuf()); 1797 temp.push_back(clearBuf());
1792 } 1798 }
1793 } else { 1799 } else {
1794 str_list values, defs; 1800 str_list defs;
1801 std::list<ast_ptr<false, ChainValue_t>> values;
1795 std::list<Exp_t*> names; 1802 std::list<Exp_t*> names;
1796 pushScope(); 1803 pushScope();
1797 for (auto& item : destruct.items) { 1804 for (auto& item : destruct.items) {
@@ -1813,8 +1820,9 @@ private:
1813 } 1820 }
1814 popScope(); 1821 popScope();
1815 if (_parser.match<Name_t>(destruct.valueVar) && isLocal(destruct.valueVar)) { 1822 if (_parser.match<Name_t>(destruct.valueVar) && isLocal(destruct.valueVar)) {
1823 auto callable = toAst<Callable_t>(destruct.valueVar, destruct.value);
1816 for (auto& v : values) { 1824 for (auto& v : values) {
1817 v.insert(0, destruct.valueVar); 1825 v->items.push_front(callable);
1818 } 1826 }
1819 if (extraScope) { 1827 if (extraScope) {
1820 if (!defs.empty()) { 1828 if (!defs.empty()) {
@@ -1842,17 +1850,22 @@ private:
1842 auto targetVar = toAst<Exp_t>(valVar, destruct.value); 1850 auto targetVar = toAst<Exp_t>(valVar, destruct.value);
1843 auto newAssignment = assignmentFrom(targetVar, destruct.value, destruct.value); 1851 auto newAssignment = assignmentFrom(targetVar, destruct.value, destruct.value);
1844 transformAssignment(newAssignment, temp); 1852 transformAssignment(newAssignment, temp);
1853 auto callable = singleValueFrom(targetVar)->item.to<ChainValue_t>()->items.front();
1845 for (auto& v : values) { 1854 for (auto& v : values) {
1846 v.insert(0, valVar); 1855 v->items.push_front(callable);
1847 } 1856 }
1848 } 1857 }
1858 if (destruct.inlineAssignment) {
1859 transformAssignment(destruct.inlineAssignment, temp);
1860 }
1849 if (optionalDestruct) { 1861 if (optionalDestruct) {
1850 while (!names.empty()) { 1862 while (!names.empty()) {
1851 auto name = names.front(); 1863 auto name = names.front();
1852 names.pop_front(); 1864 names.pop_front();
1853 auto value = values.front(); 1865 auto value = values.front().get();
1866 auto valueList = value->new_ptr<ExpList_t>();
1867 valueList->exprs.push_back(newExp(value, value));
1854 values.pop_front(); 1868 values.pop_front();
1855 auto valueList = toAst<ExpList_t>(value, x);
1856 auto newAssignment = x->new_ptr<ExpListAssign_t>(); 1869 auto newAssignment = x->new_ptr<ExpListAssign_t>();
1857 auto assignList = x->new_ptr<ExpList_t>(); 1870 auto assignList = x->new_ptr<ExpList_t>();
1858 assignList->exprs.push_back(name); 1871 assignList->exprs.push_back(name);
@@ -1863,7 +1876,10 @@ private:
1863 transformAssignment(newAssignment, temp); 1876 transformAssignment(newAssignment, temp);
1864 } 1877 }
1865 } else { 1878 } else {
1866 auto valueList = toAst<ExpList_t>(join(values, ","sv), x); 1879 auto valueList = x->new_ptr<ExpList_t>();
1880 for (const auto& v : values) {
1881 valueList->exprs.push_back(newExp(v, v));
1882 }
1867 auto newAssignment = x->new_ptr<ExpListAssign_t>(); 1883 auto newAssignment = x->new_ptr<ExpListAssign_t>();
1868 auto assignList = x->new_ptr<ExpList_t>(); 1884 auto assignList = x->new_ptr<ExpList_t>();
1869 for (auto name : names) { 1885 for (auto name : names) {
@@ -1923,7 +1939,7 @@ private:
1923 1939
1924 std::list<DestructItem> destructFromExp(ast_node* node, bool optional) { 1940 std::list<DestructItem> destructFromExp(ast_node* node, bool optional) {
1925 const node_container* tableItems = nullptr; 1941 const node_container* tableItems = nullptr;
1926 auto sep = optional ? "?"s : Empty; 1942 ast_ptr<false, existential_op_t> sep = optional ? node->new_ptr<existential_op_t>() : nullptr;
1927 switch (node->getId()) { 1943 switch (node->getId()) {
1928 case id<Exp_t>(): { 1944 case id<Exp_t>(): {
1929 auto item = singleValueFrom(node)->item.get(); 1945 auto item = singleValueFrom(node)->item.get();
@@ -1965,17 +1981,20 @@ private:
1965 if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { 1981 if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) {
1966 auto subPairs = destructFromExp(pair, optional); 1982 auto subPairs = destructFromExp(pair, optional);
1967 for (auto& p : subPairs) { 1983 for (auto& p : subPairs) {
1968 pairs.push_back({p.target, p.targetVar, 1984 if (sep) p.structure->items.push_front(sep);
1969 '[' + std::to_string(index) + ']' + sep + p.structure, 1985 p.structure->items.push_front(
1970 p.defVal}); 1986 toAst<Exp_t>(std::to_string(index), p.target));
1987 pairs.push_back(p);
1971 } 1988 }
1972 } else { 1989 } else {
1973 auto exp = static_cast<Exp_t*>(pair); 1990 auto exp = static_cast<Exp_t*>(pair);
1974 auto varName = singleVariableFrom(exp, false); 1991 auto varName = singleVariableFrom(exp, false);
1975 if (varName == "_"sv) break; 1992 if (varName == "_"sv) break;
1993 auto chain = exp->new_ptr<ChainValue_t>();
1994 chain->items.push_back(toAst<Exp_t>(std::to_string(index), exp));
1976 pairs.push_back({exp, 1995 pairs.push_back({exp,
1977 varName, 1996 varName,
1978 '[' + std::to_string(index) + ']', 1997 chain,
1979 nullptr}); 1998 nullptr});
1980 } 1999 }
1981 break; 2000 break;
@@ -1983,38 +2002,55 @@ private:
1983 case id<variable_pair_t>(): { 2002 case id<variable_pair_t>(): {
1984 auto vp = static_cast<variable_pair_t*>(pair); 2003 auto vp = static_cast<variable_pair_t*>(pair);
1985 auto name = _parser.toString(vp->name); 2004 auto name = _parser.toString(vp->name);
1986 pairs.push_back({toAst<Exp_t>(name, vp).get(), name, '.' + name, nullptr}); 2005 auto chain = toAst<ChainValue_t>('.' + name, vp->name);
2006 pairs.push_back({toAst<Exp_t>(name, vp).get(),
2007 name,
2008 chain,
2009 nullptr});
1987 break; 2010 break;
1988 } 2011 }
1989 case id<normal_pair_t>(): { 2012 case id<normal_pair_t>(): {
1990 auto np = static_cast<normal_pair_t*>(pair); 2013 auto np = static_cast<normal_pair_t*>(pair);
1991 std::string keyName; 2014 ast_ptr<true, ast_node> keyIndex;
1992 if (np->key) { 2015 if (np->key) {
1993 auto key = np->key->getByPath<Name_t>(); 2016 if (auto key = np->key->getByPath<Name_t>()) {
1994 if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, np)); 2017 auto keyNameStr = _parser.toString(key);
1995 keyName = _parser.toString(key); 2018 if (LuaKeywords.find(keyNameStr) != LuaKeywords.end()) {
1996 if (LuaKeywords.find(keyName) != LuaKeywords.end()) { 2019 keyIndex = toAst<Exp_t>('"' + keyNameStr + '"', key).get();
1997 keyName = "[\""s + keyName + "\"]"s; 2020 } else {
1998 } else { 2021 keyIndex = toAst<DotChainItem_t>('.' + keyNameStr, key).get();
1999 keyName = "."s + keyName; 2022 }
2000 } 2023 } else if (auto key = np->key->getByPath<SelfName_t>()) {
2024 auto callable = np->new_ptr<Callable_t>();
2025 callable->item.set(key);
2026 auto chainValue = np->new_ptr<ChainValue_t>();
2027 chainValue->items.push_back(callable);
2028 keyIndex = newExp(chainValue, np).get();
2029 } else if (auto key = np->key.as<Exp_t>()) {
2030 keyIndex = key;
2031 } else if (auto key = np->key.as<String_t>()) {
2032 keyIndex = newExp(key, np->key).get();
2033 } else throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, np));
2001 } 2034 }
2002 if (auto exp = np->value.as<Exp_t>()) { 2035 if (auto exp = np->value.as<Exp_t>()) {
2003 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); 2036 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't do destructure value"sv, exp));
2004 auto item = singleValueFrom(exp)->item.get(); 2037 auto item = singleValueFrom(exp)->item.get();
2005 if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { 2038 if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) {
2006 auto subPairs = destructFromExp(exp, optional); 2039 auto subPairs = destructFromExp(exp, optional);
2007 for (auto& p : subPairs) { 2040 for (auto& p : subPairs) {
2008 pairs.push_back({p.target, 2041 if (keyIndex) {
2009 p.targetVar, 2042 if (sep) p.structure->items.push_front(sep);
2010 keyName + sep + p.structure, 2043 p.structure->items.push_front(keyIndex);
2011 p.defVal}); 2044 }
2045 pairs.push_back(p);
2012 } 2046 }
2013 } else { 2047 } else {
2048 auto chain = exp->new_ptr<ChainValue_t>();
2049 if (keyIndex) chain->items.push_back(keyIndex);
2014 auto varName = singleVariableFrom(exp, false); 2050 auto varName = singleVariableFrom(exp, false);
2015 pairs.push_back({exp, 2051 pairs.push_back({exp,
2016 varName, 2052 varName,
2017 keyName, 2053 chain,
2018 nullptr}); 2054 nullptr});
2019 } 2055 }
2020 break; 2056 break;
@@ -2022,10 +2058,11 @@ private:
2022 if (np->value.is<TableBlock_t>()) { 2058 if (np->value.is<TableBlock_t>()) {
2023 auto subPairs = destructFromExp(np->value, optional); 2059 auto subPairs = destructFromExp(np->value, optional);
2024 for (auto& p : subPairs) { 2060 for (auto& p : subPairs) {
2025 pairs.push_back({p.target, 2061 if (keyIndex) {
2026 p.targetVar, 2062 if (sep) p.structure->items.push_front(sep);
2027 keyName + sep + p.structure, 2063 p.structure->items.push_front(keyIndex);
2028 p.defVal}); 2064 }
2065 pairs.push_back(p);
2029 } 2066 }
2030 } 2067 }
2031 break; 2068 break;
@@ -2035,10 +2072,9 @@ private:
2035 ++index; 2072 ++index;
2036 auto subPairs = destructFromExp(tb, optional); 2073 auto subPairs = destructFromExp(tb, optional);
2037 for (auto& p : subPairs) { 2074 for (auto& p : subPairs) {
2038 pairs.push_back({p.target, 2075 if (sep) p.structure->items.push_front(sep);
2039 p.targetVar, 2076 p.structure->items.push_front(toAst<Exp_t>(std::to_string(index), tb));
2040 '[' + std::to_string(index) + ']' + sep + p.structure, 2077 pairs.push_back(p);
2041 p.defVal});
2042 } 2078 }
2043 break; 2079 break;
2044 } 2080 }
@@ -2057,34 +2093,45 @@ private:
2057 auto varName = singleVariableFrom(exp, false); 2093 auto varName = singleVariableFrom(exp, false);
2058 pairs.push_back({exp, 2094 pairs.push_back({exp,
2059 varName, 2095 varName,
2060 '[' + std::to_string(index) + ']', 2096 toAst<ChainValue_t>('[' + std::to_string(index) + ']', value),
2061 dp->defVal}); 2097 dp->defVal});
2062 } 2098 }
2063 break; 2099 break;
2064 } 2100 }
2065 std::string keyName, valueStr; 2101 auto chain = dp->new_ptr<ChainValue_t>();
2102 std::string valueStr;
2066 if (dp->key) { 2103 if (dp->key) {
2067 auto key = dp->key->getByPath<Name_t>(); 2104 if (auto key = dp->key->getByPath<Name_t>()) {
2068 if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, dp)); 2105 auto keyName = _parser.toString(key);
2069 keyName = _parser.toString(key); 2106 if (!dp->value) valueStr = keyName;
2070 if (!dp->value) valueStr = keyName; 2107 if (LuaKeywords.find(keyName) != LuaKeywords.end()) {
2071 if (LuaKeywords.find(keyName) != LuaKeywords.end()) { 2108 chain->items.push_back(toAst<Exp_t>('"' + keyName + '"', key));
2072 keyName = "[\""s + keyName + "\"]"s; 2109 } else {
2073 } else { 2110 chain->items.push_back(toAst<DotChainItem_t>('.' + keyName, key));
2074 keyName = "."s + keyName; 2111 }
2075 } 2112 } else if (auto key = dp->key->getByPath<SelfName_t>()) {
2113 auto callable = dp->new_ptr<Callable_t>();
2114 callable->item.set(key);
2115 auto chainValue = dp->new_ptr<ChainValue_t>();
2116 chainValue->items.push_back(callable);
2117 chain->items.push_back(newExp(chainValue, dp));
2118 } else if (auto key = dp->key.as<String_t>()) {
2119 chain->items.push_back(newExp(key, dp));
2120 } else if (auto key = dp->key.as<Exp_t>()) {
2121 chain->items.push_back(key);
2122 } else throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, dp));
2076 } 2123 }
2077 if (auto exp = dp->value.get()) { 2124 if (auto exp = dp->value.get()) {
2078 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); 2125 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp));
2079 auto varName = singleVariableFrom(exp, false); 2126 auto varName = singleVariableFrom(exp, false);
2080 pairs.push_back({exp, 2127 pairs.push_back({exp,
2081 varName, 2128 varName,
2082 keyName, 2129 chain,
2083 dp->defVal}); 2130 dp->defVal});
2084 } else { 2131 } else {
2085 pairs.push_back({toAst<Exp_t>(valueStr, dp).get(), 2132 pairs.push_back({toAst<Exp_t>(valueStr, dp).get(),
2086 valueStr, 2133 valueStr,
2087 keyName, 2134 chain,
2088 dp->defVal}); 2135 dp->defVal});
2089 } 2136 }
2090 break; 2137 break;
@@ -2093,6 +2140,9 @@ private:
2093 auto mp = static_cast<meta_default_pair_t*>(pair); 2140 auto mp = static_cast<meta_default_pair_t*>(pair);
2094 auto newPair = pair->new_ptr<default_pair_t>(); 2141 auto newPair = pair->new_ptr<default_pair_t>();
2095 if (mp->key) { 2142 if (mp->key) {
2143 if (!ast_is<Variable_t, Name_t>(mp->key)) {
2144 throw std::logic_error(_info.errorMessage("destructuring with metatable accessed by expression is not supported."sv, mp->key));
2145 }
2096 auto key = _parser.toString(mp->key); 2146 auto key = _parser.toString(mp->key);
2097 _buf << "__"sv << key; 2147 _buf << "__"sv << key;
2098 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); 2148 auto newKey = toAst<KeyName_t>(clearBuf(), mp->key);
@@ -2145,14 +2195,16 @@ private:
2145 if (!subMetaDestruct->values.empty()) { 2195 if (!subMetaDestruct->values.empty()) {
2146 auto simpleValue = subMetaDestruct->new_ptr<SimpleValue_t>(); 2196 auto simpleValue = subMetaDestruct->new_ptr<SimpleValue_t>();
2147 simpleValue->value.set(subMetaDestruct); 2197 simpleValue->value.set(subMetaDestruct);
2148 auto value = subMetaDestruct->new_ptr<Value_t>(); 2198 auto subPairs = destructFromExp(newExp(simpleValue, subMetaDestruct), optional);
2149 value->item.set(simpleValue);
2150 auto subPairs = destructFromExp(newExp(value, subMetaDestruct), optional);
2151 for (const auto& p : subPairs) { 2199 for (const auto& p : subPairs) {
2152 pairs.push_back({p.target, 2200 if (!p.structure->items.empty()) {
2153 p.targetVar, 2201 if (sep) p.structure->items.push_front(sep);
2154 ".#"s + (p.structure.empty() ? Empty : sep + p.structure), 2202 }
2155 p.defVal}); 2203 auto mt = p.structure->new_ptr<Metatable_t>();
2204 auto dot = mt->new_ptr<DotChainItem_t>();
2205 dot->name.set(mt);
2206 p.structure->items.push_front(dot);
2207 pairs.push_back(p);
2156 } 2208 }
2157 } 2209 }
2158 return pairs; 2210 return pairs;
@@ -2258,6 +2310,12 @@ private:
2258 case id<Exp_t>(): 2310 case id<Exp_t>():
2259 newPair->key.set(mp->key); 2311 newPair->key.set(mp->key);
2260 break; 2312 break;
2313 case id<String_t>(): {
2314 auto value = mp->new_ptr<Value_t>();
2315 value->item.set(mp->key);
2316 newPair->key.set(newExp(value, mp));
2317 break;
2318 }
2261 default: YUEE("AST node mismatch", mp->key); break; 2319 default: YUEE("AST node mismatch", mp->key); break;
2262 } 2320 }
2263 } 2321 }
@@ -2289,9 +2347,7 @@ private:
2289 } 2347 }
2290 auto simpleValue = tab->new_ptr<SimpleValue_t>(); 2348 auto simpleValue = tab->new_ptr<SimpleValue_t>();
2291 simpleValue->value.set(tab); 2349 simpleValue->value.set(tab);
2292 auto value = tab->new_ptr<Value_t>(); 2350 auto pairs = destructFromExp(newExp(simpleValue, expr), optional);
2293 value->item.set(simpleValue);
2294 auto pairs = destructFromExp(newExp(value, expr), optional);
2295 if (pairs.empty()) { 2351 if (pairs.empty()) {
2296 throw std::logic_error(_info.errorMessage("expect items to be destructured"sv, tab)); 2352 throw std::logic_error(_info.errorMessage("expect items to be destructured"sv, tab));
2297 } 2353 }
@@ -2299,15 +2355,13 @@ private:
2299 if (!varDefOnly) { 2355 if (!varDefOnly) {
2300 if (*j == nil) { 2356 if (*j == nil) {
2301 for (auto& item : destruct.items) { 2357 for (auto& item : destruct.items) {
2302 item.structure.clear(); 2358 item.structure = nullptr;
2303 } 2359 }
2304 } else if (tab == subMetaDestruct.get()) { 2360 } else if (tab == subMetaDestruct.get()) {
2305 auto p = destruct.value.get(); 2361 auto p = destruct.value.get();
2306 auto chainValue = toAst<ChainValue_t>("getmetatable()", p); 2362 auto chainValue = toAst<ChainValue_t>("getmetatable()", p);
2307 static_cast<Invoke_t*>(chainValue->items.back())->args.push_back(destruct.value); 2363 static_cast<Invoke_t*>(chainValue->items.back())->args.push_back(destruct.value);
2308 auto value = p->new_ptr<Value_t>(); 2364 auto exp = newExp(chainValue, p);
2309 value->item.set(chainValue);
2310 auto exp = newExp(value, p);
2311 destruct.value.set(exp); 2365 destruct.value.set(exp);
2312 destruct.valueVar.clear(); 2366 destruct.valueVar.clear();
2313 } else if (destruct.items.size() == 1 && !singleValueFrom(*j)) { 2367 } else if (destruct.items.size() == 1 && !singleValueFrom(*j)) {
@@ -2318,9 +2372,7 @@ private:
2318 callable->item.set(parens); 2372 callable->item.set(parens);
2319 auto chainValue = p->new_ptr<ChainValue_t>(); 2373 auto chainValue = p->new_ptr<ChainValue_t>();
2320 chainValue->items.push_back(callable); 2374 chainValue->items.push_back(callable);
2321 auto value = p->new_ptr<Value_t>(); 2375 auto exp = newExp(chainValue, p);
2322 value->item.set(chainValue);
2323 auto exp = newExp(value, p);
2324 destruct.value.set(exp); 2376 destruct.value.set(exp);
2325 destruct.valueVar.clear(); 2377 destruct.valueVar.clear();
2326 } 2378 }
@@ -2346,6 +2398,51 @@ private:
2346 newAssign->action.set(assign); 2398 newAssign->action.set(assign);
2347 newAssignment = newAssign; 2399 newAssignment = newAssign;
2348 } 2400 }
2401 if (!varDefOnly) {
2402 pushScope();
2403 for (auto& des : destructs) {
2404 for (const auto& item : des.items) {
2405 for (auto node : item.structure->items.objects()) {
2406 if (auto exp = ast_cast<Exp_t>(node)) {
2407 if (auto value = simpleSingleValueFrom(node)) {
2408 if (ast_is<Num_t, const_value_t>(value->value)) {
2409 continue;
2410 }
2411 }
2412 if (auto value = singleValueFrom(exp); !value || !value->item.is<String_t>()) {
2413 auto var = singleVariableFrom(exp, false);
2414 if (var.empty()) {
2415 if (!des.inlineAssignment) {
2416 des.inlineAssignment = x->new_ptr<ExpListAssign_t>();
2417 auto expList = x->new_ptr<ExpList_t>();
2418 des.inlineAssignment->expList.set(expList);
2419 auto assign = x->new_ptr<Assign_t>();
2420 des.inlineAssignment->action.set(assign);
2421 }
2422 auto assignList = des.inlineAssignment->expList.get();
2423 auto assign = des.inlineAssignment->action.to<Assign_t>();
2424 auto tmpVar = getUnusedName("_tmp_"sv);
2425 addToScope(tmpVar);
2426 auto tmpExp = toAst<Exp_t>(tmpVar, exp);
2427 assignList->exprs.push_back(tmpExp);
2428 auto vExp = exp->new_ptr<Exp_t>();
2429 vExp->pipeExprs.dup(exp->pipeExprs);
2430 vExp->opValues.dup(exp->opValues);
2431 vExp->nilCoalesed.set(exp->nilCoalesed);
2432 exp->pipeExprs.clear();
2433 exp->pipeExprs.dup(tmpExp->pipeExprs);
2434 exp->opValues.clear();
2435 exp->opValues.dup(tmpExp->opValues);
2436 exp->nilCoalesed = tmpExp->nilCoalesed;
2437 assign->values.push_back(vExp);
2438 }
2439 }
2440 }
2441 }
2442 }
2443 }
2444 popScope();
2445 }
2349 return {std::move(destructs), newAssignment}; 2446 return {std::move(destructs), newAssignment};
2350 } 2447 }
2351 2448
@@ -2385,9 +2482,7 @@ private:
2385 tmpChain->items.push_back(item); 2482 tmpChain->items.push_back(item);
2386 } 2483 }
2387 } 2484 }
2388 auto value = x->new_ptr<Value_t>(); 2485 auto exp = newExp(tmpChain, x);
2389 value->item.set(tmpChain);
2390 auto exp = newExp(value, x);
2391 auto objVar = getUnusedName("_obj_"sv); 2486 auto objVar = getUnusedName("_obj_"sv);
2392 auto newAssignment = x->new_ptr<ExpListAssign_t>(); 2487 auto newAssignment = x->new_ptr<ExpListAssign_t>();
2393 newAssignment->expList.set(toAst<ExpList_t>(objVar, x)); 2488 newAssignment->expList.set(toAst<ExpList_t>(objVar, x));
@@ -2518,9 +2613,7 @@ private:
2518 ns.clear(); 2613 ns.clear();
2519 auto simpleValue = x->new_ptr<SimpleValue_t>(); 2614 auto simpleValue = x->new_ptr<SimpleValue_t>();
2520 simpleValue->value.set(newIf); 2615 simpleValue->value.set(newIf);
2521 auto value = x->new_ptr<Value_t>(); 2616 auto exp = newExp(simpleValue, x);
2522 value->item.set(simpleValue);
2523 auto exp = newExp(value, x);
2524 auto expList = x->new_ptr<ExpList_t>(); 2617 auto expList = x->new_ptr<ExpList_t>();
2525 expList->exprs.push_back(exp); 2618 expList->exprs.push_back(exp);
2526 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 2619 auto expListAssign = x->new_ptr<ExpListAssign_t>();
@@ -3129,9 +3222,7 @@ private:
3129 funLit->body.set(body); 3222 funLit->body.set(body);
3130 auto simpleValue = x->new_ptr<SimpleValue_t>(); 3223 auto simpleValue = x->new_ptr<SimpleValue_t>();
3131 simpleValue->value.set(funLit); 3224 simpleValue->value.set(funLit);
3132 auto value = x->new_ptr<Value_t>(); 3225 arg = newExp(simpleValue, x);
3133 value->item.set(simpleValue);
3134 arg = newExp(value, x);
3135 } 3226 }
3136 if (isChainValueCall(backcall->value)) { 3227 if (isChainValueCall(backcall->value)) {
3137 auto last = backcall->value->items.back(); 3228 auto last = backcall->value->items.back();
@@ -3164,9 +3255,7 @@ private:
3164 auto newStmt = x->new_ptr<Statement_t>(); 3255 auto newStmt = x->new_ptr<Statement_t>();
3165 { 3256 {
3166 auto chainValue = backcall->value.get(); 3257 auto chainValue = backcall->value.get();
3167 auto value = x->new_ptr<Value_t>(); 3258 auto exp = newExp(chainValue, x);
3168 value->item.set(chainValue);
3169 auto exp = newExp(value, x);
3170 auto expList = x->new_ptr<ExpList_t>(); 3259 auto expList = x->new_ptr<ExpList_t>();
3171 expList->exprs.push_back(exp); 3260 expList->exprs.push_back(exp);
3172 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 3261 auto expListAssign = x->new_ptr<ExpListAssign_t>();
@@ -3329,9 +3418,7 @@ private:
3329 } else { 3418 } else {
3330 auto simpleValue = x->new_ptr<SimpleValue_t>(); 3419 auto simpleValue = x->new_ptr<SimpleValue_t>();
3331 simpleValue->value.set(last->content); 3420 simpleValue->value.set(last->content);
3332 auto value = x->new_ptr<Value_t>(); 3421 auto exp = newExp(simpleValue, x);
3333 value->item.set(simpleValue);
3334 auto exp = newExp(value, x);
3335 assign->values.push_back(exp); 3422 assign->values.push_back(exp);
3336 } 3423 }
3337 newAssignment->action.set(assign); 3424 newAssignment->action.set(assign);
@@ -3857,9 +3944,7 @@ private:
3857 callable->item.set(parens); 3944 callable->item.set(parens);
3858 auto chainValue = x->new_ptr<ChainValue_t>(); 3945 auto chainValue = x->new_ptr<ChainValue_t>();
3859 chainValue->items.push_back(callable); 3946 chainValue->items.push_back(callable);
3860 auto value = x->new_ptr<Value_t>(); 3947 auto exp = newExp(chainValue, x);
3861 value->item.set(chainValue);
3862 auto exp = newExp(value, x);
3863 auto assignment = x->new_ptr<ExpListAssign_t>(); 3948 auto assignment = x->new_ptr<ExpListAssign_t>();
3864 assignment->expList.set(assignList); 3949 assignment->expList.set(assignList);
3865 auto assign = x->new_ptr<Assign_t>(); 3950 auto assign = x->new_ptr<Assign_t>();
@@ -3949,9 +4034,7 @@ private:
3949 if (!newObj.empty()) { 4034 if (!newObj.empty()) {
3950 objVar = newObj; 4035 objVar = newObj;
3951 } else { 4036 } else {
3952 auto value = x->new_ptr<Value_t>(); 4037 auto exp = newExp(chainValue, x);
3953 value->item.set(chainValue);
3954 auto exp = newExp(value, x);
3955 auto assign = x->new_ptr<Assign_t>(); 4038 auto assign = x->new_ptr<Assign_t>();
3956 assign->values.push_back(exp); 4039 assign->values.push_back(exp);
3957 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 4040 auto expListAssign = x->new_ptr<ExpListAssign_t>();
@@ -3981,9 +4064,7 @@ private:
3981 } 4064 }
3982 objVar = getUnusedName("_obj_"sv); 4065 objVar = getUnusedName("_obj_"sv);
3983 } 4066 }
3984 auto value = x->new_ptr<Value_t>(); 4067 auto exp = newExp(partOne, x);
3985 value->item.set(partOne);
3986 auto exp = newExp(value, x);
3987 auto assign = x->new_ptr<Assign_t>(); 4068 auto assign = x->new_ptr<Assign_t>();
3988 assign->values.push_back(exp); 4069 assign->values.push_back(exp);
3989 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 4070 auto expListAssign = x->new_ptr<ExpListAssign_t>();
@@ -4004,9 +4085,7 @@ private:
4004 transformChainValue(partTwo, temp, ExpUsage::Common); 4085 transformChainValue(partTwo, temp, ExpUsage::Common);
4005 break; 4086 break;
4006 case ExpUsage::Assignment: { 4087 case ExpUsage::Assignment: {
4007 auto value = x->new_ptr<Value_t>(); 4088 auto exp = newExp(partTwo, x);
4008 value->item.set(partTwo);
4009 auto exp = newExp(value, x);
4010 auto assign = x->new_ptr<Assign_t>(); 4089 auto assign = x->new_ptr<Assign_t>();
4011 assign->values.push_back(exp); 4090 assign->values.push_back(exp);
4012 auto assignment = x->new_ptr<ExpListAssign_t>(); 4091 auto assignment = x->new_ptr<ExpListAssign_t>();
@@ -4017,9 +4096,7 @@ private:
4017 } 4096 }
4018 case ExpUsage::Return: 4097 case ExpUsage::Return:
4019 case ExpUsage::Closure: { 4098 case ExpUsage::Closure: {
4020 auto value = x->new_ptr<Value_t>(); 4099 auto exp = newExp(partTwo, x);
4021 value->item.set(partTwo);
4022 auto exp = newExp(value, x);
4023 auto ret = x->new_ptr<Return_t>(); 4100 auto ret = x->new_ptr<Return_t>();
4024 auto expListLow = x->new_ptr<ExpListLow_t>(); 4101 auto expListLow = x->new_ptr<ExpListLow_t>();
4025 expListLow->exprs.push_back(exp); 4102 expListLow->exprs.push_back(exp);
@@ -4095,9 +4172,7 @@ private:
4095 auto baseVar = getUnusedName("_base_"sv); 4172 auto baseVar = getUnusedName("_base_"sv);
4096 auto fnVar = getUnusedName("_fn_"sv); 4173 auto fnVar = getUnusedName("_fn_"sv);
4097 { 4174 {
4098 auto value = x->new_ptr<Value_t>(); 4175 auto exp = newExp(baseChain, x);
4099 value->item.set(baseChain);
4100 auto exp = newExp(value, x);
4101 auto assign = x->new_ptr<Assign_t>(); 4176 auto assign = x->new_ptr<Assign_t>();
4102 assign->values.push_back(exp); 4177 assign->values.push_back(exp);
4103 auto assignment = x->new_ptr<ExpListAssign_t>(); 4178 auto assignment = x->new_ptr<ExpListAssign_t>();
@@ -4183,26 +4258,124 @@ private:
4183 for (auto it = chainList.begin(); it != opIt; ++it) { 4258 for (auto it = chainList.begin(); it != opIt; ++it) {
4184 chain->items.push_back(*it); 4259 chain->items.push_back(*it);
4185 } 4260 }
4186 auto value = x->new_ptr<Value_t>(); 4261 {
4187 value->item.set(chain); 4262 auto exp = newExp(chain, x);
4188 auto exp = newExp(value, x); 4263 chain = toAst<ChainValue_t>("getmetatable()"sv, x);
4189 4264 ast_to<Invoke_t>(chain->items.back())->args.push_back(exp);
4190 chain = toAst<ChainValue_t>("getmetatable()"sv, x); 4265 }
4191 ast_to<Invoke_t>(chain->items.back())->args.push_back(exp);
4192 switch ((*opIt)->getId()) { 4266 switch ((*opIt)->getId()) {
4193 case id<ColonChainItem_t>(): { 4267 case id<ColonChainItem_t>(): {
4194 auto colon = static_cast<ColonChainItem_t*>(*opIt); 4268 auto colon = static_cast<ColonChainItem_t*>(*opIt);
4195 auto meta = colon->name.to<Metamethod_t>(); 4269 auto meta = colon->name.to<Metamethod_t>();
4196 auto newColon = toAst<ColonChainItem_t>("\\__"s + _parser.toString(meta->name), x); 4270 switch (meta->item->getId()) {
4197 chain->items.push_back(newColon); 4271 case id<Name_t>(): {
4272 auto newColon = toAst<ColonChainItem_t>("\\__"s + _parser.toString(meta->item), x);
4273 chain->items.push_back(newColon);
4274 break;
4275 }
4276 case id<String_t>():
4277 case id<Exp_t>(): {
4278 str_list temp;
4279 std::string* funcStart = nullptr;
4280 if (usage == ExpUsage::Closure) {
4281 _enableReturn.push(true);
4282 pushAnonVarArg();
4283 funcStart = &temp.emplace_back();
4284 pushScope();
4285 } else if (usage != ExpUsage::Return) {
4286 temp.push_back(indent() + "do"s + nll(x));
4287 pushScope();
4288 }
4289 auto var = getUnusedName("_obj_"sv);
4290 auto target = toAst<Exp_t>(var, x);
4291 {
4292 auto assignment = assignmentFrom(target, newExp(chain, x), x);
4293 transformAssignment(assignment, temp);
4294 }
4295 auto newChain = toAst<ChainValue_t>(var, x);
4296 if (auto str = meta->item.as<String_t>()) {
4297 newChain->items.push_back(newExp(str, x));
4298 } else {
4299 newChain->items.push_back(meta->item);
4300 }
4301 auto newChainExp = newExp(newChain, x);
4302 for (auto it = ++opIt; it != chainList.end(); ++it) {
4303 newChain->items.push_back(*it);
4304 }
4305 auto last = newChain->items.back();
4306 if (ast_is<Invoke_t, InvokeArgs_t>(last)) {
4307 if (auto invoke = ast_cast<InvokeArgs_t>(last)) {
4308 invoke->args.push_front(target);
4309 } else {
4310 ast_to<Invoke_t>(last)->args.push_front(target);
4311 }
4312 }
4313 switch (usage) {
4314 case ExpUsage::Closure: {
4315 auto returnNode = x->new_ptr<Return_t>();
4316 auto values = x->new_ptr<ExpListLow_t>();
4317 values->exprs.push_back(newChainExp);
4318 returnNode->valueList.set(values);
4319 transformReturn(returnNode, temp);
4320 popScope();
4321 *funcStart = anonFuncStart() + nll(x);
4322 temp.push_back(indent() + anonFuncEnd());
4323 popAnonVarArg();
4324 _enableReturn.pop();
4325 break;
4326 }
4327 case ExpUsage::Return: {
4328 auto returnNode = x->new_ptr<Return_t>();
4329 auto values = x->new_ptr<ExpListLow_t>();
4330 values->exprs.push_back(newChainExp);
4331 returnNode->valueList.set(values);
4332 transformReturn(returnNode, temp);
4333 break;
4334 }
4335 case ExpUsage::Assignment: {
4336 auto assignment = x->new_ptr<ExpListAssign_t>();
4337 assignment->expList.set(assignList);
4338 auto assign = x->new_ptr<Assign_t>();
4339 assign->values.push_back(newChainExp);
4340 assignment->action.set(assign);
4341 transformAssignment(assignment, temp);
4342 popScope();
4343 temp.push_back(indent() + "end"s + nlr(x));
4344 break;
4345 }
4346 case ExpUsage::Common:
4347 transformExp(newChainExp, temp, usage);
4348 popScope();
4349 temp.push_back(indent() + "end"s + nlr(x));
4350 break;
4351 }
4352 out.push_back(join(temp));
4353 return true;
4354 }
4355 default: YUEE("AST node mismatch", meta->item); break;
4356 }
4198 break; 4357 break;
4199 } 4358 }
4200 case id<DotChainItem_t>(): { 4359 case id<DotChainItem_t>(): {
4201 auto dot = static_cast<DotChainItem_t*>(*opIt); 4360 auto dot = static_cast<DotChainItem_t*>(*opIt);
4202 if (dot->name.is<Metatable_t>()) break; 4361 if (dot->name.is<Metatable_t>()) break;
4203 auto meta = dot->name.to<Metamethod_t>(); 4362 auto meta = dot->name.to<Metamethod_t>();
4204 auto newDot = toAst<DotChainItem_t>(".__"s + _parser.toString(meta->name), x); 4363 switch (meta->item->getId()) {
4205 chain->items.push_back(newDot); 4364 case id<Name_t>(): {
4365 auto newDot = toAst<DotChainItem_t>(".__"s + _parser.toString(meta->item), x);
4366 chain->items.push_back(newDot);
4367 break;
4368 }
4369 case id<Exp_t>():
4370 chain->items.push_back(meta->item);
4371 break;
4372 case id<String_t>(): {
4373 auto str = static_cast<String_t*>(meta->item.get());
4374 chain->items.push_back(newExp(str, x));
4375 break;
4376 }
4377 default: YUEE("AST node mismatch", meta->item); break;
4378 }
4206 break; 4379 break;
4207 } 4380 }
4208 } 4381 }
@@ -4276,9 +4449,7 @@ private:
4276 for (auto i = chainList.begin(); i != current; ++i) { 4449 for (auto i = chainList.begin(); i != current; ++i) {
4277 chainValue->items.push_back(*i); 4450 chainValue->items.push_back(*i);
4278 } 4451 }
4279 auto value = x->new_ptr<Value_t>(); 4452 auto exp = newExp(chainValue, x);
4280 value->item.set(chainValue);
4281 auto exp = newExp(value, x);
4282 callVar = singleVariableFrom(exp, true); 4453 callVar = singleVariableFrom(exp, true);
4283 if (callVar.empty()) { 4454 if (callVar.empty()) {
4284 callVar = getUnusedName("_call_"s); 4455 callVar = getUnusedName("_call_"s);
@@ -4310,9 +4481,7 @@ private:
4310 for (auto i = next; i != chainList.end(); ++i) { 4481 for (auto i = next; i != chainList.end(); ++i) {
4311 chainValue->items.push_back(*i); 4482 chainValue->items.push_back(*i);
4312 } 4483 }
4313 auto value = x->new_ptr<Value_t>(); 4484 nexp = newExp(chainValue, x);
4314 value->item.set(chainValue);
4315 nexp = newExp(value, x);
4316 auto expList = x->new_ptr<ExpList_t>(); 4485 auto expList = x->new_ptr<ExpList_t>();
4317 expList->exprs.push_back(nexp); 4486 expList->exprs.push_back(nexp);
4318 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 4487 auto expListAssign = x->new_ptr<ExpListAssign_t>();
@@ -4342,9 +4511,7 @@ private:
4342 funLit->body.set(body); 4511 funLit->body.set(body);
4343 auto simpleValue = x->new_ptr<SimpleValue_t>(); 4512 auto simpleValue = x->new_ptr<SimpleValue_t>();
4344 simpleValue->value.set(funLit); 4513 simpleValue->value.set(funLit);
4345 auto value = x->new_ptr<Value_t>(); 4514 auto exp = newExp(simpleValue, x);
4346 value->item.set(simpleValue);
4347 auto exp = newExp(value, x);
4348 auto paren = x->new_ptr<Parens_t>(); 4515 auto paren = x->new_ptr<Parens_t>();
4349 paren->expr.set(exp); 4516 paren->expr.set(exp);
4350 auto callable = x->new_ptr<Callable_t>(); 4517 auto callable = x->new_ptr<Callable_t>();
@@ -4679,9 +4846,7 @@ private:
4679 for (; it != chainList.end(); ++it) { 4846 for (; it != chainList.end(); ++it) {
4680 newChain->items.push_back(*it); 4847 newChain->items.push_back(*it);
4681 } 4848 }
4682 auto value = x->new_ptr<Value_t>(); 4849 exp = newExp(newChain, x);
4683 value->item.set(newChain);
4684 exp = newExp(value, x);
4685 } 4850 }
4686 if (usage == ExpUsage::Common) { 4851 if (usage == ExpUsage::Common) {
4687 auto expList = x->new_ptr<ExpList_t>(); 4852 auto expList = x->new_ptr<ExpList_t>();
@@ -4961,9 +5126,7 @@ private:
4961 callable->item.set(selfName); 5126 callable->item.set(selfName);
4962 auto chainValue = x->new_ptr<ChainValue_t>(); 5127 auto chainValue = x->new_ptr<ChainValue_t>();
4963 chainValue->items.push_back(callable); 5128 chainValue->items.push_back(callable);
4964 auto value = x->new_ptr<Value_t>(); 5129 auto exp = newExp(chainValue, key);
4965 value->item.set(chainValue);
4966 auto exp = newExp(value, key);
4967 chainItem = exp.get(); 5130 chainItem = exp.get();
4968 } 5131 }
4969 chainValue->items.push_back(chainItem); 5132 chainValue->items.push_back(chainItem);
@@ -5034,7 +5197,7 @@ private:
5034 case id<meta_variable_pair_t>(): { 5197 case id<meta_variable_pair_t>(): {
5035 auto metaVarPair = static_cast<meta_variable_pair_t*>(item); 5198 auto metaVarPair = static_cast<meta_variable_pair_t*>(item);
5036 auto nameStr = _parser.toString(metaVarPair->name); 5199 auto nameStr = _parser.toString(metaVarPair->name);
5037 auto assignment = toAst<ExpListAssign_t>(tableVar + '.' + nameStr + "#="s + nameStr, item); 5200 auto assignment = toAst<ExpListAssign_t>(tableVar + ".<"s + nameStr + ">="s + nameStr, item);
5038 transformAssignment(assignment, temp); 5201 transformAssignment(assignment, temp);
5039 break; 5202 break;
5040 } 5203 }
@@ -5051,8 +5214,10 @@ private:
5051 break; 5214 break;
5052 } 5215 }
5053 case id<Exp_t>(): { 5216 case id<Exp_t>(): {
5054 auto dotItem = toAst<DotChainItem_t>(".#"sv, key); 5217 auto mt = key->new_ptr<Metatable_t>();
5055 chainValue->items.push_back(dotItem); 5218 auto dot = mt->new_ptr<DotChainItem_t>();
5219 dot->name.set(mt);
5220 chainValue->items.push_back(dot);
5056 chainValue->items.push_back(key); 5221 chainValue->items.push_back(key);
5057 break; 5222 break;
5058 } 5223 }
@@ -5158,6 +5323,11 @@ private:
5158 case id<Exp_t>(): 5323 case id<Exp_t>():
5159 newPair->key.set(mp->key); 5324 newPair->key.set(mp->key);
5160 break; 5325 break;
5326 case id<String_t>(): {
5327 auto str = static_cast<String_t*>(mp->key.get());
5328 newPair->key.set(newExp(str, mp));
5329 break;
5330 }
5161 default: YUEE("AST node mismatch", mp->key); break; 5331 default: YUEE("AST node mismatch", mp->key); break;
5162 } 5332 }
5163 newPair->value.set(mp->value); 5333 newPair->value.set(mp->value);
@@ -5504,9 +5674,7 @@ private:
5504 for (auto& pair : destructPairs) { 5674 for (auto& pair : destructPairs) {
5505 auto sValue = x->new_ptr<SimpleValue_t>(); 5675 auto sValue = x->new_ptr<SimpleValue_t>();
5506 sValue->value.set(pair.first); 5676 sValue->value.set(pair.first);
5507 auto value = x->new_ptr<Value_t>(); 5677 auto exp = newExp(sValue, x);
5508 value->item.set(sValue);
5509 auto exp = newExp(value, x);
5510 auto expList = x->new_ptr<ExpList_t>(); 5678 auto expList = x->new_ptr<ExpList_t>();
5511 expList->exprs.push_back(exp); 5679 expList->exprs.push_back(exp);
5512 auto assign = x->new_ptr<Assign_t>(); 5680 auto assign = x->new_ptr<Assign_t>();
@@ -5918,18 +6086,26 @@ private:
5918 transformExp(static_cast<Exp_t*>(key), temp, ExpUsage::Closure); 6086 transformExp(static_cast<Exp_t*>(key), temp, ExpUsage::Closure);
5919 temp.back() = (temp.back().front() == '[' ? "[ "s : "["s) + temp.back() + ']'; 6087 temp.back() = (temp.back().front() == '[' ? "[ "s : "["s) + temp.back() + ']';
5920 break; 6088 break;
5921 case id<DoubleString_t>(): 6089 case id<String_t>(): {
5922 transformDoubleString(static_cast<DoubleString_t*>(key), temp); 6090 auto strNode = static_cast<String_t*>(key);
5923 temp.back() = '[' + temp.back() + ']'; 6091 auto str = strNode->str.get();
5924 break; 6092 switch (str->getId()) {
5925 case id<SingleString_t>(): 6093 case id<DoubleString_t>():
5926 transformSingleString(static_cast<SingleString_t*>(key), temp); 6094 transformDoubleString(static_cast<DoubleString_t*>(str), temp);
5927 temp.back() = '[' + temp.back() + ']'; 6095 temp.back() = '[' + temp.back() + ']';
5928 break; 6096 break;
5929 case id<LuaString_t>(): 6097 case id<SingleString_t>():
5930 transformLuaString(static_cast<LuaString_t*>(key), temp); 6098 transformSingleString(static_cast<SingleString_t*>(str), temp);
5931 temp.back() = "[ "s + temp.back() + ']'; 6099 temp.back() = '[' + temp.back() + ']';
6100 break;
6101 case id<LuaString_t>():
6102 transformLuaString(static_cast<LuaString_t*>(str), temp);
6103 temp.back() = "[ "s + temp.back() + ']';
6104 break;
6105 default: YUEE("AST node mismatch", str); break;
6106 }
5932 break; 6107 break;
6108 }
5933 default: YUEE("AST node mismatch", key); break; 6109 default: YUEE("AST node mismatch", key); break;
5934 } 6110 }
5935 auto value = pair->value.get(); 6111 auto value = pair->value.get();
@@ -6308,6 +6484,8 @@ private:
6308 if (auto name = mtPair->key.as<Name_t>()) { 6484 if (auto name = mtPair->key.as<Name_t>()) {
6309 auto nameStr = _parser.toString(name); 6485 auto nameStr = _parser.toString(name);
6310 normal_pair->key.set(toAst<KeyName_t>("__"s + nameStr, keyValue)); 6486 normal_pair->key.set(toAst<KeyName_t>("__"s + nameStr, keyValue));
6487 } else if (auto str = mtPair->key.as<String_t>()) {
6488 normal_pair->key.set(newExp(str, str));
6311 } else { 6489 } else {
6312 normal_pair->key.set(mtPair->key); 6490 normal_pair->key.set(mtPair->key);
6313 } 6491 }
@@ -6624,9 +6802,7 @@ private:
6624 callable->item.set(name); 6802 callable->item.set(name);
6625 auto chainValue = x->new_ptr<ChainValue_t>(); 6803 auto chainValue = x->new_ptr<ChainValue_t>();
6626 chainValue->items.push_back(callable); 6804 chainValue->items.push_back(callable);
6627 auto value = x->new_ptr<Value_t>(); 6805 auto exp = newExp(chainValue, x);
6628 value->item.set(chainValue);
6629 auto exp = newExp(value, x);
6630 expList->exprs.push_back(exp); 6806 expList->exprs.push_back(exp);
6631 } 6807 }
6632 auto assignment = x->new_ptr<ExpListAssign_t>(); 6808 auto assignment = x->new_ptr<ExpListAssign_t>();
@@ -6979,18 +7155,14 @@ private:
6979 auto chainValue = x->new_ptr<ChainValue_t>(); 7155 auto chainValue = x->new_ptr<ChainValue_t>();
6980 chainValue->items.push_back(callable); 7156 chainValue->items.push_back(callable);
6981 chainValue->items.push_back(dotChainItem); 7157 chainValue->items.push_back(dotChainItem);
6982 auto value = x->new_ptr<Value_t>(); 7158 auto exp = newExp(chainValue, x);
6983 value->item.set(chainValue);
6984 auto exp = newExp(value, x);
6985 assign->values.push_back(exp); 7159 assign->values.push_back(exp);
6986 } 7160 }
6987 auto callable = x->new_ptr<Callable_t>(); 7161 auto callable = x->new_ptr<Callable_t>();
6988 callable->item.set(var); 7162 callable->item.set(var);
6989 auto chainValue = x->new_ptr<ChainValue_t>(); 7163 auto chainValue = x->new_ptr<ChainValue_t>();
6990 chainValue->items.push_back(callable); 7164 chainValue->items.push_back(callable);
6991 auto value = x->new_ptr<Value_t>(); 7165 auto exp = newExp(chainValue, x);
6992 value->item.set(chainValue);
6993 auto exp = newExp(value, x);
6994 expList->exprs.push_back(exp); 7166 expList->exprs.push_back(exp);
6995 break; 7167 break;
6996 } 7168 }
@@ -7004,18 +7176,14 @@ private:
7004 auto chainValue = x->new_ptr<ChainValue_t>(); 7176 auto chainValue = x->new_ptr<ChainValue_t>();
7005 chainValue->items.push_back(callable); 7177 chainValue->items.push_back(callable);
7006 chainValue->items.push_back(colonChain); 7178 chainValue->items.push_back(colonChain);
7007 auto value = x->new_ptr<Value_t>(); 7179 auto exp = newExp(chainValue, x);
7008 value->item.set(chainValue);
7009 auto exp = newExp(value, x);
7010 assign->values.push_back(exp); 7180 assign->values.push_back(exp);
7011 } 7181 }
7012 auto callable = x->new_ptr<Callable_t>(); 7182 auto callable = x->new_ptr<Callable_t>();
7013 callable->item.set(var); 7183 callable->item.set(var);
7014 auto chainValue = x->new_ptr<ChainValue_t>(); 7184 auto chainValue = x->new_ptr<ChainValue_t>();
7015 chainValue->items.push_back(callable); 7185 chainValue->items.push_back(callable);
7016 auto value = x->new_ptr<Value_t>(); 7186 auto exp = newExp(chainValue, x);
7017 value->item.set(chainValue);
7018 auto exp = newExp(value, x);
7019 expList->exprs.push_back(exp); 7187 expList->exprs.push_back(exp);
7020 break; 7188 break;
7021 } 7189 }
@@ -7507,9 +7675,7 @@ private:
7507 callable->item.set(name); 7675 callable->item.set(name);
7508 auto chainValue = x->new_ptr<ChainValue_t>(); 7676 auto chainValue = x->new_ptr<ChainValue_t>();
7509 chainValue->items.push_back(callable); 7677 chainValue->items.push_back(callable);
7510 auto value = x->new_ptr<Value_t>(); 7678 auto exp = newExp(chainValue, x);
7511 value->item.set(chainValue);
7512 auto exp = newExp(value, x);
7513 expList->exprs.push_back(exp); 7679 expList->exprs.push_back(exp);
7514 } 7680 }
7515 auto assignment = x->new_ptr<ExpListAssign_t>(); 7681 auto assignment = x->new_ptr<ExpListAssign_t>();
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index e5209ef..153babe 100755
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -351,7 +351,7 @@ YueParser::YueParser() {
351 351
352 unary_operator = 352 unary_operator =
353 expr('-') >> not_(set(">=") | space_one) | 353 expr('-') >> not_(set(">=") | space_one) |
354 expr('#') >> not_(':') | 354 expr('#') |
355 expr('~') >> not_(expr('=') | space_one) | 355 expr('~') >> not_(expr('=') | space_one) |
356 expr("not") >> not_(AlphaNum); 356 expr("not") >> not_(AlphaNum);
357 unary_exp = *(Space >> unary_operator) >> expo_exp; 357 unary_exp = *(Space >> unary_operator) >> expo_exp;
@@ -435,8 +435,9 @@ YueParser::YueParser() {
435 FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) | 435 FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) |
436 (sym('!') >> not_(expr('='))); 436 (sym('!') >> not_(expr('=')));
437 437
438 Metatable = expr('#'); 438 meta_index = Name | Index | String;
439 Metamethod = Name >> expr('#'); 439 Metatable = expr('<') >> sym('>');
440 Metamethod = expr('<') >> Space >> meta_index >> sym('>');
440 441
441 existential_op = expr('?') >> not_(expr('?')); 442 existential_op = expr('?') >> not_(expr('?'));
442 table_appending_op = expr("[]"); 443 table_appending_op = expr("[]");
@@ -453,8 +454,8 @@ YueParser::YueParser() {
453 454
454 Index = symx('[') >> not_('[') >> Exp >> sym(']'); 455 Index = symx('[') >> not_('[') >> Exp >> sym(']');
455 ChainItem = Invoke >> -existential_op | DotChainItem >> -existential_op | Slice | Index >> -existential_op; 456 ChainItem = Invoke >> -existential_op | DotChainItem >> -existential_op | Slice | Index >> -existential_op;
456 DotChainItem = symx('.') >> (Name >> not_('#') | Metatable | Metamethod); 457 DotChainItem = symx('.') >> (Name | Metatable | Metamethod);
457 ColonChainItem = (expr('\\') | expr("::")) >> ((LuaKeyword | Name) >> not_('#') | Metamethod); 458 ColonChainItem = (expr('\\') | expr("::")) >> (LuaKeyword | Name | Metamethod);
458 invoke_chain = Invoke >> -existential_op >> -ChainItems; 459 invoke_chain = Invoke >> -existential_op >> -ChainItems;
459 ColonChain = ColonChainItem >> -existential_op >> -invoke_chain; 460 ColonChain = ColonChainItem >> -existential_op >> -invoke_chain;
460 461
@@ -542,26 +543,31 @@ YueParser::YueParser() {
542 return true; 543 return true;
543 })) >> not_(Space >> statement_appendix); 544 })) >> not_(Space >> statement_appendix);
544 545
545 variable_pair = sym(':') >> Variable >> not_('#'); 546 variable_pair = sym(':') >> Variable;
546 547
547 normal_pair = ( 548 normal_pair = (
548 KeyName | 549 KeyName |
549 sym('[') >> not_('[') >> Exp >> sym(']') | 550 sym('[') >> not_('[') >> Exp >> sym(']') |
550 Space >> DoubleString | 551 Space >> String
551 Space >> SingleString |
552 Space >> LuaString
553 ) >> 552 ) >>
554 symx(':') >> not_(':') >> 553 symx(':') >> not_(':') >>
555 (Exp | TableBlock | +SpaceBreak >> Exp); 554 (Exp | TableBlock | +SpaceBreak >> Exp);
556 555
557 default_pair = (sym(':') >> Variable >> not_('#') >> Seperator | KeyName >> symx(':') >> Seperator >> exp_not_tab | exp_not_tab >> Seperator) >> sym('=') >> Exp; 556 default_pair = (
557 sym(':') >> Variable >> Seperator |
558 KeyName >> symx(':') >> not_(':') >> Seperator >> exp_not_tab |
559 Space >> String >> symx(':') >> not_(':') >> Seperator >> exp_not_tab |
560 exp_not_tab >> Seperator) >> sym('=') >> Exp;
558 561
559 meta_variable_pair = sym(':') >> Variable >> expr('#'); 562 meta_variable_pair = sym(":<") >> Space >> Variable >> sym('>');
560 563
561 meta_normal_pair = Space >> -(Name | symx('[') >> not_('[') >> Exp >> sym(']')) >> expr("#:") >> 564 meta_normal_pair = sym('<') >> Space >> -meta_index >> sym(">:") >>
562 (Exp | TableBlock | +(SpaceBreak) >> Exp); 565 (Exp | TableBlock | +(SpaceBreak) >> Exp);
563 566
564 meta_default_pair = (sym(':') >> Variable >> expr('#') >> Seperator | Space >> -Name >> expr("#:") >> Seperator >> exp_not_tab) >> sym('=') >> Exp; 567 meta_default_pair = (
568 sym(":<") >> Space >> Variable >> sym('>') >> Seperator |
569 sym('<') >> Space >> -meta_index >> sym(">:") >> Seperator >> exp_not_tab
570 ) >> sym('=') >> Exp;
565 571
566 KeyValue = variable_pair | normal_pair | meta_variable_pair | meta_normal_pair; 572 KeyValue = variable_pair | normal_pair | meta_variable_pair | meta_normal_pair;
567 KeyValueList = KeyValue >> *(sym(',') >> KeyValue); 573 KeyValueList = KeyValue >> *(sym(',') >> KeyValue);
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index dd577b4..f83f1b9 100755
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -172,6 +172,7 @@ private:
172 rule ChainItem; 172 rule ChainItem;
173 rule chain_line; 173 rule chain_line;
174 rule chain_block; 174 rule chain_block;
175 rule meta_index;
175 rule Index; 176 rule Index;
176 rule invoke_chain; 177 rule invoke_chain;
177 rule TableValue; 178 rule TableValue;