From 2ff4a80b6266a6bcd22ef6cbb654f90fc84f9276 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 3 Feb 2015 12:25:08 -0800 Subject: [PATCH] Fixes for named-args. --- AST.cpp | 2 +- AST.h | 6 +++--- ExpressionCompiler.cpp | 21 ++++++--------------- Parser.cpp | 24 ++++++++---------------- Parser.h | 2 +- 5 files changed, 19 insertions(+), 36 deletions(-) diff --git a/AST.cpp b/AST.cpp index 33cb4ac32..6028c07cf 100644 --- a/AST.cpp +++ b/AST.cpp @@ -513,7 +513,7 @@ void FunctionCall::checkTypeRequirements() for (size_t i = 0; i < m_names.size(); i++) { bool found = false; for (size_t j = 0; j < parameterNames.size(); j++) { - if (parameterNames[j] == m_names[i]) { + if (parameterNames[j] == *m_names[i]) { // check type convertible if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[j])) BOOST_THROW_EXCEPTION(createTypeError("Invalid type for argument in function call.")); diff --git a/AST.h b/AST.h index bd1535138..525907bf4 100755 --- a/AST.h +++ b/AST.h @@ -963,7 +963,7 @@ class FunctionCall: public Expression { public: FunctionCall(Location const& _location, ASTPointer const& _expression, - std::vector> const& _arguments, std::vector const& _names): + std::vector> const& _arguments, std::vector> const& _names): Expression(_location), m_expression(_expression), m_arguments(_arguments), m_names(_names) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; @@ -971,7 +971,7 @@ public: Expression const& getExpression() const { return *m_expression; } std::vector> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; } - std::vector const& getNames() const { return m_names; } + std::vector> const& getNames() const { return m_names; } /// Returns true if this is not an actual function call, but an explicit type conversion /// or constructor call. @@ -980,7 +980,7 @@ public: private: ASTPointer m_expression; std::vector> m_arguments; - std::vector m_names; + std::vector> m_names; }; /** diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index 13d8ccf12..875e00bc2 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -204,34 +204,25 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) { FunctionType const& function = dynamic_cast(*_functionCall.getExpression().getType()); TypePointers const& parameterTypes = function.getParameterTypes(); - vector const& parameterNames = function.getParameterNames(); vector> const& callArguments = _functionCall.getArguments(); - vector const& callArgumentNames = _functionCall.getNames(); + vector> const& callArgumentNames = _functionCall.getNames(); solAssert(callArguments.size() == parameterTypes.size(), ""); vector> arguments; if (callArgumentNames.empty()) - { // normal arguments - arguments = {callArguments.begin(), callArguments.end()}; - } + arguments = callArguments; else - { // named arguments - for (size_t i = 0; i < parameterNames.size(); i++) { + for (auto const& parameterName: function.getParameterNames()) + { bool found = false; - for (size_t j = 0; j < callArgumentNames.size(); j++) { - if (parameterNames[i] == callArgumentNames[j]) { + for (size_t j = 0; j < callArgumentNames.size() && !found; j++) + if ((found = (parameterName == *callArgumentNames[j]))) // we found the actual parameter position arguments.push_back(callArguments[j]); - - found = true; - break; - } - } solAssert(found, ""); } - } switch (function.getLocation()) { diff --git a/Parser.cpp b/Parser.cpp index 1cf0bce5f..74d6c982a 100644 --- a/Parser.cpp +++ b/Parser.cpp @@ -592,7 +592,6 @@ ASTPointer Parser::parseBinaryExpression(int _minPrecedence) ASTPointer expression = parseUnaryExpression(); int precedence = Token::precedence(m_scanner->getCurrentToken()); for (; precedence >= _minPrecedence; --precedence) - { while (Token::precedence(m_scanner->getCurrentToken()) == precedence) { Token::Value op = m_scanner->getCurrentToken(); @@ -601,7 +600,6 @@ ASTPointer Parser::parseBinaryExpression(int _minPrecedence) nodeFactory.setEndPositionFromNode(right); expression = nodeFactory.createNode(expression, op, right); } - } return expression; } @@ -668,8 +666,8 @@ ASTPointer Parser::parseLeftHandSideExpression() { m_scanner->next(); vector> arguments; - vector names; - parseFunctionCallArguments(arguments, names); + vector> names; + std::tie(arguments, names) = parseFunctionCallArguments(); nodeFactory.markEndPosition(); expectToken(Token::RPAREN); expression = nodeFactory.createNode(expression, arguments, names); @@ -740,8 +738,9 @@ vector> Parser::parseFunctionCallListArguments() return arguments; } -void Parser::parseFunctionCallArguments(vector>& _arguments, vector& _names) +pair>, vector>> Parser::parseFunctionCallArguments() { + pair>, vector>> ret; Token::Value token = m_scanner->getCurrentToken(); if (token == Token::LBRACE) { @@ -749,28 +748,21 @@ void Parser::parseFunctionCallArguments(vector>& _argumen expectToken(Token::LBRACE); while (m_scanner->getCurrentToken() != Token::RBRACE) { - string identifier = *expectIdentifierToken(); expectToken(Token::COLON); - ASTPointer expression = parseExpression(); - _arguments.push_back(expression); - _names.push_back(identifier); + ret.first.push_back(parseExpression()); + ret.second.push_back(expectIdentifierToken()); if (m_scanner->getCurrentToken() == Token::COMMA) - { expectToken(Token::COMMA); - } else - { break; - } } expectToken(Token::RBRACE); } else - { - _arguments = parseFunctionCallListArguments(); - } + ret.first = parseFunctionCallListArguments(); + return ret; } diff --git a/Parser.h b/Parser.h index e8d521c94..19e0af1aa 100644 --- a/Parser.h +++ b/Parser.h @@ -82,7 +82,7 @@ private: ASTPointer parseLeftHandSideExpression(); ASTPointer parsePrimaryExpression(); std::vector> parseFunctionCallListArguments(); - void parseFunctionCallArguments(std::vector> & _arguments, std::vector & _names); + std::pair>, std::vector>> parseFunctionCallArguments(); ///@} ///@{