aboutsummaryrefslogtreecommitdiffstats
path: root/Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Parser.cpp')
-rw-r--r--Parser.cpp79
1 files changed, 71 insertions, 8 deletions
diff --git a/Parser.cpp b/Parser.cpp
index fcabdb29..baddbad8 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -121,6 +121,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
vector<ASTPointer<StructDefinition>> structs;
vector<ASTPointer<VariableDeclaration>> stateVariables;
vector<ASTPointer<FunctionDefinition>> functions;
+ vector<ASTPointer<ModifierDefinition>> modifiers;
if (m_scanner->getCurrentToken() == Token::IS)
do
{
@@ -152,13 +153,15 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
stateVariables.push_back(parseVariableDeclaration(allowVar));
expectToken(Token::SEMICOLON);
}
+ else if (currentToken == Token::MODIFIER)
+ modifiers.push_back(parseModifierDefinition());
else
- BOOST_THROW_EXCEPTION(createParserError("Function, variable or struct declaration expected."));
+ BOOST_THROW_EXCEPTION(createParserError("Function, variable, struct or modifier declaration expected."));
}
nodeFactory.markEndPosition();
expectToken(Token::RBRACE);
return nodeFactory.createNode<ContractDefinition>(name, docString, baseContracts, structs,
- stateVariables, functions);
+ stateVariables, functions, modifiers);
}
ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier()
@@ -189,10 +192,18 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic, A
ASTPointer<ASTString> name(expectIdentifierToken());
ASTPointer<ParameterList> parameters(parseParameterList());
bool isDeclaredConst = false;
- if (m_scanner->getCurrentToken() == Token::CONST)
+ vector<ASTPointer<ModifierInvocation>> modifiers;
+ while (true)
{
- isDeclaredConst = true;
- m_scanner->next();
+ if (m_scanner->getCurrentToken() == Token::CONST)
+ {
+ isDeclaredConst = true;
+ m_scanner->next();
+ }
+ else if (m_scanner->getCurrentToken() == Token::IDENTIFIER)
+ modifiers.push_back(parseModifierInvocation());
+ else
+ break;
}
ASTPointer<ParameterList> returnParameters;
if (m_scanner->getCurrentToken() == Token::RETURNS)
@@ -212,8 +223,8 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic, A
nodeFactory.setEndPositionFromNode(block);
bool const c_isConstructor = (_contractName && *name == *_contractName);
return nodeFactory.createNode<FunctionDefinition>(name, _isPublic, c_isConstructor, docstring,
- parameters,
- isDeclaredConst, returnParameters, block);
+ parameters, isDeclaredConst, modifiers,
+ returnParameters, block);
}
ASTPointer<StructDefinition> Parser::parseStructDefinition()
@@ -242,6 +253,50 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(bool _allowVar)
return nodeFactory.createNode<VariableDeclaration>(type, expectIdentifierToken());
}
+ASTPointer<ModifierDefinition> Parser::parseModifierDefinition()
+{
+ ScopeGuard resetModifierFlag([this]() { m_insideModifier = false; });
+ m_insideModifier = true;
+
+ ASTNodeFactory nodeFactory(*this);
+ ASTPointer<ASTString> docstring;
+ if (m_scanner->getCurrentCommentLiteral() != "")
+ docstring = make_shared<ASTString>(m_scanner->getCurrentCommentLiteral());
+
+ expectToken(Token::MODIFIER);
+ ASTPointer<ASTString> name(expectIdentifierToken());
+ ASTPointer<ParameterList> parameters;
+ if (m_scanner->getCurrentToken() == Token::LPAREN)
+ parameters = parseParameterList();
+ else
+ {
+ // create an empty parameter list at a zero-length location
+ ASTNodeFactory nodeFactory(*this);
+ nodeFactory.setLocationEmpty();
+ parameters = nodeFactory.createNode<ParameterList>(vector<ASTPointer<VariableDeclaration>>());
+ }
+ ASTPointer<Block> block = parseBlock();
+ nodeFactory.setEndPositionFromNode(block);
+ return nodeFactory.createNode<ModifierDefinition>(name, docstring, parameters, block);
+}
+
+ASTPointer<ModifierInvocation> Parser::parseModifierInvocation()
+{
+ ASTNodeFactory nodeFactory(*this);
+ ASTPointer<Identifier> name = ASTNodeFactory(*this).createNode<Identifier>(expectIdentifierToken());
+ vector<ASTPointer<Expression>> arguments;
+ if (m_scanner->getCurrentToken() == Token::LPAREN)
+ {
+ m_scanner->next();
+ arguments = parseFunctionCallArguments();
+ nodeFactory.markEndPosition();
+ expectToken(Token::RPAREN);
+ }
+ else
+ nodeFactory.setEndPositionFromNode(name);
+ return nodeFactory.createNode<ModifierInvocation>(name, arguments);
+}
+
ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
{
ASTPointer<TypeName> type;
@@ -354,8 +409,16 @@ ASTPointer<Statement> Parser::parseStatement()
nodeFactory.setEndPositionFromNode(expression);
}
statement = nodeFactory.createNode<Return>(expression);
+ break;
}
- break;
+ case Token::IDENTIFIER:
+ if (m_insideModifier && m_scanner->getCurrentLiteral() == "_")
+ {
+ statement = ASTNodeFactory(*this).createNode<PlaceholderStatement>();
+ m_scanner->next();
+ return statement;
+ }
+ // fall-through
default:
statement = parseVarDefOrExprStmt();
}