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 | |
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.
-rw-r--r-- | README.md | 57 | ||||
-rw-r--r-- | spec/inputs/backcall.moon | 46 | ||||
-rw-r--r-- | spec/inputs/syntax.moon | 10 | ||||
-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 |
7 files changed, 274 insertions, 14 deletions
@@ -12,6 +12,63 @@ MoonPlus is a compiler with features from Moonscript language 0.5.0 and could be | |||
12 | 12 | ||
13 | ## Changes | 13 | ## Changes |
14 | 14 | ||
15 | * Add multi-line comment support. | ||
16 | * Add usage for symbol `\` to escape new line. Will compile codes: | ||
17 | ```Moonscript | ||
18 | str = --[[ | ||
19 | This is a multi line comment. | ||
20 | It's OK. | ||
21 | ]] strA \ -- comment 1 | ||
22 | .. strB \ -- comment 2 | ||
23 | .. strC | ||
24 | |||
25 | func --[[ip]] "192.168.126.110", --[[port]] 3000 | ||
26 | ``` | ||
27 |   to: | ||
28 | ```Lua | ||
29 | local str = strA .. strB .. strC | ||
30 | func("192.168.126.110", 3000) | ||
31 | ``` | ||
32 | |||
33 | * Add back call features support with new operator and syntax. For example: | ||
34 | ```Moonscript | ||
35 | {1,2,3} \ | ||
36 | |> map((x)-> x * 2) \ | ||
37 | |> filter((x)-> x > 4) \ | ||
38 | |> reduce(0, (a,b)-> a + b) \ | ||
39 | |||
40 | |||
41 | do | ||
42 | (data) <- http.get "ajaxtest" | ||
43 | body[".result"]\html data | ||
44 | (processed) <- http.get "ajaxprocess", data | ||
45 | body[".result"]\append processed | ||
46 | print "done" | ||
47 | ``` | ||
48 |   compiles to: | ||
49 | ```Lua | ||
50 | print(reduce(filter(map({ | ||
51 | 1, | ||
52 | 2, | ||
53 | 3 | ||
54 | }, function(x) | ||
55 | return x * 2 | ||
56 | end), function(x) | ||
57 | return x > 4 | ||
58 | end), 0, function(a, b) | ||
59 | return a + b | ||
60 | end)) | ||
61 | do | ||
62 | http.get("ajaxtest", function(data) | ||
63 | body[".result"]:html(data) | ||
64 | return http.get("ajaxprocess", data, function(processed) | ||
65 | body[".result"]:append(processed) | ||
66 | return print("done") | ||
67 | end) | ||
68 | end) | ||
69 | end | ||
70 | ``` | ||
71 | |||
15 | * Add existential operator support. Generate codes from: | 72 | * Add existential operator support. Generate codes from: |
16 | ```Moonscript | 73 | ```Moonscript |
17 | func?! | 74 | func?! |
diff --git a/spec/inputs/backcall.moon b/spec/inputs/backcall.moon new file mode 100644 index 0000000..407a5a7 --- /dev/null +++ b/spec/inputs/backcall.moon | |||
@@ -0,0 +1,46 @@ | |||
1 | |||
2 | {"abc", 123, 998} |> foreach print | ||
3 | |||
4 | {1,2,3} \ | ||
5 | |> map((x)-> x * 2) \ | ||
6 | |> filter((x)-> x > 4) \ | ||
7 | |> reduce(0, (a,b)-> a + b) \ | ||
8 | |||
9 | |||
10 | [i |> tostring for i = 0,10] |> table.concat(",") |> print | ||
11 | |||
12 | b = 1 + 2 + (4 |> tostring |> print(1) or 123) | ||
13 | |||
14 | if x = 233 |> math.max 998 | ||
15 | print x | ||
16 | |||
17 | 998 |> func2 "abc", 233 |> func0 |> func1 | ||
18 | 998 |> func0("abc", 233) |> func1 |> func2 | ||
19 | |||
20 | do | ||
21 | (data) <- http?.get "ajaxtest" | ||
22 | body[".result"]\html data | ||
23 | (processed) <- http.get "ajaxprocess", data | ||
24 | body[".result"]\append processed | ||
25 | <- setTimeout 1000 | ||
26 | print "done" | ||
27 | |||
28 | do | ||
29 | <- syncStatus | ||
30 | (err,data="nil") <- loadAsync "file.moon" | ||
31 | print err if err | ||
32 | (codes) <- compileAsync data | ||
33 | func = loadstring codes | ||
34 | func! | ||
35 | |||
36 | do | ||
37 | <- f1 | ||
38 | <- f2 | ||
39 | do | ||
40 | <- f3 | ||
41 | <- f4 | ||
42 | <- f5 | ||
43 | <- f6 | ||
44 | f7! | ||
45 | |||
46 | alert "hi" | ||
diff --git a/spec/inputs/syntax.moon b/spec/inputs/syntax.moon index bf0cf04..3ac9991 100644 --- a/spec/inputs/syntax.moon +++ b/spec/inputs/syntax.moon | |||
@@ -270,3 +270,13 @@ z = a- b | |||
270 | 270 | ||
271 | 271 | ||
272 | -- cooool | 272 | -- cooool |
273 | |||
274 | str = --[[ | ||
275 | This is a multi line comment. | ||
276 | It's OK. | ||
277 | ]] strA \ -- comment 1 | ||
278 | .. strB \ -- comment 2 | ||
279 | .. strC | ||
280 | |||
281 | func --[[port]] 3000, --[[ip]] "192.168.1.1" | ||
282 | |||
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 | ||