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