Skip to content

Commit 2272873

Browse files
committed
Updating code and tests
1 parent 04b1c61 commit 2272873

File tree

5 files changed

+98
-15
lines changed

5 files changed

+98
-15
lines changed

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,4 @@ pub mod rpn_resolver;
112112
pub mod session;
113113
/// Token
114114
pub mod token;
115+

src/rpn_resolver.rs

+27-15
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,6 @@ impl RpnResolver<'_> {
193193
}
194194
},
195195

196-
/* If the token is an operator, op1, then:
197-
while there is an operator, op2, at the top of the stack, and op1 is left-associative
198-
and its precedence is less than or equal to that of op2,
199-
or op1 is right-associative and its precedence is less than that of op2:
200-
pop op2 off the stack, onto the output list;
201-
push op1 on the stack.*/
202196
Token::Operator(_op) => {
203197
let op1: Token<'_> = t.clone();
204198

@@ -239,23 +233,22 @@ impl RpnResolver<'_> {
239233
/* After all tokens are read, pop remaining operators from the stack and add them to the list. */
240234
operators_stack.reverse();
241235
operators_stack.iter().for_each(|t| postfix_stack.push_back(t.clone()));
242-
//postfix_stack.pop_front()
243-
//postfix_stack.extend(operators_stack.iter());
244-
236+
245237
debug!(
246-
"Inspecting... EOF - OUT {} - OP - {}", DisplayThisDeque(&postfix_stack), DisplayThatVec(&operators_stack)
238+
"DEBUG: EOF - OUT {} - OP - {}", DisplayThisDeque(&postfix_stack), DisplayThatVec(&operators_stack)
247239
);
248240

249241
(postfix_stack, local_heap)
250242
}
251243

252244
fn factorial_helper(n: BigInt) -> BigInt {
253-
if n == Zero::zero(){
254-
One::one()
255-
} else {
256-
n.checked_mul(&RpnResolver::factorial_helper(n.checked_sub(&One::one()).expect("It should not happen")))
257-
.expect("It should not happen.")
245+
if n == BigInt::zero() {
246+
return BigInt::one();
258247
}
248+
249+
let previous = n.checked_sub(&BigInt::one()).expect("Subtraction underflow");
250+
let sub_result = RpnResolver::factorial_helper(previous);
251+
n.checked_mul(&sub_result).expect("Multiplication overflow")
259252
}
260253
}
261254

@@ -297,4 +290,23 @@ mod tests {
297290
b
298291
);
299292
}
293+
294+
#[test]
295+
fn test_factorial() {
296+
assert_eq!(RpnResolver::factorial_helper(BigInt::from(5)), BigInt::from(120));
297+
}
298+
299+
#[test]
300+
fn test_resolve() {
301+
let mut resolver = RpnResolver {
302+
rpn_expr: VecDeque::from(vec![
303+
Token::Operand(Number::NaturalNumber(BigInt::from(1u8))),
304+
Token::Operand(Number::NaturalNumber(BigInt::from(2u8))),
305+
Token::Operator(Operator::Add),
306+
]),
307+
local_heap: Rc::new(RefCell::new(HashMap::new())),
308+
};
309+
assert_eq!(resolver.resolve().unwrap(), Number::NaturalNumber(BigInt::from(3u8)));
310+
}
311+
300312
}

src/session.rs

+22
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,25 @@ impl Session {
7777
.insert(key.to_string(), Number::DecimalNumber(value));
7878
}
7979
}
80+
81+
82+
#[cfg(test)]
83+
mod tests {
84+
use super::*;
85+
use crate::token::Number;
86+
87+
#[test]
88+
fn test_session() {
89+
let session = Session::init();
90+
let mut resolver: RpnResolver = session.process("1+2*3/(4-5)");
91+
assert_eq!(resolver.resolve().unwrap(), Number::DecimalNumber(-5.0));
92+
}
93+
94+
#[test]
95+
fn test_session_set() {
96+
let session = Session::init();
97+
session.set("x", 4);
98+
let mut resolver: RpnResolver = session.process("x+2*3/(4-5)");
99+
assert_eq!(resolver.resolve().unwrap(), Number::DecimalNumber(-2.0));
100+
}
101+
}

src/token.rs

+32
Original file line numberDiff line numberDiff line change
@@ -502,4 +502,36 @@ mod tests {
502502
);
503503
assert_eq!(Token::tokenize("("), Some(Token::Bracket(Bracket::Open)));
504504
}
505+
506+
#[test]
507+
fn test_operator_priority() {
508+
assert_eq!(
509+
Token::operator_priority(Token::Operator(Operator::Add)),
510+
(1, Associate::LeftAssociative)
511+
);
512+
assert_eq!(
513+
Token::operator_priority(Token::Operator(Operator::Sub)),
514+
(1, Associate::LeftAssociative)
515+
);
516+
assert_eq!(
517+
Token::operator_priority(Token::Operator(Operator::Mul)),
518+
(2, Associate::LeftAssociative)
519+
);
520+
assert_eq!(
521+
Token::operator_priority(Token::Operator(Operator::Div)),
522+
(2, Associate::LeftAssociative)
523+
);
524+
assert_eq!(
525+
Token::operator_priority(Token::Operator(Operator::Pow)),
526+
(3, Associate::RightAssociative)
527+
);
528+
assert_eq!(
529+
Token::operator_priority(Token::Operator(Operator::Une)),
530+
(4, Associate::RightAssociative)
531+
);
532+
assert_eq!(
533+
Token::operator_priority(Token::Operator(Operator::Fac)),
534+
(5, Associate::LeftAssociative)
535+
);
536+
}
505537
}

tests/integration_tests.rs

+16
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ fn test_expressions() {
2222
"pi * 4. + 2^pi",
2323
Number::DecimalNumber(std::f64::consts::PI * 4.0 + 2.0f64.powf(std::f64::consts::PI))
2424
);
25+
resolve!(
26+
"2^3 * 4 + 5^2",
27+
Number::NaturalNumber(BigInt::from(8 * 4 + 25))
28+
);
2529
resolve!(
2630
"sin(pi / 4) + cos(pi / 4)",
2731
Number::DecimalNumber(1.414213562373095)
@@ -78,6 +82,10 @@ fn test_expressions() {
7882
)
7983
);
8084
resolve!("((10 + 5) - 3 * ( 9 / 3 )) + 2", Number::DecimalNumber(8.0));
85+
resolve!(
86+
"2^3^2 - 3^3",
87+
Number::NaturalNumber(BigInt::from(512 - 27))
88+
);
8189
}
8290

8391
#[test]
@@ -111,3 +119,11 @@ fn test_sharing_session() {
111119
assert!(b == 3265920i64);
112120
}
113121
}
122+
123+
#[test]
124+
fn test_session_set() {
125+
let session = Session::init();
126+
session.set("x", 4);
127+
let mut resolver: RpnResolver = session.process("x+2*3/(4-5)");
128+
assert_eq!(resolver.resolve().unwrap(), Number::DecimalNumber(-2.0));
129+
}

0 commit comments

Comments
 (0)