2018-09-18 22:42:38 +02:00
|
|
|
package operators
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2019-02-13 19:31:18 +02:00
|
|
|
|
2018-09-18 22:42:38 +02:00
|
|
|
"github.com/MontFerret/ferret/pkg/runtime/core"
|
|
|
|
"github.com/MontFerret/ferret/pkg/runtime/values"
|
2019-02-13 19:31:18 +02:00
|
|
|
"github.com/MontFerret/ferret/pkg/runtime/values/types"
|
2018-09-18 22:42:38 +02:00
|
|
|
)
|
|
|
|
|
2018-10-07 23:54:02 +02:00
|
|
|
type (
|
|
|
|
OperatorFunc func(left, right core.Value) core.Value
|
|
|
|
baseOperator struct {
|
|
|
|
src core.SourceMap
|
|
|
|
left core.Expression
|
|
|
|
right core.Expression
|
|
|
|
}
|
|
|
|
)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-10-07 23:54:02 +02:00
|
|
|
func (operator *baseOperator) Exec(_ context.Context, _ *core.Scope) (core.Value, error) {
|
|
|
|
return values.None, core.ErrInvalidOperation
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2018-10-07 23:54:02 +02:00
|
|
|
func (operator *baseOperator) Eval(_ context.Context, _, _ core.Value) (core.Value, error) {
|
2018-09-18 22:42:38 +02:00
|
|
|
return values.None, core.ErrInvalidOperation
|
|
|
|
}
|
|
|
|
|
|
|
|
// Equality
|
|
|
|
func Equal(left, right core.Value) core.Value {
|
|
|
|
if left.Compare(right) == 0 {
|
|
|
|
return values.True
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.False
|
|
|
|
}
|
|
|
|
|
|
|
|
func NotEqual(left, right core.Value) core.Value {
|
|
|
|
if left.Compare(right) != 0 {
|
|
|
|
return values.True
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.False
|
|
|
|
}
|
|
|
|
|
|
|
|
func Less(left, right core.Value) core.Value {
|
|
|
|
if left.Compare(right) < 0 {
|
|
|
|
return values.True
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.False
|
|
|
|
}
|
|
|
|
|
|
|
|
func LessOrEqual(left, right core.Value) core.Value {
|
|
|
|
out := left.Compare(right)
|
|
|
|
|
|
|
|
if out < 0 || out == 0 {
|
|
|
|
return values.True
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.False
|
|
|
|
}
|
|
|
|
|
|
|
|
func Greater(left, right core.Value) core.Value {
|
|
|
|
if left.Compare(right) > 0 {
|
|
|
|
return values.True
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.False
|
|
|
|
}
|
|
|
|
|
|
|
|
func GreaterOrEqual(left, right core.Value) core.Value {
|
|
|
|
out := left.Compare(right)
|
|
|
|
|
|
|
|
if out > 0 || out == 0 {
|
|
|
|
return values.True
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.False
|
|
|
|
}
|
|
|
|
|
|
|
|
func Not(left, _ core.Value) core.Value {
|
2018-09-23 02:28:33 +02:00
|
|
|
b := values.ToBoolean(left)
|
|
|
|
|
|
|
|
if b == values.True {
|
2018-09-18 22:42:38 +02:00
|
|
|
return values.False
|
|
|
|
}
|
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return values.True
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Adds numbers
|
|
|
|
// Concats strings
|
|
|
|
func Add(left, right core.Value) core.Value {
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Int {
|
|
|
|
if right.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
|
|
|
r := right.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l + r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if right.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
|
|
|
r := right.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return values.Float(l) + r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Float {
|
|
|
|
if right.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
|
|
|
r := right.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l + r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if right.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
|
|
|
r := right.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l + values.Float(r)
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.NewString(left.String() + right.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func Subtract(left, right core.Value) core.Value {
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Int {
|
|
|
|
if right.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
|
|
|
r := right.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l - r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if right.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
|
|
|
r := right.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return values.Float(l) - r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Float {
|
|
|
|
if right.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
|
|
|
r := right.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l - r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if right.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
|
|
|
r := right.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l - values.Float(r)
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.ZeroInt
|
|
|
|
}
|
|
|
|
|
|
|
|
func Multiply(left, right core.Value) core.Value {
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Int {
|
|
|
|
if right.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
|
|
|
r := right.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l * r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if right.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
|
|
|
r := right.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return values.Float(l) * r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Float {
|
|
|
|
if right.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
|
|
|
r := right.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l * r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if right.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
|
|
|
r := right.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l * values.Float(r)
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.ZeroInt
|
|
|
|
}
|
|
|
|
|
|
|
|
func Divide(left, right core.Value) core.Value {
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Int {
|
|
|
|
if right.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
|
|
|
r := right.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l / r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if right.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
|
|
|
r := right.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return values.Float(l) / r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Float {
|
|
|
|
if right.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
|
|
|
r := right.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l / r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if right.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
|
|
|
r := right.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l / values.Float(r)
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.ZeroInt
|
|
|
|
}
|
|
|
|
|
|
|
|
func Modulus(left, right core.Value) core.Value {
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Int {
|
|
|
|
if right.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
|
|
|
r := right.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l % r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if right.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
|
|
|
r := right.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l % values.Int(r)
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Float {
|
|
|
|
if right.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
|
|
|
r := right.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return values.Int(l) % values.Int(r)
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if right.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
|
|
|
r := right.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return values.Int(l) % r
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.ZeroInt
|
|
|
|
}
|
|
|
|
|
|
|
|
func Increment(left, _ core.Value) core.Value {
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l + 1
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l + 1
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return values.None
|
|
|
|
}
|
|
|
|
|
|
|
|
func Decrement(left, _ core.Value) core.Value {
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Int {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Int)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l - 1
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if left.Type() == types.Float {
|
2018-09-23 02:28:33 +02:00
|
|
|
l := left.(values.Float)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-23 02:28:33 +02:00
|
|
|
return l - 1
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return values.None
|
|
|
|
}
|
2018-10-17 17:41:40 +02:00
|
|
|
|
|
|
|
func Negative(value, _ core.Value) core.Value {
|
2019-02-13 19:31:18 +02:00
|
|
|
err := core.ValidateType(value, types.Int, types.Float)
|
2018-10-17 17:41:40 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return values.ZeroInt
|
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if value.Type() == types.Int {
|
2018-10-17 17:41:40 +02:00
|
|
|
return -value.(values.Int)
|
|
|
|
}
|
|
|
|
|
|
|
|
return -value.(values.Float)
|
|
|
|
}
|
|
|
|
|
|
|
|
func Positive(value, _ core.Value) core.Value {
|
2019-02-13 19:31:18 +02:00
|
|
|
err := core.ValidateType(value, types.Int, types.Float)
|
2018-10-17 17:41:40 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return values.ZeroInt
|
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
if value.Type() == types.Int {
|
2018-10-17 17:41:40 +02:00
|
|
|
return +value.(values.Int)
|
|
|
|
}
|
|
|
|
|
|
|
|
return +value.(values.Float)
|
|
|
|
}
|
|
|
|
|
|
|
|
func ToBoolean(value, _ core.Value) core.Value {
|
|
|
|
return values.ToBoolean(value)
|
|
|
|
}
|