Merge pull request #7374 from ethereum/hexStringUnderscores

Allow  underscores in hex strings.
This commit is contained in:
chriseth 2019-09-09 11:48:46 +02:00 committed by GitHub
commit a272506a34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 56 additions and 5 deletions

View File

@ -11,6 +11,7 @@ Breaking changes:
Language Features: Language Features:
* Allow global enums and structs. * Allow global enums and structs.
* Allow underscores as delimiters in hex strings.
Compiler Features: Compiler Features:

View File

@ -499,7 +499,7 @@ terminate the string literal. Newline only terminates the string literal if it i
Hexadecimal Literals Hexadecimal Literals
-------------------- --------------------
Hexadecimal 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. Hexadecimal literals are prefixed with the keyword ``hex`` and are enclosed in double or single-quotes (``hex"001122FF"``, ``hex'0011_22_FF'``). Their content must be hexadecimal digits which can optionally use a single underscore as separator between byte boundaries. The value of the literal will be the binary representation of the hexadecimal sequence.
Hexadecimal literals behave like :ref:`string literals <string_literals>` and have the same convertibility restrictions. Hexadecimal literals behave like :ref:`string literals <string_literals>` and have the same convertibility restrictions.

View File

@ -67,7 +67,7 @@ string langutil::to_string(ScannerError _errorCode)
{ {
case ScannerError::NoError: return "No error."; case ScannerError::NoError: return "No error.";
case ScannerError::IllegalToken: return "Invalid token."; case ScannerError::IllegalToken: return "Invalid token.";
case ScannerError::IllegalHexString: return "Expected even number of hex-nibbles within double-quotes."; case ScannerError::IllegalHexString: return "Expected even number of hex-nibbles.";
case ScannerError::IllegalHexDigit: return "Hexadecimal digit missing or invalid."; case ScannerError::IllegalHexDigit: return "Hexadecimal digit missing or invalid.";
case ScannerError::IllegalCommentTerminator: return "Expected multi-line comment-terminator."; case ScannerError::IllegalCommentTerminator: return "Expected multi-line comment-terminator.";
case ScannerError::IllegalEscapeSequence: return "Invalid escape sequence."; case ScannerError::IllegalEscapeSequence: return "Invalid escape sequence.";
@ -759,13 +759,25 @@ Token Scanner::scanHexString()
char const quote = m_char; char const quote = m_char;
advance(); // consume quote advance(); // consume quote
LiteralScope literal(this, LITERAL_TYPE_STRING); LiteralScope literal(this, LITERAL_TYPE_STRING);
bool allowUnderscore = false;
while (m_char != quote && !isSourcePastEndOfInput()) while (m_char != quote && !isSourcePastEndOfInput())
{ {
char c = m_char; char c = m_char;
if (!scanHexByte(c))
// can only return false if hex-byte is incomplete (only one hex digit instead of two) if (scanHexByte(c))
{
addLiteralChar(c);
allowUnderscore = true;
}
else if (c == '_')
{
advance();
if (!allowUnderscore || m_char == quote)
return setError(ScannerError::IllegalNumberSeparator);
allowUnderscore = false;
}
else
return setError(ScannerError::IllegalHexString); return setError(ScannerError::IllegalHexString);
addLiteralChar(c);
} }
if (m_char != quote) if (m_char != quote)

View File

@ -0,0 +1,7 @@
contract C {
function f() public pure returns(bytes memory) {
return hex"12_34_5678_9A";
}
}
// ----
// f() -> 32, 5, left(0x123456789A)

View File

@ -0,0 +1,7 @@
contract C {
function f() public pure {
hex"12__34";
}
}
// ----
// ParserError: (52-60): Invalid use of number separator '_'.

View File

@ -0,0 +1,7 @@
contract C {
function f() public pure {
hex"_1234";
}
}
// ----
// ParserError: (52-57): Invalid use of number separator '_'.

View File

@ -0,0 +1,7 @@
contract C {
function f() public pure {
hex"1_234";
}
}
// ----
// ParserError: (52-56): Expected even number of hex-nibbles.

View File

@ -0,0 +1,7 @@
contract C {
function f() public pure {
hex"1234_";
}
}
// ----
// ParserError: (52-61): Invalid use of number separator '_'.

View File

@ -0,0 +1,3 @@
contract C {
bytes constant c = hex"12_3456_789012";
}