Skip to content

Commit

Permalink
Add extra token for assembly assignment
Browse files Browse the repository at this point in the history
Adding an extra token for := prevents whitespace between : = being valid
  • Loading branch information
Marenz committed Feb 18, 2019
1 parent 2f0926c commit bc09196
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 10 deletions.
7 changes: 6 additions & 1 deletion liblangutil/Scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,12 @@ void Scanner::scanToken()
token = Token::Period;
break;
case ':':
token = selectToken(Token::Colon);
// : :=
advance();
if (m_char == '=')
token = selectToken(Token::AssemblyAssign);
else
token = Token::Colon;
break;
case ';':
token = selectToken(Token::Semicolon);
Expand Down
1 change: 1 addition & 0 deletions liblangutil/Token.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ namespace langutil
/* Assignment operators. */ \
/* IsAssignmentOp() relies on this block of enum values being */ \
/* contiguous and sorted in the same order!*/ \
T(AssemblyAssign, ":=", 2) \
T(Assign, "=", 2) \
/* The following have to be in exactly the same order as the simple binary operators*/ \
T(AssignBitOr, "|=", 2) \
Expand Down
15 changes: 8 additions & 7 deletions libyul/AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,22 +158,21 @@ Statement Parser::parseStatement()
}
while (currentToken() == Token::Comma);

expectToken(Token::Colon);
expectToken(Token::Assign);
expectToken(Token::AssemblyAssign);

assignment.value.reset(new Expression(parseExpression()));
assignment.location.end = locationOf(*assignment.value).end;
return Statement{std::move(assignment)};
}
case Token::AssemblyAssign:
case Token::Colon:
{
if (elementary.type() != typeid(Identifier))
fatalParserError("Label name / variable 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)
if (currentToken() == Token::AssemblyAssign && peekNextToken() != Token::Colon)
{
Assignment assignment = createWithLocation<Assignment>(identifier.location);
if (m_dialect->builtin(identifier.name))
Expand All @@ -188,6 +187,9 @@ Statement Parser::parseStatement()
}
else
{
if (currentToken() == Token::Colon)
advance();

// label
if (m_dialect->flavour != AsmFlavour::Loose)
fatalParserError("Labels are not supported.");
Expand Down Expand Up @@ -439,10 +441,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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ contract C {
}
}
// ----
// ParserError: (87-88): Literal, identifier or instruction expected.
// ParserError: (87-88): Expected primary expression.
// ParserError: (87-89): Literal, identifier or instruction expected.
// ParserError: (87-89): Expected primary expression.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
contract C {
function f() public pure {
assembly {
let x : = mload(0)
}
}
}
// ----
// ParserError: (69-70): Literal, identifier or instruction expected.
// ParserError: (69-70): Expected primary expression.

0 comments on commit bc09196

Please sign in to comment.