diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 9cd176048..19d810ea4 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -600,7 +600,7 @@ fn let_expr(p: &mut Parser) -> Option { 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 { } } - 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 { 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 { } } - if_expr + output } /// Parse a while expresion. @@ -675,10 +679,10 @@ fn while_expr(p: &mut Parser) -> Option { 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 { } } - while_expr + output } /// Parse a for expression. @@ -694,12 +698,12 @@ fn for_expr(p: &mut Parser) -> Option { 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 { } } - for_expr + output } /// Parse a for loop pattern. @@ -743,10 +747,10 @@ fn import_expr(p: &mut Parser) -> Option { 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 { } } - import_expr + output } /// Parse an include expression. diff --git a/src/syntax/pretty.rs b/src/syntax/pretty.rs index d186eaf68..6ac5672e4 100644 --- a/src/syntax/pretty.rs +++ b/src/syntax/pretty.rs @@ -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}"); diff --git a/tests/ref/code/if.png b/tests/ref/code/if.png index 7b54203aa..bce70b899 100644 Binary files a/tests/ref/code/if.png and b/tests/ref/code/if.png differ diff --git a/tests/typ/code/if.typ b/tests/typ/code/if.typ index 36fd3d0f5..3b3164fc6 100644 --- a/tests/typ/code/if.typ +++ b/tests/typ/code/if.typ @@ -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