Add /codepoints

This commit is contained in:
2023-03-01 03:41:39 +01:00
parent 3a817a8e7a
commit 944edaf445
2 changed files with 82 additions and 14 deletions
+23 -4
View File
@@ -1,8 +1,9 @@
module UToy.Parsers
( parseHexBytes
, parseCodepoints
) where
import Data.Char (isHexDigit, ord)
import Data.Char (isDigit, isHexDigit, ord)
import Data.Text (Text)
import Data.Word (Word8)
import Text.Printf (printf)
@@ -23,9 +24,27 @@ hexBytes = hexByte `Atto.sepBy` separators
hexDigit = hexDigitToInt <$> Atto.satisfy isHexDigit
hexDigitToInt c
| '0' <= c && c <= '9' = ord c - ord '0'
| isDigit c = ord c - ord '0'
| 'A' <= c && c <= 'F' = ord c - ord 'A' + 10
| 'a' <= c && c <= 'f' = ord c - ord 'a' + 10
| otherwise = error $ printf "not a hex digit: %c" c
separators = Atto.skipMany $ Atto.satisfy $ Atto.inClass " +."
parseCodepoints :: Text -> Either String [Word]
parseCodepoints = Atto.parseOnly $ codepoints <* Atto.endOfInput
codepoints :: Atto.Parser [Word]
codepoints = codepoint `Atto.sepBy` separators
where
codepoint = Atto.choice [literal, decLiteral, hexLiteral]
literal = Atto.decimal
decLiteral = Atto.char 'd' *> Atto.decimal
hexLiteral = Atto.char 'x' *> Atto.hexadecimal
-- Common
separators :: Atto.Parser ()
separators = Atto.skipMany $ Atto.satisfy $ Atto.inClass " +."