13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Random Shader Generator
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Statements.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgStatement.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgExpressionGenerator.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgUtils.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <typeinfo>
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace rsg
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool isCurrentTopStatementBlock (const GeneratorState& state)
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int stackDepth = state.getStatementDepth();
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return dynamic_cast<const BlockStatement*>(state.getStatementStackEntry(stackDepth-1)) != DE_NULL;
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class T> float		getWeight	(const GeneratorState& state)	{ return T::getWeight(state);	}
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class T> Statement*	create		(GeneratorState& state)			{ return new T(state);			}
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct StatementSpec
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		(*getWeight)		(const GeneratorState& state);
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Statement*	(*create)			(GeneratorState& state);
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst StatementSpec* chooseStatement (GeneratorState& state)
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const StatementSpec statementSpecs[] =
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ getWeight<BlockStatement>,		create<BlockStatement>			},
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ getWeight<ExpressionStatement>,	create<ExpressionStatement>		},
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ getWeight<DeclarationStatement>,	create<DeclarationStatement>	},
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ getWeight<ConditionalStatement>,	create<ConditionalStatement>	}
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float weights[DE_LENGTH_OF_ARRAY(statementSpecs)];
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute weights
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float sum = 0.0f;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(statementSpecs); ndx++)
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		weights[ndx] = statementSpecs[ndx].getWeight(state);
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sum += weights[ndx];
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sum > 0.0f);
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Random number in range
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p = state.getRandom().getFloat(0.0f, sum);
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const StatementSpec* spec			= DE_NULL;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const StatementSpec* lastNonZero	= DE_NULL;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find element in that point
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sum = 0.0f;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(statementSpecs); ndx++)
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sum += weights[ndx];
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (p < sum)
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec = &statementSpecs[ndx];
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (weights[ndx] > 0.0f)
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lastNonZero = &statementSpecs[ndx];
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!spec)
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec = lastNonZero;
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return spec;
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryStatement* createStatement (GeneratorState& state)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return chooseStatement(state)->create(state);
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryStatement::Statement (void)
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryStatement::~Statement (void)
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExpressionStatement::ExpressionStatement (GeneratorState& state)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_expression(DE_NULL)
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExpressionGenerator generator(state);
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_expression = generator.generate(ValueRange(VariableType(VariableType::TYPE_VOID)));
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExpressionStatement::~ExpressionStatement (void)
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_expression;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat ExpressionStatement::getWeight (const GeneratorState& state)
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(state);
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 1.0f;
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ExpressionStatement::execute (ExecutionContext& execCtx) const
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_expression->evaluate(execCtx);
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlockStatement::BlockStatement (GeneratorState& state)
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	init(state);
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlockStatement::init (GeneratorState& state)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Select number of children statements to construct
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numChildrenToCreate = state.getRandom().getInt(0, state.getShaderParameters().maxStatementsPerBlock);
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Push scope
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	state.getVariableManager().pushVariableScope(m_scope);
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlockStatement::~BlockStatement (void)
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Statement*>::iterator i = m_children.begin(); i != m_children.end(); i++)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_children.clear();
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlockStatement::addChild (Statement* statement)
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_children.push_back(statement);
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete statement;
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryStatement* BlockStatement::createNextChild (GeneratorState& state)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((int)m_children.size() < m_numChildrenToCreate)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Select and create a new child
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Statement* child = createStatement(state);
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(child);
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return child;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Done, pop scope
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.getVariableManager().popVariableScope();
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_NULL;
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat BlockStatement::getWeight (const GeneratorState& state)
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (state.getStatementDepth()+1 < state.getShaderParameters().maxStatementDepth)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isCurrentTopStatementBlock(state))
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.2f; // Low probability for anonymous blocks.
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 1.0f;
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlockStatement::tokenize (GeneratorState& state, TokenStream& str) const
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::LEFT_BRACE << Token::NEWLINE << Token::INDENT_INC;
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Statement*>::const_reverse_iterator i = m_children.rbegin(); i != m_children.rend(); i++)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(*i)->tokenize(state, str);
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::INDENT_DEC << Token::RIGHT_BRACE << Token::NEWLINE;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlockStatement::execute (ExecutionContext& execCtx) const
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Statement*>::const_reverse_iterator i = m_children.rbegin(); i != m_children.rend(); i++)
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(*i)->execute(execCtx);
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ExpressionStatement::tokenize (GeneratorState& state, TokenStream& str) const
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_expression);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_expression->tokenize(state, str);
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::SEMICOLON << Token::NEWLINE;
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool canDeclareVariable (const Variable* variable)
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return variable->getStorage() == Variable::STORAGE_LOCAL;
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool hasDeclarableVars (const VariableManager& varMgr)
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<Variable*>& liveVars = varMgr.getLiveVariables();
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Variable*>::const_iterator i = liveVars.begin(); i != liveVars.end(); i++)
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (canDeclareVariable(*i))
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return false;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDeclarationStatement::DeclarationStatement (GeneratorState& state, Variable* variable)
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_variable	(DE_NULL)
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_expression	(DE_NULL)
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (variable == DE_NULL)
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Choose random
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \todo [2011-02-03 pyry] Allocate a new here?
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \todo [2011-05-26 pyry] Weights?
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<Variable*>&	liveVars = state.getVariableManager().getLiveVariables();
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<Variable*>			candidates;
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<Variable*>::const_iterator i = liveVars.begin(); i != liveVars.end(); i++)
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (canDeclareVariable(*i))
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				candidates.push_back(*i);
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		variable = state.getRandom().choose<Variable*>(candidates.begin(), candidates.end());
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(variable);
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_variable = variable;
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ValueEntry* value = state.getVariableManager().getValue(variable);
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool createInitializer = false;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_variable->getStorage())
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Variable::STORAGE_CONST:
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(value);
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			createInitializer = true;
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Variable::STORAGE_LOCAL:
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \note Currently booleans are always treated as not having undefined range and thus
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			//       initializer is always created.
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			createInitializer = value && !isUndefinedValueRange(value->getValueRange());
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			createInitializer = false;
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (createInitializer)
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ExpressionGenerator generator(state);
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Take copy of value range for generating initializer expression
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ValueRange valueRange = value->getValueRange();
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Declare (removes value entry)
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.getVariableManager().declareVariable(variable);
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool isConst = m_variable->getStorage() == Variable::STORAGE_CONST;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isConst)
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.pushExpressionFlags(state.getExpressionFlags() | CONST_EXPR);
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_expression = generator.generate(valueRange, 1);
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isConst)
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.popExpressionFlags();
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.getVariableManager().declareVariable(variable);
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDeclarationStatement::~DeclarationStatement (void)
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_expression;
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat DeclarationStatement::getWeight (const GeneratorState& state)
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!hasDeclarableVars(state.getVariableManager()))
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!isCurrentTopStatementBlock(state))
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return state.getProgramParameters().declarationStatementBaseWeight;
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DeclarationStatement::tokenize (GeneratorState& state, TokenStream& str) const
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_variable->tokenizeDeclaration(state, str);
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_expression)
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << Token::EQUAL;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_expression->tokenize(state, str);
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::SEMICOLON << Token::NEWLINE;
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DeclarationStatement::execute (ExecutionContext& execCtx) const
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_expression)
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_expression->evaluate(execCtx);
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		execCtx.getValue(m_variable) = m_expression->getValue().value();
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConditionalStatement::ConditionalStatement (GeneratorState&)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_condition		(DE_NULL)
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_trueStatement	(DE_NULL)
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_falseStatement	(DE_NULL)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConditionalStatement::~ConditionalStatement (void)
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_condition;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_trueStatement;
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_falseStatement;
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ConditionalStatement::isElseBlockRequired (const GeneratorState& state) const
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// If parent is conditional statement with else block and this is the true statement,
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// else block must be generated or otherwise parent "else" will end up parsed as else statement for this if.
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConditionalStatement*	curChild	= this;
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							curStackNdx	= state.getStatementDepth()-2;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (curStackNdx >= 0)
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ConditionalStatement* curParent = dynamic_cast<const ConditionalStatement*>(state.getStatementStackEntry(curStackNdx));
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!curParent)
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // Not a conditional statement - can end search here.
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (curChild == curParent->m_trueStatement && curParent->m_falseStatement)
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true; // Else block is mandatory.
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Continue search.
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		curChild	 = curParent;
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		curStackNdx	-= 1;
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return false;
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3943c827367444ee418f129b2c238299f49d3264554Jarkko PoyryStatement* ConditionalStatement::createNextChild (GeneratorState& state)
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// If has neither true or false statements, choose randomly whether to create false block.
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_falseStatement && !m_trueStatement && (isElseBlockRequired(state) || state.getRandom().getBool()))
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Construct false statement
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.getVariableManager().pushValueScope(m_conditionalScope);
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_falseStatement = createStatement(state);
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_falseStatement;
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (!m_trueStatement)
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_falseStatement)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Pop previous value scope.
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.getVariableManager().popValueScope();
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_conditionalScope.clear();
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Construct true statement
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.getVariableManager().pushValueScope(m_conditionalScope);
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_trueStatement = createStatement(state);
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_trueStatement;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Pop conditional scope.
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.getVariableManager().popValueScope();
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_conditionalScope.clear();
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Create condition
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!m_condition);
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ExpressionGenerator generator(state);
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ValueRange range = ValueRange(VariableType::getScalarType(VariableType::TYPE_BOOL));
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		range.getMin().asBool() = false;
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		range.getMax().asBool() = true;
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_condition = generator.generate(range, 1);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_NULL; // Done with this statement
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool isBlockStatement (const Statement* statement)
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return dynamic_cast<const BlockStatement*>(statement) != DE_NULL;
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool isConditionalStatement (const Statement* statement)
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return dynamic_cast<const ConditionalStatement*>(statement) != DE_NULL;
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConditionalStatement::tokenize (GeneratorState& state, TokenStream& str) const
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_condition && m_trueStatement);
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// if (condition)
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::IF << Token::LEFT_PAREN;
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_condition->tokenize(state, str);
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::RIGHT_PAREN << Token::NEWLINE;
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Statement executed if true
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!isBlockStatement(m_trueStatement))
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << Token::INDENT_INC;
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_trueStatement->tokenize(state, str);
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << Token::INDENT_DEC;
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_trueStatement->tokenize(state, str);
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_falseStatement)
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << Token::ELSE;
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isConditionalStatement(m_falseStatement))
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_falseStatement->tokenize(state, str);
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (isBlockStatement(m_falseStatement))
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			str << Token::NEWLINE;
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_falseStatement->tokenize(state, str);
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			str << Token::NEWLINE << Token::INDENT_INC;
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_falseStatement->tokenize(state, str);
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			str << Token::INDENT_DEC;
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConditionalStatement::execute (ExecutionContext& execCtx) const
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Evaluate condition
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_condition->evaluate(execCtx);
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecMaskStorage	maskStorage; // Value might change when we are evaluating true block so we have to take a copy.
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecValueAccess	trueMask	= maskStorage.getValue();
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	trueMask = m_condition->getValue().value();
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// And mask, execute true statement and pop
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	execCtx.andExecutionMask(trueMask);
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_trueStatement->execute(execCtx);
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	execCtx.popExecutionMask();
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_falseStatement)
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Construct negated mask, execute false statement and pop
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ExecMaskStorage tmp;
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ExecValueAccess	falseMask = tmp.getValue();
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < EXEC_VEC_WIDTH; i++)
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			falseMask.asBool(i) = !trueMask.asBool(i);
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		execCtx.andExecutionMask(falseMask);
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_falseStatement->execute(execCtx);
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		execCtx.popExecutionMask();
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat ConditionalStatement::getWeight (const GeneratorState& state)
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!state.getProgramParameters().useConditionals)
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int availableLevels = state.getShaderParameters().maxStatementDepth - state.getStatementDepth();
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (availableLevels > 1) ? 1.0f : 0.0f;
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAssignStatement::AssignStatement (const Variable* variable, Expression* value)
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_variable	(variable)
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_valueExpr	(value)	// \note Takes ownership of value
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAssignStatement::AssignStatement (GeneratorState& state, const Variable* variable, ConstValueRangeAccess valueRange)
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_variable	(variable)
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_valueExpr	(DE_NULL)
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate random value
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExpressionGenerator generator(state);
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_valueExpr = generator.generate(valueRange, 1);
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAssignStatement::~AssignStatement (void)
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_valueExpr;
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AssignStatement::tokenize (GeneratorState& state, TokenStream& str) const
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token(m_variable->getName()) << Token::EQUAL;
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_valueExpr->tokenize(state, str);
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::SEMICOLON << Token::NEWLINE;
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AssignStatement::execute (ExecutionContext& execCtx) const
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_valueExpr->evaluate(execCtx);
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	assignMasked(execCtx.getValue(m_variable), m_valueExpr->getValue(), execCtx.getExecutionMask());
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // rsg
570