Пример #1
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var leftOperand  = LeftOperand.GetValueInternal(state).Value;
            var rightOperand = RightOperand.GetValueInternal(state).Value;

            if (IsNumber(leftOperand) && IsNumber(rightOperand))
            {
                var leftConv  = (IConvertible)leftOperand;
                var rightConv = (IConvertible)rightOperand;

                if (leftOperand is decimal || rightOperand is decimal)
                {
                    var leftVal  = leftConv.ToDecimal(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToDecimal(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal / rightVal));
                }
                else if (leftOperand is double || rightOperand is double)
                {
                    var leftVal  = leftConv.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToDouble(CultureInfo.InvariantCulture);
                    _exitTypeDescriptor = TypeDescriptor.D;
                    return(new TypedValue(leftVal / rightVal));
                }
                else if (leftOperand is float || rightOperand is float)
                {
                    var leftVal  = leftConv.ToSingle(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToSingle(CultureInfo.InvariantCulture);
                    _exitTypeDescriptor = TypeDescriptor.F;
                    return(new TypedValue(leftVal / rightVal));
                }

                // Look at need to add support for .NET types not present in Java, e.g. ulong, ushort, byte, uint
                else if (leftOperand is long || rightOperand is long)
                {
                    var leftVal  = leftConv.ToInt64(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToInt64(CultureInfo.InvariantCulture);
                    _exitTypeDescriptor = TypeDescriptor.J;
                    return(new TypedValue(leftVal / rightVal));
                }
                else if (CodeFlow.IsIntegerForNumericOp(leftOperand) || CodeFlow.IsIntegerForNumericOp(rightOperand))
                {
                    var leftVal  = leftConv.ToInt32(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToInt32(CultureInfo.InvariantCulture);
                    _exitTypeDescriptor = TypeDescriptor.I;
                    return(new TypedValue(leftVal / rightVal));
                }
                else
                {
                    var leftVal  = leftConv.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToDouble(CultureInfo.InvariantCulture);

                    // Unknown Number subtypes -> best guess is double division
                    // Look at need to add support for .NET types not present in Java, e.g. ulong, ushort, byte, uint
                    return(new TypedValue(leftVal / rightVal));
                }
            }

            return(state.Operate(Operation.DIVIDE, leftOperand, rightOperand));
        }
Пример #2
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var leftOperand  = LeftOperand.GetValueInternal(state).Value;
            var rightOperand = RightOperand.GetValueInternal(state).Value;

            if (IsNumber(leftOperand) && IsNumber(rightOperand))
            {
                var leftNumber  = (IConvertible)leftOperand;
                var rightNumber = (IConvertible)rightOperand;

                if (leftNumber is decimal || rightNumber is decimal)
                {
                    var leftVal  = leftNumber.ToDecimal(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDecimal(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal % rightVal));
                }
                else if (leftNumber is double || rightNumber is double)
                {
                    _exitTypeDescriptor = "D";
                    var leftVal  = leftNumber.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal % rightVal));
                }
                else if (leftNumber is float || rightNumber is float)
                {
                    _exitTypeDescriptor = "F";
                    var leftVal  = leftNumber.ToSingle(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToSingle(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal % rightVal));
                }
                else if (leftNumber is long || rightNumber is long)
                {
                    _exitTypeDescriptor = "J";
                    var leftVal  = leftNumber.ToInt64(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToInt64(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal % rightVal));
                }
                else if (CodeFlow.IsIntegerForNumericOp(leftNumber) || CodeFlow.IsIntegerForNumericOp(rightNumber))
                {
                    _exitTypeDescriptor = "I";
                    var leftVal  = leftNumber.ToInt32(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToInt32(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal % rightVal));
                }
                else
                {
                    // Unknown Number subtypes -> best guess is double division
                    var leftVal  = leftNumber.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal % rightVal));
                }
            }

            return(state.Operate(Operation.MODULUS, leftOperand, rightOperand));
        }
