示例#1
0
        public static bool TryParse(string value, out ConstFunction func)
        {
            long outL;

            if (long.TryParse(value, out outL))
            {
                func = new ConstFunction(outL, FunctionType.Long);
                return(true);
            }

            double outD;

            value = value.Replace('.', CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0]);
            value = value.Replace(',', CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0]);

            if (double.TryParse(value, out outD))
            {
                func = new ConstFunction(outD, FunctionType.Double);
                return(true);
            }

            func = null;
            return(false);
        }
示例#2
0
        public static IFunction GenerateFunction(string src, IDictionary <string, IFunction> knownVars, out ErrorSyntax error)
        {
            error = ErrorSyntax.None;

            #region ClearSrc
            if (EmptySrc(src, out error))
            {
                return(null);
            }

            src = new string((from ch in src where (Operators.Contains(ch) || Numbers.Contains(ch) || Letters.Contains(ch)) select ch).ToArray());

            if (EmptySrc(src, out error))
            {
                return(null);
            }
            #endregion

            #region SeparateSrcInArgs
            ArrayList args          = new ArrayList();
            int       startArgIndex = 0;

            for (int i = 0; i < src.Length; i++)
            {
                int operatorIndex = Operators.IndexOf(src[i]);

                if (operatorIndex > -1)
                {
                    if (startArgIndex != i)
                    {
                        if (args.Count > 0 && args [args.Count - 1].Equals(Operation.CloseBracket))
                        {
                            args.Add(Operation.Multiply);
                        }

                        args.Add(src.Substring(startArgIndex, i - startArgIndex));

                        if ((Operation)operatorIndex == Operation.OpenBracket)
                        {
                            args.Add(Operation.Multiply);
                        }
                    }
                    else
                    {
                        if ((Operation)operatorIndex == Operation.OpenBracket && args.Count > 0 && args [args.Count - 1].Equals(Operation.CloseBracket))
                        {
                            args.Add(Operation.Multiply);
                        }
                    }

                    args.Add((Operation)operatorIndex);

                    startArgIndex = i + 1;

                    continue;
                }

                if (i == src.Length - 1)
                {
                    i++;

                    if (args.Count > 0 && args[args.Count - 1].Equals(Operation.CloseBracket))
                    {
                        args.Add(Operation.Multiply);
                    }
                    args.Add(src.Substring(startArgIndex, i - startArgIndex));
                    break;
                }
            }
            #endregion

            #region FindSimpleFunctions
            for (int i = args.Count - 1; i > -1; i--)
            {
                if (args[i] is string)
                {
                    var name = (string)args [i];

                    ConstFunction cFunc;

                    if (ConstFunction.TryParse(name, out cFunc))
                    {
                        args[i] = cFunc;
                        continue;
                    }

                    IFunction func;
                    var       knownFunc = knownVars.TryGetValue(name, out func);

                    if (knownFunc)
                    {
                        if (func is ArgumentableFunctionsBase)
                        {
                            int closeIndex = FindCloseBracket(args, i + 2);

                            CollapseArgumentFunctions(args, i + 2, ref closeIndex, out error);
                            if (error != ErrorSyntax.None)
                            {
                                return(null);
                            }

                            var Range = args.GetRange(i + 3, closeIndex - i - 3).ToArray();

                            var no = new ArgumentableFunctionsRuntime((ArgumentableFunctionsBase)func, (from x in Range select(IFunction) x).ToArray());

                            args.RemoveRange(i, closeIndex + 1 - i);
                            args.Insert(i, no);
                        }

                        if (func is NonargumentableFunction)
                        {
                            args [i] = func;
                        }
                    }
                }
            }
            #endregion

            #region SetFuncsArgs
            if (args.Count > 2 && args[0] is string && args[1].Equals(Operation.Multiply) && args[2].Equals(Operation.OpenBracket))
            {
                int closeBracketInd = FindCloseBracket(args, 2);

                if (closeBracketInd < 0)
                {
                    error = ErrorSyntax.NotFoundCloseBracket;
                    return(null);
                }

                string[] funcArgsNames = new string[(closeBracketInd - 2) >> 1];

                if (funcArgsNames.Length < 1)
                {
                    error = ErrorSyntax.EmptyArgsForFunction;
                    return(null);
                }

                int counter = 0;

                for (int i = 3; i < closeBracketInd; i += 2)
                {
                    if (!(args[i] is string || args[i] is IFunction))
                    {
                        error = ErrorSyntax.InvalidArgsStruct;
                        return(null);
                    }

                    funcArgsNames[counter] = /*(string)*/ (args[i] is string?(string)args[i] : ((IFunction)args[i]).Name);
                    counter++;
                }

                var argumentableFunc = new ArgumentableFunctionsBase((string)args[0], null, funcArgsNames);

                foreach (var argName in funcArgsNames)
                {
                    var argFunc = new ArgumentFunction(argName, argumentableFunc);

                    for (int i = 0; i < args.Count; i++)
                    {
                        if (args[i].Equals(argName) || (args[i] is IFunction && ((IFunction)args[i]).Name == argName))
                        {
                            args[i] = argFunc;
                        }
                    }
                }

                args.RemoveRange(0, closeBracketInd + 1);
                args.Insert(0, argumentableFunc);
            }
            #endregion

            #region CollapseAllInOneFunction

            var count = args.Count - 1;

            CollapseArray(args, 0, ref count, out error);
            if (error != ErrorSyntax.None)
            {
                return(null);
            }
            #endregion

            #region SetNameForFinalFunction
            IFunction finalFunction = null;

            if (args[0] is ArgumentableFunctionsBase)
            {
                ((ArgumentableFunctionsBase)args[0]).CalcFunction = (IFunction)args[2];
                finalFunction = (IFunction)args[0];
            }
            else
            if (args.Count == 3)
            {
                if (args[1].Equals(Operation.Equal))
                {
                    ((IFunction)args[2]).Rename((args[0] is string) ? (string)args[0] : ((IFunction)args[0]).Name);
                    finalFunction = new NonargumentableFunction((IFunction)args[2]);
                    finalFunction.Rename(((IFunction)args[2]).Name);
                }
            }
            else
            {
                if (args.Count == 1)
                {
                    ((IFunction)args[0]).Rename(null);
                    finalFunction = (IFunction)args[0];
                }
            }
            #endregion

            if (finalFunction == null)
            {
                error = ErrorSyntax.FunctionIsNotCollapsed;
            }

            return(finalFunction);
        }