1use crate::{Allocator, Configuration, Lexer, Literal};
2
3#[cfg(not(feature = "stable"))]
4use std::alloc::Allocator as AllocatorTrait;
5
6#[cfg(feature = "stable")]
7use allocator_api2::vec::Vec;
8
9#[derive(Debug)]
10pub struct Expression<'a, T> {
11 pub on: T,
12 pub arguments: Vec<Expression<'a, T>, &'a Allocator>,
13}
14
15impl<'a, T> Expression<'a, T>
16where
17 T: Literal<'a>,
18{
19 pub fn from_string(
20 source: &'a str,
21 configuration: &'a Configuration,
22 allocator: &'a Allocator,
23 ) -> Self {
24 let mut reader = Lexer::new(source);
25 let this = Self::from_reader(&mut reader, configuration, allocator);
26 reader.skip();
27 if !reader.finished() {
28 panic!("not finished {:?}", reader.current());
29 }
30 this
31 }
32
33 pub fn from_reader(
34 reader: &mut Lexer<'a>,
35 configuration: &'a Configuration,
36 allocator: &'a Allocator,
37 ) -> Self {
38 Self::from_reader_with_precedence(reader, configuration, allocator, 0, None)
39 }
40
41 pub(crate) fn from_reader_with_precedence(
42 reader: &mut Lexer<'a>,
43 configuration: &'a Configuration,
44 allocator: &'a Allocator,
45 precedence: u8,
46 break_before: Option<&'a str>,
47 ) -> Self {
48 if reader.starts_with("(") {
49 reader.advance(1);
50 let value = Expression::from_reader(reader, configuration, allocator);
51 if reader.starts_with(")") {
52 reader.advance(1);
53 value
54 } else {
55 panic!("no close paren {current:?}", current = reader.current());
56 }
57 } else {
58 let top = if let Some(prefix) = configuration
59 .prefix_ternary_operators
60 .iter()
61 .find(|operator| reader.starts_with(operator.parts.0))
62 {
63 reader.advance(prefix.parts.0.len());
69
70 let next = Self::from_reader_with_precedence(
71 reader,
72 configuration,
73 allocator,
74 prefix.precedence,
75 Some(prefix.parts.1),
76 );
77 if reader.starts_with(prefix.parts.1) {
78 reader.advance(prefix.parts.1.len());
79 } else {
80 panic!("{:?}", (reader.current(), prefix.parts.1));
82 }
83
84 let lhs = Self::from_reader_with_precedence(
85 reader,
86 configuration,
87 allocator,
88 prefix.precedence,
89 Some(prefix.parts.2),
90 );
91 if reader.starts_with(prefix.parts.2) {
92 reader.advance(prefix.parts.2.len());
93 } else {
94 panic!()
95 }
96 let rhs = Self::from_reader_with_precedence(
97 reader,
98 configuration,
99 allocator,
100 prefix.precedence,
101 break_before,
102 );
103
104 let mut arguments: Vec<Expression<_>, &Allocator> = Vec::new_in(allocator);
105 arguments.push(next);
106 arguments.push(lhs);
107 arguments.push(rhs);
108
109 let on = T::from_str(prefix.name);
110 Expression { on, arguments }
111 } else if let Some(operator) = configuration
112 .prefix_unary_operators
113 .iter()
114 .find(|operator| reader.starts_with(operator.representation))
115 {
116 reader.advance(operator.representation.len());
122 let operand = Self::from_reader_with_precedence(
123 reader,
124 configuration,
125 allocator,
126 operator.precedence,
127 break_before,
128 );
129
130 let mut arguments: Vec<Expression<_>, &Allocator> = Vec::new_in(allocator);
131 arguments.push(operand);
132 Expression { on: T::from_str(operator.representation), arguments }
133 } else {
134 let identifier = reader.parse_identifier();
135
136 if let Some(ref adjacency) = configuration.adjacency
137 && !adjacency.functions.contains(&identifier)
138 {
139 let mut chars = identifier.char_indices();
141
142 let first: Self = {
143 let (idx, chr) = chars.next().unwrap();
144 let identifier = &identifier[idx..(idx + chr.len_utf8())];
145 Expression {
146 on: T::from_str(identifier),
147 arguments: Vec::new_in(allocator),
148 }
149 };
150
151 let mut top = first;
152
153 for (idx, chr) in chars {
154 let identifier = &identifier[idx..(idx + chr.len_utf8())];
155 let rhs = Expression {
156 on: T::from_str(identifier),
157 arguments: Vec::new_in(allocator),
158 };
159
160 let mut arguments = Vec::new_in(allocator);
161 arguments.push(top);
162 arguments.push(rhs);
163 top = Expression {
164 on: T::from_str(adjacency.operator.representation),
165 arguments,
166 };
167 }
168
169 top
170 } else {
171 let on = T::from_str(identifier);
172
173 let mut arguments = Vec::new_in(allocator);
174
175 while reader.starts_with_value() {
177 let Configuration {
178 binary_operators,
179 postfix_ternary_operators,
180 postfix_unary_operators,
181 ..
182 } = &configuration;
183
184 let should_break = binary_operators
185 .iter()
186 .any(|operator| reader.starts_with(operator.representation))
187 || postfix_ternary_operators
188 .iter()
189 .any(|operator| reader.starts_with(operator.parts.0))
190 || postfix_unary_operators
191 .iter()
192 .any(|operator| reader.starts_with(operator.representation))
193 || break_before
194 .is_some_and(|break_before| reader.starts_with(break_before));
195
196 if should_break {
197 break;
198 }
199
200 let expression = Self::from_reader_with_precedence(
201 reader,
202 configuration,
203 allocator,
204 1,
205 break_before,
206 );
207 arguments.push(expression);
208 }
209
210 Expression { on, arguments }
211 }
212 };
213
214 Self::append_operators(reader, configuration, allocator, precedence, break_before, top)
215 }
216 }
217
218 fn append_operators(
219 reader: &mut Lexer<'a>,
220 configuration: &'a Configuration,
221 allocator: &'a Allocator,
222 return_precedence: u8,
223 break_before: Option<&'a str>,
224 mut top: Self,
225 ) -> Self {
226 while !reader.finished() {
227 if break_before.is_some_and(|break_before| reader.starts_with(break_before)) {
228 break;
229 }
230
231 top = if let Some(postfix) = configuration
232 .postfix_ternary_operators
233 .iter()
234 .find(|operator| reader.starts_with(operator.parts.0))
235 {
236 if return_precedence > postfix.precedence {
237 return top;
238 }
239
240 reader.advance(postfix.parts.0.len());
241 let lhs = Self::from_reader_with_precedence(
242 reader,
243 configuration,
244 allocator,
245 postfix.precedence,
246 Some(postfix.parts.1),
247 );
248
249 if reader.starts_with(postfix.parts.1) {
250 reader.advance(postfix.parts.1.len());
251 let rhs = Self::from_reader_with_precedence(
252 reader,
253 configuration,
254 allocator,
255 postfix.precedence,
256 Some(postfix.parts.2),
257 );
258
259 if reader.starts_with(postfix.parts.2) {
260 reader.advance(postfix.parts.2.len());
261 } else {
262 panic!()
263 }
264
265 let mut arguments: Vec<Expression<_>, &Allocator> = Vec::new_in(allocator);
266 arguments.push(top);
267 arguments.push(lhs);
268 arguments.push(rhs);
269
270 let on = T::from_str(postfix.name);
271 Expression { on, arguments }
272 } else {
273 let substitute_binary_operator = configuration
274 .binary_operators
275 .iter()
276 .find(|operator| operator.representation == postfix.parts.0);
277
278 if let Some(operator) = substitute_binary_operator {
279 debug_assert!(
280 return_precedence <= operator.precedence,
281 "binary operator {bop_prec} not equal to ternary {tern_prec} ({return_precedence})",
282 bop_prec = operator.precedence,
283 tern_prec = postfix.precedence
284 );
285
286 let mut arguments = Vec::new_in(allocator);
287 arguments.push(top);
288 arguments.push(lhs);
289
290 let on = T::from_str(operator.representation);
291 Expression { on, arguments }
292 } else {
293 panic!(
294 "Expected {part} found {found}",
295 part = postfix.parts.1,
296 found = reader.current()
297 );
298 }
299 }
300 } else if let Some(operator) = configuration
301 .binary_operators
302 .iter()
303 .find(|operator| reader.starts_with(operator.representation))
304 {
305 if return_precedence > operator.precedence {
306 return top;
307 }
308
309 reader.advance(operator.representation.len());
310 let lhs = top;
311 let rhs = Self::from_reader_with_precedence(
312 reader,
313 configuration,
314 allocator,
315 operator.precedence,
316 break_before,
317 );
318
319 let mut arguments = Vec::new_in(allocator);
320 arguments.push(lhs);
321 arguments.push(rhs);
322
323 let on = T::from_str(operator.representation);
324 Expression { on, arguments }
325 } else if let Some(operator) = configuration
326 .postfix_unary_operators
327 .iter()
328 .find(|operator| reader.starts_with(operator.representation))
329 {
330 if return_precedence > operator.precedence {
331 return top;
332 }
333 reader.advance(operator.representation.len());
334 let mut arguments = Vec::new_in(allocator);
335 arguments.push(top);
336
337 let on = T::from_str(operator.representation);
338 Expression { on, arguments }
339 } else if reader.current().starts_with('(')
340 && let Some(adjacency) = &configuration.adjacency
341 {
342 let operator = adjacency.operator;
343 if return_precedence > operator.precedence {
344 return top;
345 }
346
347 let rhs = Self::from_reader_with_precedence(
348 reader,
349 configuration,
350 allocator,
351 operator.precedence,
352 break_before,
353 );
354 let mut arguments = Vec::new_in(allocator);
355 arguments.push(top);
356 arguments.push(rhs);
357 Expression { on: T::from_str(operator.representation), arguments }
358 } else {
359 break;
360 };
361 }
362 top
363 }
364}
365
366pub struct ExpressionRepresentation<'a, T>(pub &'a Expression<'a, T>);
367
368impl<'a, T> std::fmt::Display for ExpressionRepresentation<'a, T>
369where
370 T: std::fmt::Display,
371{
372 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
373 if self.0.arguments.is_empty() {
374 write!(f, "{on}", on = self.0.on)
375 } else {
376 write!(f, "({on}", on = self.0.on)?;
377 for arg in &self.0.arguments {
378 write!(f, " {on}", on = ExpressionRepresentation(arg))?;
379 }
380 write!(f, ")")
381 }
382 }
383}