Пример #3
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var leftOp  = LeftOperand;
            var rightOp = RightOperand;

            var leftOperand  = leftOp.GetValueInternal(state).Value;
            var rightOperand = rightOp.GetValueInternal(state).Value;

            if (IsNumber(leftOperand) && IsNumber(rightOperand))
            {
                var leftConv  = (IConvertible)leftOperand;
                var rightConv = (IConvertible)rightOperand;

                if (leftOperand is decimal)
                {
                    var rightVal = rightConv.ToInt32(CultureInfo.InvariantCulture);
                    var leftVal  = leftConv.ToDouble(CultureInfo.InvariantCulture);
                    var result   = Math.Pow(leftVal, rightVal) as IConvertible;
                    return(new TypedValue(result.ToDecimal(CultureInfo.InvariantCulture)));
                }

                // else if (leftNumber instanceof BigInteger) {
                //    BigInteger leftBigInteger = NumberUtils.convertNumberToTargetClass(leftNumber, typeof(BigInteger));
                //    return new TypedValue(leftBigInteger.pow(rightNumber.intValue()));
                // }
                else if (leftOperand is double || rightOperand is double)
                {
                    var rightVal = rightConv.ToDouble(CultureInfo.InvariantCulture);
                    var leftVal  = leftConv.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(Math.Pow(leftVal, rightVal)));
                }
                else if (leftOperand is float || rightOperand is float)
                {
                    var rightVal = rightConv.ToSingle(CultureInfo.InvariantCulture);
                    var leftVal  = leftConv.ToSingle(CultureInfo.InvariantCulture);
                    return(new TypedValue(Math.Pow(leftVal, rightVal)));
                }

                var r = rightConv.ToDouble(CultureInfo.InvariantCulture);
                var l = leftConv.ToDouble(CultureInfo.InvariantCulture);

                var d      = Math.Pow(l, r);
                var asLong = (long)d;
                if (asLong > int.MaxValue || leftOperand is long || rightOperand is long)
                {
                    return(new TypedValue((long)asLong));
                }
                else
                {
                    return(new TypedValue((int)asLong));
                }
            }

            return(state.Operate(Operation.POWER, leftOperand, rightOperand));
        }
Пример #4
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var leftOp  = LeftOperand;
            var rightOp = RightOperand;

            var leftOperand  = leftOp.GetValueInternal(state).Value;
            var rightOperand = rightOp.GetValueInternal(state).Value;

            if (IsNumber(leftOperand) && IsNumber(rightOperand))
            {
                var leftConv  = (IConvertible)leftOperand;
                var rightConv = (IConvertible)rightOperand;

                if (leftOperand is decimal)
                {
                    var rightVal = rightConv.ToInt32(CultureInfo.InvariantCulture);
                    var leftVal  = leftConv.ToDouble(CultureInfo.InvariantCulture);
                    var result   = Math.Pow(leftVal, rightVal) as IConvertible;
                    return(new TypedValue(result.ToDecimal(CultureInfo.InvariantCulture)));
                }
                else if (leftOperand is double || rightOperand is double)
                {
                    var rightVal = rightConv.ToDouble(CultureInfo.InvariantCulture);
                    var leftVal  = leftConv.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(Math.Pow(leftVal, rightVal)));
                }
                else if (leftOperand is float || rightOperand is float)
                {
                    var rightVal = rightConv.ToSingle(CultureInfo.InvariantCulture);
                    var leftVal  = leftConv.ToSingle(CultureInfo.InvariantCulture);
                    return(new TypedValue(Math.Pow(leftVal, rightVal)));
                }

                var r = rightConv.ToDouble(CultureInfo.InvariantCulture);
                var l = leftConv.ToDouble(CultureInfo.InvariantCulture);

                var d      = Math.Pow(l, r);
                var asLong = (long)d;
                if (asLong > int.MaxValue || leftOperand is long || rightOperand is long)
                {
                    return(new TypedValue(asLong));
                }
                else
                {
                    return(new TypedValue((int)asLong));
                }
            }

            return(state.Operate(Operation.POWER, leftOperand, rightOperand));
        }
