diff options
author | chriseth <chris@ethereum.org> | 2017-06-09 19:59:26 +0800 |
---|---|---|
committer | Alex Beregszaszi <alex@rtfs.hu> | 2017-06-16 17:56:21 +0800 |
commit | 0745628a734c5d22b6c9cd878aaa3ec6795df115 (patch) | |
tree | f02f055ffbd53161a7fb4926f411edbfea99416c | |
parent | 868b5ad3aa9741609e9cd79d6033ee4b172dbe2f (diff) | |
download | dexon-solidity-0745628a734c5d22b6c9cd878aaa3ec6795df115.tar.gz dexon-solidity-0745628a734c5d22b6c9cd878aaa3ec6795df115.tar.zst dexon-solidity-0745628a734c5d22b6c9cd878aaa3ec6795df115.zip |
Code generation for for-loops.
-rw-r--r-- | libjulia/backends/evm/EVMCodeTransform.cpp | 44 |
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; |