conditional.rs
1 // Copyright (C) 2019-2025 ADnet Contributors 2 // This file is part of the ADL library. 3 4 // The ADL library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 9 // The ADL library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 14 // You should have received a copy of the GNU General Public License 15 // along with the ADL library. If not, see <https://www.gnu.org/licenses/>. 16 17 use crate::{Block, Expression, Indent, Node, NodeID, Statement}; 18 use adl_span::Span; 19 20 use serde::{Deserialize, Serialize}; 21 use std::fmt; 22 23 /// An `if condition block (else next)?` statement. 24 #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] 25 pub struct ConditionalStatement { 26 /// The `bool`-typed condition deciding what to evaluate. 27 pub condition: Expression, 28 /// The block to evaluate in case `condition` yields `true`. 29 pub then: Block, 30 /// The statement, if any, to evaluate when `condition` yields `false`. 31 pub otherwise: Option<Box<Statement>>, 32 /// The span from `if` to `next` or to `block`. 33 pub span: Span, 34 /// The ID of the node. 35 pub id: NodeID, 36 } 37 38 impl fmt::Display for ConditionalStatement { 39 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 40 writeln!(f, "if {} {{", self.condition)?; 41 for stmt in self.then.statements.iter() { 42 writeln!(f, "{}{}", Indent(stmt), stmt.semicolon())?; 43 } 44 match self.otherwise.as_deref() { 45 None => write!(f, "}}")?, 46 Some(Statement::Block(block)) => { 47 writeln!(f, "}} else {{")?; 48 for stmt in block.statements.iter() { 49 writeln!(f, "{}{}", Indent(stmt), stmt.semicolon())?; 50 } 51 write!(f, "}}")?; 52 } 53 Some(Statement::Conditional(cond)) => { 54 write!(f, "}} else {cond}")?; 55 } 56 Some(_) => panic!("`otherwise` of a `ConditionalStatement` must be a block or conditional."), 57 } 58 Ok(()) 59 } 60 } 61 62 impl From<ConditionalStatement> for Statement { 63 fn from(value: ConditionalStatement) -> Self { 64 Statement::Conditional(value) 65 } 66 } 67 68 crate::simple_node_impl!(ConditionalStatement);