diff options
author | David Tolnay <[email protected]> | 2020-10-12 05:37:15 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-10-12 05:37:15 +0100 |
commit | 7118506a2a51a3261087d69a57a1c3f185175829 (patch) | |
tree | b32f4f94a2b4ba7edf1bcc882d17e06da874cc6f | |
parent | ff3ac137eda1f20bbdc339bd758301d3082f6636 (diff) |
Accept `**` operator as exponentiation (#39)
* Accept `**` operator as exponentiation
* Add test of exponentiation
-rw-r--r-- | src/lex/mod.rs | 8 | ||||
-rw-r--r-- | src/main.rs | 5 |
2 files changed, 12 insertions, 1 deletions
diff --git a/src/lex/mod.rs b/src/lex/mod.rs index b21bafb..3222c12 100644 --- a/src/lex/mod.rs +++ b/src/lex/mod.rs | |||
@@ -129,7 +129,8 @@ pub fn lexer(input: &str, prev_ans: Option<f64>) -> Result<Vec<Token>, CalcError | |||
129 | let mut result: Vec<Token> = vec![]; | 129 | let mut result: Vec<Token> = vec![]; |
130 | let mut last_char_is_op = true; | 130 | let mut last_char_is_op = true; |
131 | 131 | ||
132 | for letter in input.chars() { | 132 | let mut chars = input.chars().peekable(); |
133 | while let Some(mut letter) = chars.next() { | ||
133 | match letter { | 134 | match letter { |
134 | '0'..='9' | '.' => { | 135 | '0'..='9' | '.' => { |
135 | if !char_vec.is_empty() { | 136 | if !char_vec.is_empty() { |
@@ -209,6 +210,11 @@ pub fn lexer(input: &str, prev_ans: Option<f64>) -> Result<Vec<Token>, CalcError | |||
209 | } | 210 | } |
210 | '/' | '*' | '%' | '^' | '!' => { | 211 | '/' | '*' | '%' | '^' | '!' => { |
211 | drain_stack(&mut num_vec, &mut char_vec, &mut result); | 212 | drain_stack(&mut num_vec, &mut char_vec, &mut result); |
213 | if letter == '*' && chars.peek() == Some(&'*') { | ||
214 | // Accept `**` operator as meaning `^` (exponentation). | ||
215 | let _ = chars.next(); | ||
216 | letter = '^'; | ||
217 | } | ||
212 | let operator_token: Token = OPERATORS.get(&letter).unwrap().clone(); | 218 | let operator_token: Token = OPERATORS.get(&letter).unwrap().clone(); |
213 | result.push(operator_token); | 219 | result.push(operator_token); |
214 | last_char_is_op = true; | 220 | last_char_is_op = true; |
diff --git a/src/main.rs b/src/main.rs index 2a2cf9d..bc22ce2 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -227,6 +227,11 @@ mod tests { | |||
227 | assert_eq!(32., evaled); | 227 | assert_eq!(32., evaled); |
228 | } | 228 | } |
229 | #[test] | 229 | #[test] |
230 | fn exponentiation() { | ||
231 | let evaled = eval_math_expression("2 ** 2 ** 3", None).unwrap(); | ||
232 | assert_eq!(256., evaled); // 2^(2^3), not (2^2)^3 | ||
233 | } | ||
234 | #[test] | ||
230 | fn floating_ops() { | 235 | fn floating_ops() { |
231 | let evaled = eval_math_expression("1.2816 + 1 + 1.2816/1.2", Some(0f64)).unwrap(); | 236 | let evaled = eval_math_expression("1.2816 + 1 + 1.2816/1.2", Some(0f64)).unwrap(); |
232 | assert_eq!(3.3496, evaled); | 237 | assert_eq!(3.3496, evaled); |