aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2021-04-19 18:10:08 +0800
committerLi Jin <dragon-fly@qq.com>2021-04-19 18:10:08 +0800
commit7ac784e73b026ce7e17babb2f0b819864fd898b0 (patch)
tree244a39123a4789a04fb577d6956bdb461509a153
parentce9f6632635222b38ef0b37b4b1273da4a1877b4 (diff)
downloadyuescript-7ac784e73b026ce7e17babb2f0b819864fd898b0.tar.gz
yuescript-7ac784e73b026ce7e17babb2f0b819864fd898b0.tar.bz2
yuescript-7ac784e73b026ce7e17babb2f0b819864fd898b0.zip
rename BackcallOperator to PipeOperator.
-rw-r--r--spec/inputs/backcall.yue84
-rw-r--r--spec/inputs/loops.yue2
-rw-r--r--spec/inputs/pipe.yue84
-rw-r--r--src/yuescript/yue_ast.h16
-rw-r--r--src/yuescript/yue_compiler.cpp52
-rw-r--r--src/yuescript/yue_parser.cpp16
-rw-r--r--src/yuescript/yue_parser.h8
-rw-r--r--src/yuescript/yuescript.h56
8 files changed, 176 insertions, 142 deletions
diff --git a/spec/inputs/backcall.yue b/spec/inputs/backcall.yue
index bad3a56..d7ed0dd 100644
--- a/spec/inputs/backcall.yue
+++ b/spec/inputs/backcall.yue
@@ -1,77 +1,3 @@
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
17with b |> create? "new"
18 .value = 123
19 print \work!
20
21123 |> f?
22
23"abc" |> f1? |> f2?
24
25c = "abc" |> f1? |> f2?
26
27f = ->
28 arg |> x.y?\if
29
30998 |> func2 "abc", 233 |> func0 |> func1
31998 |> func0("abc", 233) |> func1 |> func2
32
331 |> f 2, 3, 4, 5
34val(2) |> f 1, _, 3, 4, 5
35arr[3] |> f 1, 2, _, 4, 5
36
37a = {"1","2","3"} |> table.concat("") |> tonumber |> f1(1, 2, 3, _) |> f2(1, _, 3)
38
39readFile("example.txt") |>
40 extract(_, language, {}) |>
41 parse(_, language) |>
42 emit |>
43 render |>
44 print
45
46readFile("example.txt") \
47 |> extract(_, language, {}) \
48 |> parse(_, language) \
49 |> emit \
50 |> render \
51 |> print
52
53readFile "example.txt"
54 |> extract _, language, {}
55 |> parse _, language
56 |> emit
57 |> render
58 |> print
59
60123 |> not func! |> f
61
62do
63 _1 = list{"abc","xyz","123"}\map"#"\value!
64 |> -func!
65 |> abc 123, _, "x"
66
67 global _2,_3,_4 = 1,2,3
68 |> f
69
70 local _5 = v |> f1 1
71 |> f2 2
72 |> f3 3
73 |> f4 4
74
75do 1do
76 (x)<- map {1,2,3} 2 (x)<- map {1,2,3}
77 x * 2 3 x * 2
@@ -96,7 +22,7 @@ do
96 22
97do 23do
98 <- syncStatus 24 <- syncStatus
99 (err,data="nil")<- loadAsync "file.moon" 25 (err, data="nil")<- loadAsync "file.yue"
100 if err 26 if err
101 print err 27 print err
102 return 28 return
@@ -141,13 +67,5 @@ propB = do
141 67
142alert "hi" 68alert "hi"
143 69
144x = 123 |> a |> b or 456 |> c |> d or a.if\then("abc") or a?.b\c?(123) or x\y
145
146x1 = 3 * -4 |> f
147
148x2 = 3 * -2 ^ 2 |> f
149
150y = 1 + not # 2 |> (a ^ c) |> b(3,_) * 4 ^ -123 |> f |> f1 or 123
151
152nil 70nil
153 71
diff --git a/spec/inputs/loops.yue b/spec/inputs/loops.yue
index 8946a2f..5708809 100644
--- a/spec/inputs/loops.yue
+++ b/spec/inputs/loops.yue
@@ -30,6 +30,8 @@ for x in y, z
30for x in y, z, k 30for x in y, z, k
31 print x 31 print x
32 32
33for name, members in *modules
34 print name, member
33 35
34x = -> 36x = ->
35 for x in y 37 for x in y
diff --git a/spec/inputs/pipe.yue b/spec/inputs/pipe.yue
new file mode 100644
index 0000000..7e33422
--- /dev/null
+++ b/spec/inputs/pipe.yue
@@ -0,0 +1,84 @@
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
17with b |> create? "new"
18 .value = 123
19 print \work!
20
21123 |> f?
22
23"abc" |> f1? |> f2?
24
25c = "abc" |> f1? |> f2?
26
27f = ->
28 arg |> x.y?\if
29
30998 |> func2 "abc", 233 |> func0 |> func1
31998 |> func0("abc", 233) |> func1 |> func2
32
331 |> f 2, 3, 4, 5
34val(2) |> f 1, _, 3, 4, 5
35arr[3] |> f 1, 2, _, 4, 5
36
37a = {"1","2","3"} |> table.concat("") |> tonumber |> f1(1, 2, 3, _) |> f2(1, _, 3)
38
39readFile("example.txt") |>
40 extract(_, language, {}) |>
41 parse(_, language) |>
42 emit |>
43 render |>
44 print
45
46readFile("example.txt") \
47 |> extract(_, language, {}) \
48 |> parse(_, language) \
49 |> emit \
50 |> render \
51 |> print
52
53readFile "example.txt"
54 |> extract _, language, {}
55 |> parse _, language
56 |> emit
57 |> render
58 |> print
59
60123 |> not func! |> f
61
62do
63 _1 = list{"abc","xyz","123"}\map"#"\value!
64 |> -func!
65 |> abc 123, _, "x"
66
67 global _2,_3,_4 = 1,2,3
68 |> f
69
70 local _5 = v |> f1 1
71 |> f2 2
72 |> f3 3
73 |> f4 4
74
75x = 123 |> a |> b or 456 |> c |> d or a.if\then("abc") or a?.b\c?(123) or x\y
76
77x1 = 3 * -4 |> f
78
79x2 = 3 * -2 ^ 2 |> f
80
81y = 1 + not # 2 |> (a ^ c) |> b(3,_) * 4 ^ -123 |> f |> f1 or 123
82
83nil
84
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index 4c33759..1e95d11 100644
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -391,15 +391,15 @@ class unary_exp_t;
391 391
392AST_NODE(exp_op_value) 392AST_NODE(exp_op_value)
393 ast_ptr<true, BinaryOperator_t> op; 393 ast_ptr<true, BinaryOperator_t> op;
394 ast_list<true, unary_exp_t> backcalls; 394 ast_list<true, unary_exp_t> pipeExprs;
395 AST_MEMBER(exp_op_value, &op, &backcalls) 395 AST_MEMBER(exp_op_value, &op, &pipeExprs)
396AST_END(exp_op_value) 396AST_END(exp_op_value)
397 397
398AST_NODE(Exp) 398AST_NODE(Exp)
399 ast_ptr<true, Seperator_t> sep; 399 ast_ptr<true, Seperator_t> sep;
400 ast_list<true, unary_exp_t> backcalls; 400 ast_list<true, unary_exp_t> pipeExprs;
401 ast_list<false, exp_op_value_t> opValues; 401 ast_list<false, exp_op_value_t> opValues;
402 AST_MEMBER(Exp, &sep, &backcalls, &opValues) 402 AST_MEMBER(Exp, &sep, &pipeExprs, &opValues)
403AST_END(Exp) 403AST_END(Exp)
404 404
405class Parens_t; 405class Parens_t;
@@ -727,11 +727,11 @@ AST_END(unless_line)
727AST_LEAF(BreakLoop) 727AST_LEAF(BreakLoop)
728AST_END(BreakLoop) 728AST_END(BreakLoop)
729 729
730AST_NODE(BackcallBody) 730AST_NODE(PipeBody)
731 ast_ptr<true, Seperator_t> sep; 731 ast_ptr<true, Seperator_t> sep;
732 ast_list<true, unary_exp_t> values; 732 ast_list<true, unary_exp_t> values;
733 AST_MEMBER(BackcallBody, &sep, &values) 733 AST_MEMBER(PipeBody, &sep, &values)
734AST_END(BackcallBody) 734AST_END(PipeBody)
735 735
736AST_NODE(statement_appendix) 736AST_NODE(statement_appendix)
737 ast_sel<true, if_line_t, unless_line_t, CompInner_t> item; 737 ast_sel<true, if_line_t, unless_line_t, CompInner_t> item;
@@ -744,7 +744,7 @@ AST_END(statement_sep)
744AST_NODE(Statement) 744AST_NODE(Statement)
745 ast_sel<true, Import_t, While_t, Repeat_t, For_t, ForEach_t, 745 ast_sel<true, Import_t, While_t, Repeat_t, For_t, ForEach_t,
746 Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t, 746 Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t,
747 Label_t, Goto_t, Backcall_t, LocalAttrib_t, BackcallBody_t, ExpListAssign_t> content; 747 Label_t, Goto_t, Backcall_t, LocalAttrib_t, PipeBody_t, ExpListAssign_t> content;
748 ast_ptr<false, statement_appendix_t> appendix; 748 ast_ptr<false, statement_appendix_t> appendix;
749 ast_ptr<false, statement_sep_t> needSep; 749 ast_ptr<false, statement_sep_t> needSep;
750 AST_MEMBER(Statement, &content, &appendix, &needSep) 750 AST_MEMBER(Statement, &content, &appendix, &needSep)
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index caa5b9e..85744d5 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -59,7 +59,7 @@ inline std::string s(std::string_view sv) {
59 return std::string(sv); 59 return std::string(sv);
60} 60}
61 61
62const std::string_view version = "0.7.6"sv; 62const std::string_view version = "0.7.7"sv;
63const std::string_view extension = "yue"sv; 63const std::string_view extension = "yue"sv;
64 64
65class YueCompilerImpl { 65class YueCompilerImpl {
@@ -467,8 +467,8 @@ private:
467 if (!exp) return nullptr; 467 if (!exp) return nullptr;
468 BLOCK_START 468 BLOCK_START
469 BREAK_IF(!exp->opValues.empty()); 469 BREAK_IF(!exp->opValues.empty());
470 BREAK_IF(exp->backcalls.size() != 1); 470 BREAK_IF(exp->pipeExprs.size() != 1);
471 auto unary = static_cast<unary_exp_t*>(exp->backcalls.back()); 471 auto unary = static_cast<unary_exp_t*>(exp->pipeExprs.back());
472 BREAK_IF(unary->expos.size() != 1); 472 BREAK_IF(unary->expos.size() != 1);
473 return unary; 473 return unary;
474 BLOCK_END 474 BLOCK_END
@@ -488,7 +488,7 @@ private:
488 auto unary = x->new_ptr<unary_exp_t>(); 488 auto unary = x->new_ptr<unary_exp_t>();
489 unary->expos.push_back(value); 489 unary->expos.push_back(value);
490 auto exp = x->new_ptr<Exp_t>(); 490 auto exp = x->new_ptr<Exp_t>();
491 exp->backcalls.push_back(unary); 491 exp->pipeExprs.push_back(unary);
492 return exp; 492 return exp;
493 } 493 }
494 494
@@ -500,17 +500,17 @@ private:
500 auto runary = x->new_ptr<unary_exp_t>(); 500 auto runary = x->new_ptr<unary_exp_t>();
501 runary->expos.push_back(right); 501 runary->expos.push_back(right);
502 opValue->op.set(op); 502 opValue->op.set(op);
503 opValue->backcalls.push_back(runary); 503 opValue->pipeExprs.push_back(runary);
504 } 504 }
505 auto exp = x->new_ptr<Exp_t>(); 505 auto exp = x->new_ptr<Exp_t>();
506 exp->backcalls.push_back(lunary); 506 exp->pipeExprs.push_back(lunary);
507 exp->opValues.push_back(opValue); 507 exp->opValues.push_back(opValue);
508 return exp; 508 return exp;
509 } 509 }
510 510
511 ast_ptr<false, Exp_t> newExp(unary_exp_t* unary, ast_node* x) { 511 ast_ptr<false, Exp_t> newExp(unary_exp_t* unary, ast_node* x) {
512 auto exp = x->new_ptr<Exp_t>(); 512 auto exp = x->new_ptr<Exp_t>();
513 exp->backcalls.push_back(unary); 513 exp->pipeExprs.push_back(unary);
514 return exp; 514 return exp;
515 } 515 }
516 516
@@ -785,7 +785,7 @@ private:
785 } 785 }
786 786
787 bool isPureBackcall(Exp_t* exp) const { 787 bool isPureBackcall(Exp_t* exp) const {
788 return exp->opValues.empty() && exp->backcalls.size() > 1; 788 return exp->opValues.empty() && exp->pipeExprs.size() > 1;
789 } 789 }
790 790
791 bool isMacroChain(ChainValue_t* chainValue) const { 791 bool isMacroChain(ChainValue_t* chainValue) const {
@@ -923,7 +923,7 @@ private:
923 case id<Label_t>(): transformLabel(static_cast<Label_t*>(content), out); break; 923 case id<Label_t>(): transformLabel(static_cast<Label_t*>(content), out); break;
924 case id<Goto_t>(): transformGoto(static_cast<Goto_t*>(content), out); break; 924 case id<Goto_t>(): transformGoto(static_cast<Goto_t*>(content), out); break;
925 case id<LocalAttrib_t>(): transformLocalAttrib(static_cast<LocalAttrib_t*>(content), out); break; 925 case id<LocalAttrib_t>(): transformLocalAttrib(static_cast<LocalAttrib_t*>(content), out); break;
926 case id<BackcallBody_t>(): throw std::logic_error(_info.errorMessage("backcall chain must be following a value"sv, x)); break; 926 case id<PipeBody_t>(): throw std::logic_error(_info.errorMessage("pipe chain must be following a value"sv, x)); break;
927 case id<ExpListAssign_t>(): { 927 case id<ExpListAssign_t>(): {
928 auto expListAssign = static_cast<ExpListAssign_t*>(content); 928 auto expListAssign = static_cast<ExpListAssign_t*>(content);
929 if (expListAssign->action) { 929 if (expListAssign->action) {
@@ -1955,7 +1955,7 @@ private:
1955 out.push_back(join(temp, ", "sv)); 1955 out.push_back(join(temp, ", "sv));
1956 } 1956 }
1957 1957
1958 void transform_backcall_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 1958 void transform_pipe_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
1959 if (values.size() == 1 && usage == ExpUsage::Closure) { 1959 if (values.size() == 1 && usage == ExpUsage::Closure) {
1960 transform_unary_exp(static_cast<unary_exp_t*>(values.front()), out); 1960 transform_unary_exp(static_cast<unary_exp_t*>(values.front()), out);
1961 } else { 1961 } else {
@@ -1968,7 +1968,7 @@ private:
1968 if (values.back() == *it && !unary->ops.empty() && usage == ExpUsage::Common) { 1968 if (values.back() == *it && !unary->ops.empty() && usage == ExpUsage::Common) {
1969 throw std::logic_error(_info.errorMessage("expression list is not supported here"sv, x)); 1969 throw std::logic_error(_info.errorMessage("expression list is not supported here"sv, x));
1970 } 1970 }
1971 if (!value) throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, *it)); 1971 if (!value) throw std::logic_error(_info.errorMessage("pipe operator must be followed by chain value"sv, *it));
1972 if (auto chainValue = value->item.as<ChainValue_t>()) { 1972 if (auto chainValue = value->item.as<ChainValue_t>()) {
1973 if (isChainValueCall(chainValue)) { 1973 if (isChainValueCall(chainValue)) {
1974 auto last = chainValue->items.back(); 1974 auto last = chainValue->items.back();
@@ -1989,7 +1989,7 @@ private:
1989 args->swap(a, arg); 1989 args->swap(a, arg);
1990 findPlaceHolder = true; 1990 findPlaceHolder = true;
1991 } else { 1991 } else {
1992 throw std::logic_error(_info.errorMessage("backcall placeholder can be used only in one place"sv, a)); 1992 throw std::logic_error(_info.errorMessage("pipe placeholder can be used only in one place"sv, a));
1993 } 1993 }
1994 } 1994 }
1995 } 1995 }
@@ -2003,7 +2003,7 @@ private:
2003 } 2003 }
2004 arg.set(newExp(unary, x)); 2004 arg.set(newExp(unary, x));
2005 } else { 2005 } else {
2006 throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, value)); 2006 throw std::logic_error(_info.errorMessage("pipe operator must be followed by chain value"sv, value));
2007 } 2007 }
2008 } 2008 }
2009 switch (usage) { 2009 switch (usage) {
@@ -2046,18 +2046,18 @@ private:
2046 2046
2047 void transformExp(Exp_t* exp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 2047 void transformExp(Exp_t* exp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
2048 if (exp->opValues.empty()) { 2048 if (exp->opValues.empty()) {
2049 transform_backcall_exp(exp->backcalls.objects(), out, usage, assignList); 2049 transform_pipe_exp(exp->pipeExprs.objects(), out, usage, assignList);
2050 return; 2050 return;
2051 } 2051 }
2052 if (usage != ExpUsage::Closure) { 2052 if (usage != ExpUsage::Closure) {
2053 YUEE("invalid expression usage", exp); 2053 YUEE("invalid expression usage", exp);
2054 } 2054 }
2055 str_list temp; 2055 str_list temp;
2056 transform_backcall_exp(exp->backcalls.objects(), temp, ExpUsage::Closure); 2056 transform_pipe_exp(exp->pipeExprs.objects(), temp, ExpUsage::Closure);
2057 for (auto _opValue : exp->opValues.objects()) { 2057 for (auto _opValue : exp->opValues.objects()) {
2058 auto opValue = static_cast<exp_op_value_t*>(_opValue); 2058 auto opValue = static_cast<exp_op_value_t*>(_opValue);
2059 transformBinaryOperator(opValue->op, temp); 2059 transformBinaryOperator(opValue->op, temp);
2060 transform_backcall_exp(opValue->backcalls.objects(), temp, ExpUsage::Closure); 2060 transform_pipe_exp(opValue->pipeExprs.objects(), temp, ExpUsage::Closure);
2061 } 2061 }
2062 out.push_back(join(temp, " "sv)); 2062 out.push_back(join(temp, " "sv));
2063 } 2063 }
@@ -2206,7 +2206,7 @@ private:
2206 for (auto it = nodes.begin(); it != nodes.end(); ++it) { 2206 for (auto it = nodes.begin(); it != nodes.end(); ++it) {
2207 auto node = *it; 2207 auto node = *it;
2208 auto stmt = static_cast<Statement_t*>(node); 2208 auto stmt = static_cast<Statement_t*>(node);
2209 if (auto backcallBody = stmt->content.as<BackcallBody_t>()) { 2209 if (auto pipeBody = stmt->content.as<PipeBody_t>()) {
2210 auto x = stmt; 2210 auto x = stmt;
2211 bool cond = false; 2211 bool cond = false;
2212 BLOCK_START 2212 BLOCK_START
@@ -2214,7 +2214,7 @@ private:
2214 auto last = it; --last; 2214 auto last = it; --last;
2215 auto lst = static_cast<Statement_t*>(*last); 2215 auto lst = static_cast<Statement_t*>(*last);
2216 if (lst->appendix) { 2216 if (lst->appendix) {
2217 throw std::logic_error(_info.errorMessage("statement decorator must be placed at the end of backcall chain"sv, lst->appendix.get())); 2217 throw std::logic_error(_info.errorMessage("statement decorator must be placed at the end of pipe chain"sv, lst->appendix.get()));
2218 } 2218 }
2219 lst->appendix.set(stmt->appendix); 2219 lst->appendix.set(stmt->appendix);
2220 stmt->appendix.set(nullptr); 2220 stmt->appendix.set(nullptr);
@@ -2222,18 +2222,18 @@ private:
2222 stmt->needSep.set(nullptr); 2222 stmt->needSep.set(nullptr);
2223 auto exp = lastExpFromStatement(lst); 2223 auto exp = lastExpFromStatement(lst);
2224 BREAK_IF(!exp); 2224 BREAK_IF(!exp);
2225 for (auto val : backcallBody->values.objects()) { 2225 for (auto val : pipeBody->values.objects()) {
2226 exp->backcalls.push_back(val); 2226 exp->pipeExprs.push_back(val);
2227 } 2227 }
2228 cond = true; 2228 cond = true;
2229 BLOCK_END 2229 BLOCK_END
2230 if (!cond) throw std::logic_error(_info.errorMessage("backcall chain must be following a value"sv, x)); 2230 if (!cond) throw std::logic_error(_info.errorMessage("pipe chain must be following a value"sv, x));
2231 stmt->content.set(nullptr); 2231 stmt->content.set(nullptr);
2232 auto next = it; ++next; 2232 auto next = it; ++next;
2233 BLOCK_START 2233 BLOCK_START
2234 BREAK_IF(next == nodes.end()); 2234 BREAK_IF(next == nodes.end());
2235 BREAK_IF(!static_cast<Statement_t*>(*next)->content.as<BackcallBody_t>()); 2235 BREAK_IF(!static_cast<Statement_t*>(*next)->content.as<PipeBody_t>());
2236 throw std::logic_error(_info.errorMessage("indent mismatch in backcall chain"sv, *next)); 2236 throw std::logic_error(_info.errorMessage("indent mismatch in pipe chain"sv, *next));
2237 BLOCK_END 2237 BLOCK_END
2238 } else if (auto backcall = stmt->content.as<Backcall_t>()) { 2238 } else if (auto backcall = stmt->content.as<Backcall_t>()) {
2239 auto x = *nodes.begin(); 2239 auto x = *nodes.begin();
@@ -3513,7 +3513,7 @@ private:
3513 for (auto arg : *args) { 3513 for (auto arg : *args) {
3514 std::string str; 3514 std::string str;
3515 // check whether arg is reassembled 3515 // check whether arg is reassembled
3516 // do some workaround for backcall expression 3516 // do some workaround for pipe expression
3517 if (ast_is<Exp_t>(arg) && arg->m_begin.m_it == arg->m_end.m_it) { 3517 if (ast_is<Exp_t>(arg) && arg->m_begin.m_it == arg->m_end.m_it) {
3518 auto exp = static_cast<Exp_t*>(arg); 3518 auto exp = static_cast<Exp_t*>(arg);
3519 BLOCK_START 3519 BLOCK_START
@@ -3525,10 +3525,10 @@ private:
3525 str = std::get<1>(expandMacroStr(chainValue)); 3525 str = std::get<1>(expandMacroStr(chainValue));
3526 BLOCK_END 3526 BLOCK_END
3527 if (str.empty()) { 3527 if (str.empty()) {
3528 // exp is reassembled due to backcall expressions 3528 // exp is reassembled due to pipe expressions
3529 // in transform stage, toString(exp) won't be able 3529 // in transform stage, toString(exp) won't be able
3530 // to convert its whole text content 3530 // to convert its whole text content
3531 str = _parser.toString(exp->backcalls.front()); 3531 str = _parser.toString(exp->pipeExprs.front());
3532 } 3532 }
3533 } else if (auto lstr = ast_cast<LuaString_t>(arg)) { 3533 } else if (auto lstr = ast_cast<LuaString_t>(arg)) {
3534 str = _parser.toString(lstr->content); 3534 str = _parser.toString(lstr->content);
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index c76b574..30c5598 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -333,9 +333,9 @@ YueParser::YueParser() {
333 expr("not") >> not_(AlphaNum); 333 expr("not") >> not_(AlphaNum);
334 unary_exp = *(Space >> unary_operator) >> expo_exp; 334 unary_exp = *(Space >> unary_operator) >> expo_exp;
335 335
336 BackcallOperator = expr("|>"); 336 PipeOperator = expr("|>");
337 backcall_value = Space >> BackcallOperator >> *SpaceBreak >> unary_exp; 337 pipe_value = Space >> PipeOperator >> *SpaceBreak >> unary_exp;
338 backcall_exp = unary_exp >> *backcall_value; 338 pipe_exp = unary_exp >> *pipe_value;
339 339
340 BinaryOperator = 340 BinaryOperator =
341 (expr("or") >> not_(AlphaNum)) | 341 (expr("or") >> not_(AlphaNum)) |
@@ -350,8 +350,8 @@ YueParser::YueParser() {
350 expr(">>") | 350 expr(">>") |
351 expr("//") | 351 expr("//") |
352 set("+-*/%><|&~"); 352 set("+-*/%><|&~");
353 exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> backcall_exp; 353 exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> pipe_exp;
354 Exp = Seperator >> backcall_exp >> *exp_op_value; 354 Exp = Seperator >> pipe_exp >> *exp_op_value;
355 355
356 DisableChain = pl::user(true_(), [](const item_t& item) { 356 DisableChain = pl::user(true_(), [](const item_t& item) {
357 State* st = reinterpret_cast<State*>(item.user_data); 357 State* st = reinterpret_cast<State*>(item.user_data);
@@ -563,7 +563,7 @@ YueParser::YueParser() {
563 fn_arrow_back = expr('<') >> set("-="); 563 fn_arrow_back = expr('<') >> set("-=");
564 Backcall = -FnArgsDef >> Space >> fn_arrow_back >> Space >> ChainValue; 564 Backcall = -FnArgsDef >> Space >> fn_arrow_back >> Space >> ChainValue;
565 565
566 BackcallBody = Seperator >> Space >> BackcallOperator >> unary_exp >> *(+SpaceBreak >> CheckIndent >> Space >> BackcallOperator >> unary_exp); 566 PipeBody = Seperator >> Space >> PipeOperator >> unary_exp >> *(+SpaceBreak >> CheckIndent >> Space >> PipeOperator >> unary_exp);
567 567
568 ExpList = Seperator >> Exp >> *(sym(',') >> Exp); 568 ExpList = Seperator >> Exp >> *(sym(',') >> Exp);
569 ExpListLow = Seperator >> Exp >> *(Space >> set(",;") >> Exp); 569 ExpListLow = Seperator >> Exp >> *(Space >> set(",;") >> Exp);
@@ -605,14 +605,14 @@ YueParser::YueParser() {
605 Import | While | Repeat | For | ForEach | 605 Import | While | Repeat | For | ForEach |
606 Return | Local | Global | Export | Macro | 606 Return | Local | Global | Export | Macro |
607 Space >> BreakLoop | Label | Goto | Backcall | 607 Space >> BreakLoop | Label | Goto | Backcall |
608 LocalAttrib | BackcallBody | ExpListAssign 608 LocalAttrib | PipeBody | ExpListAssign
609 ) >> Space >> 609 ) >> Space >>
610 -statement_appendix >> -statement_sep; 610 -statement_appendix >> -statement_sep;
611 611
612 Body = InBlock | Statement; 612 Body = InBlock | Statement;
613 613
614 empty_line_stop = Space >> and_(Break); 614 empty_line_stop = Space >> and_(Break);
615 Line = and_(check_indent >> Space >> not_(BackcallOperator)) >> Statement | Advance >> ensure(and_(Space >> BackcallOperator) >> Statement, PopIndent) | empty_line_stop; 615 Line = and_(check_indent >> Space >> not_(PipeOperator)) >> Statement | Advance >> ensure(and_(Space >> PipeOperator) >> Statement, PopIndent) | empty_line_stop;
616 Block = Seperator >> Line >> *(+Break >> Line); 616 Block = Seperator >> Line >> *(+Break >> Line);
617 617
618 Shebang = expr("#!") >> *(not_(Stop) >> Any); 618 Shebang = expr("#!") >> *(not_(Stop) >> Any);
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index a614d01..cb9cfba 100644
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -175,10 +175,10 @@ private:
175 rule ArgLine; 175 rule ArgLine;
176 rule ArgBlock; 176 rule ArgBlock;
177 rule invoke_args_with_table; 177 rule invoke_args_with_table;
178 rule BackcallOperator; 178 rule PipeOperator;
179 rule ExponentialOperator; 179 rule ExponentialOperator;
180 rule backcall_value; 180 rule pipe_value;
181 rule backcall_exp; 181 rule pipe_exp;
182 rule expo_value; 182 rule expo_value;
183 rule expo_exp; 183 rule expo_exp;
184 rule empty_line_stop; 184 rule empty_line_stop;
@@ -216,7 +216,7 @@ private:
216 AST_RULE(Goto) 216 AST_RULE(Goto)
217 AST_RULE(fn_arrow_back) 217 AST_RULE(fn_arrow_back)
218 AST_RULE(Backcall) 218 AST_RULE(Backcall)
219 AST_RULE(BackcallBody) 219 AST_RULE(PipeBody)
220 AST_RULE(ExpListLow) 220 AST_RULE(ExpListLow)
221 AST_RULE(ExpList) 221 AST_RULE(ExpList)
222 AST_RULE(Return) 222 AST_RULE(Return)
diff --git a/src/yuescript/yuescript.h b/src/yuescript/yuescript.h
index cdbfd57..6fc9c20 100644
--- a/src/yuescript/yuescript.h
+++ b/src/yuescript/yuescript.h
@@ -214,18 +214,48 @@ setmetatable(yue, {
214 return self.require(name) 214 return self.require(name)
215 end 215 end
216}) 216})
217for k, v in pairs({ 217local function dump(what)
218 insert_loader = insert_loader, 218 local seen = { }
219 remove_loader = remove_loader, 219 local _dump
220 loader = yue_loader, 220 _dump = function(what, depth)
221 dofile = dofile, 221 depth = depth or 0
222 loadfile = loadfile, 222 local t = type(what)
223 loadstring = loadstring, 223 if "string" == t then
224 create_yuepath = create_yuepath, 224 return "\"" .. tostring(what) .. "\"\n"
225 find_modulepath = find_modulepath, 225 elseif "table" == t then
226 pcall = yue_call, 226 if seen[what] then
227 require = yue_require 227 return "recursion(" .. tostring(what) .. ")...\n"
228}) do 228 end
229 yue[k] = v 229 seen[what] = true
230 depth = depth + 1
231 local lines = {}
232 for k, v in pairs(what) do
233 insert(lines, ('\t'):rep(depth) .. "[" .. tostring(k) .. "] = " .. _dump(v, depth))
234 end
235 seen[what] = false
236 return "{\n" .. concat(lines) .. ('\t'):rep(depth - 1) .. "}\n"
237 else
238 return tostring(what) .. "\n"
239 end
240 end
241 return _dump(what)
242end
243local function p(...)
244 local args = {...}
245 for i = 1, #args do
246 args[i] = dump(args[i])
247 end
248 print(concat(args))
230end 249end
250yue.insert_loader = insert_loader
251yue.remove_loader = remove_loader
252yue.loader = yue_loader
253yue.dofile = dofile
254yue.loadfile = loadfile
255yue.loadstring = loadstring
256yue.create_yuepath = create_yuepath
257yue.find_modulepath = find_modulepath
258yue.pcall = yue_call
259yue.require = yue_require
260yue.p = p
231)yuescript_codes"; 261)yuescript_codes";