1mod assert;
18pub use assert::*;
19
20mod assign;
21pub use assign::*;
22
23mod block;
24pub use block::*;
25
26mod conditional;
27pub use conditional::*;
28
29mod const_;
30pub use const_::*;
31
32mod definition;
33pub use definition::*;
34
35mod expression;
36pub use expression::*;
37
38mod iteration;
39pub use iteration::*;
40
41mod return_;
42pub use return_::*;
43
44use crate::{Expression, Node, NodeID};
45
46use leo_span::Span;
47
48use serde::Serialize;
49use std::fmt;
50
51#[derive(Clone, PartialEq, Eq, Hash, Serialize, Debug)]
53pub enum Statement {
54 Assert(AssertStatement),
56 Assign(Box<AssignStatement>),
58 Block(Block),
60 Conditional(ConditionalStatement),
62 Const(ConstDeclaration),
64 Definition(DefinitionStatement),
66 Expression(ExpressionStatement),
68 Iteration(Box<IterationStatement>),
70 Return(ReturnStatement),
72}
73
74impl Statement {
75 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 {
88 match self {
89 Statement::Block(block) => block.statements.is_empty(),
90 Statement::Return(return_) => matches!(return_.expression, Expression::Unit(_)),
91 _ => false,
92 }
93 }
94
95 pub fn is_removable(self: &Statement) -> bool {
97 self.is_empty() && !matches!(self, Statement::Return(_))
98 }
99}
100
101impl fmt::Display for Statement {
102 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103 match self {
104 Statement::Assert(x) => x.fmt(f),
105 Statement::Assign(x) => x.fmt(f),
106 Statement::Block(x) => x.fmt(f),
107 Statement::Conditional(x) => x.fmt(f),
108 Statement::Const(x) => x.fmt(f),
109 Statement::Definition(x) => x.fmt(f),
110 Statement::Expression(x) => x.fmt(f),
111 Statement::Iteration(x) => x.fmt(f),
112 Statement::Return(x) => x.fmt(f),
113 }
114 }
115}
116
117impl Node for Statement {
118 fn span(&self) -> Span {
119 use Statement::*;
120 match self {
121 Assert(n) => n.span(),
122 Assign(n) => n.span(),
123 Block(n) => n.span(),
124 Conditional(n) => n.span(),
125 Const(n) => n.span(),
126 Definition(n) => n.span(),
127 Expression(n) => n.span(),
128 Iteration(n) => n.span(),
129 Return(n) => n.span(),
130 }
131 }
132
133 fn set_span(&mut self, span: Span) {
134 use Statement::*;
135 match self {
136 Assert(n) => n.set_span(span),
137 Assign(n) => n.set_span(span),
138 Block(n) => n.set_span(span),
139 Conditional(n) => n.set_span(span),
140 Const(n) => n.set_span(span),
141 Definition(n) => n.set_span(span),
142 Expression(n) => n.set_span(span),
143 Iteration(n) => n.set_span(span),
144 Return(n) => n.set_span(span),
145 }
146 }
147
148 fn id(&self) -> NodeID {
149 use Statement::*;
150 match self {
151 Assert(n) => n.id(),
152 Assign(n) => n.id(),
153 Block(n) => n.id(),
154 Conditional(n) => n.id(),
155 Const(n) => n.id(),
156 Definition(n) => n.id(),
157 Expression(n) => n.id(),
158 Iteration(n) => n.id(),
159 Return(n) => n.id(),
160 }
161 }
162
163 fn set_id(&mut self, id: NodeID) {
164 use Statement::*;
165 match self {
166 Assert(n) => n.set_id(id),
167 Assign(n) => n.set_id(id),
168 Block(n) => n.set_id(id),
169 Conditional(n) => n.set_id(id),
170 Const(n) => n.set_id(id),
171 Definition(n) => n.set_id(id),
172 Expression(n) => n.set_id(id),
173 Iteration(n) => n.set_id(id),
174 Return(n) => n.set_id(id),
175 }
176 }
177}