[Yul] Adds break/continue statements and some general tests for for-loop syntax.

This commit is contained in:
Christian Parpart
2019-03-11 15:05:05 +01:00
committed by Christian Parpart
parent 4704ef843d
commit 05e2d362c8
24 changed files with 277 additions and 10 deletions
+15 -5
View File
@@ -69,7 +69,6 @@ void VariableReferenceCounter::operator()(ForLoop const& _forLoop)
m_scope = originalScope;
}
void VariableReferenceCounter::operator()(Block const& _block)
{
Scope* originalScope = m_scope;
@@ -92,7 +91,6 @@ void VariableReferenceCounter::increaseRefIfFound(YulString _variableName)
));
}
CodeTransform::CodeTransform(
AbstractAssembly& _assembly,
AsmAnalysisInfo& _analysisInfo,
@@ -605,11 +603,9 @@ void CodeTransform::operator()(ForLoop const& _forLoop)
visitStatements(_forLoop.pre.statements);
// TODO: When we implement break and continue, the labels and the stack heights at that point
// have to be stored in a stack.
AbstractAssembly::LabelID loopStart = m_assembly.newLabelId();
AbstractAssembly::LabelID loopEnd = m_assembly.newLabelId();
AbstractAssembly::LabelID postPart = m_assembly.newLabelId();
AbstractAssembly::LabelID loopEnd = m_assembly.newLabelId();
m_assembly.setSourceLocation(_forLoop.location);
m_assembly.appendLabel(loopStart);
@@ -619,6 +615,8 @@ void CodeTransform::operator()(ForLoop const& _forLoop)
m_assembly.appendInstruction(solidity::Instruction::ISZERO);
m_assembly.appendJumpToIf(loopEnd);
int const stackHeightBody = m_assembly.stackHeight();
m_context->forLoopStack.emplace(Context::ForLoopLabels{ {postPart, stackHeightBody}, {loopEnd, stackHeightBody} });
(*this)(_forLoop.body);
m_assembly.setSourceLocation(_forLoop.location);
@@ -631,7 +629,19 @@ void CodeTransform::operator()(ForLoop const& _forLoop)
m_assembly.appendLabel(loopEnd);
finalizeBlock(_forLoop.pre, stackStartHeight);
m_context->forLoopStack.pop();
m_scope = originalScope;
checkStackHeight(&_forLoop);
}
void CodeTransform::operator()(Break const&)
{
yulAssert(false, "Code generation for break statement in Yul is not implemented yet.");
}
void CodeTransform::operator()(Continue const&)
{
yulAssert(false, "Code generation for continue statement in Yul is not implemented yet.");
}
void CodeTransform::operator()(Block const& _block)
+18
View File
@@ -30,6 +30,8 @@
#include <boost/variant.hpp>
#include <boost/optional.hpp>
#include <stack>
namespace langutil
{
class ErrorReporter;
@@ -57,6 +59,20 @@ struct CodeTransformContext
std::map<Scope::Function const*, AbstractAssembly::LabelID> functionEntryIDs;
std::map<Scope::Variable const*, int> variableStackHeights;
std::map<Scope::Variable const*, unsigned> variableReferences;
struct JumpInfo
{
AbstractAssembly::LabelID label; ///< Jump's LabelID to jump to.
int targetStackHeight; ///< Stack height after the jump.
};
struct ForLoopLabels
{
JumpInfo post; ///< Jump info for jumping to post branch.
JumpInfo done; ///< Jump info for jumping to done branch.
};
std::stack<ForLoopLabels> forLoopStack;
};
/**
@@ -166,6 +182,8 @@ public:
void operator()(Switch const& _switch);
void operator()(FunctionDefinition const&);
void operator()(ForLoop const&);
void operator()(Break const&);
void operator()(Continue const&);
void operator()(Block const& _block);
private: