1
1
use std:: { collections:: { HashMap , VecDeque } , rc:: Rc , cell:: RefCell , fmt:: Display } ;
2
2
use crate :: {
3
3
parser:: Parser ,
4
- token:: { self , MathFunction , Number , Operator , Token , ZERO } ,
4
+ token:: { self , MathFunction , Number , Operator , Token } ,
5
5
} ;
6
6
use anyhow:: anyhow;
7
7
use log:: debug;
8
+ use num:: { BigInt , One , ToPrimitive , Zero } ;
8
9
9
10
static MALFORMED_ERR : & str = "Runtime Error: The mathematical expression is malformed." ;
10
11
static DIVISION_ZERO_ERR : & str = "Runtime error: Divide by zero." ;
@@ -22,6 +23,7 @@ pub struct RpnResolver<'a> {
22
23
}
23
24
24
25
impl RpnResolver < ' _ > {
26
+
25
27
/// Generates a new [`RpnResolver`] instance with borrowed heap
26
28
///
27
29
pub fn parse_with_borrowed_heap < ' a > (
@@ -41,14 +43,18 @@ impl RpnResolver<'_> {
41
43
/// This method evaluates the rpn expression stack
42
44
///
43
45
pub fn resolve ( & mut self ) -> anyhow:: Result < Number > {
46
+
47
+ let zero: Number = Number :: NaturalNumber ( Zero :: zero ( ) ) ;
48
+ let minus_one: Number = Number :: NaturalNumber ( BigInt :: from ( -1 ) ) ;
49
+
44
50
let mut result_stack: VecDeque < Number > = VecDeque :: new ( ) ;
45
51
46
52
let mut last_var_ref: Option < & str > = None ;
47
53
48
54
for t in & self . rpn_expr {
49
55
match t {
50
56
Token :: Operand ( n) => {
51
- result_stack. push_back ( * n ) ;
57
+ result_stack. push_back ( n . clone ( ) ) ;
52
58
}
53
59
Token :: Operator ( op) => {
54
60
let right_value: Number = result_stack
@@ -60,23 +66,23 @@ impl RpnResolver<'_> {
60
66
. pop_back ( )
61
67
. ok_or_else ( || anyhow ! ( "{} {}" , MALFORMED_ERR , "Invalid Left Operand." ) ) ?
62
68
} else {
63
- ZERO
69
+ zero . clone ( )
64
70
} ;
65
71
66
72
match op {
67
73
Operator :: Add => result_stack. push_back ( left_value + right_value) ,
68
74
Operator :: Sub => result_stack. push_back ( left_value - right_value) ,
69
75
Operator :: Mul => result_stack. push_back ( left_value * right_value) ,
70
76
Operator :: Div => {
71
- if right_value == ZERO {
77
+ if right_value == zero {
72
78
return Err ( anyhow ! ( DIVISION_ZERO_ERR ) ) ;
73
79
}
74
80
left_value = Number :: DecimalNumber ( left_value. into ( ) ) ;
75
81
result_stack. push_back ( left_value / right_value) ;
76
82
}
77
83
Operator :: Pow => {
78
- if right_value < ZERO {
79
- if left_value == ZERO {
84
+ if right_value < zero {
85
+ if left_value == zero {
80
86
return Err ( anyhow ! ( DIVISION_ZERO_ERR ) ) ;
81
87
}
82
88
left_value = Number :: DecimalNumber ( left_value. into ( ) ) ;
@@ -86,24 +92,25 @@ impl RpnResolver<'_> {
86
92
Operator :: Eql => {
87
93
if let Some ( var) = last_var_ref {
88
94
self . local_heap . borrow_mut ( )
89
- . insert ( var. to_string ( ) , right_value) ;
90
- debug ! ( "Heap {:?}" , self . local_heap ) ;
95
+ . insert ( var. to_string ( ) , right_value. clone ( ) ) ;
96
+
91
97
result_stack. push_back ( right_value) ;
92
98
} else {
93
99
return Err ( anyhow ! ( NO_VARIABLE_ERR ) ) ;
94
100
}
95
101
}
96
102
Operator :: Fac => {
97
103
// factorial. Only for natural numbers
98
- let v = i32 :: from ( right_value) ;
99
- if v< 0 {
100
- println ! ( "Warning: Factorial of a Negative or Decimal number has not been yet implemented." ) ;
104
+ let v = BigInt :: from ( right_value) ;
105
+ if v. partial_cmp ( & Zero :: zero ( ) ) == Some ( std :: cmp :: Ordering :: Less ) {
106
+ eprintln ! ( "Warning: Factorial of a Negative or Decimal number has not been yet implemented." ) ;
101
107
}
102
- result_stack. push_back ( Number :: NaturalNumber ( ( 1 ..=v) . product ( ) ) ) ;
108
+ let res = Self :: factorial_helper ( v) ;
109
+ result_stack. push_back ( Number :: NaturalNumber ( res) ) ;
103
110
}
104
111
Operator :: Une => {
105
112
//# unary neg
106
- result_stack. push_back ( right_value * token :: MINUS_ONE ) ;
113
+ result_stack. push_back ( right_value * minus_one . clone ( ) ) ;
107
114
}
108
115
}
109
116
}
@@ -114,7 +121,7 @@ impl RpnResolver<'_> {
114
121
let n = heap
115
122
. get ( * v)
116
123
. unwrap_or ( & Number :: DecimalNumber ( 0. ) ) ;
117
- result_stack. push_back ( * n ) ;
124
+ result_stack. push_back ( n . clone ( ) ) ;
118
125
}
119
126
Token :: Function ( fun) => {
120
127
let value: Number = result_stack
@@ -165,14 +172,13 @@ impl RpnResolver<'_> {
165
172
let mut postfix_stack: VecDeque < Token > = VecDeque :: new ( ) ;
166
173
167
174
/* Scan the infix expression from left to right. */
168
- //infix_stack.iter().for_each(|t: &Token| {
169
175
for t in infix_stack {
170
176
match * t {
171
177
/* If the token is an operand, add it to the output list. */
172
- Token :: Operand ( _) => postfix_stack. push_back ( * t ) ,
178
+ Token :: Operand ( _) => postfix_stack. push_back ( t . clone ( ) ) ,
173
179
174
180
/* If the token is a left parenthesis, push it on the stack. */
175
- Token :: Bracket ( token:: Bracket :: Open ) => operators_stack. push ( * t ) ,
181
+ Token :: Bracket ( token:: Bracket :: Open ) => operators_stack. push ( t . clone ( ) ) ,
176
182
177
183
/* If the token is a right parenthesis:
178
184
Pop the stack and add operators to the output list until you encounter a left parenthesis.
@@ -194,52 +200,63 @@ impl RpnResolver<'_> {
194
200
pop op2 off the stack, onto the output list;
195
201
push op1 on the stack.*/
196
202
Token :: Operator ( _op) => {
197
- let op1: Token < ' _ > = * t ;
203
+ let op1: Token < ' _ > = t . clone ( ) ;
198
204
199
205
while !operators_stack. is_empty ( ) {
200
206
let op2: & Token = operators_stack. last ( ) . unwrap ( ) ;
201
207
match op2 {
202
208
Token :: Operator ( _) => {
203
- if Token :: compare_operator_priority ( op1, * op2) {
204
- postfix_stack. push_back ( operators_stack. pop ( ) . unwrap ( ) ) ;
209
+ if Token :: compare_operator_priority ( op1. clone ( ) , op2. clone ( ) ) {
210
+ postfix_stack. push_back ( operators_stack. pop ( ) . expect ( "It should not happen." ) ) ;
205
211
} else {
206
212
break ;
207
213
}
208
214
} ,
209
215
Token :: Function ( _) => {
210
- postfix_stack. push_back ( operators_stack. pop ( ) . unwrap ( ) ) ;
216
+ postfix_stack. push_back ( operators_stack. pop ( ) . expect ( "It should not happen." ) ) ;
211
217
}
212
218
_ => break ,
213
219
}
214
220
}
215
- operators_stack. push ( op1) ;
221
+ operators_stack. push ( op1. clone ( ) ) ;
216
222
} ,
217
223
218
224
Token :: Function ( _) => {
219
- operators_stack. push ( * t ) ;
225
+ operators_stack. push ( t . clone ( ) ) ;
220
226
} ,
221
227
222
228
/* If the token is a variable, add it to the output list and to the local_heap with a default value*/
223
229
Token :: Variable ( s) => {
224
- postfix_stack. push_back ( * t ) ;
230
+ postfix_stack. push_back ( t . clone ( ) ) ;
225
231
let s = s. to_lowercase ( ) ;
226
232
local_heap. borrow_mut ( ) . entry ( s) // let's not override consts
227
- . or_insert ( token :: ZERO ) ;
233
+ . or_insert ( Number :: NaturalNumber ( Zero :: zero ( ) ) ) ;
228
234
} ,
229
235
}
230
236
debug ! ( "Inspecting... {} - OUT {} - OP - {}" , * t, DisplayThisDeque ( & postfix_stack) , DisplayThatVec ( & operators_stack) ) ;
231
237
} ;
232
238
233
239
/* After all tokens are read, pop remaining operators from the stack and add them to the list. */
234
240
operators_stack. reverse ( ) ;
235
- postfix_stack. extend ( operators_stack. iter ( ) ) ;
241
+ operators_stack. iter ( ) . for_each ( |t| postfix_stack. push_back ( t. clone ( ) ) ) ;
242
+ //postfix_stack.pop_front()
243
+ //postfix_stack.extend(operators_stack.iter());
236
244
237
245
debug ! (
238
246
"Inspecting... EOF - OUT {} - OP - {}" , DisplayThisDeque ( & postfix_stack) , DisplayThatVec ( & operators_stack)
239
247
) ;
240
248
241
249
( postfix_stack, local_heap)
242
250
}
251
+
252
+ 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." )
258
+ }
259
+ }
243
260
}
244
261
245
262
struct DisplayThatVec < ' a > ( & ' a Vec < Token < ' a > > ) ;
@@ -259,19 +276,20 @@ impl Display for DisplayThisDeque<'_> {
259
276
260
277
#[ cfg( test) ]
261
278
mod tests {
279
+ use num_bigint:: BigInt ;
262
280
use super :: * ;
263
281
use crate :: token:: { Number , Operator } ;
264
282
265
283
#[ test]
266
284
fn test_reverse_polish_notation ( ) {
267
285
let a: Vec < Token > = vec ! [
268
- Token :: Operand ( Number :: NaturalNumber ( 1 ) ) ,
286
+ Token :: Operand ( Number :: NaturalNumber ( BigInt :: from ( 1u8 ) ) ) ,
269
287
Token :: Operator ( Operator :: Add ) ,
270
- Token :: Operand ( Number :: NaturalNumber ( 2 ) ) ,
288
+ Token :: Operand ( Number :: NaturalNumber ( BigInt :: from ( 2u8 ) ) ) ,
271
289
] ;
272
290
let b: Vec < Token > = vec ! [
273
- Token :: Operand ( Number :: NaturalNumber ( 1 ) ) ,
274
- Token :: Operand ( Number :: NaturalNumber ( 2 ) ) ,
291
+ Token :: Operand ( Number :: NaturalNumber ( BigInt :: from ( 1u8 ) ) ) ,
292
+ Token :: Operand ( Number :: NaturalNumber ( BigInt :: from ( 2u8 ) ) ) ,
275
293
Token :: Operator ( Operator :: Add ) ,
276
294
] ;
277
295
assert_eq ! (
0 commit comments