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
sqrt | 1 | Square root | ./¯x |
trunc(ate) | 1 | Truncate value to Integer |
round | rnd | 1 | Round value to Integer (a half, rounds away from zero) |
+ sum | all | Add all values on stack togther and return sum |
Scalar Operations |
factor | 1 | Find all prime factors of item |
ln | 1 | Natural logarithm | ln(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
+ }
+ }
}