interp: fix array size assignment type inference
This commit is contained in:
committed by
Traefiker Bot
parent
bb2921b42f
commit
47923866ff
12
_test/a33.go
Normal file
12
_test/a33.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := [...]int{1, 2, 3}
|
||||
b := a
|
||||
fmt.Println(b)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [1 2 3]
|
||||
12
_test/a34.go
Normal file
12
_test/a34.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := [...]int{1, 2, 3}
|
||||
var b [3]int = a
|
||||
fmt.Println(b)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [1 2 3]
|
||||
13
_test/a35.go
Normal file
13
_test/a35.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := [...]int{1, 2, 3}
|
||||
b := a
|
||||
b[0] = -1
|
||||
fmt.Println(a)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [1 2 3]
|
||||
13
_test/a36.go
Normal file
13
_test/a36.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := [...]int{1, 2, 3}
|
||||
var b [3]int = a
|
||||
b[0] = -1
|
||||
fmt.Println(a)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [1 2 3]
|
||||
11
_test/a37.go
Normal file
11
_test/a37.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]
|
||||
11
_test/a38.go
Normal file
11
_test/a38.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := [...]byte{}
|
||||
fmt.Printf("%T\n", a)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [0]uint8
|
||||
12
_test/a39.go
Normal file
12
_test/a39.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := [...]byte{}
|
||||
b := a
|
||||
fmt.Printf("%T %T\n", a, b)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [0]uint8 [0]uint8
|
||||
@@ -395,11 +395,11 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
dest.typ = src.typ
|
||||
}
|
||||
if dest.typ.sizedef {
|
||||
dest.typ.size = compositeArrayLen(src)
|
||||
dest.typ.size = arrayTypeLen(src)
|
||||
dest.typ.rtype = nil
|
||||
}
|
||||
if sc.global {
|
||||
// Do not overload existings symbols (defined in GTA) in global scope
|
||||
// Do not overload existing symbols (defined in GTA) in global scope
|
||||
sym, _, _ = sc.lookup(dest.ident)
|
||||
} else {
|
||||
sym = &symbol{index: sc.add(dest.typ), kind: varSym, typ: dest.typ}
|
||||
@@ -1739,13 +1739,20 @@ func compositeGenerator(n *node) (gen bltnGenerator) {
|
||||
return
|
||||
}
|
||||
|
||||
// compositeArrayLen return the litteral array length, computed from definition
|
||||
func compositeArrayLen(n *node) int {
|
||||
// arrayTypeLen returns the node's array length. If the expression is an
|
||||
// array variable it is determined from the value's type, otherwise it is
|
||||
// computed from the source definition.
|
||||
func arrayTypeLen(n *node) int {
|
||||
if n.typ != nil && n.typ.sizedef {
|
||||
return n.typ.size
|
||||
}
|
||||
max := -1
|
||||
for i, c := range n.child[1:] {
|
||||
r := i
|
||||
if c.kind == keyValueExpr {
|
||||
r = int(c.child[0].rval.Int())
|
||||
if v := c.child[0].rval; v.IsValid() {
|
||||
r = int(c.child[0].rval.Int())
|
||||
}
|
||||
}
|
||||
if r > max {
|
||||
max = r
|
||||
|
||||
@@ -1351,7 +1351,7 @@ func arrayLit(n *node) {
|
||||
}
|
||||
|
||||
var a reflect.Value
|
||||
if n.typ.size > 0 {
|
||||
if n.typ.sizedef {
|
||||
a, _ = n.typ.zero()
|
||||
} else {
|
||||
a = reflect.MakeSlice(n.typ.TypeOf(), max, max)
|
||||
|
||||
@@ -123,10 +123,11 @@ type itype struct {
|
||||
|
||||
// nodeType returns a type definition for the corresponding AST subtree
|
||||
func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
|
||||
var err cfgError
|
||||
|
||||
if n.typ != nil && !n.typ.incomplete {
|
||||
return n.typ, err
|
||||
if n.kind == sliceExpr {
|
||||
n.typ.sizedef = false
|
||||
}
|
||||
return n.typ, nil
|
||||
}
|
||||
|
||||
var t = &itype{node: n, scope: sc}
|
||||
@@ -141,6 +142,7 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
|
||||
}
|
||||
}
|
||||
|
||||
var err cfgError
|
||||
switch n.kind {
|
||||
case addressExpr, starExpr:
|
||||
t.cat = ptrT
|
||||
@@ -158,7 +160,7 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
|
||||
t.size = int(n.child[0].rval.Int())
|
||||
case n.child[0].kind == ellipsisExpr:
|
||||
// [...]T expression
|
||||
t.sizedef = true
|
||||
t.size = arrayTypeLen(n.anc)
|
||||
default:
|
||||
if sym, _, ok := sc.lookup(n.child[0].ident); ok {
|
||||
// Resolve symbol to get size value
|
||||
@@ -182,6 +184,7 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
|
||||
if t.val, err = nodeType(interp, sc, n.child[1]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.sizedef = true
|
||||
t.incomplete = t.incomplete || t.val.incomplete
|
||||
} else {
|
||||
if t.val, err = nodeType(interp, sc, n.child[0]); err != nil {
|
||||
@@ -803,7 +806,7 @@ func (t *itype) refType(defined map[string]bool) reflect.Type {
|
||||
case aliasT:
|
||||
t.rtype = t.val.refType(defined)
|
||||
case arrayT, variadicT:
|
||||
if t.size > 0 {
|
||||
if t.sizedef {
|
||||
t.rtype = reflect.ArrayOf(t.size, t.val.refType(defined))
|
||||
} else {
|
||||
t.rtype = reflect.SliceOf(t.val.refType(defined))
|
||||
@@ -866,7 +869,7 @@ func (t *itype) frameType() (r reflect.Type) {
|
||||
case aliasT:
|
||||
r = t.val.frameType()
|
||||
case arrayT, variadicT:
|
||||
if t.size > 0 {
|
||||
if t.sizedef {
|
||||
r = reflect.ArrayOf(t.size, t.val.frameType())
|
||||
} else {
|
||||
r = reflect.SliceOf(t.val.frameType())
|
||||
|
||||
Reference in New Issue
Block a user