fix: correct array length computed from litteral array (#242)
This commit is contained in:
committed by
Ludovic Fernandez
parent
3528b4539d
commit
7d5ed8a713
11
_test/a27.go
Normal file
11
_test/a27.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := [...]string{"hello", "world"}
|
||||
fmt.Printf("%v %T\n", a, a)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [hello world] [2]string
|
||||
11
_test/a28.go
Normal file
11
_test/a28.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
a := [...]string{9: "hello"}
|
||||
fmt.Printf("%v %T\n", a, a)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [ hello] [10]string
|
||||
21
_test/a29.go
Normal file
21
_test/a29.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
const (
|
||||
zero = iota
|
||||
one
|
||||
two
|
||||
)
|
||||
|
||||
func main() {
|
||||
a := [...]string{
|
||||
zero: "zero",
|
||||
one: "one",
|
||||
two: "two",
|
||||
}
|
||||
fmt.Printf("%v %T\n", a, a)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// [zero one two] [3]string
|
||||
@@ -353,6 +353,10 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
} else {
|
||||
dest.typ = src.typ
|
||||
}
|
||||
if dest.typ.sizedef {
|
||||
dest.typ.size = compositeArrayLen(src)
|
||||
dest.typ.rtype = nil
|
||||
}
|
||||
if sc.global {
|
||||
// Do not overload existings symbols (defined in GTA) in global scope
|
||||
sym, _, _ = sc.lookup(dest.ident)
|
||||
@@ -363,9 +367,7 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
dest.val = src.val
|
||||
dest.recv = src.recv
|
||||
dest.findex = sym.index
|
||||
if src.kind == basicLit {
|
||||
sym.rval = src.rval
|
||||
}
|
||||
sym.rval = src.rval
|
||||
} else {
|
||||
sym, level, _ = sc.lookup(dest.ident)
|
||||
}
|
||||
@@ -394,8 +396,7 @@ func (interp *Interpreter) cfg(root *node) ([]*node, error) {
|
||||
}
|
||||
}
|
||||
n.findex = dest.findex
|
||||
n.val = dest.val
|
||||
n.rval = dest.rval
|
||||
|
||||
// Propagate type
|
||||
// TODO: Check that existing destination type matches source type
|
||||
switch {
|
||||
@@ -1664,3 +1665,18 @@ func compositeGenerator(n *node) (gen bltnGenerator) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// compositeArrayLen return the litteral array length, computed from definition
|
||||
func compositeArrayLen(n *node) int {
|
||||
max := -1
|
||||
for i, c := range n.child[1:] {
|
||||
r := i
|
||||
if c.kind == keyValueExpr {
|
||||
r = int(c.child[0].rval.Int())
|
||||
}
|
||||
if r > max {
|
||||
max = r
|
||||
}
|
||||
}
|
||||
return max + 1
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ func (interp *Interpreter) gta(root *node, rpath string) error {
|
||||
}
|
||||
sc.sym[dest.ident] = &symbol{kind: varSym, global: true, index: index, typ: typ, rval: val}
|
||||
if n.anc.kind == constDecl {
|
||||
sc.sym[dest.ident].kind = constSym
|
||||
iotaValue++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ type itype struct {
|
||||
variadic bool // true if type is variadic
|
||||
incomplete bool // true if type must be parsed again (out of order declarations)
|
||||
untyped bool // true for a literal value (string or number)
|
||||
sizedef bool // true if array size is computed from type definition
|
||||
node *node // root AST node of type definition
|
||||
scope *scope // type declaration scope (in case of re-parse incomplete type)
|
||||
}
|
||||
@@ -140,9 +141,14 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
|
||||
case arrayType:
|
||||
t.cat = arrayT
|
||||
if len(n.child) > 1 {
|
||||
if n.child[0].rval.IsValid() {
|
||||
switch {
|
||||
case n.child[0].rval.IsValid():
|
||||
// constant size
|
||||
t.size = int(n.child[0].rval.Int())
|
||||
} else {
|
||||
case n.child[0].kind == ellipsisExpr:
|
||||
// [...]T expression
|
||||
t.sizedef = true
|
||||
default:
|
||||
if sym, _, ok := sc.lookup(n.child[0].ident); ok {
|
||||
// Resolve symbol to get size value
|
||||
if sym.typ != nil && sym.typ.cat == intT {
|
||||
@@ -672,7 +678,10 @@ func (t *itype) TypeOf() reflect.Type {
|
||||
}
|
||||
|
||||
if t.incomplete {
|
||||
t, _ = t.finalize()
|
||||
var err error
|
||||
if t, err = t.finalize(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
switch t.cat {
|
||||
|
||||
Reference in New Issue
Block a user