diff options
author | chriseth <c@ethdev.com> | 2015-06-05 17:07:50 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-05 20:44:05 +0800 |
commit | f4d1acc563a972ee4f5a44c690cd3fdd1783ae97 (patch) | |
tree | b2814613dff69ffe8f1e14ef6160dcc0902eb3c4 /Parser.cpp | |
parent | 4987eec3d1e87868e091850d31af58e054ab5ee5 (diff) | |
download | dexon-solidity-f4d1acc563a972ee4f5a44c690cd3fdd1783ae97.tar dexon-solidity-f4d1acc563a972ee4f5a44c690cd3fdd1783ae97.tar.gz dexon-solidity-f4d1acc563a972ee4f5a44c690cd3fdd1783ae97.tar.bz2 dexon-solidity-f4d1acc563a972ee4f5a44c690cd3fdd1783ae97.tar.lz dexon-solidity-f4d1acc563a972ee4f5a44c690cd3fdd1783ae97.tar.xz dexon-solidity-f4d1acc563a972ee4f5a44c690cd3fdd1783ae97.tar.zst dexon-solidity-f4d1acc563a972ee4f5a44c690cd3fdd1783ae97.zip |
Ability to specify the storage location of a reference type.
Diffstat (limited to 'Parser.cpp')
-rw-r--r-- | Parser.cpp | 94 |
1 files changed, 68 insertions, 26 deletions
@@ -224,7 +224,9 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(ASTString const* name = make_shared<ASTString>(); // anonymous function else name = expectIdentifierToken(); - ASTPointer<ParameterList> parameters(parseParameterList()); + VarDeclParserOptions options; + options.allowLocationSpecifier = true; + ASTPointer<ParameterList> parameters(parseParameterList(options)); bool isDeclaredConst = false; Declaration::Visibility visibility(Declaration::Visibility::Default); vector<ASTPointer<ModifierInvocation>> modifiers; @@ -252,7 +254,7 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(ASTString const* { bool const permitEmptyParameterList = false; m_scanner->next(); - returnParameters = parseParameterList(permitEmptyParameterList); + returnParameters = parseParameterList(options, permitEmptyParameterList); } else returnParameters = createEmptyParameterList(); @@ -319,7 +321,9 @@ ASTPointer<EnumDefinition> Parser::parseEnumDefinition() } ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration( - VarDeclParserOptions const& _options, ASTPointer<TypeName> const& _lookAheadArrayType) + VarDeclParserOptions const& _options, + ASTPointer<TypeName> const& _lookAheadArrayType +) { ASTNodeFactory nodeFactory = _lookAheadArrayType ? ASTNodeFactory(*this, _lookAheadArrayType) : ASTNodeFactory(*this); @@ -334,20 +338,41 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration( } bool isIndexed = false; bool isDeclaredConst = false; - ASTPointer<ASTString> identifier; - Token::Value token = m_scanner->getCurrentToken(); Declaration::Visibility visibility(Declaration::Visibility::Default); - if (_options.isStateVariable && Token::isVariableVisibilitySpecifier(token)) - visibility = parseVisibilitySpecifier(token); - if (_options.allowIndexed && token == Token::Indexed) - { - isIndexed = true; - m_scanner->next(); - } - if (token == Token::Const) + VariableDeclaration::Location location = VariableDeclaration::Location::Default; + ASTPointer<ASTString> identifier; + + while (true) { - isDeclaredConst = true; - m_scanner->next(); + Token::Value token = m_scanner->getCurrentToken(); + if (_options.isStateVariable && Token::isVariableVisibilitySpecifier(token)) + { + if (visibility != Declaration::Visibility::Default) + BOOST_THROW_EXCEPTION(createParserError("Visibility already specified.")); + visibility = parseVisibilitySpecifier(token); + } + else + { + if (_options.allowIndexed && token == Token::Indexed) + isIndexed = true; + else if (token == Token::Const) + isDeclaredConst = true; + else if (_options.allowLocationSpecifier && Token::isLocationSpecifier(token)) + { + if (location != VariableDeclaration::Location::Default) + BOOST_THROW_EXCEPTION(createParserError("Location already specified.")); + if (!type) + BOOST_THROW_EXCEPTION(createParserError("Location specifier needs explicit type name.")); + location = ( + token == Token::Memory ? + VariableDeclaration::Location::Memory : + VariableDeclaration::Location::Storage + ); + } + else + break; + m_scanner->next(); + } } nodeFactory.markEndPosition(); @@ -371,7 +396,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration( } return nodeFactory.createNode<VariableDeclaration>(type, identifier, value, visibility, _options.isStateVariable, - isIndexed, isDeclaredConst); + isIndexed, isDeclaredConst, location); } ASTPointer<ModifierDefinition> Parser::parseModifierDefinition() @@ -388,7 +413,12 @@ ASTPointer<ModifierDefinition> Parser::parseModifierDefinition() ASTPointer<ASTString> name(expectIdentifierToken()); ASTPointer<ParameterList> parameters; if (m_scanner->getCurrentToken() == Token::LParen) - parameters = parseParameterList(); + { + VarDeclParserOptions options; + options.allowIndexed = true; + options.allowLocationSpecifier = true; + parameters = parseParameterList(options); + } else parameters = createEmptyParameterList(); ASTPointer<Block> block = parseBlock(); @@ -407,7 +437,11 @@ ASTPointer<EventDefinition> Parser::parseEventDefinition() ASTPointer<ASTString> name(expectIdentifierToken()); ASTPointer<ParameterList> parameters; if (m_scanner->getCurrentToken() == Token::LParen) - parameters = parseParameterList(true, true); + { + VarDeclParserOptions options; + options.allowIndexed = true; + parameters = parseParameterList(options); + } else parameters = createEmptyParameterList(); bool anonymous = false; @@ -505,12 +539,14 @@ ASTPointer<Mapping> Parser::parseMapping() return nodeFactory.createNode<Mapping>(keyType, valueType); } -ASTPointer<ParameterList> Parser::parseParameterList(bool _allowEmpty, bool _allowIndexed) +ASTPointer<ParameterList> Parser::parseParameterList( + VarDeclParserOptions const& _options, + bool _allowEmpty +) { ASTNodeFactory nodeFactory(*this); vector<ASTPointer<VariableDeclaration>> parameters; - VarDeclParserOptions options; - options.allowIndexed = _allowIndexed; + VarDeclParserOptions options(_options); options.allowEmptyName = true; expectToken(Token::LParen); if (!_allowEmpty || m_scanner->getCurrentToken() != Token::RParen) @@ -691,7 +727,7 @@ ASTPointer<Statement> Parser::parseSimpleStatement() } while (m_scanner->getCurrentToken() == Token::LBrack); - if (m_scanner->getCurrentToken() == Token::Identifier) + if (m_scanner->getCurrentToken() == Token::Identifier || Token::isLocationSpecifier(m_scanner->getCurrentToken())) return parseVariableDeclarationStatement(typeNameIndexAccessStructure(primary, indices)); else return parseExpressionStatement(expressionFromIndexAccessStructure(primary, indices)); @@ -703,6 +739,7 @@ ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStateme VarDeclParserOptions options; options.allowVar = true; options.allowInitialValue = true; + options.allowLocationSpecifier = true; ASTPointer<VariableDeclaration> variable = parseVariableDeclaration(options, _lookAheadArrayType); ASTNodeFactory nodeFactory(*this, variable); return nodeFactory.createNode<VariableDeclarationStatement>(variable); @@ -944,11 +981,16 @@ Parser::LookAheadInfo Parser::peekStatementType() const Token::Value token(m_scanner->getCurrentToken()); bool mightBeTypeName = (Token::isElementaryTypeName(token) || token == Token::Identifier); - if (token == Token::Mapping || token == Token::Var || - (mightBeTypeName && m_scanner->peekNextToken() == Token::Identifier)) + if (token == Token::Mapping || token == Token::Var) return LookAheadInfo::VariableDeclarationStatement; - if (mightBeTypeName && m_scanner->peekNextToken() == Token::LBrack) - return LookAheadInfo::IndexAccessStructure; + if (mightBeTypeName) + { + Token::Value next = m_scanner->peekNextToken(); + if (next == Token::Identifier || Token::isLocationSpecifier(next)) + return LookAheadInfo::VariableDeclarationStatement; + if (m_scanner->peekNextToken() == Token::LBrack) + return LookAheadInfo::IndexAccessStructure; + } return LookAheadInfo::ExpressionStatement; } |