diff options
author | Ivan Tham <[email protected]> | 2019-08-03 08:22:01 +0100 |
---|---|---|
committer | Ivan Tham <[email protected]> | 2019-08-03 08:22:01 +0100 |
commit | ae36284d60b828869ede5a77343ccb307046b69a (patch) | |
tree | 6096e09a01b472e3415bf8a0401f198644a1089d /src/lex | |
parent | 3b630aa5cf2fd58b10bb8a24c9818fda1d5049af (diff) |
Fix clippy lints
Diffstat (limited to 'src/lex')
-rw-r--r-- | src/lex/mod.rs | 127 |
1 files changed, 64 insertions, 63 deletions
diff --git a/src/lex/mod.rs b/src/lex/mod.rs index c82c17e..48e07be 100644 --- a/src/lex/mod.rs +++ b/src/lex/mod.rs | |||
@@ -7,10 +7,7 @@ use std::collections::HashMap; | |||
7 | 7 | ||
8 | use crate::CONFIGURATION; | 8 | use crate::CONFIGURATION; |
9 | 9 | ||
10 | use crate::error::{ | 10 | use crate::error::{CalcError, Math}; |
11 | CalcError, | ||
12 | Math | ||
13 | }; | ||
14 | 11 | ||
15 | #[derive(Debug, Copy, Clone, PartialEq)] | 12 | #[derive(Debug, Copy, Clone, PartialEq)] |
16 | pub struct Operator { | 13 | pub struct Operator { |
@@ -21,22 +18,22 @@ pub struct Operator { | |||
21 | } | 18 | } |
22 | 19 | ||
23 | impl Operator { | 20 | impl Operator { |
24 | fn token_from_op(token: char, | 21 | fn token_from_op( |
25 | operation: fn(f64, f64) -> f64, | 22 | token: char, |
26 | precedence: u8, | 23 | operation: fn(f64, f64) -> f64, |
27 | is_left_associative: bool) -> Token { | 24 | precedence: u8, |
28 | Token::Operator( | 25 | is_left_associative: bool, |
29 | Operator { | 26 | ) -> Token { |
30 | token, | 27 | Token::Operator(Operator { |
31 | operation, | 28 | token, |
32 | precedence, | 29 | operation, |
33 | is_left_associative | 30 | precedence, |
34 | } | 31 | is_left_associative, |
35 | ) | 32 | }) |
36 | } | 33 | } |
37 | pub fn operate(self, x: f64, y: f64) -> Result<f64, CalcError> { | 34 | pub fn operate(self, x: f64, y: f64) -> Result<f64, CalcError> { |
38 | if self.token == '/' && y == 0. { | 35 | if self.token == '/' && y == 0. { |
39 | return Err(CalcError::Math(Math::DivideByZero)) | 36 | Err(CalcError::Math(Math::DivideByZero)) |
40 | } else { | 37 | } else { |
41 | Ok((self.operation)(x, y)) | 38 | Ok((self.operation)(x, y)) |
42 | } | 39 | } |
@@ -51,31 +48,25 @@ pub struct Function { | |||
51 | 48 | ||
52 | impl Function { | 49 | impl Function { |
53 | fn token_from_fn(token: String, relation: fn(f64) -> f64) -> Token { | 50 | fn token_from_fn(token: String, relation: fn(f64) -> f64) -> Token { |
54 | Token::Function( | 51 | Token::Function(Function { token, relation }) |
55 | Function { | ||
56 | token, | ||
57 | relation | ||
58 | } | ||
59 | ) | ||
60 | } | 52 | } |
61 | pub fn apply(self, arg: f64) -> Result<f64, CalcError> { | 53 | pub fn apply(self, arg: f64) -> Result<f64, CalcError> { |
62 | let result = (self.relation)(arg); | 54 | let result = (self.relation)(arg); |
63 | if !result.is_finite() { | 55 | if !result.is_finite() { |
64 | return Err(CalcError::Math(Math::OutOfBounds)); | 56 | Err(CalcError::Math(Math::OutOfBounds)) |
65 | } else { | 57 | } else { |
66 | Ok(result) | 58 | Ok(result) |
67 | } | 59 | } |
68 | } | 60 | } |
69 | } | 61 | } |
70 | 62 | ||
71 | |||
72 | #[derive(Debug, Clone, PartialEq)] | 63 | #[derive(Debug, Clone, PartialEq)] |
73 | pub enum Token { | 64 | pub enum Token { |
74 | Operator(Operator), | 65 | Operator(Operator), |
75 | Num(f64), | 66 | Num(f64), |
76 | Function(Function), | 67 | Function(Function), |
77 | LParen, | 68 | LParen, |
78 | RParen | 69 | RParen, |
79 | } | 70 | } |
80 | 71 | ||
81 | lazy_static! { | 72 | lazy_static! { |
@@ -128,8 +119,8 @@ lazy_static! { | |||
128 | }; | 119 | }; |
129 | } | 120 | } |
130 | 121 | ||
131 | fn factorial (n: f64) -> f64 { | 122 | fn factorial(n: f64) -> f64 { |
132 | n.signum() * (1.. n.abs() as u64 +1).fold(1, |p, n| p*n) as f64 | 123 | n.signum() * (1..=n.abs() as u64).fold(1, |p, n| p * n) as f64 |
133 | } | 124 | } |
134 | 125 | ||
135 | pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { | 126 | pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { |
@@ -141,22 +132,34 @@ pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { | |||
141 | for letter in input.chars() { | 132 | for letter in input.chars() { |
142 | match letter { | 133 | match letter { |
143 | '0'...'9' | '.' => { | 134 | '0'...'9' | '.' => { |
144 | if char_vec.len() > 0 { | 135 | if !char_vec.is_empty() { |
145 | if let Some(_) = FUNCTIONS.get(&char_vec[..]) { | 136 | if FUNCTIONS.get(&char_vec[..]).is_some() { |
146 | return Err(CalcError::Syntax(format!("Function '{}' expected parentheses", char_vec))) | 137 | return Err(CalcError::Syntax(format!( |
138 | "Function '{}' expected parentheses", | ||
139 | char_vec | ||
140 | ))); | ||
147 | } else { | 141 | } else { |
148 | return Err(CalcError::Syntax(format!("Unexpected character '{}'", char_vec))) | 142 | return Err(CalcError::Syntax(format!( |
143 | "Unexpected character '{}'", | ||
144 | char_vec | ||
145 | ))); | ||
149 | } | 146 | } |
150 | } | 147 | } |
151 | num_vec.push(letter); | 148 | num_vec.push(letter); |
152 | last_char_is_op = false; | 149 | last_char_is_op = false; |
153 | }, | 150 | } |
154 | '_' => { | 151 | '_' => { |
155 | if char_vec.len() > 0 { | 152 | if !char_vec.is_empty() { |
156 | if let Some(_) = FUNCTIONS.get(&char_vec[..]) { | 153 | if FUNCTIONS.get(&char_vec[..]).is_some() { |
157 | return Err(CalcError::Syntax(format!("Function '{}' expected parentheses", char_vec))) | 154 | return Err(CalcError::Syntax(format!( |
155 | "Function '{}' expected parentheses", | ||
156 | char_vec | ||
157 | ))); | ||
158 | } else { | 158 | } else { |
159 | return Err(CalcError::Syntax(format!("Unexpected character '{}'", char_vec))) | 159 | return Err(CalcError::Syntax(format!( |
160 | "Unexpected character '{}'", | ||
161 | char_vec | ||
162 | ))); | ||
160 | } | 163 | } |
161 | } | 164 | } |
162 | let parse_num = num_vec.parse::<f64>().ok(); | 165 | let parse_num = num_vec.parse::<f64>().ok(); |
@@ -165,7 +168,7 @@ pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { | |||
165 | result.push(OPERATORS.get(&'*').unwrap().clone()); | 168 | result.push(OPERATORS.get(&'*').unwrap().clone()); |
166 | num_vec.clear(); | 169 | num_vec.clear(); |
167 | } | 170 | } |
168 | last_char_is_op = false; | 171 | last_char_is_op = false; |
169 | result.push(Token::Num(prev_ans)); | 172 | result.push(Token::Num(prev_ans)); |
170 | } | 173 | } |
171 | 'a'...'z' | 'A'...'Z' => { | 174 | 'a'...'z' | 'A'...'Z' => { |
@@ -177,7 +180,7 @@ pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { | |||
177 | } | 180 | } |
178 | char_vec.push(letter); | 181 | char_vec.push(letter); |
179 | last_char_is_op = false; | 182 | last_char_is_op = false; |
180 | }, | 183 | } |
181 | '+' | '-' => { | 184 | '+' | '-' => { |
182 | let op_token = OPERATORS.get(&letter).unwrap().clone(); | 185 | let op_token = OPERATORS.get(&letter).unwrap().clone(); |
183 | let parse_num = num_vec.parse::<f64>().ok(); | 186 | let parse_num = num_vec.parse::<f64>().ok(); |
@@ -194,27 +197,32 @@ pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { | |||
194 | result.push(op_token); | 197 | result.push(op_token); |
195 | } else if last_char_is_op { | 198 | } else if last_char_is_op { |
196 | result.push(Token::LParen); | 199 | result.push(Token::LParen); |
197 | result.push(Token::Num((letter.to_string() + "1").parse::<f64>().unwrap())); | 200 | result.push(Token::Num( |
201 | (letter.to_string() + "1").parse::<f64>().unwrap(), | ||
202 | )); | ||
198 | result.push(Token::RParen); | 203 | result.push(Token::RParen); |
199 | result.push(Operator::token_from_op('*', |x, y| x * y, 10, true)); | 204 | result.push(Operator::token_from_op('*', |x, y| x * y, 10, true)); |
200 | } | 205 | } |
201 | }, | 206 | } |
202 | '/' | '*' | '%' | '^' | '!' => { | 207 | '/' | '*' | '%' | '^' | '!' => { |
203 | drain_stack(&mut num_vec, &mut char_vec, &mut result); | 208 | drain_stack(&mut num_vec, &mut char_vec, &mut result); |
204 | let operator_token: Token = OPERATORS.get(&letter).unwrap().clone(); | 209 | let operator_token: Token = OPERATORS.get(&letter).unwrap().clone(); |
205 | result.push(operator_token); | 210 | result.push(operator_token); |
206 | last_char_is_op = true; | 211 | last_char_is_op = true; |
207 | if letter == '!' { | 212 | if letter == '!' { |
208 | result.push(Token::Num(1.)); | 213 | result.push(Token::Num(1.)); |
209 | last_char_is_op = false; | 214 | last_char_is_op = false; |
210 | } | 215 | } |
211 | }, | 216 | } |
212 | '(' => { | 217 | '(' => { |
213 | if char_vec.len() > 0 { | 218 | if !char_vec.is_empty() { |
214 | if let Some(res) = FUNCTIONS.get(&char_vec[..]) { | 219 | if let Some(res) = FUNCTIONS.get(&char_vec[..]) { |
215 | result.push(res.clone()); | 220 | result.push(res.clone()); |
216 | } else { | 221 | } else { |
217 | return Err(CalcError::Syntax(format!("Unknown function '{}'", char_vec))) | 222 | return Err(CalcError::Syntax(format!( |
223 | "Unknown function '{}'", | ||
224 | char_vec | ||
225 | ))); | ||
218 | } | 226 | } |
219 | char_vec.clear(); | 227 | char_vec.clear(); |
220 | } else { | 228 | } else { |
@@ -226,26 +234,19 @@ pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { | |||
226 | } | 234 | } |
227 | } | 235 | } |
228 | 236 | ||
229 | if let Some(x) = result.last() { | 237 | if let Some(Token::RParen) = result.last() { |
230 | match x { | 238 | result.push(OPERATORS.get(&'*').unwrap().clone()); |
231 | Token::RParen => { | ||
232 | result.push(OPERATORS.get(&'*').unwrap().clone()); | ||
233 | }, | ||
234 | _ => {} | ||
235 | }; | ||
236 | } | 239 | } |
237 | result.push(Token::LParen); | 240 | result.push(Token::LParen); |
238 | last_char_is_op = true; | 241 | last_char_is_op = true; |
239 | }, | 242 | } |
240 | ')' => { | 243 | ')' => { |
241 | drain_stack(&mut num_vec, &mut char_vec, &mut result); | 244 | drain_stack(&mut num_vec, &mut char_vec, &mut result); |
242 | result.push(Token::RParen); | 245 | result.push(Token::RParen); |
243 | last_char_is_op = false; | 246 | last_char_is_op = false; |
244 | }, | ||
245 | ' ' => {}, | ||
246 | _ => { | ||
247 | return Err(CalcError::Syntax(format!("Unexpected token: '{}'", letter))) | ||
248 | } | 247 | } |
248 | ' ' => {} | ||
249 | _ => return Err(CalcError::Syntax(format!("Unexpected token: '{}'", letter))), | ||
249 | } | 250 | } |
250 | } | 251 | } |
251 | // println!("{:?}", result); | 252 | // println!("{:?}", result); |
@@ -266,7 +267,7 @@ fn drain_stack(num_vec: &mut String, char_vec: &mut String, result: &mut Vec<Tok | |||
266 | 267 | ||
267 | fn is_radian_mode(x: f64, is_radian: bool) -> f64 { | 268 | fn is_radian_mode(x: f64, is_radian: bool) -> f64 { |
268 | if is_radian { | 269 | if is_radian { |
269 | return x | 270 | x |
270 | } else { | 271 | } else { |
271 | x.to_radians() | 272 | x.to_radians() |
272 | } | 273 | } |