refactoring a bit, defined accumulator struct

added subtraction and multiplication
master
Jordan Orelli 12 years ago
parent 39286ce998
commit ac8430076a

@ -0,0 +1,64 @@
package main
import (
"fmt"
"reflect"
)
type accumulator struct {
name string
floatFn func(float64, float64) float64
intFn func(int64, int64) int64
acc int64
accf float64
floating bool
}
func (a *accumulator) total(vals ...interface{}) (interface{}, error) {
if len(vals) == 0 {
return int64(0), nil
}
switch v := vals[0].(type) {
case int64:
a.acc = v
case float64:
a.floating = true
a.accf = v
default:
return nil, fmt.Errorf("%v is not defined for %v", a.name, reflect.TypeOf(v))
}
if len(vals) == 1 {
if a.floating {
return a.accf, nil
} else {
return a.acc, nil
}
}
for _, raw := range vals[1:] {
switch v := raw.(type) {
case int64:
if a.floating {
a.accf = a.floatFn(a.accf, float64(v))
break
}
a.acc = a.intFn(a.acc, v)
case float64:
if !a.floating {
a.floating = true
a.accf = a.floatFn(a.accf, float64(a.acc))
}
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 {
return a.acc, nil
}
panic("not reached")
}

@ -1,40 +1,42 @@
package main
import (
"fmt"
"reflect"
)
type proc func(...interface{}) (interface{}, error)
func addition(vals ...interface{}) (interface{}, error) {
addFloats := false
var accf float64
var acc int64
a := accumulator{
name: "addition",
floatFn: func(left, right float64) float64 {
return left + right
},
intFn: func(left, right int64) int64 {
return left + right
},
}
return a.total(vals...)
}
for _, raw := range vals {
switch v := raw.(type) {
case int64:
if addFloats {
accf += float64(v)
} else {
acc += v
}
case float64:
if !addFloats {
addFloats = true
accf += float64(acc)
}
accf += v
default:
return nil, fmt.Errorf("addition is not defined for %v", reflect.TypeOf(v))
}
func subtraction(vals ...interface{}) (interface{}, error) {
a := accumulator{
name: "subtraction",
floatFn: func(left, right float64) float64 {
return left - right
},
intFn: func(left, right int64) int64 {
return left - right
},
}
return a.total(vals...)
}
if addFloats {
return accf, nil
} else {
return acc, nil
func multiplication(vals ...interface{}) (interface{}, error) {
a := accumulator{
name: "multiplication",
floatFn: func(left, right float64) float64 {
return left * right
},
intFn: func(left, right int64) int64 {
return left * right
},
}
panic("not reached")
return a.total(vals...)
}

@ -17,10 +17,12 @@ type sexp []interface{}
type symbol string
var universe = environment{
"int": 5,
"float": 3.14,
"int": int64(5),
"float": float64(3.14),
"string": "Jordan",
"+": proc(addition),
"-": proc(subtraction),
"*": proc(multiplication),
}
// parses the string lexeme into a value that can be eval'd

Loading…
Cancel
Save