added division, prevent div by zero panics

master
Jordan Orelli 12 years ago
parent ac8430076a
commit 2b9322624f

@ -7,8 +7,8 @@ import (
type accumulator struct { type accumulator struct {
name string name string
floatFn func(float64, float64) float64 floatFn func(float64, float64) (float64, error)
intFn func(int64, int64) int64 intFn func(int64, int64) (int64, error)
acc int64 acc int64
accf float64 accf float64
floating bool floating bool
@ -40,21 +40,31 @@ func (a *accumulator) total(vals ...interface{}) (interface{}, error) {
for _, raw := range vals[1:] { for _, raw := range vals[1:] {
switch v := raw.(type) { switch v := raw.(type) {
case int64: case int64:
var err error
if a.floating { if a.floating {
a.accf = a.floatFn(a.accf, float64(v)) a.accf, err = a.floatFn(a.accf, float64(v))
break } else {
a.acc, err = a.intFn(a.acc, v)
}
if err != nil {
return nil, err
} }
a.acc = a.intFn(a.acc, v)
case float64: case float64:
if !a.floating { var err error
if a.floating {
a.accf, err = a.floatFn(a.accf, v)
} else {
a.floating = true a.floating = true
a.accf = a.floatFn(a.accf, float64(a.acc)) a.accf, err = a.floatFn(a.accf, float64(a.acc))
}
if err != nil {
return nil, err
} }
a.accf = a.floatFn(a.accf, v)
default: default:
return nil, fmt.Errorf("%v is not defined for %v", a.name, reflect.TypeOf(v)) return nil, fmt.Errorf("%v is not defined for %v", a.name, reflect.TypeOf(v))
} }
} }
if a.floating { if a.floating {
return a.accf, nil return a.accf, nil
} else { } else {

@ -1,15 +1,19 @@
package main package main
import (
"errors"
)
type proc func(...interface{}) (interface{}, error) type proc func(...interface{}) (interface{}, error)
func addition(vals ...interface{}) (interface{}, error) { func addition(vals ...interface{}) (interface{}, error) {
a := accumulator{ a := accumulator{
name: "addition", name: "addition",
floatFn: func(left, right float64) float64 { floatFn: func(left, right float64) (float64, error) {
return left + right return left + right, nil
}, },
intFn: func(left, right int64) int64 { intFn: func(left, right int64) (int64, error) {
return left + right return left + right, nil
}, },
} }
return a.total(vals...) return a.total(vals...)
@ -18,11 +22,11 @@ func addition(vals ...interface{}) (interface{}, error) {
func subtraction(vals ...interface{}) (interface{}, error) { func subtraction(vals ...interface{}) (interface{}, error) {
a := accumulator{ a := accumulator{
name: "subtraction", name: "subtraction",
floatFn: func(left, right float64) float64 { floatFn: func(left, right float64) (float64, error) {
return left - right return left - right, nil
}, },
intFn: func(left, right int64) int64 { intFn: func(left, right int64) (int64, error) {
return left - right return left - right, nil
}, },
} }
return a.total(vals...) return a.total(vals...)
@ -31,11 +35,30 @@ func subtraction(vals ...interface{}) (interface{}, error) {
func multiplication(vals ...interface{}) (interface{}, error) { func multiplication(vals ...interface{}) (interface{}, error) {
a := accumulator{ a := accumulator{
name: "multiplication", name: "multiplication",
floatFn: func(left, right float64) float64 { floatFn: func(left, right float64) (float64, error) {
return left * right return left * right, nil
},
intFn: func(left, right int64) (int64, error) {
return left * right, nil
},
}
return a.total(vals...)
}
func division(vals ...interface{}) (interface{}, error) {
a := accumulator{
name: "division",
floatFn: func(left, right float64) (float64, error) {
if right == 0.0 {
return 0.0, errors.New("float division by zero")
}
return left / right, nil
}, },
intFn: func(left, right int64) int64 { intFn: func(left, right int64) (int64, error) {
return left * right if right == 0 {
return 0, errors.New("int division by zero")
}
return left / right, nil
}, },
} }
return a.total(vals...) return a.total(vals...)

@ -23,6 +23,7 @@ var universe = environment{
"+": proc(addition), "+": proc(addition),
"-": proc(subtraction), "-": proc(subtraction),
"*": proc(multiplication), "*": proc(multiplication),
"/": proc(division),
} }
// parses the string lexeme into a value that can be eval'd // parses the string lexeme into a value that can be eval'd

Loading…
Cancel
Save