/// <summary> /// Builds up an expression to compare the specified operators. /// </summary> /// <param name="left">The left operand.</param> /// <param name="right">The right operand.</param> /// <returns>The operand that wraps the built expression.</returns> public override Operand Calculate(Operand left, Operand right) { Logger.Info("Multiplying operands (left = '{0}', right = '{1}').", left.OperandType.FullName, right.OperandType.FullName); Operand result = null; var operands = new OperandPair(left, right); if (operands.Are(typeof(decimal))) { result = new Operand(Expression.MultiplyChecked(left.Expression, right.Expression), typeof(decimal)); } else { Warn("'{0}' doesn't support to multiply '{1}' and '{2}'.", GetType().FullName, left.OperandType.FullName, right.OperandType.FullName); var l = Expression.Call(null, typeof(Convert).GetMethod("ToString", new Type[] { typeof(object) }), Expression.Convert(left.Expression, typeof(object))); var r = Expression.Call(null, typeof(Convert).GetMethod("ToString", new Type[] { typeof(object) }), Expression.Convert(right.Expression, typeof(object))); var method = typeof(string).GetMethod("Concat", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(string), typeof(string), typeof(string) }, null); result = new Operand(Expression.Call(null, method, l, Expression.Constant(Symbol), r), typeof(string)); } Logger.Info("Multiplied operands (result = '{0}').", result.OperandType.FullName); return(result); }
/// <summary> /// Builds up an expression to multiply the left operand by the right operand. /// </summary> /// <param name="left">The left operand.</param> /// <param name="right">The right operand.</param> /// <returns>The operand that consists of the expression to multiply the left operand by the right operand.</returns> public override Operand Calculate(Operand left, Operand right) { Logger.Info("Subtracting operands (left = '{0}', right = '{1}').", left.OperandType.FullName, right.OperandType.FullName); Operand result = null; var operands = new OperandPair(left, right); if (operands.Are(typeof(decimal)) || operands.Are(typeof(TimeSpan)) || operands.AreStrictly(typeof(DateTime), typeof(TimeSpan)) || operands.AreStrictly(typeof(DateTimeOffset), typeof(TimeSpan))) { result = new Operand(Expression.SubtractChecked(left.Expression, right.Expression), left.OperandType); } else if (operands.Are(typeof(DateTime)) || operands.Are(typeof(DateTimeOffset))) { result = new Operand(Expression.SubtractChecked(left.Expression, right.Expression), typeof(TimeSpan)); } else { this.Warn("'{0}' doesn't support to substract '{1}' and '{2}'.", this.GetType().FullName, left.OperandType.FullName, right.OperandType.FullName); MethodCallExpression l = Expression.Call(null, typeof(Convert).GetMethod("ToString", new Type[] { typeof(object) }), Expression.Convert(left.Expression, typeof(object))); MethodCallExpression r = Expression.Call(null, typeof(Convert).GetMethod("ToString", new Type[] { typeof(object) }), Expression.Convert(right.Expression, typeof(object))); MethodInfo method = typeof(string).GetMethod("Concat", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(string), typeof(string), typeof(string) }, null); result = new Operand(Expression.Call(null, method, l, Expression.Constant(this.Symbol), r), typeof(string)); } Logger.Info("Subtracted operands (result = '{0}').", result.OperandType.FullName); return(result); }
/// <summary> /// Builds up an expression to compare the specified operators. /// </summary> /// <param name="left">The left operand.</param> /// <param name="right">The right operand.</param> /// <returns>The operand that wraps the built expression.</returns> protected internal override Expression Compare(Operand left, Operand right) { Logger.Info("Comparing operands (left = '{0}', right = '{1}').", left.OperandType.FullName, right.OperandType.FullName); Expression result = null; var operands = new OperandPair(left, right); if (operands.Are(typeof(decimal)) || operands.Are(typeof(Guid)) || operands.Are(typeof(DateTime)) || operands.Are(typeof(DateTimeOffset)) || operands.Are(typeof(TimeSpan))) { result = Expression.Equal(left.Expression, right.Expression); } else { var l = Expression.Call(null, typeof(Convert).GetMethod("ToString", new Type[] { typeof(object) }), Expression.Convert(left.Expression, typeof(object))); var r = Expression.Call(null, typeof(Convert).GetMethod("ToString", new Type[] { typeof(object) }), Expression.Convert(right.Expression, typeof(object))); if (ignoreCase) { var toLower = typeof(string).GetMethod("ToLower", BindingFlags.Instance | BindingFlags.Public, null, new Type[] { }, null); return(Expression.Equal(Expression.Call(l, toLower), Expression.Call(r, toLower))); } else { result = Expression.Equal(l, r); } } return(result); }
/// <summary> /// Builds up an expression to divide the left operand by the right operand. /// </summary> /// <param name="left">The left operand.</param> /// <param name="right">The right operand.</param> /// <returns>The operand that consists of the expression to divide the left operand by the right operand.</returns> public override Operand Calculate(Operand left, Operand right) { Logger.Info("Dividing operands (left = '{0}', right = '{1}').", left.OperandType.FullName, right.OperandType.FullName); Operand result = null; var operands = new OperandPair(left, right); if (operands.Are(typeof(decimal))) { result = new Operand(Expression.Divide(left.Expression, right.Expression), typeof(decimal)); } else { Warn("'{0}' doesn't support to divide '{1}' and '{2}'.", GetType().FullName, left.OperandType.FullName, right.OperandType.FullName); var l = Expression.Call(null, typeof(Convert).GetMethod("ToString", new Type[] { typeof(object) }), Expression.Convert(left.Expression, typeof(object))); var r = Expression.Call(null, typeof(Convert).GetMethod("ToString", new Type[] { typeof(object) }), Expression.Convert(right.Expression, typeof(object))); var method = typeof(string).GetMethod("Concat", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(string), typeof(string), typeof(string) }, null); result = new Operand(Expression.Call(null, method, l, Expression.Constant(Symbol), r), typeof(string)); } Logger.Info("Divided operands (result = '{0}').", result.OperandType.FullName); return result; }
/// <summary> /// Builds up an expression to compare the specified operators. /// </summary> /// <param name="left">The left operand.</param> /// <param name="right">The right operand.</param> /// <returns>The operand that wraps the built expression.</returns> protected internal override Expression Compare(Operand left, Operand right) { Logger.Info("Comparing operands (left = '{0}', right = '{1}').", left.OperandType.FullName, right.OperandType.FullName); Expression result = null; var operands = new OperandPair(left, right); if (operands.Are(typeof(decimal)) || operands.Are(typeof(DateTime)) || operands.Are(typeof(DateTimeOffset)) || operands.Are(typeof(TimeSpan))) { result = Expression.GreaterThanOrEqual(left.Expression, right.Expression); } else { this.Warn("'{0}' doesn't support to compare '{1}' and '{2}'.", this.GetType().FullName, left.OperandType.FullName, right.OperandType.FullName); result = Expression.Constant(false); } return(result); }