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

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

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

Loading…
Cancel
Save