From 57c285b2b598f4ed913fe17f0fe5760daf09c63e Mon Sep 17 00:00:00 2001 From: shanehull Date: Thu, 23 Jul 2026 17:34:54 +1000 Subject: [PATCH] refactor: simplify calculator dispatch with variadic Set methods --- README.md | 15 ++++++++++++--- calculator.go | 10 +++++----- engine/financial.go | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d61c0d8..e7ee0ab 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ Two things in one repo: -- **`engine`** — a generic RPN calculator library: stack, registers, TVM, cash +- **`engine`**: a generic RPN calculator library: stack, registers, TVM, cash flows, statistics, depreciation, date math. No GUI dependency. -- **App** — a cross-platform financial calculator built with +- **App**: a cross-platform financial calculator built with [Wails v3](https://v3.wails.io) on top of the engine. macOS, Windows, Linux, iOS, Android. @@ -45,13 +45,19 @@ c.Snapshot() // EngineState for persistence c.Restore(state) ``` +Set methods are variadic. Omit the argument to store the current X value: + +```go +c.X = 8; c.SetI() // equivalent to c.SetI(8) +``` + ### Methods | Category | Methods | | ------------ | ---------------------------------------------------------------------------------------------- | | Stack | `Enter`, `Clx`, `Chs`, `XY`, `RollDown`, `RollUp`, `LastXRecall` | | Arithmetic | `Add`, `Sub`, `Mul`, `Div`, `YPowX` | -| TVM store | `SetN(n)`, `SetI(i)`, `SetPV(pv)`, `SetPMT(pmt)`, `SetFV(fv)` | +| TVM store | `SetN(n?)`, `SetI(i?)`, `SetPV(pv?)`, `SetPMT(pmt?)`, `SetFV(fv?)` | | TVM solve | `SolveN`, `SolveI`, `SolvePV`, `SolvePMT`, `SolveFV` | | Cash flow | `NPV`, `IRR` | | Amortization | `Amortize` | @@ -68,6 +74,9 @@ c.Restore(state) | State | `Snapshot`, `Restore` | | Clear | `ClearFin`, `ClearReg`, `ClearStats`, `ClearPgm` | +`SetN/SetI/SetPV/SetPMT/SetFV` are variadic: omit the argument to store the +current X register value (`e.SetN()` is shorthand for `e.SetN(e.X)`). + ### Fields ```go diff --git a/calculator.go b/calculator.go index 4810ad3..d9251ac 100644 --- a/calculator.go +++ b/calculator.go @@ -163,15 +163,15 @@ func (c *CalcService) PressKey(input KeyInput) KeyResult { func (c *CalcService) storeTVM(op string) { switch op { case "n": - c.e.SetN(c.e.X) + c.e.SetN() case "i": - c.e.SetI(c.e.X) + c.e.SetI() case "PV": - c.e.SetPV(c.e.X) + c.e.SetPV() case "PMT": - c.e.SetPMT(c.e.X) + c.e.SetPMT() case "FV": - c.e.SetFV(c.e.X) + c.e.SetFV() } c.e.Flags.StackLift = false } diff --git a/engine/financial.go b/engine/financial.go index a8d81db..c260603 100644 --- a/engine/financial.go +++ b/engine/financial.go @@ -2,11 +2,41 @@ package engine import "math" -func (e *Engine) SetN(n float64) { e.FinN = n } -func (e *Engine) SetI(i float64) { e.FinI = i } -func (e *Engine) SetPV(pv float64) { e.FinPV = pv } -func (e *Engine) SetPMT(pmt float64) { e.FinPMT = pmt } -func (e *Engine) SetFV(fv float64) { e.FinFV = fv } +func (e *Engine) SetN(v ...float64) { + if len(v) > 0 { + e.FinN = v[0] + } else { + e.FinN = e.X + } +} +func (e *Engine) SetI(v ...float64) { + if len(v) > 0 { + e.FinI = v[0] + } else { + e.FinI = e.X + } +} +func (e *Engine) SetPV(v ...float64) { + if len(v) > 0 { + e.FinPV = v[0] + } else { + e.FinPV = e.X + } +} +func (e *Engine) SetPMT(v ...float64) { + if len(v) > 0 { + e.FinPMT = v[0] + } else { + e.FinPMT = e.X + } +} +func (e *Engine) SetFV(v ...float64) { + if len(v) > 0 { + e.FinFV = v[0] + } else { + e.FinFV = e.X + } +} func (e *Engine) SolveN() { e.solve(math.NaN(), e.FinI/100, e.FinPV, e.FinPMT, e.FinFV) } func (e *Engine) SolveI() {