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