/*************************************************************** * Function: CodeParser::parseStmtList() * Purpose : Parse the XML code of a statement list * Initial : Maxime Chevalier-Boisvert on November 7, 2008 **************************************************************** Revisions and bug fixes: */ StmtSequence* CodeParser::parseStmtList(const XML::Element* pElement) { // Create a statement vector to store the statements StmtSequence::StmtVector stmtVector; // For each child element for (size_t i = 0; i < pElement->getNumChildren(); ++i) { // Get this child element XML::Element* pChildElement = pElement->getChildElement(i); // If this is a variable declaration if (pChildElement->getName() == "VariableDecl") { // Ignore for now continue; } // Parse this statement Statement* pStmt = parseStatement(pChildElement); // Add the statement to the vector stmtVector.push_back(pStmt); } // Return a new sequence statement return new StmtSequence(stmtVector); }
/*************************************************************** * Function: processEndExpr(StmtSequence*) * Purpose : Pre-process range end expressions in sequences * Initial : Maxime Chevalier-Boisvert on March 1, 2009 **************************************************************** Revisions and bug fixes: */ StmtSequence* processEndExpr(StmtSequence* pSeq, ProgFunction* pFunction) { // Get a reference to the statement vector const StmtSequence::StmtVector& seqStmts = pSeq->getStatements(); // Create a statement vector to store the transformed output StmtSequence::StmtVector output; // For each statement in the sequence for (StmtSequence::StmtVector::const_iterator stmtItr = seqStmts.begin(); stmtItr != seqStmts.end(); ++stmtItr) { // Get a pointer to the statement Statement* pStmt = *stmtItr; // Switch on the statement type switch (pStmt->getStmtType()) { // Expression statement case Statement::EXPR: { // Get a typed pointer to the statement ExprStmt* pExprStmt = (ExprStmt*)pStmt; // Transform the expression output.push_back( new ExprStmt( processEndExpr(pExprStmt->getExpression(), pFunction), pExprStmt->getSuppressFlag() ) ); } break; // Assignment statement case Statement::ASSIGN: { // Get a typed pointer to the statement AssignStmt* pAssignStmt = (AssignStmt*)pStmt; // Get a reference to the left expressions const AssignStmt::ExprVector& leftExprs = pAssignStmt->getLeftExprs(); // Create a vector for the transformed left-expressions AssignStmt::ExprVector newLExprs; // Transform the left-side expressions for (AssignStmt::ExprVector::const_iterator itr = leftExprs.begin(); itr != leftExprs.end(); ++itr) newLExprs.push_back(processEndExpr(*itr, pFunction)); // Transform the right-side expression Expression* pRightExpr = processEndExpr(pAssignStmt->getRightExpr(), pFunction); // Create and return the transformed assignment statement object output.push_back(new AssignStmt(newLExprs, pRightExpr, pAssignStmt->getSuppressFlag())); } break; // If-else statement case Statement::IF_ELSE: { // Get a typed pointer to the statement IfElseStmt* pIfStmt = (IfElseStmt*)pStmt; // Transform the statement output.push_back( new IfElseStmt( processEndExpr(pIfStmt->getCondition(), pFunction), processEndExpr(pIfStmt->getIfBlock(), pFunction), processEndExpr(pIfStmt->getElseBlock(), pFunction) ) ); } break; // Loop statement case Statement::LOOP: { // Get a typed pointer to the statement LoopStmt* pLoopStmt = (LoopStmt*)pStmt; // Transform the expression output.push_back( new LoopStmt( pLoopStmt->getIndexVar()? pLoopStmt->getIndexVar()->copy():NULL, pLoopStmt->getTestVar()? pLoopStmt->getTestVar()->copy():NULL, processEndExpr(pLoopStmt->getInitSeq(), pFunction), processEndExpr(pLoopStmt->getTestSeq(), pFunction), processEndExpr(pLoopStmt->getBodySeq(), pFunction), processEndExpr(pLoopStmt->getIncrSeq(), pFunction), pLoopStmt->getAnnotations() ) ); } break; // For all other statement types default: { // Copy the statement and add it to the output output.push_back(pStmt->copy()); } } } // Return the transformed output return new StmtSequence(output); }
/*************************************************************** * 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; }
/*************************************************************** * Function: transformLoops() * Purpose : Expand logical operators in a statement sequence * Initial : Maxime Chevalier-Boisvert on January 14, 2009 **************************************************************** Revisions and bug fixes: */ StmtSequence* transformLogic(StmtSequence* pSeq, ProgFunction* pFunction) { // Get a reference to the statement vector const StmtSequence::StmtVector& seqStmts = pSeq->getStatements(); // Create a statement vector to store the transformed output StmtSequence::StmtVector output; // For each statement in the sequence for (StmtSequence::StmtVector::const_iterator stmtItr = seqStmts.begin(); stmtItr != seqStmts.end(); ++stmtItr) { // Get a pointer to the statement Statement* pStmt = *stmtItr; // Switch on the statement type switch (pStmt->getStmtType()) { // Expression statement case Statement::EXPR: { // Get a typed pointer to the statement ExprStmt* pExprStmt = (ExprStmt*)pStmt; // Transform the expression Expression* pNewExpr = transformLogicExpr(pExprStmt->getExpression(), output, pFunction); // Create a new expression statement output.push_back(new ExprStmt(pNewExpr, 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) newLeftExprs.push_back(transformLogicExpr(*itr, output, pFunction)); // Transform the right expression Expression* pNewRExpr = transformLogicExpr(pAssignStmt->getRightExpr(), output, pFunction); // Create a new assignment statement output.push_back(new AssignStmt(newLeftExprs, pNewRExpr, pAssignStmt->getSuppressFlag())); } break; // If-else statement case Statement::IF_ELSE: { // Get a typed pointer to the statement IfElseStmt* pIfStmt = (IfElseStmt*)pStmt; // Transform the test expression Expression* pNewTest = transformLogicExpr(pIfStmt->getCondition(), output, pFunction); // Convert the if and else blocks to split form StmtSequence* pNewIfBlock = transformLogic(pIfStmt->getIfBlock(), pFunction); StmtSequence* pNewElseBlock = transformLogic(pIfStmt->getElseBlock(), pFunction); // Create a new if-else statement and add it to the vector output.push_back(new IfElseStmt(pNewTest, pNewIfBlock, pNewElseBlock)); } break; // Loop statement case Statement::LOOP: { // Get a typed pointer to the statement LoopStmt* pLoopStmt = (LoopStmt*)pStmt; // Transform the statement sequences of the loop StmtSequence* pNewInitSeq = transformLogic(pLoopStmt->getInitSeq(), pFunction); StmtSequence* pNewTestSeq = transformLogic(pLoopStmt->getTestSeq(), pFunction); StmtSequence* pNewBodySeq = transformLogic(pLoopStmt->getBodySeq(), pFunction); StmtSequence* pNewIncrSeq = transformLogic(pLoopStmt->getIncrSeq(), pFunction); // Create a new loop statement output.push_back( new LoopStmt( pLoopStmt->getIndexVar(), pLoopStmt->getTestVar(), pNewInitSeq, pNewTestSeq, pNewBodySeq, pNewIncrSeq, pLoopStmt->getAnnotations() ) ); } break; // Other statement types default: { // Copy the statement and add it to the output output.push_back(pStmt->copy()); } } } // Return the transformed output return new StmtSequence(output); }
/*************************************************************** * Function: transformLoopsExpr() * Purpose : Expand logical operators in an expression * Initial : Maxime Chevalier-Boisvert on January 14, 2009 **************************************************************** Revisions and bug fixes: */ Expression* transformLogicExpr(Expression* pExpr, StmtSequence::StmtVector& stmtVector, ProgFunction* pFunction) { // If this is a binary expression if (pExpr->getExprType() == Expression::BINARY_OP) { // Get a typed pointer to the expression BinaryOpExpr* pBinExpr = (BinaryOpExpr*)pExpr; // If this is a logical OR expression if (pBinExpr->getOperator() == BinaryOpExpr::OR) { // Create a new temp variable to store the result SymbolExpr* pDestVar = pFunction->createTemp(); // Create a variable to store the left-expression value SymbolExpr* pLeftVar = pFunction->createTemp(); // Create a statement vector for the left and right expression statements StmtSequence::StmtVector leftStmts; StmtSequence::StmtVector rightStmts; // Transform the left and right expressions Expression* pNewLExpr = transformLogicExpr(pBinExpr->getLeftExpr() , stmtVector, pFunction); Expression* pNewRExpr = transformLogicExpr(pBinExpr->getRightExpr(), rightStmts, pFunction); // Assign the left-expression value to a variable stmtVector.push_back(new AssignStmt(pLeftVar, pNewLExpr)); // Create an assignment statement for the if block leftStmts.push_back(new AssignStmt(pDestVar, pLeftVar)); // Create an assignment statement for the else branch rightStmts.push_back(new AssignStmt(pDestVar, pNewRExpr)); // Create a new if-statement to replace the logical operator stmtVector.push_back( new IfElseStmt( pLeftVar, new StmtSequence(leftStmts), new StmtSequence(rightStmts) ) ); // Return the destination variable as the expression to use return pDestVar; } // If this is a logical AND expression else if (pBinExpr->getOperator() == BinaryOpExpr::AND) { // Create a new temp variable to store the result SymbolExpr* pDestVar = pFunction->createTemp(); // Create a variable to store the left-expression value SymbolExpr* pLeftVar = pFunction->createTemp(); // Create a statement vector for the left and right expression statements StmtSequence::StmtVector leftStmts; StmtSequence::StmtVector rightStmts; // Transform the left and right expressions Expression* pNewLExpr = transformLogicExpr(pBinExpr->getLeftExpr() , stmtVector, pFunction); Expression* pNewRExpr = transformLogicExpr(pBinExpr->getRightExpr(), rightStmts, pFunction); // Assign the left-expression value to a variable stmtVector.push_back(new AssignStmt(pLeftVar, pNewLExpr)); // Create an assignment statement for the if branch leftStmts.push_back(new AssignStmt(pDestVar, pNewRExpr)); // Create an assignment statement for the else block rightStmts.push_back(new AssignStmt(pDestVar, pLeftVar)); // Create a new if-statement to replace the logical operator stmtVector.push_back( new IfElseStmt( pLeftVar, new StmtSequence(leftStmts), new StmtSequence(rightStmts) ) ); // Return the destination variable as the expression to use return pDestVar; } } // At this point, we know the expression is not a logical expression // However, it could contain a logical sub-expression // Make a copy of the expression to use as the new expression Expression* pNewExpr = pExpr->copy(); // Get the list of sub-expressions for this expression Expression::ExprVector subExprs = pNewExpr->getSubExprs(); // 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; // Transform the sub-expression recursively Expression* pNewSubExpr = transformLogicExpr(pSubExpr, stmtVector, pFunction); // Replace the sub-expression pExpr->replaceSubExpr(i, pNewSubExpr); } // Return the new expression return pNewExpr; }