public override HlslTreeNode Reduce() { var factor1 = Factor1.Reduce(); var factor2 = Factor2.Reduce(); var constant1 = factor1 as ConstantNode; var constant2 = factor2 as ConstantNode; if (constant1 != null) { float value1 = constant1.Value; if (value1 == 0) { Replace(factor1); return(factor1); } if (value1 == 1) { Replace(factor2); return(factor2); } if (value1 == -1) { var negation = new NegateOperation(factor2); Replace(negation); return(negation); } if (constant2 != null) { return(new ConstantNode(value1 * constant2.Value)); } // TODO: Replace with division by x only if dividend is an addition of x addends /* * if (IsFractional(value1)) * { * ConstantNode divisor = new ConstantNode(1 / value1); * var division = new DivisionOperation(factor2, divisor); * Replace(division); * return division; * } */ } if (constant2 != null) { float value2 = constant2.Value; if (value2 == 0) { Replace(factor2); return(factor2); } if (value2 == 1) { Replace(factor1); return(factor1); } if (value2 == -1) { var negation = new NegateOperation(factor1); Replace(negation); return(negation); } // TODO: Replace with division by x only if dividend is an addition of x addends /* * if (IsFractional(value2)) * { * ConstantNode divisor = new ConstantNode(1 / value2); * var division = new DivisionOperation(factor1, divisor); * Replace(division); * return division; * } */ } if (factor1 is DivisionOperation reciprocalDivision) { if (reciprocalDivision.Dividend is ConstantNode one && one.Value == 1) { var division = new DivisionOperation(factor2, reciprocalDivision.Divisor); Replace(division); return(division); } } Inputs[0] = factor1; Inputs[1] = factor2; return(this); }
protected VisitResult VisitNegate(NegateOperation operation) { return(VisitUnary(Expression.Negate, operation)); }
/// <summary> /// Calls the IOperation that corresponds to the input OperationType /// </summary> /// <param name="operationType">The operation to perform.</param> public void PerformOperation(OperationType operationType) { IOperation operation = null; switch (operationType) { case OperationType.Add: operation = new AddOperation(); break; case OperationType.Minus: operation = new MinusOperation(); break; case OperationType.Multiply: operation = new MultiplyOperation(); break; case OperationType.Divide: operation = new DivideOperation(); break; case OperationType.Negate: operation = new NegateOperation(); break; case OperationType.SquareRoot: operation = new SquareRootOperation(); break; case OperationType.Exponential: operation = new ExponentialOperation(); break; case OperationType.Power: operation = new PowerOperation(); break; case OperationType.Reciprocal: operation = new ReciprocalOperation(); break; case OperationType.Sine: operation = new SineOperation(); break; case OperationType.Cosine: operation = new CosineOperation(); break; case OperationType.Clear: operation = new ClearOperation(); break; case OperationType.Swap: operation = new SwapOperation(); break; case OperationType.Rotate: operation = new RotateOperation(); break; } if (operation != null) { /* * Exception handling is done within each class that implements IOperation. * Refactoring to multiple operation types (e.g. BinaryOperation, * UnaryOperation, and StackOperation) can make the code DRYer as each type * can use similar exception handling. */ operation.Perform(stack); } }