general_parser/
expression.rs

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(source: &'a str, config: &Configuration, allocator: &'a Allocator) -> Self {
20		let mut reader = Lexer::new(source);
21		let this = Self::from_reader(&mut reader, config, allocator);
22		if !reader.finished() {
23			panic!("not finished {}", reader.current());
24		}
25		this
26	}
27
28	pub fn from_reader(
29		reader: &mut Lexer<'a>,
30		config: &Configuration,
31		allocator: &'a Allocator,
32	) -> Self {
33		Self::from_reader_with_precedence(reader, config, allocator, 0)
34	}
35
36	pub(crate) fn from_reader_with_precedence(
37		reader: &mut Lexer<'a>,
38		config: &Configuration,
39		allocator: &'a Allocator,
40		precedence: u8,
41	) -> Self {
42		let operator = config
43			.prefix_unary_operators
44			.iter()
45			.find(|operator| reader.starts_with(operator.representation));
46
47		let top = if let Some(operator) = operator {
48			// hmm
49			// if precedence > operator.precedence {
50			//     return top;
51			// }
52			reader.advance(operator.representation.len());
53			let operand =
54				Self::from_reader_with_precedence(reader, config, allocator, operator.precedence);
55			let mut arguments: Vec<Expression<_>, &Allocator> = Vec::new_in(allocator);
56			arguments.push(operand);
57			Expression { on: T::from_str(operator.representation), arguments }
58		} else if reader.starts_with("(") {
59			reader.advance(1);
60			let value = Expression::from_reader(reader, config, allocator);
61			if reader.starts_with(")") {
62				reader.advance(1);
63			} else {
64				panic!("no close paren {current:?}", current = reader.current());
65			};
66
67			value
68		} else {
69			let identifier = reader.parse_identifier();
70
71			if let Some(ref adjacency) = config.adjacency
72				&& !adjacency.functions.contains(&identifier)
73			{
74				let mut chars = identifier.char_indices();
75
76				let first: Self = {
77					let (idx, chr) = chars.next().unwrap();
78					let identifier = &identifier[idx..(idx + chr.len_utf8())];
79					Expression { on: T::from_str(identifier), arguments: Vec::new_in(allocator) }
80				};
81
82				let mut top = first;
83
84				for (idx, chr) in chars {
85					let identifier = &identifier[idx..(idx + chr.len_utf8())];
86					let rhs = Expression {
87						on: T::from_str(identifier),
88						arguments: Vec::new_in(allocator),
89					};
90
91					let mut arguments = Vec::new_in(allocator);
92					arguments.push(top);
93					arguments.push(rhs);
94					top = Expression {
95						on: T::from_str(adjacency.operator.representation),
96						arguments,
97					};
98				}
99
100				top
101			} else {
102				let on = T::from_str(identifier);
103
104				let mut arguments = Vec::new_in(allocator);
105				// TODO WIP
106				if precedence == 0 {
107					while reader.starts_with_value() {
108						let expression =
109							Self::from_reader_with_precedence(reader, config, allocator, 1);
110						arguments.push(expression);
111					}
112				}
113
114				Expression { on, arguments }
115			}
116		};
117		Self::append_operators(reader, config, allocator, precedence, top)
118	}
119
120	fn append_operators(
121		reader: &mut Lexer<'a>,
122		config: &Configuration,
123		allocator: &'a Allocator,
124		return_precedence: u8,
125		mut top: Self,
126	) -> Self {
127		while !reader.finished() {
128			let binary_operator = config
129				.binary_operators
130				.iter()
131				.find(|operator| reader.starts_with(operator.representation));
132
133			if let Some(operator) = binary_operator {
134				if return_precedence > operator.precedence {
135					return top;
136				}
137
138				reader.advance(operator.representation.len());
139				let lhs = top;
140				let rhs = Self::from_reader_with_precedence(
141					reader,
142					config,
143					allocator,
144					operator.precedence,
145				);
146
147				let mut arguments = Vec::new_in(allocator);
148				arguments.push(lhs);
149				arguments.push(rhs);
150
151				top = Expression { on: T::from_str(operator.representation), arguments };
152			} else {
153				let unary_operator = config
154					.postfix_unary_operators
155					.iter()
156					.find(|operator| reader.starts_with(operator.representation));
157
158				if let Some(operator) = unary_operator {
159					if return_precedence > operator.precedence {
160						return top;
161					}
162					reader.advance(operator.representation.len());
163					let mut arguments = Vec::new_in(allocator);
164					arguments.push(top);
165
166					top = Expression { on: T::from_str(operator.representation), arguments };
167				} else if reader.current().starts_with('(')
168					&& let Some(adjacency) = &config.adjacency
169				{
170					let operator = adjacency.operator;
171					if return_precedence > operator.precedence {
172						return top;
173					}
174
175					let rhs = Self::from_reader_with_precedence(
176						reader,
177						config,
178						allocator,
179						operator.precedence,
180					);
181					let mut arguments = Vec::new_in(allocator);
182					arguments.push(top);
183					arguments.push(rhs);
184					top = Expression { on: T::from_str(operator.representation), arguments };
185				} else {
186					break;
187				}
188			}
189		}
190		top
191	}
192}