mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[Yul] Adds break/continue statements and some general tests for for-loop syntax.
This commit is contained in:
committed by
Christian Parpart
parent
4704ef843d
commit
05e2d362c8
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user