/*************************************************************** * Function: CodeParser::parseAssignStmt() * Purpose : Parse the XML code of an assignment statement * Initial : Maxime Chevalier-Boisvert on November 5, 2008 **************************************************************** Revisions and bug fixes: */ Statement* CodeParser::parseAssignStmt(const XML::Element* pElement) { // Get the element corresponding to the left-expression XML::Element* pLeftElem = pElement->getChildElement(0); // Create a vector to store the left expressions AssignStmt::ExprVector leftExprs; // If the left expression is a matrix expression if (pLeftElem->getName() == "MatrixExpr") { // If the number of rows is not 1, throw an exception if (pLeftElem->getNumChildren() != 1) throw XML::ParseError("invalid matrix expression on assignment lhs"); // Get the row element XML::Element* pRowElem = pLeftElem->getChildElement(0); // For each left expression element for (size_t i = 0; i < pRowElem->getNumChildren(); ++i) { // Get the child element for this expression XML::Element* pExprElem = pRowElem->getChildElement(i); // Parse this left-expression leftExprs.push_back(parseExpression(pExprElem)); } } else { // Parse the left expression directly leftExprs.push_back(parseExpression(pLeftElem)); } // Parse the right expression Expression* pRightExpr = parseExpression(pElement->getChildElement(1)); // Get the output suppression flag bool suppressOut = pElement->getBoolAttrib("outputSuppressed"); // Create and return the new assignment statement object return new AssignStmt(leftExprs, pRightExpr, suppressOut); }
/*************************************************************** * 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: 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); }