diff options
Diffstat (limited to 'MoonParser')
-rw-r--r-- | MoonParser/ast.hpp | 16 | ||||
-rw-r--r-- | MoonParser/moon_ast.cpp | 491 | ||||
-rw-r--r-- | MoonParser/moon_ast.h | 42 | ||||
-rw-r--r-- | MoonParser/moon_parser.cpp | 47 | ||||
-rw-r--r-- | MoonParser/moon_parser.h | 4 |
5 files changed, 273 insertions, 327 deletions
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp index 480f9b3..8d28177 100644 --- a/MoonParser/ast.hpp +++ b/MoonParser/ast.hpp | |||
@@ -388,6 +388,22 @@ public: | |||
388 | clear(); | 388 | clear(); |
389 | } | 389 | } |
390 | 390 | ||
391 | inline ast_node* back() const { | ||
392 | return m_objects.back(); | ||
393 | } | ||
394 | |||
395 | inline ast_node* front() const { | ||
396 | return m_objects.front(); | ||
397 | } | ||
398 | |||
399 | inline size_t size() const { | ||
400 | return m_objects.size(); | ||
401 | } | ||
402 | |||
403 | inline bool empty() const { | ||
404 | return m_objects.empty(); | ||
405 | } | ||
406 | |||
391 | void push_back(ast_node* node) { | 407 | void push_back(ast_node* node) { |
392 | assert(node && accept(node)); | 408 | assert(node && accept(node)); |
393 | m_objects.push_back(node); | 409 | m_objects.push_back(node); |
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp index 61b997b..52fbd68 100644 --- a/MoonParser/moon_ast.cpp +++ b/MoonParser/moon_ast.cpp | |||
@@ -65,14 +65,17 @@ AST_IMPL(update_op) | |||
65 | AST_IMPL(Update) | 65 | AST_IMPL(Update) |
66 | AST_IMPL(BinaryOperator) | 66 | AST_IMPL(BinaryOperator) |
67 | AST_IMPL(Assignable) | 67 | AST_IMPL(Assignable) |
68 | AST_IMPL(AssignableChain) | ||
68 | AST_IMPL(exp_op_value) | 69 | AST_IMPL(exp_op_value) |
69 | AST_IMPL(Exp) | 70 | AST_IMPL(Exp) |
70 | AST_IMPL(Callable) | 71 | AST_IMPL(Callable) |
71 | AST_IMPL(ChainValue) | 72 | AST_IMPL(ChainValue) |
72 | AST_IMPL(simple_table) | 73 | AST_IMPL(simple_table) |
73 | AST_IMPL(SimpleValue) | 74 | AST_IMPL(SimpleValue) |
74 | AST_IMPL(Chain) | ||
75 | AST_IMPL(Value) | 75 | AST_IMPL(Value) |
76 | AST_IMPL(LuaStringOpen); | ||
77 | AST_IMPL(LuaStringContent); | ||
78 | AST_IMPL(LuaStringClose); | ||
76 | AST_IMPL(LuaString) | 79 | AST_IMPL(LuaString) |
77 | AST_IMPL(SingleString) | 80 | AST_IMPL(SingleString) |
78 | AST_IMPL(double_string_inner) | 81 | AST_IMPL(double_string_inner) |
@@ -114,7 +117,7 @@ AST_IMPL(BreakLoop) | |||
114 | AST_IMPL(Statement) | 117 | AST_IMPL(Statement) |
115 | AST_IMPL(Body) | 118 | AST_IMPL(Body) |
116 | AST_IMPL(Block) | 119 | AST_IMPL(Block) |
117 | AST_IMPL(BlockEnd) | 120 | AST_IMPL(File) |
118 | 121 | ||
119 | #include <iostream> | 122 | #include <iostream> |
120 | 123 | ||
@@ -129,7 +132,7 @@ public: | |||
129 | input input = _converter.from_bytes(codes); | 132 | input input = _converter.from_bytes(codes); |
130 | error_list el; | 133 | error_list el; |
131 | State st; | 134 | State st; |
132 | auto root = parse<BlockEnd_t>(input, BlockEnd, el, &st); | 135 | auto root = parse<File_t>(input, File, el, &st); |
133 | if (root) { | 136 | if (root) { |
134 | std::cout << "compiled!\n\n"; | 137 | std::cout << "compiled!\n\n"; |
135 | str_list out; | 138 | str_list out; |
@@ -460,20 +463,15 @@ private: | |||
460 | } | 463 | } |
461 | 464 | ||
462 | bool isChainValueCall(ChainValue_t* chainValue) { | 465 | bool isChainValueCall(ChainValue_t* chainValue) { |
463 | if (chainValue->arguments) return true; | 466 | return ast_is<InvokeArgs_t, Invoke_t>(chainValue->items.back()); |
464 | if (auto chain = chainValue->caller.as<Chain_t>()) { | ||
465 | ast_node* last = chain->items.objects().back(); | ||
466 | return last->getId() == "Invoke"_id; | ||
467 | } | ||
468 | return false; | ||
469 | } | 467 | } |
470 | 468 | ||
471 | std::string variableFrom(ast_node* expList) { | 469 | std::string variableFrom(ast_node* expList) { |
472 | if (!ast_is<Exp_t, ExpList_t>(expList)) return Empty; | 470 | if (!ast_is<Exp_t, ExpList_t>(expList)) return Empty; |
473 | if (auto value = singleValueFrom(expList)) { | 471 | if (auto value = singleValueFrom(expList)) { |
474 | if (auto chainValue = value->getByPath<ChainValue_t>()) { | 472 | if (auto chainValue = value->getByPath<ChainValue_t>()) { |
475 | if (!chainValue->arguments) { | 473 | if (chainValue->items.size() == 1) { |
476 | if (auto callable = chainValue->caller.as<Callable_t>()) { | 474 | if (auto callable = ast_cast<Callable_t>(chainValue->items.front())) { |
477 | return toString(callable->item); | 475 | return toString(callable->item); |
478 | } | 476 | } |
479 | } | 477 | } |
@@ -483,29 +481,7 @@ private: | |||
483 | } | 481 | } |
484 | 482 | ||
485 | bool isColonChain(ChainValue_t* chainValue) { | 483 | bool isColonChain(ChainValue_t* chainValue) { |
486 | if (chainValue->arguments) return false; | 484 | return ast_is<ColonChainItem_t>(chainValue->items.back()); |
487 | if (auto chain = chainValue->caller.as<Chain_t>()) { | ||
488 | return chain->items.objects().back()->getId() == "ColonChainItem"_id; | ||
489 | } | ||
490 | return false; | ||
491 | } | ||
492 | |||
493 | std::vector<ast_node*> getChainList(ChainValue_t* chainValue) { | ||
494 | std::vector<ast_node*> temp; | ||
495 | switch (chainValue->caller->getId()) { | ||
496 | case "Callable"_id: | ||
497 | temp.push_back(chainValue->caller); | ||
498 | break; | ||
499 | case "Chain"_id: | ||
500 | const auto& items = chainValue->caller.to<Chain_t>()->items.objects(); | ||
501 | temp.resize(items.size()); | ||
502 | std::copy(items.begin(), items.end(), temp.begin()); | ||
503 | break; | ||
504 | } | ||
505 | if (chainValue->arguments) { | ||
506 | temp.push_back(chainValue->arguments); | ||
507 | } | ||
508 | return temp; | ||
509 | } | 485 | } |
510 | 486 | ||
511 | void transformStatement(Statement_t* statement, str_list& out) { | 487 | void transformStatement(Statement_t* statement, str_list& out) { |
@@ -524,6 +500,12 @@ private: | |||
524 | ifCond->condition.set(if_else_line->condition); | 500 | ifCond->condition.set(if_else_line->condition); |
525 | ifNode->nodes.push_back(ifCond); | 501 | ifNode->nodes.push_back(ifCond); |
526 | 502 | ||
503 | auto stmt = new_ptr<Statement_t>(); | ||
504 | stmt->content.set(statement->content); | ||
505 | auto body = new_ptr<Body_t>(); | ||
506 | body->content.set(stmt); | ||
507 | ifNode->nodes.push_back(body); | ||
508 | |||
527 | if (!ast_is<default_value_t>(if_else_line->elseExpr)) { | 509 | if (!ast_is<default_value_t>(if_else_line->elseExpr)) { |
528 | auto exprList = new_ptr<ExpList_t>(); | 510 | auto exprList = new_ptr<ExpList_t>(); |
529 | exprList->exprs.push_back(if_else_line->elseExpr); | 511 | exprList->exprs.push_back(if_else_line->elseExpr); |
@@ -533,11 +515,6 @@ private: | |||
533 | body->content.set(stmt); | 515 | body->content.set(stmt); |
534 | ifNode->nodes.push_back(body); | 516 | ifNode->nodes.push_back(body); |
535 | } | 517 | } |
536 | auto stmt = new_ptr<Statement_t>(); | ||
537 | stmt->content.set(statement->content); | ||
538 | auto body = new_ptr<Body_t>(); | ||
539 | body->content.set(stmt); | ||
540 | ifNode->nodes.push_back(body); | ||
541 | 518 | ||
542 | statement->appendix.set(nullptr); | 519 | statement->appendix.set(nullptr); |
543 | auto simpleValue = new_ptr<SimpleValue_t>(); | 520 | auto simpleValue = new_ptr<SimpleValue_t>(); |
@@ -795,6 +772,14 @@ private: | |||
795 | if (auto simpleVal = exp->value->item.as<SimpleValue_t>()) { | 772 | if (auto simpleVal = exp->value->item.as<SimpleValue_t>()) { |
796 | auto valueItem = simpleVal->value.get(); | 773 | auto valueItem = simpleVal->value.get(); |
797 | switch (valueItem->getId()) { | 774 | switch (valueItem->getId()) { |
775 | case "With"_id: { | ||
776 | str_list temp; | ||
777 | auto expList = assignment->assignable.get(); | ||
778 | std::string preDefine = getPredefine(assignment); | ||
779 | transformWith(static_cast<With_t*>(valueItem), temp, expList); | ||
780 | out.push_back(preDefine + temp.front()); | ||
781 | return; | ||
782 | } | ||
798 | case "Do"_id: { | 783 | case "Do"_id: { |
799 | auto doNode = static_cast<Do_t*>(valueItem); | 784 | auto doNode = static_cast<Do_t*>(valueItem); |
800 | auto expList = assignment->assignable.get(); | 785 | auto expList = assignment->assignable.get(); |
@@ -856,7 +841,7 @@ private: | |||
856 | if (isColonChain(chainValue)) { | 841 | if (isColonChain(chainValue)) { |
857 | auto assignable = assignment->assignable.get(); | 842 | auto assignable = assignment->assignable.get(); |
858 | std::string preDefine = getPredefine(transformAssignDefs(assignable)); | 843 | std::string preDefine = getPredefine(transformAssignDefs(assignable)); |
859 | transformColonChain(chainValue, out, ExpUsage::Assignment, static_cast<ExpList_t*>(assignable)); | 844 | transformColonChain(chainValue, out, ExpUsage::Assignment, assignable); |
860 | auto nl = preDefine.empty() ? Empty : nll(chainValue); | 845 | auto nl = preDefine.empty() ? Empty : nll(chainValue); |
861 | if (!preDefine.empty()) out.back() = preDefine + nl + out.back(); | 846 | if (!preDefine.empty()) out.back() = preDefine + nl + out.back(); |
862 | return; | 847 | return; |
@@ -1082,10 +1067,44 @@ private: | |||
1082 | switch (action->getId()) { | 1067 | switch (action->getId()) { |
1083 | case "Update"_id: { | 1068 | case "Update"_id: { |
1084 | auto update = static_cast<Update_t*>(action); | 1069 | auto update = static_cast<Update_t*>(action); |
1085 | transformExpList(expList, temp); | 1070 | auto leftExp = static_cast<Exp_t*>(expList->exprs.objects().front()); |
1071 | auto leftValue = singleValueFrom(leftExp); | ||
1072 | if (!leftValue) throw std::logic_error("left hand expression is not assignable"); | ||
1073 | if (auto chain = leftValue->getByPath<ChainValue_t>()) { | ||
1074 | auto tmpChain = new_ptr<ChainValue_t>(); | ||
1075 | for (auto item : chain->items.objects()) { | ||
1076 | bool itemAdded = false; | ||
1077 | do { | ||
1078 | auto exp = ast_cast<Exp_t>(item); | ||
1079 | if (!exp) break; | ||
1080 | auto var = variableFrom(exp); | ||
1081 | if (!var.empty()) break; | ||
1082 | auto upVar = getUnusedName("_update_"); | ||
1083 | auto assignment = new_ptr<Assignment_t>(); | ||
1084 | assignment->assignable.set(toAst<ExpList_t>(upVar, ExpList)); | ||
1085 | auto assign = new_ptr<Assign_t>(); | ||
1086 | assign->values.push_back(exp); | ||
1087 | assignment->target.set(assign); | ||
1088 | transformAssignment(assignment, temp); | ||
1089 | tmpChain->items.push_back(toAst<Exp_t>(upVar, Exp)); | ||
1090 | itemAdded = true; | ||
1091 | } while (false); | ||
1092 | if (!itemAdded) tmpChain->items.push_back(item); | ||
1093 | } | ||
1094 | chain->items.clear(); | ||
1095 | chain->items.dup(tmpChain->items); | ||
1096 | } | ||
1097 | transformValue(leftValue, temp); | ||
1098 | auto left = std::move(temp.back()); | ||
1099 | temp.pop_back(); | ||
1086 | transformExp(update->value, temp); | 1100 | transformExp(update->value, temp); |
1087 | _buf << indent() << temp.front() << " = "sv << temp.front() << | 1101 | auto right = std::move(temp.back()); |
1088 | " "sv << toString(update->op) << " "sv << temp.back() << nll(assignment); | 1102 | temp.pop_back(); |
1103 | if (!singleValueFrom(update->value)) { | ||
1104 | right = s("("sv) + right + s(")"sv); | ||
1105 | } | ||
1106 | _buf << join(temp) << indent() << left << " = "sv << left << | ||
1107 | " "sv << toString(update->op) << " "sv << right << nll(assignment); | ||
1089 | out.push_back(clearBuf()); | 1108 | out.push_back(clearBuf()); |
1090 | break; | 1109 | break; |
1091 | } | 1110 | } |
@@ -1312,23 +1331,6 @@ private: | |||
1312 | } | 1331 | } |
1313 | } | 1332 | } |
1314 | 1333 | ||
1315 | void transformChainValue(ChainValue_t* chainValue, str_list& out) { | ||
1316 | str_list temp; | ||
1317 | auto caller = chainValue->caller.get(); | ||
1318 | bool hasArgs = chainValue->arguments; | ||
1319 | switch (caller->getId()) { | ||
1320 | case "Chain"_id: transformChain(static_cast<Chain_t*>(caller), temp); break; | ||
1321 | case "Callable"_id: transformCallable(static_cast<Callable_t*>(caller), temp, hasArgs); break; | ||
1322 | default: break; | ||
1323 | } | ||
1324 | if (hasArgs) { | ||
1325 | transformInvokeArgs(chainValue->arguments, temp); | ||
1326 | out.push_back(temp.front() + s("("sv) + temp.back() + s(")"sv)); | ||
1327 | } else { | ||
1328 | out.push_back(temp.front()); | ||
1329 | } | ||
1330 | } | ||
1331 | |||
1332 | void transformCallable(Callable_t* callable, str_list& out, bool invoke) { | 1334 | void transformCallable(Callable_t* callable, str_list& out, bool invoke) { |
1333 | auto item = callable->item.get(); | 1335 | auto item = callable->item.get(); |
1334 | switch (item->getId()) { | 1336 | switch (item->getId()) { |
@@ -1524,36 +1526,42 @@ private: | |||
1524 | void transformReturn(Return_t* returnNode, str_list& out) { | 1526 | void transformReturn(Return_t* returnNode, str_list& out) { |
1525 | if (auto valueList = returnNode->valueList.get()) { | 1527 | if (auto valueList = returnNode->valueList.get()) { |
1526 | if (auto singleValue = singleValueFrom(valueList)) { | 1528 | if (auto singleValue = singleValueFrom(valueList)) { |
1527 | if (auto comp = singleValue->getByPath<SimpleValue_t, Comprehension_t>()) { | 1529 | if (auto simpleValue = singleValue->item.as<SimpleValue_t>()) { |
1528 | transformCompReturn(comp, out); | 1530 | if (auto comp = simpleValue->value.as<Comprehension_t>()) { |
1529 | return; | 1531 | transformCompReturn(comp, out); |
1530 | } | 1532 | return; |
1531 | if (auto comp = singleValue->getByPath<SimpleValue_t, TblComprehension_t>()) { | 1533 | } |
1532 | transformTblCompReturn(comp, out); | 1534 | if (auto comp = simpleValue->value.as<TblComprehension_t>()) { |
1533 | return; | 1535 | transformTblCompReturn(comp, out); |
1534 | } | 1536 | return; |
1535 | if (auto classDecl = singleValue->getByPath<SimpleValue_t, ClassDecl_t>()) { | 1537 | } |
1536 | transformClassDecl(classDecl, out, ExpUsage::Return); | 1538 | if (auto classDecl = simpleValue->value.as<ClassDecl_t>()) { |
1537 | return; | 1539 | transformClassDecl(classDecl, out, ExpUsage::Return); |
1538 | } | 1540 | return; |
1539 | if (auto doNode = singleValue->getByPath<SimpleValue_t, Do_t>()) { | 1541 | } |
1540 | transformDo(doNode, out, true); | 1542 | if (auto doNode = simpleValue->value.as<Do_t>()) { |
1541 | return; | 1543 | transformDo(doNode, out, true); |
1542 | } | 1544 | return; |
1543 | if (auto switchNode = singleValue->getByPath<SimpleValue_t, Switch_t>()) { | 1545 | } |
1544 | transformSwitch(switchNode, out, true); | 1546 | if (auto switchNode = simpleValue->value.as<Switch_t>()) { |
1545 | return; | 1547 | transformSwitch(switchNode, out, true); |
1548 | return; | ||
1549 | } | ||
1550 | if (auto ifNode = simpleValue->value.as<If_t>()) { | ||
1551 | transformIf(ifNode, out, IfUsage::Return); | ||
1552 | return; | ||
1553 | } | ||
1554 | if (auto unlessNode = simpleValue->value.as<Unless_t>()) { | ||
1555 | transformUnless(unlessNode, out, IfUsage::Return); | ||
1556 | return; | ||
1557 | } | ||
1546 | } | 1558 | } |
1547 | if (auto chainValue = singleValue->getByPath<ChainValue_t>()) { | 1559 | if (auto chainValue = singleValue->item.as<ChainValue_t>()) { |
1548 | if (isColonChain(chainValue)) { | 1560 | if (isColonChain(chainValue)) { |
1549 | transformColonChain(chainValue, out, ExpUsage::Return); | 1561 | transformColonChain(chainValue, out, ExpUsage::Return); |
1550 | return; | 1562 | return; |
1551 | } | 1563 | } |
1552 | } | 1564 | } |
1553 | if (auto ifNode = singleValue->getByPath<SimpleValue_t, If_t>()) { | ||
1554 | transformIf(ifNode, out, IfUsage::Return); | ||
1555 | return; | ||
1556 | } | ||
1557 | transformValue(singleValue, out); | 1565 | transformValue(singleValue, out); |
1558 | out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode); | 1566 | out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode); |
1559 | return; | 1567 | return; |
@@ -1699,8 +1707,7 @@ private: | |||
1699 | 1707 | ||
1700 | void transformColonChain(ChainValue_t* chainValue, str_list& out, ExpUsage usage = ExpUsage::Common, ExpList_t* expList = nullptr) { | 1708 | void transformColonChain(ChainValue_t* chainValue, str_list& out, ExpUsage usage = ExpUsage::Common, ExpList_t* expList = nullptr) { |
1701 | str_list temp; | 1709 | str_list temp; |
1702 | auto chain = chainValue->caller.to<Chain_t>(); | 1710 | const auto& chainList = chainValue->items.objects(); |
1703 | const auto& chainList = chain->items.objects(); | ||
1704 | auto end = --chainList.end(); | 1711 | auto end = --chainList.end(); |
1705 | for (auto it = chainList.begin(); it != end; ++it) { | 1712 | for (auto it = chainList.begin(); it != end; ++it) { |
1706 | auto item = *it; | 1713 | auto item = *it; |
@@ -1713,7 +1720,7 @@ private: | |||
1713 | auto next = it; ++next; | 1720 | auto next = it; ++next; |
1714 | auto followItem = next != chainList.end() ? *next : nullptr; | 1721 | auto followItem = next != chainList.end() ? *next : nullptr; |
1715 | transformCallable(static_cast<Callable_t*>(item), temp, | 1722 | transformCallable(static_cast<Callable_t*>(item), temp, |
1716 | followItem && followItem->getId() == "Invoke"_id); | 1723 | followItem && ast_is<Invoke_t, InvokeArgs_t>(followItem)); |
1717 | break; | 1724 | break; |
1718 | } | 1725 | } |
1719 | case "String"_id: | 1726 | case "String"_id: |
@@ -1742,34 +1749,33 @@ private: | |||
1742 | auto fnVar = getUnusedName("_fn_"sv); | 1749 | auto fnVar = getUnusedName("_fn_"sv); |
1743 | addToScope(fnVar); | 1750 | addToScope(fnVar); |
1744 | if (usage != ExpUsage::Return) { | 1751 | if (usage != ExpUsage::Return) { |
1745 | _buf << indent(-1) << "do"sv << nll(chain); | 1752 | _buf << indent(-1) << "do"sv << nll(chainValue); |
1746 | } | 1753 | } |
1747 | _buf << indent() << "local "sv << baseVar << " = "sv << caller << nll(chain); | 1754 | _buf << indent() << "local "sv << baseVar << " = "sv << caller << nll(chainValue); |
1748 | _buf << indent() << "local "sv << fnVar << " = "sv << baseVar << "."sv << funcName << nll(chain); | 1755 | _buf << indent() << "local "sv << fnVar << " = "sv << baseVar << "."sv << funcName << nll(chainValue); |
1749 | switch (usage) { | 1756 | switch (usage) { |
1750 | case ExpUsage::Return: | 1757 | case ExpUsage::Return: |
1751 | _buf << indent() << "return function(...)" << nll(chain); | 1758 | _buf << indent() << "return function(...)" << nll(chainValue); |
1752 | break; | 1759 | break; |
1753 | case ExpUsage::Assignment: | 1760 | case ExpUsage::Assignment: |
1754 | _buf << indent() << assignList << " = function(...)"sv << nll(chain); | 1761 | _buf << indent() << assignList << " = function(...)"sv << nll(chainValue); |
1755 | break; | 1762 | break; |
1756 | case ExpUsage::Common: | 1763 | case ExpUsage::Common: |
1757 | _buf << indent() << "_ = function(...)" << nll(chain); | 1764 | _buf << indent() << "_ = function(...)" << nll(chainValue); |
1758 | break; | 1765 | break; |
1759 | default: break; | 1766 | default: break; |
1760 | } | 1767 | } |
1761 | _buf << indent(1) << "return "sv << fnVar << "("sv << baseVar << ", ...)"sv << nll(chain); | 1768 | _buf << indent(1) << "return "sv << fnVar << "("sv << baseVar << ", ...)"sv << nll(chainValue); |
1762 | _buf << indent() << "end"sv << nll(chain); | 1769 | _buf << indent() << "end"sv << nll(chainValue); |
1763 | if (usage != ExpUsage::Return) { | 1770 | if (usage != ExpUsage::Return) { |
1764 | popScope(); | 1771 | popScope(); |
1765 | _buf << indent() << "end"sv << nll(chain); | 1772 | _buf << indent() << "end"sv << nll(chainValue); |
1766 | } | 1773 | } |
1767 | out.push_back(clearBuf()); | 1774 | out.push_back(clearBuf()); |
1768 | } | 1775 | } |
1769 | 1776 | ||
1770 | void transformChain(Chain_t* chain, str_list& out) { | 1777 | void transformChainList(const std::list<ast_node*>& chainList, str_list& out) { |
1771 | str_list temp; | 1778 | str_list temp; |
1772 | const auto& chainList = chain->items.objects(); | ||
1773 | switch (chainList.front()->getId()) { | 1779 | switch (chainList.front()->getId()) { |
1774 | case "DotChainItem"_id: | 1780 | case "DotChainItem"_id: |
1775 | case "ColonChainItem"_id: | 1781 | case "ColonChainItem"_id: |
@@ -1783,15 +1789,23 @@ private: | |||
1783 | for (auto it = chainList.begin(); it != chainList.end(); ++it) { | 1789 | for (auto it = chainList.begin(); it != chainList.end(); ++it) { |
1784 | auto item = *it; | 1790 | auto item = *it; |
1785 | switch (item->getId()) { | 1791 | switch (item->getId()) { |
1786 | case "Invoke"_id: transformInvoke(static_cast<Invoke_t*>(item), temp); break; | 1792 | case "Invoke"_id: |
1787 | case "DotChainItem"_id: transformDotChainItem(static_cast<DotChainItem_t*>(item), temp); break; | 1793 | transformInvoke(static_cast<Invoke_t*>(item), temp); |
1788 | case "ColonChainItem"_id: transformColonChainItem(static_cast<ColonChainItem_t*>(item), temp); break; | 1794 | break; |
1789 | case "Slice"_id: transformSlice(static_cast<Slice_t*>(item), temp); break; | 1795 | case "DotChainItem"_id: |
1796 | transformDotChainItem(static_cast<DotChainItem_t*>(item), temp); | ||
1797 | break; | ||
1798 | case "ColonChainItem"_id: | ||
1799 | transformColonChainItem(static_cast<ColonChainItem_t*>(item), temp); | ||
1800 | break; | ||
1801 | case "Slice"_id: | ||
1802 | transformSlice(static_cast<Slice_t*>(item), temp); | ||
1803 | break; | ||
1790 | case "Callable"_id: { | 1804 | case "Callable"_id: { |
1791 | auto next = it; ++next; | 1805 | auto next = it; ++next; |
1792 | auto followItem = next != chainList.end() ? *next : nullptr; | 1806 | auto followItem = next != chainList.end() ? *next : nullptr; |
1793 | transformCallable(static_cast<Callable_t*>(item), temp, | 1807 | transformCallable(static_cast<Callable_t*>(item), temp, |
1794 | followItem && followItem->getId() == "Invoke"_id); | 1808 | followItem && ast_is<Invoke_t, InvokeArgs_t>(followItem)); |
1795 | break; | 1809 | break; |
1796 | } | 1810 | } |
1797 | case "String"_id: | 1811 | case "String"_id: |
@@ -1802,14 +1816,28 @@ private: | |||
1802 | transformExp(static_cast<Exp_t*>(item), temp); | 1816 | transformExp(static_cast<Exp_t*>(item), temp); |
1803 | temp.back() = s("["sv) + temp.back() + s("]"sv); | 1817 | temp.back() = s("["sv) + temp.back() + s("]"sv); |
1804 | break; | 1818 | break; |
1819 | case "InvokeArgs"_id: transformInvokeArgs(static_cast<InvokeArgs_t*>(item), temp); break; | ||
1805 | default: break; | 1820 | default: break; |
1806 | } | 1821 | } |
1807 | } | 1822 | } |
1808 | out.push_back(join(temp)); | 1823 | out.push_back(join(temp)); |
1809 | } | 1824 | } |
1810 | 1825 | ||
1826 | void transformChainValue(ChainValue_t* chainValue, str_list& out) { | ||
1827 | transformChainList(chainValue->items.objects(), out); | ||
1828 | } | ||
1829 | |||
1830 | void transformAssignableChain(AssignableChain_t* chain, str_list& out) { | ||
1831 | transformChainList(chain->items.objects(), out); | ||
1832 | } | ||
1833 | |||
1811 | void transformDotChainItem(DotChainItem_t* dotChainItem, str_list& out) { | 1834 | void transformDotChainItem(DotChainItem_t* dotChainItem, str_list& out) { |
1812 | out.push_back(s("."sv) + toString(dotChainItem->name)); | 1835 | auto name = toString(dotChainItem->name); |
1836 | if (State::keywords.find(name) != State::keywords.end()) { | ||
1837 | out.push_back(s("[\""sv) + name + s("\"]"sv)); | ||
1838 | } else { | ||
1839 | out.push_back(s("."sv) + name); | ||
1840 | } | ||
1813 | } | 1841 | } |
1814 | 1842 | ||
1815 | void transformColonChainItem(ColonChainItem_t* colonChainItem, str_list& out) { | 1843 | void transformColonChainItem(ColonChainItem_t* colonChainItem, str_list& out) { |
@@ -1836,7 +1864,7 @@ private: | |||
1836 | 1864 | ||
1837 | void transform_unary_exp(unary_exp_t* unary_exp, str_list& out) { | 1865 | void transform_unary_exp(unary_exp_t* unary_exp, str_list& out) { |
1838 | std::string op = toString(unary_exp->m_begin.m_it, unary_exp->item->m_begin.m_it); | 1866 | std::string op = toString(unary_exp->m_begin.m_it, unary_exp->item->m_begin.m_it); |
1839 | str_list temp{op + (op == "not"sv ? op + " " : Empty)}; | 1867 | str_list temp{op + (op == "not"sv ? s(" "sv) : Empty)}; |
1840 | transformExp(unary_exp->item, temp); | 1868 | transformExp(unary_exp->item, temp); |
1841 | out.push_back(join(temp)); | 1869 | out.push_back(join(temp)); |
1842 | } | 1870 | } |
@@ -1994,7 +2022,7 @@ private: | |||
1994 | do { | 2022 | do { |
1995 | auto chainValue = value->item.as<ChainValue_t>(); | 2023 | auto chainValue = value->item.as<ChainValue_t>(); |
1996 | if (!chainValue) break; | 2024 | if (!chainValue) break; |
1997 | auto chainList = getChainList(chainValue); | 2025 | auto chainList = chainValue->items.objects(); |
1998 | auto slice = ast_cast<Slice_t>(chainList.back()); | 2026 | auto slice = ast_cast<Slice_t>(chainList.back()); |
1999 | if (!slice) break; | 2027 | if (!slice) break; |
2000 | endWithSlice = true; | 2028 | endWithSlice = true; |
@@ -2003,7 +2031,7 @@ private: | |||
2003 | listVar = toString(ast_to<Callable_t>(chainList.front())->item); | 2031 | listVar = toString(ast_to<Callable_t>(chainList.front())->item); |
2004 | } | 2032 | } |
2005 | chainList.pop_back(); | 2033 | chainList.pop_back(); |
2006 | auto chain = new_ptr<Chain_t>(); | 2034 | auto chain = new_ptr<ChainValue_t>(); |
2007 | for (auto item : chainList) { | 2035 | for (auto item : chainList) { |
2008 | chain->items.push_back(item); | 2036 | chain->items.push_back(item); |
2009 | } | 2037 | } |
@@ -2026,7 +2054,7 @@ private: | |||
2026 | temp.pop_back(); | 2054 | temp.pop_back(); |
2027 | } | 2055 | } |
2028 | if (newListVal) { | 2056 | if (newListVal) { |
2029 | transformChain(chain, temp); | 2057 | transformChainValue(chain, temp); |
2030 | _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); | 2058 | _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); |
2031 | } | 2059 | } |
2032 | std::string maxVar; | 2060 | std::string maxVar; |
@@ -2115,7 +2143,7 @@ private: | |||
2115 | default: break; | 2143 | default: break; |
2116 | } | 2144 | } |
2117 | } | 2145 | } |
2118 | out.push_back(join(temp, ", "sv)); | 2146 | out.push_back(s("("sv) + join(temp, ", "sv) + s(")"sv)); |
2119 | } | 2147 | } |
2120 | 2148 | ||
2121 | void transformForHead(For_t* forNode, str_list& out) { | 2149 | void transformForHead(For_t* forNode, str_list& out) { |
@@ -2359,7 +2387,13 @@ private: | |||
2359 | auto key = pair->key.get(); | 2387 | auto key = pair->key.get(); |
2360 | str_list temp; | 2388 | str_list temp; |
2361 | switch (key->getId()) { | 2389 | switch (key->getId()) { |
2362 | case "KeyName"_id: transformKeyName(static_cast<KeyName_t*>(key), temp); break; | 2390 | case "KeyName"_id: { |
2391 | transformKeyName(static_cast<KeyName_t*>(key), temp); | ||
2392 | if (State::luaKeywords.find(temp.back()) != State::luaKeywords.end()) { | ||
2393 | temp.back() = s("[\""sv) + temp.back() + s("\"]"); | ||
2394 | } | ||
2395 | break; | ||
2396 | } | ||
2363 | case "Exp"_id: | 2397 | case "Exp"_id: |
2364 | transformExp(static_cast<Exp_t*>(key), temp); | 2398 | transformExp(static_cast<Exp_t*>(key), temp); |
2365 | temp.back() = s("["sv) + temp.back() + s("]"sv); | 2399 | temp.back() = s("["sv) + temp.back() + s("]"sv); |
@@ -2391,10 +2425,6 @@ private: | |||
2391 | } | 2425 | } |
2392 | } | 2426 | } |
2393 | 2427 | ||
2394 | void transformLuaString(LuaString_t* luaString, str_list& out) { | ||
2395 | out.push_back(toString(luaString)); | ||
2396 | } | ||
2397 | |||
2398 | void replace(std::string& str, std::string_view from, std::string_view to) { | 2428 | void replace(std::string& str, std::string_view from, std::string_view to) { |
2399 | size_t start_pos = 0; | 2429 | size_t start_pos = 0; |
2400 | while((start_pos = str.find(from, start_pos)) != std::string::npos) { | 2430 | while((start_pos = str.find(from, start_pos)) != std::string::npos) { |
@@ -2403,6 +2433,13 @@ private: | |||
2403 | } | 2433 | } |
2404 | } | 2434 | } |
2405 | 2435 | ||
2436 | void transformLuaString(LuaString_t* luaString, str_list& out) { | ||
2437 | auto content = toString(luaString->content); | ||
2438 | replace(content, "\r"sv, ""); | ||
2439 | if (content[0] == '\n') content.erase(content.begin()); | ||
2440 | out.push_back(toString(luaString->open) + content + toString(luaString->close)); | ||
2441 | } | ||
2442 | |||
2406 | void transformSingleString(SingleString_t* singleString, str_list& out) { | 2443 | void transformSingleString(SingleString_t* singleString, str_list& out) { |
2407 | auto str = toString(singleString); | 2444 | auto str = toString(singleString); |
2408 | replace(str, "\r"sv, ""); | 2445 | replace(str, "\r"sv, ""); |
@@ -2430,7 +2467,7 @@ private: | |||
2430 | default: break; | 2467 | default: break; |
2431 | } | 2468 | } |
2432 | } | 2469 | } |
2433 | out.push_back(join(temp, " .. "sv)); | 2470 | out.push_back(temp.empty() ? s("\"\""sv) : join(temp, " .. "sv)); |
2434 | } | 2471 | } |
2435 | 2472 | ||
2436 | void transformString(String_t* string, str_list& out) { | 2473 | void transformString(String_t* string, str_list& out) { |
@@ -2480,10 +2517,10 @@ private: | |||
2480 | temp.push_back(indent() + s("local "sv) + className + nll(classDecl)); | 2517 | temp.push_back(indent() + s("local "sv) + className + nll(classDecl)); |
2481 | } | 2518 | } |
2482 | if (className.empty()) { | 2519 | if (className.empty()) { |
2483 | if (auto chain = ast_cast<Chain_t>(assignable->item)) { | 2520 | if (auto chain = ast_cast<AssignableChain_t>(assignable->item)) { |
2484 | if (auto dotChain = ast_cast<DotChainItem_t>(chain->items.objects().back())) { | 2521 | if (auto dotChain = ast_cast<DotChainItem_t>(chain->items.back())) { |
2485 | className = s("\""sv) + toString(dotChain->name) + s("\""sv); | 2522 | className = s("\""sv) + toString(dotChain->name) + s("\""sv); |
2486 | } else if (auto index = ast_cast<Exp_t>(chain->items.objects().back())) { | 2523 | } else if (auto index = ast_cast<Exp_t>(chain->items.back())) { |
2487 | if (auto name = index->getByPath<Value_t, String_t>()) { | 2524 | if (auto name = index->getByPath<Value_t, String_t>()) { |
2488 | transformString(name, temp); | 2525 | transformString(name, temp); |
2489 | className = temp.back(); | 2526 | className = temp.back(); |
@@ -2730,20 +2767,8 @@ private: | |||
2730 | normal_pair->value->traverse([&](ast_node* node) { | 2767 | normal_pair->value->traverse([&](ast_node* node) { |
2731 | if (node->getId() == "ClassDecl"_id) return traversal::Return; | 2768 | if (node->getId() == "ClassDecl"_id) return traversal::Return; |
2732 | if (auto chainValue = ast_cast<ChainValue_t>(node)) { | 2769 | if (auto chainValue = ast_cast<ChainValue_t>(node)) { |
2733 | if (auto var = chainValue->caller->getByPath<Variable_t>()) { | 2770 | if (auto callable = ast_cast<Callable_t>(chainValue->items.front())) { |
2734 | if (toString(var) == "super"sv) { | 2771 | auto var = callable->item.get(); |
2735 | if (chainValue->arguments) { | ||
2736 | chainValue->arguments->args.push_front(toAst<Exp_t>("self"sv, Exp)); | ||
2737 | _codeCache.push_back(newSuperCall); | ||
2738 | var->m_begin.m_it = _codeCache.back().begin(); | ||
2739 | var->m_end.m_it = _codeCache.back().end(); | ||
2740 | } else { | ||
2741 | _codeCache.push_back(_converter.from_bytes(classVar) + L".__parent"); | ||
2742 | var->m_begin.m_it = _codeCache.back().begin(); | ||
2743 | var->m_end.m_it = _codeCache.back().end(); | ||
2744 | } | ||
2745 | } | ||
2746 | } else if (auto var = chainValue->caller->getByPath<Callable_t, Variable_t>()) { | ||
2747 | if (toString(var) == "super"sv) { | 2772 | if (toString(var) == "super"sv) { |
2748 | auto insertSelfToArguments = [&](ast_node* item) { | 2773 | auto insertSelfToArguments = [&](ast_node* item) { |
2749 | switch (item->getId()) { | 2774 | switch (item->getId()) { |
@@ -2761,13 +2786,15 @@ private: | |||
2761 | return false; | 2786 | return false; |
2762 | } | 2787 | } |
2763 | }; | 2788 | }; |
2764 | auto chainList = getChainList(chainValue); | 2789 | const auto& chainList = chainValue->items.objects(); |
2765 | if (chainList.size() >= 2) { | 2790 | if (chainList.size() >= 2) { |
2766 | if (insertSelfToArguments(chainList[1])) { | 2791 | auto it = chainList.begin(); |
2792 | auto secondItem = *(++it); | ||
2793 | if (insertSelfToArguments(secondItem)) { | ||
2767 | _codeCache.push_back(newSuperCall); | 2794 | _codeCache.push_back(newSuperCall); |
2768 | } else { | 2795 | } else { |
2769 | if (auto colonChainItem = ast_cast<ColonChainItem_t>(chainList[1])) { | 2796 | if (auto colonChainItem = ast_cast<ColonChainItem_t>(secondItem)) { |
2770 | if (chainList.size() > 2 && insertSelfToArguments(chainList[2])) { | 2797 | if (chainList.size() > 2 && insertSelfToArguments(*(++it))) { |
2771 | colonChainItem->switchToDot = true; | 2798 | colonChainItem->switchToDot = true; |
2772 | } | 2799 | } |
2773 | } | 2800 | } |
@@ -2812,14 +2839,14 @@ private: | |||
2812 | void transformAssignable(Assignable_t* assignable, str_list& out) { | 2839 | void transformAssignable(Assignable_t* assignable, str_list& out) { |
2813 | auto item = assignable->item.get(); | 2840 | auto item = assignable->item.get(); |
2814 | switch (item->getId()) { | 2841 | switch (item->getId()) { |
2815 | case "Chain"_id: transformChain(static_cast<Chain_t*>(item), out); break; | 2842 | case "AssignableChain"_id: transformAssignableChain(static_cast<AssignableChain_t*>(item), out); break; |
2816 | case "Variable"_id: transformVariable(static_cast<Variable_t*>(item), out); break; | 2843 | case "Variable"_id: transformVariable(static_cast<Variable_t*>(item), out); break; |
2817 | case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(item), out, false); break; | 2844 | case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(item), out, false); break; |
2818 | default: break; | 2845 | default: break; |
2819 | } | 2846 | } |
2820 | } | 2847 | } |
2821 | 2848 | ||
2822 | void transformWith(With_t* with, str_list& out) { | 2849 | void transformWith(With_t* with, str_list& out, ExpList_t* assignList = nullptr) { |
2823 | str_list temp; | 2850 | str_list temp; |
2824 | std::string withVar; | 2851 | std::string withVar; |
2825 | bool scoped = false; | 2852 | bool scoped = false; |
@@ -2869,16 +2896,19 @@ private: | |||
2869 | transformAssignment(assignment, temp); | 2896 | transformAssignment(assignment, temp); |
2870 | } | 2897 | } |
2871 | } else { | 2898 | } else { |
2872 | withVar = getUnusedName("_with_"); | 2899 | withVar = variableFrom(with->valueList); |
2873 | auto assignment = new_ptr<Assignment_t>(); | 2900 | if (withVar.empty()) { |
2874 | assignment->assignable.set(toAst<ExpList_t>(withVar, ExpList)); | 2901 | withVar = getUnusedName("_with_"); |
2875 | auto assign = new_ptr<Assign_t>(); | 2902 | auto assignment = new_ptr<Assignment_t>(); |
2876 | assign->values.dup(with->valueList->exprs); | 2903 | assignment->assignable.set(toAst<ExpList_t>(withVar, ExpList)); |
2877 | assignment->target.set(assign); | 2904 | auto assign = new_ptr<Assign_t>(); |
2878 | scoped = true; | 2905 | assign->values.dup(with->valueList->exprs); |
2879 | temp.push_back(indent() + s("do"sv) + nll(with)); | 2906 | assignment->target.set(assign); |
2880 | pushScope(); | 2907 | scoped = true; |
2881 | transformAssignment(assignment, temp); | 2908 | temp.push_back(indent() + s("do"sv) + nll(with)); |
2909 | pushScope(); | ||
2910 | transformAssignment(assignment, temp); | ||
2911 | } | ||
2882 | } | 2912 | } |
2883 | auto exp = with->valueList->exprs.objects().front(); | 2913 | auto exp = with->valueList->exprs.objects().front(); |
2884 | if (exp->getByPath<Value_t, SimpleValue_t, TableLit_t>()) { | 2914 | if (exp->getByPath<Value_t, SimpleValue_t, TableLit_t>()) { |
@@ -2888,6 +2918,14 @@ private: | |||
2888 | _withVars.push(withVar); | 2918 | _withVars.push(withVar); |
2889 | transformBody(with->body, temp); | 2919 | transformBody(with->body, temp); |
2890 | _withVars.pop(); | 2920 | _withVars.pop(); |
2921 | if (assignList) { | ||
2922 | auto assignment = new_ptr<Assignment_t>(); | ||
2923 | assignment->assignable.set(assignList); | ||
2924 | auto assign = new_ptr<Assign_t>(); | ||
2925 | assign->values.push_back(toAst<Exp_t>(withVar, Exp)); | ||
2926 | assignment->target.set(assign); | ||
2927 | transformAssignment(assignment, temp); | ||
2928 | } | ||
2891 | if (scoped) { | 2929 | if (scoped) { |
2892 | popScope(); | 2930 | popScope(); |
2893 | temp.push_back(indent() + s("end"sv) + nll(with)); | 2931 | temp.push_back(indent() + s("end"sv) + nll(with)); |
@@ -2928,7 +2966,7 @@ private: | |||
2928 | auto callable = new_ptr<Callable_t>(); | 2966 | auto callable = new_ptr<Callable_t>(); |
2929 | callable->item.set(name); | 2967 | callable->item.set(name); |
2930 | auto chainValue = new_ptr<ChainValue_t>(); | 2968 | auto chainValue = new_ptr<ChainValue_t>(); |
2931 | chainValue->caller.set(callable); | 2969 | chainValue->items.push_back(callable); |
2932 | auto value = new_ptr<Value_t>(); | 2970 | auto value = new_ptr<Value_t>(); |
2933 | value->item.set(chainValue); | 2971 | value->item.set(chainValue); |
2934 | auto exp = new_ptr<Exp_t>(); | 2972 | auto exp = new_ptr<Exp_t>(); |
@@ -3130,11 +3168,9 @@ private: | |||
3130 | auto callable = toAst<Callable_t>(objVar, Callable); | 3168 | auto callable = toAst<Callable_t>(objVar, Callable); |
3131 | auto dotChainItem = new_ptr<DotChainItem_t>(); | 3169 | auto dotChainItem = new_ptr<DotChainItem_t>(); |
3132 | dotChainItem->name.set(var->name); | 3170 | dotChainItem->name.set(var->name); |
3133 | auto chain = new_ptr<Chain_t>(); | ||
3134 | chain->items.push_back(callable); | ||
3135 | chain->items.push_back(dotChainItem); | ||
3136 | auto chainValue = new_ptr<ChainValue_t>(); | 3171 | auto chainValue = new_ptr<ChainValue_t>(); |
3137 | chainValue->caller.set(chain); | 3172 | chainValue->items.push_back(callable); |
3173 | chainValue->items.push_back(dotChainItem); | ||
3138 | auto value = new_ptr<Value_t>(); | 3174 | auto value = new_ptr<Value_t>(); |
3139 | value->item.set(chainValue); | 3175 | value->item.set(chainValue); |
3140 | auto exp = new_ptr<Exp_t>(); | 3176 | auto exp = new_ptr<Exp_t>(); |
@@ -3144,7 +3180,7 @@ private: | |||
3144 | auto callable = new_ptr<Callable_t>(); | 3180 | auto callable = new_ptr<Callable_t>(); |
3145 | callable->item.set(var); | 3181 | callable->item.set(var); |
3146 | auto chainValue = new_ptr<ChainValue_t>(); | 3182 | auto chainValue = new_ptr<ChainValue_t>(); |
3147 | chainValue->caller.set(callable); | 3183 | chainValue->items.push_back(callable); |
3148 | auto value = new_ptr<Value_t>(); | 3184 | auto value = new_ptr<Value_t>(); |
3149 | value->item.set(chainValue); | 3185 | value->item.set(chainValue); |
3150 | auto exp = new_ptr<Exp_t>(); | 3186 | auto exp = new_ptr<Exp_t>(); |
@@ -3159,11 +3195,9 @@ private: | |||
3159 | auto callable = toAst<Callable_t>(objVar, Callable); | 3195 | auto callable = toAst<Callable_t>(objVar, Callable); |
3160 | auto colonChain = new_ptr<ColonChainItem_t>(); | 3196 | auto colonChain = new_ptr<ColonChainItem_t>(); |
3161 | colonChain->name.set(nameNode); | 3197 | colonChain->name.set(nameNode); |
3162 | auto chain = new_ptr<Chain_t>(); | ||
3163 | chain->items.push_back(callable); | ||
3164 | chain->items.push_back(colonChain); | ||
3165 | auto chainValue = new_ptr<ChainValue_t>(); | 3198 | auto chainValue = new_ptr<ChainValue_t>(); |
3166 | chainValue->caller.set(chain); | 3199 | chainValue->items.push_back(callable); |
3200 | chainValue->items.push_back(colonChain); | ||
3167 | auto value = new_ptr<Value_t>(); | 3201 | auto value = new_ptr<Value_t>(); |
3168 | value->item.set(chainValue); | 3202 | value->item.set(chainValue); |
3169 | auto exp = new_ptr<Exp_t>(); | 3203 | auto exp = new_ptr<Exp_t>(); |
@@ -3173,7 +3207,7 @@ private: | |||
3173 | auto callable = new_ptr<Callable_t>(); | 3207 | auto callable = new_ptr<Callable_t>(); |
3174 | callable->item.set(var); | 3208 | callable->item.set(var); |
3175 | auto chainValue = new_ptr<ChainValue_t>(); | 3209 | auto chainValue = new_ptr<ChainValue_t>(); |
3176 | chainValue->caller.set(callable); | 3210 | chainValue->items.push_back(callable); |
3177 | auto value = new_ptr<Value_t>(); | 3211 | auto value = new_ptr<Value_t>(); |
3178 | value->item.set(chainValue); | 3212 | value->item.set(chainValue); |
3179 | auto exp = new_ptr<Exp_t>(); | 3213 | auto exp = new_ptr<Exp_t>(); |
@@ -3294,6 +3328,9 @@ private: | |||
3294 | for (auto exp_ : exprs) { | 3328 | for (auto exp_ : exprs) { |
3295 | auto exp = static_cast<Exp_t*>(exp_); | 3329 | auto exp = static_cast<Exp_t*>(exp_); |
3296 | transformExp(exp, tmp); | 3330 | transformExp(exp, tmp); |
3331 | if (!singleValueFrom(exp)) { | ||
3332 | tmp.back() = s("("sv) + tmp.back() + s(")"sv); | ||
3333 | } | ||
3297 | temp.back().append(s(" "sv) + tmp.back() + s(" == "sv) + objVar + | 3334 | temp.back().append(s(" "sv) + tmp.back() + s(" == "sv) + objVar + |
3298 | s(exp == exprs.back() ? ""sv : " or"sv)); | 3335 | s(exp == exprs.back() ? ""sv : " or"sv)); |
3299 | } | 3336 | } |
@@ -3350,138 +3387,12 @@ int main() | |||
3350 | { | 3387 | { |
3351 | std::string s = R"TestCodesHere( | 3388 | std::string s = R"TestCodesHere( |
3352 | 3389 | ||
3353 | for x=1,10 | ||
3354 | print "yeah" | ||
3355 | |||
3356 | for x=1,#something | ||
3357 | print "yeah" | ||
3358 | |||
3359 | for y=100,60,-3 | ||
3360 | print "count down", y | ||
3361 | |||
3362 | for a=1,10 do print "okay" | ||
3363 | |||
3364 | for a=1,10 | ||
3365 | for b = 2,43 | ||
3366 | print a,b | ||
3367 | |||
3368 | for i in iter | ||
3369 | for j in yeah | ||
3370 | x = 343 + i + j | ||
3371 | print i, j | ||
3372 | |||
3373 | for x in *something | ||
3374 | print x | ||
3375 | |||
3376 | for k,v in pairs hello do print k,v | ||
3377 | |||
3378 | for x in y, z | ||
3379 | print x | ||
3380 | |||
3381 | for x in y, z, k | ||
3382 | print x | ||
3383 | |||
3384 | |||
3385 | x = -> | ||
3386 | for x in y | ||
3387 | y | ||
3388 | |||
3389 | hello = {1,2,3,4,5} | ||
3390 | |||
3391 | x = for y in *hello | ||
3392 | if y % 2 == 0 | ||
3393 | y | ||
3394 | |||
3395 | x = -> | ||
3396 | for x in *hello | ||
3397 | y | ||
3398 | |||
3399 | t = for i=10,20 do i * 2 | ||
3400 | |||
3401 | hmm = 0 | ||
3402 | y = for j = 3,30, 8 | ||
3403 | hmm += 1 | ||
3404 | j * hmm | ||
3405 | |||
3406 | -> | ||
3407 | for k=10,40 | ||
3408 | "okay" | ||
3409 | |||
3410 | -> | ||
3411 | return for k=10,40 | ||
3412 | "okay" | ||
3413 | |||
3414 | while true do print "name" | ||
3415 | |||
3416 | while 5 + 5 | ||
3417 | print "okay world" | ||
3418 | working man | ||
3419 | |||
3420 | while also do | ||
3421 | i work too | ||
3422 | "okay" | ||
3423 | |||
3424 | i = 0 | ||
3425 | x = while i < 10 | ||
3426 | i += 1 | ||
3427 | |||
3428 | -- values that can'e be coerced | ||
3429 | |||
3430 | x = for thing in *3 | ||
3431 | y = "hello" | ||
3432 | |||
3433 | x = for x=1,2 | ||
3434 | y = "hello" | ||
3435 | |||
3436 | |||
3437 | -- continue | ||
3438 | |||
3439 | while true | ||
3440 | continue if false | ||
3441 | print "yes" | ||
3442 | break if true | ||
3443 | print "no" | ||
3444 | |||
3445 | |||
3446 | for x=1,10 | ||
3447 | continue if x > 3 and x < 7 | ||
3448 | print x | ||
3449 | |||
3450 | |||
3451 | list = for x=1,10 | ||
3452 | continue if x > 3 and x < 7 | ||
3453 | x | ||
3454 | |||
3455 | |||
3456 | for a in *{1,2,3,4,5,6} | ||
3457 | continue if a == 1 | ||
3458 | continue if a == 3 | ||
3459 | print a | ||
3460 | |||
3461 | |||
3462 | |||
3463 | for x=1,10 | ||
3464 | continue if x % 2 == 0 | ||
3465 | for y = 2,12 | ||
3466 | continue if y % 3 == 0 | ||
3467 | |||
3468 | |||
3469 | while true | ||
3470 | continue if false | ||
3471 | break | ||
3472 | |||
3473 | while true | ||
3474 | continue if false | ||
3475 | return 22 | ||
3476 | |||
3477 | -- | ||
3478 | |||
3479 | do | 3390 | do |
3480 | xxx = {1,2,3,4} | 3391 | a = -> |
3481 | for thing in *xxx | 3392 | with something |
3482 | print thing | 3393 | print .hello |
3483 | 3394 | print hi | |
3484 | 3395 | print "world" | |
3485 | )TestCodesHere"; | 3396 | )TestCodesHere"; |
3486 | MoonCompliler{}.complile(s); | 3397 | MoonCompliler{}.complile(s); |
3487 | return 0; | 3398 | return 0; |
diff --git a/MoonParser/moon_ast.h b/MoonParser/moon_ast.h index 1e5d733..d4ade53 100644 --- a/MoonParser/moon_ast.h +++ b/MoonParser/moon_ast.h | |||
@@ -245,10 +245,8 @@ AST_END(Update) | |||
245 | AST_LEAF(BinaryOperator, "BinaryOperator"_id) | 245 | AST_LEAF(BinaryOperator, "BinaryOperator"_id) |
246 | AST_END(BinaryOperator) | 246 | AST_END(BinaryOperator) |
247 | 247 | ||
248 | class Chain_t; | ||
249 | |||
250 | AST_NODE(Assignable, "Assignable"_id) | 248 | AST_NODE(Assignable, "Assignable"_id) |
251 | ast_ptr<ast_node> item; // Chain_t | Variable_t | SelfName_t | 249 | ast_ptr<ast_node> item; // AssignableChain_t | Variable_t | SelfName_t |
252 | AST_END(Assignable) | 250 | AST_END(Assignable) |
253 | 251 | ||
254 | class Value_t; | 252 | class Value_t; |
@@ -267,13 +265,6 @@ AST_NODE(Callable, "Callable"_id) | |||
267 | ast_ptr<ast_node> item; // Variable_t | SelfName_t | VarArg_t | Parens_t | 265 | ast_ptr<ast_node> item; // Variable_t | SelfName_t | VarArg_t | Parens_t |
268 | AST_END(Callable) | 266 | AST_END(Callable) |
269 | 267 | ||
270 | class InvokeArgs_t; | ||
271 | |||
272 | AST_NODE(ChainValue, "ChainValue"_id) | ||
273 | ast_ptr<ast_node> caller; // Chain_t | Callable_t | ||
274 | ast_ptr<InvokeArgs_t, true> arguments; | ||
275 | AST_END(ChainValue) | ||
276 | |||
277 | AST_NODE(variable_pair, "variable_pair"_id) | 268 | AST_NODE(variable_pair, "variable_pair"_id) |
278 | ast_ptr<Variable_t> name; | 269 | ast_ptr<Variable_t> name; |
279 | AST_END(variable_pair) | 270 | AST_END(variable_pair) |
@@ -299,7 +290,19 @@ AST_NODE(SimpleValue, "SimpleValue"_id) | |||
299 | */ | 290 | */ |
300 | AST_END(SimpleValue) | 291 | AST_END(SimpleValue) |
301 | 292 | ||
302 | AST_LEAF(LuaString, "LuaString"_id) | 293 | AST_LEAF(LuaStringOpen, "LuaStringOpen"_id) |
294 | AST_END(LuaStringOpen) | ||
295 | |||
296 | AST_LEAF(LuaStringContent, "LuaStringContent"_id) | ||
297 | AST_END(LuaStringContent) | ||
298 | |||
299 | AST_LEAF(LuaStringClose, "LuaStringClose"_id) | ||
300 | AST_END(LuaStringClose) | ||
301 | |||
302 | AST_NODE(LuaString, "LuaString"_id) | ||
303 | ast_ptr<LuaStringOpen_t> open; | ||
304 | ast_ptr<LuaStringContent_t> content; | ||
305 | ast_ptr<LuaStringClose_t> close; | ||
303 | AST_END(LuaString) | 306 | AST_END(LuaString) |
304 | 307 | ||
305 | AST_LEAF(SingleString, "SingleString"_id) | 308 | AST_LEAF(SingleString, "SingleString"_id) |
@@ -345,10 +348,17 @@ AST_NODE(Invoke, "Invoke"_id) | |||
345 | ast_sel_list<Exp_t, SingleString_t, DoubleString_t, LuaString_t> args; | 348 | ast_sel_list<Exp_t, SingleString_t, DoubleString_t, LuaString_t> args; |
346 | AST_END(Invoke) | 349 | AST_END(Invoke) |
347 | 350 | ||
348 | AST_NODE(Chain, "Chain"_id) | 351 | class InvokeArgs_t; |
352 | |||
353 | AST_NODE(ChainValue, "ChainValue"_id) | ||
354 | ast_ptr<Seperator_t> sep; | ||
355 | ast_sel_list<Callable_t, Invoke_t, DotChainItem_t, ColonChainItem_t, Slice_t, Exp_t, String_t, InvokeArgs_t> items; | ||
356 | AST_END(ChainValue) | ||
357 | |||
358 | AST_NODE(AssignableChain, "AssignableChain"_id) | ||
349 | ast_ptr<Seperator_t> sep; | 359 | ast_ptr<Seperator_t> sep; |
350 | ast_sel_list<Callable_t, Invoke_t, DotChainItem_t, ColonChainItem_t, Slice_t, Exp_t> items; | 360 | ast_sel_list<Callable_t, Invoke_t, DotChainItem_t, ColonChainItem_t, Exp_t, String_t> items; |
351 | AST_END(Chain) | 361 | AST_END(AssignableChain) |
352 | 362 | ||
353 | AST_NODE(Value, "Value"_id) | 363 | AST_NODE(Value, "Value"_id) |
354 | ast_ptr<ast_node> item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t | 364 | ast_ptr<ast_node> item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t |
@@ -486,6 +496,6 @@ AST_NODE(Block, "Block"_id) | |||
486 | ast_list<Statement_t> statements; | 496 | ast_list<Statement_t> statements; |
487 | AST_END(Block) | 497 | AST_END(Block) |
488 | 498 | ||
489 | AST_NODE(BlockEnd, "BlockEnd"_id) | 499 | AST_NODE(File, "File"_id) |
490 | ast_ptr<Block_t> block; | 500 | ast_ptr<Block_t> block; |
491 | AST_END(BlockEnd) | 501 | AST_END(File) |
diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp index 481c885..ad86020 100644 --- a/MoonParser/moon_parser.cpp +++ b/MoonParser/moon_parser.cpp | |||
@@ -1,11 +1,21 @@ | |||
1 | #include "moon_parser.h" | 1 | #include "moon_parser.h" |
2 | 2 | ||
3 | std::unordered_set<std::string> State::luaKeywords = { | ||
4 | "and", "break", "do", "else", "elseif", | ||
5 | "end", "false", "for", "function", "if", | ||
6 | "in", "local", "nil", "not", "or", | ||
7 | "repeat", "return", "then", "true", "until", | ||
8 | "while" | ||
9 | }; | ||
10 | |||
3 | std::unordered_set<std::string> State::keywords = { | 11 | std::unordered_set<std::string> State::keywords = { |
4 | "and", "while", "else", "using", "continue", | 12 | "and", "break", "do", "else", "elseif", |
5 | "local", "not", "then", "return", "from", | 13 | "end", "false", "for", "function", "if", |
6 | "extends", "for", "do", "or", "export", | 14 | "in", "local", "nil", "not", "or", |
7 | "class", "in", "unless", "when", "elseif", | 15 | "repeat", "return", "then", "true", "until", |
8 | "switch", "break", "if", "with", "import", "true", "false", "nil" | 16 | "while", // Lua keywords |
17 | "class", "continue", "export", "extends", | ||
18 | "import", "switch", "unless", "using", "with" // Moon keywords | ||
9 | }; | 19 | }; |
10 | 20 | ||
11 | rule plain_space = *set(" \t"); | 21 | rule plain_space = *set(" \t"); |
@@ -44,12 +54,9 @@ rule Seperator = true_(); | |||
44 | 54 | ||
45 | rule Variable = user(Name, [](const item_t& item) { | 55 | rule Variable = user(Name, [](const item_t& item) { |
46 | State* st = reinterpret_cast<State*>(item.user_data); | 56 | State* st = reinterpret_cast<State*>(item.user_data); |
47 | for (auto it = item.begin; it != item.end; ++it) st->buffer << static_cast<char>(*it); | 57 | for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it); |
48 | std::string name; | 58 | auto it = st->keywords.find(st->buffer); |
49 | st->buffer >> name; | ||
50 | st->buffer.str(""); | ||
51 | st->buffer.clear(); | 59 | st->buffer.clear(); |
52 | auto it = st->keywords.find(name); | ||
53 | return it == st->keywords.end(); | 60 | return it == st->keywords.end(); |
54 | }); | 61 | }); |
55 | 62 | ||
@@ -252,18 +259,18 @@ rule BinaryOperator = | |||
252 | expr("//") | | 259 | expr("//") | |
253 | set("+-*/%^><|&"); | 260 | set("+-*/%^><|&"); |
254 | 261 | ||
255 | extern rule Chain; | 262 | extern rule AssignableChain; |
256 | 263 | ||
257 | rule Assignable = Chain | Space >> Variable | SelfName; | 264 | rule Assignable = AssignableChain | Space >> Variable | SelfName; |
258 | 265 | ||
259 | extern rule Value; | 266 | extern rule Value; |
260 | 267 | ||
261 | rule exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> Value; | 268 | rule exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> Value; |
262 | rule Exp = Value >> *exp_op_value; | 269 | rule Exp = Value >> *exp_op_value; |
263 | 270 | ||
264 | extern rule Callable, InvokeArgs; | 271 | extern rule Chain, Callable, InvokeArgs; |
265 | 272 | ||
266 | rule ChainValue = (Chain | Callable) >> -InvokeArgs; | 273 | rule ChainValue = Seperator >> (Chain | Callable) >> -InvokeArgs; |
267 | 274 | ||
268 | extern rule KeyValue, String, SimpleValue; | 275 | extern rule KeyValue, String, SimpleValue; |
269 | 276 | ||
@@ -321,10 +328,10 @@ rule chain_call = (Callable | String) >> ChainItems; | |||
321 | rule chain_item = and_(set(".\\")) >> ChainItems; | 328 | rule chain_item = and_(set(".\\")) >> ChainItems; |
322 | rule chain_dot_chain = DotChainItem >> -ChainItems; | 329 | rule chain_dot_chain = DotChainItem >> -ChainItems; |
323 | 330 | ||
324 | rule Chain = Seperator >> ( | 331 | rule Chain = chain_call | chain_item | |
325 | chain_call | | 332 | Space >> (chain_dot_chain | ColonChain); |
326 | chain_item | | 333 | |
327 | Space >> (chain_dot_chain | ColonChain)); | 334 | rule AssignableChain = Seperator >> Chain; |
328 | 335 | ||
329 | extern rule ChainItem; | 336 | extern rule ChainItem; |
330 | 337 | ||
@@ -491,4 +498,6 @@ rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement; | |||
491 | rule empty_line_stop = Space >> and_(Stop); | 498 | rule empty_line_stop = Space >> and_(Stop); |
492 | rule Line = CheckIndent >> Statement | empty_line_stop; | 499 | rule Line = CheckIndent >> Statement | empty_line_stop; |
493 | rule Block = Seperator >> Line >> *(+Break >> Line); | 500 | rule Block = Seperator >> Line >> *(+Break >> Line); |
494 | rule BlockEnd = Block >> eof(); | 501 | |
502 | rule Shebang = expr("#!") >> *(not_(Stop) >> Any); | ||
503 | rule File = White >> -Shebang >> Block >> eof(); | ||
diff --git a/MoonParser/moon_parser.h b/MoonParser/moon_parser.h index 5327b05..0c45538 100644 --- a/MoonParser/moon_parser.h +++ b/MoonParser/moon_parser.h | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <unordered_set> | 5 | #include <unordered_set> |
6 | #include <stack> | 6 | #include <stack> |
7 | #include <algorithm> | 7 | #include <algorithm> |
8 | #include <sstream> | ||
9 | #include <vector> | 8 | #include <vector> |
10 | #include "parserlib.hpp" | 9 | #include "parserlib.hpp" |
11 | using namespace parserlib; | 10 | using namespace parserlib; |
@@ -15,9 +14,10 @@ struct State { | |||
15 | indents.push(0); | 14 | indents.push(0); |
16 | stringOpen = -1; | 15 | stringOpen = -1; |
17 | } | 16 | } |
18 | std::stringstream buffer; | 17 | std::string buffer; |
19 | size_t stringOpen; | 18 | size_t stringOpen; |
20 | std::stack<int> indents; | 19 | std::stack<int> indents; |
21 | std::stack<bool> doStack; | 20 | std::stack<bool> doStack; |
21 | static std::unordered_set<std::string> luaKeywords; | ||
22 | static std::unordered_set<std::string> keywords; | 22 | static std::unordered_set<std::string> keywords; |
23 | }; | 23 | }; |