aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/inlineasm/AsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/inlineasm/AsmParser.cpp')
-rw-r--r--libsolidity/inlineasm/AsmParser.cpp47
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