QPair<int, double> WorkbookParserPrivate::calculateInfix(int start, QStringList items) { int i = start; bool ok; qreal d, n1, n2; QStack<qreal> values; QStack<OperatorBase<qreal>*> operators; QPair<int, double> result; // TODO add in errors ie unbalanced brackets wrong number // of values or operators // TODO handle cell references and ranges. while(i < items.size()) { QString s = items.at(i); if (s == ")") { result.first = i + 1; result.second = values.pop(); return result; } if (s == "(") { i++; result = calculateInfix(i, items); // Recurse. i = result.first; values.push(result.second); continue; } d = s.toDouble(&ok); if (ok) { values.insert(i++, d); continue; } // turns constants into their actual value in the list. ConstantBase *constant = dynamic_cast<ConstantBase*>(pPluginStore->getConstant(s)); if (constant) { values.insert(i++, constant->value()); continue; } IFunction *func = dynamic_cast<IFunction*>(pPluginStore->getFunction(s)); if (func) { result = calculateInfixFunction(func, i, items); // functioss should return a value. i = result.first; values.push(result.second); continue; } OperatorBase<qreal> *op1 = dynamic_cast<OperatorBase<qreal>*>(pPluginStore->getOperator(s)); if (op1) { if (operators.size() == 0 || operators.top()->level() < op1->level()) { OperatorBase<qreal> *op2 = operators.pop(); n1 = values.pop(); n2 = values.pop(); d = op2->calculate(n2, n1); values.push(d); } operators.push(op1); i++; continue; } // TODO string handling // OperatorBase<QString> *ops1 = dynamic_cast<OperatorBase<QString>*>(pPluginStore->getOperator(s)); // if (op1) { // // convert numbers to strings if necessary // } } return result; }