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
|
use crate::eval::Num;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum UnOp {
Neg,
Sin,
Cos,
Tan,
Asin,
Acos,
Atan,
Sqrt,
Log,
Log10,
Log2,
Floor,
Ceil,
Round,
Abs,
}
impl UnOp {
fn eval(self, x: Num) -> Num {
match self {
UnOp::Neg => Num::Int(0).sub(x),
UnOp::Sin => x.sin(),
UnOp::Cos => x.cos(),
UnOp::Tan => x.tan(),
UnOp::Asin => x.asin(),
UnOp::Acos => x.acos(),
UnOp::Atan => x.atan(),
UnOp::Sqrt => x.sqrt(),
UnOp::Log => x.log(),
UnOp::Log10 => x.log10(),
UnOp::Log2 => x.log2(),
UnOp::Floor => x.floor(),
UnOp::Ceil => x.ceil(),
UnOp::Round => x.round(),
UnOp::Abs => x.abs(),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BinOp {
Pow,
Mul,
Div,
IntDiv,
Mod,
Add,
Sub,
}
impl BinOp {
fn eval(self, x: Num, y: Num) -> Num {
match self {
BinOp::Pow => x.pow(y),
BinOp::Mul => x.mul(y),
BinOp::Div => x.div(y),
BinOp::IntDiv => x.int_div(y),
BinOp::Mod => x.modulo(y),
BinOp::Add => x.add(y),
BinOp::Sub => x.sub(y),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Op {
Num(Num),
Un(UnOp),
Bin(BinOp),
}
pub fn eval(ops: &[Op]) -> Num {
let mut stack = Vec::new();
for op in ops {
match op {
Op::Num(n) => stack.push(*n),
Op::Un(op) => {
let n = stack.pop().unwrap();
stack.push(op.eval(n));
}
Op::Bin(op) => {
let n2 = stack.pop().unwrap();
let n1 = stack.pop().unwrap();
stack.push(op.eval(n1, n2));
}
}
}
stack[0]
}
|