diff options
| -rw-r--r-- | calc.go | 12 | ||||
| -rw-r--r-- | func.go | 50 | ||||
| -rw-r--r-- | ui.go | 2 |
3 files changed, 52 insertions, 12 deletions
@@ -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 @@ -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 +} @@ -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 { |