private IParseTreeValue EvaluateUnaryMinus(IParseTreeValue parseTreeValue) { var opProvider = new OperatorTypesProvider(parseTreeValue.ValueType, ArithmeticOperators.ADDITIVE_INVERSE); if (!parseTreeValue.ParsesToConstantValue) { //Unable to resolve to a value, return an expression var opTypeName = opProvider.OperatorDeclaredType; return(_valueFactory.CreateDeclaredType($"{ArithmeticOperators.ADDITIVE_INVERSE} {parseTreeValue.Token}", opTypeName)); } var effTypeName = opProvider.OperatorEffectiveType; if (effTypeName.Equals(Tokens.Date)) { var result = DateTime.FromOADate(0 - parseTreeValue.AsDouble()); var date = new DateValue(result); return(_valueFactory.CreateDeclaredType(date.AsDate.ToString(CultureInfo.InvariantCulture), effTypeName)); } var declaredTypeName = opProvider.OperatorDeclaredType; if (parseTreeValue.TryLetCoerce(out decimal decValue)) { return(_valueFactory.CreateDeclaredType((0 - decValue).ToString(CultureInfo.InvariantCulture), declaredTypeName)); } return(_valueFactory.CreateDeclaredType((0 - parseTreeValue.AsDouble()).ToString(CultureInfo.InvariantCulture), declaredTypeName)); }
private string Compare(IParseTreeValue LHS, IParseTreeValue RHS, Func <decimal, decimal, bool> DecimalCompare, Func <double, double, bool> DoubleCompare) { if (DecimalCompare is null && DoubleCompare is null) { throw new ArgumentNullException(); } if (!(DecimalCompare is null) && LHS.TryLetCoerce(out decimal lhsValue) && RHS.TryLetCoerce(out decimal rhsValue)) { return(DecimalCompare(lhsValue, rhsValue) ? Tokens.True : Tokens.False); } return(DoubleCompare(LHS.AsDouble(), RHS.AsDouble()) ? Tokens.True : Tokens.False); }
private string Calculate(IParseTreeValue LHS, IParseTreeValue RHS, Func <decimal, decimal, decimal> DecimalCalc, Func <double, double, double> DoubleCalc) { if (DecimalCalc is null && DoubleCalc is null) { throw new ArgumentNullException(); } if (!(DecimalCalc is null) && LHS.TryLetCoerce(out decimal lhsValue) && RHS.TryLetCoerce(out decimal rhsValue)) { return(DecimalCalc(lhsValue, rhsValue).ToString(CultureInfo.InvariantCulture)); } return(DoubleCalc(LHS.AsDouble(), RHS.AsDouble()).ToString(CultureInfo.InvariantCulture)); }
private IParseTreeValue EvaluateArithmeticOp(string opSymbol, IParseTreeValue LHS, IParseTreeValue RHS) { Debug.Assert(ArithmeticOperators.Includes(opSymbol)); var opProvider = new OperatorTypesProvider((LHS.ValueType, RHS.ValueType), opSymbol); if (!(LHS.ParsesToConstantValue && RHS.ParsesToConstantValue)) { //Unable to resolve to a value, return an expression return(_valueFactory.CreateExpression($"{LHS.Token} {opSymbol} {RHS.Token}", opProvider.OperatorDeclaredType)); } if (!LHS.TryLetCoerce(opProvider.OperatorEffectiveType, out var effLHS) || !RHS.TryLetCoerce(opProvider.OperatorEffectiveType, out var effRHS)) { return(_valueFactory.CreateExpression($"{LHS.Token} {opSymbol} {RHS.Token}", opProvider.OperatorDeclaredType)); } if (opProvider.OperatorEffectiveType.Equals(Tokens.Date)) { if (!(LHS.TryLetCoerce(Tokens.Double, out effLHS) && RHS.TryLetCoerce(Tokens.Double, out effRHS))) { return(_valueFactory.CreateExpression($"{LHS.Token} {opSymbol} {RHS.Token}", opProvider.OperatorEffectiveType)); } } if (opSymbol.Equals(ArithmeticOperators.MULTIPLY)) { return(_valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => a * b, (double a, double b) => a * b), opProvider.OperatorDeclaredType)); } if (opSymbol.Equals(ArithmeticOperators.DIVIDE)) { return(_valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => a / b, (double a, double b) => a / b), opProvider.OperatorDeclaredType)); } if (opSymbol.Equals(ArithmeticOperators.INTEGER_DIVIDE)) { return(_valueFactory.CreateValueType(Calculate(effLHS, effRHS, IntDivision, IntDivision), opProvider.OperatorDeclaredType)); } if (opSymbol.Equals(ArithmeticOperators.PLUS)) { if (opProvider.OperatorEffectiveType.Equals(Tokens.String)) { return(_valueFactory.CreateValueType(Concatenate(LHS, RHS), opProvider.OperatorDeclaredType)); } if (opProvider.OperatorEffectiveType.Equals(Tokens.Date)) { var result = _valueFactory.CreateDeclaredType(Calculate(effLHS, effRHS, null, (double a, double b) => a + b), Tokens.Double); return(_valueFactory.CreateDate(result.AsDouble())); } return(_valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => a + b, (double a, double b) => a + b), opProvider.OperatorDeclaredType)); } if (opSymbol.Equals(ArithmeticOperators.MINUS)) { if (LHS.ValueType.Equals(Tokens.Date) && RHS.ValueType.Equals(Tokens.Date)) { return(_valueFactory.CreateDate(LHS.AsDouble() - RHS.AsDouble())); } return(_valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => a - b, (double a, double b) => a - b), opProvider.OperatorDeclaredType)); } if (opSymbol.Equals(ArithmeticOperators.EXPONENT)) { //Math.Pow only takes doubles, so the decimal conversion option is null return(_valueFactory.CreateValueType(Calculate(effLHS, effRHS, null, Math.Pow), opProvider.OperatorDeclaredType)); } if (opSymbol.Equals(ArithmeticOperators.MODULO)) { return(_valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => a % b, (double a, double b) => a % b), opProvider.OperatorDeclaredType)); } //ArithmeticOperators.AMPERSAND return(_valueFactory.CreateValueType(Concatenate(LHS, RHS), opProvider.OperatorDeclaredType)); }