diff options
author | Lefteris Karapetsas <lefteris@refu.co> | 2014-12-16 00:45:18 +0800 |
---|---|---|
committer | Lefteris Karapetsas <lefteris@refu.co> | 2014-12-17 07:03:30 +0800 |
commit | f7029726be3bbf119548a83696402512374d809d (patch) | |
tree | 4ba52a22a933d3f2779c8b0301f097b6ffde7ffa /Parser.cpp | |
parent | 5b802b685e794832bf8834183bf6c9604e513bbf (diff) | |
download | dexon-solidity-f7029726be3bbf119548a83696402512374d809d.tar dexon-solidity-f7029726be3bbf119548a83696402512374d809d.tar.gz dexon-solidity-f7029726be3bbf119548a83696402512374d809d.tar.bz2 dexon-solidity-f7029726be3bbf119548a83696402512374d809d.tar.lz dexon-solidity-f7029726be3bbf119548a83696402512374d809d.tar.xz dexon-solidity-f7029726be3bbf119548a83696402512374d809d.tar.zst dexon-solidity-f7029726be3bbf119548a83696402512374d809d.zip |
Adding a ForStatement solidity AST Node.
- Adding ForStatement node
- Implemented Parsing for ForStatement
- A simple parsing test for the ForStatement
- Work in progress
Diffstat (limited to 'Parser.cpp')
-rw-r--r-- | Parser.cpp | 54 |
1 files changed, 45 insertions, 9 deletions
@@ -304,6 +304,8 @@ ASTPointer<Statement> Parser::parseStatement() return parseIfStatement(); case Token::WHILE: return parseWhileStatement(); + case Token::FOR: + return parseForStatement(); case Token::LBRACE: return parseBlock(); // starting from here, all statements must be terminated by a semicolon @@ -328,15 +330,7 @@ ASTPointer<Statement> Parser::parseStatement() } break; default: - // 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. - 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)) + if (peekVariableDefinition()) statement = parseVariableDefinition(); else // "ordinary" expression statement statement = parseExpressionStatement(); @@ -377,6 +371,34 @@ ASTPointer<WhileStatement> Parser::parseWhileStatement() 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() { ASTNodeFactory nodeFactory(*this); @@ -566,6 +588,20 @@ vector<ASTPointer<Expression>> Parser::parseFunctionCallArguments() 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) { if (m_scanner->getCurrentToken() != _value) |