ginger/core/mathgen/mathgen.tpl
2014-10-23 21:00:07 -04:00

58 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}}