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);
        }
示例#2
0
 protected VisitResult VisitNegate(NegateOperation operation)
 {
     return(VisitUnary(Expression.Negate, operation));
 }
示例#3
0
文件: Calculator.cs 项目: jbvera/WOS
        /// <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);
            }
        }