1use std::{collections::VecDeque, fmt};
2use CalcType::{Add, Divide, Multiply, Power, Print, Subtract, Val};
3#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
4pub enum CalcType {
6 Add,
7 Subtract,
8 Multiply,
9 Divide,
10 Power,
11 Print,
12 Val(f64),
13}
14#[derive(Debug, Clone)]
15pub struct EvaluationError {
16 pub message: String,
17}
18
19impl fmt::Display for EvaluationError {
20 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21 write!(f, "Failed evaluation with reason: {}", self.message)
22 }
23}
24
25pub fn str_to_calc_type(string: &str) -> Option<CalcType> {
27 let as_int = string.parse::<f64>();
28 let result = match as_int {
29 Ok(x) => Some(Val(x)),
30 Err(_) => None,
31 };
32
33 if result.is_some() {
34 return result;
35 }
36
37 match string {
38 "+" => Some(Add),
39 "-" => Some(Subtract),
40 "*" => Some(Multiply),
41 "/" => Some(Divide),
42 "^" => Some(Power),
43 "p" => Some(Print),
44
45 _ => None,
46 }
47}
48
49pub fn eval(input: &str, stack: &mut VecDeque<f64>) {
59 let toks = input.split(' ').collect::<Vec<&str>>();
64 let mut ops: VecDeque<CalcType> = VecDeque::new();
65
66 for tok in &toks {
67 let x: CalcType = str_to_calc_type(tok).unwrap();
68
69 match x {
70 Add | Divide | Multiply | Power | Subtract | Print => ops.push_back(x),
71
72 Val(x_) => stack.push_back(x_),
73 }
74 }
75
76 for op in &ops {
77 match op {
78 Add => {
79 let y = &stack.pop_back().unwrap_or(0.0);
80 let x = &stack.pop_back().unwrap_or(0.0);
81 &stack.push_back(x + y)
82 }
83 Subtract => {
84 let y = &stack.pop_back().unwrap_or(0.0);
85 let x = &stack.pop_back().unwrap_or(0.0);
86 &stack.push_back(x - y)
87 }
88 Multiply => {
89 let y = &stack.pop_back().unwrap_or(0.0);
90 let x = &stack.pop_back().unwrap_or(0.0);
91 &stack.push_back(x * y)
92 }
93 Divide => {
94 let y = &stack.pop_back().unwrap_or(0.0);
95 let x = &stack.pop_back().unwrap_or(0.0);
96 &stack.push_back(x / y)
97 }
98 Power => {
99 let y = &stack.pop_back().unwrap_or(0.0);
100 let x = &stack.pop_back().unwrap_or(0.0);
101
102 let result = x.powf(*y);
103 &stack.push_back(result)
104 }
105 Print => &{ println!("{:#?}", stack.iter().last()) },
106 Val(_) => panic!("Unexpected value in the operator stack!"),
107 };
108 }
109
110 println!("{}", stack.iter().last().unwrap_or(&0.0));
111}
112
113pub fn safe_eval(input: &str) -> Result<VecDeque<f64>, EvaluationError> {
134 let mut stack: VecDeque<f64> = VecDeque::new();
136
137 let toks = input.split(' ').collect::<Vec<&str>>();
139 let mut ops: VecDeque<CalcType> = VecDeque::new();
140
141 for tok in &toks {
142 let x: CalcType = match str_to_calc_type(tok) {
143 Some(x) => x,
144 None => {
145 return Err(EvaluationError {
146 message: format!("Invalid token: {}", tok),
147 })
148 }
149 };
150
151 match x {
152 Add | Divide | Multiply | Power | Subtract | Print => ops.push_back(x),
153
154 Val(x_) => stack.push_back(x_),
155 }
156 }
157
158 for op in &ops {
159 match op {
160 Add => {
161 let y = &stack.pop_back().ok_or(EvaluationError {
162 message: "Stack is empty!".to_string(),
163 })?;
164 let x = &stack.pop_back().ok_or(EvaluationError {
165 message: "Stack is empty!".to_string(),
166 })?;
167 &stack.push_back(x + y)
168 }
169 Subtract => {
170 let y = &stack.pop_back().ok_or(EvaluationError {
171 message: "Stack is empty!".to_string(),
172 })?;
173 let x = &stack.pop_back().ok_or(EvaluationError {
174 message: "Stack is empty!".to_string(),
175 })?;
176 &stack.push_back(x - y)
177 }
178 Multiply => {
179 let y = &stack.pop_back().ok_or(EvaluationError {
180 message: "Stack is empty!".to_string(),
181 })?;
182 let x = &stack.pop_back().ok_or(EvaluationError {
183 message: "Stack is empty!".to_string(),
184 })?;
185 &stack.push_back(x * y)
186 }
187 Divide => {
188 let y = &stack.pop_back().ok_or(EvaluationError {
189 message: "Stack is empty!".to_string(),
190 })?;
191 let x = &stack.pop_back().ok_or(EvaluationError {
192 message: "Stack is empty!".to_string(),
193 })?;
194 &stack.push_back(x / y)
195 }
196 Power => {
197 let y = &stack.pop_back().ok_or(EvaluationError {
198 message: "Stack is empty!".to_string(),
199 })?;
200 let x = &stack.pop_back().ok_or(EvaluationError {
201 message: "Stack is empty!".to_string(),
202 })?;
203
204 let result = x.powf(*y);
205 &stack.push_back(result)
206 }
207 Print => &{ println!("{:#?}", stack.iter().last()) },
208 Val(_) => panic!("Unexpected value in the operator stack!"),
209 };
210 }
211
212 Ok(stack)
213}
214
215pub fn safe_eval_with_stack(
242 input: &str,
243 initial_stack: VecDeque<f64>,
244) -> Result<VecDeque<f64>, EvaluationError> {
245 let mut stack = initial_stack;
246 let toks = input.split(' ').collect::<Vec<&str>>();
248 let mut ops: VecDeque<CalcType> = VecDeque::new();
249
250 for tok in &toks {
251 let x: CalcType = match str_to_calc_type(tok) {
252 Some(x) => x,
253 None => {
254 return Err(EvaluationError {
255 message: format!("Invalid token: {}", tok),
256 })
257 }
258 };
259
260 match x {
261 Add | Divide | Multiply | Power | Subtract | Print => ops.push_back(x),
262
263 Val(x_) => stack.push_back(x_),
264 }
265 }
266
267 for op in &ops {
268 match op {
269 Add => {
270 let y = &stack.pop_back().ok_or(EvaluationError {
271 message: "Stack is empty!".to_string(),
272 })?;
273 let x = &stack.pop_back().ok_or(EvaluationError {
274 message: "Stack is empty!".to_string(),
275 })?;
276 &stack.push_back(x + y)
277 }
278 Subtract => {
279 let y = &stack.pop_back().ok_or(EvaluationError {
280 message: "Stack is empty!".to_string(),
281 })?;
282 let x = &stack.pop_back().ok_or(EvaluationError {
283 message: "Stack is empty!".to_string(),
284 })?;
285 &stack.push_back(x - y)
286 }
287 Multiply => {
288 let y = &stack.pop_back().ok_or(EvaluationError {
289 message: "Stack is empty!".to_string(),
290 })?;
291 let x = &stack.pop_back().ok_or(EvaluationError {
292 message: "Stack is empty!".to_string(),
293 })?;
294 &stack.push_back(x * y)
295 }
296 Divide => {
297 let y = &stack.pop_back().ok_or(EvaluationError {
298 message: "Stack is empty!".to_string(),
299 })?;
300 let x = &stack.pop_back().ok_or(EvaluationError {
301 message: "Stack is empty!".to_string(),
302 })?;
303 &stack.push_back(x / y)
304 }
305 Power => {
306 let y = &stack.pop_back().ok_or(EvaluationError {
307 message: "Stack is empty!".to_string(),
308 })?;
309 let x = &stack.pop_back().ok_or(EvaluationError {
310 message: "Stack is empty!".to_string(),
311 })?;
312
313 let result = x.powf(*y);
314 &stack.push_back(result)
315 }
316 Print => &{ println!("{:#?}", stack.iter().last()) },
317 Val(_) => panic!("Unexpected value in the operator stack!"),
318 };
319 }
320
321 Ok(stack)
322}