mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Add pipeline operator [Feature #15799]
This commit is contained in:
parent
e717d6faa8
commit
f169043d81
6 changed files with 47 additions and 1 deletions
12
NEWS
12
NEWS
|
@ -48,6 +48,18 @@ sufficient information, see the ChangeLog file or Redmine
|
||||||
" # This has been warned since 2.4
|
" # This has been warned since 2.4
|
||||||
EOS
|
EOS
|
||||||
|
|
||||||
|
* Pipeline operator is added.
|
||||||
|
|
||||||
|
This code equals to the next code.
|
||||||
|
|
||||||
|
foo()
|
||||||
|
|> bar 1, 2
|
||||||
|
|> display
|
||||||
|
|
||||||
|
foo()
|
||||||
|
.bar(1, 2)
|
||||||
|
.display
|
||||||
|
|
||||||
=== Core classes updates (outstanding ones only)
|
=== Core classes updates (outstanding ones only)
|
||||||
|
|
||||||
Enumerable::
|
Enumerable::
|
||||||
|
|
|
@ -111,6 +111,7 @@ token_ops = %[\
|
||||||
OROP ||
|
OROP ||
|
||||||
ANDDOT &.
|
ANDDOT &.
|
||||||
METHREF .:
|
METHREF .:
|
||||||
|
PIPE |>
|
||||||
]
|
]
|
||||||
|
|
||||||
class KeywordError < RuntimeError
|
class KeywordError < RuntimeError
|
||||||
|
|
|
@ -262,6 +262,7 @@ static const struct token_assoc {
|
||||||
{tDSTAR, O(op)},
|
{tDSTAR, O(op)},
|
||||||
{tANDDOT, O(op)},
|
{tANDDOT, O(op)},
|
||||||
{tMETHREF, O(op)},
|
{tMETHREF, O(op)},
|
||||||
|
{tPIPE, O(op)},
|
||||||
{tSTRING_BEG, O(tstring_beg)},
|
{tSTRING_BEG, O(tstring_beg)},
|
||||||
{tSTRING_CONTENT, O(tstring_content)},
|
{tSTRING_CONTENT, O(tstring_content)},
|
||||||
{tSTRING_DBEG, O(embexpr_beg)},
|
{tSTRING_DBEG, O(embexpr_beg)},
|
||||||
|
|
25
parse.y
25
parse.y
|
@ -1002,7 +1002,7 @@ static void token_info_warn(struct parser_params *p, const char *token, token_in
|
||||||
%type <node> literal numeric simple_numeric ssym dsym symbol cpath
|
%type <node> literal numeric simple_numeric ssym dsym symbol cpath
|
||||||
%type <node> top_compstmt top_stmts top_stmt begin_block
|
%type <node> top_compstmt top_stmts top_stmt begin_block
|
||||||
%type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
|
%type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
|
||||||
%type <node> expr_value expr_value_do arg_value primary_value fcall rel_expr
|
%type <node> expr_value expr_value_do arg_value primary_value fcall rel_expr pipeline
|
||||||
%type <node> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
|
%type <node> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
|
||||||
%type <node> args call_args opt_call_args
|
%type <node> args call_args opt_call_args
|
||||||
%type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
|
%type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
|
||||||
|
@ -1060,6 +1060,7 @@ static void token_info_warn(struct parser_params *p, const char *token, token_in
|
||||||
%token <id> tANDDOT RUBY_TOKEN(ANDDOT) "&."
|
%token <id> tANDDOT RUBY_TOKEN(ANDDOT) "&."
|
||||||
%token <id> tCOLON2 RUBY_TOKEN(COLON2) "::"
|
%token <id> tCOLON2 RUBY_TOKEN(COLON2) "::"
|
||||||
%token <id> tMETHREF RUBY_TOKEN(METHREF) ".:"
|
%token <id> tMETHREF RUBY_TOKEN(METHREF) ".:"
|
||||||
|
%token tPIPE RUBY_TOKEN(PIPE) "|>"
|
||||||
%token tCOLON3 ":: at EXPR_BEG"
|
%token tCOLON3 ":: at EXPR_BEG"
|
||||||
%token <id> tOP_ASGN "operator-assignment" /* +=, -= etc. */
|
%token <id> tOP_ASGN "operator-assignment" /* +=, -= etc. */
|
||||||
%token tASSOC "=>"
|
%token tASSOC "=>"
|
||||||
|
@ -1095,6 +1096,7 @@ static void token_info_warn(struct parser_params *p, const char *token, token_in
|
||||||
%nonassoc modifier_if modifier_unless modifier_while modifier_until
|
%nonassoc modifier_if modifier_unless modifier_while modifier_until
|
||||||
%left keyword_or keyword_and
|
%left keyword_or keyword_and
|
||||||
%right keyword_not
|
%right keyword_not
|
||||||
|
%left tPIPE
|
||||||
%nonassoc keyword_defined
|
%nonassoc keyword_defined
|
||||||
%right '=' tOP_ASGN
|
%right '=' tOP_ASGN
|
||||||
%left modifier_rescue
|
%left modifier_rescue
|
||||||
|
@ -2269,12 +2271,29 @@ arg : lhs '=' arg_rhs
|
||||||
/*% %*/
|
/*% %*/
|
||||||
/*% ripper: ifop!($1, $3, $6) %*/
|
/*% ripper: ifop!($1, $3, $6) %*/
|
||||||
}
|
}
|
||||||
|
| pipeline
|
||||||
| primary
|
| primary
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
pipeline : arg tPIPE operation2 opt_paren_args
|
||||||
|
{
|
||||||
|
/*%%%*/
|
||||||
|
$$ = new_command_qcall(p, ID2VAL(idPIPE), $1, $3, $4, Qnull, &@3, &@$);
|
||||||
|
/*% %*/
|
||||||
|
/*% ripper: command_call!($1, ID2VAL(idPIPE), $3, $4) %*/
|
||||||
|
}
|
||||||
|
| arg tPIPE operation2 opt_paren_args brace_block
|
||||||
|
{
|
||||||
|
/*%%%*/
|
||||||
|
$$ = new_command_qcall(p, ID2VAL(idPIPE), $1, $3, $4, $5, &@3, &@$);
|
||||||
|
/*% %*/
|
||||||
|
/*% ripper: method_add_block!(command_call!($1, ID2VAL(idPIPE), $3, $4), $5) %*/
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
relop : '>' {$$ = '>';}
|
relop : '>' {$$ = '>';}
|
||||||
| '<' {$$ = '<';}
|
| '<' {$$ = '<';}
|
||||||
| tGEQ {$$ = idGE;}
|
| tGEQ {$$ = idGE;}
|
||||||
|
@ -8924,6 +8943,10 @@ parser_yylex(struct parser_params *p)
|
||||||
SET_LEX_STATE(EXPR_BEG);
|
SET_LEX_STATE(EXPR_BEG);
|
||||||
return tOP_ASGN;
|
return tOP_ASGN;
|
||||||
}
|
}
|
||||||
|
if (c == '>') {
|
||||||
|
SET_LEX_STATE(EXPR_DOT);
|
||||||
|
return tPIPE;
|
||||||
|
}
|
||||||
SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG|EXPR_LABEL);
|
SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG|EXPR_LABEL);
|
||||||
pushback(p, c);
|
pushback(p, c);
|
||||||
return '|';
|
return '|';
|
||||||
|
|
|
@ -573,6 +573,8 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
|
||||||
scan('op', 'obj.:foo')
|
scan('op', 'obj.:foo')
|
||||||
assert_equal [],
|
assert_equal [],
|
||||||
scan('op', %q[`make all`])
|
scan('op', %q[`make all`])
|
||||||
|
assert_equal %w[|>],
|
||||||
|
scan('op', %q[x|>y])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_symbeg
|
def test_symbeg
|
||||||
|
|
|
@ -1379,6 +1379,13 @@ eom
|
||||||
assert_syntax_error('@1', /outside block/)
|
assert_syntax_error('@1', /outside block/)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_pipeline_operator
|
||||||
|
assert_valid_syntax('x |> y')
|
||||||
|
x = nil
|
||||||
|
assert_equal("121", eval('x = 12 |> pow(2) |> to_s(11)'))
|
||||||
|
assert_equal(12, x)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def not_label(x) @result = x; @not_label ||= nil end
|
def not_label(x) @result = x; @not_label ||= nil end
|
||||||
|
|
Loading…
Add table
Reference in a new issue