{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
module Aeson.Match.QQ.Internal.Parse
  ( parse
  ) where

import           Control.Applicative ((<|>), optional)
import qualified Data.Aeson.Parser as Aeson
import qualified Data.Attoparsec.ByteString as Atto
import qualified Data.ByteString as ByteString
-- cannot use .Text here due to .Aeson parsers being tied to .ByteString
import           Data.ByteString (ByteString)
import qualified Data.CaseInsensitive as CI
import qualified Data.Char as Char
import           Data.Foldable (asum)
import qualified Data.HashMap.Strict as HashMap
import           Data.Maybe (isJust)
import           Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import qualified Data.Vector as Vector
import           Data.Word (Word8)
import           Language.Haskell.Meta.Parse (parseExp)
import           Language.Haskell.TH (Exp(..))
import           Prelude hiding (any, null)

import           Aeson.Match.QQ.Internal.Value
  ( Matcher(..)
  , Box(..)
  , HoleSig(..)
  , Type(..)
  )


-- | An 'attoparsec' parser for a 'Matcher'.
--
-- /Note:/ consumes spaces before and after the matcher.
parse :: ByteString -> Either String (Matcher Exp)
parse :: ByteString -> Either [Char] (Matcher Exp)
parse =
  forall a. Parser a -> ByteString -> Either [Char] a
Atto.parseOnly (Parser ByteString (Matcher Exp)
value forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
eof)

value :: Atto.Parser (Matcher Exp)
value :: Parser ByteString (Matcher Exp)
value = do
  Matcher Exp
val <- forall {f :: * -> *} {a} {b} {a}.
Applicative f =>
f a -> f b -> f a -> f a
between Parser ()
spaces Parser ()
spaces forall a b. (a -> b) -> a -> b
$ do
    Word8
b <- Parser Word8
Atto.peekWord8'
    case Word8
b of
      Word8
HoleP ->
        Parser ByteString (Matcher Exp)
any
      Word8
NP ->
        Parser ByteString (Matcher Exp)
null
      Word8
FP ->
        Parser ByteString (Matcher Exp)
false
      Word8
TP ->
        Parser ByteString (Matcher Exp)
true
      Word8
DoubleQuoteP ->
        Parser ByteString (Matcher Exp)
string
      Word8
OpenSquareBracketP ->
        Parser ByteString (Matcher Exp)
array
      Word8
OpenParenP ->
        Parser ByteString (Matcher Exp)
arrayUO forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ByteString (Matcher Exp)
stringCI
      Word8
OpenCurlyBracketP ->
        Parser ByteString (Matcher Exp)
object
      Word8
HashP ->
        Parser ByteString (Matcher Exp)
haskellExp
      Word8
_ | Word8 -> Bool
startOfNumber Word8
b ->
          Parser ByteString (Matcher Exp)
number
        | Bool
otherwise ->
          forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char]
"a value cannot start with " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Word8
b)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (Matcher Exp -> Matcher Exp
optimize Matcher Exp
val)
 where
  startOfNumber :: Word8 -> Bool
startOfNumber Word8
b =
    Word8
b forall a. Ord a => a -> a -> Bool
>= Word8
ZeroP Bool -> Bool -> Bool
&& Word8
b forall a. Ord a => a -> a -> Bool
<= Word8
NineP Bool -> Bool -> Bool
|| Word8
b forall a. Eq a => a -> a -> Bool
== Word8
MinusP
  between :: f a -> f b -> f a -> f a
between f a
a f b
b f a
p =
    f a
a forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> f a
p forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* f b
b

optimize :: Matcher Exp -> Matcher Exp
optimize :: Matcher Exp -> Matcher Exp
optimize = \case
  -- [...] -> _ : array
  Array Box {extra :: forall a. Box a -> Bool
extra = Bool
True, values :: forall a. Box a -> a
values = (forall a. Vector a -> Bool
Vector.null -> Bool
True)} ->
    forall ext. Maybe HoleSig -> Maybe Text -> Matcher ext
Hole (forall a. a -> Maybe a
Just (Type -> Bool -> HoleSig
HoleSig Type
ArrayT Bool
False)) forall a. Maybe a
Nothing
  -- this optimization is probably never going to be used,
  -- but I'll include it for completeness:
  -- (unordered) [...] -> _ : unordered-array
  ArrayUO Box {extra :: forall a. Box a -> Bool
extra = Bool
True, values :: forall a. Box a -> a
values = (forall a. Vector a -> Bool
Vector.null -> Bool
True)} ->
    forall ext. Maybe HoleSig -> Maybe Text -> Matcher ext
