microcad_lang/syntax/statement/
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 syntax elements.
5
6use crate::{src_ref::*, syntax::*};
7
8/// If statement.
9#[derive(Clone)]
10pub struct IfStatement {
11    /// If condition.
12    pub cond: Expression,
13    /// Body if `true`.
14    pub body: Body,
15    /// Body if `false`.
16    pub body_else: Option<Body>,
17    /// Next if statement: `else if x == 1`.
18    pub next_if: Option<Box<IfStatement>>,
19    /// Source code reference.
20    pub src_ref: SrcRef,
21}
22
23impl IfStatement {
24    /// Checks if all branches of the if statement are set
25    pub fn is_complete(&self) -> bool {
26        if let Some(next_if) = &self.next_if {
27            next_if.is_complete()
28        } else {
29            self.body_else.is_some()
30        }
31    }
32}
33
34impl SrcReferrer for IfStatement {
35    fn src_ref(&self) -> SrcRef {
36        self.src_ref.clone()
37    }
38}
39
40impl std::fmt::Display for IfStatement {
41    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
42        writeln!(f, "if {cond} {body}", cond = self.cond, body = self.body)?;
43        if let Some(next) = &self.next_if {
44            writeln!(f, "else {next}")?;
45        }
46        if let Some(body) = &self.body_else {
47            writeln!(f, "else {body}")?;
48        }
49        Ok(())
50    }
51}
52
53impl std::fmt::Debug for IfStatement {
54    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
55        writeln!(
56            f,
57            "if {cond:?} {body:?}",
58            cond = self.cond,
59            body = self.body
60        )?;
61        if let Some(next) = &self.next_if {
62            writeln!(f, "else {next:?}")?;
63        }
64        if let Some(body) = &self.body_else {
65            writeln!(f, "else {body:?}")?;
66        }
67        Ok(())
68    }
69}
70
71impl TreeDisplay for IfStatement {
72    fn tree_print(&self, f: &mut std::fmt::Formatter, mut depth: TreeState) -> std::fmt::Result {
73        writeln!(f, "{:depth$}IfStatement:", "")?;
74        depth.indent();
75        writeln!(f, "{:depth$}Condition:", "")?;
76        self.cond.tree_print(f, depth.indented())?;
77        writeln!(f, "{:depth$}If:", "")?;
78        self.body.tree_print(f, depth.indented())?;
79        if let Some(body_else) = &self.body_else {
80            writeln!(f, "{:depth$}Else:", "")?;
81            body_else.tree_print(f, depth.indented())?;
82        }
83        Ok(())
84    }
85}