Introduce Leave as a keyword for Yul

This commit is contained in:
Alex Beregszaszi 2020-07-27 19:11:38 +01:00
parent caa329066e
commit 4366ede889
4 changed files with 16 additions and 12 deletions

View File

@ -972,6 +972,9 @@ tuple<Token, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
auto const token = TokenTraits::fromIdentifierOrKeyword(m_tokens[NextNext].literal); auto const token = TokenTraits::fromIdentifierOrKeyword(m_tokens[NextNext].literal);
if (m_kind == ScannerKind::Yul) if (m_kind == ScannerKind::Yul)
{ {
// Turn Solidity identifier into a Yul keyword
if (m_tokens[NextNext].literal == "leave")
return std::make_tuple(Token::Leave, 0, 0);
// Turn non-Yul keywords into identifiers. // Turn non-Yul keywords into identifiers.
if (!TokenTraits::isYulKeyword(std::get<0>(token))) if (!TokenTraits::isYulKeyword(std::get<0>(token)))
return std::make_tuple(Token::Identifier, 0, 0); return std::make_tuple(Token::Identifier, 0, 0);

View File

@ -269,6 +269,9 @@ namespace solidity::langutil
K(Unchecked, "unchecked", 0) \ K(Unchecked, "unchecked", 0) \
K(Var, "var", 0) \ K(Var, "var", 0) \
\ \
/* Yul-specific tokens, but not keywords. */ \
T(Leave, "leave", 0) \
\
/* Illegal token - not able to scan. */ \ /* Illegal token - not able to scan. */ \
T(Illegal, "ILLEGAL", 0) \ T(Illegal, "ILLEGAL", 0) \
\ \
@ -320,7 +323,7 @@ namespace TokenTraits
constexpr bool isYulKeyword(Token tok) constexpr bool isYulKeyword(Token tok)
{ {
return tok == Token::Function || tok == Token::Let || tok == Token::If || tok == Token::Switch || tok == Token::Case || return tok == Token::Function || tok == Token::Let || tok == Token::If || tok == Token::Switch || tok == Token::Case ||
tok == Token::Default || tok == Token::For || tok == Token::Break || tok == Token::Continue /* || tok == Token::Leave */ || tok == Token::Default || tok == Token::For || tok == Token::Break || tok == Token::Continue || tok == Token::Leave ||
tok == Token::TrueLiteral || tok == Token::FalseLiteral; tok == Token::TrueLiteral || tok == Token::FalseLiteral;
} }

View File

@ -126,16 +126,14 @@ Statement Parser::parseStatement()
advance(); advance();
return stmt; return stmt;
} }
case Token::Identifier: case Token::Leave:
if (currentLiteral() == "leave") {
{ Statement stmt{createWithLocation<Leave>()};
Statement stmt{createWithLocation<Leave>()}; if (!m_insideFunction)
if (!m_insideFunction) m_errorReporter.syntaxError(8149_error, currentLocation(), "Keyword \"leave\" can only be used inside a function.");
m_errorReporter.syntaxError(8149_error, currentLocation(), "Keyword \"leave\" can only be used inside a function."); advance();
advance(); return stmt;
return stmt; }
}
break;
default: default:
break; break;
} }

View File

@ -871,7 +871,7 @@ BOOST_AUTO_TEST_CASE(solidity_keywords)
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier); BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
BOOST_CHECK_EQUAL(scanner.next(), Token::TrueLiteral); BOOST_CHECK_EQUAL(scanner.next(), Token::TrueLiteral);
BOOST_CHECK_EQUAL(scanner.next(), Token::FalseLiteral); BOOST_CHECK_EQUAL(scanner.next(), Token::FalseLiteral);
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier); BOOST_CHECK_EQUAL(scanner.next(), Token::Leave);
BOOST_CHECK_EQUAL(scanner.next(), Token::Switch); BOOST_CHECK_EQUAL(scanner.next(), Token::Switch);
BOOST_CHECK_EQUAL(scanner.next(), Token::Case); BOOST_CHECK_EQUAL(scanner.next(), Token::Case);
BOOST_CHECK_EQUAL(scanner.next(), Token::Default); BOOST_CHECK_EQUAL(scanner.next(), Token::Default);