mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Introduce hex literals (#832)
* Introduce hex keyword token * Support hex literals * Include tests for hex literals * Document hex literals
This commit is contained in:
parent
970260bf0f
commit
ec3298535e
@ -218,6 +218,15 @@ String literals are written with either double or single-quotes (``"foo"`` or ``
|
||||
|
||||
String literals support escape characters, such as ``\n``, ``\xNN`` and ``\uNNNN``. ``\xNN`` takes a hex value and inserts the appropriate byte, while ``\uNNNN`` takes a Unicode codepoint and inserts an UTF-8 sequence.
|
||||
|
||||
.. index:: literal, bytes
|
||||
|
||||
Hexadecimal Literals
|
||||
--------------------
|
||||
|
||||
Hexademical Literals are prefixed with the keyword ``hex`` and are enclosed in double or single-quotes (``hex"001122FF"``). Their content must be a hexadecimal string and their value will be the binary representation of those values.
|
||||
|
||||
Hexademical Literals behave like String Literals and have the same convertibility restrictions.
|
||||
|
||||
.. index:: enum
|
||||
|
||||
.. _enums:
|
||||
|
@ -591,7 +591,23 @@ void Scanner::scanToken()
|
||||
break;
|
||||
default:
|
||||
if (isIdentifierStart(m_char))
|
||||
{
|
||||
tie(token, m, n) = scanIdentifierOrKeyword();
|
||||
|
||||
// Special case for hexademical literals
|
||||
if (token == Token::Hex)
|
||||
{
|
||||
// reset
|
||||
m = 0;
|
||||
n = 0;
|
||||
|
||||
// Special quoted hex string must follow
|
||||
if (m_char == '"' || m_char == '\'')
|
||||
token = scanHexString();
|
||||
else
|
||||
token = Token::Illegal;
|
||||
}
|
||||
}
|
||||
else if (isDecimalDigit(m_char))
|
||||
token = scanNumber();
|
||||
else if (skipWhitespace())
|
||||
@ -684,6 +700,25 @@ Token::Value Scanner::scanString()
|
||||
return Token::StringLiteral;
|
||||
}
|
||||
|
||||
Token::Value Scanner::scanHexString()
|
||||
{
|
||||
char const quote = m_char;
|
||||
advance(); // consume quote
|
||||
LiteralScope literal(this, LITERAL_TYPE_STRING);
|
||||
while (m_char != quote && !isSourcePastEndOfInput() && !isLineTerminator(m_char))
|
||||
{
|
||||
char c = m_char;
|
||||
if (!scanHexByte(c))
|
||||
return Token::Illegal;
|
||||
addLiteralChar(c);
|
||||
}
|
||||
if (m_char != quote)
|
||||
return Token::Illegal;
|
||||
literal.complete();
|
||||
advance(); // consume quote
|
||||
return Token::StringLiteral;
|
||||
}
|
||||
|
||||
void Scanner::scanDecimalDigits()
|
||||
{
|
||||
while (isDecimalDigit(m_char))
|
||||
|
@ -203,6 +203,7 @@ private:
|
||||
std::tuple<Token::Value, unsigned, unsigned> scanIdentifierOrKeyword();
|
||||
|
||||
Token::Value scanString();
|
||||
Token::Value scanHexString();
|
||||
Token::Value scanSingleLineDocComment();
|
||||
Token::Value scanMultiLineDocComment();
|
||||
/// Scans a slash '/' and depending on the characters returns the appropriate token
|
||||
|
@ -155,6 +155,7 @@ namespace solidity
|
||||
K(External, "external", 0) \
|
||||
K(For, "for", 0) \
|
||||
K(Function, "function", 0) \
|
||||
K(Hex, "hex", 0) \
|
||||
K(If, "if", 0) \
|
||||
K(Indexed, "indexed", 0) \
|
||||
K(Internal, "internal", 0) \
|
||||
|
@ -324,6 +324,42 @@ BOOST_AUTO_TEST_CASE(invalid_short_unicode_string_escape)
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(valid_hex_literal)
|
||||
{
|
||||
Scanner scanner(CharStream("{ hex\"00112233FF\""));
|
||||
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);
|
||||
BOOST_CHECK_EQUAL(scanner.currentLiteral(), std::string("\x00\x11\x22\x33\xFF", 5));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(invalid_short_hex_literal)
|
||||
{
|
||||
Scanner scanner(CharStream("{ hex\"00112233F\""));
|
||||
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(invalid_hex_literal_with_space)
|
||||
{
|
||||
Scanner scanner(CharStream("{ hex\"00112233FF \""));
|
||||
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(invalid_hex_literal_with_wrong_quotes)
|
||||
{
|
||||
Scanner scanner(CharStream("{ hex\"00112233FF'"));
|
||||
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(invalid_hex_literal_nonhex_string)
|
||||
{
|
||||
Scanner scanner(CharStream("{ hex\"hello\""));
|
||||
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);
|
||||
BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user