Introduce if-elseif-else statement.

This commit is contained in:
Bhargava Shastry 2021-06-07 13:19:54 +02:00
parent eeaf9b4e20
commit fee6ed693c
2 changed files with 62 additions and 15 deletions

View File

@ -445,27 +445,58 @@ void IfStmtGenerator::setup()
addGenerators(std::move(dependsOn)); addGenerators(std::move(dependsOn));
} }
string IfStmtGenerator::visit() string IfStmtGenerator::conditionalStmt(Condition _cond)
{ {
ostringstream ifStmt; ostringstream condStmt;
ExpressionGenerator exprGen{state}; ExpressionGenerator exprGen{state};
auto boolType = make_shared<BoolType>(); auto boolType = make_shared<BoolType>();
pair<SolidityTypePtr, string> boolTypeName = {boolType, {}}; pair<SolidityTypePtr, string> boolTypeName = {boolType, {}};
auto expression = exprGen.rLValueOrLiteral(boolTypeName); auto expression = exprGen.rLValueOrLiteral(boolTypeName);
if (expression.has_value()) solAssert(expression.has_value(), "");
ifStmt << indentation() if (_cond == Condition::IF)
<< "if (" condStmt << indentation()
<< expression.value().second << "if ("
<< ")\n"; << expression.value().second
<< ")\n";
else if (_cond == Condition::ELSEIF)
condStmt << indentation()
<< "else if ("
<< expression.value().second
<< ")\n";
else else
return "\n"; condStmt << indentation()
<< "else"
<< "\n";
// Make sure block stmt generator does not output an unchecked block // Make sure block stmt generator does not output an unchecked block
mutator->generator<BlockStmtGenerator>()->unchecked(false); mutator->generator<BlockStmtGenerator>()->unchecked(false);
ostringstream ifBlock; ostringstream condBlock;
ifBlock << visitChildren(); condBlock << visitChildren();
if (ifBlock.str().empty()) if (condBlock.str().empty())
ifBlock << indentation() << "{ }\n"; condBlock << indentation() << "{ }\n";
ifStmt << ifBlock.str(); condStmt << condBlock.str();
return condStmt.str();
}
string IfStmtGenerator::visit()
{
ostringstream ifStmt;
auto numConditionStmts = uRandDist()->distributionOneToN(s_maxConditionalStmts);
ifStmt << conditionalStmt(Condition::IF);
numConditionStmts--;
solAssert(numConditionStmts >= 0, "");
while (numConditionStmts > 0)
{
if (numConditionStmts == 1)
{
if (uRandDist()->probable(2))
ifStmt << conditionalStmt(Condition::ELSEIF);
else
ifStmt << conditionalStmt(Condition::ELSE);
}
else
ifStmt << conditionalStmt(Condition::ELSEIF);
numConditionStmts--;
}
return ifStmt.str(); return ifStmt.str();
} }
@ -523,6 +554,7 @@ string BlockStmtGenerator::visit()
{ {
if (nestingTooDeep()) if (nestingTooDeep())
return indentation() + "{ }\n"; return indentation() + "{ }\n";
ScopeGuard decDepth([&]() { decrementNestingDepth(); });
incrementNestingDepth(); incrementNestingDepth();
ostringstream block; ostringstream block;
if (unchecked() && !m_inUnchecked) if (unchecked() && !m_inUnchecked)

View File

@ -173,7 +173,7 @@ public:
bool operator>=(IntegerType const& _rhs) bool operator>=(IntegerType const& _rhs)
{ {
return this->signedType == _rhs.signedType && return this->signedType == _rhs.signedType &&
this->numBits >= _rhs.numBits; this->numBits == _rhs.numBits;
} }
std::string toString() override std::string toString() override
{ {
@ -823,6 +823,10 @@ struct ExpressionGenerator
{ {
nestingDepth++; nestingDepth++;
} }
void decrementNestingDepth()
{
nestingDepth--;
}
void resetNestingDepth() void resetNestingDepth()
{ {
nestingDepth = 0; nestingDepth = 0;
@ -1074,12 +1078,23 @@ public:
class IfStmtGenerator: public GeneratorBase class IfStmtGenerator: public GeneratorBase
{ {
public: public:
enum class Condition
{
IF,
ELSEIF,
ELSE
};
explicit IfStmtGenerator(SolidityGenerator* _mutator): explicit IfStmtGenerator(SolidityGenerator* _mutator):
GeneratorBase(std::move(_mutator)) GeneratorBase(std::move(_mutator))
{} {}
void setup() override; void setup() override;
std::string visit() override; std::string visit() override;
std::string name() override { return "If statement generator"; } std::string name() override { return "If statement generator"; }
private:
std::string conditionalStmt(Condition _cond);
static constexpr size_t s_maxConditionalStmts = 5;
}; };
class AssignmentStmtGenerator: public GeneratorBase class AssignmentStmtGenerator: public GeneratorBase
@ -1160,7 +1175,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 = 1; static constexpr unsigned s_maxNestingDepth = 10;
static constexpr size_t s_uncheckedInvProb = 13; static constexpr size_t s_uncheckedInvProb = 13;
}; };