11module Parse.Number exposing
2- ( Format (..)
3- , Outcome (..)
2+ ( Outcome (..)
43 , Error (..)
54 , parser
65 )
@@ -9,14 +8,10 @@ module Parse.Number exposing
98import Parser.Advanced as Parser exposing (Parser)
109
1110
12- type Format
13- = Decimal
14- | Hex
15-
16-
1711type Outcome
18- = Integer { format: Format, value : Int }
12+ = Integer Int
1913 | FloatingPoint Float
14+ | Hex Int
2015
2116
2217type Error
@@ -27,41 +22,84 @@ type Error
2722
2823parser : Parser c Error Outcome
2924parser =
30- Parser.chompIf (\c -> c == '-' || Char.isDigit c) NotANumber
31- |> Parser.skip (Parser.chompWhile Char.isDigit)
32- |> Parser.getChompedString
25+ Parser.oneOf
26+ [ Parser.succeed
27+ (\outcome ->
28+ when outcome is
29+ Integer int ->
30+ Integer (negate int)
31+
32+ FloatingPoint float ->
33+ FloatingPoint (negate float)
34+
35+ Hex hex ->
36+ Hex (negate hex)
37+ )
38+ |> Parser.skip (Parser.symbol negateSign)
39+ |> Parser.keep numParser
40+ , numParser
41+ ]
3342 |> Parser.andThen
34- (\str ->
35- if String.count str > 1 && (String.startsWith "0" str || String.startsWith "-0" str) then
36- Parser.problem LeadingZero
43+ (\successCase ->
44+ Parser.oneOf
45+ [ Parser.chompIf Char.isAlpha NotANumber
46+ |> Parser.andThen (\_ -> Parser.problem NotANumber)
47+ , Parser.succeed successCase
48+ ]
49+ )
50+
3751
38- else
52+ negateSign : Parser.Token Error
53+ negateSign =
54+ Parser.Token { str = "-", expecting = NotANumber }
55+
56+
57+ numParser : Parser c Error Outcome
58+ numParser =
59+ Parser.oneOf
60+ [ Parser.chompIf (\c -> c == '0') NotANumber
61+ |> Parser.andThen
62+ (\_ ->
63+ Parser.oneOf
64+ [ Parser.chompIf (\c -> c == 'x') NotANumber
65+ |> Parser.andThen (\_ -> Parser.succeed (Hex 0))
66+ , Parser.chompIf (\c -> c == '.') NotANumber
67+ |> Parser.andThen (\_ -> fractalParser "0")
68+ , Parser.chompIf Char.isDigit NotANumber
69+ |> Parser.andThen (\_ -> Parser.problem LeadingZero)
70+ , Parser.succeed (Integer 0)
71+ ]
72+ )
73+ , Parser.chompIf Char.isDigit NotANumber
74+ |> Parser.skip (Parser.chompWhile Char.isDigit)
75+ |> Parser.getChompedString
76+ |> Parser.andThen
77+ (\str ->
3978 when String.toInt str is
4079 Nothing ->
4180 Parser.problem NotANumber
4281
4382 Just num ->
4483 Parser.oneOf
4584 [ Parser.chompIf (\c -> c == '.') NotANumber
46- |> Parser.skip (Parser.chompWhile Char.isDigit)
47- |> Parser.getChompedString
48- |> Parser.andThen
49- (\postDot ->
50- if postDot == "." then
51- Parser.problem TerminatingDot
52-
53- else
54- when String.toFloat (str ++ postDot) is
55- Nothing ->
56- Parser.problem NotANumber
57-
58- Just float ->
59- Parser.succeed (FloatingPoint float)
60- )
61- , Parser.succeed <|
62- Integer
63- { format = Decimal
64- , value = num
65- }
85+ |> Parser.andThen (\_ -> fractalParser str)
86+ , Parser.succeed (Integer num)
6687 ]
88+ )
89+ ]
90+
91+
92+ fractalParser : String -> Parser c Error Outcome
93+ fractalParser str =
94+ Parser.chompIf Char.isDigit TerminatingDot
95+ |> Parser.skip (Parser.chompWhile Char.isDigit)
96+ |> Parser.getChompedString
97+ |> Parser.andThen
98+ (\postDot ->
99+ when String.toFloat (str ++ "." ++ postDot) is
100+ Nothing ->
101+ Parser.problem NotANumber
102+
103+ Just float ->
104+ Parser.succeed (FloatingPoint float)
67105 )
0 commit comments