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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
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); }
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); }
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); }
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)); }