fix: support array operations on array pointers
This commit is contained in:
committed by
Traefiker Bot
parent
e03016b6d7
commit
ec1ee5f5b6
14
_test/copy1.go
Normal file
14
_test/copy1.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := []int{10, 20, 30}
|
||||
b := &[4]int{}
|
||||
c := b[:]
|
||||
copy(c, a)
|
||||
fmt.Println(c)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [10 20 30 0]
|
||||
13
_test/ptr_array0.go
Normal file
13
_test/ptr_array0.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
type T [2]int
|
||||
|
||||
func F0(t *T) int { return t[0] }
|
||||
|
||||
func main() {
|
||||
t := &T{1, 2}
|
||||
println(F0(t))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
19
_test/ptr_array1.go
Normal file
19
_test/ptr_array1.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
type T [3]int
|
||||
|
||||
func F0(t *T) {
|
||||
for i, v := range t {
|
||||
println(i, v)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
t := &T{1, 2, 3}
|
||||
F0(t)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 0 1
|
||||
// 1 2
|
||||
// 2 3
|
||||
16
_test/ptr_array2.go
Normal file
16
_test/ptr_array2.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type T [2]int
|
||||
|
||||
func F1(t *T) { t[0] = 1 }
|
||||
|
||||
func main() {
|
||||
t := &T{}
|
||||
F1(t)
|
||||
fmt.Println(t)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// &[1 0]
|
||||
11
_test/ptr_array3.go
Normal file
11
_test/ptr_array3.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := &[...]int{1, 2, 3}
|
||||
fmt.Println(a[:])
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [1 2 3]
|
||||
@@ -86,6 +86,14 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
n.anc.gen = rangeMap
|
||||
ktyp = o.typ.key
|
||||
vtyp = o.typ.val
|
||||
case ptrT:
|
||||
ktyp = sc.getType("int")
|
||||
vtyp = o.typ.val
|
||||
if vtyp.cat == valueT {
|
||||
vtyp = &itype{cat: valueT, rtype: vtyp.rtype.Elem()}
|
||||
} else {
|
||||
vtyp = vtyp.val
|
||||
}
|
||||
case stringT:
|
||||
ktyp = sc.getType("int")
|
||||
vtyp = sc.getType("byte")
|
||||
@@ -569,20 +577,34 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
wireChild(n)
|
||||
t := n.child[0].typ
|
||||
switch t.cat {
|
||||
case valueT:
|
||||
n.typ = &itype{cat: valueT, rtype: t.rtype.Elem()}
|
||||
case ptrT:
|
||||
n.typ = t.val
|
||||
if t.val.cat == valueT {
|
||||
n.typ = &itype{cat: valueT, rtype: t.val.rtype.Elem()}
|
||||
} else {
|
||||
n.typ = t.val.val
|
||||
}
|
||||
case stringT:
|
||||
n.typ = sc.getType("byte")
|
||||
case valueT:
|
||||
n.typ = &itype{cat: valueT, rtype: t.rtype.Elem()}
|
||||
default:
|
||||
n.typ = t.val
|
||||
}
|
||||
n.findex = sc.add(n.typ)
|
||||
n.recv = &receiver{node: n}
|
||||
switch k := t.TypeOf().Kind(); k {
|
||||
typ := t.TypeOf()
|
||||
switch k := typ.Kind(); k {
|
||||
case reflect.Map:
|
||||
n.gen = getIndexMap
|
||||
case reflect.Array, reflect.Slice, reflect.String:
|
||||
n.gen = getIndexArray
|
||||
case reflect.Ptr:
|
||||
if typ2 := typ.Elem(); typ2.Kind() == reflect.Array {
|
||||
n.gen = getIndexArray
|
||||
} else {
|
||||
err = n.cfgErrorf("type %v does not support indexing", typ)
|
||||
}
|
||||
default:
|
||||
err = n.cfgErrorf("type is not an array, slice, string or map: %v", t.id())
|
||||
}
|
||||
@@ -1253,7 +1275,11 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
|
||||
case sliceExpr:
|
||||
wireChild(n)
|
||||
if ctyp := n.child[0].typ; ctyp.size != 0 {
|
||||
ctyp := n.child[0].typ
|
||||
if ctyp.cat == ptrT {
|
||||
ctyp = ctyp.val
|
||||
}
|
||||
if ctyp.size != 0 {
|
||||
// Create a slice type from an array type
|
||||
n.typ = &itype{}
|
||||
*n.typ = *ctyp
|
||||
|
||||
@@ -887,7 +887,7 @@ func getIndexBinPtrMethod(n *node) {
|
||||
// getIndexArray returns array value from index
|
||||
func getIndexArray(n *node) {
|
||||
tnext := getExec(n.tnext)
|
||||
value0 := genValue(n.child[0]) // array
|
||||
value0 := genValueArray(n.child[0]) // array
|
||||
|
||||
if n.child[1].rval.IsValid() { // constant array index
|
||||
ai := int(vInt(n.child[1].rval))
|
||||
@@ -1505,8 +1505,8 @@ func _range(n *node) {
|
||||
tnext := getExec(n.tnext)
|
||||
|
||||
if len(n.child) == 4 {
|
||||
index1 := n.child[1].findex // array value location in frame
|
||||
value := genValue(n.child[2]) // array
|
||||
index1 := n.child[1].findex // array value location in frame
|
||||
value := genValueArray(n.child[2]) // array
|
||||
n.exec = func(f *frame) bltn {
|
||||
a := value(f)
|
||||
v0 := f.data[index0]
|
||||
@@ -1519,7 +1519,7 @@ func _range(n *node) {
|
||||
return tnext
|
||||
}
|
||||
} else {
|
||||
value := genValue(n.child[1]) // array
|
||||
value := genValueArray(n.child[1]) // array
|
||||
n.exec = func(f *frame) bltn {
|
||||
a := value(f)
|
||||
v0 := f.data[index0]
|
||||
@@ -1780,7 +1780,7 @@ func _cap(n *node) {
|
||||
|
||||
func _copy(n *node) {
|
||||
dest := genValue(n)
|
||||
value0 := genValue(n.child[1])
|
||||
value0 := genValueArray(n.child[1])
|
||||
value1 := genValue(n.child[2])
|
||||
next := getExec(n.tnext)
|
||||
|
||||
@@ -2109,8 +2109,8 @@ func _select(n *node) {
|
||||
func slice(n *node) {
|
||||
i := n.findex
|
||||
next := getExec(n.tnext)
|
||||
value0 := genValue(n.child[0]) // array
|
||||
value1 := genValue(n.child[1]) // low (if 2 or 3 args) or high (if 1 arg)
|
||||
value0 := genValueArray(n.child[0]) // array
|
||||
value1 := genValue(n.child[1]) // low (if 2 or 3 args) or high (if 1 arg)
|
||||
|
||||
switch len(n.child) {
|
||||
case 2:
|
||||
@@ -2143,7 +2143,7 @@ func slice(n *node) {
|
||||
func slice0(n *node) {
|
||||
i := n.findex
|
||||
next := getExec(n.tnext)
|
||||
value0 := genValue(n.child[0])
|
||||
value0 := genValueArray(n.child[0])
|
||||
|
||||
switch len(n.child) {
|
||||
case 1:
|
||||
|
||||
@@ -107,6 +107,17 @@ func genValue(n *node) func(*frame) reflect.Value {
|
||||
}
|
||||
}
|
||||
|
||||
func genValueArray(n *node) func(*frame) reflect.Value {
|
||||
value := genValue(n)
|
||||
// dereference array pointer, to support array operations on array pointer
|
||||
if n.typ.TypeOf().Kind() == reflect.Ptr {
|
||||
return func(f *frame) reflect.Value {
|
||||
return value(f).Elem()
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func genValueInterfacePtr(n *node) func(*frame) reflect.Value {
|
||||
value := genValue(n)
|
||||
it := reflect.TypeOf((*interface{})(nil)).Elem()
|
||||
|
||||
Reference in New Issue
Block a user