diff options
author | Alex Beregszaszi <alex@rtfs.hu> | 2017-05-17 18:21:37 +0800 |
---|---|---|
committer | Alex Beregszaszi <alex@rtfs.hu> | 2017-05-26 10:20:10 +0800 |
commit | 66eab1caf63f9221a279abf71de953524fe9c2ad (patch) | |
tree | deec1c6b67f411d4a1efdee9400640e5c61a989e | |
parent | b5080860d5f2d141b8fccceaa635378a86c996a8 (diff) | |
download | dexon-solidity-66eab1caf63f9221a279abf71de953524fe9c2ad.tar.gz dexon-solidity-66eab1caf63f9221a279abf71de953524fe9c2ad.tar.zst dexon-solidity-66eab1caf63f9221a279abf71de953524fe9c2ad.zip |
Change switch case string to Literal
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.cpp | 30 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmData.h | 2 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.cpp | 5 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmPrinter.cpp | 4 |
4 files changed, 26 insertions, 15 deletions
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<string, bool> caseNames; + set<tuple<LiteralKind, string>> 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>( - 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>( + 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<Statement> 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<Literal> value; Block body; }; /// Switch statement struct Switch { SourceLocation location; std::shared_ptr<Statement> expression; std::vector<Case> 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<Literal>(std::move(boost::get<assembly::Literal>(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; |