Compare commits
2 changed files with 74 additions and 98 deletions
|
|
@ -28,8 +28,8 @@ impl Nodes {
|
||||||
let len = nodes.len();
|
let len = nodes.len();
|
||||||
collapse_toplevel(nodes, len)?;
|
collapse_toplevel(nodes, len)?;
|
||||||
|
|
||||||
match nodes.pop() {
|
match nodes.pop().unwrap() {
|
||||||
Some(Node::Number(n)) => Ok(n),
|
Node::Number(n) => Ok(n),
|
||||||
_ => Err(Error::CollapseFailed(self)),
|
_ => Err(Error::CollapseFailed(self)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ fn collapse_toplevel(nodes: &mut Vec<Node>, mut end: usize) -> Result<(), Error>
|
||||||
.rposition(|n| *n == Node::ParenthesisStart)
|
.rposition(|n| *n == Node::ParenthesisStart)
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
while let Some((index, function)) = nodes[start..end]
|
while let Some((index, variant)) = nodes[start..end]
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(i, n)| match n {
|
.filter_map(|(i, n)| match n {
|
||||||
|
|
@ -58,7 +58,20 @@ fn collapse_toplevel(nodes: &mut Vec<Node>, mut end: usize) -> Result<(), Error>
|
||||||
return Err(Error::MissingArgument(node.clone()));
|
return Err(Error::MissingArgument(node.clone()));
|
||||||
};
|
};
|
||||||
|
|
||||||
function.for_float()(n);
|
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);
|
nodes.remove(start + index);
|
||||||
end -= 1;
|
end -= 1;
|
||||||
|
|
@ -172,33 +185,11 @@ fn collapse_toplevel(nodes: &mut Vec<Node>, mut end: usize) -> Result<(), Error>
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Function {
|
|
||||||
fn for_float(&self) -> impl FnMut(&mut Float) {
|
|
||||||
match self {
|
|
||||||
Function::Sqrt => Float::sqrt_mut,
|
|
||||||
|
|
||||||
Function::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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
use super::PREC;
|
||||||
use super::super::PREC;
|
|
||||||
use super::*;
|
|
||||||
use std::assert_matches;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic() {
|
fn test() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Nodes(vec![
|
Nodes(vec![
|
||||||
Node::Function(Function::Sine),
|
Node::Function(Function::Sine),
|
||||||
|
|
@ -213,13 +204,4 @@ mod tests {
|
||||||
.to_f64(),
|
.to_f64(),
|
||||||
1.9092974268256817,
|
1.9092974268256817,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn zerosized() {
|
|
||||||
assert_matches!(
|
|
||||||
Nodes(vec![Node::ParenthesisStart, Node::ParenthesisEnd]).evaluate(),
|
|
||||||
Err(Error::CollapseFailed(Nodes(v))) if v.is_empty()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,12 +195,8 @@ impl FromStr for Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[test]
|
||||||
mod tests {
|
fn test() {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn basic() {
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Nodes::from_str("sin(2) + 1").unwrap().as_ref(),
|
Nodes::from_str("sin(2) + 1").unwrap().as_ref(),
|
||||||
&[
|
&[
|
||||||
|
|
@ -212,10 +208,9 @@ mod tests {
|
||||||
Node::from(1),
|
Node::from(1),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
#[test]
|
fn test_e() {
|
||||||
fn e_constant() {
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Nodes::from_str("5e * 5").unwrap().as_ref(),
|
Nodes::from_str("5e * 5").unwrap().as_ref(),
|
||||||
&[
|
&[
|
||||||
|
|
@ -226,9 +221,9 @@ mod tests {
|
||||||
Node::from(5),
|
Node::from(5),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn unary_op() {
|
fn test_unary_op() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Nodes::from_str("5(-5)").unwrap().as_ref(),
|
Nodes::from_str("5(-5)").unwrap().as_ref(),
|
||||||
&[
|
&[
|
||||||
|
|
@ -239,5 +234,4 @@ mod tests {
|
||||||
Node::ParenthesisEnd,
|
Node::ParenthesisEnd,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue