github.com/MontFerret/ferret@v0.18.0/pkg/runtime/expressions/operators/operator.go (about) 1 package operators 2 3 import ( 4 "context" 5 "strings" 6 7 "github.com/MontFerret/ferret/pkg/runtime/core" 8 "github.com/MontFerret/ferret/pkg/runtime/values" 9 "github.com/MontFerret/ferret/pkg/runtime/values/types" 10 ) 11 12 type ( 13 OperatorFunc func(left, right core.Value) core.Value 14 baseOperator struct { 15 src core.SourceMap 16 left core.Expression 17 right core.Expression 18 } 19 ) 20 21 func (operator *baseOperator) Exec(_ context.Context, _ *core.Scope) (core.Value, error) { 22 return values.None, core.ErrInvalidOperation 23 } 24 25 func (operator *baseOperator) Eval(_ context.Context, _, _ core.Value) (core.Value, error) { 26 return values.None, core.ErrInvalidOperation 27 } 28 29 // Equality 30 func Equal(left, right core.Value) core.Value { 31 if left.Compare(right) == 0 { 32 return values.True 33 } 34 35 return values.False 36 } 37 38 func NotEqual(left, right core.Value) core.Value { 39 if left.Compare(right) != 0 { 40 return values.True 41 } 42 43 return values.False 44 } 45 46 func Less(left, right core.Value) core.Value { 47 if left.Compare(right) < 0 { 48 return values.True 49 } 50 51 return values.False 52 } 53 54 func LessOrEqual(left, right core.Value) core.Value { 55 out := left.Compare(right) 56 57 if out < 0 || out == 0 { 58 return values.True 59 } 60 61 return values.False 62 } 63 64 func Greater(left, right core.Value) core.Value { 65 if left.Compare(right) > 0 { 66 return values.True 67 } 68 69 return values.False 70 } 71 72 func GreaterOrEqual(left, right core.Value) core.Value { 73 out := left.Compare(right) 74 75 if out > 0 || out == 0 { 76 return values.True 77 } 78 79 return values.False 80 } 81 82 func Not(left, _ core.Value) core.Value { 83 b := values.ToBoolean(left) 84 85 if b == values.True { 86 return values.False 87 } 88 89 return values.True 90 } 91 92 func ToNumberOrString(input core.Value) core.Value { 93 switch input.Type() { 94 case types.Int, types.Float, types.String: 95 return input 96 default: 97 return values.ToInt(input) 98 } 99 } 100 101 func ToNumberOnly(input core.Value) core.Value { 102 switch input.Type() { 103 case types.Int, types.Float: 104 return input 105 case types.String: 106 if strings.Contains(input.String(), ".") { 107 return values.ToFloat(input) 108 } 109 110 return values.ToInt(input) 111 case types.Array: 112 arr := input.(*values.Array) 113 length := arr.Length() 114 115 if length == 0 { 116 return values.ZeroInt 117 } 118 119 i := values.ZeroInt 120 f := values.ZeroFloat 121 122 for y := values.Int(0); y < length; y++ { 123 out := ToNumberOnly(arr.Get(y)) 124 125 if out.Type() == types.Int { 126 i += out.(values.Int) 127 } else { 128 f += out.(values.Float) 129 } 130 } 131 132 if f == 0 { 133 return i 134 } 135 136 return values.Float(i) + f 137 default: 138 return values.ToInt(input) 139 } 140 } 141 142 // Adds numbers 143 // Concatenates strings 144 func Add(inputL, inputR core.Value) core.Value { 145 left := ToNumberOrString(inputL) 146 right := ToNumberOrString(inputR) 147 148 if left.Type() == types.Int { 149 if right.Type() == types.Int { 150 l := left.(values.Int) 151 r := right.(values.Int) 152 153 return l + r 154 } 155 156 if right.Type() == types.Float { 157 l := left.(values.Int) 158 r := right.(values.Float) 159 160 return values.Float(l) + r 161 } 162 } 163 164 if left.Type() == types.Float { 165 if right.Type() == types.Float { 166 l := left.(values.Float) 167 r := right.(values.Float) 168 169 return l + r 170 } 171 172 if right.Type() == types.Int { 173 l := left.(values.Float) 174 r := right.(values.Int) 175 176 return l + values.Float(r) 177 } 178 } 179 180 return values.NewString(left.String() + right.String()) 181 } 182 183 func Subtract(inputL, inputR core.Value) core.Value { 184 left := ToNumberOnly(inputL) 185 right := ToNumberOnly(inputR) 186 187 if left.Type() == types.Int { 188 if right.Type() == types.Int { 189 l := left.(values.Int) 190 r := right.(values.Int) 191 192 return l - r 193 } 194 195 if right.Type() == types.Float { 196 l := left.(values.Int) 197 r := right.(values.Float) 198 199 return values.Float(l) - r 200 } 201 } 202 203 if left.Type() == types.Float { 204 if right.Type() == types.Float { 205 l := left.(values.Float) 206 r := right.(values.Float) 207 208 return l - r 209 } 210 211 if right.Type() == types.Int { 212 l := left.(values.Float) 213 r := right.(values.Int) 214 215 return l - values.Float(r) 216 } 217 } 218 219 return values.ZeroInt 220 } 221 222 func Multiply(inputL, inputR core.Value) core.Value { 223 left := ToNumberOnly(inputL) 224 right := ToNumberOnly(inputR) 225 226 if left.Type() == types.Int { 227 if right.Type() == types.Int { 228 l := left.(values.Int) 229 r := right.(values.Int) 230 231 return l * r 232 } 233 234 if right.Type() == types.Float { 235 l := left.(values.Int) 236 r := right.(values.Float) 237 238 return values.Float(l) * r 239 } 240 } 241 242 if left.Type() == types.Float { 243 if right.Type() == types.Float { 244 l := left.(values.Float) 245 r := right.(values.Float) 246 247 return l * r 248 } 249 250 if right.Type() == types.Int { 251 l := left.(values.Float) 252 r := right.(values.Int) 253 254 return l * values.Float(r) 255 } 256 } 257 258 return values.ZeroInt 259 } 260 261 func Divide(inputL, inputR core.Value) core.Value { 262 left := ToNumberOnly(inputL) 263 right := ToNumberOnly(inputR) 264 265 if left.Type() == types.Int { 266 if right.Type() == types.Int { 267 l := values.Float(left.(values.Int)) 268 r := values.Float(right.(values.Int)) 269 270 if r == 0.0 { 271 panic("divide by zero") 272 } 273 274 return l / r 275 } 276 277 if right.Type() == types.Float { 278 l := values.Float(left.(values.Int)) 279 r := right.(values.Float) 280 281 if r == 0.0 { 282 panic("divide by zero") 283 } 284 285 return l / r 286 } 287 } 288 289 if left.Type() == types.Float { 290 if right.Type() == types.Float { 291 l := left.(values.Float) 292 r := right.(values.Float) 293 294 if r == 0.0 { 295 panic("divide by zero") 296 } 297 298 return l / r 299 } 300 301 if right.Type() == types.Int { 302 l := left.(values.Float) 303 r := values.Float(right.(values.Int)) 304 305 if r == 0.0 { 306 panic("divide by zero") 307 } 308 309 return l / r 310 } 311 } 312 313 return values.ZeroInt 314 } 315 316 func Modulus(inputL, inputR core.Value) core.Value { 317 left := ToNumberOnly(inputL) 318 right := ToNumberOnly(inputR) 319 320 if left.Type() == types.Int { 321 if right.Type() == types.Int { 322 l := left.(values.Int) 323 r := right.(values.Int) 324 325 return l % r 326 } 327 328 if right.Type() == types.Float { 329 l := left.(values.Int) 330 r := right.(values.Float) 331 332 return l % values.Int(r) 333 } 334 } 335 336 if left.Type() == types.Float { 337 if right.Type() == types.Float { 338 l := left.(values.Float) 339 r := right.(values.Float) 340 341 return values.Int(l) % values.Int(r) 342 } 343 344 if right.Type() == types.Int { 345 l := left.(values.Float) 346 r := right.(values.Int) 347 348 return values.Int(l) % r 349 } 350 } 351 352 return values.ZeroInt 353 } 354 355 func Increment(inputL, _ core.Value) core.Value { 356 left := ToNumberOnly(inputL) 357 358 if left.Type() == types.Int { 359 l := left.(values.Int) 360 361 return l + 1 362 } 363 364 if left.Type() == types.Float { 365 l := left.(values.Float) 366 367 return l + 1 368 } 369 370 return values.None 371 } 372 373 func Decrement(inputL, _ core.Value) core.Value { 374 left := ToNumberOnly(inputL) 375 376 if left.Type() == types.Int { 377 l := left.(values.Int) 378 379 return l - 1 380 } 381 382 if left.Type() == types.Float { 383 l := left.(values.Float) 384 385 return l - 1 386 } 387 388 return values.None 389 } 390 391 func Negative(value, _ core.Value) core.Value { 392 if value.Type() == types.Int { 393 return -value.(values.Int) 394 } 395 396 if value.Type() == types.Float { 397 return -value.(values.Float) 398 } 399 400 return value 401 } 402 403 func Positive(value, _ core.Value) core.Value { 404 if value.Type() == types.Int { 405 return +value.(values.Int) 406 } 407 408 if value.Type() == types.Float { 409 return +value.(values.Float) 410 } 411 412 return value 413 } 414 415 func ToBoolean(value, _ core.Value) core.Value { 416 return values.ToBoolean(value) 417 }