diff options
| author | Sam Anthony <sam@samanthony.xyz> | 2023-07-29 10:20:07 -0230 |
|---|---|---|
| committer | Sam Anthony <sam@samanthony.xyz> | 2023-07-29 10:20:07 -0230 |
| commit | a253229dbbef5e09449884febacdfbbd4de85d6d (patch) | |
| tree | 471552d43293a856d73aa8a08692b3bca7724dc3 | |
| parent | 545f618f333a8e4d5d9c38266e14574eef542fcb (diff) | |
| download | pfc-a253229dbbef5e09449884febacdfbbd4de85d6d.zip | |
swap command
| -rw-r--r-- | calculator.go | 31 | ||||
| -rw-r--r-- | ui.go | 8 |
2 files changed, 38 insertions, 1 deletions
diff --git a/calculator.go b/calculator.go index fb1fc90..f0ed7db 100644 --- a/calculator.go +++ b/calculator.go @@ -4,15 +4,46 @@ import ( "fmt" "math" "strconv" + "strings" ) type Stack []float64 +func (s *Stack) push(v float64) { + *s = append(*s, v) +} + +func (s *Stack) pop() *float64 { + if len(*s) > 0 { + v := (*s)[len(*s)-1] + *s = (*s)[:len(*s)-1] + return &v + } + return nil +} + type Calculator struct { stack Stack buf string } +// swap swaps the values of the buffer and the bottom element of the stack. If +// the buffer is empty this simply pops from the stack. If the stack is empty, +// this simply pushes to the stack. +func (c *Calculator) swap() { + st := c.stack.pop() + if con := parseConstant(c.buf); con != nil { + c.stack.push(*con) + } else if f, err := strconv.ParseFloat(c.buf, 64); err == nil { + c.stack.push(f) + } + if st != nil { + c.buf = strings.TrimSpace(printStackVal(*st)) + } else { + c.buf = "" + } +} + // performOp performs the specified arithmetic operation and returns nil or // OpError if op is not a valid operator. func (c *Calculator) performOp(op byte) error { @@ -37,6 +37,8 @@ func (ui UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg.String() { case "ctrl+c", "Q": return ui, tea.Quit + case "J", "K": + ui.calc.swap() case "+", "-", "*", "/", "%", "^": if err := ui.calc.performOp(msg.String()[0]); err != nil { panic(err) @@ -64,7 +66,7 @@ func (ui UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (ui UI) View() string { var s string for _, f := range ui.calc.stack { - s += fmt.Sprintf(" %.*g\n", sigDigs, f) + s += printStackVal(f) + "\n" } s += boxTop(ui.windowWidth) + "\n" s += fmt.Sprintf("%[1]c%-*s%[1]c\n", boxVertical, ui.windowWidth-2, ui.calc.buf) @@ -72,6 +74,10 @@ func (ui UI) View() string { return s } +func printStackVal(v float64) string { + return fmt.Sprintf(" %.*g", sigDigs, v) +} + // boxTop returns the top of a UTF-8 box, 'width' characters wide (including // corners). func boxTop(width int) string { |