Skip to content

Commit 078f2e8

Browse files
committed
Refactor builtin.Function and move builtin funcs to builtin package
1 parent 2eb6a03 commit 078f2e8

File tree

7 files changed

+183
-145
lines changed

7 files changed

+183
-145
lines changed

builtin/builtin.go

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,15 @@ import (
77

88
type Function struct {
99
Name string
10-
Id int
1110
Func func(args ...interface{}) (interface{}, error)
1211
Types []reflect.Type
1312
Validate func(args []reflect.Type) (reflect.Type, error)
1413
}
1514

16-
const (
17-
Len = iota + 1
18-
Abs
19-
Int
20-
Float
21-
)
22-
23-
var Builtins = map[int]*Function{
24-
Len: {
15+
var Builtins = []*Function{
16+
{
2517
Name: "len",
26-
Id: Len,
18+
Func: Len,
2719
Validate: func(args []reflect.Type) (reflect.Type, error) {
2820
if len(args) != 1 {
2921
return anyType, fmt.Errorf("invalid number of arguments for len (expected 1, got %d)", len(args))
@@ -35,9 +27,9 @@ var Builtins = map[int]*Function{
3527
return anyType, fmt.Errorf("invalid argument for len (type %s)", args[0])
3628
},
3729
},
38-
Abs: {
30+
{
3931
Name: "abs",
40-
Id: Abs,
32+
Func: Abs,
4133
Validate: func(args []reflect.Type) (reflect.Type, error) {
4234
if len(args) != 1 {
4335
return anyType, fmt.Errorf("invalid number of arguments for abs (expected 1, got %d)", len(args))
@@ -49,9 +41,9 @@ var Builtins = map[int]*Function{
4941
return anyType, fmt.Errorf("invalid argument for abs (type %s)", args[0])
5042
},
5143
},
52-
Int: {
44+
{
5345
Name: "int",
54-
Id: Int,
46+
Func: Int,
5547
Validate: func(args []reflect.Type) (reflect.Type, error) {
5648
if len(args) != 1 {
5749
return anyType, fmt.Errorf("invalid number of arguments for int (expected 1, got %d)", len(args))
@@ -67,9 +59,9 @@ var Builtins = map[int]*Function{
6759
return anyType, fmt.Errorf("invalid argument for int (type %s)", args[0])
6860
},
6961
},
70-
Float: {
62+
{
7163
Name: "float",
72-
Id: Float,
64+
Func: Float,
7365
Validate: func(args []reflect.Type) (reflect.Type, error) {
7466
if len(args) != 1 {
7567
return anyType, fmt.Errorf("invalid number of arguments for float (expected 1, got %d)", len(args))

builtin/func.go

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package builtin
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
"strconv"
7+
)
8+
9+
func Len(xs ...interface{}) (interface{}, error) {
10+
x := xs[0]
11+
v := reflect.ValueOf(x)
12+
switch v.Kind() {
13+
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
14+
return v.Len(), nil
15+
default:
16+
return nil, fmt.Errorf("invalid argument for len (type %T)", x)
17+
}
18+
}
19+
20+
func Abs(xs ...interface{}) (interface{}, error) {
21+
x := xs[0]
22+
switch x.(type) {
23+
case float32:
24+
if x.(float32) < 0 {
25+
return -x.(float32), nil
26+
} else {
27+
return x, nil
28+
}
29+
case float64:
30+
if x.(float64) < 0 {
31+
return -x.(float64), nil
32+
} else {
33+
return x, nil
34+
}
35+
case int:
36+
if x.(int) < 0 {
37+
return -x.(int), nil
38+
} else {
39+
return x, nil
40+
}
41+
case int8:
42+
if x.(int8) < 0 {
43+
return -x.(int8), nil
44+
} else {
45+
return x, nil
46+
}
47+
case int16:
48+
if x.(int16) < 0 {
49+
return -x.(int16), nil
50+
} else {
51+
return x, nil
52+
}
53+
case int32:
54+
if x.(int32) < 0 {
55+
return -x.(int32), nil
56+
} else {
57+
return x, nil
58+
}
59+
case int64:
60+
if x.(int64) < 0 {
61+
return -x.(int64), nil
62+
} else {
63+
return x, nil
64+
}
65+
case uint:
66+
if x.(uint) < 0 {
67+
return -x.(uint), nil
68+
} else {
69+
return x, nil
70+
}
71+
case uint8:
72+
if x.(uint8) < 0 {
73+
return -x.(uint8), nil
74+
} else {
75+
return x, nil
76+
}
77+
case uint16:
78+
if x.(uint16) < 0 {
79+
return -x.(uint16), nil
80+
} else {
81+
return x, nil
82+
}
83+
case uint32:
84+
if x.(uint32) < 0 {
85+
return -x.(uint32), nil
86+
} else {
87+
return x, nil
88+
}
89+
case uint64:
90+
if x.(uint64) < 0 {
91+
return -x.(uint64), nil
92+
} else {
93+
return x, nil
94+
}
95+
}
96+
return nil, fmt.Errorf("invalid argument for abs (type %T)", x)
97+
}
98+
99+
func Int(xs ...interface{}) (interface{}, error) {
100+
x := xs[0]
101+
switch x := x.(type) {
102+
case float32:
103+
return int(x), nil
104+
case float64:
105+
return int(x), nil
106+
case int:
107+
return x, nil
108+
case int8:
109+
return int(x), nil
110+
case int16:
111+
return int(x), nil
112+
case int32:
113+
return int(x), nil
114+
case int64:
115+
return int(x), nil
116+
case uint:
117+
return int(x), nil
118+
case uint8:
119+
return int(x), nil
120+
case uint16:
121+
return int(x), nil
122+
case uint32:
123+
return int(x), nil
124+
case uint64:
125+
return int(x), nil
126+
case string:
127+
i, err := strconv.Atoi(x)
128+
if err != nil {
129+
return nil, fmt.Errorf("invalid operation: int(%s)", x)
130+
}
131+
return i, nil
132+
default:
133+
return nil, fmt.Errorf("invalid operation: int(%T)", x)
134+
}
135+
}
136+
137+
func Float(xs ...interface{}) (interface{}, error) {
138+
x := xs[0]
139+
switch x := x.(type) {
140+
case float32:
141+
return float64(x), nil
142+
case float64:
143+
return x, nil
144+
case int:
145+
return float64(x), nil
146+
case int8:
147+
return float64(x), nil
148+
case int16:
149+
return float64(x), nil
150+
case int32:
151+
return float64(x), nil
152+
case int64:
153+
return float64(x), nil
154+
case uint:
155+
return float64(x), nil
156+
case uint8:
157+
return float64(x), nil
158+
case uint16:
159+
return float64(x), nil
160+
case uint32:
161+
return float64(x), nil
162+
case uint64:
163+
return float64(x), nil
164+
case string:
165+
f, err := strconv.ParseFloat(x, 64)
166+
if err != nil {
167+
return nil, fmt.Errorf("invalid operation: float(%s)", x)
168+
}
169+
return f, nil
170+
default:
171+
return nil, fmt.Errorf("invalid operation: float(%T)", x)
172+
}
173+
}

compiler/compiler.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -563,10 +563,6 @@ func (c *compiler) CallNode(node *ast.CallNode) {
563563
c.compile(arg)
564564
}
565565
if node.Func != nil {
566-
if node.Func.Id > 0 {
567-
c.emit(OpBuiltin, node.Func.Id)
568-
return
569-
}
570566
switch len(node.Arguments) {
571567
case 0:
572568
c.emit(OpCall0, c.addFunction(node))

vm/opcodes.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ const (
5757
OpCallN
5858
OpCallFast
5959
OpCallTyped
60-
OpBuiltin
6160
OpArray
6261
OpMap
6362
OpLen

vm/program.go

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"text/tabwriter"
1010

1111
"github.com/antonmedv/expr/ast"
12-
"github.com/antonmedv/expr/builtin"
1312
"github.com/antonmedv/expr/file"
1413
"github.com/antonmedv/expr/vm/runtime"
1514
)
@@ -64,13 +63,6 @@ func (program *Program) Disassemble() string {
6463
}
6564
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, label, arg, c)
6665
}
67-
builtIn := func(label string) {
68-
f, ok := builtin.Builtins[arg]
69-
if !ok {
70-
panic(fmt.Sprintf("unknown builtin %v", arg))
71-
}
72-
_, _ = fmt.Fprintf(w, "%v\t%v\t%v\n", pp, "OpBuiltin", f.Name)
73-
}
7466

7567
switch op {
7668
case OpInvalid:
@@ -236,9 +228,6 @@ func (program *Program) Disassemble() string {
236228
signature := reflect.TypeOf(FuncTypes[arg]).Elem().String()
237229
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, "OpCallTyped", arg, signature)
238230

239-
case OpBuiltin:
240-
builtIn("OpBuiltin")
241-
242231
case OpArray:
243232
code("OpArray")
244233

0 commit comments

Comments
 (0)