diff options
-rw-r--r-- | spec/inputs/destructure.yue | 10 | ||||
-rw-r--r-- | spec/outputs/destructure.lua | 105 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 32 |
3 files changed, 141 insertions, 6 deletions
diff --git a/spec/inputs/destructure.yue b/spec/inputs/destructure.yue index 403923a..d161fd8 100644 --- a/spec/inputs/destructure.yue +++ b/spec/inputs/destructure.yue | |||
@@ -214,5 +214,15 @@ do | |||
214 | tb = {} | 214 | tb = {} |
215 | <[a + b]>: v1, [c!]: v2 = tb | 215 | <[a + b]>: v1, [c!]: v2 = tb |
216 | 216 | ||
217 | do | ||
218 | {a: {:<add> = addFunc}, b: {<[fieldName]>: field = 123}} = tb | ||
219 | {<"abc">: meta_field = "def", <[[any string]]>: abc = 123, <'str'>: def = {}} = tb | ||
220 | |||
221 | switch tb | ||
222 | when {a: {:<add> = addFunc}, b: {<[fieldName]>: field = 123}} | ||
223 | print add, field | ||
224 | switch tb | ||
225 | when {c: {<"abc">: meta_field = "def"}, <[[any string]]>: {d: abc = 123}, <'str'>: {e: def = {}}} | ||
226 | print meta_field, abc, def | ||
217 | nil | 227 | nil |
218 | 228 | ||
diff --git a/spec/outputs/destructure.lua b/spec/outputs/destructure.lua index 10ad2d0..f40a658 100644 --- a/spec/outputs/destructure.lua +++ b/spec/outputs/destructure.lua | |||
@@ -503,4 +503,109 @@ do | |||
503 | v1 = _obj_1[_tmp_1] | 503 | v1 = _obj_1[_tmp_1] |
504 | end | 504 | end |
505 | end | 505 | end |
506 | do | ||
507 | local add, field | ||
508 | do | ||
509 | local _obj_0 = tb | ||
510 | add, field = getmetatable(_obj_0.a).__add, getmetatable(_obj_0.b)[fieldName] | ||
511 | if add == nil then | ||
512 | add = addFunc | ||
513 | end | ||
514 | if field == nil then | ||
515 | field = 123 | ||
516 | end | ||
517 | end | ||
518 | local meta_field, abc, def | ||
519 | do | ||
520 | local _obj_0 = getmetatable(tb) | ||
521 | meta_field, abc, def = _obj_0["abc"], _obj_0[ [[any string]]], _obj_0['str'] | ||
522 | if meta_field == nil then | ||
523 | meta_field = "def" | ||
524 | end | ||
525 | if abc == nil then | ||
526 | abc = 123 | ||
527 | end | ||
528 | if def == nil then | ||
529 | def = { } | ||
530 | end | ||
531 | end | ||
532 | do | ||
533 | local _exp_0 = tb | ||
534 | local _tab_0 = "table" == type(_exp_0) | ||
535 | if _tab_0 then | ||
536 | do | ||
537 | local _obj_0 = _exp_0.a | ||
538 | if _obj_0 ~= nil then | ||
539 | do | ||
540 | local _obj_1 = getmetatable(_obj_0) | ||
541 | if _obj_1 ~= nil then | ||
542 | add = _obj_1.__add | ||
543 | end | ||
544 | end | ||
545 | end | ||
546 | end | ||
547 | do | ||
548 | local _obj_0 = _exp_0.b | ||
549 | if _obj_0 ~= nil then | ||
550 | do | ||
551 | local _obj_1 = getmetatable(_obj_0) | ||
552 | if _obj_1 ~= nil then | ||
553 | field = _obj_1[fieldName] | ||
554 | end | ||
555 | end | ||
556 | end | ||
557 | end | ||
558 | if add == nil then | ||
559 | add = addFunc | ||
560 | end | ||
561 | if field == nil then | ||
562 | field = 123 | ||
563 | end | ||
564 | print(add, field) | ||
565 | end | ||
566 | end | ||
567 | do | ||
568 | local _exp_0 = tb | ||
569 | local _tab_0 = "table" == type(_exp_0) | ||
570 | if _tab_0 then | ||
571 | local _obj_0 = _exp_0 | ||
572 | do | ||
573 | local _obj_1 = _obj_0.c | ||
574 | if _obj_1 ~= nil then | ||
575 | do | ||
576 | local _obj_2 = getmetatable(_obj_1) | ||
577 | if _obj_2 ~= nil then | ||
578 | meta_field = _obj_2["abc"] | ||
579 | end | ||
580 | end | ||
581 | end | ||
582 | end | ||
583 | if meta_field == nil then | ||
584 | meta_field = "def" | ||
585 | end | ||
586 | do | ||
587 | local _obj_1 = getmetatable(_obj_0) | ||
588 | do | ||
589 | local _obj_2 = _obj_1[ [[any string]]] | ||
590 | if _obj_2 ~= nil then | ||
591 | abc = _obj_2.d | ||
592 | end | ||
593 | end | ||
594 | do | ||
595 | local _obj_2 = _obj_1['str'] | ||
596 | if _obj_2 ~= nil then | ||
597 | def = _obj_2.e | ||
598 | end | ||
599 | end | ||
600 | if abc == nil then | ||
601 | abc = 123 | ||
602 | end | ||
603 | if def == nil then | ||
604 | def = { } | ||
605 | end | ||
606 | end | ||
607 | print(meta_field, abc, def) | ||
608 | end | ||
609 | end | ||
610 | end | ||
506 | return nil | 611 | return nil |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index c359e02..9d84f43 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -2109,6 +2109,11 @@ private: | |||
2109 | auto item = value->item.get(); | 2109 | auto item = value->item.get(); |
2110 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { | 2110 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { |
2111 | auto subPairs = destructFromExp(pair, optional); | 2111 | auto subPairs = destructFromExp(pair, optional); |
2112 | if (!subPairs.empty()) { | ||
2113 | if (defVal) { | ||
2114 | throw std::logic_error(_info.errorMessage("default value is not supported here"sv, defVal)); | ||
2115 | } | ||
2116 | } | ||
2112 | for (auto& p : subPairs) { | 2117 | for (auto& p : subPairs) { |
2113 | if (sep) p.structure->items.push_front(sep); | 2118 | if (sep) p.structure->items.push_front(sep); |
2114 | p.structure->items.push_front( | 2119 | p.structure->items.push_front( |
@@ -2171,14 +2176,20 @@ private: | |||
2171 | keyIndex = key; | 2176 | keyIndex = key; |
2172 | } else if (auto key = np->key.as<String_t>()) { | 2177 | } else if (auto key = np->key.as<String_t>()) { |
2173 | keyIndex = newExp(key, np->key).get(); | 2178 | keyIndex = newExp(key, np->key).get(); |
2174 | } else | 2179 | } else { |
2175 | throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, np)); | 2180 | throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, np)); |
2181 | } | ||
2176 | } | 2182 | } |
2177 | if (auto exp = np->value.as<Exp_t>()) { | 2183 | if (auto exp = np->value.as<Exp_t>()) { |
2178 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't do destructure value"sv, exp)); | 2184 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't do destructure value"sv, exp)); |
2179 | auto item = singleValueFrom(exp)->item.get(); | 2185 | auto item = singleValueFrom(exp)->item.get(); |
2180 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { | 2186 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { |
2181 | auto subPairs = destructFromExp(exp, optional); | 2187 | auto subPairs = destructFromExp(exp, optional); |
2188 | if (!subPairs.empty()) { | ||
2189 | if (defVal) { | ||
2190 | throw std::logic_error(_info.errorMessage("default value is not supported here"sv, defVal)); | ||
2191 | } | ||
2192 | } | ||
2182 | for (auto& p : subPairs) { | 2193 | for (auto& p : subPairs) { |
2183 | if (keyIndex) { | 2194 | if (keyIndex) { |
2184 | if (sep) p.structure->items.push_front(sep); | 2195 | if (sep) p.structure->items.push_front(sep); |
@@ -2199,6 +2210,11 @@ private: | |||
2199 | } | 2210 | } |
2200 | if (np->value.is<TableBlock_t>()) { | 2211 | if (np->value.is<TableBlock_t>()) { |
2201 | auto subPairs = destructFromExp(np->value, optional); | 2212 | auto subPairs = destructFromExp(np->value, optional); |
2213 | if (!subPairs.empty()) { | ||
2214 | if (defVal) { | ||
2215 | throw std::logic_error(_info.errorMessage("default value is not supported here"sv, defVal)); | ||
2216 | } | ||
2217 | } | ||
2202 | for (auto& p : subPairs) { | 2218 | for (auto& p : subPairs) { |
2203 | if (keyIndex) { | 2219 | if (keyIndex) { |
2204 | if (sep) p.structure->items.push_front(sep); | 2220 | if (sep) p.structure->items.push_front(sep); |
@@ -2253,6 +2269,7 @@ private: | |||
2253 | newPair->key.set(newKey); | 2269 | newPair->key.set(newKey); |
2254 | break; | 2270 | break; |
2255 | } | 2271 | } |
2272 | case id<String_t>(): | ||
2256 | case id<Exp_t>(): | 2273 | case id<Exp_t>(): |
2257 | newPair->key.set(mp->key); | 2274 | newPair->key.set(mp->key); |
2258 | break; | 2275 | break; |
@@ -5220,7 +5237,7 @@ private: | |||
5220 | case id<variable_pair_def_t>(): { | 5237 | case id<variable_pair_def_t>(): { |
5221 | if (auto pair = ast_cast<variable_pair_def_t>(item)) { | 5238 | if (auto pair = ast_cast<variable_pair_def_t>(item)) { |
5222 | if (pair->defVal) { | 5239 | if (pair->defVal) { |
5223 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | 5240 | throw std::logic_error(_info.errorMessage("invalid default value here"sv, pair->defVal)); |
5224 | } | 5241 | } |
5225 | item = pair->pair.get(); | 5242 | item = pair->pair.get(); |
5226 | } | 5243 | } |
@@ -5234,7 +5251,7 @@ private: | |||
5234 | case id<normal_pair_def_t>(): { | 5251 | case id<normal_pair_def_t>(): { |
5235 | if (auto pair = ast_cast<normal_pair_def_t>(item)) { | 5252 | if (auto pair = ast_cast<normal_pair_def_t>(item)) { |
5236 | if (pair->defVal) { | 5253 | if (pair->defVal) { |
5237 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | 5254 | throw std::logic_error(_info.errorMessage("invalid default value here"sv, pair->defVal)); |
5238 | } | 5255 | } |
5239 | item = pair->pair.get(); | 5256 | item = pair->pair.get(); |
5240 | } | 5257 | } |
@@ -5286,7 +5303,7 @@ private: | |||
5286 | auto current = item; | 5303 | auto current = item; |
5287 | if (auto pair = ast_cast<normal_def_t>(item)) { | 5304 | if (auto pair = ast_cast<normal_def_t>(item)) { |
5288 | if (pair->defVal) { | 5305 | if (pair->defVal) { |
5289 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | 5306 | throw std::logic_error(_info.errorMessage("invalid default value here"sv, pair->defVal)); |
5290 | } | 5307 | } |
5291 | item = pair->item.get(); | 5308 | item = pair->item.get(); |
5292 | } | 5309 | } |
@@ -5336,7 +5353,7 @@ private: | |||
5336 | case id<meta_variable_pair_def_t>(): { | 5353 | case id<meta_variable_pair_def_t>(): { |
5337 | if (auto pair = ast_cast<meta_variable_pair_def_t>(item)) { | 5354 | if (auto pair = ast_cast<meta_variable_pair_def_t>(item)) { |
5338 | if (pair->defVal) { | 5355 | if (pair->defVal) { |
5339 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | 5356 | throw std::logic_error(_info.errorMessage("invalid default value here"sv, pair->defVal)); |
5340 | } | 5357 | } |
5341 | item = pair->pair.get(); | 5358 | item = pair->pair.get(); |
5342 | } | 5359 | } |
@@ -5350,7 +5367,7 @@ private: | |||
5350 | case id<meta_normal_pair_def_t>(): { | 5367 | case id<meta_normal_pair_def_t>(): { |
5351 | if (auto pair = ast_cast<meta_normal_pair_def_t>(item)) { | 5368 | if (auto pair = ast_cast<meta_normal_pair_def_t>(item)) { |
5352 | if (pair->defVal) { | 5369 | if (pair->defVal) { |
5353 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | 5370 | throw std::logic_error(_info.errorMessage("invalid default value here"sv, pair->defVal)); |
5354 | } | 5371 | } |
5355 | item = pair->pair.get(); | 5372 | item = pair->pair.get(); |
5356 | } | 5373 | } |
@@ -5373,6 +5390,9 @@ private: | |||
5373 | chainValue->items.push_back(key); | 5390 | chainValue->items.push_back(key); |
5374 | break; | 5391 | break; |
5375 | } | 5392 | } |
5393 | case id<String_t>(): | ||
5394 | chainValue->items.push_back(key); | ||
5395 | break; | ||
5376 | default: YUEE("AST node mismatch", key); break; | 5396 | default: YUEE("AST node mismatch", key); break; |
5377 | } | 5397 | } |
5378 | auto assign = assignment->action.to<Assign_t>(); | 5398 | auto assign = assignment->action.to<Assign_t>(); |