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