Browse Source

Solidity ForStatement Compiler part

- Work in progress
cl-refactor
Lefteris Karapetsas 10 years ago
parent
commit
3c6e966160
  1. 5
      libsolidity/AST.h
  2. 31
      libsolidity/Compiler.cpp
  3. 22
      test/solidityEndToEndTest.cpp

5
libsolidity/AST.h

@ -529,6 +529,11 @@ public:
virtual void accept(ASTConstVisitor& _visitor) const override;
virtual void checkTypeRequirements() override;
Statement const* getInitializationExpression() const { return m_initExpression.get(); }
Expression const* getCondition() const { return m_condExpression.get(); }
ExpressionStatement const* getLoopExpression() const { return m_loopExpression.get(); }
Statement const& getBody() const { return *m_body; }
private:
/// For statement's initialization expresion. for(XXX; ; ). Can be empty
ASTPointer<Statement> m_initExpression;

31
libsolidity/Compiler.cpp

@ -289,8 +289,35 @@ bool Compiler::visit(WhileStatement const& _whileStatement)
bool Compiler::visit(ForStatement const& _forStatement)
{
// LTODO
(void) _forStatement;
eth::AssemblyItem loopStart = m_context.newTag();
eth::AssemblyItem loopEnd = m_context.newTag();
m_continueTags.push_back(loopStart);
m_breakTags.push_back(loopEnd);
if (_forStatement.getInitializationExpression())
_forStatement.getInitializationExpression()->accept(*this);
m_context << loopStart;
// if there is no terminating condition in for, default is to always be true
if (_forStatement.getCondition())
{
compileExpression(*_forStatement.getCondition());
m_context << eth::Instruction::ISZERO;
m_context.appendConditionalJumpTo(loopEnd);
}
_forStatement.getBody().accept(*this);
// for's loop expression if existing
if (_forStatement.getLoopExpression())
_forStatement.getLoopExpression()->accept(*this);
m_context.appendJumpTo(loopStart);
m_context << loopEnd;
m_continueTags.pop_back();
m_breakTags.pop_back();
return false;
}

22
test/solidityEndToEndTest.cpp

@ -176,6 +176,28 @@ BOOST_AUTO_TEST_CASE(nested_loops)
testSolidityAgainstCppOnRange(0, nested_loops_cpp, 0, 12);
}
BOOST_AUTO_TEST_CASE(for_loop)
{
char const* sourceCode = "contract test {\n"
" function f(uint n) returns(uint nfac) {\n"
" nfac = 1;\n"
" for (var i = 2; i <= n; i++)\n"
" nfac *= 1;\n"
" }\n"
"}\n";
compileAndRun(sourceCode);
auto for_loop_cpp = [](u256 const& n) -> u256
{
u256 nfac = 1;
for (auto i = 2; i <= n; i++)
nfac *= i;
return nfac;
};
testSolidityAgainstCppOnRange(0, for_loop_cpp, 0, 5);
}
BOOST_AUTO_TEST_CASE(calling_other_functions)
{
// note that the index of a function is its index in the sorted sequence of functions

Loading…
Cancel
Save