Browse Source

Solidity ForStatements expressions are now optional

cl-refactor
Lefteris Karapetsas 10 years ago
parent
commit
b2992bd659
  1. 18
      libsolidity/AST_accept.h
  2. 17
      libsolidity/Parser.cpp
  3. 2
      libsolidity/grammar.txt
  4. 12
      test/solidityParser.cpp

18
libsolidity/AST_accept.h

@ -271,9 +271,12 @@ void ForStatement::accept(ASTVisitor& _visitor)
{
if (_visitor.visit(*this))
{
m_initExpression->accept(_visitor);
m_condExpression->accept(_visitor);
m_loopExpression->accept(_visitor);
if (m_initExpression)
m_initExpression->accept(_visitor);
if (m_condExpression)
m_condExpression->accept(_visitor);
if (m_loopExpression)
m_loopExpression->accept(_visitor);
m_body->accept(_visitor);
}
_visitor.endVisit(*this);
@ -283,9 +286,12 @@ void ForStatement::accept(ASTConstVisitor& _visitor) const
{
if (_visitor.visit(*this))
{
m_initExpression->accept(_visitor);
m_condExpression->accept(_visitor);
m_loopExpression->accept(_visitor);
if (m_initExpression)
m_initExpression->accept(_visitor);
if (m_condExpression)
m_condExpression->accept(_visitor);
if (m_loopExpression)
m_loopExpression->accept(_visitor);
m_body->accept(_visitor);
}
_visitor.endVisit(*this);

17
libsolidity/Parser.cpp

@ -374,14 +374,25 @@ ASTPointer<WhileStatement> Parser::parseWhileStatement()
ASTPointer<ForStatement> Parser::parseForStatement()
{
ASTNodeFactory nodeFactory(*this);
ASTPointer<ASTNode> initExpression;
ASTPointer<Expression> conditionExpression;
ASTPointer<ExpressionStatement> loopExpression;
expectToken(Token::FOR);
expectToken(Token::LPAREN);
ASTPointer<ASTNode> initExpression = parseVardefOrExprstatement();
// LTODO: Maybe here have some predicate like peekExpression() instead of checking for semicolon and RPAREN?
if (m_scanner->getCurrentToken() != Token::SEMICOLON)
initExpression = parseVardefOrExprstatement();
expectToken(Token::SEMICOLON);
ASTPointer<Expression> conditionExpression = parseExpression();
if (m_scanner->getCurrentToken() != Token::SEMICOLON)
conditionExpression = parseExpression();
expectToken(Token::SEMICOLON);
ASTPointer<ExpressionStatement> loopExpression = parseExpressionStatement();
if (m_scanner->getCurrentToken() != Token::RPAREN)
loopExpression = parseExpressionStatement();
expectToken(Token::RPAREN);
ASTPointer<Statement> body = parseStatement();
nodeFactory.setEndPositionFromNode(body);
return nodeFactory.createNode<ForStatement>(initExpression,

2
libsolidity/grammar.txt

@ -20,7 +20,7 @@ Statement = IfStatement | WhileStatement | Block |
IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )?
WhileStatement = 'while' '(' Expression ')' Statement
ForStatement = 'for' '(' VardefOrExpressionstatement ';' Expression ';' Expressionstatement ')' Statement
ForStatement = 'for' '(' (VardefOrExpressionstatement)? ';' (Expression)? ';' (Expressionstatement)? ')' Statement
Continue = 'continue' ';'
Break = 'break' ';'
Return = 'return' Expression? ';'

12
test/solidityParser.cpp

@ -397,6 +397,18 @@ BOOST_AUTO_TEST_CASE(for_loop_simple_initexpr)
BOOST_CHECK_NO_THROW(parseTextExplainError(text));
}
BOOST_AUTO_TEST_CASE(for_loop_simple_noexpr)
{
char const* text = "contract test {\n"
" function fun(uint256 a) {\n"
" uint256 i =0;\n"
" for (;;)\n"
" { uint256 x = i; break; continue; }\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(parseTextExplainError(text));
}
BOOST_AUTO_TEST_CASE(if_statement)
{
char const* text = "contract test {\n"

Loading…
Cancel
Save