// alone.
func normalizeNumbers(n ast.Node) bool {
lit, _ := n.(*ast.BasicLit)
- if lit == nil {
+ if lit == nil || (lit.Kind != token.INT && lit.Kind != token.FLOAT && lit.Kind != token.IMAG) {
return true
}
if len(lit.Value) < 2 {
- return false // only one digit - nothing to do
+ return false // only one digit (common case) - nothing to do
}
// len(lit.Value) >= 2
+ // We ignore lit.Kind because for lit.Kind == token.IMAG the literal may be an integer
+ // or floating-point value, decimal or not. Instead, just consider the literal pattern.
x := lit.Value
- switch lit.Kind {
- case token.INT:
- switch x[:2] {
- case "0X":
- lit.Value = "0x" + x[2:]
- case "0O":
- lit.Value = "0o" + x[2:]
- case "0B":
- lit.Value = "0b" + x[2:]
+ switch x[:2] {
+ default:
+ // 0-prefix octal, decimal int, or float (possibly with 'i' suffix)
+ if i := strings.LastIndexByte(x, 'E'); i >= 0 {
+ x = x[:i] + "e" + x[i+1:]
+ break
}
-
- case token.FLOAT:
- switch lit.Value[:2] {
- default:
- if i := strings.LastIndexByte(x, 'E'); i >= 0 {
- lit.Value = x[:i] + "e" + x[i+1:]
- }
- case "0x":
- if i := strings.LastIndexByte(x, 'P'); i >= 0 {
- lit.Value = x[:i] + "p" + x[i+1:]
- }
- case "0X":
- if i := strings.LastIndexByte(x, 'P'); i >= 0 {
- lit.Value = "0x" + x[2:i] + "p" + x[i+1:]
- } else {
- lit.Value = "0x" + x[2:]
- }
- }
-
- case token.IMAG:
- // Note that integer imaginary literals may contain
- // any decimal digit even if they start with zero.
- // Imaginary literals should always end in 'i' but be
- // conservative and check anyway before proceeding.
- if x[0] == '0' && x[len(x)-1] == 'i' && isDecimals(x[1:len(x)-1]) {
+ // remove leading 0's from integer (but not floating-point) imaginary literals
+ if x[len(x)-1] == 'i' && strings.IndexByte(x, '.') < 0 && strings.IndexByte(x, 'e') < 0 {
x = strings.TrimLeft(x, "0_")
if x == "i" {
x = "0i"
}
- lit.Value = x
}
+ case "0X":
+ x = "0x" + x[2:]
+ fallthrough
+ case "0x":
+ // possibly a hexadecimal float
+ if i := strings.LastIndexByte(x, 'P'); i >= 0 {
+ x = x[:i] + "p" + x[i+1:]
+ }
+ case "0O":
+ x = "0o" + x[2:]
+ case "0o":
+ // nothing to do
+ case "0B":
+ x = "0b" + x[2:]
+ case "0b":
+ // nothing to do
}
+ lit.Value = x
return false
}
-
-// isDecimals reports whether x consists entirely of decimal digits and underscores.
-func isDecimals(x string) bool {
- i := 0
- for i < len(x) && ('0' <= x[i] && x[i] <= '9' || x[i] == '_') {
- i++
- }
- return i == len(x)
-}
(-2.499956739197529585028819e+00 + 1.759751724335650228957144e+00i),
(7.357094338218116311191939e+04 - 5.089973412479151648145882e+04i),
(1.320777296067768517259592e+01 - 3.165621914333901498921986e+01i),
- (-3.123287828297300934072149e-07 - 1.9849567521490553032502223E-7i),
+ (-3.123287828297300934072149e-07 - 1.9849567521490553032502223e-7i),
(8.0622651468477229614813e+04 - 7.80028727944573092944363e+04i),
(-1.0268824572103165858577141e+00 - 4.716844738244989776610672e-01i),
(-4.35953819012244175753187e+01 + 2.2036445974645306917648585e+02i),