Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remake else if as repeat($.else_clause) #105

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 60 additions & 38 deletions corpus/expressions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,10 @@ If expressions
================================================================================

fn main() {
if n == 2 {
}
if n == 1 {
} else if let Some(k) = z {
} else if n == 2 {
} else {
}
Expand All @@ -502,41 +505,36 @@ if foo && bar || baz {}
body: (block
(expression_statement
(if_expression
condition: (binary_expression
left: (identifier)
right: (integer_literal))
condition: (binary_expression left: (identifier) right: (integer_literal))
consequence: (block)))
(expression_statement
(if_expression
condition: (binary_expression left: (identifier) right: (integer_literal))
consequence: (block)
alternative: (else_clause
(if_expression
condition: (binary_expression
left: (identifier)
right: (integer_literal))
consequence: (block)
alternative: (else_clause
(block))))))))
(else_clause
condition: (let_condition
pattern: (tuple_struct_pattern type: (identifier) (identifier))
value: (identifier))
consequence: (block))
(else_clause
condition: (binary_expression left: (identifier) right: (integer_literal))
consequence: (block))
(else_clause
(block))))))
(let_declaration
pattern: (identifier)
value: (if_expression
condition: (binary_expression
left: (identifier)
right: (integer_literal))
consequence: (block
(integer_literal))
alternative: (else_clause
(block
(integer_literal)))))
condition: (binary_expression left: (identifier) right: (integer_literal))
consequence: (block (integer_literal))
(else_clause (block (integer_literal)))))
(expression_statement
(if_expression
condition: (binary_expression
left: (identifier)
right: (identifier))
condition: (binary_expression left: (identifier) right: (identifier))
consequence: (block)))
(expression_statement
(if_expression
condition: (binary_expression
left: (binary_expression
left: (identifier)
right: (identifier))
left: (binary_expression left: (identifier) right: (identifier))
right: (identifier))
consequence: (block))))

Expand All @@ -558,23 +556,52 @@ if let Some(a) = b
(if_expression
condition: (let_chain
(let_condition
pattern: (tuple_struct_pattern
type: (identifier)
(identifier))
pattern: (tuple_struct_pattern type: (identifier) (identifier))
value: (identifier))
(identifier)
(identifier)
(let_condition
pattern: (tuple_struct_pattern
type: (identifier)
(identifier))
pattern: (tuple_struct_pattern type: (identifier) (identifier))
value: (identifier)))
consequence: (block))))

================================================================================
If let expressions
================================================================================

let x = if let Some(a) = dish {
a
} else if let None = dish {
99
} else if n == 8 {
9
} else {
7
};

--------------------------------------------------------------------------------

(source_file
(let_declaration
pattern: (identifier)
value: (if_expression
condition: (let_condition
pattern: (tuple_struct_pattern type: (identifier) (identifier))
value: (identifier))
consequence: (block (identifier))
(else_clause
condition: (let_condition pattern: (identifier) value: (identifier))
consequence: (block (integer_literal)))
(else_clause
condition: (binary_expression left: (identifier) right: (integer_literal))
consequence: (block (integer_literal)))
(else_clause
(block (integer_literal))))))

================================================================================
If let chains
================================================================================

if let ("Bacon", b) = dish {
}

Expand Down Expand Up @@ -1270,10 +1297,7 @@ let three_ranges = [const { (0..=5).into_inner() }; 3];
(empty_statement)
(expression_statement
(if_expression
condition: (binary_expression
left: (unary_expression
(identifier))
right: (integer_literal))
condition: (binary_expression left: (unary_expression (identifier)) right: (integer_literal))
consequence: (block
(expression_statement
(const_block
Expand All @@ -1285,9 +1309,7 @@ let three_ranges = [const { (0..=5).into_inner() }; 3];
field: (field_identifier))
arguments: (arguments
(integer_literal))))))))
alternative: (else_clause
(block
(identifier)))))
(else_clause (block (identifier)))))
(let_declaration
pattern: (identifier)
value: (array_expression
Expand Down
50 changes: 50 additions & 0 deletions examples/if_expressions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
fn f(n: i32) {
// ()-typed
if n == 2 {
}
if n == 1 {
} else if n == 2 {
return;
} else {
}
// ()-typed (if let)
if let 1 = n {
} else if let 2 = n {
return;
} else if n == 2 {
return;
} else {
}
// simple if/else expression
let y = if x == 5 { 5 } else { 10 };
let z = Some(5);
// if expression with an else if branch
let y = if z.is_some() {
30
} else if z.is_none() {
99
} else {
0
};
// if expression with an else if let branch
let y = if z.is_some() {
30
} else if let None = y {
99
} else {
0
};
// if let expression with both kinds of else if
let y = if let Some(3) = y {
30
} else if let Some(4) = y {
} else if y == Some(10) {
100
} else {
0
};
// if and else-if with let-else chain
if let Some(3) = y && let None = z {
} else if let None = y && let Some(_) = z {
}
}
36 changes: 21 additions & 15 deletions grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -1096,9 +1096,29 @@ module.exports = grammar({
'if',
field('condition', $._condition),
field('consequence', $.block),
optional(field("alternative", $.else_clause))
repeat($.else_clause),
)),

_else_if: $ => prec.right(seq(
'if',
field('condition', $._condition),
field('consequence', $.block),
)),

else_clause: $ => seq(
'else',
choice(
$.block,
$._else_if
)
),

_condition: $ => choice(
$._expression,
$.let_condition,
alias($._let_chain, $.let_chain),
),

let_condition: $ => seq(
'let',
field('pattern', $._pattern),
Expand All @@ -1114,20 +1134,6 @@ module.exports = grammar({
seq($._expression, '&&', $.let_condition),
)),

_condition: $ => choice(
$._expression,
$.let_condition,
alias($._let_chain, $.let_chain),
),

else_clause: $ => seq(
'else',
choice(
$.block,
$.if_expression
)
),

match_expression: $ => seq(
'match',
field('value', $._expression),
Expand Down
Loading