shape_ast/parser/expressions/control_flow/
conditionals.rs1use crate::ast::Expr;
7use crate::error::{Result, ShapeError};
8use crate::parser::Rule;
9use pest::iterators::Pair;
10
11use super::super::super::pair_span;
12use crate::parser::pair_location;
13
14pub fn parse_if_expr(pair: Pair<Rule>) -> Result<Expr> {
16 let span = pair_span(&pair);
17 let pair_loc = pair_location(&pair);
18 let mut inner = pair.into_inner();
19
20 let condition_pair = inner.next().ok_or_else(|| ShapeError::ParseError {
21 message: "expected condition in if expression".to_string(),
22 location: Some(pair_loc.clone()),
23 })?;
24 let condition = super::super::parse_expression(condition_pair)?;
25
26 let then_pair = inner.next().ok_or_else(|| ShapeError::ParseError {
27 message: "expected then branch in if expression".to_string(),
28 location: Some(pair_loc),
29 })?;
30 let then_branch = parse_if_branch(then_pair)?;
31
32 let else_branch = if let Some(else_pair) = inner.next() {
34 let else_inner = else_pair
35 .into_inner()
36 .next()
37 .ok_or_else(|| ShapeError::ParseError {
38 message: "expected else branch in if expression".to_string(),
39 location: None,
40 })?;
41 Some(Box::new(parse_if_branch(else_inner)?))
42 } else {
43 None
44 };
45
46 Ok(Expr::Conditional {
47 condition: Box::new(condition),
48 then_expr: Box::new(then_branch),
49 else_expr: else_branch,
50 span,
51 })
52}
53
54fn parse_if_branch(pair: Pair<Rule>) -> Result<Expr> {
55 match pair.as_rule() {
56 Rule::block_expr => super::super::primary::parse_primary_expr(pair),
57 Rule::if_expr => parse_if_expr(pair),
58 _ => super::super::parse_expression(pair),
59 }
60}