Introduce while stmt.

This commit is contained in:
Bhargava Shastry 2021-06-07 15:24:46 +02:00
parent fee6ed693c
commit 6c5b86e719
3 changed files with 45 additions and 3 deletions

View File

@ -52,4 +52,5 @@
MACRO(PragmaGenerator) SEP \ MACRO(PragmaGenerator) SEP \
MACRO(SourceUnitGenerator) SEP \ MACRO(SourceUnitGenerator) SEP \
MACRO(StatementGenerator) SEP \ MACRO(StatementGenerator) SEP \
MACRO(TestCaseGenerator) ENDSEP MACRO(TestCaseGenerator) SEP \
MACRO(WhileStmtGenerator) ENDSEP

View File

@ -500,6 +500,36 @@ string IfStmtGenerator::visit()
return ifStmt.str(); return ifStmt.str();
} }
void WhileStmtGenerator::setup()
{
set<pair<GeneratorPtr, unsigned>> dependsOn = {
{mutator->generator<BlockStmtGenerator>(), 1},
};
addGenerators(std::move(dependsOn));
}
string WhileStmtGenerator::visit()
{
ostringstream whileStmt;
ExpressionGenerator exprGen{state};
auto boolType = make_shared<BoolType>();
pair<SolidityTypePtr, string> boolTypeName = {boolType, {}};
auto expression = exprGen.rLValueOrLiteral(boolTypeName);
solAssert(expression.has_value(), "");
whileStmt << indentation()
<< "while ("
<< expression.value().second
<< ")\n";
// Make sure block stmt generator does not output an unchecked block
mutator->generator<BlockStmtGenerator>()->unchecked(false);
ostringstream whileBlock;
whileBlock << visitChildren();
if (whileBlock.str().empty())
whileBlock << indentation() << "{ }\n";
whileStmt << whileBlock.str();
return whileStmt.str();
}
void StatementGenerator::setup() void StatementGenerator::setup()
{ {
set<pair<GeneratorPtr, unsigned>> dependsOn = { set<pair<GeneratorPtr, unsigned>> dependsOn = {
@ -508,6 +538,7 @@ void StatementGenerator::setup()
{mutator->generator<FunctionCallGenerator>(), 1}, {mutator->generator<FunctionCallGenerator>(), 1},
{mutator->generator<ExpressionStmtGenerator>(), 1}, {mutator->generator<ExpressionStmtGenerator>(), 1},
{mutator->generator<IfStmtGenerator>(), 2}, {mutator->generator<IfStmtGenerator>(), 2},
{mutator->generator<WhileStmtGenerator>(), 1}
}; };
addGenerators(std::move(dependsOn)); addGenerators(std::move(dependsOn));
} }

View File

@ -82,7 +82,7 @@ struct UniformRandomDistribution
/// uniformly at random. /// uniformly at random.
[[nodiscard]] size_t distributionOneToN(size_t _n) const [[nodiscard]] size_t distributionOneToN(size_t _n) const
{ {
solAssert(_n > 0, ""); solAssert(_n >= 1, "");
return Distribution(1, _n)(*randomEngine); return Distribution(1, _n)(*randomEngine);
} }
/// @returns true with a probability of 1/(@param _n), false otherwise. /// @returns true with a probability of 1/(@param _n), false otherwise.
@ -1094,7 +1094,17 @@ public:
private: private:
std::string conditionalStmt(Condition _cond); std::string conditionalStmt(Condition _cond);
static constexpr size_t s_maxConditionalStmts = 5; static constexpr size_t s_maxConditionalStmts = 5;
};
class WhileStmtGenerator: public GeneratorBase
{
public:
explicit WhileStmtGenerator(SolidityGenerator* _mutator):
GeneratorBase(std::move(_mutator))
{}
void setup() override;
std::string visit() override;
std::string name() override { return "While statement generator"; }
}; };
class AssignmentStmtGenerator: public GeneratorBase class AssignmentStmtGenerator: public GeneratorBase
@ -1175,7 +1185,7 @@ private:
bool m_unchecked; bool m_unchecked;
bool m_inUnchecked; bool m_inUnchecked;
static constexpr unsigned s_maxStatements = 4; static constexpr unsigned s_maxStatements = 4;
static constexpr unsigned s_maxNestingDepth = 10; static constexpr unsigned s_maxNestingDepth = 4;
static constexpr size_t s_uncheckedInvProb = 13; static constexpr size_t s_uncheckedInvProb = 13;
}; };