Skip to content

Commit 6107925

Browse files
committed
More strict in operator
1 parent 40d583c commit 6107925

File tree

4 files changed

+55
-41
lines changed

4 files changed

+55
-41
lines changed

checker/checker.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ func (v *visitor) BinaryNode(node *ast.BinaryNode) reflect.Type {
169169
return boolType
170170
}
171171
if isArray(r) || isMap(r) {
172+
if isNumber(l) && isCertain(node.Left) && !isCertain(node.Right) {
173+
setUncertainType(node.Right, dereference(l))
174+
}
172175
return boolType
173176
}
174177

compiler/compiler.go

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,16 @@ func (c *compiler) emit(op byte, b ...byte) int {
6868
}
6969

7070
func (c *compiler) makeConstant(i interface{}) []byte {
71-
if p, ok := c.index[i]; ok {
72-
return encode(p)
71+
hashable := true
72+
switch reflect.TypeOf(i).Kind() {
73+
case reflect.Slice:
74+
hashable = false
75+
}
76+
77+
if hashable {
78+
if p, ok := c.index[i]; ok {
79+
return encode(p)
80+
}
7381
}
7482

7583
c.constants = append(c.constants, i)
@@ -78,7 +86,9 @@ func (c *compiler) makeConstant(i interface{}) []byte {
7886
}
7987

8088
p := uint16(len(c.constants) - 1)
81-
c.index[i] = p
89+
if hashable {
90+
c.index[i] = p
91+
}
8292
return encode(p)
8393
}
8494

@@ -352,6 +362,40 @@ func (c *compiler) BinaryNode(node *ast.BinaryNode) {
352362
c.emit(OpContains)
353363

354364
case "..":
365+
min, ok1 := node.Left.(*ast.IntegerNode)
366+
max, ok2 := node.Right.(*ast.IntegerNode)
367+
if ok1 && ok2 {
368+
// Create range on compile time to avoid unnecessary work at runtime.
369+
size := max.Value - min.Value + 1
370+
rng := make([]interface{}, size)
371+
for i := range rng {
372+
switch node.Left.GetType().Kind() {
373+
case reflect.Int:
374+
rng[i] = int(min.Value + i)
375+
case reflect.Int8:
376+
rng[i] = int8(min.Value + i)
377+
case reflect.Int16:
378+
rng[i] = int16(min.Value + i)
379+
case reflect.Int32:
380+
rng[i] = int32(min.Value + i)
381+
case reflect.Int64:
382+
rng[i] = int64(min.Value + i)
383+
384+
case reflect.Uint:
385+
rng[i] = uint(min.Value + i)
386+
case reflect.Uint8:
387+
rng[i] = uint8(min.Value + i)
388+
case reflect.Uint16:
389+
rng[i] = uint16(min.Value + i)
390+
case reflect.Uint32:
391+
rng[i] = uint32(min.Value + i)
392+
case reflect.Uint64:
393+
rng[i] = uint64(min.Value + i)
394+
}
395+
}
396+
c.emit(OpConst, c.makeConstant(rng)...)
397+
return
398+
}
355399
c.compile(node.Left)
356400
c.compile(node.Right)
357401
c.emit(OpRange)

vm/runtime.go

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func in(needle interface{}, array interface{}) bool {
9191
for i := 0; i < v.Len(); i++ {
9292
value := v.Index(i)
9393
if value.IsValid() && value.CanInterface() {
94-
if equalTypeIndependent(value.Interface(), needle) {
94+
if equal(value.Interface(), needle) {
9595
return true
9696
}
9797
}
@@ -212,43 +212,6 @@ func equal(a, b interface{}) bool {
212212
}
213213
}
214214

215-
func equalTypeIndependent(a, b interface{}) bool {
216-
switch x := a.(type) {
217-
case float32:
218-
return x == float32(toFloat64(b))
219-
case float64:
220-
return x == float64(toFloat64(b))
221-
222-
case int:
223-
return x == int(toFloat64(b))
224-
case int8:
225-
return x == int8(toFloat64(b))
226-
case int16:
227-
return x == int16(toFloat64(b))
228-
case int32:
229-
return x == int32(toFloat64(b))
230-
case int64:
231-
return x == int64(toFloat64(b))
232-
233-
case uint:
234-
return x == uint(toFloat64(b))
235-
case uint8:
236-
return x == uint8(toFloat64(b))
237-
case uint16:
238-
return x == uint16(toFloat64(b))
239-
case uint32:
240-
return x == uint32(toFloat64(b))
241-
case uint64:
242-
return x == uint64(toFloat64(b))
243-
244-
case string:
245-
return x == b.(string)
246-
247-
default:
248-
return reflect.DeepEqual(a, b)
249-
}
250-
}
251-
252215
func less(a, b interface{}) interface{} {
253216
switch x := a.(type) {
254217
case float32:

vm/vm_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ func TestRun(t *testing.T) {
188188
`1 in [1, 2, 3] && "foo" in {foo: 0, bar: 1} && "Price" in Ticket`,
189189
true,
190190
},
191+
{
192+
`1.5 in [1] && 1 in [1.5]`,
193+
false,
194+
},
191195
{
192196
`(true ? 0+1 : 2+3) + (false ? -1 : -2)`,
193197
-1,

0 commit comments

Comments
 (0)