From 66eab1caf63f9221a279abf71de953524fe9c2ad Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 17 May 2017 11:21:37 +0100 Subject: Change switch case string to Literal --- libsolidity/inlineasm/AsmAnalysis.cpp | 30 +++++++++++++++++++----------- libsolidity/inlineasm/AsmData.h | 2 +- libsolidity/inlineasm/AsmParser.cpp | 5 ++++- libsolidity/inlineasm/AsmPrinter.cpp | 4 ++-- 4 files changed, 26 insertions(+), 15 deletions(-) (limited to 'libsolidity/inlineasm') diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index ecc63372..a83a93a8 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -292,21 +292,29 @@ bool AsmAnalyzer::operator()(Switch const& _switch) return false; expectDeposit(1, initialStackHeight, locationOf(*_switch.expression)); - map caseNames; + set> cases; for (auto const& _case: _switch.cases) { - /// Note: the parser ensures there is only one default case - if (caseNames[_case.name]) + if (_case.value) { - m_errors.push_back(make_shared( - Error::Type::DeclarationError, - "Duplicate case defined: " + _case.name, - _case.location - )); - return false; + int const initialStackHeight = m_stackHeight; + if (!(*this)(*_case.value)) + return false; + expectDeposit(1, initialStackHeight, _case.value->location); + m_stackHeight--; + + /// Note: the parser ensures there is only one default case + auto val = make_tuple(_case.value->kind, _case.value->value); + if (!cases.insert(val).second) + { + m_errors.push_back(make_shared( + Error::Type::DeclarationError, + "Duplicate case defined", + _case.location + )); + return false; + } } - else - caseNames[_case.name] = true; if (!(*this)(_case.body)) return false; diff --git a/libsolidity/inlineasm/AsmData.h b/libsolidity/inlineasm/AsmData.h index 92ff1c5a..72afeef1 100644 --- a/libsolidity/inlineasm/AsmData.h +++ b/libsolidity/inlineasm/AsmData.h @@ -79,7 +79,7 @@ struct Block { SourceLocation location; std::vector statements; }; /// Function definition ("function f(a, b) -> (d, e) { ... }") struct FunctionDefinition { SourceLocation location; std::string name; TypedNameList arguments; TypedNameList returns; Block body; }; /// Switch case or default case -struct Case { SourceLocation location; std::string name; Block body; }; +struct Case { SourceLocation location; std::shared_ptr value; Block body; }; /// Switch statement struct Switch { SourceLocation location; std::shared_ptr expression; std::vector cases; }; diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index a3a25a42..11b33218 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -156,7 +156,10 @@ assembly::Case Parser::parseCase(bool _defaultCase) else { expectToken(Token::Case); - _case.name = expectAsmIdentifier(); + assembly::Statement statement = parseElementaryOperation(); + if (statement.type() != typeid(assembly::Literal)) + fatalParserError("Literal expected."); + _case.value = make_shared(std::move(boost::get(statement))); } expectToken(Token::Colon); _case.body = parseBlock(); diff --git a/libsolidity/inlineasm/AsmPrinter.cpp b/libsolidity/inlineasm/AsmPrinter.cpp index 92200f84..1ef9d071 100644 --- a/libsolidity/inlineasm/AsmPrinter.cpp +++ b/libsolidity/inlineasm/AsmPrinter.cpp @@ -172,10 +172,10 @@ string AsmPrinter::operator()(Switch const& _switch) string out = "switch " + boost::apply_visitor(*this, *_switch.expression); for (auto const& _case: _switch.cases) { - if (_case.name.empty()) + if (!_case.value) out += "\ndefault: "; else - out += "\ncase " + _case.name + ": "; + out += "\ncase " + (*this)(*_case.value) + ": "; out += (*this)(_case.body); } return out; -- cgit v1.2.3