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));
}
string IfStmtGenerator::visit()
string IfStmtGenerator::conditionalStmt(Condition _cond)
{
ostringstream ifStmt;
ostringstream condStmt;
ExpressionGenerator exprGen{state};
auto boolType = make_shared<BoolType>();
pair<SolidityTypePtr, string> boolTypeName = {boolType, {}};
auto expression = exprGen.rLValueOrLiteral(boolTypeName);
if (expression.has_value())
ifStmt << indentation()
<< "if ("
<< expression.value().second
<< ")\n";
solAssert(expression.has_value(), "");
if (_cond == Condition::IF)
condStmt << indentation()
<< "if ("
<< expression.value().second
<< ")\n";
else if (_cond == Condition::ELSEIF)
condStmt << indentation()
<< "else if ("
<< expression.value().second
<< ")\n";
else
return "\n";
condStmt << indentation()
<< "else"
<< "\n";
// Make sure block stmt generator does not output an unchecked block
mutator->generator<BlockStmtGenerator>()->unchecked(false);
ostringstream ifBlock;
ifBlock << visitChildren();
if (ifBlock.str().empty())
ifBlock << indentation() << "{ }\n";
ifStmt << ifBlock.str();
ostringstream condBlock;
condBlock << visitChildren();
if (condBlock.str().empty())
condBlock << indentation() << "{ }\n";
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();
}
@ -523,6 +554,7 @@ string BlockStmtGenerator::visit()
{
if (nestingTooDeep())
return indentation() + "{ }\n";
ScopeGuard decDepth([&]() { decrementNestingDepth(); });
incrementNestingDepth();
ostringstream block;
if (unchecked() && !m_inUnchecked)

View File

@ -173,7 +173,7 @@ public:
bool operator>=(IntegerType const& _rhs)
{
return this->signedType == _rhs.signedType &&
this->numBits >= _rhs.numBits;
this->numBits == _rhs.numBits;
}
std::string toString() override
{
@ -823,6 +823,10 @@ struct ExpressionGenerator
{
nestingDepth++;
}
void decrementNestingDepth()
{
nestingDepth--;
}
void resetNestingDepth()
{
nestingDepth = 0;
@ -1074,12 +1078,23 @@ public:
class IfStmtGenerator: public GeneratorBase
{
public:
enum class Condition
{
IF,
ELSEIF,
ELSE
};
explicit IfStmtGenerator(SolidityGenerator* _mutator):
GeneratorBase(std::move(_mutator))
{}
void setup() override;
std::string visit() override;
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
@ -1160,7 +1175,7 @@ private:
bool m_unchecked;
bool m_inUnchecked;
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;
};