1mod array_expression;
7mod marker;
8mod range_expression;
9mod tuple_expression;
10
11pub use array_expression::*;
12pub use marker::*;
13pub use range_expression::*;
14pub use tuple_expression::*;
15
16use crate::{src_ref::*, syntax::*, value::*};
17
18pub type ListExpression = Vec<Expression>;
20
21#[derive(Clone, Default)]
23pub enum Expression {
24 #[default]
26 Invalid,
27 Literal(Literal),
29 FormatString(FormatString),
31 ArrayExpression(ArrayExpression),
33 TupleExpression(TupleExpression),
35 Body(Body),
37 If(Box<IfStatement>),
39 Call(Call),
41 QualifiedName(QualifiedName),
43 Marker(Marker),
45 BinaryOp {
47 lhs: Box<Expression>,
49 op: String,
51 rhs: Box<Expression>,
53 src_ref: SrcRef,
55 },
56 UnaryOp {
58 op: String,
60 rhs: Box<Expression>,
62 src_ref: SrcRef,
64 },
65 ArrayElementAccess(Box<Expression>, Box<Expression>, SrcRef),
67 PropertyAccess(Box<Expression>, Identifier, SrcRef),
69
70 AttributeAccess(Box<Expression>, Identifier, SrcRef),
72
73 MethodCall(Box<Expression>, MethodCall, SrcRef),
76}
77
78impl SingleIdentifier for Expression {
79 fn single_identifier(&self) -> Option<&Identifier> {
81 match &self {
82 Expression::Invalid
83 | Expression::Literal(..)
84 | Expression::FormatString(..)
85 | Expression::Marker(..)
86 | Expression::PropertyAccess(..)
87 | Expression::AttributeAccess(..)
88 | Expression::MethodCall(..)
89 | Expression::ArrayExpression(..)
90 | Expression::TupleExpression(..)
91 | Expression::Body(..)
92 | Expression::If(..)
93 | Expression::Call(..) => None,
94
95 Expression::QualifiedName(qualified_name) => qualified_name.single_identifier(),
96 Expression::BinaryOp {
97 lhs,
98 op: _,
99 rhs,
100 src_ref: _,
101 } => {
102 let l = lhs.single_identifier();
103 let r = rhs.single_identifier();
104 if l == r || r.is_none() {
105 l
106 } else if l.is_none() {
107 r
108 } else {
109 None
110 }
111 }
112 Expression::UnaryOp {
113 op: _,
114 rhs,
115 src_ref: _,
116 } => rhs.single_identifier(),
117 Expression::ArrayElementAccess(expression, ..) => expression.single_identifier(),
118 }
119 }
120}
121
122impl SrcReferrer for Expression {
123 fn src_ref(&self) -> crate::src_ref::SrcRef {
124 match self {
125 Self::Invalid => SrcRef(None),
126 Self::Literal(l) => l.src_ref(),
127 Self::FormatString(fs) => fs.src_ref(),
128 Self::ArrayExpression(le) => le.src_ref(),
129 Self::TupleExpression(te) => te.src_ref(),
130 Self::Call(c) => c.src_ref(),
131 Self::Body(b) => b.src_ref(),
132 Self::If(i) => i.src_ref(),
133 Self::QualifiedName(q) => q.src_ref(),
134 Self::Marker(m) => m.src_ref(),
135 Self::BinaryOp {
136 lhs: _,
137 op: _,
138 rhs: _,
139 src_ref,
140 } => src_ref.clone(),
141 Self::UnaryOp {
142 op: _,
143 rhs: _,
144 src_ref,
145 } => src_ref.clone(),
146 Self::ArrayElementAccess(_, _, src_ref) => src_ref.clone(),
147 Self::PropertyAccess(_, _, src_ref) => src_ref.clone(),
148 Self::AttributeAccess(_, _, src_ref) => src_ref.clone(),
149 Self::MethodCall(_, _, src_ref) => src_ref.clone(),
150 }
151 }
152}
153
154impl std::fmt::Display for Expression {
155 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
156 match self {
157 Self::Literal(literal) => write!(f, "{literal}"),
158 Self::FormatString(format_string) => write!(f, "{format_string}"),
159 Self::ArrayExpression(array_expression) => write!(f, "{array_expression}"),
160 Self::TupleExpression(tuple_expression) => write!(f, "{tuple_expression}"),
161 Self::BinaryOp {
162 lhs,
163 op,
164 rhs,
165 src_ref: _,
166 } => write!(f, "{lhs} {op} {rhs}"),
167 Self::UnaryOp {
168 op,
169 rhs,
170 src_ref: _,
171 } => write!(f, "{op}{rhs}"),
172 Self::ArrayElementAccess(lhs, rhs, _) => write!(f, "{lhs}[{rhs}]"),
173 Self::PropertyAccess(lhs, rhs, _) => write!(f, "{lhs}.{rhs}"),
174 Self::AttributeAccess(lhs, rhs, _) => write!(f, "{lhs}#{rhs}"),
175 Self::MethodCall(lhs, method_call, _) => write!(f, "{lhs}.{method_call}"),
176 Self::Call(call) => write!(f, "{call}"),
177 Self::Body(body) => write!(f, "{body}"),
178 Self::If(if_) => write!(f, "{if_}"),
179 Self::QualifiedName(qualified_name) => write!(f, "{qualified_name}"),
180 Self::Marker(marker) => write!(f, "{marker}"),
181 _ => unimplemented!(),
182 }
183 }
184}
185
186impl std::fmt::Debug for Expression {
187 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
188 match self {
189 Self::Literal(literal) => write!(f, "{literal}"),
190 Self::FormatString(format_string) => write!(f, "{format_string:?}"),
191 Self::ArrayExpression(array_expression) => write!(f, "{array_expression:?}"),
192 Self::TupleExpression(tuple_expression) => write!(f, "{tuple_expression:?}"),
193 Self::BinaryOp {
194 lhs,
195 op,
196 rhs,
197 src_ref: _,
198 } => write!(f, "{lhs:?} {op} {rhs:?}"),
199 Self::UnaryOp {
200 op,
201 rhs,
202 src_ref: _,
203 } => write!(f, "{op}{rhs:?}"),
204 Self::ArrayElementAccess(lhs, rhs, _) => write!(f, "{lhs:?}[{rhs:?}]"),
205 Self::PropertyAccess(lhs, rhs, _) => write!(f, "{lhs:?}.{rhs:?}"),
206 Self::AttributeAccess(lhs, rhs, _) => write!(f, "{lhs:?}#{rhs:?}"),
207 Self::MethodCall(lhs, method_call, _) => write!(f, "{lhs:?}.{method_call:?}"),
208 Self::Call(call) => write!(f, "{call:?}"),
209 Self::Body(body) => write!(f, "{body:?}"),
210 Self::If(if_) => write!(f, "{if_:?}"),
211 Self::QualifiedName(qualified_name) => write!(f, "{qualified_name:?}"),
212 Self::Marker(marker) => write!(f, "{marker:?}"),
213 _ => unimplemented!(),
214 }
215 }
216}
217
218impl TreeDisplay for Value {
219 fn tree_print(&self, f: &mut std::fmt::Formatter, depth: TreeState) -> std::fmt::Result {
220 write!(f, "{:depth$}Value: {value}", "", value = self)
221 }
222}
223
224impl TreeDisplay for Expression {
225 fn tree_print(&self, f: &mut std::fmt::Formatter, mut depth: TreeState) -> std::fmt::Result {
226 match self {
227 Expression::Literal(literal) => literal.tree_print(f, depth),
228 Expression::FormatString(format_string) => format_string.tree_print(f, depth),
229 Expression::ArrayExpression(array_expression) => array_expression.tree_print(f, depth),
230 Expression::TupleExpression(tuple_expression) => tuple_expression.tree_print(f, depth),
231 Expression::BinaryOp {
232 lhs,
233 op,
234 rhs,
235 src_ref: _,
236 } => {
237 writeln!(f, "{:depth$}BinaryOp '{op}':", "")?;
238 depth.indent();
239 lhs.tree_print(f, depth)?;
240 rhs.tree_print(f, depth)
241 }
242 Expression::UnaryOp {
243 op,
244 rhs,
245 src_ref: _,
246 } => {
247 writeln!(f, "{:depth$}UnaryOp '{op}':", "")?;
248 depth.indent();
249 rhs.tree_print(f, depth)
250 }
251 Expression::ArrayElementAccess(lhs, rhs, _) => {
252 writeln!(f, "{:depth$}ArrayElementAccess:", "")?;
253 depth.indent();
254 lhs.tree_print(f, depth)?;
255 rhs.tree_print(f, depth)
256 }
257 Expression::PropertyAccess(lhs, rhs, _) => {
258 writeln!(f, "{:depth$}FieldAccess:", "")?;
259 depth.indent();
260 lhs.tree_print(f, depth)?;
261 rhs.tree_print(f, depth)
262 }
263 Expression::AttributeAccess(lhs, rhs, _) => {
264 writeln!(f, "{:depth$}AttributeAccess:", "")?;
265 depth.indent();
266 lhs.tree_print(f, depth)?;
267 rhs.tree_print(f, depth)
268 }
269 Expression::MethodCall(lhs, method_call, _) => {
270 writeln!(f, "{:depth$}MethodCall:", "")?;
271 depth.indent();
272 lhs.tree_print(f, depth)?;
273 method_call.tree_print(f, depth)
274 }
275 Expression::Call(call) => call.tree_print(f, depth),
276 Expression::Body(body) => body.tree_print(f, depth),
277 Expression::If(if_) => if_.tree_print(f, depth),
278 Expression::QualifiedName(qualified_name) => qualified_name.tree_print(f, depth),
279 Expression::Marker(marker) => marker.tree_print(f, depth),
280 Expression::Invalid => write!(f, "{}", crate::invalid!(EXPRESSION)),
281 }
282 }
283}
284
285impl AsRef<Self> for Expression {
286 fn as_ref(&self) -> &Self {
287 self
288 }
289}
290
291impl PartialEq for Expression {
292 fn eq(&self, other: &Self) -> bool {
293 match (self, other) {
294 (Self::Literal(l0), Self::Literal(r0)) => l0 == r0,
295 (Self::FormatString(l0), Self::FormatString(r0)) => l0 == r0,
296 (Self::ArrayExpression(l0), Self::ArrayExpression(r0)) => l0 == r0,
297 (Self::TupleExpression(l0), Self::TupleExpression(r0)) => l0 == r0,
298 (Self::QualifiedName(l0), Self::QualifiedName(r0)) => l0 == r0,
299 (
300 Self::BinaryOp {
301 lhs: l_lhs,
302 op: l_op,
303 rhs: l_rhs,
304 src_ref: l_src_ref,
305 },
306 Self::BinaryOp {
307 lhs: r_lhs,
308 op: r_op,
309 rhs: r_rhs,
310 src_ref: r_src_ref,
311 },
312 ) => l_lhs == r_lhs && l_op == r_op && l_rhs == r_rhs && l_src_ref == r_src_ref,
313 (
314 Self::UnaryOp {
315 op: l_op,
316 rhs: l_rhs,
317 src_ref: l_src_ref,
318 },
319 Self::UnaryOp {
320 op: r_op,
321 rhs: r_rhs,
322 src_ref: r_src_ref,
323 },
324 ) => l_op == r_op && l_rhs == r_rhs && l_src_ref == r_src_ref,
325 (Self::ArrayElementAccess(l0, l1, l2), Self::ArrayElementAccess(r0, r1, r2)) => {
326 l0 == r0 && l1 == r1 && l2 == r2
327 }
328 _ => unreachable!("PartialEq implemented for const expressions only"),
329 }
330 }
331}