diff --git a/src/nodes/eval.rs b/src/nodes/eval.rs index ea06c2b..cd37cb3 100644 --- a/src/nodes/eval.rs +++ b/src/nodes/eval.rs @@ -7,6 +7,8 @@ use crate::nodes::{Function, Node, Nodes, Operator}; #[derive(Clone, Debug, thiserror::Error)] pub enum Error { + #[error("out of bounds: index {0}, {1}")] + OutOfBounds(Nodes, usize), #[error("invalid operand: {0}")] InvalidOperand(Node), #[error("missing argument, got: {0}")] @@ -48,22 +50,27 @@ fn collapse_toplevel(nodes: &mut Vec, mut end: usize) -> Result<(), Error> }) .next() { - match &mut nodes[start..end][index + 1] { - Node::Number(n) => match variant { - Function::Sqrt => n.sqrt_mut(), + let Some(node) = nodes.get_mut(start + index + 1) else { + return Err(Error::OutOfBounds(Nodes(nodes.clone()), start + index + 1)); + }; - Function::Ln => n.ln_mut(), + let Node::Number(n) = node else { + return Err(Error::MissingArgument(node.clone())); + }; - Function::Sine => n.sin_mut(), - Function::ArcSine => n.asin_mut(), - Function::Cosine => n.cos_mut(), - Function::ArcCosine => n.acos_mut(), - Function::Tangent => n.tan_mut(), - Function::ArcTangent => n.atan_mut(), - Function::Secant => n.sec_mut(), - Function::CoSecant => n.csc_mut(), - }, - n => return Err(Error::MissingArgument(n.clone())), + match variant { + Function::Sqrt => n.sqrt_mut(), + + Function::Ln => n.ln_mut(), + + Function::Sine => n.sin_mut(), + Function::ArcSine => n.asin_mut(), + Function::Cosine => n.cos_mut(), + Function::ArcCosine => n.acos_mut(), + Function::Tangent => n.tan_mut(), + Function::ArcTangent => n.atan_mut(), + Function::Secant => n.sec_mut(), + Function::CoSecant => n.csc_mut(), }; nodes.remove(start + index); @@ -79,9 +86,11 @@ fn collapse_toplevel(nodes: &mut Vec, mut end: usize) -> Result<(), Error> n => return Err(Error::InvalidOperand(n)), }; end -= 1; - match &mut nodes[start..end][operator] { - Node::Number(n) => n.pow_from(lhs), - n => return Err(Error::InvalidOperand(n.clone())), + 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())), }; nodes.remove(start + operator - 1); @@ -97,9 +106,11 @@ fn collapse_toplevel(nodes: &mut Vec, mut end: usize) -> Result<(), Error> n => return Err(Error::InvalidOperand(n)), }; end -= 1; - match &mut nodes[start..end][operator] { - Node::Number(n) => n.div_from(lhs), - n => return Err(Error::InvalidOperand(n.clone())), + 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); @@ -115,9 +126,11 @@ fn collapse_toplevel(nodes: &mut Vec, mut end: usize) -> Result<(), Error> n => return Err(Error::InvalidOperand(n)), }; end -= 1; - match &mut nodes[start..end][operator] { - Node::Number(n) => n.mul_from(lhs), - n => return Err(Error::InvalidOperand(n.clone())), + 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); @@ -133,9 +146,11 @@ fn collapse_toplevel(nodes: &mut Vec, mut end: usize) -> Result<(), Error> n => return Err(Error::InvalidOperand(n)), }; end -= 1; - match &mut nodes[start..end][operator] { - Node::Number(n) => n.sub_from(lhs), - n => return Err(Error::InvalidOperand(n.clone())), + 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); @@ -151,9 +166,11 @@ fn collapse_toplevel(nodes: &mut Vec, mut end: usize) -> Result<(), Error> n => return Err(Error::InvalidOperand(n)), }; end -= 1; - match &mut nodes[start..end][operator] { - Node::Number(n) => n.add_from(lhs), - n => return Err(Error::InvalidOperand(n.clone())), + 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);