Hole (forall a. a -> Maybe a
Just (Type -> Bool -> HoleSig
HoleSig Type
ArrayUOT Bool
False)) forall a. Maybe a
Nothing
  -- {...} -> _ : object
  Object Box {extra :: forall a. Box a -> Bool
extra = Bool
True, values :: forall a. Box a -> a
values = (forall k v. HashMap k v -> Bool
HashMap.null -> Bool
True)} ->
    forall ext. Maybe HoleSig -> Maybe Text -> Matcher ext
Hole (forall a. a -> Maybe a
Just (Type -> Bool -> HoleSig
HoleSig Type
ObjectT Bool
False)) forall a. Maybe a
Nothing
  Matcher Exp
val ->
    Matcher Exp
val

any :: Atto.Parser (Matcher Exp)
any :: Parser ByteString (Matcher Exp)
any = do
  Word8
_ <- Word8 -> Parser Word8
Atto.word8 Word8
HoleP
  Maybe Text
name <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Maybe a
Just Parser Text
key forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
  Parser ()
spaces
  Maybe Word8
b <- forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser Word8
Atto.peekWord8'
  Maybe HoleSig
expectedType <- case Maybe Word8
b of
    Just Word8
ColonP ->
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Maybe a
Just Parser HoleSig
holeSig
    Maybe Word8
_ ->
      forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall ext. Maybe HoleSig -> Maybe Text -> Matcher ext
Hole Maybe HoleSig
expectedType Maybe Text
name)

null :: Atto.Parser (Matcher Exp)
null :: Parser ByteString (Matcher Exp)
null =
  forall ext. Matcher ext
Null forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ByteString -> Parser ByteString
Atto.string ByteString
"null"

false :: Atto.Parser (Matcher Exp)
false :: Parser ByteString (Matcher Exp)
false =
  forall ext. Bool -> Matcher ext
Bool Bool
False forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ByteString -> Parser ByteString
Atto.string ByteString
"false"

true :: Atto.Parser (Matcher Exp)
true :: Parser ByteString (Matcher Exp)
true =
  forall ext. Bool -> Matcher ext
Bool Bool
True forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ByteString -> Parser ByteString
Atto.string ByteString
"true"

number :: Atto.Parser (Matcher Exp)
number :: Parser ByteString (Matcher Exp)
number =
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ext. Scientific -> Matcher ext
Number Parser Scientific
Aeson.scientific

string :: Atto.Parser (Matcher Exp)
string :: Parser ByteString (Matcher Exp)
string =
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ext. Text -> Matcher ext
String Parser Text
Aeson.jstring

stringCI :: Atto.Parser (Matcher Exp)
stringCI :: Parser ByteString (Matcher Exp)
stringCI = do
  ByteString
_ <- ByteString -> Parser ByteString
Atto.string ByteString
"(ci)"
  Parser ()
spaces
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall ext. CI Text -> Matcher ext
StringCI forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s. FoldCase s => s -> CI s
CI.mk) Parser Text
Aeson.jstring

array :: Atto.Parser (Matcher Exp)
array :: Parser ByteString (Matcher Exp)
array = do
  Word8
_ <- Word8 -> Parser Word8
Atto.word8 Word8
OpenSquareBracketP
  Parser ()
spaces
  Word8
b <- Parser Word8
Atto.peekWord8'
  case Word8
b of
    Word8
CloseSquareBracketP -> do
      Word8
_ <- Word8 -> Parser Word8
Atto.word8 Word8
CloseSquareBracketP
      forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall ext. Array ext -> Matcher ext
Array Box {values :: Vector (Matcher Exp)
values = forall a. Vector a
Vector.empty, extra :: Bool
extra = Bool
False})
    Word8
_ -> do
      [Matcher Exp] -> Int -> Parser ByteString (Matcher Exp)
loop [] Int
0
 where
  loop :: [Matcher Exp] -> Int -> Parser ByteString (Matcher Exp)
loop [Matcher Exp]
acc !Int
n = do
    Parser ()
spaces
    Word8
