Browse Source

Fix float formatting with tight-binding +/-

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.
pull/19/head
Fredrik Ekre 2 years ago
parent
commit
d7ea5f69a7
No known key found for this signature in database
GPG Key ID: DE82E6D5E364C0A2
  1. 7
      src/runestone.jl
  2. 18
      test/runtests.jl

7
src/runestone.jl

@ -96,6 +96,7 @@ function format_float_literals(ctx::Context, node::JuliaSyntax.GreenNode)
# Check and shortcut the happy path first # Check and shortcut the happy path first
r = r""" r = r"""
^ ^
(?:[+-])? # Optional sign
(?:(?:[1-9]\d*)|0) # Non-zero followed by any digit, or just a single zero (?:(?:[1-9]\d*)|0) # Non-zero followed by any digit, or just a single zero
\. # Decimal point \. # Decimal point
(?:(?:\d*[1-9])|0) # Any digit with a final nonzero, or just a single zero (?:(?:\d*[1-9])|0) # Any digit with a final nonzero, or just a single zero
@ -110,9 +111,13 @@ function format_float_literals(ctx::Context, node::JuliaSyntax.GreenNode)
return nothing return nothing
end end
# Split up the pieces # 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) m = match(r, str)
io = IOBuffer() # TODO: Could be reused? 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 # Strip leading zeros from integral part
int_part = isempty(m[:int]) ? "0" : m[:int] int_part = isempty(m[:int]) ? "0" : m[:int]
int_part = replace(int_part, r"^0*((?:[1-9]\d*)|0)$" => s"\1") int_part = replace(int_part, r"^0*((?:[1-9]\d*)|0)$" => s"\1")

18
test/runtests.jl

@ -79,13 +79,17 @@ end
["1f-3", "01f-3", "01.f-3", "1.f-3", "1.000f-3", "01.00f-3"] => "1.0f-3", ["1f-3", "01f-3", "01.f-3", "1.f-3", "1.000f-3", "01.00f-3"] => "1.0f-3",
] ]
mod = Module() mod = Module()
for (as, b) in test_cases for prefix in ("", "-", "+")
for a in as for (as, b) in test_cases
c = Core.eval(mod, Meta.parse(a)) b = prefix * b
d = Core.eval(mod, Meta.parse(b)) for a in as
@test c == d a = prefix * a
@test typeof(c) == typeof(d) c = Core.eval(mod, Meta.parse(a))
@test format_string(a) == b d = Core.eval(mod, Meta.parse(b))
@test c == d
@test typeof(c) == typeof(d)
@test format_string(a) == b
end
end end
end end
end end

Loading…
Cancel
Save