diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 157 |
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 | } |