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 {
19                    Ok(Value::None)
20                }
21            }
22            _ => {
23                context.error(self, EvalError::IfConditionIsNotBool(cond.to_string()))?;
24                Ok(Value::None)
25            }
26        }
27    }
28}
29
30impl Eval<Option<Model>> for IfStatement {
31    fn eval(&self, context: &mut EvalContext) -> EvalResult<Option<Model>> {
32        log::debug!("Evaluating if statement to model: {self}");
33        self.grant(context)?;
34        let cond = self.cond.eval(context)?;
35        match cond {
36            Value::Bool(true) => Ok(self.body.eval(context)?),
37            Value::Bool(false) => {
38                if let Some(body) = &self.body_else {
39                    Ok(body.eval(context)?)
40                } else {
41                    Ok(None)
42                }
43            }
44            _ => {
45                context.error(self, EvalError::IfConditionIsNotBool(cond.to_string()))?;
46                Ok(None)
47            }
48        }
49    }
50}