@@ -1,5 +1,14 @@
1module Data.String
1module Data.String
4+parseNumWithoutSign : List Char -> Integer -> Maybe Integer
5+parseNumWithoutSign [] acc = Just acc
6+parseNumWithoutSign (c :: cs) acc =
7+ if (c >= '0' && c <= '9')
8+ then parseNumWithoutSign cs ((acc * 10) + (cast ((ord c) - (ord '0'))))
3||| Convert a positive number string to a Num.
12||| Convert a positive number string to a Num.
5||| ```idris example
14||| ```idris example
@@ -15,15 +24,8 @@ parsePositive s = parsePosTrimmed (trim s)
15 parsePosTrimmed "" | StrNil = Nothing
24 parsePosTrimmed "" | StrNil = Nothing
16 parsePosTrimmed (strCons x xs) | (StrCons x xs) =
25 parsePosTrimmed (strCons x xs) | (StrCons x xs) =
17 if (x == '+')
26 if (x == '+')
18− then map fromInteger (parsePosAux (unpack xs) 0)
27+ then map fromInteger (parseNumWithoutSign (unpack xs) 0)
19− else map fromInteger (parsePosAux (unpack xs) (cast (ord x - ord '0')))
28+ else map fromInteger (parseNumWithoutSign (unpack xs) (cast (ord x - ord '0')))
21− parsePosAux : List Char -> Integer -> Maybe Integer
22− parsePosAux [] acc = Just acc
23− parsePosAux (c :: cs) acc =
24− if (c >= '0' && c <= '9')
25− then parsePosAux cs ((acc * 10) + (cast ((ord c) - (ord '0'))))
29||| Convert a number string to a Num.
31||| Convert a number string to a Num.
@@ -41,14 +43,68 @@ parseInteger s = parseIntTrimmed (trim s)
41 parseIntTrimmed "" | StrNil = Nothing
43 parseIntTrimmed "" | StrNil = Nothing
42 parseIntTrimmed (strCons x xs) | (StrCons x xs) =
44 parseIntTrimmed (strCons x xs) | (StrCons x xs) =
43 if (x == '-')
45 if (x == '-')
44− then map (\y => negate (fromInteger y)) (parseIntegerAux (unpack xs) 0)
46+ then map (\y => negate (fromInteger y)) (parseNumWithoutSign (unpack xs) 0)
45 else if (x == '+')
47 else if (x == '+')
46− then map fromInteger (parseIntegerAux (unpack xs) (cast {from=Int} 0))
48+ then map fromInteger (parseNumWithoutSign (unpack xs) (cast {from=Int} 0))
47− else map fromInteger (parseIntegerAux (unpack xs) (cast (ord x - ord '0')))
49+ else map fromInteger (parseNumWithoutSign (unpack xs) (cast (ord x - ord '0')))
49− parseIntegerAux : List Char -> Integer -> Maybe Integer
51+
50− parseIntegerAux [] acc = Just acc
52+||| Convert a number string to a Double.
51− parseIntegerAux (c :: cs) acc =
53+|||
52− if (c >= '0' && c <= '9')
54+||| ```idris example
53− then parseIntegerAux cs ((acc * 10) + (cast ((ord c) - (ord '0'))))
55+||| parseDouble "+123.123e-2"
58+||| parseDouble {a=Int} " -123.123E+2"
61+||| parseDouble {a=Int} " +123.123"
63+parseDouble : String -> Maybe Double
64+parseDouble = mkDouble . wfe . trim
66+ mkDouble (Just (w, f, e)) = let ex = intPow 10 e in
67+ Just $ (w * ex + f * ex)
68+ mkDouble Nothing = Nothing
71+ intPow : Integer -> Integer -> Double
72+ intPow base exp = if exp > 0 then (num base exp) else 1 / (num base exp)
75+ num base e = if e < 0
76+ then cast base * num base (e + 1)
77+ else cast base * num base (e - 1)
79+ wfe : String -> Maybe (Double, Double, Integer)
80+ wfe cs = case split (== '.') cs of
81+ (wholeAndExp :: []) =>
82+ case split (\c => c == 'e' || c == 'E') wholeAndExp of
85+ w <- cast <$> parseInteger whole
86+ e <- parseInteger exp
90+ w <- cast <$> parseInteger whole
93+ (whole::fracAndExp::[]) =>
94+ case split (\c => c == 'e' || c == 'E') fracAndExp of
95+ (""::exp::[]) => Nothing
98+ w <- cast <$> parseInteger whole
99+ f <- (/ (pow 10 (length frac))) <$>
100+ (cast <$> parseNumWithoutSign (unpack frac) 0)
101+ e <- parseInteger exp
102+ return (w, if w < 0 then (-f) else f, e)
105+ w <- cast <$> parseInteger whole
106+ f <- (/ (pow 10 (length frac))) <$>
107+ (cast <$> parseNumWithoutSign (unpack frac) 0)
108+ return (w, if w < 0 then (-f) else f, 0)
54− else Nothing
110+ _ => Nothing