Пример #5
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var leftOp = LeftOperand;

            if (_children.Length < 2)
            {
                // if only one operand, then this is unary plus
                var operandOne = leftOp.GetValueInternal(state).Value;
                if (IsNumber(operandOne))
                {
                    if (operandOne is double)
                    {
                        _exitTypeDescriptor = "D";
                    }
                    else if (operandOne is float)
                    {
                        _exitTypeDescriptor = "F";
                    }
                    else if (operandOne is long)
                    {
                        _exitTypeDescriptor = "J";
                    }
                    else if (operandOne is int)
                    {
                        _exitTypeDescriptor = "I";
                    }

                    return(new TypedValue(operandOne));
                }

                return(state.Operate(Operation.ADD, operandOne, null));
            }

            var operandOneValue = leftOp.GetValueInternal(state);
            var leftOperand     = operandOneValue.Value;
            var operandTwoValue = RightOperand.GetValueInternal(state);
            var rightOperand    = operandTwoValue.Value;

            if (IsNumber(leftOperand) && IsNumber(rightOperand))
            {
                var leftNumber  = (IConvertible)leftOperand;
                var rightNumber = (IConvertible)rightOperand;

                if (leftNumber is decimal || rightNumber is decimal)
                {
                    var leftVal  = leftNumber.ToDecimal(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDecimal(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal + rightVal));
                }
                else if (leftNumber is double || rightNumber is double)
                {
                    _exitTypeDescriptor = "D";
                    var leftVal  = leftNumber.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal + rightVal));
                }
                else if (leftNumber is float || rightNumber is float)
                {
                    _exitTypeDescriptor = "F";
                    var leftVal  = leftNumber.ToSingle(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToSingle(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal + rightVal));
                }
                else if (leftNumber is long || rightNumber is long)
                {
                    _exitTypeDescriptor = "J";
                    var leftVal  = leftNumber.ToInt64(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToInt64(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal + rightVal));
                }
                else if (CodeFlow.IsIntegerForNumericOp(leftNumber) || CodeFlow.IsIntegerForNumericOp(rightNumber))
                {
                    _exitTypeDescriptor = "I";
                    var leftVal  = leftNumber.ToInt32(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToInt32(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal + rightVal));
                }
                else
                {
                    // Unknown Number subtypes -> best guess is double addition
                    var leftVal  = leftNumber.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal + rightVal));
                }
            }

            if (leftOperand is string && rightOperand is string)
            {
                _exitTypeDescriptor = "LSystem/String";
                return(new TypedValue((string)leftOperand + (string)rightOperand));
            }

            if (leftOperand is string)
            {
                return(new TypedValue(leftOperand + (rightOperand == null ? "null" : ConvertTypedValueToString(operandTwoValue, state))));
            }

            if (rightOperand is string)
            {
                return(new TypedValue((leftOperand == null ? "null" : ConvertTypedValueToString(operandOneValue, state)) + rightOperand));
            }

            return(state.Operate(Operation.ADD, leftOperand, rightOperand));
        }
