aboutsummaryrefslogtreecommitdiffstats
path: root/libjulia/backends/evm/EVMCodeTransform.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libjulia/backends/evm/EVMCodeTransform.cpp')
-rw-r--r--libjulia/backends/evm/EVMCodeTransform.cpp44
1 files changed, 38 insertions, 6 deletions
diff --git a/libjulia/backends/evm/EVMCodeTransform.cpp b/libjulia/backends/evm/EVMCodeTransform.cpp
index e313e69c..a50af9af 100644
--- a/libjulia/backends/evm/EVMCodeTransform.cpp
+++ b/libjulia/backends/evm/EVMCodeTransform.cpp
@@ -33,12 +33,6 @@ using namespace dev::julia;
using namespace dev::solidity;
using namespace dev::solidity::assembly;
-
-void CodeTransform::operator()(ForLoop const&)
-{
- solAssert(false, "For loop not removed during desugaring phase.");
-}
-
void CodeTransform::operator()(VariableDeclaration const& _varDecl)
{
solAssert(m_scope, "");
@@ -344,6 +338,44 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
checkStackHeight(&_function);
}
+void CodeTransform::operator()(ForLoop const& _forLoop)
+{
+ Scope* originalScope = m_scope;
+ // We start with visiting the block, but not finalizing it.
+ m_scope = m_info.scopes.at(&_forLoop.pre).get();
+ int stackStartHeight = m_assembly.stackHeight();
+
+ for (auto const& statement: _forLoop.pre.statements)
+ boost::apply_visitor(*this, statement);
+
+ // 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();
+
+ m_assembly.appendLabel(loopStart);
+
+ visitExpression(*_forLoop.condition);
+ m_assembly.setSourceLocation(_forLoop.location);
+ m_assembly.appendInstruction(solidity::Instruction::ISZERO);
+ m_assembly.appendJumpToIf(loopEnd);
+
+ (*this)(_forLoop.body);
+
+ m_assembly.setSourceLocation(_forLoop.location);
+ m_assembly.appendLabel(postPart);
+
+ (*this)(_forLoop.post);
+
+ m_assembly.setSourceLocation(_forLoop.location);
+ m_assembly.appendJumpTo(loopStart);
+ m_assembly.appendLabel(loopEnd);
+
+ finalizeBlock(_forLoop.pre, stackStartHeight);
+ m_scope = originalScope;
+}
+
void CodeTransform::operator()(Block const& _block)
{
Scope* originalScope = m_scope;