diff --git a/src/nodes/eval.rs b/src/nodes/eval.rs index 2ebfee0..2683745 100644 --- a/src/nodes/eval.rs +++ b/src/nodes/eval.rs @@ -89,105 +89,35 @@ fn collapse_toplevel(nodes: &mut Vec, 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, 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, } } }