/// <summary> /// Constructor /// </summary> /// <param name="creator">Base formula creator</param> public FormulaArrayObjectCreator(IFormulaObjectCreator creator) { this.creator = creator; for (int i = 0; i < creator.BinaryCount; i++) { binary.Add(new BinaryArrayOperationDetector(creator.GetBinaryDetector(i))); } for (int i = 0; i < creator.MultiOperationCount; i++) { multi.Add(new MultiArrayOperationDetector(creator.GetMultiOperationDetector(i))); } for (int i = 0; i < creator.OperationCount; i++) { IOperationDetector d = creator.GetDetector(i); TypeInfo dt = d.ToTypeInfo(); TreeTransformationAttribute da = dt.GetAttribute <TreeTransformationAttribute>(); if (da != null) { detectors.Add(d); goto detectorSelected; } detectors.Add(new ArrayOperationDetector(d)); detectorSelected: continue; } detectors.Add(ArraySingleDetector.Object); }
/// <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); }