lib: support scientific number notation (#704, #706)

closes simonmichael/hledger#704
This commit is contained in:
Mykola Orliuk 2018-02-09 23:18:16 +01:00 committed by Simon Michael
parent a8dc474a27
commit b377bff90a
2 changed files with 114 additions and 2 deletions

View File

@ -21,6 +21,7 @@ where
--- * imports
import Prelude ()
import Prelude.Compat hiding (readFile)
import Control.Arrow ((***))
import Control.Monad.Compat
import Control.Monad.Except (ExceptT(..), runExceptT, throwError) --, catchError)
import Control.Monad.State.Strict
@ -464,10 +465,12 @@ rightsymbolamountp = do
m <- lift multiplierp
sign <- lift signp
rawnum <- lift $ rawnumberp
expMod <- lift . option id $ try exponentp
commodityspaced <- lift $ skipMany' spacenonewline
c <- lift commoditysymbolp
suggestedStyle <- getAmountStyle c
let (q,prec,mdec,mgrps) = fromRawNumber suggestedStyle (sign == "-") rawnum
let (q0,prec0,mdec,mgrps) = fromRawNumber suggestedStyle (sign == "-") rawnum
(q, prec) = expMod (q0, prec0)
p <- priceamountp
let s = amountstyle{ascommodityside=R, ascommodityspaced=commodityspaced, asprecision=prec, asdecimalpoint=mdec, asdigitgroups=mgrps}
return $ Amount c q p s m
@ -572,9 +575,20 @@ numberp suggestedStyle = do
sign <- signp
raw <- rawnumberp
dbg8 "numberp parsed" raw `seq` return ()
return $ dbg8 "numberp quantity,precision,mdecimalpoint,mgrps" (fromRawNumber suggestedStyle (sign == "-") raw)
let num@(q, prec, decSep, groups) = dbg8 "numberp quantity,precision,mdecimalpoint,mgrps" (fromRawNumber suggestedStyle (sign == "-") raw)
option num . try $ do
when (isJust groups) $ fail "groups and exponent are not mixable"
(q', prec') <- exponentp <*> pure (q, prec)
return (q', prec', decSep, groups)
<?> "numberp"
exponentp :: TextParser m ((Quantity, Int) -> (Quantity, Int))
exponentp = do
char' 'e'
exp <- liftM read $ (++) <$> signp <*> some digitChar
return $ (* 10^^exp) *** (0 `max`) . (+ (-exp))
<?> "exponentp"
fromRawNumber :: Maybe AmountStyle -> Bool -> (Maybe Char, [String], Maybe (Char, String)) -> (Quantity, Int, Maybe Char, Maybe DigitGroupStyle)
fromRawNumber suggestedStyle negated raw = (quantity, precision, mdecimalpoint, mgrps) where
-- unpack with a hint if useful

View File

@ -0,0 +1,98 @@
# just check
hledger -f - bal --no-total
<<<
D $1,000.00
2018/1/1
(a) 2.3
>>>
$2.30 a
>>>=0
# some basic cases with commodity
hledger -f - bal --no-total
<<<
commodity $1,000.00000000
2018/1/1
a $1.05e2
b $31415926e-7
c $1E+3
d
>>>
$105.00000000 a
$3.14159260 b
$1,000.00000000 c
$-1,108.14159260 d
>>>=0
# some basic cases with commodity
hledger -f - print --explicit
<<<
commodity $1,000.00000000
2018/1/1
a $1.05e2
b $31415926e-7
c $1E+3
d
>>>
2018/01/01
a $105.00000000
b $3.14159260
c $1,000.00000000
d $-1,108.14159260
>>>=0
#
# some basic cases
hledger -f - bal --no-total
<<<
2018/1/1
a 1.05e2
b 31415926e-7
c 1E+3
d
>>>
105.0000000 a
3.1415926 b
1000.0000000 c
-1108.1415926 d
>>>2
>>>=0
# some strang effect of default
hledger -f - bal --no-total
<<<
D $1,000.00
2018/1/1
a 1.050000e2
b 31415926e-7
c 1E+3
d
>>>
$105.0000000 a
$3.1415926 b
$1,000.0000000 c
$-1,108.1415926 d
>>>2
>>>=0
# we still should recognize commodities with e
hledger -f - bal --no-total
<<<
2018/1/1
(a) 1.00005e
(a) 2.00003E
>>>
2.00003E
1.00005e a
>>>=0
hledger -f - reg
<<<
2018/1/1
(a) 1,000.5e-1
>>>
>>>=1