@@ -7,23 +7,98 @@ import (
7
7
"github.com/antonmedv/expr/vm/runtime"
8
8
)
9
9
10
+ var (
11
+ anyType = reflect .TypeOf (new (interface {})).Elem ()
12
+ integerType = reflect .TypeOf (0 )
13
+ )
14
+
10
15
type Function struct {
11
16
Name string
12
- Func func (params ... interface {}) (interface {}, error )
17
+ Func func (args ... interface {}) (interface {}, error )
13
18
Types []reflect.Type
14
- Validate func (args []reflect.Type ) error
19
+ Validate func (args []reflect.Type ) (reflect. Type , error )
15
20
}
16
21
17
22
var Builtins = []* Function {
18
23
{
19
24
Name : "len" ,
20
25
Func : runtime .Len ,
21
- Validate : func (args []reflect.Type ) error {
26
+ Validate : func (args []reflect.Type ) (reflect.Type , error ) {
27
+ if len (args ) != 1 {
28
+ return anyType , fmt .Errorf ("invalid number of arguments for len (expected 1, got %d)" , len (args ))
29
+ }
22
30
switch args [0 ].Kind () {
23
31
case reflect .Array , reflect .Map , reflect .Slice , reflect .String , reflect .Interface :
24
- return nil
32
+ return integerType , nil
33
+ }
34
+ return anyType , fmt .Errorf ("invalid argument for len (type %s)" , args [0 ])
35
+ },
36
+ },
37
+ {
38
+ Name : "abs" ,
39
+ Func : func (args ... interface {}) (interface {}, error ) {
40
+ x := args [0 ]
41
+ switch x .(type ) {
42
+ case float32 :
43
+ if x .(float32 ) < 0 {
44
+ return - x .(float32 ), nil
45
+ }
46
+ case float64 :
47
+ if x .(float64 ) < 0 {
48
+ return - x .(float64 ), nil
49
+ }
50
+ case int :
51
+ if x .(int ) < 0 {
52
+ return - x .(int ), nil
53
+ }
54
+ case int8 :
55
+ if x .(int8 ) < 0 {
56
+ return - x .(int8 ), nil
57
+ }
58
+ case int16 :
59
+ if x .(int16 ) < 0 {
60
+ return - x .(int16 ), nil
61
+ }
62
+ case int32 :
63
+ if x .(int32 ) < 0 {
64
+ return - x .(int32 ), nil
65
+ }
66
+ case int64 :
67
+ if x .(int64 ) < 0 {
68
+ return - x .(int64 ), nil
69
+ }
70
+ case uint :
71
+ if x .(uint ) < 0 {
72
+ return - x .(uint ), nil
73
+ }
74
+ case uint8 :
75
+ if x .(uint8 ) < 0 {
76
+ return - x .(uint8 ), nil
77
+ }
78
+ case uint16 :
79
+ if x .(uint16 ) < 0 {
80
+ return - x .(uint16 ), nil
81
+ }
82
+ case uint32 :
83
+ if x .(uint32 ) < 0 {
84
+ return - x .(uint32 ), nil
85
+ }
86
+ case uint64 :
87
+ if x .(uint64 ) < 0 {
88
+ return - x .(uint64 ), nil
89
+ }
90
+ }
91
+ return nil , fmt .Errorf ("invalid argument for abs (type %T)" , x )
92
+ },
93
+ Validate : func (args []reflect.Type ) (reflect.Type , error ) {
94
+ if len (args ) != 1 {
95
+ return anyType , fmt .Errorf ("invalid number of arguments for abs (expected 1, got %d)" , len (args ))
96
+ }
97
+ switch args [0 ].Kind () {
98
+ case reflect .Float32 , reflect .Float64 , reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 , reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Interface :
99
+ return args [0 ], nil
25
100
}
26
- return fmt .Errorf ("invalid argument for len (type %s)" , args [0 ])
101
+ return anyType , fmt .Errorf ("invalid argument for abs (type %s)" , args [0 ])
27
102
},
28
103
},
29
104
}
0 commit comments