示例#1
0
文件: parser.cpp 项目: Sable/mcvm
/***************************************************************
* 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);
}
示例#2
0
/***************************************************************
* 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);
}
示例#3
0
/***************************************************************
* 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;
}
示例#4
0
/***************************************************************
* 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);
}