@@ -3,6 +3,7 @@ package expr
33import (
44 "fmt"
55 "math"
6+ "reflect"
67 "regexp"
78)
89
@@ -297,25 +298,51 @@ func (n methodNode) Eval(env interface{}) (interface{}, error) {
297298 return nil , err
298299 }
299300
300- return call (n .method , method , n .arguments , env )
301- }
301+ in := make ([]reflect.Value , 0 )
302302
303- func (n builtinNode ) Eval (env interface {}) (interface {}, error ) {
304- if len (n .arguments ) == 0 {
305- return nil , fmt .Errorf ("missing argument to %v" , n .name )
303+ for _ , a := range n .arguments {
304+ i , err := a .Eval (env )
305+ if err != nil {
306+ return nil , err
307+ }
308+ in = append (in , reflect .ValueOf (i ))
306309 }
307- if len (n .arguments ) > 1 {
308- return nil , fmt .Errorf ("too many arguments to %v: %v" , n .name , n )
310+
311+ out := reflect .ValueOf (method ).Call (in )
312+
313+ if len (out ) == 0 {
314+ return nil , nil
315+ } else if len (out ) > 1 {
316+ return nil , fmt .Errorf ("method %q must return only one value" , n .method )
309317 }
310318
311- a , err := n .arguments [0 ].Eval (env )
312- if err != nil {
313- return nil , err
319+ if out [0 ].IsValid () && out [0 ].CanInterface () {
320+ return out [0 ].Interface (), nil
314321 }
315322
323+ return nil , nil
324+ }
325+
326+ func (n builtinNode ) Eval (env interface {}) (interface {}, error ) {
316327 switch n .name {
317328 case "len" :
318- return count (n .arguments [0 ], a )
329+ if len (n .arguments ) == 0 {
330+ return nil , fmt .Errorf ("missing argument: %v" , n )
331+ }
332+ if len (n .arguments ) > 1 {
333+ return nil , fmt .Errorf ("too many arguments: %v" , n )
334+ }
335+
336+ i , err := n .arguments [0 ].Eval (env )
337+ if err != nil {
338+ return nil , err
339+ }
340+
341+ switch reflect .TypeOf (i ).Kind () {
342+ case reflect .Array , reflect .Slice , reflect .String :
343+ return float64 (reflect .ValueOf (i ).Len ()), nil
344+ }
345+ return nil , fmt .Errorf ("invalid argument %v (type %T)" , n , i )
319346 }
320347
321348 return nil , fmt .Errorf ("unknown %q builtin" , n .name )
@@ -327,7 +354,29 @@ func (n functionNode) Eval(env interface{}) (interface{}, error) {
327354 return nil , err
328355 }
329356
330- return call (n .name , fn , n .arguments , env )
357+ in := make ([]reflect.Value , 0 )
358+
359+ for _ , a := range n .arguments {
360+ i , err := a .Eval (env )
361+ if err != nil {
362+ return nil , err
363+ }
364+ in = append (in , reflect .ValueOf (i ))
365+ }
366+
367+ out := reflect .ValueOf (fn ).Call (in )
368+
369+ if len (out ) == 0 {
370+ return nil , nil
371+ } else if len (out ) > 1 {
372+ return nil , fmt .Errorf ("func %q must return only one value" , n .name )
373+ }
374+
375+ if out [0 ].IsValid () && out [0 ].CanInterface () {
376+ return out [0 ].Interface (), nil
377+ }
378+
379+ return nil , nil
331380}
332381
333382func (n conditionalNode ) Eval (env interface {}) (interface {}, error ) {
0 commit comments