Skip to content

Commit

Permalink
fix: correctly handle constant init for further type declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
mvertes committed Feb 12, 2020
1 parent 0596031 commit 681f2f9
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 25 deletions.
22 changes: 22 additions & 0 deletions _test/const6.go
@@ -0,0 +1,22 @@
package main

const (
maxNonStarters = 30
maxBufferSize = maxNonStarters + 2
)

type reorderBuffer struct {
rune [maxBufferSize]Properties
}

type Properties struct {
pos uint8
size uint8
}

func main() {
println(len(reorderBuffer{}.rune))
}

// Output:
// 32
19 changes: 19 additions & 0 deletions _test/const7.go
@@ -0,0 +1,19 @@
package main

import "fmt"

const (
a = iota
b
c
d
)

type T [c]int

func main() {
fmt.Println(T{})
}

// Output:
// [0 0]
4 changes: 0 additions & 4 deletions interp/ast.go
Expand Up @@ -75,8 +75,6 @@ const (
parenExpr
rangeStmt
returnStmt
rvalueExpr
rtypeExpr
selectStmt
selectorExpr
selectorImport
Expand Down Expand Up @@ -154,8 +152,6 @@ var kinds = [...]string{
parenExpr: "parenExpr",
rangeStmt: "rangeStmt",
returnStmt: "returnStmt",
rvalueExpr: "rvalueExpr",
rtypeExpr: "rtypeExpr",
selectStmt: "selectStmt",
selectorExpr: "selectorExpr",
selectorImport: "selectorImport",
Expand Down
22 changes: 9 additions & 13 deletions interp/cfg.go
Expand Up @@ -429,7 +429,8 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
if sc.global {
// Do not overload existing symbols (defined in GTA) in global scope
sym, _, _ = sc.lookup(dest.ident)
} else {
}
if sym == nil {
sym = &symbol{index: sc.add(dest.typ), kind: varSym, typ: dest.typ}
sc.sym[dest.ident] = sym
}
Expand Down Expand Up @@ -509,9 +510,10 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
if isMapEntry(dest) {
dest.gen = nop // skip getIndexMap
}
}
if n.anc.kind == constDecl {
iotaValue++
if n.anc.kind == constDecl {
sc.sym[dest.ident].kind = constSym
iotaValue++
}
}

case incDecStmt:
Expand Down Expand Up @@ -924,7 +926,8 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
case identExpr:
if isKey(n) || isNewDefine(n, sc) {
break
} else if sym, level, ok := sc.lookup(n.ident); ok {
}
if sym, level, ok := sc.lookup(n.ident); ok {
// Found symbol, populate node info
n.typ, n.findex, n.level = sym.typ, sym.index, level
if n.findex < 0 {
Expand All @@ -941,11 +944,6 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
case n.ident == "nil":
n.kind = basicLit
case sym.kind == binSym:
if sym.rval.IsValid() {
n.kind = rvalueExpr
} else {
n.kind = rtypeExpr
}
n.typ = sym.typ
n.rval = sym.rval
case sym.kind == bltnSym:
Expand Down Expand Up @@ -1161,10 +1159,8 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
pkg := n.child[0].sym.typ.path
if s, ok := interp.binPkg[pkg][name]; ok {
if isBinType(s) {
n.kind = rtypeExpr
n.typ = &itype{cat: valueT, rtype: s.Type().Elem()}
} else {
n.kind = rvalueExpr
n.typ = &itype{cat: valueT, rtype: s.Type(), untyped: isValueUntyped(s)}
n.rval = s
}
Expand Down Expand Up @@ -1587,7 +1583,7 @@ func isBinType(v reflect.Value) bool { return v.IsValid() && v.Kind() == reflect
// isType returns true if node refers to a type definition, false otherwise
func (n *node) isType(sc *scope) bool {
switch n.kind {
case arrayType, chanType, funcType, interfaceType, mapType, structType, rtypeExpr:
case arrayType, chanType, funcType, interfaceType, mapType, structType:
return true
case parenExpr, starExpr:
if len(n.child) == 1 {
Expand Down
7 changes: 6 additions & 1 deletion interp/gta.go
Expand Up @@ -21,6 +21,9 @@ func (interp *Interpreter) gta(root *node, rpath, pkgID string) ([]*node, error)
switch n.kind {
case constDecl:
iotaValue = 0
// Early parse of constDecl subtree, to compute all constant
// values which may be necessary in further declarations.
_, err = interp.cfg(n, pkgID)

case blockStmt:
if n != root {
Expand Down Expand Up @@ -63,7 +66,9 @@ func (interp *Interpreter) gta(root *node, rpath, pkgID string) ([]*node, error)
if typ.isBinMethod {
typ = &itype{cat: valueT, rtype: typ.methodCallType(), isBinMethod: true}
}
sc.sym[dest.ident] = &symbol{kind: varSym, global: true, index: sc.add(typ), typ: typ, rval: val}
if sc.sym[dest.ident] == nil {
sc.sym[dest.ident] = &symbol{kind: varSym, global: true, index: sc.add(typ), typ: typ, rval: val}
}
if n.anc.kind == constDecl {
sc.sym[dest.ident].kind = constSym
iotaValue++
Expand Down
8 changes: 4 additions & 4 deletions interp/interp_eval_test.go
Expand Up @@ -78,11 +78,11 @@ func TestEvalBuiltin(t *testing.T) {
i := interp.New(interp.Options{})
runTests(t, i, []testCase{
{src: `a := []int{}; a = append(a, 1); a`, res: "[1]"},
{src: `a := []int{1}; a = append(a, 2, 3); a`, res: "[1 2 3]"},
{src: `a := []int{1}; b := []int{2, 3}; a = append(a, b...); a`, res: "[1 2 3]"},
{src: `b := []int{1}; b = append(a, 2, 3); b`, res: "[1 2 3]"},
{src: `c := []int{1}; d := []int{2, 3}; c = append(c, d...); c`, res: "[1 2 3]"},
{src: `string(append([]byte("hello "), "world"...))`, res: "hello world"},
{src: `a := "world"; string(append([]byte("hello "), a...))`, res: "hello world"},
{src: `a := []byte("Hello"); copy(a, "world"); string(a)`, res: "world"},
{src: `e := "world"; string(append([]byte("hello "), e...))`, res: "hello world"},
{src: `f := []byte("Hello"); copy(f, "world"); string(f)`, res: "world"},
})
}

Expand Down
3 changes: 0 additions & 3 deletions interp/value.go
Expand Up @@ -90,9 +90,6 @@ func genValue(n *node) func(*frame) reflect.Value {
v = reflect.ValueOf(n.val)
}
return func(f *frame) reflect.Value { return v }
case rvalueExpr:
v := n.rval
return func(f *frame) reflect.Value { return v }
default:
if n.rval.IsValid() {
v := n.rval
Expand Down

0 comments on commit 681f2f9

Please sign in to comment.