Skip to content

Commit

Permalink
Fix float formatting with tight-binding +/-
Browse files Browse the repository at this point in the history
A leading `+`/`-` is part of the float literal if there is no space in
between (in which case it becomes a call). This patch fixes the regexes
to handle this for float parsing.
  • Loading branch information
fredrikekre committed May 27, 2024
1 parent c84fb37 commit 7a8fb3e
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
7 changes: 6 additions & 1 deletion src/runestone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ function format_float_literals(ctx::Context, node::JuliaSyntax.GreenNode)
# Check and shortcut the happy path first
r = r"""
^
(?:[+-])? # Optional sign
(?:(?:[1-9]\d*)|0) # Non-zero followed by any digit, or just a single zero
\. # Decimal point
(?:(?:\d*[1-9])|0) # Any digit with a final nonzero, or just a single zero
Expand All @@ -110,9 +111,13 @@ function format_float_literals(ctx::Context, node::JuliaSyntax.GreenNode)
return nothing
end
# Split up the pieces
r = r"^(?<int>\d*)(?:\.?(?<frac>\d*))?(?:(?<epm>[eEf][+-]?)(?<exp>\d+))?$"
r = r"^(?<sgn>[+-])?(?<int>\d*)(?:\.?(?<frac>\d*))?(?:(?<epm>[eEf][+-]?)(?<exp>\d+))?$"
m = match(r, str)
io = IOBuffer() # TODO: Could be reused?
# Write the sign part
if (sgn = m[:sgn]; sgn !== nothing)
write(io, sgn)
end
# Strip leading zeros from integral part
int_part = isempty(m[:int]) ? "0" : m[:int]
int_part = replace(int_part, r"^0*((?:[1-9]\d*)|0)$" => s"\1")
Expand Down
18 changes: 11 additions & 7 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,17 @@ end
["1f-3", "01f-3", "01.f-3", "1.f-3", "1.000f-3", "01.00f-3"] => "1.0f-3",
]
mod = Module()
for (as, b) in test_cases
for a in as
c = Core.eval(mod, Meta.parse(a))
d = Core.eval(mod, Meta.parse(b))
@test c == d
@test typeof(c) == typeof(d)
@test format_string(a) == b
for prefix in ("", "-", "+")
for (as, b) in test_cases
b = prefix * b
for a in as
a = prefix * a
c = Core.eval(mod, Meta.parse(a))
d = Core.eval(mod, Meta.parse(b))
@test c == d
@test typeof(c) == typeof(d)
@test format_string(a) == b
end
end
end
end
Expand Down

0 comments on commit 7a8fb3e

Please sign in to comment.