diff options
| author | Li Jin <dragon-fly@qq.com> | 2019-10-06 17:30:11 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2019-10-06 17:30:11 +0800 |
| commit | 055fcb596781a8488afeb0030e9ef4295e3d7017 (patch) | |
| tree | 0512d6d9660e563be37af5b6ac1bb888a9023e6a | |
| parent | 2de63a85a87c9a64032602fdd3736f69e73efbc5 (diff) | |
| download | yuescript-055fcb596781a8488afeb0030e9ef4295e3d7017.tar.gz yuescript-055fcb596781a8488afeb0030e9ef4295e3d7017.tar.bz2 yuescript-055fcb596781a8488afeb0030e9ef4295e3d7017.zip | |
updating
| -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 | }; |
