diff options
Diffstat (limited to '')
| -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 | } |
