示例#1
0
文件: parser.cpp 项目: Sable/mcvm
/***************************************************************
* 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);
}
示例#2
0
/***************************************************************
* Function: splitSequence()
* Purpose : Convert a sequence of statements to split form
* Initial : Maxime Chevalier-Boisvert on January 7, 2009
****************************************************************
Revisions and bug fixes:
*/
StmtSequence* splitSequence(StmtSequence* pSeq, ProgFunction* pFunction)
{
	// Get a reference to the statement vector
	const StmtSequence::StmtVector& seqStmts = pSeq->getStatements();
	
	// Create a statement vector to store the split output
	StmtSequence::StmtVector stmtVector;
	
	// For each statement in the sequence
	for (StmtSequence::StmtVector::const_iterator stmtItr = seqStmts.begin(); stmtItr != seqStmts.end(); ++stmtItr)
	{
		// Convert this statement to split form
		StmtSequence::StmtVector splitOutput = splitStatement(*stmtItr, pFunction);
		
		// Add the converted statements to the output vector
		stmtVector.insert(stmtVector.end(), splitOutput.begin(), splitOutput.end());
	}
	
	// Return the split output
	return new StmtSequence(stmtVector);
}
示例#3
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);
}
示例#4
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;
}
示例#5
0
/***************************************************************
* 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;
}
示例#6
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);
}
示例#7
0
/***************************************************************
* 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;
}