aboutsummaryrefslogtreecommitdiffstats
path: root/op.go
diff options
context:
space:
mode:
Diffstat (limited to 'op.go')
-rw-r--r--op.go43
1 files changed, 43 insertions, 0 deletions
diff --git a/op.go b/op.go
new file mode 100644
index 0000000..ab57a84
--- /dev/null
+++ b/op.go
@@ -0,0 +1,43 @@
+package main
+
+import (
+ "fmt"
+ "math"
+)
+
+// parseOp returns a closure that performs the specified arithmetic operation,
+// or OpError if op is not a valid operator.
+func parseOp(op byte) (func(lhs *float64, rhs float64), error) {
+ switch op {
+ case '+':
+ return func(lhs *float64, rhs float64) { *lhs += rhs }, nil
+ case '-':
+ return func(lhs *float64, rhs float64) { *lhs -= rhs }, nil
+ case '*':
+ return func(lhs *float64, rhs float64) { *lhs *= rhs }, nil
+ case '/':
+ return func(lhs *float64, rhs float64) {
+ if rhs != 0 {
+ *lhs /= rhs
+ }
+ }, nil
+ case '%':
+ return func(lhs *float64, rhs float64) {
+ if rhs != 0 {
+ *lhs = float64(int64(*lhs) % int64(rhs))
+ }
+ }, nil
+ case '^':
+ return func(lhs *float64, rhs float64) { *lhs = math.Pow(*lhs, rhs) }, nil
+ }
+ return nil, OpError{op}
+}
+
+// OpError records an invalid arithmetic operator.
+type OpError struct {
+ c byte
+}
+
+func (e OpError) Error() string {
+ return fmt.Sprintf("invalid operator: %c", e.c)
+}