diff --git a/src/fixtures/help.html b/src/fixtures/help.html index 0b31771..bc93f54 100644 --- a/src/fixtures/help.html +++ b/src/fixtures/help.html @@ -71,6 +71,7 @@

RPN-rs is a graphical reverse polish notation (RPN) calculator

sqrt1Square root./¯x trunc(ate)1Truncate value to Integer round | rnd1Round value to Integer (a half, rounds away from zero) + sumallAdd all values on stack togther and return sum Scalar Operations factor1Find all prime factors of item ln1Natural logarithmln(x) diff --git a/src/main.rs b/src/main.rs index 24f4a5c..dc39215 100644 --- a/src/main.rs +++ b/src/main.rs @@ -174,6 +174,7 @@ fn main() { "round" | "rnd" => stacks[0].try_unary(|a| a.try_round()), "trunc" | "truncate" => stacks[0].try_unary(|a| a.try_trunc()), "factor" => stacks[0].try_unary_v(|a| a.try_factor()), + "sum" => stacks[0].try_reduce(|acc, e| acc + e), // Matrix Operations "det" | "determinant" => stacks[0].try_unary(|a| a.try_det()), "trans" | "transpose" => stacks[0].try_unary(|a| a.try_transpose()), diff --git a/src/stack.rs b/src/stack.rs index 5ba53c4..662b880 100644 --- a/src/stack.rs +++ b/src/stack.rs @@ -19,6 +19,7 @@ pub trait StackOps { fn try_unary_v Result, String>>(&mut self, f: F) -> Return; fn unary_v Vec>(&mut self, f: F) -> Return; fn binary_v Vec>(&mut self, f: F) -> Return; + fn try_reduce Result>(&mut self, f: F) -> Return; } impl StackOps for Vec { @@ -104,4 +105,19 @@ impl StackOps for Vec { Return::Noop } } + // This is roughly Iterator::try_reduce() but needs to consume self + fn try_reduce Result>(&mut self, f: F) -> Return { + if let Some(mut acc) = self.pop() { + while let Some(e) = self.pop() { + match f(acc, e) { + Ok(c) => acc = c, + Err(e) => return Return::Err(e), + } + } + self.push(acc); + Return::Ok + } else { + Return::Noop + } + } }