aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/MoonP/moon_compiler.cpp157
1 files changed, 93 insertions, 64 deletions
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp
index 0028f22..58b3bb0 100644
--- a/src/MoonP/moon_compiler.cpp
+++ b/src/MoonP/moon_compiler.cpp
@@ -337,7 +337,7 @@ private:
337 return _converter.to_bytes(std::wstring(begin, end)); 337 return _converter.to_bytes(std::wstring(begin, end));
338 } 338 }
339 339
340 Value_t* singleValueFrom(ast_node* item) { 340 Value_t* singleValueFrom(ast_node* item) const {
341 Exp_t* exp = nullptr; 341 Exp_t* exp = nullptr;
342 switch (item->getId()) { 342 switch (item->getId()) {
343 case "Exp"_id: 343 case "Exp"_id:
@@ -491,7 +491,7 @@ private:
491 return Empty; 491 return Empty;
492 } 492 }
493 493
494 bool isAssignable(const node_container& chainItems) { 494 bool isAssignable(const node_container& chainItems) const {
495 if (chainItems.size() == 1) { 495 if (chainItems.size() == 1) {
496 auto firstItem = chainItems.back(); 496 auto firstItem = chainItems.back();
497 if (auto callable = ast_cast<Callable_t>(firstItem)) { 497 if (auto callable = ast_cast<Callable_t>(firstItem)) {
@@ -514,7 +514,7 @@ private:
514 return false; 514 return false;
515 } 515 }
516 516
517 bool isAssignable(Exp_t* exp) { 517 bool isAssignable(Exp_t* exp) const {
518 if (auto value = singleValueFrom(exp)) { 518 if (auto value = singleValueFrom(exp)) {
519 auto item = value->item.get(); 519 auto item = value->item.get();
520 switch (item->getId()) { 520 switch (item->getId()) {
@@ -522,7 +522,7 @@ private:
522 return true; 522 return true;
523 case "SimpleValue"_id: { 523 case "SimpleValue"_id: {
524 auto simpleValue = static_cast<SimpleValue_t*>(item); 524 auto simpleValue = static_cast<SimpleValue_t*>(item);
525 if (simpleValue->value.is<TableLit_t>()) { 525 if (simpleValue->value. is<TableLit_t>()) {
526 return true; 526 return true;
527 } 527 }
528 return false; 528 return false;
@@ -536,14 +536,14 @@ private:
536 return false; 536 return false;
537 } 537 }
538 538
539 bool isAssignable(Assignable_t* assignable) { 539 bool isAssignable(Assignable_t* assignable) const {
540 if (auto assignableChain = ast_cast<AssignableChain_t>(assignable->item)) { 540 if (auto assignableChain = ast_cast<AssignableChain_t>(assignable->item)) {
541 return isAssignable(assignableChain->items.objects()); 541 return isAssignable(assignableChain->items.objects());
542 } 542 }
543 return true; 543 return true;
544 } 544 }
545 545
546 void checkAssignable(ExpList_t* expList) { 546 void checkAssignable(ExpList_t* expList) const {
547 for (auto exp_ : expList->exprs.objects()) { 547 for (auto exp_ : expList->exprs.objects()) {
548 Exp_t* exp = static_cast<Exp_t*>(exp_); 548 Exp_t* exp = static_cast<Exp_t*>(exp_);
549 if (!isAssignable(exp)) { 549 if (!isAssignable(exp)) {
@@ -552,7 +552,22 @@ private:
552 } 552 }
553 } 553 }
554 554
555 std::string debugInfo(std::string_view msg, const input_range* loc) { 555 bool isPureBackcall(Exp_t* exp) const {
556 if (exp->opValues.empty()) {
557 return false;
558 }
559 bool backcall = true;
560 for (auto _opValue : exp->opValues.objects()) {
561 auto opValue = static_cast<exp_op_value_t*>(_opValue);
562 if (!opValue->op.is<BackcallOperator_t>()) {
563 backcall = false;
564 break;
565 }
566 }
567 return backcall;
568 }
569
570 std::string debugInfo(std::string_view msg, const input_range* loc) const {
556 const int ASCII = 255; 571 const int ASCII = 255;
557 int length = loc->m_begin.m_line; 572 int length = loc->m_begin.m_line;
558 auto begin = _input.begin(); 573 auto begin = _input.begin();
@@ -569,7 +584,7 @@ private:
569 count++; 584 count++;
570 } 585 }
571 } 586 }
572 auto line = _converter.to_bytes(std::wstring(begin, end)); 587 auto line = Converter{}.to_bytes(std::wstring(begin, end));
573 int oldCol = loc->m_begin.m_col; 588 int oldCol = loc->m_begin.m_col;
574 int col = std::max(0, oldCol - 1); 589 int col = std::max(0, oldCol - 1);
575 auto it = begin; 590 auto it = begin;
@@ -741,20 +756,9 @@ private:
741 } 756 }
742 } else if (expList->exprs.size() == 1){ 757 } else if (expList->exprs.size() == 1){
743 auto exp = static_cast<Exp_t*>(expList->exprs.back()); 758 auto exp = static_cast<Exp_t*>(expList->exprs.back());
744 if (exp->opValues.size() > 0) { 759 if (isPureBackcall(exp)) {
745 bool backcall = true; 760 transformExp(exp, out, ExpUsage::Common);
746 for (auto _opValue : exp->opValues.objects()) { 761 break;
747 auto opValue = static_cast<exp_op_value_t*>(_opValue);
748 if (!opValue->op.is<BackcallOperator_t>()) {
749 backcall = false;
750 break;
751 }
752 }
753 if (backcall) {
754 transformExp(exp, out);
755 out.back().append(nll(exp));
756 break;
757 }
758 } 762 }
759 } 763 }
760 throw std::logic_error(debugInfo("Expression list must appear at the end of body block."sv, expList)); 764 throw std::logic_error(debugInfo("Expression list must appear at the end of body block."sv, expList));
@@ -1046,6 +1050,11 @@ private:
1046 break; 1050 break;
1047 } 1051 }
1048 } 1052 }
1053 if (isPureBackcall(exp)) {
1054 auto expList = assignment->expList.get();
1055 transformExp(exp, out, ExpUsage::Assignment, expList);
1056 return;
1057 }
1049 BLOCK_END 1058 BLOCK_END
1050 auto info = extractDestructureInfo(assignment); 1059 auto info = extractDestructureInfo(assignment);
1051 if (info.first.empty()) { 1060 if (info.first.empty()) {
@@ -1116,7 +1125,7 @@ private:
1116 case "If"_id: transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break; 1125 case "If"_id: transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break;
1117 case "Switch"_id: transformSwitchClosure(static_cast<Switch_t*>(value), out); break; 1126 case "Switch"_id: transformSwitchClosure(static_cast<Switch_t*>(value), out); break;
1118 case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), out); break; 1127 case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), out); break;
1119 case "Exp"_id: transformExp(static_cast<Exp_t*>(value), out); break; 1128 case "Exp"_id: transformExp(static_cast<Exp_t*>(value), out, ExpUsage::Closure); break;
1120 default: break; 1129 default: break;
1121 } 1130 }
1122 } 1131 }
@@ -1162,7 +1171,7 @@ private:
1162 bool isVariable = !varName.empty(); 1171 bool isVariable = !varName.empty();
1163 if (!isVariable) { 1172 if (!isVariable) {
1164 str_list temp; 1173 str_list temp;
1165 transformExp(exp, temp); 1174 transformExp(exp, temp, ExpUsage::Closure);
1166 varName = std::move(temp.back()); 1175 varName = std::move(temp.back());
1167 } 1176 }
1168 _config.lintGlobalVariable = lintGlobal; 1177 _config.lintGlobalVariable = lintGlobal;
@@ -1211,7 +1220,7 @@ private:
1211 bool isVariable = !varName.empty(); 1220 bool isVariable = !varName.empty();
1212 if (!isVariable) { 1221 if (!isVariable) {
1213 str_list temp; 1222 str_list temp;
1214 transformExp(exp, temp); 1223 transformExp(exp, temp, ExpUsage::Closure);
1215 varName = std::move(temp.back()); 1224 varName = std::move(temp.back());
1216 } 1225 }
1217 _config.lintGlobalVariable = lintGlobal; 1226 _config.lintGlobalVariable = lintGlobal;
@@ -1342,7 +1351,7 @@ private:
1342 transformValue(leftValue, temp); 1351 transformValue(leftValue, temp);
1343 auto left = std::move(temp.back()); 1352 auto left = std::move(temp.back());
1344 temp.pop_back(); 1353 temp.pop_back();
1345 transformExp(update->value, temp); 1354 transformExp(update->value, temp, ExpUsage::Closure);
1346 auto right = std::move(temp.back()); 1355 auto right = std::move(temp.back());
1347 temp.pop_back(); 1356 temp.pop_back();
1348 if (!singleValueFrom(update->value)) { 1357 if (!singleValueFrom(update->value)) {
@@ -1543,13 +1552,13 @@ private:
1543 if (auto value = singleValueFrom(condition)) { 1552 if (auto value = singleValueFrom(condition)) {
1544 transformValue(value, tmp); 1553 transformValue(value, tmp);
1545 } else { 1554 } else {
1546 transformExp(condition, tmp); 1555 transformExp(condition, tmp, ExpUsage::Closure);
1547 tmp.back() = s("("sv) + tmp.back() + s(")"sv); 1556 tmp.back() = s("("sv) + tmp.back() + s(")"sv);
1548 } 1557 }
1549 tmp.back().insert(0, s("not "sv)); 1558 tmp.back().insert(0, s("not "sv));
1550 unless = false; 1559 unless = false;
1551 } else { 1560 } else {
1552 transformExp(condition, tmp); 1561 transformExp(condition, tmp, ExpUsage::Closure);
1553 } 1562 }
1554 _buf << indent(); 1563 _buf << indent();
1555 if (pair != ifCondPairs.front()) { 1564 if (pair != ifCondPairs.front()) {
@@ -1596,7 +1605,7 @@ private:
1596 void transformExpList(ExpList_t* expList, str_list& out) { 1605 void transformExpList(ExpList_t* expList, str_list& out) {
1597 str_list temp; 1606 str_list temp;
1598 for (auto exp : expList->exprs.objects()) { 1607 for (auto exp : expList->exprs.objects()) {
1599 transformExp(static_cast<Exp_t*>(exp), temp); 1608 transformExp(static_cast<Exp_t*>(exp), temp, ExpUsage::Closure);
1600 } 1609 }
1601 out.push_back(join(temp, ", "sv)); 1610 out.push_back(join(temp, ", "sv));
1602 } 1611 }
@@ -1604,12 +1613,12 @@ private:
1604 void transformExpListLow(ExpListLow_t* expListLow, str_list& out) { 1613 void transformExpListLow(ExpListLow_t* expListLow, str_list& out) {
1605 str_list temp; 1614 str_list temp;
1606 for (auto exp : expListLow->exprs.objects()) { 1615 for (auto exp : expListLow->exprs.objects()) {
1607 transformExp(static_cast<Exp_t*>(exp), temp); 1616 transformExp(static_cast<Exp_t*>(exp), temp, ExpUsage::Closure);
1608 } 1617 }
1609 out.push_back(join(temp, ", "sv)); 1618 out.push_back(join(temp, ", "sv));
1610 } 1619 }
1611 1620
1612 void transformExp(Exp_t* exp, str_list& out) { 1621 void transformExp(Exp_t* exp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
1613 auto x = exp; 1622 auto x = exp;
1614 const auto& opValues = exp->opValues.objects(); 1623 const auto& opValues = exp->opValues.objects();
1615 for (auto it = opValues.begin(); it != opValues.end(); ++it) { 1624 for (auto it = opValues.begin(); it != opValues.end(); ++it) {
@@ -1643,7 +1652,20 @@ private:
1643 value->item.set(chainValue); 1652 value->item.set(chainValue);
1644 newExp->value.set(value); 1653 newExp->value.set(value);
1645 } 1654 }
1646 transformExp(newExp, out); 1655 if (newExp->opValues.size() == 0) {
1656 if (usage == ExpUsage::Assignment) {
1657 auto assign = x->new_ptr<Assign_t>();
1658 assign->values.push_back(newExp);
1659 auto assignment = x->new_ptr<ExpListAssign_t>();
1660 assignment->expList.set(assignList);
1661 assignment->action.set(assign);
1662 transformAssignment(assignment, out);
1663 } else {
1664 transformChainValue(chainValue, out, usage);
1665 }
1666 } else {
1667 transformExp(newExp, out, usage, assignList);
1668 }
1647 return; 1669 return;
1648 } else { 1670 } else {
1649 throw std::logic_error(debugInfo("Backcall operator must be followed by chain value."sv, opValue->value)); 1671 throw std::logic_error(debugInfo("Backcall operator must be followed by chain value."sv, opValue->value));
@@ -1711,7 +1733,7 @@ private:
1711 1733
1712 void transformParens(Parens_t* parans, str_list& out) { 1734 void transformParens(Parens_t* parans, str_list& out) {
1713 str_list temp; 1735 str_list temp;
1714 transformExp(parans->expr, temp); 1736 transformExp(parans->expr, temp, ExpUsage::Closure);
1715 out.push_back(s("("sv) + temp.front() + s(")"sv)); 1737 out.push_back(s("("sv) + temp.front() + s(")"sv));
1716 } 1738 }
1717 1739
@@ -1963,6 +1985,13 @@ private:
1963 1985
1964 void transformReturn(Return_t* returnNode, str_list& out) { 1986 void transformReturn(Return_t* returnNode, str_list& out) {
1965 if (auto valueList = returnNode->valueList.get()) { 1987 if (auto valueList = returnNode->valueList.get()) {
1988 if (valueList->exprs.size() == 1) {
1989 auto exp = static_cast<Exp_t*>(valueList->exprs.back());
1990 if (isPureBackcall(exp)) {
1991 transformExp(exp, out, ExpUsage::Return);
1992 return;
1993 }
1994 }
1966 if (auto singleValue = singleValueFrom(valueList)) { 1995 if (auto singleValue = singleValueFrom(valueList)) {
1967 if (auto simpleValue = singleValue->item.as<SimpleValue_t>()) { 1996 if (auto simpleValue = singleValue->item.as<SimpleValue_t>()) {
1968 auto value = simpleValue->value.get(); 1997 auto value = simpleValue->value.get();
@@ -2640,7 +2669,7 @@ private:
2640 temp.back() = s("("sv) + temp.back() + s(")"sv); 2669 temp.back() = s("("sv) + temp.back() + s(")"sv);
2641 break; 2670 break;
2642 case "Exp"_id: 2671 case "Exp"_id:
2643 transformExp(static_cast<Exp_t*>(item), temp); 2672 transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure);
2644 temp.back() = s("["sv) + temp.back() + s("]"sv); 2673 temp.back() = s("["sv) + temp.back() + s("]"sv);
2645 break; 2674 break;
2646 case "InvokeArgs"_id: transformInvokeArgs(static_cast<InvokeArgs_t*>(item), temp); break; 2675 case "InvokeArgs"_id: transformInvokeArgs(static_cast<InvokeArgs_t*>(item), temp); break;
@@ -2700,7 +2729,7 @@ private:
2700 str_list temp; 2729 str_list temp;
2701 for (auto arg : invoke->args.objects()) { 2730 for (auto arg : invoke->args.objects()) {
2702 switch (arg->getId()) { 2731 switch (arg->getId()) {
2703 case "Exp"_id: transformExp(static_cast<Exp_t*>(arg), temp); break; 2732 case "Exp"_id: transformExp(static_cast<Exp_t*>(arg), temp, ExpUsage::Closure); break;
2704 case "SingleString"_id: transformSingleString(static_cast<SingleString_t*>(arg), temp); break; 2733 case "SingleString"_id: transformSingleString(static_cast<SingleString_t*>(arg), temp); break;
2705 case "DoubleString"_id: transformDoubleString(static_cast<DoubleString_t*>(arg), temp); break; 2734 case "DoubleString"_id: transformDoubleString(static_cast<DoubleString_t*>(arg), temp); break;
2706 case "LuaString"_id: transformLuaString(static_cast<LuaString_t*>(arg), temp); break; 2735 case "LuaString"_id: transformLuaString(static_cast<LuaString_t*>(arg), temp); break;
@@ -2713,7 +2742,7 @@ private:
2713 void transform_unary_exp(unary_exp_t* unary_exp, str_list& out) { 2742 void transform_unary_exp(unary_exp_t* unary_exp, str_list& out) {
2714 std::string op = toString(unary_exp->m_begin.m_it, unary_exp->item->m_begin.m_it); 2743 std::string op = toString(unary_exp->m_begin.m_it, unary_exp->item->m_begin.m_it);
2715 str_list temp{op + (op == "not"sv ? s(" "sv) : Empty)}; 2744 str_list temp{op + (op == "not"sv ? s(" "sv) : Empty)};
2716 transformExp(unary_exp->item, temp); 2745 transformExp(unary_exp->item, temp, ExpUsage::Closure);
2717 out.push_back(join(temp)); 2746 out.push_back(join(temp));
2718 } 2747 }
2719 2748
@@ -2742,7 +2771,7 @@ private:
2742 transformCompFor(static_cast<CompFor_t*>(item), temp); 2771 transformCompFor(static_cast<CompFor_t*>(item), temp);
2743 break; 2772 break;
2744 case "Exp"_id: 2773 case "Exp"_id:
2745 transformExp(static_cast<Exp_t*>(item), temp); 2774 transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure);
2746 temp.back() = indent() + s("if "sv) + temp.back() + s(" then"sv) + nll(item); 2775 temp.back() = indent() + s("if "sv) + temp.back() + s(" then"sv) + nll(item);
2747 pushScope(); 2776 pushScope();
2748 break; 2777 break;
@@ -2794,7 +2823,7 @@ private:
2794 transformCompFor(static_cast<CompFor_t*>(item), temp); 2823 transformCompFor(static_cast<CompFor_t*>(item), temp);
2795 break; 2824 break;
2796 case "Exp"_id: 2825 case "Exp"_id:
2797 transformExp(static_cast<Exp_t*>(item), temp); 2826 transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure);
2798 temp.back() = indent() + s("if "sv) + temp.back() + s(" then"sv) + nll(item); 2827 temp.back() = indent() + s("if "sv) + temp.back() + s(" then"sv) + nll(item);
2799 pushScope(); 2828 pushScope();
2800 break; 2829 break;
@@ -2908,19 +2937,19 @@ private:
2908 } 2937 }
2909 std::string startValue("1"sv); 2938 std::string startValue("1"sv);
2910 if (auto exp = slice->startValue.as<Exp_t>()) { 2939 if (auto exp = slice->startValue.as<Exp_t>()) {
2911 transformExp(exp, temp); 2940 transformExp(exp, temp, ExpUsage::Closure);
2912 startValue = temp.back(); 2941 startValue = temp.back();
2913 temp.pop_back(); 2942 temp.pop_back();
2914 } 2943 }
2915 std::string stopValue; 2944 std::string stopValue;
2916 if (auto exp = slice->stopValue.as<Exp_t>()) { 2945 if (auto exp = slice->stopValue.as<Exp_t>()) {
2917 transformExp(exp, temp); 2946 transformExp(exp, temp, ExpUsage::Closure);
2918 stopValue = temp.back(); 2947 stopValue = temp.back();
2919 temp.pop_back(); 2948 temp.pop_back();
2920 } 2949 }
2921 std::string stepValue; 2950 std::string stepValue;
2922 if (auto exp = slice->stepValue.as<Exp_t>()) { 2951 if (auto exp = slice->stepValue.as<Exp_t>()) {
2923 transformExp(exp, temp); 2952 transformExp(exp, temp, ExpUsage::Closure);
2924 stepValue = temp.back(); 2953 stepValue = temp.back();
2925 temp.pop_back(); 2954 temp.pop_back();
2926 } 2955 }
@@ -2957,7 +2986,7 @@ private:
2957 varBefore.push_back(listVar); 2986 varBefore.push_back(listVar);
2958 } 2987 }
2959 if (!endWithSlice) { 2988 if (!endWithSlice) {
2960 transformExp(star_exp->value, temp); 2989 transformExp(star_exp->value, temp, ExpUsage::Closure);
2961 if (newListVal) _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); 2990 if (newListVal) _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList);
2962 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << listVar << " do"sv << nlr(loopTarget); 2991 _buf << indent() << "for "sv << indexVar << " = 1, #"sv << listVar << " do"sv << nlr(loopTarget);
2963 _buf << indent(1) << "local "sv << join(vars) << " = "sv << listVar << "["sv << indexVar << "]"sv << nll(nameList); 2992 _buf << indent(1) << "local "sv << join(vars) << " = "sv << listVar << "["sv << indexVar << "]"sv << nll(nameList);
@@ -2966,7 +2995,7 @@ private:
2966 break; 2995 break;
2967 } 2996 }
2968 case "Exp"_id: 2997 case "Exp"_id:
2969 transformExp(static_cast<Exp_t*>(loopTarget), temp); 2998 transformExp(static_cast<Exp_t*>(loopTarget), temp, ExpUsage::Closure);
2970 _buf << indent() << "for "sv << join(vars, ", "sv) << " in "sv << temp.back() << " do"sv << nlr(loopTarget); 2999 _buf << indent() << "for "sv << join(vars, ", "sv) << " in "sv << temp.back() << " do"sv << nlr(loopTarget);
2971 out.push_back(clearBuf()); 3000 out.push_back(clearBuf());
2972 break; 3001 break;
@@ -3010,7 +3039,7 @@ private:
3010 str_list temp; 3039 str_list temp;
3011 for (auto arg : invokeArgs->args.objects()) { 3040 for (auto arg : invokeArgs->args.objects()) {
3012 switch (arg->getId()) { 3041 switch (arg->getId()) {
3013 case "Exp"_id: transformExp(static_cast<Exp_t*>(arg), temp); break; 3042 case "Exp"_id: transformExp(static_cast<Exp_t*>(arg), temp, ExpUsage::Closure); break;
3014 case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(arg), temp); break; 3043 case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(arg), temp); break;
3015 default: break; 3044 default: break;
3016 } 3045 }
@@ -3021,10 +3050,10 @@ private:
3021 void transformForHead(For_t* forNode, str_list& out) { 3050 void transformForHead(For_t* forNode, str_list& out) {
3022 str_list temp; 3051 str_list temp;
3023 std::string varName = toString(forNode->varName); 3052 std::string varName = toString(forNode->varName);
3024 transformExp(forNode->startValue, temp); 3053 transformExp(forNode->startValue, temp, ExpUsage::Closure);
3025 transformExp(forNode->stopValue, temp); 3054 transformExp(forNode->stopValue, temp, ExpUsage::Closure);
3026 if (forNode->stepValue) { 3055 if (forNode->stepValue) {
3027 transformExp(forNode->stepValue->value, temp); 3056 transformExp(forNode->stepValue->value, temp, ExpUsage::Closure);
3028 } else { 3057 } else {
3029 temp.emplace_back(); 3058 temp.emplace_back();
3030 } 3059 }
@@ -3229,7 +3258,7 @@ private:
3229 break; 3258 break;
3230 } 3259 }
3231 case "Exp"_id: 3260 case "Exp"_id:
3232 transformExp(static_cast<Exp_t*>(key), temp); 3261 transformExp(static_cast<Exp_t*>(key), temp, ExpUsage::Closure);
3233 temp.back() = s("["sv) + temp.back() + s("]"sv); 3262 temp.back() = s("["sv) + temp.back() + s("]"sv);
3234 break; 3263 break;
3235 case "DoubleString"_id: 3264 case "DoubleString"_id:
@@ -3243,7 +3272,7 @@ private:
3243 } 3272 }
3244 auto value = pair->value.get(); 3273 auto value = pair->value.get();
3245 switch (value->getId()) { 3274 switch (value->getId()) {
3246 case "Exp"_id: transformExp(static_cast<Exp_t*>(value), temp); break; 3275 case "Exp"_id: transformExp(static_cast<Exp_t*>(value), temp, ExpUsage::Closure); break;
3247 case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), temp); break; 3276 case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), temp); break;
3248 default: break; 3277 default: break;
3249 } 3278 }
@@ -3259,7 +3288,7 @@ private:
3259 } 3288 }
3260 } 3289 }
3261 3290
3262 void replace(std::string& str, std::string_view from, std::string_view to) { 3291 void replace(std::string& str, std::string_view from, std::string_view to) const {
3263 size_t start_pos = 0; 3292 size_t start_pos = 0;
3264 while((start_pos = str.find(from, start_pos)) != std::string::npos) { 3293 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
3265 str.replace(start_pos, from.size(), to); 3294 str.replace(start_pos, from.size(), to);
@@ -3295,7 +3324,7 @@ private:
3295 break; 3324 break;
3296 } 3325 }
3297 case "Exp"_id: 3326 case "Exp"_id:
3298 transformExp(static_cast<Exp_t*>(content), temp); 3327 transformExp(static_cast<Exp_t*>(content), temp, ExpUsage::Closure);
3299 temp.back() = s("tostring("sv) + temp.back() + s(")"sv); 3328 temp.back() = s("tostring("sv) + temp.back() + s(")"sv);
3300 break; 3329 break;
3301 default: break; 3330 default: break;
@@ -3428,7 +3457,7 @@ private:
3428 if (extend) { 3457 if (extend) {
3429 parentVar = getUnusedName("_parent_"sv); 3458 parentVar = getUnusedName("_parent_"sv);
3430 addToScope(parentVar); 3459 addToScope(parentVar);
3431 transformExp(extend, temp); 3460 transformExp(extend, temp, ExpUsage::Closure);
3432 parent = temp.back(); 3461 parent = temp.back();
3433 temp.pop_back(); 3462 temp.pop_back();
3434 temp.push_back(indent() + s("local "sv) + parentVar + s(" = "sv) + parent + nll(classDecl)); 3463 temp.push_back(indent() + s("local "sv) + parentVar + s(" = "sv) + parent + nll(classDecl));
@@ -3904,7 +3933,7 @@ private:
3904 pushScope(); 3933 pushScope();
3905 for (auto pair : pairs) { 3934 for (auto pair : pairs) {
3906 switch (pair->getId()) { 3935 switch (pair->getId()) {
3907 case "Exp"_id: transformExp(static_cast<Exp_t*>(pair), temp); break; 3936 case "Exp"_id: transformExp(static_cast<Exp_t*>(pair), temp, ExpUsage::Closure); break;
3908 case "variable_pair"_id: transform_variable_pair(static_cast<variable_pair_t*>(pair), temp); break; 3937 case "variable_pair"_id: transform_variable_pair(static_cast<variable_pair_t*>(pair), temp); break;
3909 case "normal_pair"_id: transform_normal_pair(static_cast<normal_pair_t*>(pair), temp); break; 3938 case "normal_pair"_id: transform_normal_pair(static_cast<normal_pair_t*>(pair), temp); break;
3910 } 3939 }
@@ -3943,15 +3972,15 @@ private:
3943 transformCompFor(static_cast<CompFor_t*>(item), temp); 3972 transformCompFor(static_cast<CompFor_t*>(item), temp);
3944 break; 3973 break;
3945 case "Exp"_id: 3974 case "Exp"_id:
3946 transformExp(static_cast<Exp_t*>(item), temp); 3975 transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure);
3947 temp.back() = indent() + s("if "sv) + temp.back() + s(" then"sv) + nll(item); 3976 temp.back() = indent() + s("if "sv) + temp.back() + s(" then"sv) + nll(item);
3948 pushScope(); 3977 pushScope();
3949 break; 3978 break;
3950 } 3979 }
3951 } 3980 }
3952 transformExp(comp->key, kv); 3981 transformExp(comp->key, kv, ExpUsage::Closure);
3953 if (comp->value) { 3982 if (comp->value) {
3954 transformExp(comp->value->value, kv); 3983 transformExp(comp->value->value, kv, ExpUsage::Closure);
3955 } 3984 }
3956 for (size_t i = 0; i < compInner->items.objects().size(); ++i) { 3985 for (size_t i = 0; i < compInner->items.objects().size(); ++i) {
3957 popScope(); 3986 popScope();
@@ -4004,10 +4033,10 @@ private:
4004 void transformCompFor(CompFor_t* comp, str_list& out) { 4033 void transformCompFor(CompFor_t* comp, str_list& out) {
4005 str_list temp; 4034 str_list temp;
4006 std::string varName = toString(comp->varName); 4035 std::string varName = toString(comp->varName);
4007 transformExp(comp->startValue, temp); 4036 transformExp(comp->startValue, temp, ExpUsage::Closure);
4008 transformExp(comp->stopValue, temp); 4037 transformExp(comp->stopValue, temp, ExpUsage::Closure);
4009 if (comp->stepValue) { 4038 if (comp->stepValue) {
4010 transformExp(comp->stepValue->value, temp); 4039 transformExp(comp->stepValue->value, temp, ExpUsage::Closure);
4011 } else { 4040 } else {
4012 temp.emplace_back(); 4041 temp.emplace_back();
4013 } 4042 }
@@ -4200,7 +4229,7 @@ private:
4200 addToScope(lenVar); 4229 addToScope(lenVar);
4201 temp.push_back(indent() + s("local "sv) + accumVar + s(" = { }"sv) + nll(whileNode)); 4230 temp.push_back(indent() + s("local "sv) + accumVar + s(" = { }"sv) + nll(whileNode));
4202 temp.push_back(indent() + s("local "sv) + lenVar + s(" = 1"sv) + nll(whileNode)); 4231 temp.push_back(indent() + s("local "sv) + lenVar + s(" = 1"sv) + nll(whileNode));
4203 transformExp(whileNode->condition, temp); 4232 transformExp(whileNode->condition, temp, ExpUsage::Closure);
4204 temp.back() = indent() + s("while "sv) + temp.back() + s(" do"sv) + nll(whileNode); 4233 temp.back() = indent() + s("while "sv) + temp.back() + s(" do"sv) + nll(whileNode);
4205 pushScope(); 4234 pushScope();
4206 auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), ExpList, x); 4235 auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), ExpList, x);
@@ -4237,7 +4266,7 @@ private:
4237 addToScope(lenVar); 4266 addToScope(lenVar);
4238 temp.push_back(indent() + s("local "sv) + accumVar + s(" = { }"sv) + nll(whileNode)); 4267 temp.push_back(indent() + s("local "sv) + accumVar + s(" = { }"sv) + nll(whileNode));
4239 temp.push_back(indent() + s("local "sv) + lenVar + s(" = 1"sv) + nll(whileNode)); 4268 temp.push_back(indent() + s("local "sv) + lenVar + s(" = 1"sv) + nll(whileNode));
4240 transformExp(whileNode->condition, temp); 4269 transformExp(whileNode->condition, temp, ExpUsage::Closure);
4241 temp.back() = indent() + s("while "sv) + temp.back() + s(" do"sv) + nll(whileNode); 4270 temp.back() = indent() + s("while "sv) + temp.back() + s(" do"sv) + nll(whileNode);
4242 pushScope(); 4271 pushScope();
4243 auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), ExpList, x); 4272 auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), ExpList, x);
@@ -4255,7 +4284,7 @@ private:
4255 void transformWhile(While_t* whileNode, str_list& out) { 4284 void transformWhile(While_t* whileNode, str_list& out) {
4256 str_list temp; 4285 str_list temp;
4257 pushScope(); 4286 pushScope();
4258 transformExp(whileNode->condition, temp); 4287 transformExp(whileNode->condition, temp, ExpUsage::Closure);
4259 transformLoopBody(whileNode->body, temp, Empty); 4288 transformLoopBody(whileNode->body, temp, Empty);
4260 popScope(); 4289 popScope();
4261 _buf << indent() << "while "sv << temp.front() << " do"sv << nll(whileNode); 4290 _buf << indent() << "while "sv << temp.front() << " do"sv << nll(whileNode);
@@ -4280,7 +4309,7 @@ private:
4280 if (objVar.empty()) { 4309 if (objVar.empty()) {
4281 objVar = getUnusedName("_exp_"sv); 4310 objVar = getUnusedName("_exp_"sv);
4282 addToScope(objVar); 4311 addToScope(objVar);
4283 transformExp(switchNode->target, temp); 4312 transformExp(switchNode->target, temp, ExpUsage::Closure);
4284 _buf << indent() << "local "sv << objVar << " = "sv << temp.back() << nll(switchNode); 4313 _buf << indent() << "local "sv << objVar << " = "sv << temp.back() << nll(switchNode);
4285 temp.back() = clearBuf(); 4314 temp.back() = clearBuf();
4286 } 4315 }
@@ -4292,7 +4321,7 @@ private:
4292 const auto& exprs = branch->valueList->exprs.objects(); 4321 const auto& exprs = branch->valueList->exprs.objects();
4293 for (auto exp_ : exprs) { 4322 for (auto exp_ : exprs) {
4294 auto exp = static_cast<Exp_t*>(exp_); 4323 auto exp = static_cast<Exp_t*>(exp_);
4295 transformExp(exp, tmp); 4324 transformExp(exp, tmp, ExpUsage::Closure);
4296 if (!singleValueFrom(exp)) { 4325 if (!singleValueFrom(exp)) {
4297 tmp.back() = s("("sv) + tmp.back() + s(")"sv); 4326 tmp.back() = s("("sv) + tmp.back() + s(")"sv);
4298 } 4327 }