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 }