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

View File

@ -603,6 +603,7 @@ mod tests {
roundtrip("#let x = 1 + 2"); roundtrip("#let x = 1 + 2");
test_parse("#let f(x) = y", "#let f = (x) => y"); test_parse("#let f(x) = y", "#let f = (x) => y");
roundtrip("#if x [y] else [z]"); roundtrip("#if x [y] else [z]");
roundtrip("#if x {} else if y {} else {}");
roundtrip("#while x {y}"); roundtrip("#while x {y}");
roundtrip("#for x in y {z}"); roundtrip("#for x in y {z}");
roundtrip("#for k, 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.] 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. // Value of if expressions.
// Ref: false // Ref: false