diff options
Diffstat (limited to 'libsolidity/inlineasm/AsmParser.cpp')
-rw-r--r-- | libsolidity/inlineasm/AsmParser.cpp | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 530cd726..605d27be 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -67,6 +67,26 @@ assembly::Statement Parser::parseStatement() return parseFunctionDefinition(); case Token::LBrace: return parseBlock(); + case Token::Switch: + { + assembly::Switch _switch = createWithLocation<assembly::Switch>(); + m_scanner->next(); + _switch.expression = make_shared<Statement>(parseExpression()); + if (_switch.expression->type() == typeid(assembly::Instruction)) + fatalParserError("Instructions are not supported as expressions for switch."); + while (m_scanner->currentToken() == Token::Case) + _switch.cases.emplace_back(parseCase()); + if (m_scanner->currentToken() == Token::Default) + _switch.cases.emplace_back(parseCase()); + if (m_scanner->currentToken() == Token::Default) + fatalParserError("Only one default case allowed."); + else if (m_scanner->currentToken() == Token::Case) + fatalParserError("Case not allowed after default case."); + if (_switch.cases.size() == 0) + fatalParserError("Switch statement without any cases."); + _switch.location.end = _switch.cases.back().body.location.end; + return _switch; + } case Token::Assign: { if (m_julia) @@ -82,9 +102,6 @@ assembly::Statement Parser::parseStatement() expectToken(Token::Identifier); return assignment; } - case Token::Return: // opcode - case Token::Byte: // opcode - case Token::Address: // opcode default: break; } @@ -134,6 +151,26 @@ assembly::Statement Parser::parseStatement() return statement; } +assembly::Case Parser::parseCase() +{ + assembly::Case _case = createWithLocation<assembly::Case>(); + if (m_scanner->currentToken() == Token::Default) + m_scanner->next(); + else if (m_scanner->currentToken() == Token::Case) + { + m_scanner->next(); + assembly::Statement statement = parseElementaryOperation(); + if (statement.type() != typeid(assembly::Literal)) + fatalParserError("Literal expected."); + _case.value = make_shared<Literal>(std::move(boost::get<assembly::Literal>(statement))); + } + else + fatalParserError("Case or default case expected."); + _case.body = parseBlock(); + _case.location.end = _case.body.location.end; + return _case; +} + assembly::Statement Parser::parseExpression() { Statement operation = parseElementaryOperation(true); @@ -247,7 +284,7 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) fatalParserError( m_julia ? "Literal or identifier expected." : - "Expected elementary inline assembly operation." + "Literal, identifier or instruction expected." ); } return ret; @@ -259,7 +296,7 @@ assembly::VariableDeclaration Parser::parseVariableDeclaration() expectToken(Token::Let); while (true) { - varDecl.variables.push_back(parseTypedName()); + varDecl.variables.emplace_back(parseTypedName()); if (m_scanner->currentToken() == Token::Comma) expectToken(Token::Comma); else |