/ compiler / ast / src / statement / mod.rs
mod.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  mod assert;
 18  pub use assert::*;
 19  
 20  mod assign;
 21  pub use assign::*;
 22  
 23  mod block;
 24  pub use block::*;
 25  
 26  mod conditional;
 27  pub use conditional::*;
 28  
 29  mod const_;
 30  pub use const_::*;
 31  
 32  mod definition;
 33  pub use definition::*;
 34  
 35  mod expression;
 36  pub use expression::*;
 37  
 38  mod iteration;
 39  pub use iteration::*;
 40  
 41  mod return_;
 42  pub use return_::*;
 43  
 44  use crate::{Expression, Node, NodeID};
 45  
 46  use adl_span::Span;
 47  
 48  use serde::{Deserialize, Serialize};
 49  use std::fmt;
 50  
 51  /// Program statement that defines some action (or expression) to be carried out.
 52  #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
 53  pub enum Statement {
 54      /// An assert statement.
 55      Assert(AssertStatement),
 56      /// An assignment statement.
 57      Assign(Box<AssignStatement>),
 58      /// A block statement.
 59      Block(Block),
 60      /// An `if` statement.
 61      Conditional(ConditionalStatement),
 62      /// A binding from identifier to constant value.
 63      Const(ConstDeclaration),
 64      /// A binding or set of bindings / variables to declare.
 65      Definition(DefinitionStatement),
 66      /// An expression statement
 67      Expression(ExpressionStatement),
 68      /// A `for` statement.
 69      Iteration(Box<IterationStatement>),
 70      /// A return statement `return expr;`.
 71      Return(ReturnStatement),
 72  }
 73  
 74  impl Statement {
 75      /// Returns a dummy statement made from an empty block `{}`.
 76      pub fn dummy() -> Self {
 77          Block { statements: Vec::new(), span: Default::default(), id: Default::default() }.into()
 78      }
 79  
 80      pub(crate) fn semicolon(&self) -> &'static str {
 81          use Statement::*;
 82  
 83          if matches!(self, Block(..) | Conditional(..) | Iteration(..)) { "" } else { ";" }
 84      }
 85  
 86      pub fn is_empty(self: &Statement) -> bool {
 87          match self {
 88              Statement::Block(block) => block.statements.is_empty(),
 89              Statement::Return(return_) => matches!(return_.expression, Expression::Unit(_)),
 90              _ => false,
 91          }
 92      }
 93  }
 94  
 95  impl fmt::Display for Statement {
 96      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 97          match self {
 98              Statement::Assert(x) => x.fmt(f),
 99              Statement::Assign(x) => x.fmt(f),
100              Statement::Block(x) => x.fmt(f),
101              Statement::Conditional(x) => x.fmt(f),
102              Statement::Const(x) => x.fmt(f),
103              Statement::Definition(x) => x.fmt(f),
104              Statement::Expression(x) => x.fmt(f),
105              Statement::Iteration(x) => x.fmt(f),
106              Statement::Return(x) => x.fmt(f),
107          }
108      }
109  }
110  
111  impl Node for Statement {
112      fn span(&self) -> Span {
113          use Statement::*;
114          match self {
115              Assert(n) => n.span(),
116              Assign(n) => n.span(),
117              Block(n) => n.span(),
118              Conditional(n) => n.span(),
119              Const(n) => n.span(),
120              Definition(n) => n.span(),
121              Expression(n) => n.span(),
122              Iteration(n) => n.span(),
123              Return(n) => n.span(),
124          }
125      }
126  
127      fn set_span(&mut self, span: Span) {
128          use Statement::*;
129          match self {
130              Assert(n) => n.set_span(span),
131              Assign(n) => n.set_span(span),
132              Block(n) => n.set_span(span),
133              Conditional(n) => n.set_span(span),
134              Const(n) => n.set_span(span),
135              Definition(n) => n.set_span(span),
136              Expression(n) => n.set_span(span),
137              Iteration(n) => n.set_span(span),
138              Return(n) => n.set_span(span),
139          }
140      }
141  
142      fn id(&self) -> NodeID {
143          use Statement::*;
144          match self {
145              Assert(n) => n.id(),
146              Assign(n) => n.id(),
147              Block(n) => n.id(),
148              Conditional(n) => n.id(),
149              Const(n) => n.id(),
150              Definition(n) => n.id(),
151              Expression(n) => n.id(),
152              Iteration(n) => n.id(),
153              Return(n) => n.id(),
154          }
155      }
156  
157      fn set_id(&mut self, id: NodeID) {
158          use Statement::*;
159          match self {
160              Assert(n) => n.set_id(id),
161              Assign(n) => n.set_id(id),
162              Block(n) => n.set_id(id),
163              Conditional(n) => n.set_id(id),
164              Const(n) => n.set_id(id),
165              Definition(n) => n.set_id(id),
166              Expression(n) => n.set_id(id),
167              Iteration(n) => n.set_id(id),
168              Return(n) => n.set_id(id),
169          }
170      }
171  }