summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-01-28 00:41:53 +0800
committerLi Jin <dragon-fly@qq.com>2020-01-28 01:10:31 +0800
commitfb47c11bd942c83317f1f9a2e255535649401cbf (patch)
tree3fb35b9b23911a37c4e4499cf650792ba2b8b21c
parent27717564cb1ab72c88c10a8392b6795ddea7a0ef (diff)
downloadyuescript-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.md57
-rw-r--r--spec/inputs/backcall.moon46
-rw-r--r--spec/inputs/syntax.moon10
-rw-r--r--src/MoonP/moon_ast.cpp2
-rw-r--r--src/MoonP/moon_ast.h16
-rw-r--r--src/MoonP/moon_compiler.cpp138
-rw-r--r--src/MoonP/moon_parser.cpp19
7 files changed, 274 insertions, 14 deletions
diff --git a/README.md b/README.md
index 7786bc7..968cc99 100644
--- a/README.md
+++ b/README.md
@@ -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
18str = --[[
19 This is a multi line comment.
20 It's OK.
21]] strA \ -- comment 1
22 .. strB \ -- comment 2
23 .. strC
24
25func --[[ip]] "192.168.126.110", --[[port]] 3000
26```
27&emsp;&emsp;to:
28```Lua
29local str = strA .. strB .. strC
30func("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 |> print
40
41do
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&emsp;&emsp;compiles to:
49```Lua
50print(reduce(filter(map({
51 1,
52 2,
53 3
54}, function(x)
55 return x * 2
56end), function(x)
57 return x > 4
58end), 0, function(a, b)
59 return a + b
60end))
61do
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)
69end
70```
71
15* Add existential operator support. Generate codes from: 72* Add existential operator support. Generate codes from:
16```Moonscript 73```Moonscript
17func?! 74func?!
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 |> print
9
10[i |> tostring for i = 0,10] |> table.concat(",") |> print
11
12b = 1 + 2 + (4 |> tostring |> print(1) or 123)
13
14if x = 233 |> math.max 998
15 print x
16
17998 |> func2 "abc", 233 |> func0 |> func1
18998 |> func0("abc", 233) |> func1 |> func2
19
20do
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
28do
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
36do
37 <- f1
38 <- f2
39 do
40 <- f3
41 <- f4
42 <- f5
43 <- f6
44 f7!
45
46alert "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
274str = --[[
275This is a multi line comment.
276It's OK.
277]] strA \ -- comment 1
278 .. strB \ -- comment 2
279 .. strC
280
281func --[[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)
34AST_IMPL(ImportFrom) 34AST_IMPL(ImportFrom)
35AST_IMPL(ImportAs) 35AST_IMPL(ImportAs)
36AST_IMPL(Import) 36AST_IMPL(Import)
37AST_IMPL(Backcall)
37AST_IMPL(ExpListLow) 38AST_IMPL(ExpListLow)
38AST_IMPL(ExpList) 39AST_IMPL(ExpList)
39AST_IMPL(Return) 40AST_IMPL(Return)
@@ -59,6 +60,7 @@ AST_IMPL(Assign)
59AST_IMPL(update_op) 60AST_IMPL(update_op)
60AST_IMPL(Update) 61AST_IMPL(Update)
61AST_IMPL(BinaryOperator) 62AST_IMPL(BinaryOperator)
63AST_IMPL(BackcallOperator)
62AST_IMPL(Assignable) 64AST_IMPL(Assignable)
63AST_IMPL(AssignableChain) 65AST_IMPL(AssignableChain)
64AST_IMPL(exp_op_value) 66AST_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)
136AST_END(Import) 136AST_END(Import)
137 137
138class FnArgsDef_t;
139class ChainValue_t;
140
141AST_NODE(Backcall, "Backcall"_id)
142 ast_ptr<false, FnArgsDef_t> argsDef;
143 ast_ptr<true, ChainValue_t> value;
144 AST_MEMBER(Backcall, &argsDef, &value)
145AST_END(Backcall)
146
138AST_NODE(ExpListLow, "ExpListLow"_id) 147AST_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)
295AST_LEAF(BinaryOperator, "BinaryOperator"_id) 304AST_LEAF(BinaryOperator, "BinaryOperator"_id)
296AST_END(BinaryOperator) 305AST_END(BinaryOperator)
297 306
307AST_LEAF(BackcallOperator, "BackcallOperator"_id)
308AST_END(BackcallOperator)
309
298class AssignableChain_t; 310class AssignableChain_t;
299 311
300AST_NODE(Assignable, "Assignable"_id) 312AST_NODE(Assignable, "Assignable"_id)
@@ -305,7 +317,7 @@ AST_END(Assignable)
305class Value_t; 317class Value_t;
306 318
307AST_NODE(exp_op_value, "exp_op_value"_id) 319AST_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)
311AST_END(exp_op_value) 323AST_END(exp_op_value)
@@ -586,7 +598,7 @@ AST_END(BreakLoop)
586AST_NODE(Statement, "Statement"_id) 598AST_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)
592AST_END(Statement) 604AST_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();
37rule White = *(set(" \t") | Break); 37rule White = *(set(" \t") | Break);
38rule Stop = Break | eof(); 38rule Stop = Break | eof();
39rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); 39rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop);
40rule Indent = *set(" \t"); 40rule multi_line_open = expr("--[[");
41rule Space = plain_space >> -Comment; 41rule multi_line_close = expr("]]");
42rule multi_line_content = *(not_(multi_line_close) >> Any);
43rule MultiLineComment = multi_line_open >> multi_line_content >> multi_line_close;
44rule Indent = plain_space;
45rule EscapeNewLine = expr('\\') >> plain_space >> -Comment >> Break;
46rule Space = *(set(" \t") | MultiLineComment | EscapeNewLine) >> -Comment;
42rule SomeSpace = +set(" \t") >> -Comment; 47rule SomeSpace = +set(" \t") >> -Comment;
43rule SpaceBreak = Space >> Break; 48rule SpaceBreak = Space >> Break;
44rule EmptyLine = SpaceBreak; 49rule EmptyLine = SpaceBreak;
@@ -287,13 +292,15 @@ rule BinaryOperator =
287 expr("//") | 292 expr("//") |
288 set("+-*/%^><|&"); 293 set("+-*/%^><|&");
289 294
295rule BackcallOperator = expr("|>");
296
290extern rule AssignableChain; 297extern rule AssignableChain;
291 298
292rule Assignable = AssignableChain | Space >> Variable | SelfName; 299rule Assignable = AssignableChain | Space >> Variable | SelfName;
293 300
294extern rule Value; 301extern rule Value;
295 302
296rule exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> Value; 303rule exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value;
297rule Exp = Value >> *exp_op_value; 304rule Exp = Value >> *exp_op_value;
298 305
299extern rule Chain, Callable, InvokeArgs, existential_op; 306extern 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
337rule LuaStringContent = *(not_(LuaStringClose) >> (Break | Any)); 344rule LuaStringContent = *(not_(LuaStringClose) >> Any);
338 345
339rule LuaString = pl::user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) 346rule 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
474rule NameOrDestructure = Space >> Variable | TableLit; 481rule NameOrDestructure = Space >> Variable | TableLit;
475rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure); 482rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure);
476 483
484rule Backcall = -FnArgsDef >> Space >> symx("<-") >> Space >> ChainValue;
485
477rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp); 486rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp);
478rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp); 487rule 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