diff options
author | chriseth <c@ethdev.com> | 2017-02-01 06:59:41 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2017-02-16 17:15:22 +0800 |
commit | 5d584aded8bcabaafddf2f61692f8663913be603 (patch) | |
tree | 4d233a7f3ae77773b3c2d7c58f0fcd39572c5516 | |
parent | ad751bd3e6f22fadc01d43610ec2e2e008c32f11 (diff) | |
download | dexon-solidity-5d584aded8bcabaafddf2f61692f8663913be603.tar.gz dexon-solidity-5d584aded8bcabaafddf2f61692f8663913be603.tar.zst dexon-solidity-5d584aded8bcabaafddf2f61692f8663913be603.zip |
Parsing function definitions.
-rw-r--r-- | libsolidity/inlineasm/AsmCodeGen.cpp | 5 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmData.h | 5 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.cpp | 49 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.h | 2 | ||||
-rw-r--r-- | test/libsolidity/InlineAssembly.cpp | 10 |
5 files changed, 65 insertions, 6 deletions
diff --git a/libsolidity/inlineasm/AsmCodeGen.cpp b/libsolidity/inlineasm/AsmCodeGen.cpp index 43c3b27a..1eab5df0 100644 --- a/libsolidity/inlineasm/AsmCodeGen.cpp +++ b/libsolidity/inlineasm/AsmCodeGen.cpp @@ -249,7 +249,10 @@ public: _block.location ); } - + } + void operator()(assembly::FunctionDefinition const&) + { + solAssert(false, "Function definition not removed during desugaring phase."); } private: diff --git a/libsolidity/inlineasm/AsmData.h b/libsolidity/inlineasm/AsmData.h index d622ff54..64dd7b8e 100644 --- a/libsolidity/inlineasm/AsmData.h +++ b/libsolidity/inlineasm/AsmData.h @@ -48,8 +48,9 @@ struct Label { SourceLocation location; std::string name; }; struct Assignment { SourceLocation location; Identifier variableName; }; struct FunctionalAssignment; struct VariableDeclaration; +struct FunctionDefinition; struct Block; -using Statement = boost::variant<Instruction, Literal, Label, Assignment, Identifier, FunctionalAssignment, FunctionalInstruction, VariableDeclaration, Block>; +using Statement = boost::variant<Instruction, Literal, Label, Assignment, Identifier, FunctionalAssignment, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Block>; /// Functional assignment ("x := mload(20)", expects push-1-expression on the right hand /// side and requires x to occupy exactly one stack slot. struct FunctionalAssignment { SourceLocation location; Identifier variableName; std::shared_ptr<Statement> value; }; @@ -59,6 +60,8 @@ struct FunctionalInstruction { SourceLocation location; Instruction instruction; struct VariableDeclaration { SourceLocation location; std::string name; std::shared_ptr<Statement> value; }; /// Block that creates a scope (frees declared stack variables) struct Block { SourceLocation location; std::vector<Statement> statements; }; +/// Function definition ("function f(a, b) -> (d, e) { ... }") +struct FunctionDefinition { SourceLocation location; std::string name; std::vector<std::string> arguments; std::vector<std::string> returns; Block body; }; struct LocationExtractor: boost::static_visitor<SourceLocation> { diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 46a2730d..019ec1a3 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -62,6 +62,8 @@ assembly::Statement Parser::parseStatement() { case Token::Let: return parseVariableDeclaration(); + case Token::Function: + return parseFunctionDefinition(); case Token::LBrace: return parseBlock(); case Token::Assign: @@ -214,10 +216,7 @@ assembly::VariableDeclaration Parser::parseVariableDeclaration() { VariableDeclaration varDecl = createWithLocation<VariableDeclaration>(); expectToken(Token::Let); - varDecl.name = m_scanner->currentLiteral(); - if (instructions().count(varDecl.name)) - fatalParserError("Cannot use instruction names for identifier names."); - expectToken(Token::Identifier); + varDecl.name = expectAsmIdentifier(); expectToken(Token::Colon); expectToken(Token::Assign); varDecl.value.reset(new Statement(parseExpression())); @@ -225,6 +224,39 @@ assembly::VariableDeclaration Parser::parseVariableDeclaration() return varDecl; } +assembly::FunctionDefinition Parser::parseFunctionDefinition() +{ + FunctionDefinition funDef = createWithLocation<FunctionDefinition>(); + expectToken(Token::Function); + funDef.name = expectAsmIdentifier(); + expectToken(Token::LParen); + while (m_scanner->currentToken() != Token::RParen) + { + funDef.arguments.push_back(expectAsmIdentifier()); + if (m_scanner->currentToken() == Token::RParen) + break; + expectToken(Token::Comma); + } + expectToken(Token::RParen); + if (m_scanner->currentToken() == Token::Sub) + { + expectToken(Token::Sub); + expectToken(Token::GreaterThan); + expectToken(Token::LParen); + while (true) + { + funDef.returns.push_back(expectAsmIdentifier()); + if (m_scanner->currentToken() == Token::RParen) + break; + expectToken(Token::Comma); + } + expectToken(Token::RParen); + } + funDef.body = parseBlock(); + funDef.location.end = funDef.body.location.end; + return funDef; +} + FunctionalInstruction Parser::parseFunctionalInstruction(assembly::Statement&& _instruction) { if (_instruction.type() != typeid(Instruction)) @@ -266,3 +298,12 @@ FunctionalInstruction Parser::parseFunctionalInstruction(assembly::Statement&& _ expectToken(Token::RParen); return ret; } + +string Parser::expectAsmIdentifier() +{ + string name = m_scanner->currentLiteral(); + if (instructions().count(name)) + fatalParserError("Cannot use instruction names for identifier names."); + expectToken(Token::Identifier); + return name; +} diff --git a/libsolidity/inlineasm/AsmParser.h b/libsolidity/inlineasm/AsmParser.h index 643548dd..1da049f6 100644 --- a/libsolidity/inlineasm/AsmParser.h +++ b/libsolidity/inlineasm/AsmParser.h @@ -67,7 +67,9 @@ protected: std::map<std::string, dev::solidity::Instruction> const& instructions(); Statement parseElementaryOperation(bool _onlySinglePusher = false); VariableDeclaration parseVariableDeclaration(); + FunctionDefinition parseFunctionDefinition(); FunctionalInstruction parseFunctionalInstruction(Statement&& _instruction); + std::string expectAsmIdentifier(); }; } diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 8744d96f..5216ac06 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -159,6 +159,16 @@ BOOST_AUTO_TEST_CASE(blocks) BOOST_CHECK(successParse("{ let x := 7 { let y := 3 } { let z := 2 } }")); } +BOOST_AUTO_TEST_CASE(function_definitions) +{ + BOOST_CHECK(successParse("{ function f() { } function g(a) -> (x) { } }")); +} + +BOOST_AUTO_TEST_CASE(function_definitions_multiple_args) +{ + BOOST_CHECK(successParse("{ function f(a, d) { } function g(a, d) -> (x, y) { } }")); +} + BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(Printing) |