-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterpreter.rs
93 lines (87 loc) · 3.37 KB
/
interpreter.rs
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
use crate::parser::{ Number, Operator, Paran, Token };
/// uses a shunting yard algorithm to convert a vector of tokens into postfix notation
pub fn shunt(tokens: Vec<Token>) -> Vec<Token> {
let mut output: Vec<Token> = Vec::new();
let mut stack: Vec<Token> = Vec::new();
for token in tokens.iter() {
match token {
Token::Number(_) => output.push(token.clone()),
Token::Operator(op1) => {
let mut pushed = false;
while !stack.is_empty() {
let top = stack.last().unwrap().clone();
if let Token::Operator(op2) = top {
if op1.precedence() > op2.precedence() {
pushed = true;
stack.push(Token::Operator(op1.clone()));
break;
} else if op1.precedence() < op2.precedence() {
stack.pop();
output.push(top.clone());
} else if op1.associativity() == 0 {
pushed = true;
stack.pop();
output.push(top.clone());
stack.push(Token::Operator(op1.clone()));
break;
} else {
pushed = true;
stack.push(Token::Operator(op1.clone()));
break;
}
} else {
pushed = true;
stack.push(token.clone());
break;
}
}
if !pushed { stack.push(token.clone()); }
},
Token::Paran(p) => {
if *p == Paran::Open {
stack.push(Token::Paran(Paran::Open));
} else {
let mut top = stack.last().unwrap().clone();
while top != Token::Paran(Paran::Open) {
stack.pop();
output.push(top.clone());
top = stack.last().unwrap().clone();
}
stack.pop();
}
},
}
}
while !stack.is_empty() {
output.push(stack.pop().unwrap());
}
return output;
}
/// interpret a vector of tokens in postfix notation
pub fn interpret(tokens: Vec<Token>) -> i64 {
let mut stack: Vec<i64> = Vec::new();
for token in tokens.iter() {
match token {
Token::Number(num) => {
match num {
Number::Binary(n) => stack.push(*n),
Number::Octal(n) => stack.push(*n),
Number::Decimal(n) => stack.push(*n),
Number::Hexadecimal(n) => stack.push(*n),
}
},
Token::Operator(op) => {
let b = stack.pop().unwrap();
let a = stack.pop().unwrap();
match op {
Operator::Add => stack.push(a + b),
Operator::Subtract => stack.push(a - b),
Operator::Multiply => stack.push(a * b),
Operator::Divide => stack.push(a / b),
}
},
_ => (),
}
}
return stack.pop().unwrap();
}