Support else if

This commit is contained in:
Laurenz 2021-09-30 19:07:06 +02:00
parent 9e95502622
commit 6d26e15fbe
4 changed files with 48 additions and 16 deletions

View File

@ -600,7 +600,7 @@ fn let_expr(p: &mut Parser) -> Option<Expr> {
let start = p.next_start();
p.eat_assert(Token::Let);
let mut let_expr = None;
let mut output = None;
if let Some(binding) = ident(p) {
let mut init = None;
@ -635,14 +635,14 @@ fn let_expr(p: &mut Parser) -> Option<Expr> {
}
}
let_expr = Some(Expr::Let(Box::new(LetExpr {
output = Some(Expr::Let(Box::new(LetExpr {
span: p.span_from(start),
binding,
init,
})));
}
let_expr
output
}
/// Parse an if expresion.
@ -650,15 +650,19 @@ fn if_expr(p: &mut Parser) -> Option<Expr> {
let start = p.next_start();
p.eat_assert(Token::If);
let mut if_expr = None;
let mut output = None;
if let Some(condition) = expr(p) {
if let Some(if_body) = body(p) {
let mut else_body = None;
if p.eat_if(Token::Else) {
else_body = body(p);
if p.peek() == Some(Token::If) {
else_body = if_expr(p);
} else {
else_body = body(p);
}
}
if_expr = Some(Expr::If(Box::new(IfExpr {
output = Some(Expr::If(Box::new(IfExpr {
span: p.span_from(start),
condition,
if_body,
@ -667,7 +671,7 @@ fn if_expr(p: &mut Parser) -> Option<Expr> {
}
}
if_expr
output
}
/// Parse a while expresion.
@ -675,10 +679,10 @@ fn while_expr(p: &mut Parser) -> Option<Expr> {
let start = p.next_start();
p.eat_assert(Token::While);
let mut while_expr = None;
let mut output = None;
if let Some(condition) = expr(p) {
if let Some(body) = body(p) {
while_expr = Some(Expr::While(Box::new(WhileExpr {
output = Some(Expr::While(Box::new(WhileExpr {
span: p.span_from(start),
condition,
body,
@ -686,7 +690,7 @@ fn while_expr(p: &mut Parser) -> Option<Expr> {
}
}
while_expr
output
}
/// Parse a for expression.
@ -694,12 +698,12 @@ fn for_expr(p: &mut Parser) -> Option<Expr> {
let start = p.next_start();
p.eat_assert(Token::For);
let mut for_expr = None;
let mut output = None;
if let Some(pattern) = for_pattern(p) {
if p.eat_expect(Token::In) {
if let Some(iter) = expr(p) {
if let Some(body) = body(p) {
for_expr = Some(Expr::For(Box::new(ForExpr {
output = Some(Expr::For(Box::new(ForExpr {
span: p.span_from(start),
pattern,
iter,
@ -710,7 +714,7 @@ fn for_expr(p: &mut Parser) -> Option<Expr> {
}
}
for_expr
output
}
/// Parse a for loop pattern.
@ -743,10 +747,10 @@ fn import_expr(p: &mut Parser) -> Option<Expr> {
Imports::Idents(idents(p, items))
};
let mut import_expr = None;
let mut output = None;
if p.eat_expect(Token::From) {
if let Some(path) = expr(p) {
import_expr = Some(Expr::Import(Box::new(ImportExpr {
output = Some(Expr::Import(Box::new(ImportExpr {
span: p.span_from(start),
imports,
path,
@ -754,7 +758,7 @@ fn import_expr(p: &mut Parser) -> Option<Expr> {
}
}
import_expr
output
}
/// Parse an include expression.

View File

@ -603,6 +603,7 @@ mod tests {
roundtrip("#let x = 1 + 2");
test_parse("#let f(x) = y", "#let f = (x) => y");
roundtrip("#if x [y] else [z]");
roundtrip("#if x {} else if y {} else {}");
roundtrip("#while x {y}");
roundtrip("#for x in y {z}");
roundtrip("#for k, x in y {z}");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -45,6 +45,33 @@
if "template" == type [Nope] else [ve.]
}
#let i = 3
#if i < 2 [
Five.
] else if i < 4 [
Six.
] else [
Seven.
]
---
// Test else if.
// Ref: false
#let nth(n) = {
str(n)
(if n == 1 { "st" }
else if n == 2 { "nd" }
else if n == 3 { "rd" }
else { "th" })
}
#test(nth(1), "1st")
#test(nth(2), "2nd")
#test(nth(3), "3rd")
#test(nth(4), "4th")
#test(nth(5), "5th")
---
// Value of if expressions.
// Ref: false