1use crate::{
2 error::{EquationError, EquationErrorType},
3 item::Item,
4 item::{FunctionalOperator, LeftAssociativeOperator},
5};
6
7#[derive(Debug)]
9pub struct ParseStream(String);
10
11impl ParseStream {
12 pub fn new(stream: String) -> ParseStream {
14 ParseStream(stream)
15 }
16 pub fn parse_items(&self) -> Result<Vec<Item>, EquationError> {
18 let mut depths: Vec<(Vec<Item>, Option<char>)> = Vec::new();
19 depths.push((Vec::new(), None));
20 let mut i = 0;
21 let mut current_numeric: Option<String> = None;
22 while i < self.0.len() {
23 let current_group = depths.last_mut().unwrap();
24 let c = self.0.chars().nth(i).ok_or(EquationError::new(
25 "Unexpected end of stream".to_string(),
26 EquationErrorType::UnexpectedToken,
27 ))?;
28 i += 1;
29
30 match (¤t_numeric, c) {
31 (Some(val), c) if c == '.' || c.is_numeric() => {
32 current_numeric = Some(
33 {
34 let mut x = val.clone();
35 x.push(c);
36 x
37 }
38 .to_owned(),
39 );
40 continue;
41 }
42 (None, c) if c.is_numeric() => {
43 current_numeric = Some(c.to_string());
44 continue;
45 }
46 (Some(val), _) => {
47 current_group.0.push(Item::Value(val.parse().map_err(|_| {
48 EquationError::new(
49 "Invalid number".to_string(),
50 EquationErrorType::UnexpectedToken,
51 )
52 })?));
53 current_numeric = None;
54 i -= 1;
55 continue;
56 }
57 (None, c) if c.is_alphabetic() => {
58 let mut temp_i = i;
60 while temp_i < self.0.len() {
61 let temp_c = self.0.chars().nth(temp_i).ok_or(EquationError::new(
62 "Unexpected end of stream".to_string(),
63 EquationErrorType::UnexpectedToken,
64 ))?;
65 temp_i += 1;
66 if temp_c.is_alphabetic() {
67 continue;
68 } else {
69 break;
70 }
71 }
72 if temp_i >= self.0.len() - 1 {
74 temp_i = self.0.len() + 1;
75 }
76 let var_name = self.0.get((i - 1)..(temp_i - 1)).unwrap();
77 current_group.0.push(match var_name {
79 "log" => FunctionalOperator::Log.into(),
80 "ln" => FunctionalOperator::Ln.into(),
81 "sin" => FunctionalOperator::Sin.into(),
82 "cos" => FunctionalOperator::Cos.into(),
83 "tan" => FunctionalOperator::Tan.into(),
84 "cot" => FunctionalOperator::Cot.into(),
85 "sec" => FunctionalOperator::Sec.into(),
86 "csc" => FunctionalOperator::Csc.into(),
87 "arcsin" => FunctionalOperator::Arcsin.into(),
88 "arccos" => FunctionalOperator::Arccos.into(),
89 "arctan" => FunctionalOperator::Arctan.into(),
90 "arccot" => FunctionalOperator::Arccot.into(),
91 "arcsec" => FunctionalOperator::Arcsec.into(),
92 "arccsc" => FunctionalOperator::Arccsc.into(),
93 _ => var_name.to_string().into(),
94 });
95 i = temp_i - 1;
96 }
97 (None, c) if c == '(' || c == '[' => {
98 depths.push((Vec::new(), Some(if c == '(' { ')' } else { ']' })));
99 }
100 (None, c) if Some(c) == current_group.1 => {
101 let current_group = depths.pop().unwrap();
102 if let Some(parent_group) = depths.last_mut() {
103 parent_group.0.push(current_group.0.into());
104 }
105 }
106 (None, c) => current_group.0.push(match c {
107 '+' => LeftAssociativeOperator::Add.into(),
108 '-' => LeftAssociativeOperator::Subtract.into(),
109 '*' => LeftAssociativeOperator::Multiply.into(),
110 '/' => LeftAssociativeOperator::Divide.into(),
111 '^' => LeftAssociativeOperator::Power.into(),
112 ' ' => continue,
113 _ => {
114 return Err(EquationError::new(
115 "Unexpected token".to_string(),
116 EquationErrorType::UnexpectedToken,
117 ))
118 }
119 }),
120 }
121
122 if c.is_numeric() && current_numeric.is_some() || c == '.' {
123 continue;
124 } else if c.is_numeric() {
125 current_numeric = Some(c.to_string());
126 continue;
127 }
128
129 if c == ' ' {
130 continue;
131 }
132 }
133 if let Some(val) = current_numeric {
134 depths
135 .last_mut()
136 .unwrap()
137 .0
138 .push(Item::Value(val.parse().map_err(|_| {
139 EquationError::new(
140 "Invalid number".to_string(),
141 EquationErrorType::UnexpectedToken,
142 )
143 })?));
144 }
145 if depths.len() != 1 {
146 return Err(EquationError::new(
147 "Unexpected end of stream (Missing Closing Delimiter)".to_string(),
148 EquationErrorType::MissingItems,
149 ));
150 }
151 Ok(depths.pop().unwrap().0)
152 }
153}