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(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 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 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}