-- |
-- 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