aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2024-05-17 16:38:44 +0800
committerLi Jin <dragon-fly@qq.com>2024-05-17 16:38:44 +0800
commit06bf167924d04aaefe80d6e4ead40989a447ea34 (patch)
treeccd2c3b62797d378ee7cc1872440483d328980ca /src
parentfe317e2bdd9cb60b3c7cd347e21ce65cf90396e7 (diff)
downloadyuescript-06bf167924d04aaefe80d6e4ead40989a447ea34.tar.gz
yuescript-06bf167924d04aaefe80d6e4ead40989a447ea34.tar.bz2
yuescript-06bf167924d04aaefe80d6e4ead40989a447ea34.zip
fix more cases in try-catch syntax.v0.23.6
Diffstat (limited to 'src')
-rw-r--r--src/yuescript/yue_compiler.cpp326
1 files changed, 310 insertions, 16 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index c205031..7f6a042 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -75,7 +75,7 @@ static std::unordered_set<std::string> Metamethods = {
75 "close"s // Lua 5.4 75 "close"s // Lua 5.4
76}; 76};
77 77
78const std::string_view version = "0.23.4"sv; 78const std::string_view version = "0.23.6"sv;
79const std::string_view extension = "yue"sv; 79const std::string_view extension = "yue"sv;
80 80
81class CompileError : public std::logic_error { 81class CompileError : public std::logic_error {
@@ -577,6 +577,273 @@ private:
577 } 577 }
578 } 578 }
579 579
580 bool isConstTableItem(ast_node* item) {
581 switch (item->get_id()) {
582 case id<VariablePairDef_t>(): {
583 auto pair = static_cast<VariablePairDef_t*>(item);
584 if (pair->defVal) return false;
585 return isConstTableItem(pair->pair);
586 }
587 case id<NormalPairDef_t>(): {
588 auto pair = static_cast<NormalPairDef_t*>(item);
589 if (pair->defVal) return false;
590 return isConstTableItem(pair->pair);
591 }
592 case id<MetaVariablePairDef_t>(): {
593 auto pair = static_cast<MetaVariablePairDef_t*>(item);
594 if (pair->defVal) return false;
595 return isConstTableItem(pair->pair);
596 }
597 case id<MetaNormalPairDef_t>(): {
598 auto pair = static_cast<MetaNormalPairDef_t*>(item);
599 if (pair->defVal) return false;
600 return isConstTableItem(pair->pair);
601 }
602 case id<NormalDef_t>(): {
603 auto pair = static_cast<NormalDef_t*>(item);
604 if (pair->defVal) return false;
605 return isConstTableItem(pair->item);
606 }
607 case id<Exp_t>(): {
608 auto pair = static_cast<Exp_t*>(item);
609 return isConstExp(pair);
610 }
611 case id<VariablePair_t>(): {
612 auto pair = static_cast<VariablePair_t*>(item);
613 return isLocal(variableToString(pair->name));
614 }
615 case id<NormalPair_t>(): {
616 auto pair = static_cast<NormalPair_t*>(item);
617 if (auto exp = pair->key.as<Exp_t>()) {
618 if (!isConstExp(exp)) {
619 return false;
620 }
621 }
622 if (auto exp = pair->value.as<Exp_t>()) {
623 if (!isConstExp(exp)) {
624 return false;
625 }
626 } else if (auto tbBlock = pair->value.as<TableBlock_t>()) {
627 if (!isConstTable(tbBlock)) {
628 return false;
629 }
630 } else {
631 return false;
632 }
633 return true;
634 }
635 case id<TableBlockIndent_t>(): {
636 auto pair = static_cast<TableBlockIndent_t*>(item);
637 return isConstTable(pair);
638 }
639 case id<TableBlock_t>(): {
640 auto pair = static_cast<TableBlock_t*>(item);
641 return isConstTable(pair);
642 break;
643 }
644 case id<MetaVariablePair_t>(): {
645 auto pair = static_cast<MetaVariablePair_t*>(item);
646 return isLocal(variableToString(pair->name));
647 }
648 case id<MetaNormalPair_t>(): {
649 auto pair = static_cast<MetaNormalPair_t*>(item);
650 if (auto str = pair->key.as<String_t>()) {
651 if (!ast_is<SingleString_t, LuaString_t>(str)) {
652 return false;
653 }
654 } else if (auto exp = pair->key.as<Exp_t>()) {
655 if (!isConstExp(exp)) {
656 return false;
657 }
658 } else if (pair->key.is<Name_t>()) {
659 return true;
660 } else {
661 return false;
662 }
663 if (auto exp = pair->value.as<Exp_t>()) {
664 if (!isConstExp(exp)) {
665 return false;
666 }
667 } else if (auto tbBlock = pair->value.as<TableBlock_t>()) {
668 if (!isConstTable(tbBlock)) {
669 return false;
670 }
671 } else {
672 return false;
673 }
674 return true;
675 }
676 }
677 return false;
678 }
679
680 bool isConstTable(TableLit_t* tableLit) {
681 for (auto value : tableLit->values.objects()) {
682 if (!isConstTableItem(value)) {
683 return false;
684 }
685 }
686 return true;
687 }
688
689 bool isConstTable(TableBlock_t* tableBlock) {
690 for (auto value : tableBlock->values.objects()) {
691 if (!isConstTableItem(value)) {
692 return false;
693 }
694 }
695 return true;
696 }
697
698 bool isConstTable(SimpleTable_t* stable) {
699 for (auto value : stable->pairs.objects()) {
700 if (!isConstTableItem(value)) {
701 return false;
702 }
703 }
704 return true;
705 }
706
707 bool isConstTable(TableBlockIndent_t* table) {
708 for (auto value : table->values.objects()) {
709 if (!isConstTableItem(value)) {
710 return false;
711 }
712 }
713 return true;
714 }
715
716 bool isConstChainValue(ChainValue_t* value) {
717 auto var = singleVariableFrom(value, AccessType::None);
718 return isLocal(var);
719 }
720
721 bool isConstUnaryValue(UnaryValue_t* value) {
722 if (value->ops.size() > 1) {
723 return false;
724 }
725 auto unaryStr = _parser.toString(value->ops.front());
726 if (unaryStr == "-"sv) {
727 return value->value->item->get_by_path<SimpleValue_t, Num_t>();
728 } else if (unaryStr == "#"sv) {
729 return false;
730 } else if (unaryStr == "not"sv) {
731 return isConstValue(value->value);
732 }
733 return false;
734 }
735
736 bool isConstNum(Value_t* value) {
737 return value->get_by_path<SimpleValue_t, Num_t>();
738 }
739
740 bool isConstUnaryExp(UnaryExp_t* value) {
741 if (value->inExp) return false;
742 if (value->ops.size() == 0) {
743 if (value->expos.size() == 1) {
744 return isConstValue(static_cast<Value_t*>(value->expos.front()));
745 }
746 for (auto expo : value->expos.objects()) {
747 if (!isConstNum(static_cast<Value_t*>(expo))) {
748 return false;
749 }
750 }
751 return true;
752 }
753 if (value->ops.size() > 1) {
754 return false;
755 }
756 auto unaryStr = _parser.toString(value->ops.front());
757 if (unaryStr == "-"sv) {
758 for (auto expo : value->expos.objects()) {
759 if (!isConstNum(static_cast<Value_t*>(expo))) {
760 return false;
761 }
762 }
763 return true;
764 } else if (unaryStr == "#"sv) {
765 return false;
766 } else if (unaryStr == "not"sv) {
767 if (value->expos.size() == 1) {
768 return isConstValue(static_cast<Value_t*>(value->expos.front()));
769 }
770 for (auto expo : value->expos.objects()) {
771 if (!isConstNum(static_cast<Value_t*>(expo))) {
772 return false;
773 }
774 }
775 return true;
776 }
777 return false;
778 }
779
780 bool isConstValue(Value_t* value) {
781 if (auto strNode = value->item.as<String_t>()) {
782 switch (strNode->str->get_id()) {
783 case id<SingleString_t>():
784 case id<LuaString_t>():
785 return true;
786 case id<DoubleString_t>():
787 return false;
788 default:
789 YUEE("AST node mismatch", strNode->str);
790 return false;
791 }
792 } else if (auto chainValue = value->item.as<ChainValue_t>()) {
793 return isConstChainValue(chainValue);
794 } else if (auto simpleValue = value->item.as<SimpleValue_t>()) {
795 if (ast_is<ConstValue_t, Num_t, VarArg_t, FunLit_t>(simpleValue->value.get())) {
796 return true;
797 } else if (auto uValue = simpleValue->value.as<UnaryValue_t>()) {
798 return isConstUnaryValue(uValue);
799 } else if (auto comp = simpleValue->value.as<Comprehension_t>()) {
800 for (auto item : comp->items.objects()) {
801 if (auto ndef = ast_cast<NormalDef_t>(item)) {
802 if (ndef->defVal) {
803 return false;
804 }
805 if (!isConstExp(ndef->item)) {
806 return false;
807 }
808 } else {
809 return false;
810 }
811 }
812 return true;
813 } else if (auto tableLit = simpleValue->value.as<TableLit_t>()) {
814 return isConstTable(tableLit);
815 } else {
816 return false;
817 }
818 } else if (auto simpleTable = value->item.as<SimpleTable_t>()) {
819 return isConstTable(simpleTable);
820 }
821 return false;
822 }
823
824 bool isConstUnaryExps(const ast_list<true, UnaryExp_t>& list) {
825 if (list.size() > 1) {
826 return false;
827 }
828 if (!isConstUnaryExp(static_cast<UnaryExp_t*>(list.front()))) {
829 return false;
830 }
831 return true;
832 }
833
834 bool isConstExp(Exp_t* exp) {
835 if (exp->nilCoalesed) {
836 return false;
837 }
838 if (!isConstUnaryExps(exp->pipeExprs)) {
839 return false;
840 }
841 if (exp->opValues.empty()) {
842 return true;
843 }
844 return false;
845 }
846
580 void markVarConst(const std::string& name) { 847 void markVarConst(const std::string& name) {
581 auto& scope = _scopes.back(); 848 auto& scope = _scopes.back();
582 scope.vars->insert_or_assign(name, VarType::Const); 849 scope.vars->insert_or_assign(name, VarType::Const);
@@ -3691,7 +3958,7 @@ private:
3691 }) != traversal::Stop; 3958 }) != traversal::Stop;
3692 } 3959 }
3693 3960
3694 std::optional<std::pair<std::string, str_list>> getUpValueFuncFromBlock(Block_t* block, str_list* ensureArgListInTheEnd) { 3961 std::optional<std::pair<std::string, str_list>> getUpValueFuncFromBlock(Block_t* block, str_list* ensureArgListInTheEnd, bool noGlobalVarPassing) {
3695 if (_funcLevel <= 1) return std::nullopt; 3962 if (_funcLevel <= 1) return std::nullopt;
3696 auto result = block->traverse([&](ast_node* node) { 3963 auto result = block->traverse([&](ast_node* node) {
3697 switch (node->get_id()) { 3964 switch (node->get_id()) {
@@ -3754,6 +4021,9 @@ private:
3754 } else if (std::find(args.begin(), args.end(), global.name) == args.end()) { 4021 } else if (std::find(args.begin(), args.end(), global.name) == args.end()) {
3755 args.push_back(global.name); 4022 args.push_back(global.name);
3756 } 4023 }
4024 if (noGlobalVarPassing && !isLocal(global.name)) {
4025 return std::nullopt;
4026 }
3757 } 4027 }
3758 } 4028 }
3759 } 4029 }
@@ -3809,9 +4079,9 @@ private:
3809 } 4079 }
3810 4080
3811 4081
3812 std::optional<std::pair<std::string, str_list>> upValueFuncFrom(Block_t* block, str_list* ensureArgListInTheEnd = nullptr) { 4082 std::optional<std::pair<std::string, str_list>> upValueFuncFrom(Block_t* block, str_list* ensureArgListInTheEnd = nullptr, bool noGlobalVarPassing = false) {
3813 if (checkUpValueFuncAvailable(block)) { 4083 if (checkUpValueFuncAvailable(block)) {
3814 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd); 4084 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, noGlobalVarPassing);
3815 } 4085 }
3816 return std::nullopt; 4086 return std::nullopt;
3817 } 4087 }
@@ -3826,7 +4096,7 @@ private:
3826 auto stmt = exp->new_ptr<Statement_t>(); 4096 auto stmt = exp->new_ptr<Statement_t>();
3827 stmt->content.set(returnNode); 4097 stmt->content.set(returnNode);
3828 block->statements.push_back(stmt); 4098 block->statements.push_back(stmt);
3829 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd); 4099 return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false);
3830 } 4100 }
3831 return std::nullopt; 4101 return std::nullopt;
3832 } 4102 }
@@ -9135,23 +9405,47 @@ private:
9135 BREAK_IF(var.empty()); 9405 BREAK_IF(var.empty());
9136 tryFunc.set(expListAssign->expList->exprs.front()); 9406 tryFunc.set(expListAssign->expList->exprs.front());
9137 BLOCK_END 9407 BLOCK_END
9138 } else { 9408 }
9139 auto tryExp = tryFunc.as<Exp_t>(); 9409 if (auto tryExp = tryFunc.as<Exp_t>()) {
9140 bool needWrap = singleVariableFrom(tryExp, AccessType::None).empty(); 9410 bool wrapped = true;
9141 BLOCK_START 9411 BLOCK_START
9142 auto value = singleValueFrom(tryExp); 9412 auto value = singleValueFrom(tryExp);
9143 BREAK_IF(!value); 9413 BREAK_IF(!value);
9144 auto chainValue = value->item.as<ChainValue_t>(); 9414 auto chainValue = value->item.as<ChainValue_t>();
9145 BREAK_IF(!chainValue); 9415 BREAK_IF(!chainValue);
9146 BREAK_IF(!isChainValueCall(chainValue)); 9416 BREAK_IF(!isChainValueCall(chainValue));
9147 auto tmpChain = chainValue->new_ptr<ChainValue_t>(); 9417 auto chainCaller = chainValue->new_ptr<ChainValue_t>();
9148 tmpChain->items.dup(chainValue->items); 9418 chainCaller->items.dup(chainValue->items);
9149 tmpChain->items.pop_back(); 9419 chainCaller->items.pop_back();
9150 auto var = singleVariableFrom(tmpChain, AccessType::None); 9420 BREAK_IF(!isConstChainValue(chainCaller));
9151 BREAK_IF(var.empty()); 9421 _ast_list* args = nullptr;
9152 needWrap = false; 9422 if (auto invoke = ast_cast<InvokeArgs_t>(chainValue->items.back())) {
9423 args = &invoke->args;
9424 } else {
9425 args = &(ast_to<Invoke_t>(chainValue->items.back())->args);
9426 }
9427 wrapped = false;
9428 for (auto arg : args->objects()) {
9429 switch (arg->get_id()) {
9430 case id<Exp_t>():
9431 if (isConstExp(static_cast<Exp_t*>(arg))) continue;
9432 break;
9433 case id<SingleString_t>():
9434 case id<LuaString_t>():
9435 continue;
9436 case id<DoubleString_t>():
9437 break;
9438 case id<TableLit_t>():
9439 if (isConstTable(static_cast<TableLit_t*>(arg))) continue;
9440 break;
9441 case id<TableBlock_t>():
9442 if (isConstTable(static_cast<TableBlock_t*>(arg))) continue;
9443 break;
9444 }
9445 wrapped = true;
9446 }
9153 BLOCK_END 9447 BLOCK_END
9154 if (needWrap) { 9448 if (wrapped) {
9155 auto expList = x->new_ptr<ExpList_t>(); 9449 auto expList = x->new_ptr<ExpList_t>();
9156 expList->exprs.push_back(tryFunc); 9450 expList->exprs.push_back(tryFunc);
9157 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 9451 auto expListAssign = x->new_ptr<ExpListAssign_t>();
@@ -9165,7 +9459,7 @@ private:
9165 } 9459 }
9166 if (auto tryBlock = tryFunc.as<Block_t>()) { 9460 if (auto tryBlock = tryFunc.as<Block_t>()) {
9167 if (getLuaTarget(tryBlock) >= 502 || !errHandler) { 9461 if (getLuaTarget(tryBlock) >= 502 || !errHandler) {
9168 if (auto result = upValueFuncFrom(tryBlock)) { 9462 if (auto result = upValueFuncFrom(tryBlock, nullptr, true)) {
9169 auto [funcName, args] = std::move(*result); 9463 auto [funcName, args] = std::move(*result);
9170 if (errHandler) { 9464 if (errHandler) {
9171 auto xpcall = toAst<ChainValue_t>("xpcall()", x); 9465 auto xpcall = toAst<ChainValue_t>("xpcall()", x);