aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/inlineasm
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2017-05-17 18:21:37 +0800
committerAlex Beregszaszi <alex@rtfs.hu>2017-05-26 10:20:10 +0800
commit66eab1caf63f9221a279abf71de953524fe9c2ad (patch)
treedeec1c6b67f411d4a1efdee9400640e5c61a989e /libsolidity/inlineasm
parentb5080860d5f2d141b8fccceaa635378a86c996a8 (diff)
downloaddexon-solidity-66eab1caf63f9221a279abf71de953524fe9c2ad.tar.gz
dexon-solidity-66eab1caf63f9221a279abf71de953524fe9c2ad.tar.zst
dexon-solidity-66eab1caf63f9221a279abf71de953524fe9c2ad.zip
Change switch case string to Literal
Diffstat (limited to 'libsolidity/inlineasm')
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.cpp30
-rw-r--r--libsolidity/inlineasm/AsmData.h2
-rw-r--r--libsolidity/inlineasm/AsmParser.cpp5
-rw-r--r--libsolidity/inlineasm/AsmPrinter.cpp4
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;