Пример #6
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var leftOp = LeftOperand;

            if (_children.Length < 2)
            {
                // if only one operand, then this is unary minus
                var operand = leftOp.GetValueInternal(state).Value;
                if (IsNumber(operand))
                {
                    switch (operand)
                    {
                    case decimal val: return(new TypedValue(0M - val));

                    case double val:
                        _exitTypeDescriptor = TypeDescriptor.D;
                        return(new TypedValue(0d - val));

                    case float val:
                        _exitTypeDescriptor = TypeDescriptor.F;
                        return(new TypedValue(0f - val));

                    case long val:
                        _exitTypeDescriptor = TypeDescriptor.J;
                        return(new TypedValue(0L - val));

                    case int val:
                        _exitTypeDescriptor = TypeDescriptor.I;
                        return(new TypedValue(0 - val));

                    case short val: return(new TypedValue(0 - val));

                    case byte val: return(new TypedValue(0 - val));

                    case ulong val: return(new TypedValue(0UL - val));

                    case uint val: return(new TypedValue(0U - val));

                    case ushort val: return(new TypedValue(0 - val));

                    case sbyte val: return(new TypedValue(0 - val));

                    default: return(state.Operate(Operation.SUBTRACT, operand, null));
                    }
                }

                return(state.Operate(Operation.SUBTRACT, operand, null));
            }

            var left  = leftOp.GetValueInternal(state).Value;
            var right = RightOperand.GetValueInternal(state).Value;

            if (IsNumber(left) && IsNumber(right))
            {
                var leftNumber  = (IConvertible)left;
                var rightNumber = (IConvertible)right;

                if (leftNumber is decimal || rightNumber is decimal)
                {
                    var leftVal  = leftNumber.ToDecimal(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDecimal(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
                else if (leftNumber is double || rightNumber is double)
                {
                    _exitTypeDescriptor = TypeDescriptor.D;
                    var leftVal  = leftNumber.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
                else if (leftNumber is float || rightNumber is float)
                {
                    _exitTypeDescriptor = TypeDescriptor.F;
                    var leftVal  = leftNumber.ToSingle(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToSingle(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
                else if (leftNumber is long || rightNumber is long)
                {
                    _exitTypeDescriptor = TypeDescriptor.J;
                    var leftVal  = leftNumber.ToInt64(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToInt64(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
                else if (CodeFlow.IsIntegerForNumericOp(leftNumber) || CodeFlow.IsIntegerForNumericOp(rightNumber))
                {
                    _exitTypeDescriptor = TypeDescriptor.I;
                    var leftVal  = leftNumber.ToInt32(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToInt32(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
                else
                {
                    // Unknown Number subtypes -> best guess is double subtraction
                    var leftVal  = leftNumber.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
            }

            if (left is string str && right is int integer && str.Length == 1)
            {
                var theString  = str;
                var theInteger = integer;

                // Implements character - int (ie. b - 1 = a)
                return(new TypedValue(((char)(theString[0] - theInteger)).ToString()));
            }

            return(state.Operate(Operation.SUBTRACT, left, right));
        }
Пример #7
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var leftOp = LeftOperand;

            if (_children.Length < 2)
            {
                // if only one operand, then this is unary minus
                var operand = leftOp.GetValueInternal(state).Value;
                if (IsNumber(operand))
                {
                    if (operand is decimal)
                    {
                        return(new TypedValue(0M - ((decimal)operand)));
                    }
                    else if (operand is double)
                    {
                        _exitTypeDescriptor = "D";
                        return(new TypedValue(0d - ((double)operand)));
                    }
                    else if (operand is float)
                    {
                        _exitTypeDescriptor = "F";
                        return(new TypedValue(0f - ((float)operand)));
                    }
                    else if (operand is long)
                    {
                        _exitTypeDescriptor = "J";
                        return(new TypedValue(0L - ((long)operand)));
                    }
                    else if (operand is int)
                    {
                        _exitTypeDescriptor = "I";
                        return(new TypedValue(0 - ((int)operand)));
                    }
                    else if (operand is short)
                    {
                        return(new TypedValue(((short)0) - ((short)operand)));
                    }
                    else if (operand is byte)
                    {
                        return(new TypedValue(((byte)0) - ((byte)operand)));
                    }
                    else if (operand is ulong)
                    {
                        return(new TypedValue(0UL - ((ulong)operand)));
                    }
                    else if (operand is uint)
                    {
                        return(new TypedValue(0U - ((uint)operand)));
                    }
                    else if (operand is ushort)
                    {
                        return(new TypedValue(((ushort)0) - ((ushort)operand)));
                    }
                    else if (operand is sbyte)
                    {
                        return(new TypedValue(((sbyte)0) - ((sbyte)operand)));
                    }
                }

                return(state.Operate(Operation.SUBTRACT, operand, null));
            }

            var left  = leftOp.GetValueInternal(state).Value;
            var right = RightOperand.GetValueInternal(state).Value;

            if (IsNumber(left) && IsNumber(right))
            {
                var leftNumber  = (IConvertible)left;
                var rightNumber = (IConvertible)right;

                if (leftNumber is decimal || rightNumber is decimal)
                {
                    var leftVal  = leftNumber.ToDecimal(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDecimal(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
                else if (leftNumber is double || rightNumber is double)
                {
                    _exitTypeDescriptor = "D";
                    var leftVal  = leftNumber.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
                else if (leftNumber is float || rightNumber is float)
                {
                    _exitTypeDescriptor = "F";
                    var leftVal  = leftNumber.ToSingle(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToSingle(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
                else if (leftNumber is long || rightNumber is long)
                {
                    _exitTypeDescriptor = "J";
                    var leftVal  = leftNumber.ToInt64(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToInt64(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
                else if (CodeFlow.IsIntegerForNumericOp(leftNumber) || CodeFlow.IsIntegerForNumericOp(rightNumber))
                {
                    _exitTypeDescriptor = "I";
                    var leftVal  = leftNumber.ToInt32(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToInt32(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
                else
                {
                    // Unknown Number subtypes -> best guess is double subtraction
                    var leftVal  = leftNumber.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal - rightVal));
                }
            }

            if (left is string && right is int && ((string)left).Length == 1)
            {
                var theString  = (string)left;
                var theInteger = (int)right;

                // Implements character - int (ie. b - 1 = a)
                return(new TypedValue(((char)(theString[0] - theInteger)).ToString()));
            }

            return(state.Operate(Operation.SUBTRACT, left, right));
        }
Пример #8
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var leftOperand  = LeftOperand.GetValueInternal(state).Value;
            var rightOperand = RightOperand.GetValueInternal(state).Value;

            if (IsNumber(leftOperand) && IsNumber(rightOperand))
            {
                var leftConv  = (IConvertible)leftOperand;
                var rightConv = (IConvertible)rightOperand;

                if (leftOperand is decimal || rightOperand is decimal)
                {
                    var leftVal  = leftConv.ToDecimal(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToDecimal(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal / rightVal));
                }
                else if (leftOperand is double || rightOperand is double)
                {
                    var leftVal  = leftConv.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToDouble(CultureInfo.InvariantCulture);
                    _exitTypeDescriptor = "D";
                    return(new TypedValue(leftVal / rightVal));
                }
                else if (leftOperand is float || rightOperand is float)
                {
                    var leftVal  = leftConv.ToSingle(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToSingle(CultureInfo.InvariantCulture);
                    _exitTypeDescriptor = "F";
                    return(new TypedValue(leftVal / rightVal));
                }

                // else if (leftNumber instanceof BigInteger || rightNumber instanceof BigInteger) {
                //    BigInteger leftBigInteger = NumberUtils.convertNumberToTargetClass(leftNumber, BigInteger.class);
                // BigInteger rightBigInteger = NumberUtils.convertNumberToTargetClass(rightNumber, BigInteger.class);
                // return new TypedValue(leftBigInteger.divide(rightBigInteger));
                // }

                // TODO: Look at need to add support for .NET types not present in Java, e.g. ulong, ushort, byte, uint
                else if (leftOperand is long || rightOperand is long)
                {
                    var leftVal  = leftConv.ToInt64(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToInt64(CultureInfo.InvariantCulture);
                    _exitTypeDescriptor = "J";
                    return(new TypedValue(leftVal / rightVal));
                }
                else if (CodeFlow.IsIntegerForNumericOp(leftOperand) || CodeFlow.IsIntegerForNumericOp(rightOperand))
                {
                    var leftVal  = leftConv.ToInt32(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToInt32(CultureInfo.InvariantCulture);
                    _exitTypeDescriptor = "I";
                    return(new TypedValue(leftVal / rightVal));
                }
                else
                {
                    var leftVal  = leftConv.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightConv.ToDouble(CultureInfo.InvariantCulture);

                    // Unknown Number subtypes -> best guess is double division
                    // TODO: Look at need to add support for .NET types not present in Java, e.g. ulong, ushort, byte, uint
                    return(new TypedValue(leftVal / rightVal));
                }
            }

            return(state.Operate(Operation.DIVIDE, leftOperand, rightOperand));
        }
Пример #9
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var operand  = LeftOperand;
            var valueRef = operand.GetValueRef(state);

            var         typedValue  = valueRef.GetValue();
            var         value       = typedValue.Value;
            var         returnValue = typedValue;
            ITypedValue newValue    = null;

            if (IsNumber(value))
            {
                var op1 = (IConvertible)value;
                if (op1 is decimal)
                {
                    newValue = new TypedValue(((decimal)op1) + 1M, typedValue.TypeDescriptor);
                }
                else if (op1 is double)
                {
                    newValue = new TypedValue(((double)op1) + 1.0d, typedValue.TypeDescriptor);
                }
                else if (op1 is float)
                {
                    newValue = new TypedValue(((float)op1) + 1.0f, typedValue.TypeDescriptor);
                }
                else if (op1 is long)
                {
                    newValue = new TypedValue(((long)op1) + 1L, typedValue.TypeDescriptor);
                }
                else if (op1 is int)
                {
                    newValue = new TypedValue(((int)op1) + 1, typedValue.TypeDescriptor);
                }
                else if (op1 is short)
                {
                    newValue = new TypedValue((short)(((short)op1) + (short)1), typedValue.TypeDescriptor);
                }
                else if (op1 is byte)
                {
                    newValue = new TypedValue((byte)(((byte)op1) + (byte)1), typedValue.TypeDescriptor);
                }
                else if (op1 is ulong)
                {
                    newValue = new TypedValue((ulong)(((ulong)op1) + 1UL), typedValue.TypeDescriptor);
                }
                else if (op1 is uint)
                {
                    newValue = new TypedValue((uint)(((uint)op1) + 1U), typedValue.TypeDescriptor);
                }
                else if (op1 is ushort)
                {
                    newValue = new TypedValue((ushort)(((ushort)op1) + (ushort)1), typedValue.TypeDescriptor);
                }
                else if (op1 is sbyte)
                {
                    newValue = new TypedValue((sbyte)(((sbyte)op1) + (sbyte)1), typedValue.TypeDescriptor);
                }
            }

            if (newValue == null)
            {
                try
                {
                    newValue = state.Operate(Operation.ADD, returnValue.Value, 1);
                }
                catch (SpelEvaluationException ex)
                {
                    if (ex.MessageCode == SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES)
                    {
                        // This means the operand is not incrementable
                        throw new SpelEvaluationException(operand.StartPosition, SpelMessage.OPERAND_NOT_INCREMENTABLE, operand.ToStringAST());
                    }

                    throw;
                }
            }

            // set the name value
            try
            {
                valueRef.SetValue(newValue.Value);
            }
            catch (SpelEvaluationException see)
            {
                // If unable to set the value the operand is not writable (e.g. 1++ )
                if (see.MessageCode == SpelMessage.SETVALUE_NOT_SUPPORTED)
                {
                    throw new SpelEvaluationException(operand.StartPosition, SpelMessage.OPERAND_NOT_INCREMENTABLE);
                }
                else
                {
                    throw;
                }
            }

            if (!_postfix)
            {
                // The return value is the new value, not the original value
                returnValue = newValue;
            }

            return(returnValue);
        }
Пример #10
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var operand = LeftOperand;

            // The operand is going to be read and then assigned to, we don't want to evaluate it twice.
            var lvalue = operand.GetValueRef(state);

            var         operandTypedValue = lvalue.GetValue();
            var         operandValue      = operandTypedValue.Value;
            var         returnValue       = operandTypedValue;
            ITypedValue newValue          = null;

            if (IsNumber(operandValue))
            {
                newValue = operandValue switch
                {
                    decimal val => new TypedValue(val - 1M, operandTypedValue.TypeDescriptor),
                    double val => new TypedValue(val - 1.0d, operandTypedValue.TypeDescriptor),
                    float val => new TypedValue(val - 1.0f, operandTypedValue.TypeDescriptor),
                    long val => new TypedValue(val - 1L, operandTypedValue.TypeDescriptor),
                    int val => new TypedValue(val - 1, operandTypedValue.TypeDescriptor),
                    short val => new TypedValue((short)(val - 1), operandTypedValue.TypeDescriptor),
                    byte val => new TypedValue((byte)(val - 1), operandTypedValue.TypeDescriptor),
                    ulong val => new TypedValue(val - 1L, operandTypedValue.TypeDescriptor),
                    uint val => new TypedValue(val - 1, operandTypedValue.TypeDescriptor),
                    ushort val => new TypedValue((ushort)(val - 1), operandTypedValue.TypeDescriptor),
                    sbyte val => new TypedValue((sbyte)(val - 1), operandTypedValue.TypeDescriptor),
                    _ => null
                };
            }

            if (newValue == null)
            {
                try
                {
                    newValue = state.Operate(Operation.SUBTRACT, returnValue.Value, 1);
                }
                catch (SpelEvaluationException ex)
                {
                    if (ex.MessageCode == SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES)
                    {
                        // This means the operand is not decrementable
                        throw new SpelEvaluationException(operand.StartPosition, SpelMessage.OPERAND_NOT_DECREMENTABLE, operand.ToStringAST());
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            // set the new value
            try
            {
                lvalue.SetValue(newValue.Value);
            }
            catch (SpelEvaluationException see)
            {
                // if unable to set the value the operand is not writable (e.g. 1-- )
                if (see.MessageCode == SpelMessage.SETVALUE_NOT_SUPPORTED)
                {
                    throw new SpelEvaluationException(operand.StartPosition, SpelMessage.OPERAND_NOT_DECREMENTABLE);
                }
                else
                {
                    throw;
                }
            }

            if (!_postfix)
            {
                // the return value is the new value, not the original value
                returnValue = newValue;
            }

            return(returnValue);
        }
Пример #11
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var operand = LeftOperand;

            // The operand is going to be read and then assigned to, we don't want to evaluate it twice.
            var lvalue = operand.GetValueRef(state);

            var         operandTypedValue = lvalue.GetValue(); // operand.getValueInternal(state);
            var         operandValue      = operandTypedValue.Value;
            var         returnValue       = operandTypedValue;
            ITypedValue newValue          = null;

            if (IsNumber(operandValue))
            {
                if (operandValue is decimal)
                {
                    var val = (decimal)operandValue;
                    newValue = new TypedValue(val - 1M, operandTypedValue.TypeDescriptor);
                }
                else if (operandValue is double)
                {
                    var val = (double)operandValue;
                    newValue = new TypedValue(val - 1.0d, operandTypedValue.TypeDescriptor);
                }
                else if (operandValue is float)
                {
                    var val = (float)operandValue;
                    newValue = new TypedValue(val - 1.0f, operandTypedValue.TypeDescriptor);
                }
                else if (operandValue is long)
                {
                    var val = (long)operandValue;
                    newValue = new TypedValue(val - 1L, operandTypedValue.TypeDescriptor);
                }
                else if (operandValue is int)
                {
                    var val = (int)operandValue;
                    newValue = new TypedValue(val - 1, operandTypedValue.TypeDescriptor);
                }
                else if (operandValue is short)
                {
                    var val = (short)operandValue;
                    newValue = new TypedValue((short)(val - (short)1), operandTypedValue.TypeDescriptor);
                }
                else if (operandValue is byte)
                {
                    var val = (byte)operandValue;
                    newValue = new TypedValue((byte)(val - (byte)1), operandTypedValue.TypeDescriptor);
                }
                else if (operandValue is ulong)
                {
                    var val = (ulong)operandValue;
                    newValue = new TypedValue((ulong)(val - 1L), operandTypedValue.TypeDescriptor);
                }
                else if (operandValue is uint)
                {
                    var val = (uint)operandValue;
                    newValue = new TypedValue((uint)(val - 1), operandTypedValue.TypeDescriptor);
                }
                else if (operandValue is ushort)
                {
                    var val = (ushort)operandValue;
                    newValue = new TypedValue((ushort)(val - (ushort)1), operandTypedValue.TypeDescriptor);
                }
                else if (operandValue is sbyte)
                {
                    var val = (sbyte)operandValue;
                    newValue = new TypedValue((sbyte)(val - (sbyte)1), operandTypedValue.TypeDescriptor);
                }

                // else
                // {
                //    // Unknown Number subtype -> best guess is double decrement
                //    var val = (double)operandValue;
                //    newValue = new TypedValue(val - 1.0d, operandTypedValue.TypeDescriptor);
                // }
            }

            if (newValue == null)
            {
                try
                {
                    newValue = state.Operate(Operation.SUBTRACT, returnValue.Value, 1);
                }
                catch (SpelEvaluationException ex)
                {
                    if (ex.MessageCode == SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES)
                    {
                        // This means the operand is not decrementable
                        throw new SpelEvaluationException(operand.StartPosition, SpelMessage.OPERAND_NOT_DECREMENTABLE, operand.ToStringAST());
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            // set the new value
            try
            {
                lvalue.SetValue(newValue.Value);
            }
            catch (SpelEvaluationException see)
            {
                // if unable to set the value the operand is not writable (e.g. 1-- )
                if (see.MessageCode == SpelMessage.SETVALUE_NOT_SUPPORTED)
                {
                    throw new SpelEvaluationException(operand.StartPosition, SpelMessage.OPERAND_NOT_DECREMENTABLE);
                }
                else
                {
                    throw;
                }
            }

            if (!_postfix)
            {
                // the return value is the new value, not the original value
                returnValue = newValue;
            }

            return(returnValue);
        }
Пример #12
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var leftOperand  = LeftOperand.GetValueInternal(state).Value;
            var rightOperand = RightOperand.GetValueInternal(state).Value;

            if (IsNumber(leftOperand) && IsNumber(rightOperand))
            {
                var leftNumber  = (IConvertible)leftOperand;
                var rightNumber = (IConvertible)rightOperand;

                if (leftNumber is decimal || rightNumber is decimal)
                {
                    var leftVal  = leftNumber.ToDecimal(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDecimal(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal * rightVal));
                }
                else if (leftNumber is double || rightNumber is double)
                {
                    _exitTypeDescriptor = TypeDescriptor.D;
                    var leftVal  = leftNumber.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal * rightVal));
                }
                else if (leftNumber is float || rightNumber is float)
                {
                    _exitTypeDescriptor = TypeDescriptor.F;
                    var leftVal  = leftNumber.ToSingle(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToSingle(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal * rightVal));
                }
                else if (leftNumber is long || rightNumber is long)
                {
                    _exitTypeDescriptor = TypeDescriptor.J;
                    var leftVal  = leftNumber.ToInt64(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToInt64(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal * rightVal));
                }
                else if (CodeFlow.IsIntegerForNumericOp(leftNumber) || CodeFlow.IsIntegerForNumericOp(rightNumber))
                {
                    _exitTypeDescriptor = TypeDescriptor.I;
                    var leftVal  = leftNumber.ToInt32(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToInt32(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal * rightVal));
                }
                else
                {
                    // Unknown Number subtypes -> best guess is double multiplication
                    var leftVal  = leftNumber.ToDouble(CultureInfo.InvariantCulture);
                    var rightVal = rightNumber.ToDouble(CultureInfo.InvariantCulture);
                    return(new TypedValue(leftVal * rightVal));
                }
            }

            if (leftOperand is string && rightOperand is int integer)
            {
                var repeats = integer;
                var result  = new StringBuilder();
                for (var i = 0; i < repeats; i++)
                {
                    result.Append(leftOperand);
                }

                return(new TypedValue(result.ToString()));
            }

            return(state.Operate(Operation.MULTIPLY, leftOperand, rightOperand));
        }