Skip to content

Commit 6bedd3b

Browse files
committed
Separate opcode for int equal
1 parent 3817bac commit 6bedd3b

File tree

6 files changed

+79
-47
lines changed

6 files changed

+79
-47
lines changed

bench_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ func Benchmark_expr(b *testing.B) {
1010
params := make(map[string]interface{})
1111
params["Origin"] = "MOW"
1212
params["Country"] = "RU"
13-
params["Adults"] = int64(1)
14-
params["Value"] = int64(100)
13+
params["Adults"] = 1
14+
params["Value"] = 100
1515

1616
program, err := expr.Compile(`(Origin == "MOW" || Country == "RU") && (Value >= 100 || Adults == 1)`, expr.Env(params))
1717
if err != nil {
@@ -52,7 +52,7 @@ func Benchmark_filter(b *testing.B) {
5252

5353
func Benchmark_access(b *testing.B) {
5454
type Price struct {
55-
Value int64
55+
Value int
5656
}
5757
type Env struct {
5858
Price Price

compiler/compiler.go

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -250,16 +250,17 @@ func (c *compiler) UnaryNode(node *ast.UnaryNode) {
250250
}
251251

252252
func (c *compiler) BinaryNode(node *ast.BinaryNode) {
253+
l := kind(node.Left)
254+
r := kind(node.Right)
253255

254256
switch node.Operator {
255257
case "==":
256258
c.compile(node.Left)
257259
c.compile(node.Right)
258260

259-
l := kind(node.Left)
260-
r := kind(node.Right)
261-
262-
if l == reflect.String && r == reflect.String {
261+
if l == r && l == reflect.Int {
262+
c.emit(OpEqualInt)
263+
} else if l == r && l == reflect.String {
263264
c.emit(OpEqualString)
264265
} else {
265266
c.emit(OpEqual)
@@ -299,22 +300,42 @@ func (c *compiler) BinaryNode(node *ast.BinaryNode) {
299300
case "<":
300301
c.compile(node.Left)
301302
c.compile(node.Right)
302-
c.emit(OpLess)
303+
304+
if l == r && l == reflect.Int {
305+
c.emit(OpLessInt)
306+
} else {
307+
c.emit(OpLess)
308+
}
303309

304310
case ">":
305311
c.compile(node.Left)
306312
c.compile(node.Right)
307-
c.emit(OpMore)
308313

309-
case ">=":
314+
if l == r && l == reflect.Int {
315+
c.emit(OpMoreInt)
316+
} else {
317+
c.emit(OpMore)
318+
}
319+
320+
case "<=":
310321
c.compile(node.Left)
311322
c.compile(node.Right)
312-
c.emit(OpMoreOrEqual)
313323

314-
case "<=":
324+
if l == r && l == reflect.Int {
325+
c.emit(OpLessOrEqualInt)
326+
} else {
327+
c.emit(OpLessOrEqual)
328+
}
329+
330+
case ">=":
315331
c.compile(node.Left)
316332
c.compile(node.Right)
317-
c.emit(OpLessOrEqual)
333+
334+
if l == r && l == reflect.Int {
335+
c.emit(OpMoreOrEqualInt)
336+
} else {
337+
c.emit(OpMoreOrEqual)
338+
}
318339

319340
case "+":
320341
c.compile(node.Left)

vm/bytecodes.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,21 @@ const (
1212
OpNegate
1313
OpNot
1414
OpEqual
15+
OpEqualInt
1516
OpEqualString
1617
OpJump
1718
OpJumpIfTrue
1819
OpJumpIfFalse
1920
OpJumpBackward
2021
OpIn
2122
OpLess
23+
OpLessInt
2224
OpMore
25+
OpMoreInt
2326
OpLessOrEqual
27+
OpLessOrEqualInt
2428
OpMoreOrEqual
29+
OpMoreOrEqualInt
2530
OpAdd
2631
OpSubtract
2732
OpMultiply

vm/program.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ func (program *Program) Disassemble() string {
9292
case OpEqual:
9393
code("OpEqual")
9494

95+
case OpEqualInt:
96+
code("OpEqualInt")
97+
9598
case OpEqualString:
9699
code("OpEqualString")
97100

@@ -113,15 +116,27 @@ func (program *Program) Disassemble() string {
113116
case OpLess:
114117
code("OpLess")
115118

119+
case OpLessInt:
120+
code("OpLessInt")
121+
116122
case OpMore:
117123
code("OpMore")
118124

125+
case OpMoreInt:
126+
code("OpMoreInt")
127+
119128
case OpLessOrEqual:
120129
code("OpLessOrEqual")
121130

131+
case OpLessOrEqualInt:
132+
code("OpLessOrEqualInt")
133+
122134
case OpMoreOrEqual:
123135
code("OpMoreOrEqual")
124136

137+
case OpMoreOrEqualInt:
138+
code("OpMoreOrEqualInt")
139+
125140
case OpAdd:
126141
code("OpAdd")
127142

vm/runtime.go

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -177,40 +177,6 @@ func negate(i interface{}) interface{} {
177177
}
178178
}
179179

180-
func inc(i interface{}) interface{} {
181-
switch v := i.(type) {
182-
case float32:
183-
return v + 1
184-
case float64:
185-
return v + 1
186-
187-
case int:
188-
return v + 1
189-
case int8:
190-
return v + 1
191-
case int16:
192-
return v + 1
193-
case int32:
194-
return v + 1
195-
case int64:
196-
return v + 1
197-
198-
case uint:
199-
return v + 1
200-
case uint8:
201-
return v + 1
202-
case uint16:
203-
return v + 1
204-
case uint32:
205-
return v + 1
206-
case uint64:
207-
return v + 1
208-
209-
default:
210-
panic(fmt.Sprintf("invalid operation: %T + 1", v))
211-
}
212-
}
213-
214180
func exponent(a, b interface{}) float64 {
215181
return math.Pow(toFloat64(a), toFloat64(b))
216182
}

vm/vm.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ func (vm *VM) Run() interface{} {
112112
a := vm.pop()
113113
vm.push(equal(a, b))
114114

115+
case OpEqualInt:
116+
b := vm.pop()
117+
a := vm.pop()
118+
vm.push(a.(int) == b.(int))
119+
115120
case OpEqualString:
116121
b := vm.pop()
117122
a := vm.pop()
@@ -147,21 +152,41 @@ func (vm *VM) Run() interface{} {
147152
a := vm.pop()
148153
vm.push(less(a, b))
149154

155+
case OpLessInt:
156+
b := vm.pop()
157+
a := vm.pop()
158+
vm.push(a.(int) < b.(int))
159+
150160
case OpMore:
151161
b := vm.pop()
152162
a := vm.pop()
153163
vm.push(more(a, b))
154164

165+
case OpMoreInt:
166+
b := vm.pop()
167+
a := vm.pop()
168+
vm.push(a.(int) > b.(int))
169+
155170
case OpLessOrEqual:
156171
b := vm.pop()
157172
a := vm.pop()
158173
vm.push(lessOrEqual(a, b))
159174

175+
case OpLessOrEqualInt:
176+
b := vm.pop()
177+
a := vm.pop()
178+
vm.push(a.(int) <= b.(int))
179+
160180
case OpMoreOrEqual:
161181
b := vm.pop()
162182
a := vm.pop()
163183
vm.push(moreOrEqual(a, b))
164184

185+
case OpMoreOrEqualInt:
186+
b := vm.pop()
187+
a := vm.pop()
188+
vm.push(a.(int) >= b.(int))
189+
165190
case OpAdd:
166191
b := vm.pop()
167192
a := vm.pop()

0 commit comments

Comments
 (0)