Add extra token for assembly assignment

Adding an extra token for := prevents whitespace between : = being valid
This commit is contained in:
Mathias Baumann
2019-02-21 13:58:21 +01:00
parent 5bf8af8004
commit f395d5bab4
13 changed files with 152 additions and 54 deletions
+47 -45
View File
@@ -138,63 +138,66 @@ Statement Parser::parseStatement()
return ExpressionStatement{locationOf(expr), expr};
}
case Token::Comma:
case Token::AssemblyAssign:
{
// if a comma follows, a multiple assignment is assumed
std::vector<Identifier> variableNames;
if (elementary.type() != typeid(Identifier))
fatalParserError("Label name / variable name must precede \",\" (multiple assignment).");
Identifier const& identifier = boost::get<Identifier>(elementary);
Assignment assignment = createWithLocation<Assignment>(identifier.location);
assignment.variableNames.emplace_back(identifier);
do
while (true)
{
expectToken(Token::Comma);
elementary = parseElementaryOperation();
if (elementary.type() != typeid(Identifier))
fatalParserError("Variable name expected in multiple assignment.");
assignment.variableNames.emplace_back(boost::get<Identifier>(elementary));
}
while (currentToken() == Token::Comma);
{
auto const token = currentToken() == Token::Comma ? "," : ":=";
expectToken(Token::Colon);
expectToken(Token::Assign);
fatalParserError(
std::string("Variable name must precede \"") +
token +
"\"" +
(currentToken() == Token::Comma ? " in multiple assignment." : " in assignment.")
);
}
auto const& identifier = boost::get<Identifier>(elementary);
if (m_dialect->builtin(identifier.name))
fatalParserError("Cannot assign to builtin function \"" + identifier.name.str() + "\".");
variableNames.emplace_back(identifier);
if (currentToken() != Token::Comma)
break;
expectToken(Token::Comma);
elementary = parseElementaryOperation();
}
Assignment assignment =
createWithLocation<Assignment>(boost::get<Identifier>(elementary).location);
assignment.variableNames = std::move(variableNames);
expectToken(Token::AssemblyAssign);
assignment.value.reset(new Expression(parseExpression()));
assignment.location.end = locationOf(*assignment.value).end;
return Statement{std::move(assignment)};
}
case Token::Colon:
{
if (elementary.type() != typeid(Identifier))
fatalParserError("Label name / variable name must precede \":\".");
fatalParserError("Label name must precede \":\".");
Identifier const& identifier = boost::get<Identifier>(elementary);
advance();
// identifier:=: should be parsed as identifier: =: (i.e. a label),
// while identifier:= (being followed by a non-colon) as identifier := (assignment).
if (currentToken() == Token::Assign && peekNextToken() != Token::Colon)
{
Assignment assignment = createWithLocation<Assignment>(identifier.location);
if (m_dialect->builtin(identifier.name))
fatalParserError("Cannot assign to builtin function \"" + identifier.name.str() + "\".");
else if (m_dialect->flavour != AsmFlavour::Yul && instructions().count(identifier.name.str()))
fatalParserError("Cannot use instruction names for identifier names.");
advance();
assignment.variableNames.emplace_back(identifier);
assignment.value.reset(new Expression(parseExpression()));
assignment.location.end = locationOf(*assignment.value).end;
return Statement{std::move(assignment)};
}
else
{
// label
if (m_dialect->flavour != AsmFlavour::Loose)
fatalParserError("Labels are not supported.");
Label label = createWithLocation<Label>(identifier.location);
label.name = identifier.name;
return label;
}
// label
if (m_dialect->flavour != AsmFlavour::Loose)
fatalParserError("Labels are not supported.");
Label label = createWithLocation<Label>(identifier.location);
label.name = identifier.name;
return label;
}
default:
if (m_dialect->flavour != AsmFlavour::Loose)
@@ -439,10 +442,9 @@ VariableDeclaration Parser::parseVariableDeclaration()
else
break;
}
if (currentToken() == Token::Colon)
if (currentToken() == Token::AssemblyAssign)
{
expectToken(Token::Colon);
expectToken(Token::Assign);
expectToken(Token::AssemblyAssign);
varDecl.value = make_unique<Expression>(parseExpression());
varDecl.location.end = locationOf(*varDecl.value).end;
}