interp: fix operators working on integer constants
Always attempt to obtain an integer constant value for operators expecting so. It allows to use '/' in integer constant defintions, instead of default big.Rat. Fixes #1005
This commit is contained in:
15
_test/const22.go
Normal file
15
_test/const22.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
const (
|
||||
numDec uint8 = (1 << iota) / 2
|
||||
numHex
|
||||
numOct
|
||||
numFloat
|
||||
)
|
||||
|
||||
func main() {
|
||||
println(13 & (numHex | numOct))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
@@ -209,7 +209,11 @@ func {{$name}}Const(n *node) {
|
||||
v := constant.BinaryOp(vConstantValue(v0), operator, vConstantValue(v1))
|
||||
n.rval.Set(reflect.ValueOf(v))
|
||||
{{- else}}
|
||||
{{- if $op.Int}}
|
||||
v := constant.BinaryOp(constant.ToInt(vConstantValue(v0)), token.{{tokenFromName $name}}, constant.ToInt(vConstantValue(v1)))
|
||||
{{- else}}
|
||||
v := constant.BinaryOp(vConstantValue(v0), token.{{tokenFromName $name}}, vConstantValue(v1))
|
||||
{{- end}}
|
||||
n.rval.Set(reflect.ValueOf(v))
|
||||
{{- end}}
|
||||
{{- if $op.Str}}
|
||||
@@ -940,6 +944,7 @@ type Op struct {
|
||||
Complex bool // true if operator applies to complex
|
||||
Shift bool // true if operator is a shift operation
|
||||
Bool bool // true if operator applies to bool
|
||||
Int bool // true if operator applies to int only
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -968,17 +973,17 @@ func main() {
|
||||
b := &bytes.Buffer{}
|
||||
data := map[string]interface{}{
|
||||
"Arithmetic": map[string]Op{
|
||||
"add": {"+", true, true, true, false, false},
|
||||
"sub": {"-", false, true, true, false, false},
|
||||
"mul": {"*", false, true, true, false, false},
|
||||
"quo": {"/", false, true, true, false, false},
|
||||
"rem": {"%", false, false, false, false, false},
|
||||
"shl": {"<<", false, false, false, true, false},
|
||||
"shr": {">>", false, false, false, true, false},
|
||||
"and": {"&", false, false, false, false, false},
|
||||
"or": {"|", false, false, false, false, false},
|
||||
"xor": {"^", false, false, false, false, false},
|
||||
"andNot": {"&^", false, false, false, false, false},
|
||||
"add": {"+", true, true, true, false, false, false},
|
||||
"sub": {"-", false, true, true, false, false, false},
|
||||
"mul": {"*", false, true, true, false, false, false},
|
||||
"quo": {"/", false, true, true, false, false, false},
|
||||
"rem": {"%", false, false, false, false, false, true},
|
||||
"shl": {"<<", false, false, false, true, false, true},
|
||||
"shr": {">>", false, false, false, true, false, true},
|
||||
"and": {"&", false, false, false, false, false, true},
|
||||
"or": {"|", false, false, false, false, false, true},
|
||||
"xor": {"^", false, false, false, false, false, true},
|
||||
"andNot": {"&^", false, false, false, false, false, true},
|
||||
},
|
||||
"IncDec": map[string]Op{
|
||||
"inc": {Name: "+"},
|
||||
@@ -996,7 +1001,7 @@ func main() {
|
||||
"not": {Name: "!", Float: false, Bool: true},
|
||||
"neg": {Name: "-", Float: true, Bool: false},
|
||||
"pos": {Name: "+", Float: true, Bool: false},
|
||||
"bitNot": {Name: "^", Float: false, Bool: false},
|
||||
"bitNot": {Name: "^", Float: false, Bool: false, Int: true},
|
||||
},
|
||||
}
|
||||
if err = parse.Execute(b, data); err != nil {
|
||||
|
||||
10
interp/op.go
10
interp/op.go
@@ -253,7 +253,7 @@ func andConst(n *node) {
|
||||
n.rval = reflect.New(t).Elem()
|
||||
switch {
|
||||
case isConst:
|
||||
v := constant.BinaryOp(vConstantValue(v0), token.AND, vConstantValue(v1))
|
||||
v := constant.BinaryOp(constant.ToInt(vConstantValue(v0)), token.AND, constant.ToInt(vConstantValue(v1)))
|
||||
n.rval.Set(reflect.ValueOf(v))
|
||||
case isUint(t):
|
||||
n.rval.SetUint(vUint(v0) & vUint(v1))
|
||||
@@ -338,7 +338,7 @@ func andNotConst(n *node) {
|
||||
n.rval = reflect.New(t).Elem()
|
||||
switch {
|
||||
case isConst:
|
||||
v := constant.BinaryOp(vConstantValue(v0), token.AND_NOT, vConstantValue(v1))
|
||||
v := constant.BinaryOp(constant.ToInt(vConstantValue(v0)), token.AND_NOT, constant.ToInt(vConstantValue(v1)))
|
||||
n.rval.Set(reflect.ValueOf(v))
|
||||
case isUint(t):
|
||||
n.rval.SetUint(vUint(v0) &^ vUint(v1))
|
||||
@@ -564,7 +564,7 @@ func orConst(n *node) {
|
||||
n.rval = reflect.New(t).Elem()
|
||||
switch {
|
||||
case isConst:
|
||||
v := constant.BinaryOp(vConstantValue(v0), token.OR, vConstantValue(v1))
|
||||
v := constant.BinaryOp(constant.ToInt(vConstantValue(v0)), token.OR, constant.ToInt(vConstantValue(v1)))
|
||||
n.rval.Set(reflect.ValueOf(v))
|
||||
case isUint(t):
|
||||
n.rval.SetUint(vUint(v0) | vUint(v1))
|
||||
@@ -799,7 +799,7 @@ func remConst(n *node) {
|
||||
n.rval = reflect.New(t).Elem()
|
||||
switch {
|
||||
case isConst:
|
||||
v := constant.BinaryOp(vConstantValue(v0), token.REM, vConstantValue(v1))
|
||||
v := constant.BinaryOp(constant.ToInt(vConstantValue(v0)), token.REM, constant.ToInt(vConstantValue(v1)))
|
||||
n.rval.Set(reflect.ValueOf(v))
|
||||
case isUint(t):
|
||||
n.rval.SetUint(vUint(v0) % vUint(v1))
|
||||
@@ -1195,7 +1195,7 @@ func xorConst(n *node) {
|
||||
n.rval = reflect.New(t).Elem()
|
||||
switch {
|
||||
case isConst:
|
||||
v := constant.BinaryOp(vConstantValue(v0), token.XOR, vConstantValue(v1))
|
||||
v := constant.BinaryOp(constant.ToInt(vConstantValue(v0)), token.XOR, constant.ToInt(vConstantValue(v1)))
|
||||
n.rval.Set(reflect.ValueOf(v))
|
||||
case isUint(t):
|
||||
n.rval.SetUint(vUint(v0) ^ vUint(v1))
|
||||
|
||||
Reference in New Issue
Block a user