1use crate::{Identifier, Node, NodeID};
18use leo_span::Span;
19
20use serde::{Deserialize, Serialize};
21use std::fmt;
22
23mod array_access;
24pub use array_access::*;
25
26mod associated_constant;
27pub use associated_constant::*;
28
29mod associated_function;
30pub use associated_function::*;
31
32mod array;
33pub use array::*;
34
35mod binary;
36pub use binary::*;
37
38mod call;
39pub use call::*;
40
41mod cast;
42pub use cast::*;
43
44mod err;
45pub use err::*;
46
47mod member_access;
48pub use member_access::*;
49
50mod repeat;
51pub use repeat::*;
52
53mod struct_init;
54pub use struct_init::*;
55
56mod ternary;
57pub use ternary::*;
58
59mod tuple;
60pub use tuple::*;
61
62mod tuple_access;
63pub use tuple_access::*;
64
65mod unary;
66pub use unary::*;
67
68mod unit;
69pub use unit::*;
70
71mod literal;
72pub use literal::*;
73
74pub mod locator;
75pub use locator::*;
76
77#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
79pub enum Expression {
80 ArrayAccess(Box<ArrayAccess>),
82 AssociatedConstant(AssociatedConstantExpression),
84 AssociatedFunction(AssociatedFunctionExpression),
86 Array(ArrayExpression),
88 Binary(Box<BinaryExpression>),
90 Call(Box<CallExpression>),
92 Cast(Box<CastExpression>),
94 Err(ErrExpression),
97 Identifier(Identifier),
99 Literal(Literal),
101 Locator(LocatorExpression),
103 MemberAccess(Box<MemberAccess>),
105 Repeat(Box<RepeatExpression>),
107 Struct(StructExpression),
109 Ternary(Box<TernaryExpression>),
111 Tuple(TupleExpression),
113 TupleAccess(Box<TupleAccess>),
115 Unary(Box<UnaryExpression>),
117 Unit(UnitExpression),
119}
120
121impl Default for Expression {
122 fn default() -> Self {
123 Expression::Err(Default::default())
124 }
125}
126
127impl Node for Expression {
128 fn span(&self) -> Span {
129 use Expression::*;
130 match self {
131 ArrayAccess(n) => n.span(),
132 Array(n) => n.span(),
133 AssociatedConstant(n) => n.span(),
134 AssociatedFunction(n) => n.span(),
135 Binary(n) => n.span(),
136 Call(n) => n.span(),
137 Cast(n) => n.span(),
138 Err(n) => n.span(),
139 Identifier(n) => n.span(),
140 Literal(n) => n.span(),
141 Locator(n) => n.span(),
142 MemberAccess(n) => n.span(),
143 Repeat(n) => n.span(),
144 Struct(n) => n.span(),
145 Ternary(n) => n.span(),
146 Tuple(n) => n.span(),
147 TupleAccess(n) => n.span(),
148 Unary(n) => n.span(),
149 Unit(n) => n.span(),
150 }
151 }
152
153 fn set_span(&mut self, span: Span) {
154 use Expression::*;
155 match self {
156 ArrayAccess(n) => n.set_span(span),
157 Array(n) => n.set_span(span),
158 AssociatedConstant(n) => n.set_span(span),
159 AssociatedFunction(n) => n.set_span(span),
160 Binary(n) => n.set_span(span),
161 Call(n) => n.set_span(span),
162 Cast(n) => n.set_span(span),
163 Err(n) => n.set_span(span),
164 Identifier(n) => n.set_span(span),
165 Literal(n) => n.set_span(span),
166 Locator(n) => n.set_span(span),
167 MemberAccess(n) => n.set_span(span),
168 Repeat(n) => n.set_span(span),
169 Struct(n) => n.set_span(span),
170 Ternary(n) => n.set_span(span),
171 Tuple(n) => n.set_span(span),
172 TupleAccess(n) => n.set_span(span),
173 Unary(n) => n.set_span(span),
174 Unit(n) => n.set_span(span),
175 }
176 }
177
178 fn id(&self) -> NodeID {
179 use Expression::*;
180 match self {
181 Array(n) => n.id(),
182 ArrayAccess(n) => n.id(),
183 AssociatedConstant(n) => n.id(),
184 AssociatedFunction(n) => n.id(),
185 Binary(n) => n.id(),
186 Call(n) => n.id(),
187 Cast(n) => n.id(),
188 Identifier(n) => n.id(),
189 Literal(n) => n.id(),
190 Locator(n) => n.id(),
191 MemberAccess(n) => n.id(),
192 Repeat(n) => n.id(),
193 Err(n) => n.id(),
194 Struct(n) => n.id(),
195 Ternary(n) => n.id(),
196 Tuple(n) => n.id(),
197 TupleAccess(n) => n.id(),
198 Unary(n) => n.id(),
199 Unit(n) => n.id(),
200 }
201 }
202
203 fn set_id(&mut self, id: NodeID) {
204 use Expression::*;
205 match self {
206 Array(n) => n.set_id(id),
207 ArrayAccess(n) => n.set_id(id),
208 AssociatedConstant(n) => n.set_id(id),
209 AssociatedFunction(n) => n.set_id(id),
210 Binary(n) => n.set_id(id),
211 Call(n) => n.set_id(id),
212 Cast(n) => n.set_id(id),
213 Identifier(n) => n.set_id(id),
214 Literal(n) => n.set_id(id),
215 Locator(n) => n.set_id(id),
216 MemberAccess(n) => n.set_id(id),
217 Repeat(n) => n.set_id(id),
218 Err(n) => n.set_id(id),
219 Struct(n) => n.set_id(id),
220 Ternary(n) => n.set_id(id),
221 Tuple(n) => n.set_id(id),
222 TupleAccess(n) => n.set_id(id),
223 Unary(n) => n.set_id(id),
224 Unit(n) => n.set_id(id),
225 }
226 }
227}
228
229impl fmt::Display for Expression {
230 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
231 use Expression::*;
232 match &self {
233 Array(n) => n.fmt(f),
234 ArrayAccess(n) => n.fmt(f),
235 AssociatedConstant(n) => n.fmt(f),
236 AssociatedFunction(n) => n.fmt(f),
237 Binary(n) => n.fmt(f),
238 Call(n) => n.fmt(f),
239 Cast(n) => n.fmt(f),
240 Err(n) => n.fmt(f),
241 Identifier(n) => n.fmt(f),
242 Literal(n) => n.fmt(f),
243 Locator(n) => n.fmt(f),
244 MemberAccess(n) => n.fmt(f),
245 Repeat(n) => n.fmt(f),
246 Struct(n) => n.fmt(f),
247 Ternary(n) => n.fmt(f),
248 Tuple(n) => n.fmt(f),
249 TupleAccess(n) => n.fmt(f),
250 Unary(n) => n.fmt(f),
251 Unit(n) => n.fmt(f),
252 }
253 }
254}
255
256#[derive(Clone, Copy, Eq, PartialEq)]
257pub(crate) enum Associativity {
258 Left,
259 Right,
260 None,
261}
262
263impl Expression {
264 pub(crate) fn precedence(&self) -> u32 {
265 use Expression::*;
266 match self {
267 Binary(e) => e.precedence(),
268 Cast(_) => 12,
269 Ternary(_) => 14,
270 Array(_)
271 | ArrayAccess(_)
272 | AssociatedConstant(_)
273 | AssociatedFunction(_)
274 | Call(_)
275 | Err(_)
276 | Identifier(_)
277 | Literal(_)
278 | Locator(_)
279 | MemberAccess(_)
280 | Repeat(_)
281 | Struct(_)
282 | Tuple(_)
283 | TupleAccess(_)
284 | Unary(_)
285 | Unit(_) => 20,
286 }
287 }
288
289 pub(crate) fn associativity(&self) -> Associativity {
290 if let Expression::Binary(bin) = self { bin.associativity() } else { Associativity::None }
291 }
292
293 pub fn as_u32(&self) -> Option<u32> {
296 if let Expression::Literal(literal) = &self {
297 if let LiteralVariant::Integer(int_type, s, ..) = &literal.variant {
298 use crate::IntegerType::*;
299 let s = s.replace("_", "");
300
301 return match int_type {
302 U8 => u8::from_str_by_radix(&s).map(|v| v as u32).ok(),
303 U16 => u16::from_str_by_radix(&s).map(|v| v as u32).ok(),
304 U32 => u32::from_str_by_radix(&s).ok(),
305 U64 => u64::from_str_by_radix(&s).ok().and_then(|v| u32::try_from(v).ok()),
306 U128 => u128::from_str_by_radix(&s).ok().and_then(|v| u32::try_from(v).ok()),
307 I8 => i8::from_str_by_radix(&s).ok().and_then(|v| u32::try_from(v).ok()),
308 I16 => i16::from_str_by_radix(&s).ok().and_then(|v| u32::try_from(v).ok()),
309 I32 => i32::from_str_by_radix(&s).ok().and_then(|v| u32::try_from(v).ok()),
310 I64 => i64::from_str_by_radix(&s).ok().and_then(|v| u32::try_from(v).ok()),
311 I128 => i128::from_str_by_radix(&s).ok().and_then(|v| u32::try_from(v).ok()),
312 };
313 } else if let LiteralVariant::Unsuffixed(s) = &literal.variant {
314 let s = s.replace("_", "");
316 return u32::from_str_by_radix(&s).ok();
317 }
318 }
319 None
320 }
321}