aboutsummaryrefslogtreecommitdiff
path: root/src/lex
diff options
context:
space:
mode:
authorIvan Tham <[email protected]>2019-08-03 08:22:01 +0100
committerIvan Tham <[email protected]>2019-08-03 08:22:01 +0100
commitae36284d60b828869ede5a77343ccb307046b69a (patch)
tree6096e09a01b472e3415bf8a0401f198644a1089d /src/lex
parent3b630aa5cf2fd58b10bb8a24c9818fda1d5049af (diff)
Fix clippy lints
Diffstat (limited to 'src/lex')
-rw-r--r--src/lex/mod.rs127
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
8use crate::CONFIGURATION; 8use crate::CONFIGURATION;
9 9
10use crate::error::{ 10use crate::error::{CalcError, Math};
11 CalcError,
12 Math
13};
14 11
15#[derive(Debug, Copy, Clone, PartialEq)] 12#[derive(Debug, Copy, Clone, PartialEq)]
16pub struct Operator { 13pub struct Operator {
@@ -21,22 +18,22 @@ pub struct Operator {
21} 18}
22 19
23impl Operator { 20impl 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
52impl Function { 49impl 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)]
73pub enum Token { 64pub 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
81lazy_static! { 72lazy_static! {
@@ -128,8 +119,8 @@ lazy_static! {
128 }; 119 };
129} 120}
130 121
131fn factorial (n: f64) -> f64 { 122fn 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
135pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { 126pub 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
267fn is_radian_mode(x: f64, is_radian: bool) -> f64 { 268fn 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 }