b <- Parser Word8
Atto.peekWord8'
    case Word8
b of
      Word8
DotP -> do
       Parser ()
rest
       Parser ()
spaces
       Word8
_ <- Word8 -> Parser Word8
Atto.word8 Word8
CloseSquareBracketP
       forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall ext. Array ext -> Matcher ext
Array Box
         { values :: Vector (Matcher Exp)
values = forall a. Int -> [a] -> Vector a
Vector.fromListN (Int
n forall a. Num a => a -> a -> a
+ Int
1) (forall a. [a] -> [a]
reverse [Matcher Exp]
acc)
         , extra :: Bool
extra = Bool
True
         }
      Word8
_ -> do
       Matcher Exp
val <- Parser ByteString (Matcher Exp)
value
       Word8
sep <- (Word8 -> Bool) -> Parser Word8
Atto.satisfy (\Word8
w -> Word8
w forall a. Eq a => a -> a -> Bool
== Word8
CommaP Bool -> Bool -> Bool
|| Word8
w forall a. Eq a => a -> a -> Bool
== Word8
CloseSquareBracketP) forall i a. Parser i a -> [Char] -> Parser i a
Atto.<?> [Char]
"',' or ']'"
       case Word8
sep of
         Word8
CommaP ->
           [Matcher Exp] -> Int -> Parser ByteString (Matcher Exp)
loop (Matcher Exp
val forall a. a -> [a] -> [a]
: [Matcher Exp]
acc) (Int
n forall a. Num a => a -> a -> a
+ Int
1)
         Word8
CloseSquareBracketP ->
           forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall ext. Array ext -> Matcher ext
Array Box
             { values :: Vector (Matcher Exp)
values = forall a. Int -> [a] -> Vector a
Vector.fromListN (Int
n forall a. Num a => a -> a -> a
+ Int
1) (forall a. [a] -> [a]
reverse (Matcher Exp
val forall a. a -> [a] -> [a]
: [Matcher Exp]
acc))
             , extra :: Bool
extra = Bool
False
             }
         Word8
_ ->
           forall a. HasCallStack => [Char] -> a
error [Char]
"impossible"

arrayUO :: Atto.Parser (Matcher Exp)
arrayUO :: Parser ByteString (Matcher Exp)
arrayUO = do
  ByteString
_ <- ByteString -> Parser ByteString
Atto.string ByteString
"(unordered)"
  Parser ()
spaces
  Array Box (Vector (Matcher Exp))
box <- Parser ByteString (Matcher Exp)
array
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall ext. Array ext -> Matcher ext
ArrayUO Box (Vector (Matcher Exp))
box)

object :: Atto.Parser (Matcher Exp)
object :: Parser ByteString (Matcher Exp)
object = do
  Word8
_ <- Word8 -> Parser Word8
Atto.word8 Word8
OpenCurlyBracketP
  Parser ()
spaces
  Word8
b <- Parser Word8
Atto.peekWord8'
  case Word8
b of
    Word8
CloseCurlyBracketP -> do
      Word8
_ <- Word8 -> Parser Word8
Atto.word8 Word8
CloseCurlyBracketP
      forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall ext. Object ext -> Matcher ext
Object Box {values :: HashMap Text (Matcher Exp)
values = forall k v. HashMap k v
HashMap.empty, extra :: Bool
extra = Bool
False})
    Word8
_ ->
      [(Text, Matcher Exp)] -> Parser ByteString (Matcher Exp)
loop []
 where
  loop :: [(Text, Matcher Exp)] -> Parser ByteString (Matcher Exp)
loop [(Text, Matcher Exp)]
acc = do
    Parser ()
spaces
    Word8
b <- Parser Word8
Atto.peekWord8'
    case Word8
b of
      Word8
DotP -> do
        Parser ()
rest
        Parser ()
spaces
        Word8
_ <- Word8 -> Parser Word8
Atto.word8 Word8
CloseCurlyBracketP
        forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall ext. Object ext -> Matcher ext
Object Box
          { values :: HashMap Text (Matcher Exp)
values = forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList [(Text, Matcher Exp)]
acc
          , extra :: Bool
extra = Bool
True
          }
      Word8
_ -> do
        Text
k <- Parser Text
key
        Parser ()
spaces
        Word8
