aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-11-21 16:56:43 +0800
committerLi Jin <dragon-fly@qq.com>2022-11-21 16:56:43 +0800
commit58cf1a70971ad37ef9260aa93851e92fd6e4c1ce (patch)
treefbf8e3ae38b7b230122aac32e5461c5570dc88bf /src
parent8abf668c0b031c0aa81f186745eaf154aa036c8a (diff)
downloadyuescript-58cf1a70971ad37ef9260aa93851e92fd6e4c1ce.tar.gz
yuescript-58cf1a70971ad37ef9260aa93851e92fd6e4c1ce.tar.bz2
yuescript-58cf1a70971ad37ef9260aa93851e92fd6e4c1ce.zip
fix table pattern matching. confirm fixing issue #116.
Diffstat (limited to 'src')
-rw-r--r--src/yuescript/yue_compiler.cpp54
-rw-r--r--src/yuescript/yue_parser.cpp17
2 files changed, 41 insertions, 30 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 066a661..cd91c97 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -60,7 +60,7 @@ namespace yue {
60 60
61typedef std::list<std::string> str_list; 61typedef std::list<std::string> str_list;
62 62
63const std::string_view version = "0.15.14"sv; 63const std::string_view version = "0.15.15"sv;
64const std::string_view extension = "yue"sv; 64const std::string_view extension = "yue"sv;
65 65
66class YueCompilerImpl { 66class YueCompilerImpl {
@@ -1806,7 +1806,7 @@ private:
1806 case ChainType::EndWithColon: 1806 case ChainType::EndWithColon:
1807 case ChainType::MetaFieldInvocation: { 1807 case ChainType::MetaFieldInvocation: {
1808 std::string preDefine = getPreDefineLine(assignment); 1808 std::string preDefine = getPreDefineLine(assignment);
1809 transformChainValue(chainValue, out, ExpUsage::Assignment, expList); 1809 transformChainValue(chainValue, out, ExpUsage::Assignment, expList, false, optionalDestruct);
1810 out.back().insert(0, preDefine); 1810 out.back().insert(0, preDefine);
1811 return; 1811 return;
1812 } 1812 }
@@ -1850,7 +1850,7 @@ private:
1850 newChain->items.dup(pair.structure->items); 1850 newChain->items.dup(pair.structure->items);
1851 } 1851 }
1852 auto newAssignment = assignmentFrom(pair.target, newExp(newChain, val->item), x); 1852 auto newAssignment = assignmentFrom(pair.target, newExp(newChain, val->item), x);
1853 transformAssignment(newAssignment, temp); 1853 transformAssignment(newAssignment, temp, optionalDestruct);
1854 if (pair.defVal) { 1854 if (pair.defVal) {
1855 bool isNil = false; 1855 bool isNil = false;
1856 if (auto v1 = singleValueFrom(pair.defVal)) { 1856 if (auto v1 = singleValueFrom(pair.defVal)) {
@@ -1898,7 +1898,7 @@ private:
1898 chain->items.dup(pair.structure->items); 1898 chain->items.dup(pair.structure->items);
1899 auto valueExp = newExp(chain, pair.target); 1899 auto valueExp = newExp(chain, pair.target);
1900 auto newAssignment = assignmentFrom(pair.target, valueExp, x); 1900 auto newAssignment = assignmentFrom(pair.target, valueExp, x);
1901 transformAssignment(newAssignment, temp); 1901 transformAssignment(newAssignment, temp, optionalDestruct);
1902 if (!isLocalValue) { 1902 if (!isLocalValue) {
1903 popScope(); 1903 popScope();
1904 _buf << indent() << "end"sv << nlr(x); 1904 _buf << indent() << "end"sv << nlr(x);
@@ -1986,7 +1986,7 @@ private:
1986 auto assign = x->new_ptr<Assign_t>(); 1986 auto assign = x->new_ptr<Assign_t>();
1987 assign->values.dup(valueList->exprs); 1987 assign->values.dup(valueList->exprs);
1988 newAssignment->action.set(assign); 1988 newAssignment->action.set(assign);
1989 transformAssignment(newAssignment, temp); 1989 transformAssignment(newAssignment, temp, true);
1990 } 1990 }
1991 } else { 1991 } else {
1992 auto valueList = x->new_ptr<ExpList_t>(); 1992 auto valueList = x->new_ptr<ExpList_t>();
@@ -2114,10 +2114,10 @@ private:
2114 throw std::logic_error(_info.errorMessage("default value is not supported here"sv, defVal)); 2114 throw std::logic_error(_info.errorMessage("default value is not supported here"sv, defVal));
2115 } 2115 }
2116 } 2116 }
2117 auto indexItem = toAst<Exp_t>(std::to_string(index), value);
2117 for (auto& p : subPairs) { 2118 for (auto& p : subPairs) {
2118 if (sep) p.structure->items.push_front(sep); 2119 if (sep) p.structure->items.push_front(sep);
2119 p.structure->items.push_front( 2120 p.structure->items.push_front(indexItem);
2120 toAst<Exp_t>(std::to_string(index), p.target));
2121 pairs.push_back(p); 2121 pairs.push_back(p);
2122 } 2122 }
2123 } else { 2123 } else {
@@ -2125,7 +2125,8 @@ private:
2125 auto varName = singleVariableFrom(exp, false); 2125 auto varName = singleVariableFrom(exp, false);
2126 if (varName == "_"sv) break; 2126 if (varName == "_"sv) break;
2127 auto chain = exp->new_ptr<ChainValue_t>(); 2127 auto chain = exp->new_ptr<ChainValue_t>();
2128 chain->items.push_back(toAst<Exp_t>(std::to_string(index), exp)); 2128 auto indexItem = toAst<Exp_t>(std::to_string(index), exp);
2129 chain->items.push_back(indexItem);
2129 pairs.push_back({exp, 2130 pairs.push_back({exp,
2130 varName, 2131 varName,
2131 chain, 2132 chain,
@@ -2229,9 +2230,10 @@ private:
2229 auto tb = static_cast<TableBlockIndent_t*>(pair); 2230 auto tb = static_cast<TableBlockIndent_t*>(pair);
2230 ++index; 2231 ++index;
2231 auto subPairs = destructFromExp(tb, optional); 2232 auto subPairs = destructFromExp(tb, optional);
2233 auto indexItem = toAst<Exp_t>(std::to_string(index), tb);
2232 for (auto& p : subPairs) { 2234 for (auto& p : subPairs) {
2233 if (sep) p.structure->items.push_front(sep); 2235 if (sep) p.structure->items.push_front(sep);
2234 p.structure->items.push_front(toAst<Exp_t>(std::to_string(index), tb)); 2236 p.structure->items.push_front(indexItem);
2235 pairs.push_back(p); 2237 pairs.push_back(p);
2236 } 2238 }
2237 break; 2239 break;
@@ -2290,13 +2292,13 @@ private:
2290 auto simpleValue = subMetaDestruct->new_ptr<SimpleValue_t>(); 2292 auto simpleValue = subMetaDestruct->new_ptr<SimpleValue_t>();
2291 simpleValue->value.set(subMetaDestruct); 2293 simpleValue->value.set(subMetaDestruct);
2292 auto subPairs = destructFromExp(newExp(simpleValue, subMetaDestruct), optional); 2294 auto subPairs = destructFromExp(newExp(simpleValue, subMetaDestruct), optional);
2295 auto mt = simpleValue->new_ptr<Metatable_t>();
2296 auto dot = mt->new_ptr<DotChainItem_t>();
2297 dot->name.set(mt);
2293 for (const auto& p : subPairs) { 2298 for (const auto& p : subPairs) {
2294 if (!p.structure->items.empty()) { 2299 if (!p.structure->items.empty()) {
2295 if (sep) p.structure->items.push_front(sep); 2300 if (sep) p.structure->items.push_front(sep);
2296 } 2301 }
2297 auto mt = p.structure->new_ptr<Metatable_t>();
2298 auto dot = mt->new_ptr<DotChainItem_t>();
2299 dot->name.set(mt);
2300 p.structure->items.push_front(dot); 2302 p.structure->items.push_front(dot);
2301 pairs.push_back(p); 2303 pairs.push_back(p);
2302 } 2304 }
@@ -2511,7 +2513,6 @@ private:
2511 } 2513 }
2512 } 2514 }
2513 } 2515 }
2514 popScope();
2515 for (const auto& p : destructPairs) { 2516 for (const auto& p : destructPairs) {
2516 exprs.erase(p.first); 2517 exprs.erase(p.first);
2517 values.erase(p.second); 2518 values.erase(p.second);
@@ -2529,7 +2530,6 @@ private:
2529 newAssignment = newAssign; 2530 newAssignment = newAssign;
2530 } 2531 }
2531 if (!varDefOnly) { 2532 if (!varDefOnly) {
2532 pushScope();
2533 for (auto& des : destructs) { 2533 for (auto& des : destructs) {
2534 for (const auto& item : des.items) { 2534 for (const auto& item : des.items) {
2535 for (auto node : item.structure->items.objects()) { 2535 for (auto node : item.structure->items.objects()) {
@@ -2552,7 +2552,7 @@ private:
2552 auto assignList = des.inlineAssignment->expList.get(); 2552 auto assignList = des.inlineAssignment->expList.get();
2553 auto assign = des.inlineAssignment->action.to<Assign_t>(); 2553 auto assign = des.inlineAssignment->action.to<Assign_t>();
2554 auto tmpVar = getUnusedName("_tmp_"sv); 2554 auto tmpVar = getUnusedName("_tmp_"sv);
2555 addToScope(tmpVar); 2555 forceAddToScope(tmpVar);
2556 auto tmpExp = toAst<Exp_t>(tmpVar, exp); 2556 auto tmpExp = toAst<Exp_t>(tmpVar, exp);
2557 assignList->exprs.push_back(tmpExp); 2557 assignList->exprs.push_back(tmpExp);
2558 auto vExp = exp->new_ptr<Exp_t>(); 2558 auto vExp = exp->new_ptr<Exp_t>();
@@ -2571,8 +2571,8 @@ private:
2571 } 2571 }
2572 } 2572 }
2573 } 2573 }
2574 popScope();
2575 } 2574 }
2575 popScope();
2576 return {std::move(destructs), newAssignment}; 2576 return {std::move(destructs), newAssignment};
2577 } 2577 }
2578 2578
@@ -4098,7 +4098,7 @@ private:
4098 return false; 4098 return false;
4099 } 4099 }
4100 4100
4101 bool transformChainWithEOP(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t* assignList) { 4101 bool transformChainWithEOP(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t* assignList, bool optionalDestruct) {
4102 auto opIt = std::find_if(chainList.begin(), chainList.end(), [](ast_node* node) { return ast_is<existential_op_t>(node); }); 4102 auto opIt = std::find_if(chainList.begin(), chainList.end(), [](ast_node* node) { return ast_is<existential_op_t>(node); });
4103 if (opIt != chainList.end()) { 4103 if (opIt != chainList.end()) {
4104 auto x = chainList.front(); 4104 auto x = chainList.front();
@@ -4185,7 +4185,6 @@ private:
4185 auto it = opIt; 4185 auto it = opIt;
4186 ++it; 4186 ++it;
4187 if (it != chainList.end() && ast_is<Invoke_t, InvokeArgs_t>(*it)) { 4187 if (it != chainList.end() && ast_is<Invoke_t, InvokeArgs_t>(*it)) {
4188
4189 if (auto invoke = ast_cast<Invoke_t>(*it)) { 4188 if (auto invoke = ast_cast<Invoke_t>(*it)) {
4190 invoke->args.push_front(toAst<Exp_t>(objVar, x)); 4189 invoke->args.push_front(toAst<Exp_t>(objVar, x));
4191 } else { 4190 } else {
@@ -4203,7 +4202,15 @@ private:
4203 expListAssign->action.set(assign); 4202 expListAssign->action.set(assign);
4204 transformAssignment(expListAssign, temp); 4203 transformAssignment(expListAssign, temp);
4205 } 4204 }
4206 _buf << indent() << "if "sv << objVar << " ~= nil then"sv << nll(x); 4205 if (optionalDestruct) {
4206 auto typeVar = getUnusedName("_type_"sv);
4207 _buf << typeVar << "=type "sv << objVar;
4208 auto typeAssign = toAst<ExpListAssign_t>(clearBuf(), partOne);
4209 transformAssignment(typeAssign, temp);
4210 _buf << indent() << "if \"table\" == " << typeVar << " or \"userdata\" == "sv << typeVar << " then"sv << nll(x);
4211 } else {
4212 _buf << indent() << "if "sv << objVar << " ~= nil then"sv << nll(x);
4213 }
4207 temp.push_back(clearBuf()); 4214 temp.push_back(clearBuf());
4208 pushScope(); 4215 pushScope();
4209 auto partTwo = x->new_ptr<ChainValue_t>(); 4216 auto partTwo = x->new_ptr<ChainValue_t>();
@@ -4222,7 +4229,7 @@ private:
4222 auto assignment = x->new_ptr<ExpListAssign_t>(); 4229 auto assignment = x->new_ptr<ExpListAssign_t>();
4223 assignment->expList.set(assignList); 4230 assignment->expList.set(assignList);
4224 assignment->action.set(assign); 4231 assignment->action.set(assign);
4225 transformAssignment(assignment, temp); 4232 transformAssignment(assignment, temp, optionalDestruct);
4226 break; 4233 break;
4227 } 4234 }
4228 case ExpUsage::Return: 4235 case ExpUsage::Return:
@@ -5018,7 +5025,7 @@ private:
5018 } 5025 }
5019#endif // YUE_NO_MACRO 5026#endif // YUE_NO_MACRO
5020 5027
5021 void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr, bool allowBlockMacroReturn = false) { 5028 void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr, bool allowBlockMacroReturn = false, bool optionalDestruct = false) {
5022 if (isMacroChain(chainValue)) { 5029 if (isMacroChain(chainValue)) {
5023#ifndef YUE_NO_MACRO 5030#ifndef YUE_NO_MACRO
5024 ast_ptr<false, ast_node> node; 5031 ast_ptr<false, ast_node> node;
@@ -5072,7 +5079,7 @@ private:
5072 if (transformChainEndWithEOP(chainList, out, usage, assignList)) { 5079 if (transformChainEndWithEOP(chainList, out, usage, assignList)) {
5073 return; 5080 return;
5074 } 5081 }
5075 if (transformChainWithEOP(chainList, out, usage, assignList)) { 5082 if (transformChainWithEOP(chainList, out, usage, assignList, optionalDestruct)) {
5076 return; 5083 return;
5077 } 5084 }
5078 if (transformChainWithMetatable(chainList, out, usage, assignList)) { 5085 if (transformChainWithMetatable(chainList, out, usage, assignList)) {
@@ -7837,7 +7844,8 @@ private:
7837 } 7844 }
7838 tabCheckVar = getUnusedName("_tab_"); 7845 tabCheckVar = getUnusedName("_tab_");
7839 forceAddToScope(tabCheckVar); 7846 forceAddToScope(tabCheckVar);
7840 temp.push_back(indent() + "local "s + tabCheckVar + " = \"table\" == "s + globalVar("type", branch) + '(' + objVar + ')' + nll(branch)); 7847 temp.push_back(indent() + "local "s + tabCheckVar + " = "s + globalVar("type", branch) + '(' + objVar + ')' + nll(branch));
7848 temp.push_back(indent() + tabCheckVar + " = \"table\" == "s + tabCheckVar + " or \"userdata\" == "s + tabCheckVar + nll(branch));
7841 } 7849 }
7842 std::string matchVar; 7850 std::string matchVar;
7843 bool lastBranch = branches.back() == branch_ && !switchNode->lastBranch; 7851 bool lastBranch = branches.back() == branch_ && !switchNode->lastBranch;
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index 3f1b9a1..24f821c 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -242,18 +242,21 @@ YueParser::YueParser() {
242 SwitchCase = Space >> key("when") >> disable_chain(disable_arg_table_block(SwitchList)) >> body_with("then"); 242 SwitchCase = Space >> key("when") >> disable_chain(disable_arg_table_block(SwitchList)) >> body_with("then");
243 SwitchElse = Space >> key("else") >> body; 243 SwitchElse = Space >> key("else") >> body;
244 244
245 SwitchBlock = *EmptyLine >> 245 SwitchBlock =
246 Advance >> Seperator >>
247 SwitchCase >>
248 *(Break >> *EmptyLine >> CheckIndent >> SwitchCase) >> 246 *(Break >> *EmptyLine >> CheckIndent >> SwitchCase) >>
249 -(Break >> *EmptyLine >> CheckIndent >> SwitchElse) >> 247 -(Break >> *EmptyLine >> CheckIndent >> SwitchElse);
250 PopIndent;
251 248
252 exp_not_tab = not_(simple_table | TableLit) >> Exp; 249 exp_not_tab = not_(simple_table | TableLit) >> Exp;
253 250
254 SwitchList = Seperator >> (and_(simple_table | TableLit) >> Exp | exp_not_tab >> *(sym(',') >> exp_not_tab)); 251 SwitchList = Seperator >> (and_(simple_table | TableLit) >> Exp | exp_not_tab >> *(sym(',') >> exp_not_tab));
255 Switch = Space >> key("switch") >> disable_do(Exp) >> -(Space >> key("do")) 252 Switch = Space >> key("switch") >> Exp >>
256 >> -Space >> Break >> SwitchBlock; 253 Seperator >> (
254 SwitchCase >> Space >> (
255 Break >> *EmptyLine >> CheckIndent >> SwitchCase >> SwitchBlock |
256 *SwitchCase >> -SwitchElse
257 ) |
258 SpaceBreak >> *EmptyLine >> Advance >> SwitchCase >> SwitchBlock >> PopIndent
259 ) >> SwitchBlock;
257 260
258 assignment = ExpList >> Assign; 261 assignment = ExpList >> Assign;
259 IfCond = disable_chain(disable_arg_table_block(assignment | Exp)); 262 IfCond = disable_chain(disable_arg_table_block(assignment | Exp));