microcad_lang/eval/statements/
if_statement.rs

1// Copyright © 2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! If statement evaluation.
5
6use crate::{eval::*, model::*, syntax::*, value::*};
7
8impl Eval<Value> for IfStatement {
9    fn eval(&self, context: &mut crate::eval::EvalContext) -> crate::eval::EvalResult<Value> {
10        log::debug!("Evaluating if statement to value: {self}");
11        self.grant(context)?;
12        let cond = self.cond.eval(context)?;
13        match cond {
14            Value::Bool(true) => Ok(self.body.eval(context)?),
15            Value::Bool(false) => {
16                if let Some(body) = &self.body_else {
17                    Ok(body.eval(context)?)
18                } else if let Some(next) = &self.next_if {
19                    next.eval(context)
20                } else {
21                    Ok(Value::None)
22                }
23            }
24            _ => {
25                context.error(self, EvalError::IfConditionIsNotBool(cond.to_string()))?;
26                Ok(Value::None)
27            }
28        }
29    }
30}
31
32impl Eval<Option<Model>> for IfStatement {
33    fn eval(&self, context: &mut EvalContext) -> EvalResult<Option<Model>> {
34        log::debug!("Evaluating if statement to model: {self}");
35        self.grant(context)?;
36        let cond = self.cond.eval(context)?;
37        match cond {
38            Value::Bool(true) => Ok(self.body.eval(context)?),
39            Value::Bool(false) => {
40                if let Some(body) = &self.body_else {
41                    Ok(body.eval(context)?)
42                } else if let Some(next) = &self.next_if {
43                    next.eval(context)
44                } else {
45                    Ok(None)
46                }
47            }
48            _ => {
49                context.error(self, EvalError::IfConditionIsNotBool(cond.to_string()))?;
50                Ok(None)
51            }
52        }
53    }
54}