Skip to main content

shape_ast/parser/expressions/control_flow/
conditionals.rs

1//! Conditional expression parsing
2//!
3//! This module handles parsing of conditional expressions:
4//! - If/else expressions
5
6use 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
14/// Parse if expression
15pub 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    // Check if there's an else branch
33    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}