/// <summary>
        /// Detects operation
        /// </summary>
        /// <param name="s">First symbol of the formula</param>
        /// <returns>Acceptor of operation</returns>
        public IOperationAcceptor Detect(MathSymbol s)
        {
            IOperationAcceptor acc = detector.Detect(s);

            if (acc == null)
            {
                return(null);
            }
            if (acc is IMultiVariableOperationAcceptor)
            {
                return(new MultiVariableArrayOperationAcceptor(acc as IMultiVariableOperationAcceptor));
            }
            return(new ArrayOperationAcceptor(acc));
        }
Esempio n. 2
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);
        }