QVariant WorkbookParserPrivate::parse() { QString expression; QModelIndex index; // TODO possibly a range of data has changed. if (pWorkbook) { index = pWorkbook->currentWorksheetView()->currentIndex(); expression = pWorkbook->currentWorksheetView()->model()->data(index).toString(); } else if (pWorksheet) { index = pWorksheet->currentIndex(); expression = pWorksheet->model()->data(index).toString(); } clearErrors(); // formulae must start with an = sign but it has no relevance later. if (expression.startsWith("=")) { QStringList tokenList = splitExpression(expression.mid(1)); tokenise(tokenList); } return QVariant(QVariant::Double); }
/*************************************************************** * Function: splitStatement() * Purpose : Convert a statement to split form * Initial : Maxime Chevalier-Boisvert on January 7, 2009 **************************************************************** Revisions and bug fixes: */ StmtSequence::StmtVector splitStatement(Statement* pStmt, ProgFunction* pFunction) { // Create a statement vector to store the converted statements StmtSequence::StmtVector stmtVector; // Switch on the statement type switch (pStmt->getStmtType()) { // Expression statement case Statement::EXPR: { // Get a typed pointer to the statement ExprStmt* pExprStmt = (ExprStmt*)pStmt; // Declare a variable to store the top-level expression created Expression* pTopExpr = NULL; // Split the expression contained in the statement splitExpression(pExprStmt->getExpression(), stmtVector, pTopExpr, pFunction); // Add a statement for the last expression stmtVector.push_back(new ExprStmt(pTopExpr, pExprStmt->getSuppressFlag())); } break; // Assignment statement case Statement::ASSIGN: { // Get a typed pointer to the statement AssignStmt* pAssignStmt = (AssignStmt*)pStmt; // Get the left expressions for this assignment const AssignStmt::ExprVector& leftExprs = pAssignStmt->getLeftExprs(); // Create a vector to store the transformed left expressions AssignStmt::ExprVector newLeftExprs; // For each left expression for (AssignStmt::ExprVector::const_iterator itr = leftExprs.begin(); itr != leftExprs.end(); ++itr) { // Declare a variable to store the last right expression Expression* pLExpr = NULL; // Split the left expression splitExpression(*itr, stmtVector, pLExpr, pFunction); // Add the expression to the list newLeftExprs.push_back(pLExpr); } // Declare a variable to store the last right expression Expression* pRExpr = NULL; // Split the right expression splitExpression(pAssignStmt->getRightExpr(), stmtVector, pRExpr, pFunction); // Create a new assignment statement for the top-level expressions stmtVector.push_back(new AssignStmt(newLeftExprs, pRExpr, pAssignStmt->getSuppressFlag())); } break; // If-else statement case Statement::IF_ELSE: { // Get a typed pointer to the statement IfElseStmt* pIfStmt = (IfElseStmt*)pStmt; // Declare a variable to store the tSequenceStmt::StmtVectorop-level test expression Expression* pTopTest = NULL; // Split the test expression bool exprSplit = splitExpression(pIfStmt->getCondition(), stmtVector, pTopTest, pFunction); // If the test expression was split if (exprSplit) { // Create a new symbol object for the test variable SymbolExpr* pTestVar = pFunction->createTemp(); // Assign the test sub-expression to the temp variable stmtVector.push_back(new AssignStmt(pTestVar, pTopTest)); // Replace the top test by the test variable pTopTest = pTestVar; } // Convert the if and else blocks to split form StmtSequence* pNewIfBlock = splitSequence(pIfStmt->getIfBlock(), pFunction); StmtSequence* pNewElseBlock = splitSequence(pIfStmt->getElseBlock(), pFunction); // Create a new if-else statement and add it to the vector stmtVector.push_back(new IfElseStmt(pTopTest, pNewIfBlock, pNewElseBlock)); } break; // Loop statement case Statement::LOOP: { // Split the loop statement and add it to the vector stmtVector.push_back(splitLoopStmt((LoopStmt*)pStmt, pFunction)); } break; // Default case, all other statement types default: { // Simply copy the statement without altering it stmtVector.push_back(pStmt->copy()); } break; } // Return the statement vector return stmtVector; }
/*************************************************************** * Function: splitExpression() * Purpose : Convert an expression to split form * Initial : Maxime Chevalier-Boisvert on January 7, 2009 **************************************************************** Revisions and bug fixes: */ bool splitExpression(Expression* pExpr, StmtSequence::StmtVector& stmtVector, Expression*& pTopExpr, ProgFunction* pFunction) { // // For each sub-expression: // - Split it recursively // - Assign top-level expression to a temp // - Replace sub-expr by temp var // // Take a temp from list to assign sub-expr to temp // Once temps are used, they become free again // // Make a copy of the expression to use as the top-level expression pTopExpr = pExpr->copy(); // If the expression is a lambda expression, perform no splitting and return early if (pTopExpr->getExprType() == Expression::ExprType::LAMBDA) return false; if (pTopExpr->getExprType() == Expression::ExprType::DOT) return false; // Get the list of sub-expressions for this expression Expression::ExprVector subExprs = pTopExpr->getSubExprs(); // If there are no sub-expressions, perform no splitting and return early if (subExprs.empty()) return false; // For each sub-expression for (size_t i = 0; i < subExprs.size(); ++i) { // Get a pointer to the sub-expression Expression* pSubExpr = subExprs[i]; // If the sub-expression is null, skip it if (pSubExpr == NULL) continue; // Declare a variable to store the top-level expression Expression* pTopSubExpr = NULL; // Split the sub-expression bool exprSplit = splitExpression(pSubExpr, stmtVector, pTopSubExpr, pFunction); // If the sub-expression was not split, skip it if (!exprSplit) continue; // If the current expression is a parameterized or // cell indexing expression and the sub-expression // is a range expressions if ((pTopExpr->getExprType() == Expression::ExprType::PARAM || pTopExpr->getExprType() == Expression::ExprType::CELL_INDEX) && pTopSubExpr->getExprType() == Expression::ExprType::RANGE) { // Replace the sub-expression by the top sub-expression directly pTopExpr->replaceSubExpr(i, pTopSubExpr); } // If the current expression is a parameterized // expression and the sub-expression is a cell-indexing // expression else if (pTopExpr->getExprType() == Expression::ExprType::PARAM && pTopSubExpr->getExprType() == Expression::ExprType::CELL_INDEX) { // Replace the sub-expression by the top sub-expression directly pTopExpr->replaceSubExpr(i, pTopSubExpr); } else { // Create a new symbol object for the temp variable SymbolExpr* pTempVar = pFunction->createTemp(); // Assign the sub-expression to the temp variable stmtVector.push_back(new AssignStmt(pTempVar, pTopSubExpr)); // Replace the sub-expression use by the temp variable pTopExpr->replaceSubExpr(i, pTempVar); } } // Expression split return true; }