/// <summary> /// Reduces the expression node to a simpler expression. /// </summary> /// <returns>The reduced expression.</returns> public override Expression Reduce() { var functionalOp = new Func <Expression, Expression>(lhs => { var operation = default(ExpressionType); switch (OperationNodeType) { case CSharpExpressionType.PreIncrementAssign: case CSharpExpressionType.PreIncrementAssignChecked: case CSharpExpressionType.PostIncrementAssign: case CSharpExpressionType.PostIncrementAssignChecked: operation = ExpressionType.Increment; break; case CSharpExpressionType.PreDecrementAssign: case CSharpExpressionType.PreDecrementAssignChecked: case CSharpExpressionType.PostDecrementAssign: case CSharpExpressionType.PostDecrementAssignChecked: operation = ExpressionType.Decrement; break; default: throw ContractUtils.Unreachable; } var args = new[] { CSharpArgumentInfo.Create(Operand.Flags, null) }; var binder = Binder.UnaryOperation(Flags, operation, Context, args); var dynamic = DynamicHelpers.MakeDynamic(typeof(object), binder, new[] { lhs }, new[] { lhs.Type }); // NB: no conversion needed in the unary case return(dynamic); }); var flags = Flags | CSharpBinderFlags.ValueFromCompoundAssignment; var res = DynamicHelpers.ReduceDynamicAssignment(Operand, functionalOp, flags, IsPrefix); return(res); }
private Expression ReduceCore(DynamicCSharpArgument left) { var functionalOp = new Func <Expression, Expression>(lhs => { var operation = default(ExpressionType); switch (OperationNodeType) { case CSharpExpressionType.AddAssign: case CSharpExpressionType.AddAssignChecked: operation = ExpressionType.AddAssign; break; case CSharpExpressionType.SubtractAssign: case CSharpExpressionType.SubtractAssignChecked: operation = ExpressionType.SubtractAssign; break; case CSharpExpressionType.MultiplyAssign: case CSharpExpressionType.MultiplyAssignChecked: operation = ExpressionType.MultiplyAssign; break; case CSharpExpressionType.DivideAssign: operation = ExpressionType.DivideAssign; break; case CSharpExpressionType.ModuloAssign: operation = ExpressionType.ModuloAssign; break; case CSharpExpressionType.AndAssign: operation = ExpressionType.AndAssign; break; case CSharpExpressionType.OrAssign: operation = ExpressionType.OrAssign; break; case CSharpExpressionType.ExclusiveOrAssign: operation = ExpressionType.ExclusiveOrAssign; break; case CSharpExpressionType.LeftShiftAssign: operation = ExpressionType.LeftShiftAssign; break; case CSharpExpressionType.RightShiftAssign: operation = ExpressionType.RightShiftAssign; break; default: throw ContractUtils.Unreachable; } var args = new[] { CSharpArgumentInfo.Create(GetArgumentInfoFlags(Left), null), CSharpArgumentInfo.Create(GetArgumentInfoFlags(Right), null), }; var binder = Binder.BinaryOperation(Flags, operation, Context, args); var dynamic = DynamicHelpers.MakeDynamic(typeof(object), binder, new[] { lhs, Right.Expression }, new[] { lhs.Type, Right.Expression.Type }); var leftType = Left.Expression.Type; if (leftType != dynamic.Type) { var convert = Binder.Convert(CSharpBinderFlags.ConvertExplicit, leftType, Context); dynamic = DynamicHelpers.MakeDynamic(leftType, convert, new[] { dynamic }, null); } return(dynamic); }); var flags = Flags | CSharpBinderFlags.ValueFromCompoundAssignment; var res = DynamicHelpers.ReduceDynamicAssignment(left, functionalOp, flags); return(res); }