public override ITypedValue GetValueInternal(ExpressionState state) { var left = LeftOperand.GetValueInternal(state).Value; var right = RightOperand.GetValueInternal(state).Value; if (!(right is IList) || ((IList)right).Count != 2) { throw new SpelEvaluationException(RightOperand.StartPosition, SpelMessage.BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST); } var list = (IList)right; var low = list[0]; var high = list[1]; var comp = state.TypeComparator; try { return(BooleanTypedValue.ForValue(comp.Compare(left, low) >= 0 && comp.Compare(left, high) <= 0)); } catch (SpelEvaluationException ex) { ex.Position = StartPosition; throw; } }
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 leftValue = LeftOperand.GetValueInternal(state).Value; var rightValue = RightOperand.GetValueInternal(state).Value; _leftActualDescriptor = CodeFlow.ToDescriptorFromObject(leftValue); _rightActualDescriptor = CodeFlow.ToDescriptorFromObject(rightValue); return(BooleanTypedValue.ForValue(!EqualityCheck(state.EvaluationContext, leftValue, rightValue))); }
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 left = LeftOperand.GetValueInternal(state).Value; var right = RightOperand.GetValueInternal(state).Value; _leftActualDescriptor = CodeFlow.ToDescriptorFromObject(left); _rightActualDescriptor = CodeFlow.ToDescriptorFromObject(right); if (IsNumber(left) && IsNumber(right)) { var leftConv = (IConvertible)left; var rightConv = (IConvertible)right; if (left is decimal || right is decimal) { var leftVal = leftConv.ToDecimal(CultureInfo.InvariantCulture); var rightVal = rightConv.ToDecimal(CultureInfo.InvariantCulture); return(BooleanTypedValue.ForValue(leftVal.CompareTo(rightVal) <= 0)); } else if (left is double || right is double) { var leftVal = leftConv.ToDouble(CultureInfo.InvariantCulture); var rightVal = rightConv.ToDouble(CultureInfo.InvariantCulture); return(BooleanTypedValue.ForValue(leftVal <= rightVal)); } else if (left is float || right is float) { var leftVal = leftConv.ToSingle(CultureInfo.InvariantCulture); var rightVal = rightConv.ToSingle(CultureInfo.InvariantCulture); return(BooleanTypedValue.ForValue(leftVal <= rightVal)); } else if (left is long || right is long) { var leftVal = leftConv.ToInt64(CultureInfo.InvariantCulture); var rightVal = rightConv.ToInt64(CultureInfo.InvariantCulture); return(BooleanTypedValue.ForValue(leftVal <= rightVal)); } else if (left is int || right is int) { var leftVal = leftConv.ToInt32(CultureInfo.InvariantCulture); var rightVal = rightConv.ToInt32(CultureInfo.InvariantCulture); return(BooleanTypedValue.ForValue(leftVal <= rightVal)); } else if (left is short || right is short) { var leftVal = leftConv.ToInt16(CultureInfo.InvariantCulture); var rightVal = rightConv.ToInt16(CultureInfo.InvariantCulture); return(BooleanTypedValue.ForValue(leftVal <= rightVal)); } else if (left is byte || right is byte) { var leftVal = leftConv.ToByte(CultureInfo.InvariantCulture); var rightVal = rightConv.ToByte(CultureInfo.InvariantCulture); return(BooleanTypedValue.ForValue(leftVal <= rightVal)); } else if (left is ulong || right is ulong) { var leftVal = leftConv.ToUInt64(CultureInfo.InvariantCulture); var rightVal = rightConv.ToUInt64(CultureInfo.InvariantCulture); return(BooleanTypedValue.ForValue(leftVal <= rightVal)); } else if (left is uint || right is uint) { var leftVal = leftConv.ToUInt32(CultureInfo.InvariantCulture); var rightVal = rightConv.ToUInt32(CultureInfo.InvariantCulture); return(BooleanTypedValue.ForValue(leftVal <= rightVal)); } else if (left is ushort || right is ushort) { var leftVal = leftConv.ToUInt16(CultureInfo.InvariantCulture); var rightVal = rightConv.ToUInt16(CultureInfo.InvariantCulture); return(BooleanTypedValue.ForValue(leftVal <= rightVal)); } else if (left is sbyte || right is sbyte) { var leftVal = leftConv.ToSByte(CultureInfo.InvariantCulture); var rightVal = rightConv.ToSByte(CultureInfo.InvariantCulture); return(BooleanTypedValue.ForValue(leftVal <= rightVal)); } } return(BooleanTypedValue.ForValue(state.TypeComparator.Compare(left, right) <= 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)); }
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 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)); }