design/19308-number-literals.md: document 'i' suffix on any number literal

Document that the imaginary suffix 'i' may now be used on any (non-imaginary)
number literal, while maintaining backward compatibility.

While at it, consolidate the syntax around for int_lit and float_lit
to match the respective spec changes in https://golang.org/cl161098,
and clean up order of examples.

Change-Id: Ia6f2e3c5c0b7bcb70f81042ed20b2b18ecb81e6e
Reviewed-on: https://go-review.googlesource.com/c/proposal/+/163857
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/design/19308-number-literals.md b/design/19308-number-literals.md
index 69f02f0..ff33655 100644
--- a/design/19308-number-literals.md
+++ b/design/19308-number-literals.md
@@ -3,7 +3,7 @@
 Russ Cox\
 Robert Griesemer
 
-Last updated: January 23, 2019
+Last updated: March 6, 2019
 
 [golang.org/design/19308-number-literals](https://golang.org/design/19308-number-literals)
 
@@ -272,6 +272,9 @@
 and to add underscore as a base-prefix-or-digit separator
 (case 0b0011 above; see rationale below),
 along with appropriate library support.
+Finally, to fit the existing imaginary literals seemlessly
+into the new number literals, we propose that the imaginary
+suffix `i` may be used on any (non-imaginary) number literal.
 
 ### Language Changes
 
@@ -285,33 +288,38 @@
 > An integer literal is a sequence of digits representing an integer constant. 
 > An optional prefix sets a non-decimal base:
 > 0, 0o, or 0O for octal, 0b or 0B for binary, 0x or 0X for hexadecimal.
+> A single 0 is considered a decimal zero.
 > In hexadecimal literals, letters a-f and A-F represent values 10 through 15.
 > For readability, an underscore may appear after a base prefix or
 > between successive digits; such underscores do not change the literal value.
 >
->     int_lit     = decimal_lit | octal_lit | binary_lit | hex_lit .
->     decimal_lit = ( "1" … "9" ) { [ "_" ] decimal_digit } .
->     octal_lit   = "0" [ "o" | "O" ] { [ "_" ] octal_digit } .
->     binary_lit  = "0" ( "b" | "B" ) [ "_" ] binary_digit { [ "_" ] binary_digit } .
->     hex_lit     = "0" ( "x" | "X" ) [ "_" ] hex_digit { [ "_" ] hex_digit } .
+>     int_lit        = decimal_lit | binary_lit | octal_lit | hex_lit .
+>     decimal_lit    = "0" | ( "1" … "9" ) [ [ "_" ] decimal_digits ] .
+>     binary_lit     = "0" ( "b" | "B" ) [ "_" ] binary_digits .
+>     octal_lit      = "0" [ "o" | "O" ] [ "_" ] octal_digits .
+>     hex_lit        = "0" ( "x" | "X" ) [ "_" ] hex_digits .
+>     
+>     decimal_digits = decimal_digit { [ "_" ] decimal_digit } .
+>     binary_digits  = binary_digit { [ "_" ] binary_digit } .
+>     octal_digits   = octal_digit { [ "_" ] octal_digit } .
+>     hex_digits     = hex_digit { [ "_" ] hex_digit } .
 >
 >     42
 >     4_2
->     _42 // an identifier, not a number
->     42_ // illegal: _ must separate digits
->     4__2 // illegal: only one _ at a time
 >     0600
->     0_660
+>     0_600
 >     0o600
->     0O600 // second character is capital letter O
->     0b01111000
->     0b0111_1000
+>     0O600       // second character is capital letter 'O'
 >     0xBadFace
 >     0xBad_Face
 >     0x_67_7a_2f_cc_40_c6
->     0_xBadFace // illegal: _ must separate digits
 >     170141183460469231731687303715884105727
 >     170_141183_460469_231731_687303_715884_105727
+>     
+>     _42         // an identifier, not an integer literal
+>     42_         // invalid: _ must separate successive digits
+>     4__2        // invalid: only one _ at a time
+>     0_xBadFace  // invalid: _ must separate successive digits
 
 The https://golang.org/ref/spec#Floating-point_literals section would be amended to read:
 
@@ -338,49 +346,77 @@
 > For readability, an underscore may appear after a base prefix or
 > between successive digits; such underscores do not change the literal value.
 >
->     float_lit = decimal_float_lit | hexadecimal_float_lit .
->     decimal_float_lit = decimals "." [ decimals ] [ exponent ] |
->                         decimals exponent |
->                         "." decimals [ exponent ] .
->     decimals  = decimal_digit { [ "_" ] decimal_digit } .
->     exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals .
->     hex_float_lit = hex_prefix [ "_" ] hex_digits "." [ hex_digits ] hex_exponent |
->                     hex_prefix [ "_" ] hex_digits hex_exponent |
->                     hex_prefix "." hex_digits hex_exponent .
->     hex_prefix = "0" ( "x" | "X" ) .
->     hex_digits  = hex_digit { [ "_" ] hex_digit } .
->     hex_exponent  = ( "p" | "P" ) [ "+" | "-" ] decimals .
+>
+>     float_lit         = decimal_float_lit | hex_float_lit .
+>     
+>     decimal_float_lit = decimal_digits "." [ decimal_digits ] [ decimal_exponent ] |
+>                         decimal_digits decimal_exponent |
+>                         "." decimal_digits [ decimal_exponent ] .
+>     decimal_exponent  = ( "e" | "E" ) [ "+" | "-" ] decimal_digits .
+>     
+>     hex_float_lit     = "0" ( "x" | "X" ) hex_mantissa hex_exponent .
+>     hex_mantissa      = [ "_" ] hex_digits "." [ hex_digits ] |
+>                         [ "_" ] hex_digits |
+>                         "." hex_digits .
+>     hex_exponent      = ( "p" | "P" ) [ "+" | "-" ] decimal_digits .
+>
 >
 >     0.
 >     72.40
->     072.40        // == 72.40
+>     072.40       // == 72.40
 >     2.71828
 >     1.e+0
 >     6.67428e-11
 >     1E6
 >     .25
 >     .12345E+5
->     0x1p-2        // == 0.25
->     0x2.p10       // == 2048.0
->     0x1.Fp+0      // == 1.9375
->     0X.8p-0       // == 0.5
->     0X_1FFFP-16   // == 0.1249847412109375
->     0x.p1         // illegal: must have hex digit
->     1p-2          // illegal: p exponent requires hexadecimal mantissa
->     0x1.5e-2      // illegal: hexadecimal mantissa requires p exponent
->     0x15e-2       // == 0x15e - 2 (integer subtraction)
->     1_5.          // == 15.0
->     0.15e+0_2     // == 15.0
->     1_.5          // illegal: _ must separate digits
->     1._5          // illegal: _ must separate digits
->     1.5_e1        // illegal: _ must separate digits
->     1.5e_1        // illegal: _ must separate digits
->     1.5e1_        // illegal: _ must separate digits
+>     1_5.         // == 15.0
+>     0.15e+0_2    // == 15.0
+>     
+>     0x1p-2       // == 0.25
+>     0x2.p10      // == 2048.0
+>     0x1.Fp+0     // == 1.9375
+>     0X.8p-0      // == 0.5
+>     0X_1FFFP-16  // == 0.1249847412109375
+>     0x15e-2      // == 0x15e - 2 (integer subtraction)
+>     
+>     0x.p1        // invalid: mantissa has no digits
+>     1p-2         // invalid: p exponent requires hexadecimal mantissa
+>     0x1.5e-2     // invalid: hexadecimal mantissa requires p exponent
+>     1_.5         // invalid: _ must separate successive digits
+>     1._5         // invalid: _ must separate successive digits
+>     1.5_e1       // invalid: _ must separate successive digits
+>     1.5e_1       // invalid: _ must separate successive digits
+>     1.5e1_       // invalid: _ must separate successive digits
+
 
 The syntax in https://golang.org/ref/spec#Imaginary_literals section would be amended to read:
 
 
->     imaginary_lit = (decimals | decimal_float_lit) .
+> An imaginary literal represents the imaginary part of a complex constant.
+> It consists of an integer or floating-point literal followed by the lower-case
+> letter i.
+> The value of an imaginary literal is the value of the respective
+> integer or floating-point literal multiplied by the imaginary unit i.
+> 
+>     imaginary_lit = (decimal_digits | int_lit | float_lit) "i" .
+> 
+> For backward-compatibility, an imaginary literal's integer part consisting
+> entirely of decimal digits (and possibly underscores) is considered a decimal
+> integer, not octal, even if it starts with a leading 0.
+> 
+>     0i
+>     0123i         // == 123i for backward-compatibility
+>     0o123i        // == 0o123 * 1i == 83i
+>     0xabci        // == 0xabc * 1i == 2748i
+>     0.i
+>     2.71828i
+>     1.e+0i
+>     6.67428e-11i
+>     1E6i
+>     .25i
+>     .12345E+5i
+>     0x1p-2i       // == 0x1p-2 * 1i == 0.25i
 
 ### Library Changes