interp: fix map range handling
This commit is contained in:
committed by
Traefiker Bot
parent
47923866ff
commit
4bf4aeecbb
@@ -19,7 +19,6 @@ cache:
|
|||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
include:
|
include:
|
||||||
- go: 1.11.x
|
|
||||||
- go: 1.12.x
|
- go: 1.12.x
|
||||||
- go: 1.13.x
|
- go: 1.13.x
|
||||||
env: STABLE=true
|
env: STABLE=true
|
||||||
|
|||||||
14
_test/range3.go
Normal file
14
_test/range3.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
m := map[int]bool{1: true, 3: true, 5: true}
|
||||||
|
for k := range m {
|
||||||
|
m[k*2] = true
|
||||||
|
}
|
||||||
|
fmt.Println("ok")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// ok
|
||||||
15
_test/range4.go
Normal file
15
_test/range4.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
m := map[int]bool{1: true, 3: true, 5: true}
|
||||||
|
for _, v := range m {
|
||||||
|
fmt.Println(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
15
_test/range5.go
Normal file
15
_test/range5.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
m := map[int]bool{1: true, 3: true, 5: true}
|
||||||
|
var n int
|
||||||
|
for range m {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
fmt.Println(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 3
|
||||||
18
_test/range6.go
Normal file
18
_test/range6.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
m := map[float64]bool{math.NaN(): true, math.NaN(): true, math.NaN(): true}
|
||||||
|
for _, v := range m {
|
||||||
|
fmt.Println(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// true
|
||||||
|
// true
|
||||||
@@ -87,6 +87,8 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
|||||||
}
|
}
|
||||||
case mapT:
|
case mapT:
|
||||||
n.anc.gen = rangeMap
|
n.anc.gen = rangeMap
|
||||||
|
ityp := &itype{cat: valueT, rtype: reflect.TypeOf((*reflect.MapIter)(nil))}
|
||||||
|
sc.add(ityp)
|
||||||
ktyp = o.typ.key
|
ktyp = o.typ.key
|
||||||
vtyp = o.typ.val
|
vtyp = o.typ.val
|
||||||
case ptrT:
|
case ptrT:
|
||||||
|
|||||||
@@ -1601,31 +1601,40 @@ func rangeChan(n *node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func rangeMap(n *node) {
|
func rangeMap(n *node) {
|
||||||
index0 := n.child[0].findex // array index location in frame
|
index0 := n.child[0].findex // map index location in frame
|
||||||
index1 := n.child[1].findex // array value location in frame
|
index2 := index0 - 1 // iterator for range, always just behind index0
|
||||||
value := genValue(n.child[2]) // array
|
|
||||||
fnext := getExec(n.fnext)
|
fnext := getExec(n.fnext)
|
||||||
tnext := getExec(n.tnext)
|
tnext := getExec(n.tnext)
|
||||||
// TODO: move i and keys to frame
|
|
||||||
var i int
|
|
||||||
var keys []reflect.Value
|
|
||||||
|
|
||||||
n.exec = func(f *frame) bltn {
|
var value func(*frame) reflect.Value
|
||||||
a := value(f)
|
if len(n.child) == 4 {
|
||||||
i++
|
index1 := n.child[1].findex // map value location in frame
|
||||||
if i >= a.Len() {
|
value = genValue(n.child[2]) // map
|
||||||
return fnext
|
n.exec = func(f *frame) bltn {
|
||||||
|
iter := f.data[index2].Interface().(*reflect.MapIter)
|
||||||
|
if !iter.Next() {
|
||||||
|
return fnext
|
||||||
|
}
|
||||||
|
f.data[index0].Set(iter.Key())
|
||||||
|
f.data[index1].Set(iter.Value())
|
||||||
|
return tnext
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = genValue(n.child[1]) // map
|
||||||
|
n.exec = func(f *frame) bltn {
|
||||||
|
iter := f.data[index2].Interface().(*reflect.MapIter)
|
||||||
|
if !iter.Next() {
|
||||||
|
return fnext
|
||||||
|
}
|
||||||
|
f.data[index0].Set(iter.Key())
|
||||||
|
return tnext
|
||||||
}
|
}
|
||||||
f.data[index0].Set(keys[i])
|
|
||||||
f.data[index1].Set(a.MapIndex(keys[i]))
|
|
||||||
return tnext
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init sequence
|
// Init sequence
|
||||||
next := n.exec
|
next := n.exec
|
||||||
n.child[0].exec = func(f *frame) bltn {
|
n.child[0].exec = func(f *frame) bltn {
|
||||||
keys = value(f).MapKeys()
|
f.data[index2].Set(reflect.ValueOf(value(f).MapRange()))
|
||||||
i = -1
|
|
||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user