diff options
| author | Li Jin <dragon-fly@qq.com> | 2020-01-28 00:41:53 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2020-01-28 01:10:31 +0800 |
| commit | fb47c11bd942c83317f1f9a2e255535649401cbf (patch) | |
| tree | 3fb35b9b23911a37c4e4499cf650792ba2b8b21c /src | |
| parent | 27717564cb1ab72c88c10a8392b6795ddea7a0ef (diff) | |
| download | yuescript-fb47c11bd942c83317f1f9a2e255535649401cbf.tar.gz yuescript-fb47c11bd942c83317f1f9a2e255535649401cbf.tar.bz2 yuescript-fb47c11bd942c83317f1f9a2e255535649401cbf.zip | |
Add multi-line comment support. Add escape new line symbol. Add back call syntax.
Diffstat (limited to 'src')
| -rw-r--r-- | src/MoonP/moon_ast.cpp | 2 | ||||
| -rw-r--r-- | src/MoonP/moon_ast.h | 16 | ||||
| -rw-r--r-- | src/MoonP/moon_compiler.cpp | 138 | ||||
| -rw-r--r-- | src/MoonP/moon_parser.cpp | 19 |
4 files changed, 161 insertions, 14 deletions
diff --git a/src/MoonP/moon_ast.cpp b/src/MoonP/moon_ast.cpp index 8b8a674..f14fa74 100644 --- a/src/MoonP/moon_ast.cpp +++ b/src/MoonP/moon_ast.cpp | |||
| @@ -34,6 +34,7 @@ AST_IMPL(ImportLiteral) | |||
| 34 | AST_IMPL(ImportFrom) | 34 | AST_IMPL(ImportFrom) |
| 35 | AST_IMPL(ImportAs) | 35 | AST_IMPL(ImportAs) |
| 36 | AST_IMPL(Import) | 36 | AST_IMPL(Import) |
| 37 | AST_IMPL(Backcall) | ||
| 37 | AST_IMPL(ExpListLow) | 38 | AST_IMPL(ExpListLow) |
| 38 | AST_IMPL(ExpList) | 39 | AST_IMPL(ExpList) |
| 39 | AST_IMPL(Return) | 40 | AST_IMPL(Return) |
| @@ -59,6 +60,7 @@ AST_IMPL(Assign) | |||
| 59 | AST_IMPL(update_op) | 60 | AST_IMPL(update_op) |
| 60 | AST_IMPL(Update) | 61 | AST_IMPL(Update) |
| 61 | AST_IMPL(BinaryOperator) | 62 | AST_IMPL(BinaryOperator) |
| 63 | AST_IMPL(BackcallOperator) | ||
| 62 | AST_IMPL(Assignable) | 64 | AST_IMPL(Assignable) |
| 63 | AST_IMPL(AssignableChain) | 65 | AST_IMPL(AssignableChain) |
| 64 | AST_IMPL(exp_op_value) | 66 | AST_IMPL(exp_op_value) |
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index e71afe9..6969688 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h | |||
| @@ -135,6 +135,15 @@ AST_NODE(Import, "Import"_id) | |||
| 135 | AST_MEMBER(Import, &content) | 135 | AST_MEMBER(Import, &content) |
| 136 | AST_END(Import) | 136 | AST_END(Import) |
| 137 | 137 | ||
| 138 | class FnArgsDef_t; | ||
| 139 | class ChainValue_t; | ||
| 140 | |||
| 141 | AST_NODE(Backcall, "Backcall"_id) | ||
| 142 | ast_ptr<false, FnArgsDef_t> argsDef; | ||
| 143 | ast_ptr<true, ChainValue_t> value; | ||
| 144 | AST_MEMBER(Backcall, &argsDef, &value) | ||
| 145 | AST_END(Backcall) | ||
| 146 | |||
| 138 | AST_NODE(ExpListLow, "ExpListLow"_id) | 147 | AST_NODE(ExpListLow, "ExpListLow"_id) |
| 139 | ast_ptr<true, Seperator_t> sep; | 148 | ast_ptr<true, Seperator_t> sep; |
| 140 | ast_list<true, Exp_t> exprs; | 149 | ast_list<true, Exp_t> exprs; |
| @@ -295,6 +304,9 @@ AST_END(Update) | |||
| 295 | AST_LEAF(BinaryOperator, "BinaryOperator"_id) | 304 | AST_LEAF(BinaryOperator, "BinaryOperator"_id) |
| 296 | AST_END(BinaryOperator) | 305 | AST_END(BinaryOperator) |
| 297 | 306 | ||
| 307 | AST_LEAF(BackcallOperator, "BackcallOperator"_id) | ||
| 308 | AST_END(BackcallOperator) | ||
| 309 | |||
| 298 | class AssignableChain_t; | 310 | class AssignableChain_t; |
| 299 | 311 | ||
| 300 | AST_NODE(Assignable, "Assignable"_id) | 312 | AST_NODE(Assignable, "Assignable"_id) |
| @@ -305,7 +317,7 @@ AST_END(Assignable) | |||
| 305 | class Value_t; | 317 | class Value_t; |
| 306 | 318 | ||
| 307 | AST_NODE(exp_op_value, "exp_op_value"_id) | 319 | AST_NODE(exp_op_value, "exp_op_value"_id) |
| 308 | ast_ptr<true, BinaryOperator_t> op; | 320 | ast_sel<true, BinaryOperator_t, BackcallOperator_t> op; |
| 309 | ast_ptr<true, Value_t> value; | 321 | ast_ptr<true, Value_t> value; |
| 310 | AST_MEMBER(exp_op_value, &op, &value) | 322 | AST_MEMBER(exp_op_value, &op, &value) |
| 311 | AST_END(exp_op_value) | 323 | AST_END(exp_op_value) |
| @@ -586,7 +598,7 @@ AST_END(BreakLoop) | |||
| 586 | AST_NODE(Statement, "Statement"_id) | 598 | AST_NODE(Statement, "Statement"_id) |
| 587 | ast_sel<true, Import_t, While_t, For_t, ForEach_t, | 599 | ast_sel<true, Import_t, While_t, For_t, ForEach_t, |
| 588 | Return_t, Local_t, Export_t, BreakLoop_t, | 600 | Return_t, Local_t, Export_t, BreakLoop_t, |
| 589 | ExpListAssign_t> content; | 601 | Backcall_t, ExpListAssign_t> content; |
| 590 | ast_ptr<false, statement_appendix_t> appendix; | 602 | ast_ptr<false, statement_appendix_t> appendix; |
| 591 | AST_MEMBER(Statement, &content, &appendix) | 603 | AST_MEMBER(Statement, &content, &appendix) |
| 592 | AST_END(Statement) | 604 | AST_END(Statement) |
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 4723af4..6173389 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
| @@ -739,6 +739,23 @@ private: | |||
| 739 | break; | 739 | break; |
| 740 | } | 740 | } |
| 741 | } | 741 | } |
| 742 | } else if (expList->exprs.size() == 1){ | ||
| 743 | auto exp = static_cast<Exp_t*>(expList->exprs.back()); | ||
| 744 | if (exp->opValues.size() > 0) { | ||
| 745 | bool backcall = true; | ||
| 746 | for (auto _opValue : exp->opValues.objects()) { | ||
| 747 | auto opValue = static_cast<exp_op_value_t*>(_opValue); | ||
| 748 | if (!opValue->op.is<BackcallOperator_t>()) { | ||
| 749 | backcall = false; | ||
| 750 | break; | ||
| 751 | } | ||
| 752 | } | ||
| 753 | if (backcall) { | ||
| 754 | transformExp(exp, out); | ||
| 755 | out.back().append(nll(exp)); | ||
| 756 | break; | ||
| 757 | } | ||
| 758 | } | ||
| 742 | } | 759 | } |
| 743 | throw std::logic_error(debugInfo("Expression list must appear at the end of body block."sv, expList)); | 760 | throw std::logic_error(debugInfo("Expression list must appear at the end of body block."sv, expList)); |
| 744 | } | 761 | } |
| @@ -1593,11 +1610,55 @@ private: | |||
| 1593 | } | 1610 | } |
| 1594 | 1611 | ||
| 1595 | void transformExp(Exp_t* exp, str_list& out) { | 1612 | void transformExp(Exp_t* exp, str_list& out) { |
| 1613 | auto x = exp; | ||
| 1614 | const auto& opValues = exp->opValues.objects(); | ||
| 1615 | for (auto it = opValues.begin(); it != opValues.end(); ++it) { | ||
| 1616 | auto opValue = static_cast<exp_op_value_t*>(*it); | ||
| 1617 | if (opValue->op.is<BackcallOperator_t>()) { | ||
| 1618 | if (auto chainValue = opValue->value->item.as<ChainValue_t>()) { | ||
| 1619 | auto newExp = x->new_ptr<Exp_t>(); | ||
| 1620 | { | ||
| 1621 | auto arg = x->new_ptr<Exp_t>(); | ||
| 1622 | arg->value.set(exp->value); | ||
| 1623 | for (auto i = opValues.begin(); i != it; ++i) { | ||
| 1624 | arg->opValues.push_back(*i); | ||
| 1625 | } | ||
| 1626 | auto next = it; ++next; | ||
| 1627 | for (auto i = next; i != opValues.end(); ++i) { | ||
| 1628 | newExp->opValues.push_back(*i); | ||
| 1629 | } | ||
| 1630 | if (isChainValueCall(chainValue)) { | ||
| 1631 | auto last = chainValue->items.back(); | ||
| 1632 | if (auto invoke = ast_cast<InvokeArgs_t>(last)) { | ||
| 1633 | invoke->args.push_front(arg); | ||
| 1634 | } else { | ||
| 1635 | ast_to<Invoke_t>(last)->args.push_front(arg); | ||
| 1636 | } | ||
| 1637 | } else { | ||
| 1638 | auto invoke = x->new_ptr<Invoke_t>(); | ||
| 1639 | invoke->args.push_front(arg); | ||
| 1640 | chainValue->items.push_back(invoke); | ||
| 1641 | } | ||
| 1642 | auto value = x->new_ptr<Value_t>(); | ||
| 1643 | value->item.set(chainValue); | ||
| 1644 | newExp->value.set(value); | ||
| 1645 | } | ||
| 1646 | transformExp(newExp, out); | ||
| 1647 | return; | ||
| 1648 | } else { | ||
| 1649 | throw std::logic_error(debugInfo("Backcall operator must be followed by chain value."sv, opValue->value)); | ||
| 1650 | } | ||
| 1651 | } | ||
| 1652 | } | ||
| 1596 | str_list temp; | 1653 | str_list temp; |
| 1597 | transformValue(exp->value, temp); | 1654 | transformValue(exp->value, temp); |
| 1598 | for (auto _opValue : exp->opValues.objects()) { | 1655 | for (auto _opValue : exp->opValues.objects()) { |
| 1599 | auto opValue = static_cast<exp_op_value_t*>(_opValue); | 1656 | auto opValue = static_cast<exp_op_value_t*>(_opValue); |
| 1600 | transformBinaryOperator(opValue->op, temp); | 1657 | if (auto op = opValue->op.as<BinaryOperator_t>()) { |
| 1658 | transformBinaryOperator(op, temp); | ||
| 1659 | } else { | ||
| 1660 | temp.push_back(s("|>"sv)); | ||
| 1661 | } | ||
| 1601 | transformValue(opValue->value, temp); | 1662 | transformValue(opValue->value, temp); |
| 1602 | } | 1663 | } |
| 1603 | out.push_back(join(temp, " "sv)); | 1664 | out.push_back(join(temp, " "sv)); |
| @@ -1731,8 +1792,68 @@ private: | |||
| 1731 | void transformCodes(const node_container& nodes, str_list& out, bool implicitReturn) { | 1792 | void transformCodes(const node_container& nodes, str_list& out, bool implicitReturn) { |
| 1732 | LocalMode mode = LocalMode::None; | 1793 | LocalMode mode = LocalMode::None; |
| 1733 | Local_t* any = nullptr, *capital = nullptr; | 1794 | Local_t* any = nullptr, *capital = nullptr; |
| 1734 | for (auto node : nodes) { | 1795 | for (auto it = nodes.begin(); it != nodes.end(); ++it) { |
| 1796 | auto node = *it; | ||
| 1735 | auto stmt = static_cast<Statement_t*>(node); | 1797 | auto stmt = static_cast<Statement_t*>(node); |
| 1798 | if (auto backcall = stmt->content.as<Backcall_t>()) { | ||
| 1799 | auto x = *nodes.begin(); | ||
| 1800 | auto newBlock = x->new_ptr<Block_t>(); | ||
| 1801 | if (it != nodes.begin()) { | ||
| 1802 | for (auto i = nodes.begin(); i != it; ++i) { | ||
| 1803 | newBlock->statements.push_back(*i); | ||
| 1804 | } | ||
| 1805 | } | ||
| 1806 | x = backcall; | ||
| 1807 | auto arg = x->new_ptr<Exp_t>(); | ||
| 1808 | { | ||
| 1809 | auto block = x->new_ptr<Block_t>(); | ||
| 1810 | auto next = it; ++next; | ||
| 1811 | if (next != nodes.end()) { | ||
| 1812 | for (auto i = next; i != nodes.end(); ++i) { | ||
| 1813 | block->statements.push_back(*i); | ||
| 1814 | } | ||
| 1815 | } | ||
| 1816 | auto body = x->new_ptr<Body_t>(); | ||
| 1817 | body->content.set(block); | ||
| 1818 | auto funLit = x->new_ptr<FunLit_t>(); | ||
| 1819 | funLit->argsDef.set(backcall->argsDef); | ||
| 1820 | funLit->arrow.set(toAst<fn_arrow_t>("->"sv, fn_arrow, x)); | ||
| 1821 | funLit->body.set(body); | ||
| 1822 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | ||
| 1823 | simpleValue->value.set(funLit); | ||
| 1824 | auto value = x->new_ptr<Value_t>(); | ||
| 1825 | value->item.set(simpleValue); | ||
| 1826 | arg->value.set(value); | ||
| 1827 | } | ||
| 1828 | if (isChainValueCall(backcall->value)) { | ||
| 1829 | auto last = backcall->value->items.back(); | ||
| 1830 | if (auto invoke = ast_cast<Invoke_t>(last)) { | ||
| 1831 | invoke->args.push_back(arg); | ||
| 1832 | } else { | ||
| 1833 | ast_to<InvokeArgs_t>(last)->args.push_back(arg); | ||
| 1834 | } | ||
| 1835 | } else { | ||
| 1836 | auto invoke = x->new_ptr<Invoke_t>(); | ||
| 1837 | invoke->args.push_back(arg); | ||
| 1838 | backcall->value->items.push_back(invoke); | ||
| 1839 | } | ||
| 1840 | auto newStmt = x->new_ptr<Statement_t>(); | ||
| 1841 | { | ||
| 1842 | auto chainValue = backcall->value.get(); | ||
| 1843 | auto value = x->new_ptr<Value_t>(); | ||
| 1844 | value->item.set(chainValue); | ||
| 1845 | auto exp = x->new_ptr<Exp_t>(); | ||
| 1846 | exp->value.set(value); | ||
| 1847 | auto expList = x->new_ptr<ExpList_t>(); | ||
| 1848 | expList->exprs.push_back(exp); | ||
| 1849 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | ||
| 1850 | expListAssign->expList.set(expList); | ||
| 1851 | newStmt->content.set(expListAssign); | ||
| 1852 | newBlock->statements.push_back(newStmt); | ||
| 1853 | } | ||
| 1854 | transformBlock(newBlock, out, implicitReturn); | ||
| 1855 | return; | ||
| 1856 | } | ||
| 1736 | if (auto local = stmt->content.as<Local_t>()) { | 1857 | if (auto local = stmt->content.as<Local_t>()) { |
| 1737 | if (auto flag = local->name.as<local_flag_t>()) { | 1858 | if (auto flag = local->name.as<local_flag_t>()) { |
| 1738 | LocalMode newMode = toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; | 1859 | LocalMode newMode = toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; |
| @@ -1802,9 +1923,10 @@ private: | |||
| 1802 | } | 1923 | } |
| 1803 | } | 1924 | } |
| 1804 | if (implicitReturn) { | 1925 | if (implicitReturn) { |
| 1926 | BLOCK_START | ||
| 1927 | BREAK_IF(nodes.empty()); | ||
| 1805 | auto last = static_cast<Statement_t*>(nodes.back()); | 1928 | auto last = static_cast<Statement_t*>(nodes.back()); |
| 1806 | auto x = last; | 1929 | auto x = last; |
| 1807 | BLOCK_START | ||
| 1808 | auto expList = expListFrom(last); | 1930 | auto expList = expListFrom(last); |
| 1809 | BREAK_IF(!expList || | 1931 | BREAK_IF(!expList || |
| 1810 | (last->appendix && | 1932 | (last->appendix && |
| @@ -1816,11 +1938,13 @@ private: | |||
| 1816 | last->content.set(returnNode); | 1938 | last->content.set(returnNode); |
| 1817 | BLOCK_END | 1939 | BLOCK_END |
| 1818 | } | 1940 | } |
| 1819 | str_list temp; | 1941 | if (!nodes.empty()) { |
| 1820 | for (auto node : nodes) { | 1942 | str_list temp; |
| 1821 | transformStatement(static_cast<Statement_t*>(node), temp); | 1943 | for (auto node : nodes) { |
| 1944 | transformStatement(static_cast<Statement_t*>(node), temp); | ||
| 1945 | } | ||
| 1946 | out.push_back(join(temp)); | ||
| 1822 | } | 1947 | } |
| 1823 | out.push_back(join(temp)); | ||
| 1824 | } | 1948 | } |
| 1825 | 1949 | ||
| 1826 | void transformBody(Body_t* body, str_list& out, bool implicitReturn = false) { | 1950 | void transformBody(Body_t* body, str_list& out, bool implicitReturn = false) { |
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index 6d1b86c..baea9bf 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp | |||
| @@ -37,8 +37,13 @@ rule Any = Break | any(); | |||
| 37 | rule White = *(set(" \t") | Break); | 37 | rule White = *(set(" \t") | Break); |
| 38 | rule Stop = Break | eof(); | 38 | rule Stop = Break | eof(); |
| 39 | rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); | 39 | rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); |
| 40 | rule Indent = *set(" \t"); | 40 | rule multi_line_open = expr("--[["); |
| 41 | rule Space = plain_space >> -Comment; | 41 | rule multi_line_close = expr("]]"); |
| 42 | rule multi_line_content = *(not_(multi_line_close) >> Any); | ||
| 43 | rule MultiLineComment = multi_line_open >> multi_line_content >> multi_line_close; | ||
| 44 | rule Indent = plain_space; | ||
| 45 | rule EscapeNewLine = expr('\\') >> plain_space >> -Comment >> Break; | ||
| 46 | rule Space = *(set(" \t") | MultiLineComment | EscapeNewLine) >> -Comment; | ||
| 42 | rule SomeSpace = +set(" \t") >> -Comment; | 47 | rule SomeSpace = +set(" \t") >> -Comment; |
| 43 | rule SpaceBreak = Space >> Break; | 48 | rule SpaceBreak = Space >> Break; |
| 44 | rule EmptyLine = SpaceBreak; | 49 | rule EmptyLine = SpaceBreak; |
| @@ -287,13 +292,15 @@ rule BinaryOperator = | |||
| 287 | expr("//") | | 292 | expr("//") | |
| 288 | set("+-*/%^><|&"); | 293 | set("+-*/%^><|&"); |
| 289 | 294 | ||
| 295 | rule BackcallOperator = expr("|>"); | ||
| 296 | |||
| 290 | extern rule AssignableChain; | 297 | extern rule AssignableChain; |
| 291 | 298 | ||
| 292 | rule Assignable = AssignableChain | Space >> Variable | SelfName; | 299 | rule Assignable = AssignableChain | Space >> Variable | SelfName; |
| 293 | 300 | ||
| 294 | extern rule Value; | 301 | extern rule Value; |
| 295 | 302 | ||
| 296 | rule exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> Value; | 303 | rule exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value; |
| 297 | rule Exp = Value >> *exp_op_value; | 304 | rule Exp = Value >> *exp_op_value; |
| 298 | 305 | ||
| 299 | extern rule Chain, Callable, InvokeArgs, existential_op; | 306 | extern rule Chain, Callable, InvokeArgs, existential_op; |
| @@ -334,7 +341,7 @@ rule LuaStringClose = pl::user(lua_string_close, [](const item_t& item) | |||
| 334 | return st->stringOpen == count; | 341 | return st->stringOpen == count; |
| 335 | }); | 342 | }); |
| 336 | 343 | ||
| 337 | rule LuaStringContent = *(not_(LuaStringClose) >> (Break | Any)); | 344 | rule LuaStringContent = *(not_(LuaStringClose) >> Any); |
| 338 | 345 | ||
| 339 | rule LuaString = pl::user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) | 346 | rule LuaString = pl::user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) |
| 340 | { | 347 | { |
| @@ -474,6 +481,8 @@ rule NameList = Seperator >> Space >> Variable >> *(sym(',') >> Space >> Variabl | |||
| 474 | rule NameOrDestructure = Space >> Variable | TableLit; | 481 | rule NameOrDestructure = Space >> Variable | TableLit; |
| 475 | rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure); | 482 | rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure); |
| 476 | 483 | ||
| 484 | rule Backcall = -FnArgsDef >> Space >> symx("<-") >> Space >> ChainValue; | ||
| 485 | |||
| 477 | rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp); | 486 | rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp); |
| 478 | rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp); | 487 | rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp); |
| 479 | 488 | ||
| @@ -518,7 +527,7 @@ rule Statement = | |||
| 518 | ( | 527 | ( |
| 519 | Import | While | For | ForEach | | 528 | Import | While | For | ForEach | |
| 520 | Return | Local | Export | Space >> BreakLoop | | 529 | Return | Local | Export | Space >> BreakLoop | |
| 521 | ExpListAssign | 530 | Backcall | ExpListAssign |
| 522 | ) >> Space >> | 531 | ) >> Space >> |
| 523 | -statement_appendix; | 532 | -statement_appendix; |
| 524 | 533 | ||