_ <- Word8 -> Parser Word8
Atto.word8 Word8
ColonP
        Matcher Exp
val <- Parser ByteString (Matcher Exp)
value
        Word8
sep <- (Word8 -> Bool) -> Parser Word8
Atto.satisfy (\Word8
w -> Word8
w forall a. Eq a => a -> a -> Bool
== Word8
CommaP Bool -> Bool -> Bool
|| Word8
w forall a. Eq a => a -> a -> Bool
== Word8
CloseCurlyBracketP) forall i a. Parser i a -> [Char] -> Parser i a
Atto.<?> [Char]
"',' or '}'"
        case Word8
sep of
          Word8
CommaP ->
            [(Text, Matcher Exp)] -> Parser ByteString (Matcher Exp)
loop ((Text
k, Matcher Exp
val) forall a. a -> [a] -> [a]
: [(Text, Matcher Exp)]
acc)
          Word8
CloseCurlyBracketP ->
            forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall ext. Object ext -> Matcher ext
Object Box
              { values :: HashMap Text (Matcher Exp)
values = forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList ((Text
k, Matcher Exp
val) forall a. a -> [a] -> [a]
: [(Text, Matcher Exp)]
acc)
              , extra :: Bool
extra = Bool
False
              }
          Word8
_ ->
            forall a. HasCallStack => [Char] -> a
error [Char]
"impossible"

key :: Atto.Parser Text
key :: Parser Text
key =
  Parser Text
Aeson.jstring forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text
bareKey

bareKey :: Atto.Parser Text
bareKey :: Parser Text
bareKey =
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
    (ByteString -> Text
Text.decodeUtf8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
ByteString.pack)
    (forall (f :: * -> *) a. Alternative f => f a -> f [a]
Atto.many1
      ((Word8 -> Bool) -> Parser Word8
Atto.satisfy
        (Char -> Bool
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Char
Char.chr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral)))
 where
  p :: Char -> Bool
p Char
c =
    Bool -> Bool
not (Char -> Bool
Char.isSpace Char
c Bool -> Bool -> Bool
|| Char
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([Char]
"\\\":;><${}[],#" :: String))

rest :: Atto.Parser ()
rest :: Parser ()
rest =
  () forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ByteString -> Parser ByteString
Atto.string ByteString
"..."

haskellExp :: Atto.Parser (Matcher Exp)
haskellExp :: Parser ByteString (Matcher Exp)
haskellExp =
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ext. ext -> Matcher ext
Ext (ByteString -> Parser ByteString
Atto.string ByteString
"#{" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser ByteString Exp
go)
 where
  go :: Parser ByteString Exp
go = do
    ByteString
str <- (Word8 -> Bool) -> Parser ByteString
Atto.takeWhile1 (forall a. Eq a => a -> a -> Bool
/= Word8
CloseCurlyBracketP) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Word8 -> Parser Word8
Atto.word8 Word8
CloseCurlyBracketP
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char] -> Either [Char] Exp
parseExp (Text -> [Char]
Text.unpack (ByteString -> Text
Text.decodeUtf8 ByteString
str)))

holeSig :: Atto.Parser HoleSig
holeSig :: Parser HoleSig
holeSig = do
  Word8
_ <- Word8 -> Parser Word8
Atto.word8 Word8
ColonP
  Parser ()
spaces
  forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum
    [ ByteString -> Type -> Parser HoleSig
p ByteString
"bool" Type
BoolT
    , ByteString -> Type -> Parser HoleSig
p ByteString
"number" Type
NumberT
    , ByteString -> Type -> Parser HoleSig
p ByteString
"string" Type
StringT
    , ByteString -> Type -> Parser HoleSig
p ByteString
"ci-string" Type
StringCIT
    , ByteString -> Type -> Parser HoleSig
p ByteString
"array" Type
ArrayT
    , ByteString -> Type -> Parser HoleSig
p ByteString
"unordered-array" Type
ArrayUOT
    , ByteString -> Type -> Parser HoleSig
p ByteString
"object" Type
ObjectT
    ] forall i a. Parser i a -> [Char] -> Parser i a
Atto.<?> [Char]
"unknown type in hole signature"
 where
  p :: ByteString -> Type -> Parser HoleSig
p ByteString
name Type
typeName = do
    ByteString
_ <- ByteString -> Parser ByteString
Atto.string ByteString
name
    Maybe Word8
