mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Adding a ForStatement solidity AST Node.
- Adding ForStatement node - Implemented Parsing for ForStatement - A simple parsing test for the ForStatement - Work in progress
This commit is contained in:
parent
5b802b685e
commit
f7029726be
7
AST.cpp
7
AST.cpp
@ -130,6 +130,13 @@ void WhileStatement::checkTypeRequirements()
|
|||||||
m_body->checkTypeRequirements();
|
m_body->checkTypeRequirements();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ForStatement::checkTypeRequirements()
|
||||||
|
{
|
||||||
|
// LTODO
|
||||||
|
m_condExpression->expectType(BoolType());
|
||||||
|
m_body->checkTypeRequirements();
|
||||||
|
}
|
||||||
|
|
||||||
void Return::checkTypeRequirements()
|
void Return::checkTypeRequirements()
|
||||||
{
|
{
|
||||||
if (!m_expression)
|
if (!m_expression)
|
||||||
|
24
AST.h
24
AST.h
@ -509,6 +509,30 @@ private:
|
|||||||
ASTPointer<Statement> m_body;
|
ASTPointer<Statement> m_body;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ForStatement: public BreakableStatement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ForStatement(Location const& _location,
|
||||||
|
ASTPointer<ASTNode> const& _initExpression,
|
||||||
|
ASTPointer<Expression> const& _conditionExpression,
|
||||||
|
ASTPointer<ExpressionStatement> const& _loopExpression,
|
||||||
|
ASTPointer<Statement> const& _body):
|
||||||
|
BreakableStatement(_location),
|
||||||
|
m_initExpression(_initExpression),
|
||||||
|
m_condExpression(_conditionExpression),
|
||||||
|
m_loopExpression(_loopExpression),
|
||||||
|
m_body(_body) {}
|
||||||
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
|
virtual void checkTypeRequirements() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ASTPointer<ASTNode> m_initExpression;
|
||||||
|
ASTPointer<Expression> m_condExpression;
|
||||||
|
ASTPointer<ExpressionStatement> m_loopExpression;
|
||||||
|
ASTPointer<Statement> m_body;
|
||||||
|
};
|
||||||
|
|
||||||
class Continue: public Statement
|
class Continue: public Statement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -52,6 +52,7 @@ class Block;
|
|||||||
class IfStatement;
|
class IfStatement;
|
||||||
class BreakableStatement;
|
class BreakableStatement;
|
||||||
class WhileStatement;
|
class WhileStatement;
|
||||||
|
class ForStatement;
|
||||||
class Continue;
|
class Continue;
|
||||||
class Break;
|
class Break;
|
||||||
class Return;
|
class Return;
|
||||||
|
@ -150,6 +150,13 @@ bool ASTPrinter::visit(WhileStatement const& _node)
|
|||||||
return goDeeper();
|
return goDeeper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(ForStatement const& _node)
|
||||||
|
{
|
||||||
|
writeLine("ForStatement");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
bool ASTPrinter::visit(Continue const& _node)
|
bool ASTPrinter::visit(Continue const& _node)
|
||||||
{
|
{
|
||||||
writeLine("Continue");
|
writeLine("Continue");
|
||||||
@ -360,6 +367,11 @@ void ASTPrinter::endVisit(WhileStatement const&)
|
|||||||
m_indentation--;
|
m_indentation--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(ForStatement const&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
void ASTPrinter::endVisit(Continue const&)
|
void ASTPrinter::endVisit(Continue const&)
|
||||||
{
|
{
|
||||||
m_indentation--;
|
m_indentation--;
|
||||||
|
@ -57,6 +57,7 @@ public:
|
|||||||
bool visit(IfStatement const& _node) override;
|
bool visit(IfStatement const& _node) override;
|
||||||
bool visit(BreakableStatement const& _node) override;
|
bool visit(BreakableStatement const& _node) override;
|
||||||
bool visit(WhileStatement const& _node) override;
|
bool visit(WhileStatement const& _node) override;
|
||||||
|
bool visit(ForStatement const& _node) override;
|
||||||
bool visit(Continue const& _node) override;
|
bool visit(Continue const& _node) override;
|
||||||
bool visit(Break const& _node) override;
|
bool visit(Break const& _node) override;
|
||||||
bool visit(Return const& _node) override;
|
bool visit(Return const& _node) override;
|
||||||
@ -90,6 +91,7 @@ public:
|
|||||||
void endVisit(IfStatement const&) override;
|
void endVisit(IfStatement const&) override;
|
||||||
void endVisit(BreakableStatement const&) override;
|
void endVisit(BreakableStatement const&) override;
|
||||||
void endVisit(WhileStatement const&) override;
|
void endVisit(WhileStatement const&) override;
|
||||||
|
void endVisit(ForStatement const&) override;
|
||||||
void endVisit(Continue const&) override;
|
void endVisit(Continue const&) override;
|
||||||
void endVisit(Break const&) override;
|
void endVisit(Break const&) override;
|
||||||
void endVisit(Return const&) override;
|
void endVisit(Return const&) override;
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
virtual bool visit(IfStatement&) { return true; }
|
virtual bool visit(IfStatement&) { return true; }
|
||||||
virtual bool visit(BreakableStatement&) { return true; }
|
virtual bool visit(BreakableStatement&) { return true; }
|
||||||
virtual bool visit(WhileStatement&) { return true; }
|
virtual bool visit(WhileStatement&) { return true; }
|
||||||
|
virtual bool visit(ForStatement&) { return true; }
|
||||||
virtual bool visit(Continue&) { return true; }
|
virtual bool visit(Continue&) { return true; }
|
||||||
virtual bool visit(Break&) { return true; }
|
virtual bool visit(Break&) { return true; }
|
||||||
virtual bool visit(Return&) { return true; }
|
virtual bool visit(Return&) { return true; }
|
||||||
@ -93,6 +94,7 @@ public:
|
|||||||
virtual void endVisit(IfStatement&) { }
|
virtual void endVisit(IfStatement&) { }
|
||||||
virtual void endVisit(BreakableStatement&) { }
|
virtual void endVisit(BreakableStatement&) { }
|
||||||
virtual void endVisit(WhileStatement&) { }
|
virtual void endVisit(WhileStatement&) { }
|
||||||
|
virtual void endVisit(ForStatement&) { }
|
||||||
virtual void endVisit(Continue&) { }
|
virtual void endVisit(Continue&) { }
|
||||||
virtual void endVisit(Break&) { }
|
virtual void endVisit(Break&) { }
|
||||||
virtual void endVisit(Return&) { }
|
virtual void endVisit(Return&) { }
|
||||||
@ -132,6 +134,7 @@ public:
|
|||||||
virtual bool visit(IfStatement const&) { return true; }
|
virtual bool visit(IfStatement const&) { return true; }
|
||||||
virtual bool visit(BreakableStatement const&) { return true; }
|
virtual bool visit(BreakableStatement const&) { return true; }
|
||||||
virtual bool visit(WhileStatement const&) { return true; }
|
virtual bool visit(WhileStatement const&) { return true; }
|
||||||
|
virtual bool visit(ForStatement const&) { return true; }
|
||||||
virtual bool visit(Continue const&) { return true; }
|
virtual bool visit(Continue const&) { return true; }
|
||||||
virtual bool visit(Break const&) { return true; }
|
virtual bool visit(Break const&) { return true; }
|
||||||
virtual bool visit(Return const&) { return true; }
|
virtual bool visit(Return const&) { return true; }
|
||||||
@ -167,6 +170,7 @@ public:
|
|||||||
virtual void endVisit(IfStatement const&) { }
|
virtual void endVisit(IfStatement const&) { }
|
||||||
virtual void endVisit(BreakableStatement const&) { }
|
virtual void endVisit(BreakableStatement const&) { }
|
||||||
virtual void endVisit(WhileStatement const&) { }
|
virtual void endVisit(WhileStatement const&) { }
|
||||||
|
virtual void endVisit(ForStatement const&) { }
|
||||||
virtual void endVisit(Continue const&) { }
|
virtual void endVisit(Continue const&) { }
|
||||||
virtual void endVisit(Break const&) { }
|
virtual void endVisit(Break const&) { }
|
||||||
virtual void endVisit(Return const&) { }
|
virtual void endVisit(Return const&) { }
|
||||||
|
24
AST_accept.h
24
AST_accept.h
@ -267,6 +267,30 @@ void WhileStatement::accept(ASTConstVisitor& _visitor) const
|
|||||||
_visitor.endVisit(*this);
|
_visitor.endVisit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ForStatement::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this))
|
||||||
|
{
|
||||||
|
m_initExpression->accept(_visitor);
|
||||||
|
m_condExpression->accept(_visitor);
|
||||||
|
m_loopExpression->accept(_visitor);
|
||||||
|
m_body->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForStatement::accept(ASTConstVisitor& _visitor) const
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this))
|
||||||
|
{
|
||||||
|
m_initExpression->accept(_visitor);
|
||||||
|
m_condExpression->accept(_visitor);
|
||||||
|
m_loopExpression->accept(_visitor);
|
||||||
|
m_body->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
void Continue::accept(ASTVisitor& _visitor)
|
void Continue::accept(ASTVisitor& _visitor)
|
||||||
{
|
{
|
||||||
_visitor.visit(*this);
|
_visitor.visit(*this);
|
||||||
|
@ -287,6 +287,13 @@ bool Compiler::visit(WhileStatement const& _whileStatement)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Compiler::visit(ForStatement const& _forStatement)
|
||||||
|
{
|
||||||
|
// LTODO
|
||||||
|
(void) _forStatement;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Compiler::visit(Continue const&)
|
bool Compiler::visit(Continue const&)
|
||||||
{
|
{
|
||||||
if (!m_continueTags.empty())
|
if (!m_continueTags.empty())
|
||||||
|
@ -53,6 +53,7 @@ private:
|
|||||||
virtual bool visit(FunctionDefinition const& _function) override;
|
virtual bool visit(FunctionDefinition const& _function) override;
|
||||||
virtual bool visit(IfStatement const& _ifStatement) override;
|
virtual bool visit(IfStatement const& _ifStatement) override;
|
||||||
virtual bool visit(WhileStatement const& _whileStatement) override;
|
virtual bool visit(WhileStatement const& _whileStatement) override;
|
||||||
|
virtual bool visit(ForStatement const& _forStatement) override;
|
||||||
virtual bool visit(Continue const& _continue) override;
|
virtual bool visit(Continue const& _continue) override;
|
||||||
virtual bool visit(Break const& _break) override;
|
virtual bool visit(Break const& _break) override;
|
||||||
virtual bool visit(Return const& _return) override;
|
virtual bool visit(Return const& _return) override;
|
||||||
|
54
Parser.cpp
54
Parser.cpp
@ -304,6 +304,8 @@ ASTPointer<Statement> Parser::parseStatement()
|
|||||||
return parseIfStatement();
|
return parseIfStatement();
|
||||||
case Token::WHILE:
|
case Token::WHILE:
|
||||||
return parseWhileStatement();
|
return parseWhileStatement();
|
||||||
|
case Token::FOR:
|
||||||
|
return parseForStatement();
|
||||||
case Token::LBRACE:
|
case Token::LBRACE:
|
||||||
return parseBlock();
|
return parseBlock();
|
||||||
// starting from here, all statements must be terminated by a semicolon
|
// starting from here, all statements must be terminated by a semicolon
|
||||||
@ -328,15 +330,7 @@ ASTPointer<Statement> Parser::parseStatement()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// distinguish between variable definition (and potentially assignment) and expression statement
|
if (peekVariableDefinition())
|
||||||
// (which include assignments to other expressions and pre-declared variables)
|
|
||||||
// We have a variable definition if we get a keyword that specifies a type name, or
|
|
||||||
// in the case of a user-defined type, we have two identifiers following each other.
|
|
||||||
if (m_scanner->getCurrentToken() == Token::MAPPING ||
|
|
||||||
m_scanner->getCurrentToken() == Token::VAR ||
|
|
||||||
((Token::isElementaryTypeName(m_scanner->getCurrentToken()) ||
|
|
||||||
m_scanner->getCurrentToken() == Token::IDENTIFIER) &&
|
|
||||||
m_scanner->peekNextToken() == Token::IDENTIFIER))
|
|
||||||
statement = parseVariableDefinition();
|
statement = parseVariableDefinition();
|
||||||
else // "ordinary" expression statement
|
else // "ordinary" expression statement
|
||||||
statement = parseExpressionStatement();
|
statement = parseExpressionStatement();
|
||||||
@ -377,6 +371,34 @@ ASTPointer<WhileStatement> Parser::parseWhileStatement()
|
|||||||
return nodeFactory.createNode<WhileStatement>(condition, body);
|
return nodeFactory.createNode<WhileStatement>(condition, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASTPointer<ForStatement> Parser::parseForStatement()
|
||||||
|
{
|
||||||
|
ASTNodeFactory nodeFactory(*this);
|
||||||
|
expectToken(Token::FOR);
|
||||||
|
expectToken(Token::LPAREN);
|
||||||
|
ASTPointer<ASTNode> initExpression = parseVardefOrExprstatement();
|
||||||
|
expectToken(Token::SEMICOLON);
|
||||||
|
ASTPointer<Expression> conditionExpression = parseExpression();
|
||||||
|
expectToken(Token::SEMICOLON);
|
||||||
|
ASTPointer<ExpressionStatement> loopExpression = parseExpressionStatement();
|
||||||
|
expectToken(Token::SEMICOLON);
|
||||||
|
expectToken(Token::RPAREN);
|
||||||
|
ASTPointer<Statement> body = parseStatement();
|
||||||
|
nodeFactory.setEndPositionFromNode(body);
|
||||||
|
return nodeFactory.createNode<ForStatement>(initExpression,
|
||||||
|
conditionExpression,
|
||||||
|
loopExpression,
|
||||||
|
body);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTPointer<ASTNode> Parser::parseVardefOrExprstatement()
|
||||||
|
{
|
||||||
|
if (peekVariableDefinition())
|
||||||
|
return parseVariableDefinition();
|
||||||
|
else
|
||||||
|
return parseExpressionStatement();
|
||||||
|
}
|
||||||
|
|
||||||
ASTPointer<VariableDefinition> Parser::parseVariableDefinition()
|
ASTPointer<VariableDefinition> Parser::parseVariableDefinition()
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
@ -566,6 +588,20 @@ vector<ASTPointer<Expression>> Parser::parseFunctionCallArguments()
|
|||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// distinguish between variable definition (and potentially assignment) and expression statement
|
||||||
|
// (which include assignments to other expressions and pre-declared variables)
|
||||||
|
// We have a variable definition if we get a keyword that specifies a type name, or
|
||||||
|
// in the case of a user-defined type, we have two identifiers following each other.
|
||||||
|
bool Parser::peekVariableDefinition()
|
||||||
|
{
|
||||||
|
return (m_scanner->getCurrentToken() == Token::MAPPING ||
|
||||||
|
m_scanner->getCurrentToken() == Token::VAR ||
|
||||||
|
((Token::isElementaryTypeName(m_scanner->getCurrentToken()) ||
|
||||||
|
m_scanner->getCurrentToken() == Token::IDENTIFIER) &&
|
||||||
|
m_scanner->peekNextToken() == Token::IDENTIFIER));
|
||||||
|
}
|
||||||
|
|
||||||
void Parser::expectToken(Token::Value _value)
|
void Parser::expectToken(Token::Value _value)
|
||||||
{
|
{
|
||||||
if (m_scanner->getCurrentToken() != _value)
|
if (m_scanner->getCurrentToken() != _value)
|
||||||
|
6
Parser.h
6
Parser.h
@ -59,6 +59,8 @@ private:
|
|||||||
ASTPointer<Statement> parseStatement();
|
ASTPointer<Statement> parseStatement();
|
||||||
ASTPointer<IfStatement> parseIfStatement();
|
ASTPointer<IfStatement> parseIfStatement();
|
||||||
ASTPointer<WhileStatement> parseWhileStatement();
|
ASTPointer<WhileStatement> parseWhileStatement();
|
||||||
|
ASTPointer<ForStatement> parseForStatement();
|
||||||
|
ASTPointer<ASTNode> parseVardefOrExprstatement();
|
||||||
ASTPointer<VariableDefinition> parseVariableDefinition();
|
ASTPointer<VariableDefinition> parseVariableDefinition();
|
||||||
ASTPointer<ExpressionStatement> parseExpressionStatement();
|
ASTPointer<ExpressionStatement> parseExpressionStatement();
|
||||||
ASTPointer<Expression> parseExpression();
|
ASTPointer<Expression> parseExpression();
|
||||||
@ -72,6 +74,10 @@ private:
|
|||||||
///@{
|
///@{
|
||||||
///@name Helper functions
|
///@name Helper functions
|
||||||
|
|
||||||
|
/// Peeks ahead in the scanner to determine if an expression statement
|
||||||
|
/// could be a variable definition
|
||||||
|
bool peekVariableDefinition();
|
||||||
|
|
||||||
/// If current token value is not _value, throw exception otherwise advance token.
|
/// If current token value is not _value, throw exception otherwise advance token.
|
||||||
void expectToken(Token::Value _value);
|
void expectToken(Token::Value _value);
|
||||||
Token::Value expectAssignmentOperator();
|
Token::Value expectAssignmentOperator();
|
||||||
|
@ -20,6 +20,7 @@ Statement = IfStatement | WhileStatement | Block |
|
|||||||
|
|
||||||
IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )?
|
IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )?
|
||||||
WhileStatement = 'while' '(' Expression ')' Statement
|
WhileStatement = 'while' '(' Expression ')' Statement
|
||||||
|
ForStatement = 'for' '(' Expressionstatement Expression Expressionstatement ')' Statement
|
||||||
Continue = 'continue' ';'
|
Continue = 'continue' ';'
|
||||||
Break = 'break' ';'
|
Break = 'break' ';'
|
||||||
Return = 'return' Expression? ';'
|
Return = 'return' Expression? ';'
|
||||||
|
Loading…
Reference in New Issue
Block a user