Skip to content

Commit a711bef

Browse files
committed
Dont require [] for keyword list operand in when/2
1 parent aa1b678 commit a711bef

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

lib/elixir/src/elixir_parser.yrl

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,28 @@ expr -> matched_expr : '$1'.
8787
expr -> no_parens_expr : '$1'.
8888
expr -> unmatched_expr : '$1'.
8989

90+
%% In Elixir we have three main call syntaxes: with parentheses,
91+
%% without parentheses and with do blocks. They are represented
92+
%% in the AST as matched, no_parens and unmatched.
93+
%%
94+
%% The distinction is required because we can't, for example, have
95+
%% a function call with a do block as argument inside another do
96+
%% block call, unless there are parentheses:
97+
%%
98+
%% if if true do true else false end do #=> invalid
99+
%% if(if true do true else false end) do #=> valid
100+
%%
101+
%% Similarly, it is not possible to nest calls without parentheses
102+
%% if their arity is more than 1:
103+
%%
104+
%% foo a, bar b, c #=> invalid
105+
%% foo(a, bar b, c) #=> invalid
106+
%% foo a, bar b #=> valid
107+
%% foo a, bar(b, c) #=> valid
108+
%%
109+
%% So the different grammar rules need to take into account
110+
%% if calls without parentheses are do blocks in particular
111+
%% segments and act accordingly.
90112
matched_expr -> matched_expr matched_op_expr : build_op(element(1, '$2'), '$1', element(2, '$2')).
91113
matched_expr -> matched_expr no_parens_op_expr : build_op(element(1, '$2'), '$1', element(2, '$2')).
92114
matched_expr -> unary_op_eol matched_expr : build_unary_op('$1', '$2').
@@ -140,13 +162,16 @@ no_parens_op_expr -> tail_op_eol no_parens_expr : { '$1', '$2' }.
140162
no_parens_op_expr -> than_op_eol no_parens_expr : { '$1', '$2' }.
141163
no_parens_op_expr -> in_op_eol no_parens_expr : { '$1', '$2' }.
142164
no_parens_op_expr -> inc_op_eol no_parens_expr : { '$1', '$2' }.
143-
no_parens_op_expr -> when_op_eol no_parens_expr : { '$1', '$2' }.
144165
no_parens_op_expr -> range_op_eol no_parens_expr : { '$1', '$2' }.
145166
no_parens_op_expr -> default_op_eol no_parens_expr : { '$1', '$2' }.
146167
no_parens_op_expr -> type_op_eol no_parens_expr : { '$1', '$2' }.
147168
no_parens_op_expr -> comp_op_eol no_parens_expr : { '$1', '$2' }.
148169
no_parens_op_expr -> arrow_op_eol no_parens_expr : { '$1', '$2' }.
149170

171+
%% Allow when (and only when) with keywords
172+
no_parens_op_expr -> when_op_eol no_parens_expr : { '$1', '$2' }.
173+
no_parens_op_expr -> when_op_eol call_args_no_parens_kw : { '$1', '$2' }.
174+
150175
matched_op_expr -> match_op_eol matched_expr : { '$1', '$2' }.
151176
matched_op_expr -> add_op_eol matched_expr : { '$1', '$2' }.
152177
matched_op_expr -> mult_op_eol matched_expr : { '$1', '$2' }.

0 commit comments

Comments
 (0)