Esempio n. 1
0
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
}
Esempio n. 2
0
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
}