diff options
Diffstat (limited to 'libsolidity/inlineasm/AsmParser.cpp')
-rw-r--r-- | libsolidity/inlineasm/AsmParser.cpp | 49 |
1 files changed, 45 insertions, 4 deletions
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; +} |