q <- forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Word8 -> Parser Word8
Atto.word8 Word8
QuestionMarkP)
    forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> Bool -> HoleSig
HoleSig Type
typeName (forall a. Maybe a -> Bool
isJust Maybe Word8
q))

eof :: Atto.Parser ()
eof :: Parser ()
eof =
  forall t. Chunk t => Parser t ()
Atto.endOfInput forall i a. Parser i a -> [Char] -> Parser i a
Atto.<?> [Char]
"trailing garbage after a Matcher value"

-- This function has been stolen from aeson.
-- ref: https://hackage.haskell.org/package/aeson-1.4.6.0/docs/src/Data.Aeson.Parser.Internal.html#skipSpace
spaces :: Atto.Parser ()
spaces :: Parser ()
spaces =
  (Word8 -> Bool) -> Parser ()
Atto.skipWhile (\Word8
b -> Word8
b forall a. Eq a => a -> a -> Bool
== Word8
SpaceP Bool -> Bool -> Bool
|| Word8
b forall a. Eq a => a -> a -> Bool
== Word8
NewLineP Bool -> Bool -> Bool
|| Word8
b forall a. Eq a => a -> a -> Bool
== Word8
CRP Bool -> Bool -> Bool
|| Word8
b forall a. Eq a => a -> a -> Bool
== Word8
TabP)
{-# INLINE spaces #-}

pattern HoleP, NP, FP, TP, DoubleQuoteP, DotP, CommaP, HashP :: Word8
pattern $bHoleP :: Word8
$mHoleP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
HoleP = 95 -- '_'
pattern $bNP :: Word8
$mNP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
NP = 110 -- 'n'
pattern $bFP :: Word8
$mFP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
FP = 102 -- 'f'
pattern $bTP :: Word8
$mTP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
TP = 116 -- 't'
pattern $bDoubleQuoteP :: Word8
$mDoubleQuoteP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
DoubleQuoteP = 34 -- '"'
pattern $bCommaP :: Word8
$mCommaP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
CommaP = 44 -- ','
pattern $bDotP :: Word8
$mDotP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
DotP = 46 -- '.'
pattern $bHashP :: Word8
$mHashP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
HashP = 35 -- '#'

pattern OpenSquareBracketP, CloseSquareBracketP :: Word8
pattern $bOpenSquareBracketP :: Word8
$mOpenSquareBracketP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
OpenSquareBracketP = 91 -- '['
pattern $bCloseSquareBracketP :: Word8
$mCloseSquareBracketP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
CloseSquareBracketP = 93 -- ']'

pattern OpenParenP :: Word8
pattern $bOpenParenP :: Word8
$mOpenParenP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
OpenParenP = 40 -- '('
-- pattern CloseParenP :: Word8
-- pattern CloseParenP = 41 -- ')'

pattern OpenCurlyBracketP, CloseCurlyBracketP, ColonP :: Word8
pattern $bOpenCurlyBracketP :: Word8
$mOpenCurlyBracketP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
OpenCurlyBracketP = 123 -- '{'
pattern $bCloseCurlyBracketP :: Word8
$mCloseCurlyBracketP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
CloseCurlyBracketP = 125 -- '}'

pattern $bColonP :: Word8
$mColonP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
ColonP = 58 -- ':'

pattern ZeroP, NineP, MinusP :: Word8
pattern $bZeroP :: Word8
$mZeroP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
ZeroP = 48 -- '0'
pattern $bNineP :: Word8
$mNineP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
NineP = 57 -- '9'
pattern $bMinusP :: Word8
$mMinusP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
MinusP = 45 -- '-'

pattern SpaceP, NewLineP, CRP, TabP :: Word8
pattern $bSpaceP :: Word8
$mSpaceP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
SpaceP = 0x20
pattern $bNewLineP :: Word8
$mNewLineP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
NewLineP = 0x0a
pattern $bCRP :: Word8
$mCRP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
CRP = 0x0d
pattern $bTabP :: Word8
$mTabP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
TabP = 0x09

pattern QuestionMarkP :: Word8
pattern $bQuestionMarkP :: Word8
$mQuestionMarkP :: forall {r}. Word8 -> ((# #) -> r) -> ((# #) -> r) -> r
QuestionMarkP = 63 -- '?'