refactor: replace duplicate eval code with macro
This commit is contained in:
parent
7182e29512
commit
570da21956
1 changed files with 49 additions and 108 deletions
|
|
@ -89,105 +89,35 @@ fn collapse_toplevel(nodes: &mut Vec<Node>, mut end: usize) -> Result<(), Error>
|
|||
end -= 1;
|
||||
}
|
||||
|
||||
while let Some(operator) = nodes[start..end]
|
||||
.iter()
|
||||
.position(|n| *n == Node::Operator(Operator::Exp))
|
||||
{
|
||||
let lhs = match nodes.remove(start + operator - 1) {
|
||||
Node::Number(n) => n,
|
||||
n => return Err(Error::InvalidOperand(n)),
|
||||
};
|
||||
end -= 1;
|
||||
match nodes.get_mut(start + operator) {
|
||||
None => return Err(Error::OutOfBounds(Nodes(nodes.clone()), start + operator)),
|
||||
macro_rules! collapse_operator {
|
||||
($operator:expr) => {
|
||||
while let Some(operator) = nodes[start..end]
|
||||
.iter()
|
||||
.position(|n| *n == Node::Operator($operator))
|
||||
{
|
||||
let lhs = match nodes.remove(start + operator - 1) {
|
||||
Node::Number(n) => n,
|
||||
n => return Err(Error::InvalidOperand(n)),
|
||||
};
|
||||
end -= 1;
|
||||
match nodes.get_mut(start + operator) {
|
||||
None => return Err(Error::OutOfBounds(Nodes(nodes.clone()), start + operator)),
|
||||
|
||||
Some(Node::Number(n)) => n.pow_from(lhs),
|
||||
Some(n) => return Err(Error::InvalidOperand(n.clone())),
|
||||
};
|
||||
Some(Node::Number(n)) => $operator.for_float()(n, lhs),
|
||||
Some(n) => return Err(Error::InvalidOperand(n.clone())),
|
||||
};
|
||||
|
||||
nodes.remove(start + operator - 1);
|
||||
end -= 1;
|
||||
nodes.remove(start + operator - 1);
|
||||
end -= 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
while let Some(operator) = nodes[start..end]
|
||||
.iter()
|
||||
.position(|n| *n == Node::Operator(Operator::Div))
|
||||
{
|
||||
let lhs = match nodes.remove(start + operator - 1) {
|
||||
Node::Number(n) => n,
|
||||
n => return Err(Error::InvalidOperand(n)),
|
||||
};
|
||||
end -= 1;
|
||||
match nodes.get_mut(start + operator) {
|
||||
None => return Err(Error::OutOfBounds(Nodes(nodes.clone()), start + operator)),
|
||||
|
||||
Some(Node::Number(n)) => n.div_from(lhs),
|
||||
Some(n) => return Err(Error::InvalidOperand(n.clone())),
|
||||
};
|
||||
|
||||
nodes.remove(start + operator - 1);
|
||||
end -= 1;
|
||||
}
|
||||
|
||||
while let Some(operator) = nodes[start..end]
|
||||
.iter()
|
||||
.position(|n| *n == Node::Operator(Operator::Mult))
|
||||
{
|
||||
let lhs = match nodes.remove(start + operator - 1) {
|
||||
Node::Number(n) => n,
|
||||
n => return Err(Error::InvalidOperand(n)),
|
||||
};
|
||||
end -= 1;
|
||||
match nodes.get_mut(start + operator) {
|
||||
None => return Err(Error::OutOfBounds(Nodes(nodes.clone()), start + operator)),
|
||||
|
||||
Some(Node::Number(n)) => n.mul_from(lhs),
|
||||
Some(n) => return Err(Error::InvalidOperand(n.clone())),
|
||||
};
|
||||
|
||||
nodes.remove(start + operator - 1);
|
||||
end -= 1;
|
||||
}
|
||||
|
||||
while let Some(operator) = nodes[start..end]
|
||||
.iter()
|
||||
.position(|n| *n == Node::Operator(Operator::Minus))
|
||||
{
|
||||
let lhs = match nodes.remove(start + operator - 1) {
|
||||
Node::Number(n) => n,
|
||||
n => return Err(Error::InvalidOperand(n)),
|
||||
};
|
||||
end -= 1;
|
||||
match nodes.get_mut(start + operator) {
|
||||
None => return Err(Error::OutOfBounds(Nodes(nodes.clone()), start + operator)),
|
||||
|
||||
Some(Node::Number(n)) => n.sub_from(lhs),
|
||||
Some(n) => return Err(Error::InvalidOperand(n.clone())),
|
||||
};
|
||||
|
||||
nodes.remove(start + operator - 1);
|
||||
end -= 1;
|
||||
}
|
||||
|
||||
while let Some(operator) = nodes[start..end]
|
||||
.iter()
|
||||
.position(|n| *n == Node::Operator(Operator::Plus))
|
||||
{
|
||||
let lhs = match nodes.remove(start + operator - 1) {
|
||||
Node::Number(n) => n,
|
||||
n => return Err(Error::InvalidOperand(n)),
|
||||
};
|
||||
end -= 1;
|
||||
match nodes.get_mut(start + operator) {
|
||||
None => return Err(Error::OutOfBounds(Nodes(nodes.clone()), start + operator)),
|
||||
|
||||
Some(Node::Number(n)) => n.add_from(lhs),
|
||||
Some(n) => return Err(Error::InvalidOperand(n.clone())),
|
||||
};
|
||||
|
||||
nodes.remove(start + operator - 1);
|
||||
end -= 1;
|
||||
}
|
||||
collapse_operator!(Operator::Exp);
|
||||
collapse_operator!(Operator::Div);
|
||||
collapse_operator!(Operator::Mult);
|
||||
collapse_operator!(Operator::Minus);
|
||||
collapse_operator!(Operator::Plus);
|
||||
|
||||
if nodes.len() > 1 {
|
||||
nodes.remove(end);
|
||||
|
|
@ -200,18 +130,29 @@ fn collapse_toplevel(nodes: &mut Vec<Node>, mut end: usize) -> Result<(), Error>
|
|||
impl Function {
|
||||
fn for_float(&self) -> impl FnMut(&mut Float) {
|
||||
match self {
|
||||
Function::Sqrt => Float::sqrt_mut,
|
||||
Self::Sqrt => Float::sqrt_mut,
|
||||
|
||||
Function::Ln => Float::ln_mut,
|
||||
Self::Ln => Float::ln_mut,
|
||||
|
||||
Function::Sine => Float::sin_mut,
|
||||
Function::ArcSine => Float::asin_mut,
|
||||
Function::Cosine => Float::cos_mut,
|
||||
Function::ArcCosine => Float::acos_mut,
|
||||
Function::Tangent => Float::tan_mut,
|
||||
Function::ArcTangent => Float::atan_mut,
|
||||
Function::Secant => Float::sec_mut,
|
||||
Function::CoSecant => Float::csc_mut,
|
||||
Self::Sine => Float::sin_mut,
|
||||
Self::ArcSine => Float::asin_mut,
|
||||
Self::Cosine => Float::cos_mut,
|
||||
Self::ArcCosine => Float::acos_mut,
|
||||
Self::Tangent => Float::tan_mut,
|
||||
Self::ArcTangent => Float::atan_mut,
|
||||
Self::Secant => Float::sec_mut,
|
||||
Self::CoSecant => Float::csc_mut,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Operator {
|
||||
fn for_float(&self) -> impl FnMut(&mut Float, Float) {
|
||||
match self {
|
||||
Self::Plus => Float::add_from,
|
||||
Self::Minus => Float::sub_from,
|
||||
Self::Mult => Float::mul_from,
|
||||
Self::Div => Float::div_from,
|
||||
Self::Exp => Float::pow_from,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue