Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix and improve float formatting #1309

Merged
merged 4 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions build/lex.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,12 +318,17 @@ func (in *input) startToken(val *yySymType) {
// has not done that already.
func (in *input) endToken(val *yySymType) {
if val.tok == "" {
tok := string(in.token[:len(in.token)-len(in.remaining)])
tok := string(in.peekToken())
val.tok = tok
in.lastToken = val.tok
}
}

// peekToken returns the bytes comprising the current token being scanned.
func (in *input) peekToken() []byte {
return in.token[:len(in.token)-len(in.remaining)]
}

// Lex is called from the generated parser to obtain the next input token.
// It returns the token value (either a rune like '+' or a symbolic token _FOR)
// and sets val to the data associated with the token.
Expand Down Expand Up @@ -619,7 +624,15 @@ func (in *input) Lex(val *yySymType) int {
for {
c := in.peekRune()
if !isIdent(c) {
break
if c == '+' || c == '-' {
t := in.peekToken()
// Parse 12.3e-4 and 12.3E+4 as a single token.
if !(len(t) > 0 && t[0] >= '0' && t[0] <= '9' && (t[len(t)-1] == 'e' || t[len(t)-1] == 'E')) {
break
}
} else {
break
}
}
in.readRune()
}
Expand Down
30 changes: 30 additions & 0 deletions build/rewrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ var rewrites = []struct {
{"formatdocstrings", formatDocstrings, scopeBoth},
{"reorderarguments", reorderArguments, scopeBoth},
{"editoctal", editOctals, scopeBoth},
{"editfloat", editFloats, scopeBoth},
}

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

// editFloats inserts '0' before the decimal point in floats and normalizes the
// exponent part to lowercase, no plus sign, and no leading zero.
func editFloats(f *File, _ *Rewriter) {
Walk(f, func(expr Expr, stack []Expr) {
l, ok := expr.(*LiteralExpr)
if !ok {
return
}
if !strings.ContainsRune(l.Token, '.') {
return
}
if strings.HasPrefix(l.Token, ".") {
l.Token = "0" + l.Token
}
if !strings.ContainsAny(l.Token, "eE") {
return
}
parts := strings.SplitN(l.Token, "e", 2)
if len(parts) != 2 {
parts = strings.SplitN(l.Token, "E", 2)
}
if len(parts) != 2 {
// Invalid float, skip rewriting.
return
}
l.Token = parts[0] + "e" + strings.TrimLeft(parts[1], "0+")
})
}

// removeParens removes trivial parens
func removeParens(f *File, _ *Rewriter) {
var simplify func(expr Expr, stack []Expr) Expr
Expand Down
20 changes: 19 additions & 1 deletion build/testdata/003.golden
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,24 @@ numbers = [
11,
123.456,
123.,
.456,
0.456,
1.23e45,
-1,
+1,
0.0,
-0.0,
1.0,
-1.0,
+1.0,
1e6,
-1e6,
-1.23e-45,
3.539537889086625e24,
3.539537889086625e24,
3.539537889086625e24000,
3.539537889086625e24000,
3539537889086624823140625,
0x123,
0xE45,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this E also be lowercased?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or this is invalid and just left as is?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a float, but a hex number. We could discuss whether hex literals should be canonicalized in some way, but I would prefer to handle that in a separate PR.

0xe45,
]
18 changes: 18 additions & 0 deletions build/testdata/003.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,22 @@ numbers = [
123.,
.456,
1.23e45,
-1,
+1,
0.0,
-0.0,
1.0,
-1.0,
+1.0,
1e6,
-1e6,
-1.23e-45,
3.539537889086625e+24,
3.539537889086625E+24,
3.539537889086625e00024000,
3.539537889086625e+00024000,
3539537889086624823140625,
0x123,
0xE45,
0xe45,
]