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 mut value = Expression::from_reader(reader, configuration, allocator);
51 if reader.starts_with(")") {
52 reader.advance(1);
53
54 if let Some(ref adjacency) = configuration.adjacency
55 && reader.starts_with_value()
56 {
57 let identifier = reader.parse_identifier();
58 let rhs = Expression {
59 on: T::from_str(identifier),
60 arguments: Vec::new_in(allocator),
61 };
62
63 let mut arguments = Vec::new_in(allocator);
64 arguments.push(value);
65 arguments.push(rhs);
66 value = Expression {
67 on: T::from_str(adjacency.operator.representation),
68 arguments,
69 };
70 }
71
72 value
73 } else {
74 panic!("no close paren {current:?}", current = reader.current());
75 }
76 } else {
77 let top = if let Some(prefix) = configuration
78 .prefix_ternary_operators
79 .iter()
80 .find(|operator| reader.starts_with(operator.parts.0))
81 {
82 reader.advance(prefix.parts.0.len());
88
89 let next = Self::from_reader_with_precedence(
90 reader,
91 configuration,
92 allocator,
93 prefix.precedence,
94 Some(prefix.parts.1),
95 );
96 if reader.starts_with(prefix.parts.1) {
97 reader.advance(prefix.parts.1.len());
98 } else {
99 panic!("{:?}", (reader.current(), prefix.parts.1));
101 }
102
103 let lhs = Self::from_reader_with_precedence(
104 reader,
105 configuration,
106 allocator,
107 prefix.precedence,
108 Some(prefix.parts.2),
109 );
110 if reader.starts_with(prefix.parts.2) {
111 reader.advance(prefix.parts.2.len());
112 } else {
113 panic!()
114 }
115 let rhs = Self::from_reader_with_precedence(
116 reader,
117 configuration,
118 allocator,
119 prefix.precedence,
120 break_before,
121 );
122
123 let mut arguments: Vec<Expression<_>, &Allocator> = Vec::new_in(allocator);
124 arguments.push(next);
125 arguments.push(lhs);
126 arguments.push(rhs);
127
128 let on = T::from_str(prefix.name);
129 Expression { on, arguments }
130 } else if let Some(operator) = configuration
131 .prefix_unary_operators
132 .iter()
133 .find(|operator| reader.starts_with(operator.representation))
134 {
135 reader.advance(operator.representation.len());
141 let operand = Self::from_reader_with_precedence(
142 reader,
143 configuration,
144 allocator,
145 operator.precedence,
146 break_before,
147 );
148
149 let mut arguments: Vec<Expression<_>, &Allocator> = Vec::new_in(allocator);
150 arguments.push(operand);
151 Expression { on: T::from_str(operator.representation), arguments }
152 } else {
153 let identifier = reader.parse_identifier();
154
155 if let Some(ref adjacency) = configuration.adjacency {
156 let parts = identifier
157 .find(|chr| !matches!(chr, '0'..='9' | '.'))
158 .map(|idx| identifier.split_at(idx));
159
160 if let Some((numeric, item)) = parts {
161 let top = if adjacency.functions.contains(&item) {
162 let on = T::from_str(item);
163 Expression::parse_function_call(
164 reader,
165 configuration,
166 allocator,
167 break_before,
168 on,
169 )
170 } else {
171 let (prefix, after) = item.split_at(1);
172 let mut top = Expression {
173 on: T::from_str(prefix),
174 arguments: Vec::new_in(allocator),
175 };
176 for slice in chars_slices(after) {
177 let item = Expression {
178 on: T::from_str(slice),
179 arguments: Vec::new_in(allocator),
180 };
181
182 let mut arguments = Vec::new_in(allocator);
183 arguments.push(item);
184 arguments.push(top);
185 top = Expression {
186 on: T::from_str(adjacency.operator.representation),
187 arguments,
188 };
189 }
190 top
191 };
192 if numeric.is_empty() {
193 top
194 } else {
195 let item = Expression {
196 on: T::from_str(numeric),
197 arguments: Vec::new_in(allocator),
198 };
199
200 let mut arguments = Vec::new_in(allocator);
201 arguments.push(item);
202 arguments.push(top);
203 Expression {
204 on: T::from_str(adjacency.operator.representation),
205 arguments,
206 }
207 }
208 } else {
209 Expression {
210 on: T::from_str(identifier),
211 arguments: Vec::new_in(allocator),
212 }
213 }
214 } else {
215 let on = T::from_str(identifier);
216 Expression::parse_function_call(
217 reader,
218 configuration,
219 allocator,
220 break_before,
221 on,
222 )
223 }
224 };
225
226 Self::append_operators(reader, configuration, allocator, precedence, break_before, top)
227 }
228 }
229
230 fn append_operators(
231 reader: &mut Lexer<'a>,
232 configuration: &'a Configuration,
233 allocator: &'a Allocator,
234 return_precedence: u8,
235 break_before: Option<&'a str>,
236 mut top: Self,
237 ) -> Self {
238 while !reader.finished() {
239 if break_before.is_some_and(|break_before| reader.starts_with(break_before)) {
240 break;
241 }
242
243 top = if let Some(postfix) = configuration
244 .postfix_ternary_operators
245 .iter()
246 .find(|operator| reader.starts_with(operator.parts.0))
247 {
248 if return_precedence > postfix.precedence {
249 return top;
250 }
251
252 reader.advance(postfix.parts.0.len());
253 let lhs = Self::from_reader_with_precedence(
254 reader,
255 configuration,
256 allocator,
257 postfix.precedence,
258 Some(postfix.parts.1),
259 );
260
261 if reader.starts_with(postfix.parts.1) {
262 reader.advance(postfix.parts.1.len());
263 let rhs = Self::from_reader_with_precedence(
264 reader,
265 configuration,
266 allocator,
267 postfix.precedence,
268 Some(postfix.parts.2),
269 );
270
271 if reader.starts_with(postfix.parts.2) {
272 reader.advance(postfix.parts.2.len());
273 } else {
274 panic!()
275 }
276
277 let mut arguments: Vec<Expression<_>, &Allocator> = Vec::new_in(allocator);
278 arguments.push(top);
279 arguments.push(lhs);
280 arguments.push(rhs);
281
282 let on = T::from_str(postfix.name);
283 Expression { on, arguments }
284 } else {
285 let substitute_binary_operator = configuration
286 .binary_operators
287 .iter()
288 .find(|operator| operator.representation == postfix.parts.0);
289
290 if let Some(operator) = substitute_binary_operator {
291 debug_assert!(
292 return_precedence <= operator.precedence,
293 "binary operator {bop_prec} not equal to ternary {tern_prec} ({return_precedence})",
294 bop_prec = operator.precedence,
295 tern_prec = postfix.precedence
296 );
297
298 let mut arguments = Vec::new_in(allocator);
299 arguments.push(top);
300 arguments.push(lhs);
301
302 let on = T::from_str(operator.representation);
303 Expression { on, arguments }
304 } else {
305 panic!(
306 "Expected {part} found {found}",
307 part = postfix.parts.1,
308 found = reader.current()
309 );
310 }
311 }
312 } else if let Some(operator) = configuration
313 .binary_operators
314 .iter()
315 .find(|operator| reader.starts_with(operator.representation))
316 {
317 if return_precedence > operator.precedence {
318 return top;
319 }
320
321 reader.advance(operator.representation.len());
322 let lhs = top;
323 let rhs = Self::from_reader_with_precedence(
324 reader,
325 configuration,
326 allocator,
327 operator.precedence,
328 break_before,
329 );
330
331 let mut arguments = Vec::new_in(allocator);
332 arguments.push(lhs);
333 arguments.push(rhs);
334
335 let on = T::from_str(operator.representation);
336 Expression { on, arguments }
337 } else if let Some(operator) = configuration
338 .postfix_unary_operators
339 .iter()
340 .find(|operator| reader.starts_with(operator.representation))
341 {
342 if return_precedence > operator.precedence {
343 return top;
344 }
345 reader.advance(operator.representation.len());
346 let mut arguments = Vec::new_in(allocator);
347 arguments.push(top);
348
349 let on = T::from_str(operator.representation);
350 Expression { on, arguments }
351 } else if reader.current().starts_with('(')
352 && let Some(adjacency) = &configuration.adjacency
353 {
354 let operator = adjacency.operator;
355 if return_precedence > operator.precedence {
356 return top;
357 }
358
359 let rhs = Self::from_reader_with_precedence(
360 reader,
361 configuration,
362 allocator,
363 operator.precedence,
364 break_before,
365 );
366 let mut arguments = Vec::new_in(allocator);
367 arguments.push(top);
368 arguments.push(rhs);
369 Expression { on: T::from_str(operator.representation), arguments }
370 } else {
371 break;
372 };
373 }
374 top
375 }
376
377 fn parse_function_call(
378 reader: &mut Lexer<'a>,
379 configuration: &'a Configuration,
380 allocator: &'a Allocator,
381 break_before: Option<&'a str>,
382 on: T,
383 ) -> Self {
384 let mut arguments = Vec::new_in(allocator);
385
386 while reader.starts_with_value() {
387 let Configuration {
388 binary_operators,
389 postfix_ternary_operators,
390 postfix_unary_operators,
391 ..
392 } = &configuration;
393
394 let should_break =
395 binary_operators.iter().any(|operator| reader.starts_with(operator.representation))
396 || postfix_ternary_operators
397 .iter()
398 .any(|operator| reader.starts_with(operator.parts.0))
399 || postfix_unary_operators
400 .iter()
401 .any(|operator| reader.starts_with(operator.representation))
402 || break_before.is_some_and(|break_before| reader.starts_with(break_before));
403
404 if should_break {
405 break;
406 }
407
408 let expression = Self::from_reader_with_precedence(
409 reader,
410 configuration,
411 allocator,
412 1,
413 break_before,
414 );
415 arguments.push(expression);
416 }
417
418 Expression { on, arguments }
419 }
420}
421
422fn chars_slices(slice: &str) -> impl Iterator<Item = &str> {
423 slice.char_indices().map(|(idx, chr)| &slice[idx..][..chr.len_utf8()])
424}
425
426pub struct ExpressionRepresentation<'a, T>(pub &'a Expression<'a, T>);
427
428impl<'a, T> std::fmt::Display for ExpressionRepresentation<'a, T>
429where
430 T: std::fmt::Display,
431{
432 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
433 if self.0.arguments.is_empty() {
434 write!(f, "{on}", on = self.0.on)
435 } else {
436 write!(f, "({on}", on = self.0.on)?;
437 for arg in &self.0.arguments {
438 write!(f, " {on}", on = ExpressionRepresentation(arg))?;
439 }
440 write!(f, ")")
441 }
442 }
443}