AK.ExpressionSolver.SymbolicateValue C# (CSharp) Method

SymbolicateValue() private method

private SymbolicateValue ( string formula, int begin, int end, Expression exp ) : Symbol
formula string
begin int
end int
exp Expression
return Symbol
        Symbol SymbolicateValue(string formula, int begin, int end, Expression exp)
        {
            if (formula[begin] == '+')
            {
                begin++;
            }

            // Check for string value
            if (formula[begin] == '\'' && formula[end - 1] == '\'')
            {
                var svalue = formula.Substring(begin+1,end-begin-2).Replace("\\'","'");
                return new Symbol(svalue);
            }

            int depth=0;
            for (int k = begin; k < end; k++)
            {
                if (formula[k]=='(')
                    depth++;
                else if (formula[k]==')')
                    depth--;
                else if (depth == 0 && formula[k] == '^')
                {
                    // Check for small integer powers: they will be done using multiplication instead!
                    Symbol lhs = Symbolicate(formula,begin,k,exp);
                    Symbol rhs = Symbolicate(formula,k+1,end,exp);
                    var newSubExpression = new SymbolList();
                    if (end-k-1 == 1 && lhs.type == SymbolType.RealValue && formula.Substring(k+1,end-k-1)=="2")
                    {
                        // Second power found
                        newSubExpression.Append(lhs);
                        newSubExpression.Append(lhs);
                    }
                    else if (end-k-1 == 1 && lhs.type == SymbolType.RealValue && formula.Substring(k+1,end-k-1)=="3")
                    {
                        // Second power found
                        newSubExpression.Append(lhs);
                        newSubExpression.Append(lhs);
                        newSubExpression.Append(lhs);
                    }
                    else
                    {
                        newSubExpression.Append(new Symbol(SymbolType.Pow));
                        newSubExpression.Append(lhs);
                        newSubExpression.Append(rhs);
                    }
                    Symbol newSymbol = new Symbol(SymbolType.SubExpression);
                    newSymbol.subExpression = newSubExpression;
                    return newSymbol;
                }
            }

            if (formula[begin] == '(' && formula[end - 1] == ')')
            {
                var s = Symbolicate(formula, begin + 1, end - 1,exp);
                s.Simplify();
                return s;
            }

            double valueAsRealNumber;
            if (double.TryParse(formula.Substring(begin,end-begin),out valueAsRealNumber))
            {
                return new Symbol(valueAsRealNumber);
            }

            // Check if the value is transformed by a function
            if (formula[end-1]==')') {
                int i = begin;
                while (i < end-1) {
                    if (formula[i]=='(') {
                        break;
                    }
                    i++;
                }

                string funcName = formula.Substring(begin,i-begin);
                CustomFunction customFunc;
                if (customFuncs.TryGetValue(funcName,out customFunc))
                {
                    int requiredParameterCount = customFunc.paramCount;
                    int foundParameterCount = SolverTools.CountParameters(formula,begin,end);
                    if (requiredParameterCount == foundParameterCount) {
                        if (requiredParameterCount == 1) {
                            SymbolList newSubExpression = new SymbolList();
                            newSubExpression.Append(new Symbol(customFunc));
                            newSubExpression.Append(Symbolicate(formula,i+1,end-1,exp));
                            return new Symbol(newSubExpression);
                        }
                        else {
                            List<SolverTools.IntPair> parameters = SolverTools.ParseParameters(formula,i,end);
                            SymbolList newSubExpression = new SymbolList();
                            newSubExpression.Append(new Symbol(customFunc));
                            for (int k=0;k<requiredParameterCount;k++) {
                                Symbol p = Symbolicate(formula,parameters[k].first,parameters[k].second,exp);
                                newSubExpression.Append(p);
                            }

                            Symbol newSymbol = new Symbol(SymbolType.SubExpression);
                            newSymbol.subExpression = newSubExpression;
                            return newSymbol;

                        }
                    }
                    else
                    {
                        throw new ESInvalidParametersException(customFunc.name + " expects " + requiredParameterCount + " parameters, " + foundParameterCount + " given.");
                    }
                }
                else
                {
                    throw new ESInvalidFunctionNameException(funcName);
                }
            }

            var valueName = formula.Substring(begin,end-begin);

            // Then a local constant specific to our expression
            Variable variable;
            if (exp.constants.TryGetValue(valueName,out variable)) {
                return new Symbol(variable);
            }

            // Non immutable globals
            if (globalConstants.TryGetValue(valueName,out variable)) {
                return new Symbol(variable);
            }

            // Immutable globals
            double constDouble;
            if (immutableGlobalConstants.TryGetValue(valueName, out constDouble))
            {
                return new Symbol(constDouble);
            }

            // Found an unknown value name. Check policy to see what to do.
            Variable v = null;
            switch (undefinedVariablePolicy)
            {
                case UndefinedVariablePolicy.DefineExpressionLocalVariable:
                    v = new Variable(valueName,0);
                    exp.constants.Add(valueName,v);
                    return new Symbol(v);
                case UndefinedVariablePolicy.DefineGlobalVariable:
                    v = new Variable(valueName,0);
                    globalConstants.Add(valueName,v);
                    return new Symbol(v);
                default:
                    throw new ESUnknownExpressionException(valueName);
            }
        }