microcad_lang/eval/statements/
if_statement.rs1use microcad_lang_base::{PushDiag, SrcReferrer};
7
8use crate::{eval::*, model::*, syntax::*, value::*};
9
10impl Eval<Value> for IfStatement {
11 fn eval(&self, context: &mut crate::eval::EvalContext) -> crate::eval::EvalResult<Value> {
12 log::debug!("Evaluating if statement to value: {self}");
13
14 let cond = self.cond.eval(context)?;
15 match cond {
16 Value::Bool(true) => Ok(self.body.eval(context)?),
17 Value::Bool(false) => {
18 if let Some(body) = &self.body_else {
19 Ok(body.eval(context)?)
20 } else if let Some(next) = &self.next_if {
21 next.eval(context)
22 } else {
23 Ok(Value::None)
24 }
25 }
26 _ => {
27 context.error(
28 self,
29 EvalError::IfConditionIsNotBool {
30 condition: cond.to_string(),
31 src_ref: self.cond.src_ref(),
32 },
33 )?;
34 Ok(Value::None)
35 }
36 }
37 }
38}
39
40impl Eval<Option<Model>> for IfStatement {
41 fn eval(&self, context: &mut EvalContext) -> EvalResult<Option<Model>> {
42 log::debug!("Evaluating if statement to model: {self}");
43
44 let cond = self.cond.eval(context)?;
45 match cond {
46 Value::Bool(true) => Ok(self.body.eval(context)?),
47 Value::Bool(false) => {
48 if let Some(body) = &self.body_else {
49 Ok(body.eval(context)?)
50 } else if let Some(next) = &self.next_if {
51 next.eval(context)
52 } else {
53 Ok(None)
54 }
55 }
56 _ => {
57 context.error(
58 self,
59 EvalError::IfConditionIsNotBool {
60 condition: cond.to_string(),
61 src_ref: self.cond.src_ref(),
62 },
63 )?;
64 Ok(None)
65 }
66 }
67 }
68}