fix: add support for ^ and + as unary operators

This commit is contained in:
Marc Vertes
2020-01-07 15:34:05 +01:00
committed by Traefiker Bot
parent a1f2d3bf1d
commit 878fcc835c
6 changed files with 186 additions and 37 deletions

View File

@@ -24,6 +24,7 @@ var builtin = [...]bltnGenerator{
aAndAssign: andAssign,
aAndNot: andNot,
aAndNotAssign: andNotAssign,
aBitNot: bitNot,
aCall: call,
aCase: _case,
aCompositeLit: arrayLit,
@@ -40,11 +41,12 @@ var builtin = [...]bltnGenerator{
aLowerEqual: lowerEqual,
aMul: mul,
aMulAssign: mulAssign,
aNegate: negate,
aNeg: neg,
aNot: not,
aNotEqual: notEqual,
aOr: or,
aOrAssign: orAssign,
aPos: pos,
aQuo: quo,
aQuoAssign: quoAssign,
aRange: _range,
@@ -340,6 +342,7 @@ func assign(n *node) {
}
func not(n *node) {
dest := genValue(n)
value := genValue(n.child[0])
tnext := getExec(n.tnext)
@@ -352,9 +355,8 @@ func not(n *node) {
return fnext
}
} else {
i := n.findex
n.exec = func(f *frame) bltn {
f.data[i].SetBool(!value(f).Bool())
dest(f).SetBool(!value(f).Bool())
return tnext
}
}
@@ -1246,7 +1248,7 @@ func getIndexSeqMethod(n *node) {
}
}
func negate(n *node) {
func neg(n *node) {
dest := genValue(n)
value := genValue(n.child[0])
next := getExec(n.tnext)
@@ -1270,6 +1272,37 @@ func negate(n *node) {
}
}
func pos(n *node) {
dest := genValue(n)
value := genValue(n.child[0])
next := getExec(n.tnext)
n.exec = func(f *frame) bltn {
dest(f).Set(value(f))
return next
}
}
func bitNot(n *node) {
dest := genValue(n)
value := genValue(n.child[0])
next := getExec(n.tnext)
typ := n.typ.TypeOf()
switch typ.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
n.exec = func(f *frame) bltn {
dest(f).SetInt(^value(f).Int())
return next
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
n.exec = func(f *frame) bltn {
dest(f).SetUint(^value(f).Uint())
return next
}
}
}
func land(n *node) {
value0 := genValue(n.child[0])
value1 := genValue(n.child[1])
@@ -1946,7 +1979,7 @@ func _close(n *node) {
}
func _complex(n *node) {
i := n.findex
dest := genValue(n)
c1, c2 := n.child[1], n.child[2]
convertLiteralValue(c1, floatType)
convertLiteralValue(c2, floatType)
@@ -1956,38 +1989,38 @@ func _complex(n *node) {
if typ := n.typ.TypeOf(); isComplex(typ) {
n.exec = func(f *frame) bltn {
f.data[i].SetComplex(complex(value0(f).Float(), value1(f).Float()))
dest(f).SetComplex(complex(value0(f).Float(), value1(f).Float()))
return next
}
} else {
// Not a complex type: ignore imaginary part
n.exec = func(f *frame) bltn {
f.data[i].Set(value0(f).Convert(typ))
dest(f).Set(value0(f).Convert(typ))
return next
}
}
}
func _imag(n *node) {
i := n.findex
dest := genValue(n)
convertLiteralValue(n.child[1], complexType)
value := genValue(n.child[1])
next := getExec(n.tnext)
n.exec = func(f *frame) bltn {
f.data[i].SetFloat(imag(value(f).Complex()))
dest(f).SetFloat(imag(value(f).Complex()))
return next
}
}
func _real(n *node) {
i := n.findex
dest := genValue(n)
convertLiteralValue(n.child[1], complexType)
value := genValue(n.child[1])
next := getExec(n.tnext)
n.exec = func(f *frame) bltn {
f.data[i].SetFloat(real(value(f).Complex()))
dest(f).SetFloat(real(value(f).Complex()))
return next
}
}
@@ -2005,12 +2038,12 @@ func _delete(n *node) {
}
func _len(n *node) {
i := n.findex
dest := genValue(n)
value := genValue(n.child[1])
next := getExec(n.tnext)
n.exec = func(f *frame) bltn {
f.data[i].SetInt(int64(value(f).Len()))
dest(f).SetInt(int64(value(f).Len()))
return next
}
}
@@ -2420,21 +2453,21 @@ func isNil(n *node) {
value = genValue(n.child[0])
}
tnext := getExec(n.tnext)
i := n.findex
dest := genValue(n)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
if value(f).IsNil() {
f.data[i].SetBool(true)
dest(f).SetBool(true)
return tnext
}
f.data[i].SetBool(false)
dest(f).SetBool(false)
return fnext
}
} else {
n.exec = func(f *frame) bltn {
f.data[i].SetBool(value(f).IsNil())
dest(f).SetBool(value(f).IsNil())
return tnext
}
}
@@ -2448,21 +2481,21 @@ func isNotNil(n *node) {
value = genValue(n.child[0])
}
tnext := getExec(n.tnext)
i := n.findex
dest := genValue(n)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
if value(f).IsNil() {
f.data[i].SetBool(false)
dest(f).SetBool(false)
return fnext
}
f.data[i].SetBool(true)
dest(f).SetBool(true)
return tnext
}
} else {
n.exec = func(f *frame) bltn {
f.data[i].SetBool(!value(f).IsNil())
dest(f).SetBool(!value(f).IsNil())
return tnext
}
}