예제 #1
0
        /// <summary>
        /// Accepts operation
        /// </summary>
        /// <param name="type">Argument type</param>
        /// <returns>The operation</returns>
        public IObjectOperation Accept(object type)
        {
            IObjectOperation ownOp = acceptor.Accept(type);

            if (ownOp != null)
            {
                return(ownOp);
            }
            if (type is ArrayReturnType)
            {
                ArrayReturnType a = type as ArrayReturnType;
                if (a.IsObjectType)
                {
                    IObjectOperation op = acceptor.Accept(a.ElementType);
                    if (op == null)
                    {
                        return(null);
                    }
                    IObjectOperation dop = GetDynamicalOperation(a, op);
                    if (dop != null)
                    {
                        return(dop);
                    }
                    return(new ArrayOperation(op, new object[] { type }));
                }
            }
            IObjectOperation ope = acceptor.Accept(type);

            if (ope != null)
            {
                return(ope);
            }
            if (type is ArrayReturnType)
            {
                ArrayReturnType  a  = type as ArrayReturnType;
                IObjectOperation op = acceptor.Accept(a.ElementType);
                if (op == null)
                {
                    return(null);
                }
                IObjectOperation dop = GetDynamicalOperation(a, op);
                if (dop != null)
                {
                    return(dop);
                }
                return(new ArrayOperation(op, new object[] { type }));
            }
            return(null);
        }
        /// <summary>
        /// Implements the Visitor design pattern.
        /// </summary>
        /// <param name="acceptor">
        /// The object accepting this operation.
        /// </param>
        public override void Visit(IOperationAcceptor acceptor)
        {
            Guard.NotNull(acceptor, nameof(acceptor));

            acceptor.Accept(this);
        }
예제 #3
0
        /// <summary>
        /// Implements the Visitor design pattern.
        /// </summary>
        /// <param name="acceptor">
        /// The object accepting this operation.
        /// </param>
        public override void Visit(IOperationAcceptor acceptor)
        {
            Guard.NotNull(acceptor, nameof(acceptor));

            acceptor.Accept(this);
        }
예제 #4
0
        /// <summary>
        /// Processes ordinary operation
        /// </summary>
        /// <param name="formula">Formula</param>
        /// <param name="creator">Formula creator</param>
        /// <returns>True if operation exists and false otherwise</returns>
        protected bool processOperation(MathFormula formula, IFormulaObjectCreator creator)
        {
            int braCount           = 0;
            ObjectFormulaTree tree = null;

            for (int i = 0; i < creator.OperationCount; i++)
            {
                IOperationDetector detector = creator.GetDetector(i);
                IOperationAcceptor acceptor = detector.Detect(formula[braCount]);
                if (acceptor == null)
                {
                    continue;
                }
                TypeInfo dt = detector.ToTypeInfo();
                TreeTransformationAttribute attr = detector.GetAttribute <TreeTransformationAttribute>();
                if (attr != null)
                {
                    ITreeTransformation trans = acceptor as ITreeTransformation;
                    if (tree == null)
                    {
                        tree = CreateTree(new MathFormula(formula, 2 * braCount + 1, formula.Count - 1), creator);
                    }
                    if (tree != null)
                    {
                        ObjectFormulaTree tr = trans.Transform(tree);
                        if (tr != null)
                        {
                            operation = tr.operation;
                            children  = tr.children;
                            y         = tr.y;
                            return(true);
                        }
                    }
                }
                object type = null;
                if (formula.Count > 1)
                {
                    if (tree == null)
                    {
                        tree = CreateTree(new MathFormula(formula, 2 * braCount + 1, formula.Count - 1), creator);
                    }
                    type = tree.ReturnType;
                }
                if (acceptor is IMultiVariableOperationAcceptor)
                {
                    IMultiVariableOperationAcceptor ma      = acceptor as IMultiVariableOperationAcceptor;
                    IMultiVariableOperation         multiOp = ma.AcceptOperation(formula[0]);
                    MathSymbol          s     = formula[0];
                    ObjectFormulaTree[] trees = null;
                    object[]            types = null;
                    if (s.HasChildren)
                    {
                        int n = 0;
                        for (int j = 0; j < s.Count; j++)
                        {
                            if (s[j] != null)
                            {
                                if (!s[j].IsEmpty)
                                {
                                    ++n;
                                }
                            }
                        }
                        trees = new ObjectFormulaTree[n];
                        types = new object[n];
                        n     = 0;
                        for (int j = 0; j < s.Count; j++)
                        {
                            if (s[j] != null)
                            {
                                if (!s[j].IsEmpty)
                                {
                                    ObjectFormulaTree tr = CreateTree(s[j], creator);
                                    if (tr == null)
                                    {
                                        operation = null;
                                        goto mo;
                                    }
                                    trees[j] = tr;
                                    types[j] = trees[j].ReturnType;
                                    ++n;
                                }
                            }
                        }
                    }
                    operation = multiOp.Accept(types);
mo:
                    if (operation == null)
                    {
                        continue;
                    }
                    y = new object[types.Length];
                    if (trees != null)
                    {
                        foreach (ObjectFormulaTree t in trees)
                        {
                            if (t != null)
                            {
                                children.Add(t);
                            }
                        }
                    }
                    return(true);
                }
                IObjectOperation op = acceptor.Accept(type);
                if (op != null)
                {
                    if (op.IsPowered())
                    {
                        if (formula.First.HasChildren)
                        {
                            ObjectFormulaTree pow = CreateTree(formula.First[0], creator);
                            ObjectFormulaTree val = new ObjectFormulaTree();
                            val.operation = op;
                            val.y         = new object[op.InputTypes.Length];
                            val.CreateResult();
                            if (tree != null)
                            {
                                val.children.Add(tree);
                            }
                            IObjectOperation powOp = creator.GetPowerOperation(val.ReturnType, pow.ReturnType);
                            if (powOp == null)
                            {
                                return(false);
                            }
                            operation = powOp;
                            children.Add(val);
                            children.Add(pow);
                            y = new object[2];
                            return(true);
                        }
                    }
                    operation = op;
                    if (tree != null)
                    {
                        children.Add(tree);
                        y = new object[1];
                    }
                    return(true);
                }
            }
            return(false);
        }