Add /codepoints
This commit is contained in:
+23
-4
@@ -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 " +."
|
||||
|
||||
Reference in New Issue
Block a user