module Streamly.Internal.Unicode.Parser
(
char
, charIgnoreCase
, string
, stringIgnoreCase
, dropSpace
, dropSpace1
, alpha
, alphaNum
, letter
, ascii
, asciiLower
, asciiUpper
, latin1
, lower
, upper
, mark
, printable
, punctuation
, separator
, space
, symbol
, digit
, octDigit
, hexDigit
, numeric
, signed
, double
, decimal
, hexadecimal
)
where
import Control.Applicative (Alternative(..))
import Data.Bits (Bits, (.|.), shiftL)
import Data.Char (ord)
import Streamly.Internal.Data.Parser (Parser)
import qualified Data.Char as Char
import qualified Streamly.Data.Fold as Fold
import qualified Streamly.Internal.Data.Parser as Parser
(
lmap
, satisfy
, listEq
, takeWhile1
, dropWhile
)
#define CHAR_PARSER_SIG(NAME) NAME :: Monad m => Parser Char m Char
#define CHAR_PARSER(NAME, PREDICATE) NAME = Parser.satisfy Char.PREDICATE
#define CHAR_PARSER_DOC(PREDICATE) -- | Match any character that satisfies 'Char.PREDICATE'
#define CHAR_PARSER_INLINE(NAME) {-# INLINE NAME #-}
CHAR_PARSER_DOC(isSpace)
CHAR_PARSER_INLINE(space)
CHAR_PARSER_SIG(space)
CHAR_PARSER(space,isSpace)
CHAR_PARSER_DOC(isLower)
CHAR_PARSER_INLINE(lower)
CHAR_PARSER_SIG(lower)
CHAR_PARSER(lower,isLower)
CHAR_PARSER_DOC(isUpper)
CHAR_PARSER_INLINE(upper)
CHAR_PARSER_SIG(upper)
CHAR_PARSER(upper,isUpper)
CHAR_PARSER_DOC(isAlpha)
CHAR_PARSER_INLINE(alpha)
CHAR_PARSER_SIG(alpha)
CHAR_PARSER(alpha,isAlpha)
CHAR_PARSER_DOC(isAlphaNum)
CHAR_PARSER_INLINE(alphaNum)
CHAR_PARSER_SIG(alphaNum)
CHAR_PARSER(alphaNum,isAlphaNum)
CHAR_PARSER_DOC(isPrint)
CHAR_PARSER_INLINE(printable)
CHAR_PARSER_SIG(printable)
CHAR_PARSER(printable,isPrint)
CHAR_PARSER_DOC(isDigit)
CHAR_PARSER_INLINE(digit)
CHAR_PARSER_SIG(digit)
CHAR_PARSER(digit,isDigit)
CHAR_PARSER_DOC(isOctDigit)
CHAR_PARSER_INLINE(octDigit)
CHAR_PARSER_SIG(octDigit)
CHAR_PARSER(octDigit,isOctDigit)
CHAR_PARSER_DOC(isHexDigit)
CHAR_PARSER_INLINE(hexDigit)
CHAR_PARSER_SIG(hexDigit)
CHAR_PARSER(hexDigit,isHexDigit)
CHAR_PARSER_DOC(isLetter)
CHAR_PARSER_INLINE(letter)
CHAR_PARSER_SIG(letter)
CHAR_PARSER(letter,isLetter)
CHAR_PARSER_DOC(isMark)
CHAR_PARSER_INLINE(mark)
CHAR_PARSER_SIG(mark)
CHAR_PARSER(mark,isMark)
CHAR_PARSER_DOC(isNumber)
CHAR_PARSER_INLINE(numeric)
CHAR_PARSER_SIG(numeric)
CHAR_PARSER(numeric,isNumber)
CHAR_PARSER_DOC(isPunctuation)
CHAR_PARSER_INLINE(punctuation)
CHAR_PARSER_SIG(punctuation)
punctuation :: Parser Char m Char
CHAR_PARSER(punctuation,isPunctuation)
CHAR_PARSER_DOC(isSymbol)
CHAR_PARSER_INLINE(symbol)
CHAR_PARSER_SIG(symbol)
CHAR_PARSER(symbol,isSymbol)
CHAR_PARSER_DOC(isSeparator)
CHAR_PARSER_INLINE(separator)
CHAR_PARSER_SIG(separator)
CHAR_PARSER(separator,isSeparator)
CHAR_PARSER_DOC(isAscii)
CHAR_PARSER_INLINE(ascii)
CHAR_PARSER_SIG(ascii)
CHAR_PARSER(ascii,isAscii)
CHAR_PARSER_DOC(isLatin1)
CHAR_PARSER_INLINE(latin1)
CHAR_PARSER_SIG(latin1)
CHAR_PARSER(latin1,isLatin1)
CHAR_PARSER_DOC(isAsciiUpper)
CHAR_PARSER_INLINE(asciiUpper)
CHAR_PARSER_SIG(asciiUpper)
CHAR_PARSER(asciiUpper,isAsciiUpper)
CHAR_PARSER_DOC(isAsciiLower)
CHAR_PARSER_INLINE(asciiLower)
CHAR_PARSER_SIG(asciiLower)
CHAR_PARSER(asciiLower,isAsciiLower)
{-# INLINE char #-}
char :: Monad m => Char -> Parser Char m Char
char :: Char -> Parser Char m Char
char Char
c = (Char -> Bool) -> Parser Char m Char
forall (m :: * -> *) a. Monad m => (a -> Bool) -> Parser a m a
Parser.satisfy (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
c)
{-# INLINE charIgnoreCase #-}
charIgnoreCase :: Monad m => Char -> Parser Char m Char
charIgnoreCase :: Char -> Parser Char m Char
charIgnoreCase Char
c = (Char -> Char) -> Parser Char m Char -> Parser Char m Char
forall a b (m :: * -> *) r.
(a -> b) -> Parser b m r -> Parser a m r
Parser.lmap Char -> Char
Char.toLower ((Char -> Bool) -> Parser Char m Char
forall (m :: * -> *) a. Monad m => (a -> Bool) -> Parser a m a
Parser.satisfy (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char -> Char
Char.toLower Char
c))
string :: Monad m => String -> Parser Char m String
string :: String -> Parser Char m String
string = String -> Parser Char m String
forall (m :: * -> *) a. (Monad m, Eq a) => [a] -> Parser a m [a]
Parser.listEq
stringIgnoreCase :: Monad m => String -> Parser Char m String
stringIgnoreCase :: String -> Parser Char m String
stringIgnoreCase String
s =
(Char -> Char) -> Parser Char m String -> Parser Char m String
forall a b (m :: * -> *) r.
(a -> b) -> Parser b m r -> Parser a m r
Parser.lmap Char -> Char
Char.toLower (String -> Parser Char m String
forall (m :: * -> *) a. (Monad m, Eq a) => [a] -> Parser a m [a]
Parser.listEq ((Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
Char.toLower String
s))
dropSpace :: Monad m => Parser Char m ()
dropSpace :: Parser Char m ()
dropSpace = (Char -> Bool) -> Parser Char m ()
forall (m :: * -> *) a. Monad m => (a -> Bool) -> Parser a m ()
Parser.dropWhile Char -> Bool
Char.isSpace
dropSpace1 :: Monad m => Parser Char m ()
dropSpace1 :: Parser Char m ()
dropSpace1 = (Char -> Bool) -> Fold m Char () -> Parser Char m ()
forall (m :: * -> *) a b.
Monad m =>
(a -> Bool) -> Fold m a b -> Parser a m b
Parser.takeWhile1 Char -> Bool
Char.isSpace Fold m Char ()
forall (m :: * -> *) a. Monad m => Fold m a ()
Fold.drain
{-# INLINE decimal #-}
decimal :: (Monad m, Integral a) => Parser Char m a
decimal :: Parser Char m a
decimal = (Char -> Bool) -> Fold m Char a -> Parser Char m a
forall (m :: * -> *) a b.
Monad m =>
(a -> Bool) -> Fold m a b -> Parser a m b
Parser.takeWhile1 Char -> Bool
Char.isDigit ((a -> Char -> a) -> a -> Fold m Char a
forall (m :: * -> *) b a.
Monad m =>
(b -> a -> b) -> b -> Fold m a b
Fold.foldl' a -> Char -> a
forall a. Num a => a -> Char -> a
step a
0)
where
step :: a -> Char -> a
step a
a Char
c = a
a a -> a -> a
forall a. Num a => a -> a -> a
* a
10 a -> a -> a
forall a. Num a => a -> a -> a
+ Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
48)
{-# INLINE hexadecimal #-}
hexadecimal :: (Monad m, Integral a, Bits a) => Parser Char m a
hexadecimal :: Parser Char m a
hexadecimal = (Char -> Bool) -> Fold m Char a -> Parser Char m a
forall (m :: * -> *) a b.
Monad m =>
(a -> Bool) -> Fold m a b -> Parser a m b
Parser.takeWhile1 Char -> Bool
isHexDigit ((a -> Char -> a) -> a -> Fold m Char a
forall (m :: * -> *) b a.
Monad m =>
(b -> a -> b) -> b -> Fold m a b
Fold.foldl' a -> Char -> a
forall a. (Bits a, Num a) => a -> Char -> a
step a
0)
where
isHexDigit :: Char -> Bool
isHexDigit Char
c =
(Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'9')
Bool -> Bool -> Bool
|| (Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'a' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'f')
Bool -> Bool -> Bool
|| (Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'A' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'F')
step :: a -> Char -> a
step a
a Char
c
| Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
48 Bool -> Bool -> Bool
&& Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
57 =
(a
a a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` Int
4) a -> a -> a
forall a. Bits a => a -> a -> a
.|. Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
48)
| Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
97 =
(a
a a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` Int
4) a -> a -> a
forall a. Bits a => a -> a -> a
.|. Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
87)
| Bool
otherwise =
(a
a a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` Int
4) a -> a -> a
forall a. Bits a => a -> a -> a
.|. Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
55)
where
w :: Int
w = Char -> Int
ord Char
c
{-# INLINE signed #-}
signed :: (Num a, Monad m) => Parser Char m a -> Parser Char m a
signed :: Parser Char m a -> Parser Char m a
signed Parser Char m a
p = (a -> a
forall a. Num a => a -> a
negate (a -> a) -> Parser Char m a -> Parser Char m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Parser Char m Char
forall (m :: * -> *). Monad m => Char -> Parser Char m Char
char Char
'-' Parser Char m Char -> Parser Char m a -> Parser Char m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Char m a
p)) Parser Char m a -> Parser Char m a -> Parser Char m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Char -> Parser Char m Char
forall (m :: * -> *). Monad m => Char -> Parser Char m Char
char Char
'+' Parser Char m Char -> Parser Char m a -> Parser Char m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Char m a
p) Parser Char m a -> Parser Char m a -> Parser Char m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Char m a
p
double :: Parser Char m Double
double :: Parser Char m Double
double = Parser Char m Double
forall a. HasCallStack => a
undefined