public static double loadAndCalculate(string data, ref int from, char to = END_LINE) { if (from >= data.Length || data[from] == to) { throw new ArgumentException("Loaded invalid data: " + data); } List <Cell> listToMerge = new List <Cell>(16); StringBuilder item = new StringBuilder(); do { // Main processing cycle of the first part. char ch = data[from++]; if (stillCollecting(item.ToString(), ch, to)) { // The char still belongs to the previous operand. item.Append(ch); if (from < data.Length && data[from] != to) { continue; } } // We are done getting the next token. The getValue() call below may // recursively call loadAndCalculate(). This will happen if extracted // item is a function or if the next item is starting with a START_ARG '('. ParserFunction func = new ParserFunction(data, ref from, item.ToString(), ch); double value = func.getValue(data, ref from); char action = validAction(ch) ? ch : updateAction(data, ref from, ch, to); listToMerge.Add(new Cell(value, action)); item.Clear(); } while (from < data.Length && data[from] != to); if (from < data.Length && (data[from] == END_ARG || data[from] == to)) { // This happens when called recursively: move one char forward. from++; } Cell baseCell = listToMerge[0]; int index = 1; return(merge(baseCell, ref index, listToMerge)); }