diff options
| author | Li Jin <dragon-fly@qq.com> | 2022-11-21 16:56:43 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2022-11-21 16:56:43 +0800 |
| commit | 58cf1a70971ad37ef9260aa93851e92fd6e4c1ce (patch) | |
| tree | fbf8e3ae38b7b230122aac32e5461c5570dc88bf | |
| parent | 8abf668c0b031c0aa81f186745eaf154aa036c8a (diff) | |
| download | yuescript-58cf1a70971ad37ef9260aa93851e92fd6e4c1ce.tar.gz yuescript-58cf1a70971ad37ef9260aa93851e92fd6e4c1ce.tar.bz2 yuescript-58cf1a70971ad37ef9260aa93851e92fd6e4c1ce.zip | |
fix table pattern matching. confirm fixing issue #116.
Diffstat (limited to '')
| -rw-r--r-- | spec/outputs/destructure.lua | 33 | ||||
| -rw-r--r-- | spec/outputs/switch.lua | 48 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 54 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 17 |
4 files changed, 95 insertions, 57 deletions
diff --git a/spec/outputs/destructure.lua b/spec/outputs/destructure.lua index f40a658..8953a2a 100644 --- a/spec/outputs/destructure.lua +++ b/spec/outputs/destructure.lua | |||
| @@ -472,7 +472,8 @@ do | |||
| 472 | end | 472 | end |
| 473 | do | 473 | do |
| 474 | local _exp_0 = tb | 474 | local _exp_0 = tb |
| 475 | local _tab_0 = "table" == type(_exp_0) | 475 | local _tab_0 = type(_exp_0) |
| 476 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 476 | if _tab_0 then | 477 | if _tab_0 then |
| 477 | local name, meta_field | 478 | local name, meta_field |
| 478 | do | 479 | do |
| @@ -531,14 +532,17 @@ do | |||
| 531 | end | 532 | end |
| 532 | do | 533 | do |
| 533 | local _exp_0 = tb | 534 | local _exp_0 = tb |
| 534 | local _tab_0 = "table" == type(_exp_0) | 535 | local _tab_0 = type(_exp_0) |
| 536 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 535 | if _tab_0 then | 537 | if _tab_0 then |
| 536 | do | 538 | do |
| 537 | local _obj_0 = _exp_0.a | 539 | local _obj_0 = _exp_0.a |
| 538 | if _obj_0 ~= nil then | 540 | local _type_0 = type(_obj_0) |
| 541 | if "table" == _type_0 or "userdata" == _type_0 then | ||
| 539 | do | 542 | do |
| 540 | local _obj_1 = getmetatable(_obj_0) | 543 | local _obj_1 = getmetatable(_obj_0) |
| 541 | if _obj_1 ~= nil then | 544 | local _type_1 = type(_obj_1) |
| 545 | if "table" == _type_1 or "userdata" == _type_1 then | ||
| 542 | add = _obj_1.__add | 546 | add = _obj_1.__add |
| 543 | end | 547 | end |
| 544 | end | 548 | end |
| @@ -546,10 +550,12 @@ do | |||
| 546 | end | 550 | end |
| 547 | do | 551 | do |
| 548 | local _obj_0 = _exp_0.b | 552 | local _obj_0 = _exp_0.b |
| 549 | if _obj_0 ~= nil then | 553 | local _type_0 = type(_obj_0) |
| 554 | if "table" == _type_0 or "userdata" == _type_0 then | ||
| 550 | do | 555 | do |
| 551 | local _obj_1 = getmetatable(_obj_0) | 556 | local _obj_1 = getmetatable(_obj_0) |
| 552 | if _obj_1 ~= nil then | 557 | local _type_1 = type(_obj_1) |
| 558 | if "table" == _type_1 or "userdata" == _type_1 then | ||
| 553 | field = _obj_1[fieldName] | 559 | field = _obj_1[fieldName] |
| 554 | end | 560 | end |
| 555 | end | 561 | end |
| @@ -566,15 +572,18 @@ do | |||
| 566 | end | 572 | end |
| 567 | do | 573 | do |
| 568 | local _exp_0 = tb | 574 | local _exp_0 = tb |
| 569 | local _tab_0 = "table" == type(_exp_0) | 575 | local _tab_0 = type(_exp_0) |
| 576 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 570 | if _tab_0 then | 577 | if _tab_0 then |
| 571 | local _obj_0 = _exp_0 | 578 | local _obj_0 = _exp_0 |
| 572 | do | 579 | do |
| 573 | local _obj_1 = _obj_0.c | 580 | local _obj_1 = _obj_0.c |
| 574 | if _obj_1 ~= nil then | 581 | local _type_0 = type(_obj_1) |
| 582 | if "table" == _type_0 or "userdata" == _type_0 then | ||
| 575 | do | 583 | do |
| 576 | local _obj_2 = getmetatable(_obj_1) | 584 | local _obj_2 = getmetatable(_obj_1) |
| 577 | if _obj_2 ~= nil then | 585 | local _type_1 = type(_obj_2) |
| 586 | if "table" == _type_1 or "userdata" == _type_1 then | ||
| 578 | meta_field = _obj_2["abc"] | 587 | meta_field = _obj_2["abc"] |
| 579 | end | 588 | end |
| 580 | end | 589 | end |
| @@ -587,13 +596,15 @@ do | |||
| 587 | local _obj_1 = getmetatable(_obj_0) | 596 | local _obj_1 = getmetatable(_obj_0) |
| 588 | do | 597 | do |
| 589 | local _obj_2 = _obj_1[ [[any string]]] | 598 | local _obj_2 = _obj_1[ [[any string]]] |
| 590 | if _obj_2 ~= nil then | 599 | local _type_0 = type(_obj_2) |
| 600 | if "table" == _type_0 or "userdata" == _type_0 then | ||
| 591 | abc = _obj_2.d | 601 | abc = _obj_2.d |
| 592 | end | 602 | end |
| 593 | end | 603 | end |
| 594 | do | 604 | do |
| 595 | local _obj_2 = _obj_1['str'] | 605 | local _obj_2 = _obj_1['str'] |
| 596 | if _obj_2 ~= nil then | 606 | local _type_0 = type(_obj_2) |
| 607 | if "table" == _type_0 or "userdata" == _type_0 then | ||
| 597 | def = _obj_2.e | 608 | def = _obj_2.e |
| 598 | end | 609 | end |
| 599 | end | 610 | end |
diff --git a/spec/outputs/switch.lua b/spec/outputs/switch.lua index 4358027..3c48120 100644 --- a/spec/outputs/switch.lua +++ b/spec/outputs/switch.lua | |||
| @@ -107,37 +107,43 @@ do | |||
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | do | 109 | do |
| 110 | local _tab_0 = "table" == type(dict) | 110 | local _tab_0 = type(dict) |
| 111 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 111 | if _tab_0 then | 112 | if _tab_0 then |
| 112 | local first = dict[1] | 113 | local first = dict[1] |
| 113 | local one | 114 | local one |
| 114 | do | 115 | do |
| 115 | local _obj_0 = dict[2] | 116 | local _obj_0 = dict[2] |
| 116 | if _obj_0 ~= nil then | 117 | local _type_0 = type(_obj_0) |
| 118 | if "table" == _type_0 or "userdata" == _type_0 then | ||
| 117 | one = _obj_0[1] | 119 | one = _obj_0[1] |
| 118 | end | 120 | end |
| 119 | end | 121 | end |
| 120 | local two | 122 | local two |
| 121 | do | 123 | do |
| 122 | local _obj_0 = dict[2] | 124 | local _obj_0 = dict[2] |
| 123 | if _obj_0 ~= nil then | 125 | local _type_0 = type(_obj_0) |
| 126 | if "table" == _type_0 or "userdata" == _type_0 then | ||
| 124 | two = _obj_0[2] | 127 | two = _obj_0[2] |
| 125 | end | 128 | end |
| 126 | end | 129 | end |
| 127 | local three | 130 | local three |
| 128 | do | 131 | do |
| 129 | local _obj_0 = dict[2] | 132 | local _obj_0 = dict[2] |
| 130 | if _obj_0 ~= nil then | 133 | local _type_0 = type(_obj_0) |
| 134 | if "table" == _type_0 or "userdata" == _type_0 then | ||
| 131 | three = _obj_0[3] | 135 | three = _obj_0[3] |
| 132 | end | 136 | end |
| 133 | end | 137 | end |
| 134 | local c | 138 | local c |
| 135 | do | 139 | do |
| 136 | local _obj_0 = dict.a | 140 | local _obj_0 = dict.a |
| 137 | if _obj_0 ~= nil then | 141 | local _type_0 = type(_obj_0) |
| 142 | if "table" == _type_0 or "userdata" == _type_0 then | ||
| 138 | do | 143 | do |
| 139 | local _obj_1 = _obj_0.b | 144 | local _obj_1 = _obj_0.b |
| 140 | if _obj_1 ~= nil then | 145 | local _type_1 = type(_obj_1) |
| 146 | if "table" == _type_1 or "userdata" == _type_1 then | ||
| 141 | c = _obj_1.c | 147 | c = _obj_1.c |
| 142 | end | 148 | end |
| 143 | end | 149 | end |
| @@ -146,10 +152,12 @@ do | |||
| 146 | local z | 152 | local z |
| 147 | do | 153 | do |
| 148 | local _obj_0 = dict.x | 154 | local _obj_0 = dict.x |
| 149 | if _obj_0 ~= nil then | 155 | local _type_0 = type(_obj_0) |
| 156 | if "table" == _type_0 or "userdata" == _type_0 then | ||
| 150 | do | 157 | do |
| 151 | local _obj_1 = _obj_0.y | 158 | local _obj_1 = _obj_0.y |
| 152 | if _obj_1 ~= nil then | 159 | local _type_1 = type(_obj_1) |
| 160 | if "table" == _type_1 or "userdata" == _type_1 then | ||
| 153 | z = _obj_1.z | 161 | z = _obj_1.z |
| 154 | end | 162 | end |
| 155 | end | 163 | end |
| @@ -176,7 +184,8 @@ do | |||
| 176 | for _index_0 = 1, #items do | 184 | for _index_0 = 1, #items do |
| 177 | local item = items[_index_0] | 185 | local item = items[_index_0] |
| 178 | do | 186 | do |
| 179 | local _tab_0 = "table" == type(item) | 187 | local _tab_0 = type(item) |
| 188 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 180 | local _match_0 = false | 189 | local _match_0 = false |
| 181 | if _tab_0 then | 190 | if _tab_0 then |
| 182 | local x = item.x | 191 | local x = item.x |
| @@ -234,7 +243,8 @@ end | |||
| 234 | do | 243 | do |
| 235 | local tb = { } | 244 | local tb = { } |
| 236 | do | 245 | do |
| 237 | local _tab_0 = "table" == type(tb) | 246 | local _tab_0 = type(tb) |
| 247 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 238 | if _tab_0 then | 248 | if _tab_0 then |
| 239 | local a = tb.a | 249 | local a = tb.a |
| 240 | local b = tb.b | 250 | local b = tb.b |
| @@ -248,7 +258,8 @@ do | |||
| 248 | end | 258 | end |
| 249 | end | 259 | end |
| 250 | do | 260 | do |
| 251 | local _tab_0 = "table" == type(tb) | 261 | local _tab_0 = type(tb) |
| 262 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 252 | if _tab_0 then | 263 | if _tab_0 then |
| 253 | local a = tb.a | 264 | local a = tb.a |
| 254 | local b = tb.b | 265 | local b = tb.b |
| @@ -261,7 +272,8 @@ do | |||
| 261 | end | 272 | end |
| 262 | end | 273 | end |
| 263 | do | 274 | do |
| 264 | local _tab_0 = "table" == type(tb) | 275 | local _tab_0 = type(tb) |
| 276 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 265 | local _match_0 = false | 277 | local _match_0 = false |
| 266 | if _tab_0 then | 278 | if _tab_0 then |
| 267 | local a = tb.a | 279 | local a = tb.a |
| @@ -281,7 +293,8 @@ do | |||
| 281 | x = "abc" | 293 | x = "abc" |
| 282 | } | 294 | } |
| 283 | do | 295 | do |
| 284 | local _tab_0 = "table" == type(tb) | 296 | local _tab_0 = type(tb) |
| 297 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 285 | local _match_0 = false | 298 | local _match_0 = false |
| 286 | if _tab_0 then | 299 | if _tab_0 then |
| 287 | local x = tb.x | 300 | local x = tb.x |
| @@ -308,7 +321,8 @@ do | |||
| 308 | if 1 == _exp_0 then | 321 | if 1 == _exp_0 then |
| 309 | matched = "1" | 322 | matched = "1" |
| 310 | else | 323 | else |
| 311 | local _tab_0 = "table" == type(_exp_0) | 324 | local _tab_0 = type(_exp_0) |
| 325 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 312 | local _match_0 = false | 326 | local _match_0 = false |
| 313 | if _tab_0 then | 327 | if _tab_0 then |
| 314 | local x = _exp_0.x | 328 | local x = _exp_0.x |
| @@ -333,7 +347,8 @@ do | |||
| 333 | return "invalid" | 347 | return "invalid" |
| 334 | else | 348 | else |
| 335 | do | 349 | do |
| 336 | local _tab_0 = "table" == type(_exp_0) | 350 | local _tab_0 = type(_exp_0) |
| 351 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 337 | local _match_0 = false | 352 | local _match_0 = false |
| 338 | if _tab_0 then | 353 | if _tab_0 then |
| 339 | local a = _exp_0.a | 354 | local a = _exp_0.a |
| @@ -367,7 +382,8 @@ end | |||
| 367 | do | 382 | do |
| 368 | do | 383 | do |
| 369 | local _exp_0 = y | 384 | local _exp_0 = y |
| 370 | local _tab_0 = "table" == type(_exp_0) | 385 | local _tab_0 = type(_exp_0) |
| 386 | _tab_0 = "table" == _tab_0 or "userdata" == _tab_0 | ||
| 371 | if _tab_0 then | 387 | if _tab_0 then |
| 372 | local mt = (function() | 388 | local mt = (function() |
| 373 | local _obj_0 = _exp_0.x | 389 | local _obj_0 = _exp_0.x |
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 | ||
| 61 | typedef std::list<std::string> str_list; | 61 | typedef std::list<std::string> str_list; |
| 62 | 62 | ||
| 63 | const std::string_view version = "0.15.14"sv; | 63 | const std::string_view version = "0.15.15"sv; |
| 64 | const std::string_view extension = "yue"sv; | 64 | const std::string_view extension = "yue"sv; |
| 65 | 65 | ||
| 66 | class YueCompilerImpl { | 66 | class 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)); |
