作者:nicolle
项目:bosu
func (e *State) walkFunc(node *parse.FuncNode, T miniprofiler.Timer) *Results {
var res *Results
T.Step("func: "+node.Name, func(T miniprofiler.Timer) {
var in []reflect.Value
for i, a := range node.Args {
var v interface{}
switch t := a.(type) {
case *parse.StringNode:
v = t.Text
case *parse.NumberNode:
v = t.Float64
case *parse.FuncNode:
v = extract(e.walkFunc(t, T))
case *parse.UnaryNode:
v = extract(e.walkUnary(t, T))
case *parse.BinaryNode:
v = extract(e.walkBinary(t, T))
case *parse.ExprNode:
v = e.walkExpr(t, T)
default:
panic(fmt.Errorf("expr: unknown func arg type"))
}
var argType models.FuncType
if i >= len(node.F.Args) {
if !node.F.VArgs {
panic("expr: shouldn't be here, more args then expected and not variable argument type func")
}
argType = node.F.Args[node.F.VArgsPos]
} else {
argType = node.F.Args[i]
}
if f, ok := v.(float64); ok && argType == models.TypeNumberSet {
v = fromScalar(f)
}
in = append(in, reflect.ValueOf(v))
}
f := reflect.ValueOf(node.F.F)
fr := f.Call(append([]reflect.Value{reflect.ValueOf(e), reflect.ValueOf(T)}, in...))
res = fr[0].Interface().(*Results)
if len(fr) > 1 && !fr[1].IsNil() {
err := fr[1].Interface().(error)
if err != nil {
panic(err)
}
}
if node.Return() == models.TypeNumberSet {
for _, r := range res.Results {
e.AddComputation(r, node.String(), r.Value.(Number))
}
}
})
return res
}
作者:marswan
项目:bosu
func (e *State) walkFunc(node *parse.FuncNode, T miniprofiler.Timer) *Results {
var res *Results
T.Step("func: "+node.Name, func(T miniprofiler.Timer) {
var in []reflect.Value
for i, a := range node.Args {
var v interface{}
switch t := a.(type) {
case *parse.StringNode:
v = t.Text
case *parse.NumberNode:
v = t.Float64
case *parse.FuncNode:
v = extract(e.walkFunc(t, T))
case *parse.UnaryNode:
v = extract(e.walkUnary(t, T))
case *parse.BinaryNode:
v = extract(e.walkBinary(t, T))
default:
panic(fmt.Errorf("expr: unknown func arg type"))
}
if f, ok := v.(float64); ok && node.F.Args[i] == parse.TypeNumberSet {
v = fromScalar(f)
}
in = append(in, reflect.ValueOf(v))
}
f := reflect.ValueOf(node.F.F)
fr := f.Call(append([]reflect.Value{reflect.ValueOf(e), reflect.ValueOf(T)}, in...))
res = fr[0].Interface().(*Results)
if len(fr) > 1 && !fr[1].IsNil() {
err := fr[1].Interface().(error)
if err != nil {
panic(err)
}
}
if node.Return() == parse.TypeNumberSet {
for _, r := range res.Results {
e.AddComputation(r, node.String(), r.Value.(Number))
}
}
})
return res
}