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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use crate::core::*;
use std::fmt;
use std::cmp::Ordering;
const PRIORITY: [Actions; 5] = [
Actions::Sub,
Actions::Add,
Actions::Mul,
Actions::Pow,
Actions::Div,
];
#[derive(Debug, Clone)]
pub enum Actions {
Sub,
Add,
Mul,
Div,
Pow,
Var(String),
Val(f64),
Brackets(Box<Expression>, Brackets),
}
impl Default for Actions {
fn default() -> Self {
Actions::Add
}
}
impl fmt::Display for Actions {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self {
Actions::Add => f.write_str(literals::SYMBOL_ADD),
Actions::Mul => f.write_str(literals::SYMBOL_MUL),
Actions::Pow => f.write_str(literals::SYMBOL_POW),
Actions::Div => f.write_str(literals::SYMBOL_DIV),
Actions::Sub => f.write_str(literals::SYMBOL_SUB),
Actions::Var(literal) => f.write_str(&literal),
Actions::Val(value) => f.write_str(&value.to_string()),
Actions::Brackets(expr, brackets) => {
let (left, right) = brackets.get_symbols();
f.write_str(left)?;
f.write_str(&expr.to_string())?;
f.write_str(right)
},
}
}
}
impl PartialEq for Actions {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Actions::Sub, Actions::Sub) => true,
(Actions::Add, Actions::Add) => true,
(Actions::Sub, Actions::Add) => true,
(Actions::Add, Actions::Sub) => true,
(Actions::Mul, Actions::Mul) => true,
(Actions::Div, Actions::Div) => true,
(Actions::Div, Actions::Mul) => true,
(Actions::Mul, Actions::Div) => true,
(Actions::Pow, Actions::Pow) => true,
(Actions::Val(..), Actions::Val(..)) => true,
(Actions::Var(..), Actions::Var(..)) => true,
(Actions::Val(..), Actions::Var(..)) => true,
(Actions::Var(..), Actions::Val(..)) => true,
(Actions::Brackets(..), Actions::Brackets(..)) => true,
_ => false
}
}
}
impl PartialOrd for Actions {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let mut priority = Vec::from(PRIORITY);
priority.push(Actions::Brackets(Box::from(Expression::default()), Brackets::Round));
let self_prior = priority.iter().position(|x| x == self);
let other_prior = priority.iter().position(|x| x == other);
if self_prior.is_some() && other_prior.is_some() {
let (self_prior, other_prior) = (self_prior.unwrap(), other_prior.unwrap());
self_prior.partial_cmp(&other_prior)
}
else { return None }
}
}