    module Language.C99.Util.Expr
      ( digit
      , nonzerodigit
      , nondigit
      , ident
      , litbool
      , litint
      , litdouble
      , litfloat
      , litstring
      , identdeclr
      ) where

    import Data.Char (isDigit)

    import Language.C99.AST
    import Language.C99.Util.Wrap

    -- A digit in Haskell, not C
    type HSDigit = Int

    digit :: Int -> Digit
    digit :: Int -> Digit
    digit Int
    i = case Int
    i of
      Int
    0 -> Digit
    DZero
      Int
    1 -> Digit
    DOne
      Int
    2 -> Digit
    DTwo
      Int
    3 -> Digit
    DThree
      Int
    4 -> Digit
    DFour
      Int
    5 -> Digit
    DFive
      Int
    6 -> Digit
    DSix
      Int
    7 -> Digit
    DSeven
      Int
    8 -> Digit
    DEight
      Int
    9 -> Digit
    DNine
      Int
    _ -> [Char] -> Digit
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Digit) -> [Char] -> Digit
    forall a b. (a -> b) -> a -> b
    $ Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    i [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is not a digit"

    nonzerodigit :: Int -> NonZeroDigit
    nonzerodigit :: Int -> NonZeroDigit
    nonzerodigit Int
    i = case Int
    i of
      Int
    1 -> NonZeroDigit
    NZOne
      Int
    2 -> NonZeroDigit
    NZTwo
      Int
    3 -> NonZeroDigit
    NZThree
      Int
    4 -> NonZeroDigit
    NZFour
      Int
    5 -> NonZeroDigit
    NZFive
      Int
    6 -> NonZeroDigit
    NZSix
      Int
    7 -> NonZeroDigit
    NZSeven
      Int
    8 -> NonZeroDigit
    NZEight
      Int
    9 -> NonZeroDigit
    NZNine
      Int
    _ -> [Char] -> NonZeroDigit
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> NonZeroDigit) -> [Char] -> NonZeroDigit
    forall a b. (a -> b) -> a -> b
    $ Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    i [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is not a non-zero digit"

    nondigit :: Char -> IdentNonDigit
    nondigit :: Char -> IdentNonDigit
    nondigit Char
    c = NonDigit -> IdentNonDigit
    IdentNonDigit (NonDigit -> IdentNonDigit) -> NonDigit -> IdentNonDigit
    forall a b. (a -> b) -> a -> b
    $ case Char
    c of
      Char
    '_' -> NonDigit
    NDUnderscore
      Char
    'a' -> NonDigit
    NDa ;      Char
    'A' -> NonDigit
    NDA
      Char
    'b' -> NonDigit
    NDb ;      Char
    'B' -> NonDigit
    NDB
      Char
    'c' -> NonDigit
    NDc ;      Char
    'C' -> NonDigit
    NDC
      Char
    'd' -> NonDigit
    NDd ;      Char
    'D' -> NonDigit
    NDD
      Char
    'e' -> NonDigit
    NDe ;      Char
    'E' -> NonDigit
    NDE
      Char
    'f' -> NonDigit
    NDf ;      Char
    'F' -> NonDigit
    NDF
      Char
    'g' -> NonDigit
    NDg ;      Char
    'G' -> NonDigit
    NDG
      Char
    'h' -> NonDigit
    NDh ;      Char
    'H' -> NonDigit
    NDH
      Char
    'i' -> NonDigit
    NDi ;      Char
    'I' -> NonDigit
    NDI
      Char
    'j' -> NonDigit
    NDj ;      Char
    'J' -> NonDigit
    NDJ
      Char
    'k' -> NonDigit
    NDk ;      Char
    'K' -> NonDigit
    NDK
      Char
    'l' -> NonDigit
    NDl ;      Char
    'L' -> NonDigit
    NDL
      Char
    'm' -> NonDigit
    NDm ;      Char
    'M' -> NonDigit
    NDM
      Char
    'n' -> NonDigit
    NDn ;      Char
    'N' -> NonDigit
    NDN
      Char
    'o' -> NonDigit
    NDo ;      Char
    'O' -> NonDigit
    NDO
      Char
    'p' -> NonDigit
    NDp ;      Char
    'P' -> NonDigit
    NDP
      Char
    'q' -> NonDigit
    NDq ;      Char
    'Q' -> NonDigit
    NDQ
      Char
    'r' -> NonDigit
    NDr ;      Char
    'R' -> NonDigit
    NDR
      Char
    's' -> NonDigit
    NDs ;      Char
    'S' -> NonDigit
    NDS
      Char
    't' -> NonDigit
    NDt ;      Char
    'T' -> NonDigit
    NDT
      Char
    'u' -> NonDigit
    NDu ;      Char
    'U' -> NonDigit
    NDU
      Char
    'v' -> NonDigit
    NDv ;      Char
    'V' -> NonDigit
    NDV
      Char
    'w' -> NonDigit
    NDw ;      Char
    'W' -> NonDigit
    NDW
      Char
    'x' -> NonDigit
    NDx ;      Char
    'X' -> NonDigit
    NDX
      Char
    'y' -> NonDigit
    NDy ;      Char
    'Y' -> NonDigit
    NDY
      Char
    'z' -> NonDigit
    NDz ;      Char
    'Z' -> NonDigit
    NDZ
      Char
    _   -> [Char] -> NonDigit
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> NonDigit) -> [Char] -> NonDigit
    forall a b. (a -> b) -> a -> b
    $ Char -> [Char]
    forall a. Show a => a -> [Char]
    show Char
    c [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is not a nondigit"

    ident :: String -> Ident
    ident :: [Char] -> Ident
    ident (Char
    c:[Char]
    cs) = (Ident -> Char -> Ident) -> Ident -> [Char] -> Ident
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl Ident -> Char -> Ident
    char (IdentNonDigit -> Ident
    IdentBase (IdentNonDigit -> Ident) -> IdentNonDigit -> Ident
    forall a b. (a -> b) -> a -> b
    $ Char -> IdentNonDigit
    nondigit Char
    c) [Char]
    cs where
      char :: Ident -> Char -> Ident
    char Ident
    cs Char
    c | Char -> Bool
    isDigit Char
    c = Ident -> Digit -> Ident
    IdentCons         Ident
    cs (Int -> Digit
    digit ([Char] -> Int
    forall a. Read a => [Char] -> a
    read [Char
    c]))
                | Bool
    otherwise = Ident -> IdentNonDigit -> Ident
    IdentConsNonDigit Ident
    cs (Char -> IdentNonDigit
    nondigit Char
    c)

    litbool :: Bool -> PrimExpr
    litbool :: Bool -> PrimExpr
    litbool Bool
    False = Const -> PrimExpr
    PrimConst (Const -> PrimExpr) -> Const -> PrimExpr
    forall a b. (a -> b) -> a -> b
    $ EnumConst -> Const
    ConstEnum (EnumConst -> Const) -> EnumConst -> Const
    forall a b. (a -> b) -> a -> b
    $ Ident -> EnumConst
    Enum ([Char] -> Ident
    ident [Char]
    "false")
    litbool Bool
    True  = Const -> PrimExpr
    PrimConst (Const -> PrimExpr) -> Const -> PrimExpr
    forall a b. (a -> b) -> a -> b
    $ EnumConst -> Const
    ConstEnum (EnumConst -> Const) -> EnumConst -> Const
    forall a b. (a -> b) -> a -> b
    $ Ident -> EnumConst
    Enum ([Char] -> Ident
    ident [Char]
    "true")

    litint :: Integer -> UnaryExpr
    litint :: Integer -> UnaryExpr
    litint Integer
    i | Integer
    i Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    0 = PostfixExpr -> UnaryExpr
    UnaryPostfix (PostfixExpr -> UnaryExpr) -> PostfixExpr -> UnaryExpr
    forall a b. (a -> b) -> a -> b
    $ PrimExpr -> PostfixExpr
    PostfixPrim (PrimExpr -> PostfixExpr) -> PrimExpr -> PostfixExpr
    forall a b. (a -> b) -> a -> b
    $ PrimExpr
    constzero
             | Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >  Integer
    0 = PostfixExpr -> UnaryExpr
    UnaryPostfix (PostfixExpr -> UnaryExpr) -> PostfixExpr -> UnaryExpr
    forall a b. (a -> b) -> a -> b
    $ PrimExpr -> PostfixExpr
    PostfixPrim (PrimExpr -> PostfixExpr) -> PrimExpr -> PostfixExpr
    forall a b. (a -> b) -> a -> b
    $ Integer -> PrimExpr
    constint Integer
    i
             | Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    <  Integer
    0 = UnaryOp -> CastExpr -> UnaryExpr
    UnaryOp UnaryOp
    UOMin (UnaryExpr -> CastExpr
    CastUnary (UnaryExpr -> CastExpr) -> UnaryExpr -> CastExpr
    forall a b. (a -> b) -> a -> b
    $ Integer -> UnaryExpr
    litint (Integer -> Integer
    forall a. Num a => a -> a
    abs Integer
    i))

    litfp :: (RealFloat a, Show a) => Maybe FloatSuffix -> a -> UnaryExpr
    litfp :: forall a.
    (RealFloat a, Show a) =>
    Maybe FloatSuffix -> a -> UnaryExpr
    litfp Maybe FloatSuffix
    mbFS a
    n
      | a -> Bool
    forall a. RealFloat a => a -> Bool
    isNaN a
    n = PostfixExpr -> UnaryExpr
    UnaryPostfix (PostfixExpr -> UnaryExpr) -> PostfixExpr -> UnaryExpr
    forall a b. (a -> b) -> a -> b
    $ PrimExpr -> PostfixExpr
    PostfixPrim (PrimExpr -> PostfixExpr) -> PrimExpr -> PostfixExpr
    forall a b. (a -> b) -> a -> b
    $ Ident -> PrimExpr
    PrimIdent (Ident -> PrimExpr) -> Ident -> PrimExpr
    forall a b. (a -> b) -> a -> b
    $ [Char] -> Ident
    ident [Char]
    "NAN"
      | a -> Bool
    forall a. RealFloat a => a -> Bool
    isInfinite a
    n = case a
    n a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    > a
    0 of
        Bool
    True  -> PostfixExpr -> UnaryExpr
    UnaryPostfix (PostfixExpr -> UnaryExpr) -> PostfixExpr -> UnaryExpr
    forall a b. (a -> b) -> a -> b
    $ PrimExpr -> PostfixExpr
    PostfixPrim (PrimExpr -> PostfixExpr) -> PrimExpr -> PostfixExpr
    forall a b. (a -> b) -> a -> b
    $ Ident -> PrimExpr
    PrimIdent (Ident -> PrimExpr) -> Ident -> PrimExpr
    forall a b. (a -> b) -> a -> b
    $ [Char] -> Ident
    ident [Char]
    "INFINITY"
        Bool
    False -> UnaryOp -> CastExpr -> UnaryExpr
    UnaryOp UnaryOp
    UOMin (UnaryExpr -> CastExpr
    CastUnary (UnaryExpr -> CastExpr) -> UnaryExpr -> CastExpr
    forall a b. (a -> b) -> a -> b
    $ PostfixExpr -> UnaryExpr
    UnaryPostfix (PostfixExpr -> UnaryExpr) -> PostfixExpr -> UnaryExpr
    forall a b. (a -> b) -> a -> b
    $ PrimExpr -> PostfixExpr
    PostfixPrim (PrimExpr -> PostfixExpr) -> PrimExpr -> PostfixExpr
    forall a b. (a -> b) -> a -> b
    $ Ident -> PrimExpr
    PrimIdent (Ident -> PrimExpr) -> Ident -> PrimExpr
    forall a b. (a -> b) -> a -> b
    $ [Char] -> Ident
    ident [Char]
    "INFINITY")
      | Bool
    otherwise = Maybe FloatSuffix -> a -> UnaryExpr
    forall a.
    (RealFloat a, Show a) =>
    Maybe FloatSuffix -> a -> UnaryExpr
    litfpFinite Maybe FloatSuffix
    mbFS a
    n
      where
        litfpFinite :: (RealFloat a, Show a) => Maybe FloatSuffix -> a -> UnaryExpr
        litfpFinite :: forall a.
    (RealFloat a, Show a) =>
    Maybe FloatSuffix -> a -> UnaryExpr
    litfpFinite Maybe FloatSuffix
    mbFS = ([Char], [Char], [Char]) -> UnaryExpr
    parse (([Char], [Char], [Char]) -> UnaryExpr)
    -> (a -> ([Char], [Char], [Char])) -> a -> UnaryExpr
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> ([Char], [Char], [Char])
    forall a. (RealFloat a, Show a) => a -> ([Char], [Char], [Char])
    lex where
          lex :: (RealFloat a, Show a) => a -> (String, String, String)
          lex :: forall a. (RealFloat a, Show a) => a -> ([Char], [Char], [Char])
    lex a
    d = ([Char]
    nat, [Char]
    dec, [Char]
    exp) where
            ds :: [Char]
    ds = a -> [Char]
    forall a. Show a => a -> [Char]
    show a
    d
            e :: [Char]
    e = (Char -> Bool) -> [Char] -> [Char]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /=Char
    'e') [Char]
    ds
            nat :: [Char]
    nat = (Char -> Bool) -> [Char] -> [Char]
    forall a. (a -> Bool) -> [a] -> [a]
    takeWhile (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /=Char
    '.') [Char]
    ds
            dec :: [Char]
    dec = (Char -> Bool) -> [Char] -> [Char]
    forall a. (a -> Bool) -> [a] -> [a]
    takeWhile (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /=Char
    'e') ([Char] -> [Char]) -> [Char] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> [Char]
    forall a. HasCallStack => [a] -> [a]
    tail ([Char] -> [Char]) -> [Char] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> [Char] -> [Char]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /=Char
    '.') [Char]
    ds
            exp :: [Char]
    exp = case [Char] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Char]
    e of
              Int
    0 -> [Char]
    ""
              Int
    _ -> [Char] -> [Char]
    forall a. HasCallStack => [a] -> [a]
    tail [Char]
    e

        parse :: (String, String, String) -> UnaryExpr
        parse :: ([Char], [Char], [Char]) -> UnaryExpr
    parse ([Char]
    nat, [Char]
    dec, [Char]
    exp) = PostfixExpr -> UnaryExpr
    op (PostfixExpr -> UnaryExpr) -> PostfixExpr -> UnaryExpr
    forall a b. (a -> b) -> a -> b
    $ PrimExpr -> PostfixExpr
    PostfixPrim (PrimExpr -> PostfixExpr) -> PrimExpr -> PostfixExpr
    forall a b. (a -> b) -> a -> b
    $ Const -> PrimExpr
    PrimConst (Const -> PrimExpr) -> Const -> PrimExpr
    forall a b. (a -> b) -> a -> b
    $ FloatConst -> Const
    ConstFloat (FloatConst -> Const) -> FloatConst -> Const
    forall a b. (a -> b) -> a -> b
    $ DecFloatConst -> FloatConst
    FloatDec (DecFloatConst -> FloatConst) -> DecFloatConst -> FloatConst
    forall a b. (a -> b) -> a -> b
    $ FracConst -> Maybe ExpPart -> Maybe FloatSuffix -> DecFloatConst
    DecFloatFrac (Maybe DigitSeq -> DigitSeq -> FracConst
    FracZero (DigitSeq -> Maybe DigitSeq
    forall a. a -> Maybe a
    Just DigitSeq
    nat') DigitSeq
    dec') Maybe ExpPart
    exp' Maybe FloatSuffix
    mbFS where
          op :: PostfixExpr -> UnaryExpr
    op = case [Char] -> Char
    forall a. HasCallStack => [a] -> a
    head [Char]
    nat of
            Char
    '-' -> UnaryOp -> CastExpr -> UnaryExpr
    UnaryOp UnaryOp
    UOMin (CastExpr -> UnaryExpr)
    -> (PostfixExpr -> CastExpr) -> PostfixExpr -> UnaryExpr
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UnaryExpr -> CastExpr
    CastUnary (UnaryExpr -> CastExpr)
    -> (PostfixExpr -> UnaryExpr) -> PostfixExpr -> CastExpr
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PostfixExpr -> UnaryExpr
    UnaryPostfix
            Char
    _   -> PostfixExpr -> UnaryExpr
    UnaryPostfix
          nat' :: DigitSeq
    nat' = case [Char] -> Char
    forall a. HasCallStack => [a] -> a
    head [Char]
    nat of
            Char
    '-' -> [Int] -> DigitSeq
    digitseq ([Int] -> DigitSeq) -> [Int] -> DigitSeq
    forall a b. (a -> b) -> a -> b
    $ [Char] -> [Int]
    digitsc ([Char] -> [Char]
    forall a. HasCallStack => [a] -> [a]
    tail [Char]
    nat)
            Char
    _   -> [Int] -> DigitSeq
    digitseq ([Int] -> DigitSeq) -> [Int] -> DigitSeq
    forall a b. (a -> b) -> a -> b
    $ [Char] -> [Int]
    digitsc [Char]
    nat
          dec' :: DigitSeq
    dec' = [Int] -> DigitSeq
    digitseq ([Int] -> DigitSeq) -> [Int] -> DigitSeq
    forall a b. (a -> b) -> a -> b
    $ [Char] -> [Int]
    digitsc [Char]
    dec
          exp' :: Maybe ExpPart
    exp' = case [Char]
    exp of
            [Char]
    "" -> Maybe ExpPart
    forall a. Maybe a
    Nothing
            (Char
    e:[Char]
    es)  -> case Char
    e of
              Char
    '-' -> ExpPart -> Maybe ExpPart
    forall a. a -> Maybe a
    Just (ExpPart -> Maybe ExpPart) -> ExpPart -> Maybe ExpPart
    forall a b. (a -> b) -> a -> b
    $ Maybe Sign -> DigitSeq -> ExpPart
    E (Sign -> Maybe Sign
    forall a. a -> Maybe a
    Just Sign
    SMinus) ([Int] -> DigitSeq
    digitseq ([Int] -> DigitSeq) -> [Int] -> DigitSeq
    forall a b. (a -> b) -> a -> b
    $ [Char] -> [Int]
    digitsc [Char]
    es)
              Char
    _   -> ExpPart -> Maybe ExpPart
    forall a. a -> Maybe a
    Just (ExpPart -> Maybe ExpPart) -> ExpPart -> Maybe ExpPart
    forall a b. (a -> b) -> a -> b
    $ Maybe Sign -> DigitSeq -> ExpPart
    E Maybe Sign
    forall a. Maybe a
    Nothing ([Int] -> DigitSeq
    digitseq ([Int] -> DigitSeq) -> [Int] -> DigitSeq
    forall a b. (a -> b) -> a -> b
    $ [Char] -> [Int]
    digitsc (Char
    eChar -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    :[Char]
    es))

    litdouble :: Double -> UnaryExpr
    litdouble :: Double -> UnaryExpr
    litdouble = Maybe FloatSuffix -> Double -> UnaryExpr
    forall a.
    (RealFloat a, Show a) =>
    Maybe FloatSuffix -> a -> UnaryExpr
    litfp Maybe FloatSuffix
    forall a. Maybe a
    Nothing

    litfloat :: Float -> UnaryExpr
    litfloat :: Float -> UnaryExpr
    litfloat = Maybe FloatSuffix -> Float -> UnaryExpr
    forall a.
    (RealFloat a, Show a) =>
    Maybe FloatSuffix -> a -> UnaryExpr
    litfp (FloatSuffix -> Maybe FloatSuffix
    forall a. a -> Maybe a
    Just FloatSuffix
    FF)

    litstring :: String -> UnaryExpr
    litstring :: [Char] -> UnaryExpr
    litstring [Char]
    ss = PrimExpr -> UnaryExpr
    forall a b. Wrap a b => a -> b
    wrap (PrimExpr -> UnaryExpr) -> PrimExpr -> UnaryExpr
    forall a b. (a -> b) -> a -> b
    $ StringLit -> PrimExpr
    PrimString (StringLit -> PrimExpr) -> StringLit -> PrimExpr
    forall a b. (a -> b) -> a -> b
    $ Maybe SCharSeq -> StringLit
    StringLit (Maybe SCharSeq -> StringLit) -> Maybe SCharSeq -> StringLit
    forall a b. (a -> b) -> a -> b
    $ ([Char] -> Maybe SCharSeq
    sl [Char]
    ss) where
      sl :: String -> Maybe SCharSeq
      sl :: [Char] -> Maybe SCharSeq
    sl [] = Maybe SCharSeq
    forall a. Maybe a
    Nothing
      sl [Char]
    cs = SCharSeq -> Maybe SCharSeq
    forall a. a -> Maybe a
    Just (SCharSeq -> Maybe SCharSeq) -> SCharSeq -> Maybe SCharSeq
    forall a b. (a -> b) -> a -> b
    $ [Char] -> SCharSeq
    readschar [Char]
    cs

      readschar :: String -> SCharSeq
      readschar :: [Char] -> SCharSeq
    readschar (Char
    c:[Char]
    cs) = (SCharSeq -> SChar -> SCharSeq) -> SCharSeq -> [SChar] -> SCharSeq
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl SCharSeq -> SChar -> SCharSeq
    SCharCons (SChar -> SCharSeq
    SCharBase (SChar -> SCharSeq) -> SChar -> SCharSeq
    forall a b. (a -> b) -> a -> b
    $ Char -> SChar
    f Char
    c) ((Char -> SChar) -> [Char] -> [SChar]
    forall a b. (a -> b) -> [a] -> [b]
    map Char -> SChar
    f [Char]
    cs)

      f :: Char -> SChar
      f :: Char -> SChar
    f Char
    c | Char -> Bool
    isEscseq Char
    c = EscSeq -> SChar
    SCharEsc (EscSeq -> SChar) -> EscSeq -> SChar
    forall a b. (a -> b) -> a -> b
    $ Char -> EscSeq
    litescseq Char
    c
          | Bool
    otherwise  = Char -> SChar
    SChar Char
    c

    litescseq :: Char -> EscSeq
    litescseq :: Char -> EscSeq
    litescseq Char
    c = case Char
    c of
      Char
    '\'' -> SimpleEscSeq -> EscSeq
    EscSimple SimpleEscSeq
    SEQuote
      Char
    '\"' -> SimpleEscSeq -> EscSeq
    EscSimple SimpleEscSeq
    SEDQuote
      -- '\?' -> EscSimple SEQuestion
      Char
    '\\' -> SimpleEscSeq -> EscSeq
    EscSimple SimpleEscSeq
    SEBackSlash
      Char
    '\a' -> SimpleEscSeq -> EscSeq
    EscSimple SimpleEscSeq
    SEa
      Char
    '\b' -> SimpleEscSeq -> EscSeq
    EscSimple SimpleEscSeq
    SEb
      Char
    '\f' -> SimpleEscSeq -> EscSeq
    EscSimple SimpleEscSeq
    SEf
      Char
    '\n' -> SimpleEscSeq -> EscSeq
    EscSimple SimpleEscSeq
    SEn
      Char
    '\r' -> SimpleEscSeq -> EscSeq
    EscSimple SimpleEscSeq
    SEr
      Char
    '\t' -> SimpleEscSeq -> EscSeq
    EscSimple SimpleEscSeq
    SEt
      Char
    '\v' -> SimpleEscSeq -> EscSeq
    EscSimple SimpleEscSeq
    SEv
      Char
    otherwise -> [Char] -> EscSeq
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> EscSeq) -> [Char] -> EscSeq
    forall a b. (a -> b) -> a -> b
    $ Char -> [Char]
    forall a. Show a => a -> [Char]
    show Char
    c [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is not an escape sequence."

    isEscseq :: Char -> Bool
    isEscseq :: Char -> Bool
    isEscseq Char
    c = Char
    c Char -> [Char] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Char]
    "\'\"\\\a\b\f\n\n\r\t\v"

    identdeclr :: String -> Declr
    identdeclr :: [Char] -> Declr
    identdeclr [Char]
    name = Maybe Ptr -> DirectDeclr -> Declr
    Declr Maybe Ptr
    forall a. Maybe a
    Nothing (Ident -> DirectDeclr
    DirectDeclrIdent (Ident -> DirectDeclr) -> Ident -> DirectDeclr
    forall a b. (a -> b) -> a -> b
    $ [Char] -> Ident
    ident [Char]
    name)

    intdigits :: Integer -> [HSDigit]
    intdigits :: Integer -> [Int]
    intdigits = (Char -> Int) -> [Char] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map ([Char] -> Int
    forall a. Read a => [Char] -> a
    read([Char] -> Int) -> (Char -> [Char]) -> Char -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .Char -> [Char]
    forall a. a -> [a]
    forall (m :: * -> *) a. Monad m => a -> m a
    return)([Char] -> [Int]) -> (Integer -> [Char]) -> Integer -> [Int]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .Integer -> [Char]
    forall a. Show a => a -> [Char]
    show

    constint :: Integer -> PrimExpr
    constint :: Integer -> PrimExpr
    constint Integer
    i = Const -> PrimExpr
    PrimConst (Const -> PrimExpr) -> Const -> PrimExpr
    forall a b. (a -> b) -> a -> b
    $ IntConst -> Const
    ConstInt (IntConst -> Const) -> IntConst -> Const
    forall a b. (a -> b) -> a -> b
    $ DecConst -> Maybe IntSuffix -> IntConst
    IntDec ([Int] -> DecConst
    decconst ([Int] -> DecConst) -> [Int] -> DecConst
    forall a b. (a -> b) -> a -> b
    $ Integer -> [Int]
    intdigits Integer
    i) Maybe IntSuffix
    forall a. Maybe a
    Nothing

    constzero :: PrimExpr
    constzero :: PrimExpr
    constzero = Const -> PrimExpr
    PrimConst (Const -> PrimExpr) -> Const -> PrimExpr
    forall a b. (a -> b) -> a -> b
    $ IntConst -> Const
    ConstInt (IntConst -> Const) -> IntConst -> Const
    forall a b. (a -> b) -> a -> b
    $ OcConst -> Maybe IntSuffix -> IntConst
    IntOc OcConst
    Oc0 Maybe IntSuffix
    forall a. Maybe a
    Nothing

    decconst :: [HSDigit] -> DecConst
    decconst :: [Int] -> DecConst
    decconst (Int
    d:[Int]
    ds) = (DecConst -> Int -> DecConst) -> DecConst -> [Int] -> DecConst
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl DecConst -> Int -> DecConst
    step DecConst
    base [Int]
    ds where
      base :: DecConst
    base      = NonZeroDigit -> DecConst
    DecBase (NonZeroDigit -> DecConst) -> NonZeroDigit -> DecConst
    forall a b. (a -> b) -> a -> b
    $ Int -> NonZeroDigit
    nonzerodigit Int
    d
      step :: DecConst -> Int -> DecConst
    step DecConst
    xs Int
    x = DecConst -> Digit -> DecConst
    DecCons DecConst
    xs (Int -> Digit
    digit Int
    x)

    digitseq :: [Int] -> DigitSeq
    digitseq :: [Int] -> DigitSeq
    digitseq (Int
    x:[Int]
    xs) = (DigitSeq -> Digit -> DigitSeq) -> DigitSeq -> [Digit] -> DigitSeq
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl DigitSeq -> Digit -> DigitSeq
    DigitCons (Digit -> DigitSeq
    DigitBase (Int -> Digit
    digit Int
    x)) ((Int -> Digit) -> [Int] -> [Digit]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> Digit
    digit [Int]
    xs) where

    digitsc :: [Char] -> [Int]
    digitsc :: [Char] -> [Int]
    digitsc [Char]
    cs = (Char -> Int) -> [Char] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map (\Char
    x -> [Char] -> Int
    forall a. Read a => [Char] -> a
    read [Char
    x]) [Char]
    cs