Change switch case string to Literal

This commit is contained in:
Alex Beregszaszi 2017-05-17 11:21:37 +01:00
parent b5080860d5
commit 66eab1caf6
4 changed files with 26 additions and 15 deletions

View File

@ -292,21 +292,29 @@ bool AsmAnalyzer::operator()(Switch const& _switch)
return false; return false;
expectDeposit(1, initialStackHeight, locationOf(*_switch.expression)); expectDeposit(1, initialStackHeight, locationOf(*_switch.expression));
map<string, bool> caseNames; set<tuple<LiteralKind, string>> cases;
for (auto const& _case: _switch.cases) for (auto const& _case: _switch.cases)
{ {
/// Note: the parser ensures there is only one default case if (_case.value)
if (caseNames[_case.name])
{ {
m_errors.push_back(make_shared<Error>( int const initialStackHeight = m_stackHeight;
Error::Type::DeclarationError, if (!(*this)(*_case.value))
"Duplicate case defined: " + _case.name, return false;
_case.location expectDeposit(1, initialStackHeight, _case.value->location);
)); m_stackHeight--;
return false;
/// 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)) if (!(*this)(_case.body))
return false; return false;

View File

@ -79,7 +79,7 @@ struct Block { SourceLocation location; std::vector<Statement> statements; };
/// Function definition ("function f(a, b) -> (d, e) { ... }") /// Function definition ("function f(a, b) -> (d, e) { ... }")
struct FunctionDefinition { SourceLocation location; std::string name; TypedNameList arguments; TypedNameList returns; Block body; }; struct FunctionDefinition { SourceLocation location; std::string name; TypedNameList arguments; TypedNameList returns; Block body; };
/// Switch case or default case /// 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 /// Switch statement
struct Switch { SourceLocation location; std::shared_ptr<Statement> expression; std::vector<Case> cases; }; struct Switch { SourceLocation location; std::shared_ptr<Statement> expression; std::vector<Case> cases; };

View File

@ -156,7 +156,10 @@ assembly::Case Parser::parseCase(bool _defaultCase)
else else
{ {
expectToken(Token::Case); 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); expectToken(Token::Colon);
_case.body = parseBlock(); _case.body = parseBlock();

View File

@ -172,10 +172,10 @@ string AsmPrinter::operator()(Switch const& _switch)
string out = "switch " + boost::apply_visitor(*this, *_switch.expression); string out = "switch " + boost::apply_visitor(*this, *_switch.expression);
for (auto const& _case: _switch.cases) for (auto const& _case: _switch.cases)
{ {
if (_case.name.empty()) if (!_case.value)
out += "\ndefault: "; out += "\ndefault: ";
else else
out += "\ncase " + _case.name + ": "; out += "\ncase " + (*this)(*_case.value) + ": ";
out += (*this)(_case.body); out += (*this)(_case.body);
} }
return out; return out;