aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2021-02-10 14:34:08 +0800
committerLi Jin <dragon-fly@qq.com>2021-02-10 20:50:03 +0800
commitc68e11bc6d7631185749aaf0c8d89147b3ac9cc9 (patch)
treee91306fa43513f7a66022ba16abbc224a91c8bd5
parent9f622c5bbd9cfb7e66a9fd3c371461af4249d566 (diff)
downloadyuescript-c68e11bc6d7631185749aaf0c8d89147b3ac9cc9.tar.gz
yuescript-c68e11bc6d7631185749aaf0c8d89147b3ac9cc9.tar.bz2
yuescript-c68e11bc6d7631185749aaf0c8d89147b3ac9cc9.zip
update backcall operator syntax, fix issue #31.
-rw-r--r--spec/inputs/backcall.mp28
-rw-r--r--src/MoonP/moon_ast.h8
-rw-r--r--src/MoonP/moon_compiler.cpp104
-rw-r--r--src/MoonP/moon_parser.cpp8
-rw-r--r--src/MoonP/moon_parser.h1
5 files changed, 134 insertions, 15 deletions
diff --git a/spec/inputs/backcall.mp b/spec/inputs/backcall.mp
index a648b16..0d52f3f 100644
--- a/spec/inputs/backcall.mp
+++ b/spec/inputs/backcall.mp
@@ -2,9 +2,9 @@
2{"abc", 123, 998} |> foreach print 2{"abc", 123, 998} |> foreach print
3 3
4{1,2,3} 4{1,2,3}
5 |> map((x)-> x * 2) 5 |> map (x)-> x * 2
6 |> filter((x)-> x > 4) 6 |> filter (x)-> x > 4
7 |> reduce(0, (a,b)-> a + b) 7 |> reduce 0, (a,b)-> a + b
8 |> print 8 |> print
9 9
10[i |> tostring for i = 0,10] |> table.concat(",") |> print 10[i |> tostring for i = 0,10] |> table.concat(",") |> print
@@ -36,6 +36,28 @@ arr[3] |> f 1, 2, _, 4, 5
36 36
37a = {"1","2","3"} |> table.concat("") |> tonumber |> f1(1, 2, 3, _) |> f2(1, _, 3) 37a = {"1","2","3"} |> table.concat("") |> tonumber |> f1(1, 2, 3, _) |> f2(1, _, 3)
38 38
39readFile "example.txt"
40 |> extract _, language, {}
41 |> parse _, language
42 |> emit
43 |> render
44 |> print
45
46123 |> not func! |> f
47
48do
49 _1 = list{"abc","xyz","123"}\map"#"\value!
50 |> -func!
51 |> abc 123, _, "x"
52
53 global _2,_3,_4 = 1,2,3
54 |> f
55
56 local _5 = v |> f1 1
57 |> f2 2
58 |> f3 3
59 |> f4 4
60
39do 61do
40 (x)<- map {1,2,3} 62 (x)<- map {1,2,3}
41 x * 2 63 x * 2
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h
index d00d855..2f5123b 100644
--- a/src/MoonP/moon_ast.h
+++ b/src/MoonP/moon_ast.h
@@ -701,6 +701,12 @@ AST_END(unless_line)
701AST_LEAF(BreakLoop) 701AST_LEAF(BreakLoop)
702AST_END(BreakLoop) 702AST_END(BreakLoop)
703 703
704AST_NODE(BackcallBody)
705 ast_ptr<true, Seperator_t> sep;
706 ast_list<true, unary_exp_t> values;
707 AST_MEMBER(BackcallBody, &sep, &values)
708AST_END(BackcallBody)
709
704AST_NODE(statement_appendix) 710AST_NODE(statement_appendix)
705 ast_sel<true, if_line_t, unless_line_t, CompInner_t> item; 711 ast_sel<true, if_line_t, unless_line_t, CompInner_t> item;
706 AST_MEMBER(statement_appendix, &item) 712 AST_MEMBER(statement_appendix, &item)
@@ -712,7 +718,7 @@ AST_END(statement_sep)
712AST_NODE(Statement) 718AST_NODE(Statement)
713 ast_sel<true, Import_t, While_t, Repeat_t, For_t, ForEach_t, 719 ast_sel<true, Import_t, While_t, Repeat_t, For_t, ForEach_t,
714 Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t, 720 Return_t, Local_t, Global_t, Export_t, Macro_t, BreakLoop_t,
715 Label_t, Goto_t, Backcall_t, LocalAttrib_t, ExpListAssign_t> content; 721 Label_t, Goto_t, Backcall_t, LocalAttrib_t, BackcallBody_t, ExpListAssign_t> content;
716 ast_ptr<false, statement_appendix_t> appendix; 722 ast_ptr<false, statement_appendix_t> appendix;
717 ast_ptr<false, statement_sep_t> needSep; 723 ast_ptr<false, statement_sep_t> needSep;
718 AST_MEMBER(Statement, &content, &appendix, &needSep) 724 AST_MEMBER(Statement, &content, &appendix, &needSep)
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp
index 73bbd60..11d4ed8 100644
--- a/src/MoonP/moon_compiler.cpp
+++ b/src/MoonP/moon_compiler.cpp
@@ -53,7 +53,7 @@ inline std::string s(std::string_view sv) {
53 return std::string(sv); 53 return std::string(sv);
54} 54}
55 55
56const std::string_view version = "0.5.2"sv; 56const std::string_view version = "0.6.0"sv;
57const std::string_view extension = "mp"sv; 57const std::string_view extension = "mp"sv;
58 58
59class MoonCompilerImpl { 59class MoonCompilerImpl {
@@ -429,7 +429,7 @@ private:
429 return result; 429 return result;
430 } 430 }
431 431
432 Value_t* singleValueFrom(ast_node* item) const { 432 unary_exp_t* singleUnaryExpFrom(ast_node* item) const {
433 Exp_t* exp = nullptr; 433 Exp_t* exp = nullptr;
434 switch (item->getId()) { 434 switch (item->getId()) {
435 case id<Exp_t>(): 435 case id<Exp_t>():
@@ -451,8 +451,8 @@ private:
451 } 451 }
452 case id<unary_exp_t>(): { 452 case id<unary_exp_t>(): {
453 auto unary = static_cast<unary_exp_t*>(item); 453 auto unary = static_cast<unary_exp_t*>(item);
454 if (unary->ops.empty() && unary->expos.size() == 1) { 454 if (unary->expos.size() == 1) {
455 return static_cast<Value_t*>(unary->expos.back()); 455 return unary;
456 } 456 }
457 return nullptr; 457 return nullptr;
458 } 458 }
@@ -463,13 +463,21 @@ private:
463 BREAK_IF(!exp->opValues.empty()); 463 BREAK_IF(!exp->opValues.empty());
464 BREAK_IF(exp->backcalls.size() != 1); 464 BREAK_IF(exp->backcalls.size() != 1);
465 auto unary = static_cast<unary_exp_t*>(exp->backcalls.back()); 465 auto unary = static_cast<unary_exp_t*>(exp->backcalls.back());
466 BREAK_IF(!unary->ops.empty());
467 BREAK_IF(unary->expos.size() != 1); 466 BREAK_IF(unary->expos.size() != 1);
468 return static_cast<Value_t*>(unary->expos.back()); 467 return unary;
469 BLOCK_END 468 BLOCK_END
470 return nullptr; 469 return nullptr;
471 } 470 }
472 471
472 Value_t* singleValueFrom(ast_node* item) const {
473 if (auto unary = singleUnaryExpFrom(item)) {
474 if (unary->ops.empty()) {
475 return static_cast<Value_t*>(unary->expos.back());
476 }
477 }
478 return nullptr;
479 }
480
473 ast_ptr<false, Exp_t> newExp(Value_t* value, ast_node* x) { 481 ast_ptr<false, Exp_t> newExp(Value_t* value, ast_node* x) {
474 auto unary = x->new_ptr<unary_exp_t>(); 482 auto unary = x->new_ptr<unary_exp_t>();
475 unary->expos.push_back(value); 483 unary->expos.push_back(value);
@@ -522,6 +530,60 @@ private:
522 return stmts.empty() ? nullptr : static_cast<Statement_t*>(stmts.back()); 530 return stmts.empty() ? nullptr : static_cast<Statement_t*>(stmts.back());
523 } 531 }
524 532
533 Exp_t* lastExpFromAssign(ast_node* action) {
534 switch (action->getId()) {
535 case id<Update_t>(): {
536 auto update = static_cast<Update_t*>(action);
537 return update->value;
538 }
539 case id<Assign_t>(): {
540 auto assign = static_cast<Assign_t*>(action);
541 return ast_cast<Exp_t>(assign->values.back());
542 }
543 }
544 return nullptr;
545 }
546
547 Exp_t* lastExpFromStatement(Statement_t* stmt) {
548 if (!stmt->content) return nullptr;
549 switch (stmt->content->getId()) {
550 case id<ExpListAssign_t>(): {
551 auto expListAssign = static_cast<ExpListAssign_t*>(stmt->content.get());
552 if (auto action = expListAssign->action.get()) {
553 return lastExpFromAssign(action);
554 } else {
555 return static_cast<Exp_t*>(expListAssign->expList->exprs.back());
556 }
557 }
558 case id<Export_t>(): {
559 auto exportNode = static_cast<Export_t*>(stmt->content.get());
560 if (auto action = exportNode->assign.get()) {
561 return lastExpFromAssign(action);
562 } else {
563 switch (exportNode->target->getId()) {
564 case id<Exp_t>(): return exportNode->target.to<Exp_t>();
565 case id<ExpList_t>(): return static_cast<Exp_t*>(exportNode->target.to<ExpList_t>()->exprs.back());
566 }
567 }
568 }
569 case id<Local_t>(): {
570 if (auto localValues = static_cast<Local_t*>(stmt->content.get())->item.as<local_values_t>()) {
571 if (auto expList = localValues->valueList.as<ExpListLow_t>()) {
572 return static_cast<Exp_t*>(expList->exprs.back());
573 }
574 }
575 }
576 case id<Global_t>(): {
577 if (auto globalValues = static_cast<Global_t*>(stmt->content.get())->item.as<global_values_t>()) {
578 if (auto expList = globalValues->valueList.as<ExpListLow_t>()) {
579 return static_cast<Exp_t*>(expList->exprs.back());
580 }
581 }
582 }
583 }
584 return nullptr;
585 }
586
525 template <class T> 587 template <class T>
526 ast_ptr<false, T> toAst(std::string_view codes, ast_node* parent) { 588 ast_ptr<false, T> toAst(std::string_view codes, ast_node* parent) {
527 auto res = _parser.parse<T>(s(codes)); 589 auto res = _parser.parse<T>(s(codes));
@@ -812,6 +874,7 @@ private:
812 case id<Label_t>(): transformLabel(static_cast<Label_t*>(content), out); break; 874 case id<Label_t>(): transformLabel(static_cast<Label_t*>(content), out); break;
813 case id<Goto_t>(): transformGoto(static_cast<Goto_t*>(content), out); break; 875 case id<Goto_t>(): transformGoto(static_cast<Goto_t*>(content), out); break;
814 case id<LocalAttrib_t>(): transformLocalAttrib(static_cast<LocalAttrib_t*>(content), out); break; 876 case id<LocalAttrib_t>(): transformLocalAttrib(static_cast<LocalAttrib_t*>(content), out); break;
877 case id<BackcallBody_t>(): throw std::logic_error(_info.errorMessage("backcall chain must be following a value"sv, x)); break;
815 case id<ExpListAssign_t>(): { 878 case id<ExpListAssign_t>(): {
816 auto expListAssign = static_cast<ExpListAssign_t*>(content); 879 auto expListAssign = static_cast<ExpListAssign_t*>(content);
817 if (expListAssign->action) { 880 if (expListAssign->action) {
@@ -1692,7 +1755,10 @@ private:
1692 auto begin = values.begin(); begin++; 1755 auto begin = values.begin(); begin++;
1693 for (auto it = begin; it != values.end(); ++it) { 1756 for (auto it = begin; it != values.end(); ++it) {
1694 auto unary = static_cast<unary_exp_t*>(*it); 1757 auto unary = static_cast<unary_exp_t*>(*it);
1695 auto value = singleValueFrom(unary); 1758 auto value = static_cast<Value_t*>(singleUnaryExpFrom(unary) ? unary->expos.back() : nullptr);
1759 if (values.back() == *it && !unary->ops.empty() && usage == ExpUsage::Common) {
1760 throw std::logic_error(_info.errorMessage("expression list is not supported here"sv, x));
1761 }
1696 if (!value) throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, *it)); 1762 if (!value) throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, *it));
1697 if (auto chainValue = value->item.as<ChainValue_t>()) { 1763 if (auto chainValue = value->item.as<ChainValue_t>()) {
1698 if (isChainValueCall(chainValue)) { 1764 if (isChainValueCall(chainValue)) {
@@ -1936,7 +2002,29 @@ private:
1936 for (auto it = nodes.begin(); it != nodes.end(); ++it) { 2002 for (auto it = nodes.begin(); it != nodes.end(); ++it) {
1937 auto node = *it; 2003 auto node = *it;
1938 auto stmt = static_cast<Statement_t*>(node); 2004 auto stmt = static_cast<Statement_t*>(node);
1939 if (auto backcall = stmt->content.as<Backcall_t>()) { 2005 if (auto backcallBody = stmt->content.as<BackcallBody_t>()) {
2006 auto x = stmt;
2007 bool cond = false;
2008 BLOCK_START
2009 BREAK_IF(it == nodes.begin());
2010 auto last = it; --last;
2011 auto lst = static_cast<Statement_t*>(*last);
2012 auto exp = lastExpFromStatement(lst);
2013 BREAK_IF(!exp);
2014 for (auto val : backcallBody->values.objects()) {
2015 exp->backcalls.push_back(val);
2016 }
2017 cond = true;
2018 BLOCK_END
2019 if (!cond) throw std::logic_error(_info.errorMessage("backcall chain must be following a value"sv, x));
2020 stmt->content.set(nullptr);
2021 auto next = it; ++next;
2022 BLOCK_START
2023 BREAK_IF(next == nodes.end());
2024 BREAK_IF(!static_cast<Statement_t*>(*next)->content.as<BackcallBody_t>());
2025 throw std::logic_error(_info.errorMessage("indent mismatch in backcall chain"sv, *next));
2026 BLOCK_END
2027 } else if (auto backcall = stmt->content.as<Backcall_t>()) {
1940 auto x = *nodes.begin(); 2028 auto x = *nodes.begin();
1941 auto newBlock = x->new_ptr<Block_t>(); 2029 auto newBlock = x->new_ptr<Block_t>();
1942 if (it != nodes.begin()) { 2030 if (it != nodes.begin()) {
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp
index 63ffec7..f15492f 100644
--- a/src/MoonP/moon_parser.cpp
+++ b/src/MoonP/moon_parser.cpp
@@ -319,7 +319,7 @@ MoonParser::MoonParser() {
319 unary_exp = *(Space >> unary_operator) >> expo_exp; 319 unary_exp = *(Space >> unary_operator) >> expo_exp;
320 320
321 BackcallOperator = expr("|>"); 321 BackcallOperator = expr("|>");
322 backcall_value = White >> BackcallOperator >> *SpaceBreak >> unary_exp; 322 backcall_value = Space >> BackcallOperator >> *SpaceBreak >> unary_exp;
323 backcall_exp = unary_exp >> *backcall_value; 323 backcall_exp = unary_exp >> *backcall_value;
324 324
325 BinaryOperator = 325 BinaryOperator =
@@ -522,6 +522,8 @@ MoonParser::MoonParser() {
522 fn_arrow_back = expr('<') >> set("-="); 522 fn_arrow_back = expr('<') >> set("-=");
523 Backcall = -FnArgsDef >> Space >> fn_arrow_back >> Space >> ChainValue; 523 Backcall = -FnArgsDef >> Space >> fn_arrow_back >> Space >> ChainValue;
524 524
525 BackcallBody = Seperator >> Space >> BackcallOperator >> unary_exp >> *(+SpaceBreak >> CheckIndent >> Space >> BackcallOperator >> unary_exp);
526
525 ExpList = Seperator >> Exp >> *(sym(',') >> Exp); 527 ExpList = Seperator >> Exp >> *(sym(',') >> Exp);
526 ExpListLow = Seperator >> Exp >> *(Space >> set(",;") >> Exp); 528 ExpListLow = Seperator >> Exp >> *(Space >> set(",;") >> Exp);
527 529
@@ -562,14 +564,14 @@ MoonParser::MoonParser() {
562 Import | While | Repeat | For | ForEach | 564 Import | While | Repeat | For | ForEach |
563 Return | Local | Global | Export | Macro | 565 Return | Local | Global | Export | Macro |
564 Space >> BreakLoop | Label | Goto | Backcall | 566 Space >> BreakLoop | Label | Goto | Backcall |
565 LocalAttrib | ExpListAssign 567 LocalAttrib | BackcallBody | ExpListAssign
566 ) >> Space >> 568 ) >> Space >>
567 -statement_appendix >> -statement_sep; 569 -statement_appendix >> -statement_sep;
568 570
569 Body = Space >> Break >> *EmptyLine >> InBlock | Statement; 571 Body = Space >> Break >> *EmptyLine >> InBlock | Statement;
570 572
571 empty_line_stop = Space >> and_(Stop); 573 empty_line_stop = Space >> and_(Stop);
572 Line = CheckIndent >> Statement | empty_line_stop; 574 Line = CheckIndent >> Statement | and_(Space >> BackcallOperator) >> Advance >> ensure(Statement, PopIndent) | empty_line_stop;
573 Block = Seperator >> Line >> *(+Break >> Line); 575 Block = Seperator >> Line >> *(+Break >> Line);
574 576
575 Shebang = expr("#!") >> *(not_(Stop) >> Any); 577 Shebang = expr("#!") >> *(not_(Stop) >> Any);
diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h
index f036a7c..bee3c9c 100644
--- a/src/MoonP/moon_parser.h
+++ b/src/MoonP/moon_parser.h
@@ -209,6 +209,7 @@ private:
209 AST_RULE(Goto) 209 AST_RULE(Goto)
210 AST_RULE(fn_arrow_back) 210 AST_RULE(fn_arrow_back)
211 AST_RULE(Backcall) 211 AST_RULE(Backcall)
212 AST_RULE(BackcallBody)
212 AST_RULE(ExpListLow) 213 AST_RULE(ExpListLow)
213 AST_RULE(ExpList) 214 AST_RULE(ExpList)
214 AST_RULE(Return) 215 AST_RULE(Return)