    -- |
    -- Module      :  Language.C.Quote.ObjC
    -- Copyright   :  (c) 2006-2011 Harvard University
    --                (c) 2011-2013 Geoffrey Mainland
    --                (c) 2013-2014 Manuel M T Chakravarty
    --             :  (c) 2013-2015 Drexel University
    -- License     :  BSD-style
    -- Maintainer  :  mainland@drexel.edu

    {-# LANGUAGE FlexibleInstances #-}

    module Language.C.Quote.ObjC (
        ToIdent(..),
        ToConst(..),
        ToExp(..),
        objcLit,
        cexp,
        cedecl,
        cdecl,
        csdecl,
        cenum,
        ctyquals,
        cty,
        cparam,
        cparams,
        cinit,
        cstm,
        cstms,
        citem,
        citems,
        cunit,
        cfun,
        objcprop,
        objcifdecls,
        objcimdecls,
        objcdictelem,
        objcpropattr,
        objcmethparam,
        objcmethproto,
        objcmethdef,
        objcmethrecv,
        objcarg
      ) where

    import qualified Language.C.Parser as P
    import qualified Language.C.Syntax as C
    import Language.C.Quote.Base (ToIdent(..), ToConst(..), ToExp(..), quasiquote)
    import Language.Haskell.TH.Quote (QuasiQuoter)

    exts :: [C.Extensions]
    exts :: [Extensions]
    exts = [Extensions
    C.ObjC, Extensions
    C.Blocks, Extensions
    C.Gcc]

    typenames :: [String]
    typenames :: [String]
    typenames = [String
    "id", String
    "instancetype"]

    -- | A wrapper for a value indicating that it should be treated as an
    -- Objective-C literal.
    newtype ObjCLit a = ObjCLit a
        deriving (Int -> ObjCLit a -> ShowS
    [ObjCLit a] -> ShowS
    ObjCLit a -> String
    (Int -> ObjCLit a -> ShowS)
    -> (ObjCLit a -> String)
    -> ([ObjCLit a] -> ShowS)
    -> Show (ObjCLit a)
    forall a. Show a => Int -> ObjCLit a -> ShowS
    forall a. Show a => [ObjCLit a] -> ShowS
    forall a. Show a => ObjCLit a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> ObjCLit a -> ShowS
    showsPrec :: Int -> ObjCLit a -> ShowS
    $cshow :: forall a. Show a => ObjCLit a -> String
    show :: ObjCLit a -> String
    $cshowList :: forall a. Show a => [ObjCLit a] -> ShowS
    showList :: [ObjCLit a] -> ShowS
    Show, ReadPrec [ObjCLit a]
    ReadPrec (ObjCLit a)
    Int -> ReadS (ObjCLit a)
    ReadS [ObjCLit a]
    (Int -> ReadS (ObjCLit a))
    -> ReadS [ObjCLit a]
    -> ReadPrec (ObjCLit a)
    -> ReadPrec [ObjCLit a]
    -> Read (ObjCLit a)
    forall a. Read a => ReadPrec [ObjCLit a]
    forall a. Read a => ReadPrec (ObjCLit a)
    forall a. Read a => Int -> ReadS (ObjCLit a)
    forall a. Read a => ReadS [ObjCLit a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: forall a. Read a => Int -> ReadS (ObjCLit a)
    readsPrec :: Int -> ReadS (ObjCLit a)
    $creadList :: forall a. Read a => ReadS [ObjCLit a]
    readList :: ReadS [ObjCLit a]
    $creadPrec :: forall a. Read a => ReadPrec (ObjCLit a)
    readPrec :: ReadPrec (ObjCLit a)
    $creadListPrec :: forall a. Read a => ReadPrec [ObjCLit a]
    readListPrec :: ReadPrec [ObjCLit a]
    Read, ObjCLit a -> ObjCLit a -> Bool
    (ObjCLit a -> ObjCLit a -> Bool)
    -> (ObjCLit a -> ObjCLit a -> Bool) -> Eq (ObjCLit a)
    forall a. Eq a => ObjCLit a -> ObjCLit a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => ObjCLit a -> ObjCLit a -> Bool
    == :: ObjCLit a -> ObjCLit a -> Bool
    $c/= :: forall a. Eq a => ObjCLit a -> ObjCLit a -> Bool
    /= :: ObjCLit a -> ObjCLit a -> Bool
    Eq, Eq (ObjCLit a)
    Eq (ObjCLit a) =>
    (ObjCLit a -> ObjCLit a -> Ordering)
    -> (ObjCLit a -> ObjCLit a -> Bool)
    -> (ObjCLit a -> ObjCLit a -> Bool)
    -> (ObjCLit a -> ObjCLit a -> Bool)
    -> (ObjCLit a -> ObjCLit a -> Bool)
    -> (ObjCLit a -> ObjCLit a -> ObjCLit a)
    -> (ObjCLit a -> ObjCLit a -> ObjCLit a)
    -> Ord (ObjCLit a)
    ObjCLit a -> ObjCLit a -> Bool
    ObjCLit a -> ObjCLit a -> Ordering
    ObjCLit a -> ObjCLit a -> ObjCLit a
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    forall a. Ord a => Eq (ObjCLit a)
    forall a. Ord a => ObjCLit a -> ObjCLit a -> Bool
    forall a. Ord a => ObjCLit a -> ObjCLit a -> Ordering
    forall a. Ord a => ObjCLit a -> ObjCLit a -> ObjCLit a
    $ccompare :: forall a. Ord a => ObjCLit a -> ObjCLit a -> Ordering
    compare :: ObjCLit a -> ObjCLit a -> Ordering
    $c< :: forall a. Ord a => ObjCLit a -> ObjCLit a -> Bool
    < :: ObjCLit a -> ObjCLit a -> Bool
    $c<= :: forall a. Ord a => ObjCLit a -> ObjCLit a -> Bool
    <= :: ObjCLit a -> ObjCLit a -> Bool
    $c> :: forall a. Ord a => ObjCLit a -> ObjCLit a -> Bool
    > :: ObjCLit a -> ObjCLit a -> Bool
    $c>= :: forall a. Ord a => ObjCLit a -> ObjCLit a -> Bool
    >= :: ObjCLit a -> ObjCLit a -> Bool
    $cmax :: forall a. Ord a => ObjCLit a -> ObjCLit a -> ObjCLit a
    max :: ObjCLit a -> ObjCLit a -> ObjCLit a
    $cmin :: forall a. Ord a => ObjCLit a -> ObjCLit a -> ObjCLit a
    min :: ObjCLit a -> ObjCLit a -> ObjCLit a
    Ord)

    instance ToExp (ObjCLit String) where
        toExp :: ObjCLit String -> SrcLoc -> Exp
    toExp (ObjCLit String
    s) SrcLoc
    loc = [Const] -> SrcLoc -> Exp
    C.ObjCLitString [[String] -> String -> SrcLoc -> Const
    C.StringConst [ShowS
    forall a. Show a => a -> String
    show String
    s] String
    s SrcLoc
    loc] SrcLoc
    loc

    instance ToExp (ObjCLit Bool) where
        toExp :: ObjCLit Bool -> SrcLoc -> Exp
    toExp (ObjCLit Bool
    b) SrcLoc
    loc = Bool -> SrcLoc -> Exp
    C.ObjCLitBool Bool
    b SrcLoc
    loc

    instance ToExp (ObjCLit Char) where
        toExp :: ObjCLit Char -> SrcLoc -> Exp
    toExp (ObjCLit Char
    c) SrcLoc
    loc = Maybe UnOp -> Const -> SrcLoc -> Exp
    C.ObjCLitConst Maybe UnOp
    forall a. Maybe a
    Nothing (String -> Char -> SrcLoc -> Const
    C.CharConst (Char -> String
    forall a. Show a => a -> String
    show Char
    c) Char
    c SrcLoc
    loc) SrcLoc
    loc

    -- | Indicates that a value should be treated as an Objective-C literal.
    objcLit :: a -> ObjCLit a
    objcLit :: forall a. a -> ObjCLit a
    objcLit = a -> ObjCLit a
    forall a. a -> ObjCLit a
    ObjCLit

    cdecl, cedecl, cenum, cexp, cfun, cinit, cparam, cparams, csdecl, cstm, cstms :: QuasiQuoter
    citem, citems, ctyquals, cty, cunit :: QuasiQuoter
    cdecl :: QuasiQuoter
    cdecl    = [Extensions] -> [String] -> P InitGroup -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P InitGroup
    P.parseDecl
    cedecl :: QuasiQuoter
    cedecl   = [Extensions] -> [String] -> P Definition -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Definition
    P.parseEdecl
    cenum :: QuasiQuoter
    cenum    = [Extensions] -> [String] -> P CEnum -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P CEnum
    P.parseEnum
    cexp :: QuasiQuoter
    cexp     = [Extensions] -> [String] -> P Exp -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Exp
    P.parseExp
    cfun :: QuasiQuoter
    cfun     = [Extensions] -> [String] -> P Func -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Func
    P.parseFunc
    cinit :: QuasiQuoter
    cinit    = [Extensions] -> [String] -> P Initializer -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Initializer
    P.parseInit
    cparam :: QuasiQuoter
    cparam   = [Extensions] -> [String] -> P Param -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Param
    P.parseParam
    cparams :: QuasiQuoter
    cparams  = [Extensions] -> [String] -> P [Param] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [Param]
    P.parseParams
    csdecl :: QuasiQuoter
    csdecl   = [Extensions] -> [String] -> P FieldGroup -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P FieldGroup
    P.parseStructDecl
    cstm :: QuasiQuoter
    cstm     = [Extensions] -> [String] -> P Stm -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Stm
    P.parseStm
    cstms :: QuasiQuoter
    cstms    = [Extensions] -> [String] -> P [Stm] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [Stm]
    P.parseStms
    citem :: QuasiQuoter
    citem    = [Extensions] -> [String] -> P BlockItem -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P BlockItem
    P.parseBlockItem
    citems :: QuasiQuoter
    citems   = [Extensions] -> [String] -> P [BlockItem] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [BlockItem]
    P.parseBlockItems
    ctyquals :: QuasiQuoter
    ctyquals = [Extensions] -> [String] -> P [TypeQual] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [TypeQual]
    P.parseTypeQuals
    cty :: QuasiQuoter
    cty      = [Extensions] -> [String] -> P Type -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Type
    P.parseType
    cunit :: QuasiQuoter
    cunit    = [Extensions] -> [String] -> P [Definition] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [Definition]
    P.parseUnit

    objcprop, objcpropattr, objcifdecls, objcimdecls, objcdictelem, objcmethparam, objcmethproto :: QuasiQuoter
    objcmethdef, objcmethrecv, objcarg :: QuasiQuoter
    objcprop :: QuasiQuoter
    objcprop      = [Extensions] -> [String] -> P ObjCIfaceDecl -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P ObjCIfaceDecl
    P.parseObjCProp
    objcifdecls :: QuasiQuoter
    objcifdecls   = [Extensions] -> [String] -> P [ObjCIfaceDecl] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [ObjCIfaceDecl]
    P.parseObjCIfaceDecls
    objcimdecls :: QuasiQuoter
    objcimdecls   = [Extensions] -> [String] -> P [Definition] -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P [Definition]
    P.parseObjCImplDecls
    objcpropattr :: QuasiQuoter
    objcpropattr  = [Extensions] -> [String] -> P ObjCPropAttr -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P ObjCPropAttr
    P.parseObjCPropAttr
    objcdictelem :: QuasiQuoter
    objcdictelem  = [Extensions] -> [String] -> P ObjCDictElem -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P ObjCDictElem
    P.parseObjCDictElem
    objcmethparam :: QuasiQuoter
    objcmethparam = [Extensions] -> [String] -> P ObjCParam -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P ObjCParam
    P.parseObjCMethodParam
    objcmethproto :: QuasiQuoter
    objcmethproto = [Extensions] -> [String] -> P ObjCMethodProto -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P ObjCMethodProto
    P.parseObjCMethodProto
    objcmethdef :: QuasiQuoter
    objcmethdef   = [Extensions] -> [String] -> P Definition -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P Definition
    P.parseObjCMethodDef
    objcmethrecv :: QuasiQuoter
    objcmethrecv  = [Extensions] -> [String] -> P ObjCRecv -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P ObjCRecv
    P.parseObjCMethodRecv
    objcarg :: QuasiQuoter
    objcarg       = [Extensions] -> [String] -> P ObjCArg -> QuasiQuoter
    forall a. Data a => [Extensions] -> [String] -> P a -> QuasiQuoter
    quasiquote [Extensions]
    exts [String]
    typenames P ObjCArg
    P.parseObjCKeywordArg