fix: compute numeral constant on typed objects

This commit is contained in:
Marc Vertes
2020-05-19 14:38:03 +02:00
committed by GitHub
parent bb1be9e6e1
commit 6f4643ff19
4 changed files with 210 additions and 3 deletions

View File

@@ -39,7 +39,7 @@ install:
- go mod download
before_script:
- rm -f interp/op.go interp/interp_test.go
- rm -f interp/op.go
- make generate
- git update-index -q --refresh
- CHANGED=$(git diff-index --name-only HEAD --)

17
_test/const12.go Normal file
View File

@@ -0,0 +1,17 @@
package main
type Kind int
const (
None Kind = 0
Left Kind = 1 << iota
Right
Both Kind = Left | Right
)
func main() {
println(None, Left, Right, Both)
}
// Output:
// 0 2 4 6

View File

@@ -1867,7 +1867,7 @@ func (n *node) isInteger() bool {
if isInt(n.typ.TypeOf()) {
return true
}
if n.typ.untyped && n.rval.IsValid() {
if n.rval.IsValid() {
t := n.rval.Type()
if isInt(t) {
return true
@@ -1890,7 +1890,7 @@ func (n *node) isNatural() bool {
if isUint(n.typ.TypeOf()) {
return true
}
if n.typ.untyped && n.rval.IsValid() {
if n.rval.IsValid() {
t := n.rval.Type()
if isUint(t) {
return true

190
interp/interp_test.go Normal file
View File

@@ -0,0 +1,190 @@
package interp
import (
"log"
"reflect"
"testing"
)
func init() { log.SetFlags(log.Lshortfile) }
func TestIsNatural(t *testing.T) {
tests := []struct {
desc string
n *node
expected bool
}{
{
desc: "positive uint var",
n: &node{
typ: &itype{
rtype: func() reflect.Type {
var x uint = 3
return reflect.TypeOf(x)
}(),
},
rval: func() reflect.Value {
var x uint = 3
return reflect.ValueOf(x)
}(),
},
expected: true,
},
{
desc: "positive untyped var",
n: &node{
typ: &itype{
rtype: func() reflect.Type {
var x = 3
return reflect.TypeOf(x)
}(),
},
rval: func() reflect.Value {
var x = 3
return reflect.ValueOf(x)
}(),
},
expected: true,
},
{
desc: "positive int var",
n: &node{
typ: &itype{
rtype: func() reflect.Type {
var x int = 3
return reflect.TypeOf(x)
}(),
},
rval: func() reflect.Value {
var x int = 3
return reflect.ValueOf(x)
}(),
},
expected: true,
},
{
desc: "positive float var, null decimal",
n: &node{
typ: &itype{
rtype: func() reflect.Type {
var x float64 = 3.0
return reflect.TypeOf(x)
}(),
},
rval: func() reflect.Value {
var x float64 = 3.0
return reflect.ValueOf(x)
}(),
},
expected: true,
},
{
desc: "positive float var, with decimal",
n: &node{
typ: &itype{
rtype: func() reflect.Type {
var x float64 = 3.14
return reflect.TypeOf(x)
}(),
},
rval: func() reflect.Value {
var x float64 = 3.14
return reflect.ValueOf(x)
}(),
},
expected: false,
},
{
desc: "negative int var",
n: &node{
typ: &itype{
rtype: func() reflect.Type {
var x int = -3
return reflect.TypeOf(x)
}(),
},
rval: func() reflect.Value {
var x int = -3
return reflect.ValueOf(x)
}(),
},
expected: false,
},
{
desc: "positive typed const",
n: &node{
typ: &itype{
rtype: func() reflect.Type {
const a uint = 3
return reflect.TypeOf(a)
}(),
},
rval: func() reflect.Value {
const a uint = 3
return reflect.ValueOf(a)
}(),
},
expected: true,
},
{
desc: "positive untyped const",
n: &node{
typ: &itype{
rtype: func() reflect.Type {
const a = 3
return reflect.TypeOf(a)
}(),
},
rval: func() reflect.Value {
const a = 3
return reflect.ValueOf(a)
}(),
},
expected: true,
},
{
desc: "positive untyped const (iota)",
n: &node{
typ: &itype{
rtype: func() reflect.Type {
const (
zero = iota
a
)
return reflect.TypeOf(a)
}(),
},
rval: func() reflect.Value {
const (
zero = iota
a
)
return reflect.ValueOf(a)
}(),
},
expected: true,
},
{
desc: "negative const",
n: &node{
typ: &itype{
rtype: func() reflect.Type {
const a = -3
return reflect.TypeOf(a)
}(),
},
rval: func() reflect.Value {
const a = -3
return reflect.ValueOf(a)
}(),
},
expected: false,
},
}
for _, test := range tests {
got := test.n.isNatural()
if test.expected != got {
t.Fatalf("%s: got %v, wanted %v", test.desc, got, test.expected)
}
}
}