Skip to content

Commit ea15a1e

Browse files
committed
Hex numbers now implemented
1 parent ced40c4 commit ea15a1e

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/Parse/Number.gren

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ type Outcome
1717
type Error
1818
= NotANumber
1919
| LeadingZero
20-
| TerminatingDot
20+
| ExpectedInt
21+
| ExpectedHex
2122

2223

2324
parser : Parser c Error Outcome
@@ -62,7 +63,7 @@ numParser =
6263
(\_ ->
6364
Parser.oneOf
6465
[ Parser.chompIf (\c -> c == 'x') NotANumber
65-
|> Parser.andThen (\_ -> Parser.succeed (Hex 0))
66+
|> Parser.andThen (\_ -> hexParser)
6667
, Parser.chompIf (\c -> c == '.') NotANumber
6768
|> Parser.andThen (\_ -> fractalParser "0")
6869
, Parser.chompIf Char.isDigit NotANumber
@@ -91,7 +92,7 @@ numParser =
9192

9293
fractalParser : String -> Parser c Error Outcome
9394
fractalParser str =
94-
Parser.chompIf Char.isDigit TerminatingDot
95+
Parser.chompIf Char.isDigit ExpectedInt
9596
|> Parser.skip (Parser.chompWhile Char.isDigit)
9697
|> Parser.getChompedString
9798
|> Parser.andThen
@@ -103,3 +104,37 @@ fractalParser str =
103104
Just float ->
104105
Parser.succeed (FloatingPoint float)
105106
)
107+
108+
hexParser : Parser c Error Outcome
109+
hexParser =
110+
Parser.chompIf Char.isHexDigit ExpectedHex
111+
|> Parser.skip (Parser.chompWhile Char.isHexDigit)
112+
|> Parser.getChompedString
113+
|> Parser.andThen
114+
(\hexString ->
115+
String.foldl hexFolder 0 hexString
116+
|> Hex
117+
|> Parser.succeed
118+
)
119+
120+
121+
hexFolder : Char -> Int -> Int
122+
hexFolder char acc =
123+
let
124+
charCode =
125+
Char.toCode char
126+
in
127+
if charCode >= 48 && charCode <= 57 then
128+
-- 0-9
129+
16 * acc + charCode - 48
130+
131+
else if charCode >= 65 && charCode <= 70 then
132+
-- A-F
133+
16 * acc + 10 + charCode - 65
134+
135+
else if charCode >= 97 && charCode <= 102 then
136+
-- a-f
137+
16 * acc + 10 + charCode - 97
138+
139+
else
140+
acc

tests/src/Test/Parse/Number.gren

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ tests =
4242
|> Expect.equal (Ok (PN.FloatingPoint float))
4343
, test "Requires a number after ." <| \{} ->
4444
run "0."
45-
|> expectErr PN.TerminatingDot
45+
|> expectErr PN.ExpectedInt
4646
, test "when followed by letter, it fails" <| \{} ->
4747
run "0.15a"
4848
|> expectErr PN.NotANumber
@@ -51,6 +51,12 @@ tests =
5151
[ test "Can parse hex" <| \{} ->
5252
run "0xAFFE"
5353
|> Expect.equal (Ok (PN.Hex 45054))
54+
, test "Requires a hex digit after 0x" <| \{} ->
55+
run "0x"
56+
|> expectErr PN.ExpectedHex
57+
, test "When followed by illegal character, it fails" <| \{} ->
58+
run "0xABZ"
59+
|> expectErr PN.NotANumber
5460
]
5561
]
5662

0 commit comments

Comments
 (0)