aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Anthony <sam@samanthony.xyz>2023-07-29 10:20:07 -0230
committerSam Anthony <sam@samanthony.xyz>2023-07-29 10:20:07 -0230
commita253229dbbef5e09449884febacdfbbd4de85d6d (patch)
tree471552d43293a856d73aa8a08692b3bca7724dc3
parent545f618f333a8e4d5d9c38266e14574eef542fcb (diff)
downloadpfc-a253229dbbef5e09449884febacdfbbd4de85d6d.zip
swap command
-rw-r--r--calculator.go31
-rw-r--r--ui.go8
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 {
diff --git a/ui.go b/ui.go
index aedaa6c..aa0f114 100644
--- a/ui.go
+++ b/ui.go
@@ -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 {