aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Tolnay <[email protected]>2020-10-12 05:37:15 +0100
committerGitHub <[email protected]>2020-10-12 05:37:15 +0100
commit7118506a2a51a3261087d69a57a1c3f185175829 (patch)
treeb32f4f94a2b4ba7edf1bcc882d17e06da874cc6f
parentff3ac137eda1f20bbdc339bd758301d3082f6636 (diff)
Accept `**` operator as exponentiation (#39)
* Accept `**` operator as exponentiation * Add test of exponentiation
-rw-r--r--src/lex/mod.rs8
-rw-r--r--src/main.rs5
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);