aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2025-05-07 18:16:22 +0800
committerLi Jin <dragon-fly@qq.com>2025-05-07 18:16:22 +0800
commitd905d9744344da7376ae56e7dc270a81da33d15f (patch)
tree3d3674024308ee663763bed14ffd8dee8da666ed
parentc925dbea9c9108a18b9abf4a57d9d59b0ed04652 (diff)
downloadyuescript-d905d9744344da7376ae56e7dc270a81da33d15f.tar.gz
yuescript-d905d9744344da7376ae56e7dc270a81da33d15f.tar.bz2
yuescript-d905d9744344da7376ae56e7dc270a81da33d15f.zip
Updated.
-rw-r--r--spec/inputs/switch.yue56
-rw-r--r--spec/outputs/switch.lua241
-rw-r--r--src/yuescript/yue_compiler.cpp66
3 files changed, 334 insertions, 29 deletions
diff --git a/spec/inputs/switch.yue b/spec/inputs/switch.yue
index 49d47f3..7ff3118 100644
--- a/spec/inputs/switch.yue
+++ b/spec/inputs/switch.yue
@@ -165,5 +165,59 @@ do
165 print item 165 print item
166 when [a = 1, b = "abc"] 166 when [a = 1, b = "abc"]
167 print a, b 167 print a, b
168nil
169 168
169do
170 switch tb
171 when [1, 2, 3]
172 print "1, 2, 3"
173 when [1, b, 3]
174 print "1, #{b}, 3"
175 when [1, 2, b = 3]
176 print "1, 2, #{b}"
177
178do
179 switch tb
180 when success: true, :result
181 print "success", result
182 when success: false
183 print "failed", result
184 else
185 print "invalid"
186
187do
188 switch tb
189 when {type: "success", :content}
190 print "success", content
191 when {type: "error", :content}
192 print "failed", content
193 else
194 print "invalid"
195
196do
197 switch tb
198 when [
199 {a: 1, b: 2}
200 {a: 3, b: 4}
201 {a: 5, b: 6}
202 fourth
203 ]
204 print "matched", fourth
205
206 switch tb
207 when [
208 {c: 1, d: 2}
209 {c: 3, d: 4}
210 {c: 5, d: 6}
211 ]
212 print "OK"
213 when [
214 _
215 _
216 {a: 1, b: 2}
217 {a: 3, b: 4}
218 {a: 5, b: 6}
219 sixth
220 ]
221 print "matched", sixth
222
223nil \ No newline at end of file
diff --git a/spec/outputs/switch.lua b/spec/outputs/switch.lua
index e4dedc9..0f8bba2 100644
--- a/spec/outputs/switch.lua
+++ b/spec/outputs/switch.lua
@@ -415,4 +415,245 @@ do
415 end 415 end
416 end 416 end
417end 417end
418do
419 local _exp_0 = tb
420 local _type_0 = type(_exp_0)
421 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
422 local _match_0 = false
423 if _tab_0 then
424 if 1 == _exp_0[1] and 2 == _exp_0[2] and 3 == _exp_0[3] then
425 _match_0 = true
426 print("1, 2, 3")
427 end
428 end
429 if not _match_0 then
430 local _match_1 = false
431 if _tab_0 then
432 local b = _exp_0[2]
433 if 1 == _exp_0[1] and b ~= nil and 3 == _exp_0[3] then
434 _match_1 = true
435 print("1, " .. tostring(b) .. ", 3")
436 end
437 end
438 if not _match_1 then
439 if _tab_0 then
440 local b = _exp_0[3]
441 if b == nil then
442 b = 3
443 end
444 if 1 == _exp_0[1] and 2 == _exp_0[2] then
445 print("1, 2, " .. tostring(b))
446 end
447 end
448 end
449 end
450end
451do
452 local _exp_0 = tb
453 local _type_0 = type(_exp_0)
454 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
455 local _match_0 = false
456 if _tab_0 then
457 local result = _exp_0.result
458 if true == _exp_0.success and result ~= nil then
459 _match_0 = true
460 print("success", result)
461 end
462 end
463 if not _match_0 then
464 local _match_1 = false
465 if _tab_0 then
466 if false == _exp_0.success then
467 _match_1 = true
468 print("failed", result)
469 end
470 end
471 if not _match_1 then
472 print("invalid")
473 end
474 end
475end
476do
477 local _exp_0 = tb
478 local _type_0 = type(_exp_0)
479 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
480 local _match_0 = false
481 if _tab_0 then
482 local content = _exp_0.content
483 if "success" == _exp_0.type and content ~= nil then
484 _match_0 = true
485 print("success", content)
486 end
487 end
488 if not _match_0 then
489 local _match_1 = false
490 if _tab_0 then
491 local content = _exp_0.content
492 if "error" == _exp_0.type and content ~= nil then
493 _match_1 = true
494 print("failed", content)
495 end
496 end
497 if not _match_1 then
498 print("invalid")
499 end
500 end
501end
502do
503 do
504 local _exp_0 = tb
505 local _type_0 = type(_exp_0)
506 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
507 if _tab_0 then
508 local fourth = _exp_0[4]
509 local _val_0
510 do
511 local _obj_0 = _exp_0[1]
512 if _obj_0 ~= nil then
513 _val_0 = _obj_0.a
514 end
515 end
516 local _val_1
517 do
518 local _obj_0 = _exp_0[1]
519 if _obj_0 ~= nil then
520 _val_1 = _obj_0.b
521 end
522 end
523 local _val_2
524 do
525 local _obj_0 = _exp_0[2]
526 if _obj_0 ~= nil then
527 _val_2 = _obj_0.a
528 end
529 end
530 local _val_3
531 do
532 local _obj_0 = _exp_0[2]
533 if _obj_0 ~= nil then
534 _val_3 = _obj_0.b
535 end
536 end
537 local _val_4
538 do
539 local _obj_0 = _exp_0[3]
540 if _obj_0 ~= nil then
541 _val_4 = _obj_0.a
542 end
543 end
544 local _val_5
545 do
546 local _obj_0 = _exp_0[3]
547 if _obj_0 ~= nil then
548 _val_5 = _obj_0.b
549 end
550 end
551 if 1 == _val_0 and 2 == _val_1 and 3 == _val_2 and 4 == _val_3 and 5 == _val_4 and 6 == _val_5 and fourth ~= nil then
552 print("matched", fourth)
553 end
554 end
555 end
556 local _exp_0 = tb
557 local _type_0 = type(_exp_0)
558 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
559 local _match_0 = false
560 if _tab_0 then
561 local _val_0
562 do
563 local _obj_0 = _exp_0[1]
564 if _obj_0 ~= nil then
565 _val_0 = _obj_0.c
566 end
567 end
568 local _val_1
569 do
570 local _obj_0 = _exp_0[1]
571 if _obj_0 ~= nil then
572 _val_1 = _obj_0.d
573 end
574 end
575 local _val_2
576 do
577 local _obj_0 = _exp_0[2]
578 if _obj_0 ~= nil then
579 _val_2 = _obj_0.c
580 end
581 end
582 local _val_3
583 do
584 local _obj_0 = _exp_0[2]
585 if _obj_0 ~= nil then
586 _val_3 = _obj_0.d
587 end
588 end
589 local _val_4
590 do
591 local _obj_0 = _exp_0[3]
592 if _obj_0 ~= nil then
593 _val_4 = _obj_0.c
594 end
595 end
596 local _val_5
597 do
598 local _obj_0 = _exp_0[3]
599 if _obj_0 ~= nil then
600 _val_5 = _obj_0.d
601 end
602 end
603 if 1 == _val_0 and 2 == _val_1 and 3 == _val_2 and 4 == _val_3 and 5 == _val_4 and 6 == _val_5 then
604 _match_0 = true
605 print("OK")
606 end
607 end
608 if not _match_0 then
609 if _tab_0 then
610 local sixth = _exp_0[6]
611 local _val_0
612 do
613 local _obj_0 = _exp_0[3]
614 if _obj_0 ~= nil then
615 _val_0 = _obj_0.a
616 end
617 end
618 local _val_1
619 do
620 local _obj_0 = _exp_0[3]
621 if _obj_0 ~= nil then
622 _val_1 = _obj_0.b
623 end
624 end
625 local _val_2
626 do
627 local _obj_0 = _exp_0[4]
628 if _obj_0 ~= nil then
629 _val_2 = _obj_0.a
630 end
631 end
632 local _val_3
633 do
634 local _obj_0 = _exp_0[4]
635 if _obj_0 ~= nil then
636 _val_3 = _obj_0.b
637 end
638 end
639 local _val_4
640 do
641 local _obj_0 = _exp_0[5]
642 if _obj_0 ~= nil then
643 _val_4 = _obj_0.a
644 end
645 end
646 local _val_5
647 do
648 local _obj_0 = _exp_0[5]
649 if _obj_0 ~= nil then
650 _val_5 = _obj_0.b
651 end
652 end
653 if 1 == _val_0 and 2 == _val_1 and 3 == _val_2 and 4 == _val_3 and 5 == _val_4 and 6 == _val_5 and sixth ~= nil then
654 print("matched", sixth)
655 end
656 end
657 end
658end
418return nil 659return nil
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 06f0d6d..bc4574b 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -2814,19 +2814,19 @@ private:
2814 if (!varDefOnly) throw e; 2814 if (!varDefOnly) throw e;
2815 } 2815 }
2816 if (!assignable && !varDefOnly) { 2816 if (!assignable && !varDefOnly) {
2817 if (optional) { 2817 if (optional) break;
2818 if (defVal) { 2818 throw CompileError("can't destructure value"sv, pair);
2819 throw CompileError("default value is not supported here"sv, defVal); 2819 }
2820 } 2820 if (optional && varDefOnly && !assignable) {
2821 auto exp = static_cast<Exp_t*>(pair); 2821 if (defVal) {
2822 auto chain = exp->new_ptr<ChainValue_t>(); 2822 throw CompileError("default value is not supported here"sv, defVal);
2823 auto indexItem = toAst<Exp_t>(std::to_string(index), exp);
2824 chain->items.push_back(indexItem);
2825 pairs.push_back({exp, Empty, chain, nullptr});
2826 break;
2827 } else {
2828 throw CompileError("can't destructure value"sv, pair);
2829 } 2823 }
2824 auto exp = static_cast<Exp_t*>(pair);
2825 auto chain = exp->new_ptr<ChainValue_t>();
2826 auto indexItem = toAst<Exp_t>(std::to_string(index), exp);
2827 chain->items.push_back(indexItem);
2828 pairs.push_back({exp, Empty, chain, nullptr});
2829 break;
2830 } 2830 }
2831 auto value = singleValueFrom(pair); 2831 auto value = singleValueFrom(pair);
2832 auto item = value->item.get(); 2832 auto item = value->item.get();
@@ -2914,17 +2914,17 @@ private:
2914 if (!varDefOnly) throw e; 2914 if (!varDefOnly) throw e;
2915 } 2915 }
2916 if (!assignable && !varDefOnly) { 2916 if (!assignable && !varDefOnly) {
2917 if (optional) { 2917 if (optional) break;
2918 if (defVal) { 2918 throw CompileError("can't destructure value"sv, pair);
2919 throw CompileError("default value is not supported here"sv, defVal); 2919 }
2920 } 2920 if (optional && varDefOnly && !assignable) {
2921 auto chain = exp->new_ptr<ChainValue_t>(); 2921 if (defVal) {
2922 if (keyIndex) chain->items.push_back(keyIndex); 2922 throw CompileError("default value is not supported here"sv, defVal);
2923 pairs.push_back({exp, Empty, chain, nullptr});
2924 break;
2925 } else {
2926 throw CompileError("can't destructure value"sv, exp);
2927 } 2923 }
2924 auto chain = exp->new_ptr<ChainValue_t>();
2925 if (keyIndex) chain->items.push_back(keyIndex);
2926 pairs.push_back({exp, Empty, chain, nullptr});
2927 break;
2928 } 2928 }
2929 auto item = singleValueFrom(exp)->item.get(); 2929 auto item = singleValueFrom(exp)->item.get();
2930 ast_node* subExp = ast_cast<SimpleTable_t>(item); 2930 ast_node* subExp = ast_cast<SimpleTable_t>(item);
@@ -10652,16 +10652,26 @@ private:
10652 for (const auto& item : destruct.items) { 10652 for (const auto& item : destruct.items) {
10653 if (!item.defVal) { 10653 if (!item.defVal) {
10654 if (!isAssignable(item.target)) { 10654 if (!isAssignable(item.target)) {
10655 transformExp(item.target, conds, ExpUsage::Closure);
10656 auto callable = chainValue->items.front(); 10655 auto callable = chainValue->items.front();
10657 auto chain = callable->new_ptr<ChainValue_t>(); 10656 auto chain = callable->new_ptr<ChainValue_t>();
10658 chain->items.push_back(callable); 10657 chain->items.push_back(callable);
10659 chain->items.dup(item.structure->items); 10658 chain->items.dup(item.structure->items);
10660 transformChainValue(chain, conds, ExpUsage::Closure); 10659 if (specialChainValue(chain) == ChainType::Common) {
10661 auto vStr = conds.back(); 10660 transformChainValue(chain, conds, ExpUsage::Closure);
10662 conds.pop_back(); 10661 auto vStr = conds.back();
10663 conds.back().append(" == "s); 10662 conds.pop_back();
10664 conds.back().append(vStr); 10663 transformExp(item.target, conds, ExpUsage::Closure);
10664 conds.back().append(" == "s);
10665 conds.back().append(vStr);
10666 } else {
10667 auto varName = getUnusedName("_val_"sv);
10668 auto vExp = toAst<Exp_t>(varName, chain);
10669 auto asmt = assignmentFrom(vExp, newExp(chain, chain), chain);
10670 transformAssignment(asmt, temp);
10671 transformExp(item.target, conds, ExpUsage::Closure);
10672 conds.back().append(" == "s);
10673 conds.back().append(varName);
10674 }
10665 } else { 10675 } else {
10666 transformExp(item.target, conds, ExpUsage::Closure); 10676 transformExp(item.target, conds, ExpUsage::Closure);
10667 conds.back().append(" ~= nil"s); 10677 conds.back().append(" ~= nil"s);