diff options
Diffstat (limited to '')
| -rwxr-xr-x | src/yuescript/yue_ast.h | 9 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 37 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 8 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.h | 1 |
4 files changed, 50 insertions, 5 deletions
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 0925f5a..21266c9 100755 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
| @@ -827,6 +827,13 @@ AST_END(YueLineComment, "comment"sv) | |||
| 827 | AST_LEAF(YueMultilineComment) | 827 | AST_LEAF(YueMultilineComment) |
| 828 | AST_END(YueMultilineComment, "comment"sv) | 828 | AST_END(YueMultilineComment, "comment"sv) |
| 829 | 829 | ||
| 830 | AST_NODE(ChainAssign) | ||
| 831 | ast_ptr<true, Seperator_t> sep; | ||
| 832 | ast_list<true, Exp_t> exprs; | ||
| 833 | ast_ptr<true, Assign_t> assign; | ||
| 834 | AST_MEMBER(ChainAssign, &sep, &exprs, &assign) | ||
| 835 | AST_END(ChainAssign, "chain_assign") | ||
| 836 | |||
| 830 | AST_NODE(Statement) | 837 | AST_NODE(Statement) |
| 831 | ast_ptr<true, Seperator_t> sep; | 838 | ast_ptr<true, Seperator_t> sep; |
| 832 | ast_sel_list<false, YueLineComment_t, YueMultilineComment_t> comments; | 839 | ast_sel_list<false, YueLineComment_t, YueMultilineComment_t> comments; |
| @@ -834,7 +841,7 @@ AST_NODE(Statement) | |||
| 834 | Import_t, While_t, Repeat_t, For_t, ForEach_t, | 841 | Import_t, While_t, Repeat_t, For_t, ForEach_t, |
| 835 | Return_t, Local_t, Global_t, Export_t, Macro_t, MacroInPlace_t, | 842 | Return_t, Local_t, Global_t, Export_t, Macro_t, MacroInPlace_t, |
| 836 | BreakLoop_t, Label_t, Goto_t, ShortTabAppending_t, | 843 | BreakLoop_t, Label_t, Goto_t, ShortTabAppending_t, |
| 837 | Backcall_t, LocalAttrib_t, PipeBody_t, ExpListAssign_t | 844 | Backcall_t, LocalAttrib_t, PipeBody_t, ExpListAssign_t, ChainAssign_t |
| 838 | > content; | 845 | > content; |
| 839 | ast_ptr<false, statement_appendix_t> appendix; | 846 | ast_ptr<false, statement_appendix_t> appendix; |
| 840 | ast_ptr<false, statement_sep_t> needSep; | 847 | ast_ptr<false, statement_sep_t> needSep; |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 45a9bf6..4072974 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -59,7 +59,7 @@ namespace yue { | |||
| 59 | 59 | ||
| 60 | typedef std::list<std::string> str_list; | 60 | typedef std::list<std::string> str_list; |
| 61 | 61 | ||
| 62 | const std::string_view version = "0.15.10"sv; | 62 | const std::string_view version = "0.15.11"sv; |
| 63 | const std::string_view extension = "yue"sv; | 63 | const std::string_view extension = "yue"sv; |
| 64 | 64 | ||
| 65 | class YueCompilerImpl { | 65 | class YueCompilerImpl { |
| @@ -1276,6 +1276,7 @@ private: | |||
| 1276 | } | 1276 | } |
| 1277 | break; | 1277 | break; |
| 1278 | } | 1278 | } |
| 1279 | case id<ChainAssign_t>(): transformChainAssign(static_cast<ChainAssign_t*>(content), out); break; | ||
| 1279 | default: YUEE("AST node mismatch", content); break; | 1280 | default: YUEE("AST node mismatch", content); break; |
| 1280 | } | 1281 | } |
| 1281 | if (statement->needSep && !out.empty() && !out.back().empty()) { | 1282 | if (statement->needSep && !out.empty() && !out.back().empty()) { |
| @@ -8004,6 +8005,40 @@ private: | |||
| 8004 | assignment->action.set(tab->assign); | 8005 | assignment->action.set(tab->assign); |
| 8005 | transformAssignment(assignment, out); | 8006 | transformAssignment(assignment, out); |
| 8006 | } | 8007 | } |
| 8008 | |||
| 8009 | void transformChainAssign(ChainAssign_t* chainAssign, str_list& out) { | ||
| 8010 | auto x = chainAssign; | ||
| 8011 | str_list temp; | ||
| 8012 | auto value = chainAssign->assign->values.front(); | ||
| 8013 | bool constVal = false; | ||
| 8014 | if (auto simpleVal = simpleSingleValueFrom(value)) { | ||
| 8015 | constVal = ast_is<const_value_t, Num_t>(simpleVal->value); | ||
| 8016 | } | ||
| 8017 | if (constVal || !singleVariableFrom(value, false).empty()) { | ||
| 8018 | for (auto exp : chainAssign->exprs.objects()) { | ||
| 8019 | transformAssignment(assignmentFrom(static_cast<Exp_t*>(exp), value, exp), temp); | ||
| 8020 | } | ||
| 8021 | out.push_back(join(temp)); | ||
| 8022 | return; | ||
| 8023 | } | ||
| 8024 | auto valName = getUnusedName("_tmp_"); | ||
| 8025 | auto newValue = toAst<Exp_t>(valName, value); | ||
| 8026 | ast_list<false, ExpListAssign_t> assignments; | ||
| 8027 | for (auto exp : chainAssign->exprs.objects()) { | ||
| 8028 | auto assignment = assignmentFrom(static_cast<Exp_t*>(exp), newValue, exp); | ||
| 8029 | assignments.push_back(assignment.get()); | ||
| 8030 | temp.push_back(getPreDefineLine(assignment)); | ||
| 8031 | } | ||
| 8032 | assignments.push_front(assignmentFrom(newValue, value, value)); | ||
| 8033 | temp.push_back(indent() + "do"s + nll(x)); | ||
| 8034 | pushScope(); | ||
| 8035 | for (auto item : assignments.objects()) { | ||
| 8036 | transformAssignment(static_cast<ExpListAssign_t*>(item), temp); | ||
| 8037 | } | ||
| 8038 | popScope(); | ||
| 8039 | temp.push_back(indent() + "end"s + nll(x)); | ||
| 8040 | out.push_back(join(temp)); | ||
| 8041 | } | ||
| 8007 | }; | 8042 | }; |
| 8008 | 8043 | ||
| 8009 | const std::string YueCompilerImpl::Empty; | 8044 | const std::string YueCompilerImpl::Empty; |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index e755fb2..b1f29a9 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -650,7 +650,7 @@ YueParser::YueParser() { | |||
| 650 | unary_value | TblComprehension | TableLit | Comprehension | | 650 | unary_value | TblComprehension | TableLit | Comprehension | |
| 651 | FunLit | Num); | 651 | FunLit | Num); |
| 652 | 652 | ||
| 653 | ExpListAssign = ExpList >> -(Update | Assign); | 653 | ExpListAssign = ExpList >> -(Update | Assign) >> not_(Space >> expr('=')); |
| 654 | 654 | ||
| 655 | if_line = Space >> IfType >> IfCond; | 655 | if_line = Space >> IfType >> IfCond; |
| 656 | while_line = Space >> WhileType >> Exp; | 656 | while_line = Space >> WhileType >> Exp; |
| @@ -661,13 +661,15 @@ YueParser::YueParser() { | |||
| 661 | yue_multiline_comment = multi_line_open >> YueMultilineComment >> multi_line_close; | 661 | yue_multiline_comment = multi_line_open >> YueMultilineComment >> multi_line_close; |
| 662 | yue_comment = check_indent >> (yue_multiline_comment >> *(set(" \t") | yue_multiline_comment) >> -yue_line_comment | yue_line_comment) >> and_(Break); | 662 | yue_comment = check_indent >> (yue_multiline_comment >> *(set(" \t") | yue_multiline_comment) >> -yue_line_comment | yue_line_comment) >> and_(Break); |
| 663 | 663 | ||
| 664 | ChainAssign = Seperator >> Exp >> +(sym('=') >> Exp >> Space >> and_('=')) >> Assign; | ||
| 665 | |||
| 664 | statement_appendix = (if_line | while_line | CompInner) >> Space; | 666 | statement_appendix = (if_line | while_line | CompInner) >> Space; |
| 665 | statement_sep = and_(*SpaceBreak >> CheckIndent >> Space >> (set("($'\"") | expr("[[") | expr("[="))); | 667 | statement_sep = and_(*SpaceBreak >> CheckIndent >> Space >> (set("($'\"") | expr("[[") | expr("[="))); |
| 666 | Statement = Seperator >> -(yue_comment >> *(Break >> yue_comment) >> Break >> CheckIndent) >> Space >> ( | 668 | Statement = Seperator >> -(yue_comment >> *(Break >> yue_comment) >> Break >> CheckIndent) >> Space >> ( |
| 667 | Import | While | Repeat | For | ForEach | | 669 | Import | While | Repeat | For | ForEach | |
| 668 | Return | Local | Global | Export | Macro | | 670 | Return | Local | Global | Export | Macro | |
| 669 | MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending | | 671 | MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending | |
| 670 | LocalAttrib | Backcall | PipeBody | ExpListAssign | | 672 | LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign | |
| 671 | statement_appendix >> empty_block_error | 673 | statement_appendix >> empty_block_error |
| 672 | ) >> Space >> | 674 | ) >> Space >> |
| 673 | -statement_appendix >> -statement_sep; | 675 | -statement_appendix >> -statement_sep; |
| @@ -679,7 +681,7 @@ YueParser::YueParser() { | |||
| 679 | advance >> ensure(MultiLineComment >> Space | Comment, PopIndent) | | 681 | advance >> ensure(MultiLineComment >> Space | Comment, PopIndent) | |
| 680 | plain_space) >> and_(Break); | 682 | plain_space) >> and_(Break); |
| 681 | 683 | ||
| 682 | indentation_error = pl::user(not_(PipeOperator), [](const item_t& item) { | 684 | indentation_error = pl::user(not_(PipeOperator | eof()), [](const item_t& item) { |
| 683 | throw ParserError("unexpected indent", *item.begin, *item.end); | 685 | throw ParserError("unexpected indent", *item.begin, *item.end); |
| 684 | return false; | 686 | return false; |
| 685 | }); | 687 | }); |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 74281fb..88d688c 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
| @@ -361,6 +361,7 @@ private: | |||
| 361 | AST_RULE(Statement) | 361 | AST_RULE(Statement) |
| 362 | AST_RULE(YueLineComment) | 362 | AST_RULE(YueLineComment) |
| 363 | AST_RULE(YueMultilineComment) | 363 | AST_RULE(YueMultilineComment) |
| 364 | AST_RULE(ChainAssign) | ||
| 364 | AST_RULE(Body) | 365 | AST_RULE(Body) |
| 365 | AST_RULE(Block) | 366 | AST_RULE(Block) |
| 366 | AST_RULE(BlockEnd) | 367 | AST_RULE(BlockEnd) |
