From 2b9322624f7d58627bcaee521b8d756787bf28d8 Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Sat, 20 Oct 2012 17:43:00 -0400 Subject: [PATCH] added division, prevent div by zero panics --- acc.go | 26 ++++++++++++++++++-------- proc.go | 47 +++++++++++++++++++++++++++++++++++------------ skeam.go | 1 + 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/acc.go b/acc.go index e6b41d6..be4fb44 100644 --- a/acc.go +++ b/acc.go @@ -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 { diff --git a/proc.go b/proc.go index 6d67290..a2501d9 100644 --- a/proc.go +++ b/proc.go @@ -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...) diff --git a/skeam.go b/skeam.go index a3708b9..4600ff1 100644 --- a/skeam.go +++ b/skeam.go @@ -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