iteration.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, Identifier, Indent, Node, NodeID, Statement, Type}; 18 19 use adl_span::Span; 20 21 use serde::{Deserialize, Serialize}; 22 use std::fmt; 23 24 /// A bounded `for` loop statement `for variable in start .. =? stop block`. 25 #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] 26 pub struct IterationStatement { 27 /// The binding / variable to introduce in the body `block`. 28 pub variable: Identifier, 29 /// The type of the iteration. 30 pub type_: Option<Type>, 31 /// The start of the iteration. 32 pub start: Expression, 33 /// The end of the iteration, possibly `inclusive`. 34 pub stop: Expression, 35 /// Whether `stop` is inclusive or not. 36 /// Signified with `=` when parsing. 37 pub inclusive: bool, 38 /// The block to run on each iteration. 39 pub block: Block, 40 /// The span from `for` to `block`. 41 pub span: Span, 42 /// The ID of the node. 43 pub id: NodeID, 44 } 45 46 impl fmt::Display for IterationStatement { 47 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 48 let eq = if self.inclusive { "=" } else { "" }; 49 if let Some(ty) = &self.type_ { 50 writeln!(f, "for {}: {} in {}..{eq}{} {{", self.variable, ty, self.start, self.stop)?; 51 } else { 52 writeln!(f, "for {} in {}..{eq}{} {{", self.variable, self.start, self.stop)?; 53 } 54 for stmt in self.block.statements.iter() { 55 writeln!(f, "{}{}", Indent(stmt), stmt.semicolon())?; 56 } 57 writeln!(f, "}}") 58 } 59 } 60 61 impl From<IterationStatement> for Statement { 62 fn from(value: IterationStatement) -> Self { 63 Statement::Iteration(Box::new(value)) 64 } 65 } 66 67 crate::simple_node_impl!(IterationStatement);