{-# OPTIONS_GHC -Wno-incomplete-patterns #-}
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
module Parsley.Char (
satisfy, char, item,
string, token,
oneOf, noneOf,
digit, letter, letterOrDigit
) where
import Prelude hiding (traverse)
import Data.Char (isAlpha, isAlphaNum)
import Data.List (sort)
import Parsley.Applicative (($>), traverse)
import Parsley.Defunctionalized (Defunc(LIFTED, RANGES))
import Parsley.Internal (Parser, makeQ)
import Parsley.ParserOps (satisfy)
import qualified Parsley.Internal as Internal (try)
string :: String -> Parser String
string :: String -> Parser String
string = (Char -> Parser Char) -> String -> Parser String
forall a b. (a -> Parser b) -> [a] -> Parser [b]
traverse Char -> Parser Char
char
oneOf :: [Char] -> Parser Char
oneOf :: String -> Parser Char
oneOf = Defunc (Char -> Bool) -> Parser Char
forall (rep :: Type -> Type).
ParserOps rep =>
rep (Char -> Bool) -> Parser Char
satisfy (Defunc (Char -> Bool) -> Parser Char)
-> (String -> Defunc (Char -> Bool)) -> String -> Parser Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> [(Char, Char)] -> Defunc (Char -> Bool)
RANGES Bool
True ([(Char, Char)] -> Defunc (Char -> Bool))
-> (String -> [(Char, Char)]) -> String -> Defunc (Char -> Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [(Char, Char)]
ranges
noneOf :: [Char] -> Parser Char
noneOf :: String -> Parser Char
noneOf = Defunc (Char -> Bool) -> Parser Char
forall (rep :: Type -> Type).
ParserOps rep =>
rep (Char -> Bool) -> Parser Char
satisfy (Defunc (Char -> Bool) -> Parser Char)
-> (String -> Defunc (Char -> Bool)) -> String -> Parser Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> [(Char, Char)] -> Defunc (Char -> Bool)
RANGES Bool
False ([(Char, Char)] -> Defunc (Char -> Bool))
-> (String -> [(Char, Char)]) -> String -> Defunc (Char -> Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [(Char, Char)]
ranges
ranges :: [Char] -> [(Char, Char)]
ranges :: String -> [(Char, Char)]
ranges [] = []
ranges (String -> String
forall a. Ord a => [a] -> [a]
sort -> Char
c:String
cs) = Char -> Int -> String -> [(Char, Char)]
go Char
c (Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
c) String
cs
where
go :: Char -> Int -> [Char] -> [(Char, Char)]
go :: Char -> Int -> String -> [(Char, Char)]
go Char
lower Int
prev [] = [(Char
lower, Int -> Char
forall a. Enum a => Int -> a
toEnum Int
prev)]
go Char
lower Int
prev (Char
c:String
cs)
| Int
i <- Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
c, Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
prev Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 = Char -> Int -> String -> [(Char, Char)]
go Char
lower Int
i String
cs
| Bool
otherwise = (Char
lower, Int -> Char
forall a. Enum a => Int -> a
toEnum Int
prev) (Char, Char) -> [(Char, Char)] -> [(Char, Char)]
forall a. a -> [a] -> [a]
: Char -> Int -> String -> [(Char, Char)]
go Char
c (Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
c) String
cs
token :: String -> Parser String
token :: String -> Parser String
token = Parser String -> Parser String
forall a. Parser a -> Parser a
Internal.try (Parser String -> Parser String)
-> (String -> Parser String) -> String -> Parser String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Parser String
string
char :: Char -> Parser Char
char :: Char -> Parser Char
char Char
c = Defunc (Char -> Bool) -> Parser Char
forall (rep :: Type -> Type).
ParserOps rep =>
rep (Char -> Bool) -> Parser Char
satisfy (Bool -> [(Char, Char)] -> Defunc (Char -> Bool)
RANGES Bool
True [(Char
c, Char
c)]) Parser Char -> Defunc Char -> Parser Char
forall (rep :: Type -> Type) a b.
ParserOps rep =>
Parser a -> rep b -> Parser b
$> Char -> Defunc Char
forall a. (Show a, Lift a, Typeable a) => a -> Defunc a
LIFTED Char
c
item :: Parser Char
item :: Parser Char
item = Defunc (Char -> Bool) -> Parser Char
forall (rep :: Type -> Type).
ParserOps rep =>
rep (Char -> Bool) -> Parser Char
satisfy (Bool -> [(Char, Char)] -> Defunc (Char -> Bool)
RANGES Bool
False [])
isDigit :: Defunc (Char -> Bool)
isDigit :: Defunc (Char -> Bool)
isDigit = Bool -> [(Char, Char)] -> Defunc (Char -> Bool)
RANGES Bool
True [(Char
'0', Char
'9')]
digit :: Parser Char
digit :: Parser Char
digit = Defunc (Char -> Bool) -> Parser Char
forall (rep :: Type -> Type).
ParserOps rep =>
rep (Char -> Bool) -> Parser Char
satisfy Defunc (Char -> Bool)
isDigit
letter :: Parser Char
letter :: Parser Char
letter = Defunc (Char -> Bool) -> Parser Char
forall (rep :: Type -> Type).
ParserOps rep =>
rep (Char -> Bool) -> Parser Char
satisfy ((Char -> Bool) -> Code (Char -> Bool) -> Defunc (Char -> Bool)
forall (q :: Type -> Type) a. Quapplicative q => a -> Code a -> q a
makeQ Char -> Bool
isAlpha [||isAlpha||])
letterOrDigit :: Parser Char
letterOrDigit :: Parser Char
letterOrDigit = Defunc (Char -> Bool) -> Parser Char
forall (rep :: Type -> Type).
ParserOps rep =>
rep (Char -> Bool) -> Parser Char
satisfy ((Char -> Bool) -> Code (Char -> Bool) -> Defunc (Char -> Bool)
forall (q :: Type -> Type) a. Quapplicative q => a -> Code a -> q a
makeQ Char -> Bool
isAlphaNum [||isAlphaNum||])