1
1
using Parsers
2
- using Parsers: AbstractConf, SourceType, XOPTIONS, Result
2
+ using Parsers: AbstractConf, Result
3
3
4
4
"""
5
5
RoundThrows
@@ -8,11 +8,15 @@ Raises an `InexactError` if any rounding is necessary.
8
8
"""
9
9
const RoundThrows = RoundingMode {:Throw} ()
10
10
11
+ # make our own conf struct to avoid specializing Parsers.typeparser on each unique precision value
11
12
struct FixedDecimalConf{T<: Integer } <: AbstractConf{T}
12
13
f:: Int
13
14
end
15
+ # this overload says that when parsing a FixedDecimal type, use our new custom FixedDecimalConf type
14
16
Parsers. conf (:: Type{FixedDecimal{T,f}} , opts:: Parsers.Options , kw... ) where {T<: Integer ,f} = FixedDecimalConf {T} (f)
17
+ # Because the value returned from our `typeparser` isn't a FixedDecimal, we overload here to show we're returning an integer type
15
18
Parsers. returntype (:: Type{FixedDecimal{T,f}} ) where {T,f} = T
19
+ # this overload allows us to take the Result{IntegerType} returned from typeparser and turn it into a FixedDecimal Result
16
20
function Parsers. result (FD:: Type{FixedDecimal{T,f}} , res:: Parsers.Result{T} ) where {T,f}
17
21
return Parsers. invalid (res. code) ? Result {FD} (res. code, res. tlen) :
18
22
Result {FD} (res. code, res. tlen, reinterpret (FD, res. val))
@@ -98,11 +102,12 @@ function _divpow10!(x::BigInt, code, pow, ::RoundingMode{:Throw})
98
102
end
99
103
100
104
# Rescale the digits we accumulated so far into the the a an integer representing the decimal
105
+ # Note the 2nd argument `FloatType` is used by Parsers.jl for _float_ parsing, but we can ignore in the fixed decimal case
101
106
@inline function Parsers. scale (
102
107
conf:: FixedDecimalConf{T} , :: Parsers.FloatType , digits:: V , exp, neg, code, ndigits, f:: F , options:: Parsers.Options
103
108
) where {T,V,F}
104
109
rounding = something (options. rounding, RoundThrows)
105
- # Positive: how many trailing zeroes we need to add to out integer
110
+ # Positive: how many trailing zeroes we need to add to our integer
106
111
# Negative: how many digits are past our precision (we need to handle them in rounding)
107
112
decimal_shift = conf. f + exp
108
113
# Number of digits we need to accumulate including any trailigng zeros or digits past our precision
111
116
if iszero (ndigits)
112
117
# all digits are zero
113
118
i = zero (T)
119
+ # The backing_integer_digits == 0 case is handled in the `else` (it means
120
+ # that all the digits are passed the precision but we might get `1` from rounding)
114
121
elseif backing_integer_digits < 0
115
122
# All digits are past our precision, no overflow possible
116
123
i = zero (T)
0 commit comments