1use crate::equation::Group;
2
3#[derive(Debug, Clone)]
5pub enum Item {
6 Value(f64),
8 Variable(String),
10 Operator(Operator),
12 Group(Group),
14}
15
16#[derive(Debug, Clone, PartialEq)]
18pub enum Operator {
19 LeftAssociative(LeftAssociativeOperator),
21 Functional(FunctionalOperator),
23}
24
25#[derive(Debug, Clone, PartialEq)]
27pub enum LeftAssociativeOperator {
28 Add,
30 Subtract,
32 Multiply,
34 Divide,
36 Power,
38 Root,
40}
41
42#[derive(Debug, Clone, PartialEq)]
44pub enum FunctionalOperator {
45 Log,
47 Ln,
49 Sin,
51 Cos,
53 Tan,
55 Cot,
57 Sec,
59 Csc,
61 Arcsin,
63 Arccos,
65 Arctan,
67 Arccot,
69 Arcsec,
71 Arccsc,
73}
74
75impl From<f64> for Item {
76 fn from(val: f64) -> Self {
77 Item::Value(val)
78 }
79}
80
81impl From<String> for Item {
82 fn from(val: String) -> Self {
83 Item::Variable(val)
84 }
85}
86
87impl From<Operator> for Item {
88 fn from(val: Operator) -> Self {
89 Item::Operator(val)
90 }
91}
92
93impl From<Group> for Item {
94 fn from(val: Group) -> Self {
95 Item::Group(val)
96 }
97}
98
99impl From<LeftAssociativeOperator> for Operator {
100 fn from(val: LeftAssociativeOperator) -> Self {
101 Operator::LeftAssociative(val)
102 }
103}
104
105impl From<FunctionalOperator> for Operator {
106 fn from(val: FunctionalOperator) -> Self {
107 Operator::Functional(val)
108 }
109}
110
111impl From<LeftAssociativeOperator> for Item {
112 fn from(val: LeftAssociativeOperator) -> Self {
113 Item::Operator(val.into())
114 }
115}
116
117impl From<FunctionalOperator> for Item {
118 fn from(val: FunctionalOperator) -> Self {
119 Item::Operator(val.into())
120 }
121}
122
123impl From<Vec<Item>> for Item {
124 fn from(val: Vec<Item>) -> Self {
125 Item::Group(val.into())
126 }
127}
128
129impl FunctionalOperator {
130 pub fn evaluate(&self, x: f64) -> f64 {
132 match self {
133 FunctionalOperator::Log => x.log10(),
134 FunctionalOperator::Ln => x.ln(),
135 FunctionalOperator::Sin => x.sin(),
136 FunctionalOperator::Cos => x.cos(),
137 FunctionalOperator::Tan => x.tan(),
138 FunctionalOperator::Cot => x.tan().recip(),
139 FunctionalOperator::Sec => x.cos().recip(),
140 FunctionalOperator::Csc => x.sin().recip(),
141 FunctionalOperator::Arcsin => x.asin(),
142 FunctionalOperator::Arccos => x.acos(),
143 FunctionalOperator::Arctan => x.atan(),
144 FunctionalOperator::Arccot => x.atan().recip(),
145 FunctionalOperator::Arcsec => x.acos().recip(),
146 FunctionalOperator::Arccsc => x.asin().recip(),
147 }
148 }
149}
150
151impl LeftAssociativeOperator {
152 pub fn is_of_order(&self, order: &u8) -> bool {
154 match self {
160 LeftAssociativeOperator::Add | LeftAssociativeOperator::Subtract => *order == 2,
161 LeftAssociativeOperator::Multiply | LeftAssociativeOperator::Divide => *order == 1,
162 LeftAssociativeOperator::Power | LeftAssociativeOperator::Root => *order == 0,
163 }
164 }
165 pub fn eval(&self, lhs: f64, rhs: f64) -> f64 {
167 match self {
168 LeftAssociativeOperator::Add => lhs + rhs,
169 LeftAssociativeOperator::Subtract => lhs - rhs,
170 LeftAssociativeOperator::Multiply => lhs * rhs,
171 LeftAssociativeOperator::Divide => lhs / rhs,
172 LeftAssociativeOperator::Power => lhs.powf(rhs),
173 LeftAssociativeOperator::Root => rhs.powf(lhs.recip()),
174 }
175 }
176}