github.com/bobyang007/helper@v1.1.3/reflecth/op-binary.go (about) 1 package reflecth 2 3 import ( 4 "github.com/bobyang007/helper/strconvh" 5 "go/token" 6 "reflect" 7 ) 8 9 //replacer:ignore 10 //go:generate go run $GOPATH/src/github.com/apaxa-go/generator/replacer/main.go -- $GOFILE 11 12 //replacer:ignore 13 //go:generate go run $GOPATH/src/github.com/apaxa-go/generator/replacer/main.go -- $GOFILE 14 15 // BinaryOp performs binary operation <x><op><y> as Go language specification describes. 16 // Supported operations: && || + - * / % & | ^ &^ . 17 // If operation cannot be performed then error will be returned. 18 func BinaryOp(x reflect.Value, op token.Token, y reflect.Value) (r reflect.Value, err error) { 19 // Basic check 20 if xT, yT := x.Type(), y.Type(); !xT.AssignableTo(yT) && !yT.AssignableTo(xT) { 21 return reflect.Value{}, binaryOpMismatchTypesError(x, op, y) 22 } 23 24 r = reflect.New(x.Type()).Elem() 25 switch x.Kind() { 26 case reflect.Bool: 27 v, err := binaryOpBool(x.Bool(), op, y.Bool()) 28 if err != nil { 29 return reflect.Value{}, err 30 } 31 r.SetBool(v) 32 case reflect.Int: 33 v, err := binaryOpInt(int(x.Int()), op, int(y.Int())) 34 if err != nil { 35 return reflect.Value{}, err 36 } 37 r.SetInt(int64(v)) 38 case reflect.Int8: 39 v, err := binaryOpInt8(int8(x.Int()), op, int8(y.Int())) 40 if err != nil { 41 return reflect.Value{}, err 42 } 43 r.SetInt(int64(v)) 44 case reflect.Int16: 45 v, err := binaryOpInt16(int16(x.Int()), op, int16(y.Int())) 46 if err != nil { 47 return reflect.Value{}, err 48 } 49 r.SetInt(int64(v)) 50 case reflect.Int32: 51 v, err := binaryOpInt32(int32(x.Int()), op, int32(y.Int())) 52 if err != nil { 53 return reflect.Value{}, err 54 } 55 r.SetInt(int64(v)) 56 case reflect.Int64: 57 v, err := binaryOpInt64(x.Int(), op, y.Int()) 58 if err != nil { 59 return reflect.Value{}, err 60 } 61 r.SetInt(v) 62 case reflect.Uint: 63 v, err := binaryOpUint(uint(x.Uint()), op, uint(y.Uint())) 64 if err != nil { 65 return reflect.Value{}, err 66 } 67 r.SetUint(uint64(v)) 68 case reflect.Uint8: 69 v, err := binaryOpUint8(uint8(x.Uint()), op, uint8(y.Uint())) 70 if err != nil { 71 return reflect.Value{}, err 72 } 73 r.SetUint(uint64(v)) 74 case reflect.Uint16: 75 v, err := binaryOpUint16(uint16(x.Uint()), op, uint16(y.Uint())) 76 if err != nil { 77 return reflect.Value{}, err 78 } 79 r.SetUint(uint64(v)) 80 case reflect.Uint32: 81 v, err := binaryOpUint32(uint32(x.Uint()), op, uint32(y.Uint())) 82 if err != nil { 83 return reflect.Value{}, err 84 } 85 r.SetUint(uint64(v)) 86 case reflect.Uint64: 87 v, err := binaryOpUint64(x.Uint(), op, y.Uint()) 88 if err != nil { 89 return reflect.Value{}, err 90 } 91 r.SetUint(v) 92 case reflect.Float32: 93 v, err := binaryOpFloat32(float32(x.Float()), op, float32(y.Float())) 94 if err != nil { 95 return reflect.Value{}, err 96 } 97 r.SetFloat(float64(v)) 98 case reflect.Float64: 99 v, err := binaryOpFloat64(x.Float(), op, y.Float()) 100 if err != nil { 101 return reflect.Value{}, err 102 } 103 r.SetFloat(v) 104 case reflect.Complex64: 105 v, err := binaryOpComplex64(complex64(x.Complex()), op, complex64(y.Complex())) 106 if err != nil { 107 return reflect.Value{}, err 108 } 109 r.SetComplex(complex128(v)) 110 case reflect.Complex128: 111 v, err := binaryOpComplex128(x.Complex(), op, y.Complex()) 112 if err != nil { 113 return reflect.Value{}, err 114 } 115 r.SetComplex(v) 116 case reflect.String: 117 v, err := binaryOpString(x.String(), op, y.String()) 118 if err != nil { 119 return reflect.Value{}, err 120 } 121 r.SetString(v) 122 default: 123 return reflect.Value{}, invBinOpTypesInvalError(x, op, y) 124 } 125 return 126 } 127 128 func binaryOpBool(x bool, op token.Token, y bool) (r bool, err error) { 129 switch op { 130 case token.LAND: 131 return x && y, nil 132 case token.LOR: 133 return x || y, nil 134 default: 135 return false, binaryOpInvalidOperatorSError(strconvh.FormatBool(x), op.String(), strconvh.FormatBool(y)) 136 } 137 } 138 139 func binaryOpString(x string, op token.Token, y string) (r string, err error) { 140 switch op { 141 case token.ADD: 142 return x + y, nil 143 default: 144 return "", binaryOpInvalidOperatorSError(x, op.String(), y) 145 } 146 } 147 148 //replacer:replace 149 //replacer:old int64 Int64 150 //replacer:new int Int 151 //replacer:new int8 Int8 152 //replacer:new int16 Int16 153 //replacer:new int32 Int32 154 //replacer:new uint Uint 155 //replacer:new uint8 Uint8 156 //replacer:new uint16 Uint16 157 //replacer:new uint32 Uint32 158 //replacer:new uint64 Uint64 159 160 func binaryOpInt64(x int64, op token.Token, y int64) (r int64, err error) { 161 switch op { 162 case token.ADD: 163 return x + y, nil 164 case token.SUB: 165 return x - y, nil 166 case token.MUL: 167 return x * y, nil 168 case token.QUO: 169 return x / y, nil 170 case token.REM: 171 return x % y, nil 172 case token.AND: 173 return x & y, nil 174 case token.OR: 175 return x | y, nil 176 case token.XOR: 177 return x ^ y, nil 178 case token.AND_NOT: 179 return x &^ y, nil 180 default: 181 return 0, binaryOpInvalidOperatorSError(strconvh.FormatInt64(x), op.String(), strconvh.FormatInt64(y)) 182 } 183 } 184 185 //replacer:replace 186 //replacer:old float32 Float32 187 //replacer:new float64 Float64 188 //replacer:new complex64 Complex64 189 //replacer:new complex128 Complex128 190 191 func binaryOpFloat32(x float32, op token.Token, y float32) (r float32, err error) { 192 switch op { 193 case token.ADD: 194 return x + y, nil 195 case token.SUB: 196 return x - y, nil 197 case token.MUL: 198 return x * y, nil 199 case token.QUO: 200 return x / y, nil 201 default: 202 return 0, binaryOpInvalidOperatorSError(strconvh.FormatFloat32(x), op.String(), strconvh.FormatFloat32(y)) 203 } 204 }