blob: e5c28e607ac22fe913456f6c879c5b0c7b68a554 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
use crate::lex::Token;
pub fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> {
let mut postfixed: Vec<Token> = vec![];
let mut op_stack: Vec<Token> = vec![];
for token in tokens {
match token {
Token::Num(_) => {
postfixed.push(token);
},
Token::Function(_) => {
op_stack.push(token);
}
Token::Operator(current_op) => {
while let Some(top_op) = op_stack.last() {
match top_op {
Token::LParen => {
break;
}
Token::Operator(x) => {
let tp = x.precedence;
let cp = current_op.precedence;
if tp > cp || (tp == cp && x.is_left_associative) {
postfixed.push(op_stack.pop().unwrap());
} else {
break;
}
}
Token::Function(_) => {
postfixed.push(op_stack.pop().unwrap());
}
_ => {
return Err(format!("{:?} must not be on operator stack", top_op))
}
}
}
op_stack.push(token);
},
Token::LParen => {
op_stack.push(token);
},
Token::RParen => {
let mut push_until_paren: bool = false;
while let Some(token) = op_stack.pop() {
if token == Token::LParen {
push_until_paren = true;
break;
}
postfixed.push(token)
}
if !push_until_paren {
return Err(String::from("Mismatched ')'"));
}
}
}
}
while let Some(op) = op_stack.pop() {
postfixed.push(op);
}
Ok(postfixed)
}
pub fn eval_postfix(postfixed: Vec<Token>) -> Result<f64, String> {
let mut num_stack: Vec<f64> = vec![];
for token in postfixed {
match token {
Token::Num(n) => {
num_stack.push(n);
},
Token::Operator(op) => {
if let Some(n2) = num_stack.pop() {
if let Some(n1) = num_stack.pop() {
num_stack.push(op.operate(n1, n2))
} else {
return Err(format!("Too many operators, Too little operands"))
}
} else {
return Err(format!("Too many operators, Too little operands"))
}
},
Token::Function(funct) => {
if let Some(arg) = num_stack.pop() {
num_stack.push(funct.apply(arg))
}
}
_ => {
return Err(format!("Yo nibba how did this get here"))
}
}
}
if num_stack.len() == 1 {
Ok(num_stack.pop().unwrap())
} else {
Err(format!("Parser Error"))
}
}
|