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