Update binary-literals.md (#3161)

This commit is contained in:
Rex Jaeschke 2020-02-11 11:04:42 -05:00 committed by Bill Wagner
parent 7351ff1e34
commit 7e343a404b

View file

@ -1,36 +1,68 @@
# Binary literals
Theres a relatively common request to add binary literals to C# and VB. For bitmasks (e.g. flag enums) this seems genuinely useful, but it would also be great just for educational purposes.
This proposal specifies the changes required to the [C# 6.0 (draft) Language specification](../../spec/introduction.md) to support *binary integer literals*.
Binary literals would look like this:
## Changes to [Lexical structure](../../spec/lexical-structure.md)
```csharp
int nineteen = 0b10011;
```
### Literals
Syntactically and semantically they are identical to hexadecimal literals, except for using `b`/`B` instead of `x`/`X`, having only digits `0` and `1` and being interpreted in base 2 instead of 16.
#### Integer literals
Theres little cost to implementing these, and little conceptual overhead to users of the language.
> The grammar for [integer literals](../../spec/lexical-structure.md#Integer-literals) is extended to include `binary_integer_literal`:
## Syntax
The grammar would be as follows:
Integer literals are used to write values of types `int`, `uint`, `long`, and `ulong`. Integer literals have three possible forms: decimal, hexadecimal, and binary.
```antlr
integer-literal:
: ...
| binary-integer-literal
integer_literal
: decimal_integer_literal
| hexadecimal_integer_literal
| binary_integer_literal
;
decimal_integer_literal
: decimal_digit+ integer_type_suffix?
;
binary-integer-literal:
: `0b` binary-digits integer-type-suffix-opt
| `0B` binary-digits integer-type-suffix-opt
decimal_digit
: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
;
binary-digits:
: binary-digit
| binary-digits binary-digit
integer_type_suffix
: 'U' | 'u' | 'L' | 'l' | 'UL' | 'Ul' | 'uL' | 'ul' | 'LU' | 'Lu' | 'lU' | 'lu'
;
binary-digit:
: `0`
| `1`
hexadecimal_integer_literal
: '0x' hex_digit+ integer_type_suffix?
| '0X' hex_digit+ integer_type_suffix?
;
hex_digit
: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
| 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';
binary_integer_literal:
: '0b' binary_digit+ integer_type_suffix?
| '0B' binary_digit+ integer_type_suffix?
;
binary_digit:
: '0'
| '1'
;
```
The type of an integer literal is determined as follows:
* If the literal has no suffix, it has the first of these types in which its value can be represented: `int`, `uint`, `long`, `ulong`.
* If the literal is suffixed by `U` or `u`, it has the first of these types in which its value can be represented: `uint`, `ulong`.
* If the literal is suffixed by `L` or `l`, it has the first of these types in which its value can be represented: `long`, `ulong`.
* If the literal is suffixed by `UL`, `Ul`, `uL`, `ul`, `LU`, `Lu`, `lU`, or `lu`, it is of type `ulong`.
If the value represented by an integer literal is outside the range of the `ulong` type, a compile-time error occurs.
As a matter of style, it is suggested that "`L`" be used instead of "`l`" when writing literals of type `long`, since it is easy to confuse the letter "`l`" with the digit "`1`".
To permit the smallest possible `int` and `long` values to be written as decimal integer literals, the following two rules exist:
* When a *decimal_integer_literal* with the value 2147483648 (2^31) and no *integer_type_suffix* appears as the token immediately following a unary minus operator token ([Unary minus operator](expressions.md#unary-minus-operator)), the result is a constant of type `int` with the value -2147483648 (-2^31). In all other situations, such a *decimal_integer_literal* is of type `uint`.
* When a *decimal_integer_literal* with the value 9223372036854775808 (2^63) and no *integer_type_suffix* or the *integer_type_suffix* `L` or `l` appears as the token immediately following a unary minus operator token ([Unary minus operator](expressions.md#unary-minus-operator)), the result is a constant of type `long` with the value -9223372036854775808 (-2^63). In all other situations, such a *decimal_integer_literal* is of type `ulong`.