ginger/core/mathgen/mathgen.tpl
2014-10-23 20:46:05 -04:00

67 lines
1.5 KiB
Smarty

package core
import (
"fmt"
"github.com/mediocregopher/ginger/seq"
"github.com/mediocregopher/ginger/types"
)
type mathReduceFn func(types.Elem, types.Elem) types.Elem
func mathReduce(fn mathReduceFn, zero types.Elem, s seq.Seq) types.Elem {
reduceFn := func(acc, el types.Elem) (types.Elem, bool) {
return fn(acc, el), false
}
return seq.Reduce(reduceFn, zero, s)
}
{{range .}}
{{$mathOp := .}}
{{range .OpTypes}}
func {{$mathOp.Private}}{{.CastFn}}(a, b types.Elem) types.Elem {
return types.GoType{ {{.CastFn}}(a) {{$mathOp.Op}} {{.CastFn}}(b) }
}
{{end}}
{{if $mathOp.IncludeString}}
func {{$mathOp.Private}}String(a, b types.Elem) types.Elem {
return types.GoType{ String(a) {{$mathOp.Op}} String(b) }
}
{{end}}
func {{$mathOp.Public}}(s seq.Seq) types.Elem {
var first, zero types.Elem
{{if (eq $mathOp.Unit "")}}
if seq.Empty(s) {
panic("{{$mathOp.Public}} cannot be called with no arguments")
}
zero, s, _ = s.FirstRest()
first = zero
{{else}}
if seq.Empty(s) {
return types.GoType{ {{$mathOp.Unit}} }
}
first, _, _ = s.FirstRest()
{{end}}
var fn mathReduceFn
switch first.(types.GoType).V.(type) {
{{range .OpTypes}}
case {{.Type}}:
fn = {{$mathOp.Private}}{{.CastFn}}
{{if (ne $mathOp.Unit "")}}
zero = types.GoType{ {{.Type}}({{$mathOp.Unit}}) }
{{end}}
{{end}}
{{if $mathOp.IncludeString}}
case string:
fn = {{$mathOp.Private}}String
zero = types.GoType{string("")}
{{end}}
default:
panic(fmt.Sprintf("$#v cannot have {{$mathOp.Public}} called on it", first))
}
return mathReduce(fn, zero, s)
}
{{end}}