mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Parse multi variable declaration statement.
This commit is contained in:
parent
2ba0002998
commit
67d208d144
@ -7,6 +7,7 @@ Features:
|
|||||||
* Control Flow Graph: Add Control Flow Graph as analysis structure.
|
* Control Flow Graph: Add Control Flow Graph as analysis structure.
|
||||||
* Control Flow Graph: Warn about returning uninitialized storage pointers.
|
* Control Flow Graph: Warn about returning uninitialized storage pointers.
|
||||||
* Gas Estimator: Only explore paths with higher gas costs. This reduces accuracy but greatly improves the speed of gas estimation.
|
* Gas Estimator: Only explore paths with higher gas costs. This reduces accuracy but greatly improves the speed of gas estimation.
|
||||||
|
* General: Allow multiple variables to be declared as part of a tuple assignment, e.g. ``(uint a, uint b) = ...``.
|
||||||
* Optimizer: Remove unnecessary masking of the result of known short instructions (``ADDRESS``, ``CALLER``, ``ORIGIN`` and ``COINBASE``).
|
* Optimizer: Remove unnecessary masking of the result of known short instructions (``ADDRESS``, ``CALLER``, ``ORIGIN`` and ``COINBASE``).
|
||||||
* Parser: Display nicer error messages by showing the actual tokens and not internal names.
|
* Parser: Display nicer error messages by showing the actual tokens and not internal names.
|
||||||
* Parser: Use the entire location of the token instead of only its starting position as source location for parser errors.
|
* Parser: Use the entire location of the token instead of only its starting position as source location for parser errors.
|
||||||
|
@ -1086,15 +1086,79 @@ ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const&
|
|||||||
LookAheadInfo statementType;
|
LookAheadInfo statementType;
|
||||||
IndexAccessedPath iap;
|
IndexAccessedPath iap;
|
||||||
|
|
||||||
tie(statementType, iap) = tryParseIndexAccessedPath();
|
if (m_scanner->currentToken() == Token::LParen)
|
||||||
switch (statementType)
|
|
||||||
{
|
{
|
||||||
case LookAheadInfo::VariableDeclaration:
|
ASTNodeFactory nodeFactory(*this);
|
||||||
return parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap));
|
size_t emptyComponents = 0;
|
||||||
case LookAheadInfo::Expression:
|
// First consume all empty components.
|
||||||
return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap));
|
expectToken(Token::LParen);
|
||||||
default:
|
while (m_scanner->currentToken() == Token::Comma)
|
||||||
solAssert(false, "");
|
{
|
||||||
|
m_scanner->next();
|
||||||
|
emptyComponents++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now see whether we have a variable declaration or an expression.
|
||||||
|
tie(statementType, iap) = tryParseIndexAccessedPath();
|
||||||
|
switch (statementType)
|
||||||
|
{
|
||||||
|
case LookAheadInfo::VariableDeclaration:
|
||||||
|
{
|
||||||
|
vector<ASTPointer<VariableDeclaration>> variables;
|
||||||
|
ASTPointer<Expression> value;
|
||||||
|
// We have already parsed something like `(,,,,a.b.c[2][3]`
|
||||||
|
VarDeclParserOptions options;
|
||||||
|
options.allowLocationSpecifier = true;
|
||||||
|
variables = vector<ASTPointer<VariableDeclaration>>(emptyComponents, nullptr);
|
||||||
|
variables.push_back(parseVariableDeclaration(options, typeNameFromIndexAccessStructure(iap)));
|
||||||
|
|
||||||
|
while (m_scanner->currentToken() != Token::RParen)
|
||||||
|
{
|
||||||
|
expectToken(Token::Comma);
|
||||||
|
if (m_scanner->currentToken() == Token::Comma || m_scanner->currentToken() == Token::RParen)
|
||||||
|
variables.push_back(nullptr);
|
||||||
|
else
|
||||||
|
variables.push_back(parseVariableDeclaration(options));
|
||||||
|
}
|
||||||
|
expectToken(Token::RParen);
|
||||||
|
expectToken(Token::Assign);
|
||||||
|
value = parseExpression();
|
||||||
|
nodeFactory.setEndPositionFromNode(value);
|
||||||
|
return nodeFactory.createNode<VariableDeclarationStatement>(_docString, variables, value);
|
||||||
|
}
|
||||||
|
case LookAheadInfo::Expression:
|
||||||
|
{
|
||||||
|
// Complete parsing the expression in the current component.
|
||||||
|
vector<ASTPointer<Expression>> components(emptyComponents, nullptr);
|
||||||
|
components.push_back(parseExpression(expressionFromIndexAccessStructure(iap)));
|
||||||
|
while (m_scanner->currentToken() != Token::RParen)
|
||||||
|
{
|
||||||
|
expectToken(Token::Comma);
|
||||||
|
if (m_scanner->currentToken() == Token::Comma || m_scanner->currentToken() == Token::RParen)
|
||||||
|
components.push_back(ASTPointer<Expression>());
|
||||||
|
else
|
||||||
|
components.push_back(parseExpression());
|
||||||
|
}
|
||||||
|
nodeFactory.markEndPosition();
|
||||||
|
expectToken(Token::RParen);
|
||||||
|
return parseExpressionStatement(_docString, nodeFactory.createNode<TupleExpression>(components, false));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
solAssert(false, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tie(statementType, iap) = tryParseIndexAccessedPath();
|
||||||
|
switch (statementType)
|
||||||
|
{
|
||||||
|
case LookAheadInfo::VariableDeclaration:
|
||||||
|
return parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap));
|
||||||
|
case LookAheadInfo::Expression:
|
||||||
|
return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap));
|
||||||
|
default:
|
||||||
|
solAssert(false, "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1144,6 +1208,9 @@ ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStateme
|
|||||||
ASTPointer<TypeName> const& _lookAheadArrayType
|
ASTPointer<TypeName> const& _lookAheadArrayType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// This does not parse multi variable declaration statements starting directly with
|
||||||
|
// `(`, they are parsed in parseSimpleStatement, because they are hard to distinguish
|
||||||
|
// from tuple expressions.
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
if (_lookAheadArrayType)
|
if (_lookAheadArrayType)
|
||||||
|
Loading…
Reference in New Issue
Block a user