aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Anthony <sam@samanthony.xyz>2023-07-29 11:19:55 -0230
committerSam Anthony <sam@samanthony.xyz>2023-07-29 11:19:55 -0230
commit008e4021375883610cf1b07e005a4176acadc0de (patch)
tree3148bbf1945c8e0517810ea234e16c498f968eb4
parentc12813975d7529f864199b876bc3ee3b470c1c18 (diff)
downloadpfc-008e4021375883610cf1b07e005a4176acadc0de.zip
trig functions
-rw-r--r--calc.go12
-rw-r--r--func.go50
-rw-r--r--ui.go2
3 files changed, 52 insertions, 12 deletions
diff --git a/calc.go b/calc.go
index 8afc43a..1d969cc 100644
--- a/calc.go
+++ b/calc.go
@@ -5,9 +5,17 @@ import (
"strings"
)
+type AngleMode int
+
+const (
+ modeDeg = iota
+ modeRad
+)
+
type Calculator struct {
- stack Stack
- buf string
+ stack Stack
+ buf string
+ anglem AngleMode
}
// swap swaps the values of the buffer and the bottom element of the stack. If
diff --git a/func.go b/func.go
index 914cb61..445cb41 100644
--- a/func.go
+++ b/func.go
@@ -1,18 +1,50 @@
package main
-import "math"
+import (
+ "fmt"
+ "math"
+)
-// parseFunction returns nil is s is not a valid function.
-func parseFunction(s string) func(Stack) {
- switch s {
- case "sin":
- return sin
+// parseFunction returns nil is fn is not a valid function.
+func parseFunction(fn string) func(Calculator) {
+ switch fn {
+ case "sin", "cos", "tan":
+ return trig(fn)
}
return nil
}
-func sin(stack Stack) {
- if len(stack) > 0 {
- stack[len(stack)-1] = math.Sin(stack[len(stack)-1])
+// trig returns a closure that performs the trig function specified by fn.
+// Panics if fn is not one of "sin", "cos" or "tan".
+func trig(fn string) func(Calculator) {
+ return func(c Calculator) {
+ if len(c.stack) <= 0 {
+ return
+ }
+ v := &c.stack[len(c.stack)-1]
+ // The math package expects arguments to trig functions to be in radians.
+ if c.anglem == modeDeg {
+ *v = radians(*v)
+ }
+ switch fn {
+ case "sin":
+ *v = math.Sin(*v)
+ case "cos":
+ *v = math.Cos(*v)
+ case "tan":
+ *v = math.Tan(*v)
+ default:
+ panic(fmt.Sprintf("invalid trig function: '%s'", fn))
+ }
}
}
+
+// radians converts degrees to radians.
+func radians(deg float64) float64 {
+ return deg * math.Pi / 180.0
+}
+
+// degrees converts radians to degrees.
+func degrees(rad float64) float64 {
+ return rad * 180 / math.Pi
+}
diff --git a/ui.go b/ui.go
index 9bf9caa..877f11b 100644
--- a/ui.go
+++ b/ui.go
@@ -56,7 +56,7 @@ func (ui UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
case "enter":
if fn := parseFunction(ui.calc.buf); fn != nil {
- fn(ui.calc.stack)
+ fn(ui.calc)
} else if con := parseConstant(ui.calc.buf); con != nil {
ui.calc.stack.push(*con)
} else if f, err := strconv.ParseFloat(ui.calc.buf, 64); err == nil {