Skip to content

Commit 3a48437

Browse files
authored
Fix and improve float formatting (#1309)
* Don't break `12e+34` into `12e + 34` * Better implementation * Normalize floats
1 parent c84efd9 commit 3a48437

File tree

4 files changed

+82
-3
lines changed

4 files changed

+82
-3
lines changed

build/lex.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,12 +318,17 @@ func (in *input) startToken(val *yySymType) {
318318
// has not done that already.
319319
func (in *input) endToken(val *yySymType) {
320320
if val.tok == "" {
321-
tok := string(in.token[:len(in.token)-len(in.remaining)])
321+
tok := string(in.peekToken())
322322
val.tok = tok
323323
in.lastToken = val.tok
324324
}
325325
}
326326

327+
// peekToken returns the bytes comprising the current token being scanned.
328+
func (in *input) peekToken() []byte {
329+
return in.token[:len(in.token)-len(in.remaining)]
330+
}
331+
327332
// Lex is called from the generated parser to obtain the next input token.
328333
// It returns the token value (either a rune like '+' or a symbolic token _FOR)
329334
// and sets val to the data associated with the token.
@@ -619,7 +624,15 @@ func (in *input) Lex(val *yySymType) int {
619624
for {
620625
c := in.peekRune()
621626
if !isIdent(c) {
622-
break
627+
if c == '+' || c == '-' {
628+
t := in.peekToken()
629+
// Parse 12.3e-4 and 12.3E+4 as a single token.
630+
if !(len(t) > 0 && t[0] >= '0' && t[0] <= '9' && (t[len(t)-1] == 'e' || t[len(t)-1] == 'E')) {
631+
break
632+
}
633+
} else {
634+
break
635+
}
623636
}
624637
in.readRune()
625638
}

build/rewrite.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ var rewrites = []struct {
137137
{"formatdocstrings", formatDocstrings, scopeBoth},
138138
{"reorderarguments", reorderArguments, scopeBoth},
139139
{"editoctal", editOctals, scopeBoth},
140+
{"editfloat", editFloats, scopeBoth},
140141
}
141142

142143
// leaveAlone reports whether any of the nodes on the stack are marked
@@ -1399,6 +1400,35 @@ func editOctals(f *File, _ *Rewriter) {
13991400
})
14001401
}
14011402

1403+
// editFloats inserts '0' before the decimal point in floats and normalizes the
1404+
// exponent part to lowercase, no plus sign, and no leading zero.
1405+
func editFloats(f *File, _ *Rewriter) {
1406+
Walk(f, func(expr Expr, stack []Expr) {
1407+
l, ok := expr.(*LiteralExpr)
1408+
if !ok {
1409+
return
1410+
}
1411+
if !strings.ContainsRune(l.Token, '.') {
1412+
return
1413+
}
1414+
if strings.HasPrefix(l.Token, ".") {
1415+
l.Token = "0" + l.Token
1416+
}
1417+
if !strings.ContainsAny(l.Token, "eE") {
1418+
return
1419+
}
1420+
parts := strings.SplitN(l.Token, "e", 2)
1421+
if len(parts) != 2 {
1422+
parts = strings.SplitN(l.Token, "E", 2)
1423+
}
1424+
if len(parts) != 2 {
1425+
// Invalid float, skip rewriting.
1426+
return
1427+
}
1428+
l.Token = parts[0] + "e" + strings.TrimLeft(parts[1], "0+")
1429+
})
1430+
}
1431+
14021432
// removeParens removes trivial parens
14031433
func removeParens(f *File, _ *Rewriter) {
14041434
var simplify func(expr Expr, stack []Expr) Expr

build/testdata/003.golden

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,24 @@ numbers = [
33
11,
44
123.456,
55
123.,
6-
.456,
6+
0.456,
77
1.23e45,
8+
-1,
9+
+1,
10+
0.0,
11+
-0.0,
12+
1.0,
13+
-1.0,
14+
+1.0,
15+
1e6,
16+
-1e6,
17+
-1.23e-45,
18+
3.539537889086625e24,
19+
3.539537889086625e24,
20+
3.539537889086625e24000,
21+
3.539537889086625e24000,
22+
3539537889086624823140625,
23+
0x123,
24+
0xE45,
25+
0xe45,
826
]

build/testdata/003.in

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,22 @@ numbers = [
55
123.,
66
.456,
77
1.23e45,
8+
-1,
9+
+1,
10+
0.0,
11+
-0.0,
12+
1.0,
13+
-1.0,
14+
+1.0,
15+
1e6,
16+
-1e6,
17+
-1.23e-45,
18+
3.539537889086625e+24,
19+
3.539537889086625E+24,
20+
3.539537889086625e00024000,
21+
3.539537889086625e+00024000,
22+
3539537889086624823140625,
23+
0x123,
24+
0xE45,
25+
0xe45,
826
]

0 commit comments

Comments
 (0)