{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns    #-}
{-# OPTIONS_GHC -Wno-missing-signatures #-}
{-# OPTIONS_GHC -Wno-missing-pattern-synonym-signatures #-}
{- HLINT ignore "Use camelCase" -}
module Tokstyle.C.Patterns where

import           Language.C.Analysis.SemRep    (ArraySize (..),
                                                CompTypeRef (..), Decl (..),
                                                Expr, FunType (..),
                                                IdentDecl (..), IntType (..),
                                                ParamDecl (..), Type (..),
                                                TypeDefRef (..), TypeName (..),
                                                VarDecl (..), VarName (..))
import           Language.C.Analysis.TypeUtils (canonicalType)
import           Language.C.Data.Ident         (Ident (..), SUERef (..))

pattern $mTY_typedef :: forall r. Type -> (String -> r) -> (Void# -> r) -> r
TY_typedef name         <- TypeDefType (TypeDefRef (Ident name _ _) _ _) _ _
pattern $mTY_void_ptr :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
TY_void_ptr             <- PtrType (DirectType TyVoid _ _) _ _
pattern $mTY_uint8_t_arr :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
TY_uint8_t_arr          <- ArrayType (TY_typedef "uint8_t") _ _ _
pattern $mTY_uint8_t_ptr :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
TY_uint8_t_ptr          <- PtrType (TY_typedef "uint8_t") _ _
pattern $mTY_char_arr :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
TY_char_arr             <- ArrayType (DirectType (TyIntegral TyChar) _ _) _ _ _
pattern $mTY_char_ptr :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
TY_char_ptr             <- PtrType (DirectType (TyIntegral TyChar) _ _) _ _
pattern $mTY_struct :: forall r. Type -> (String -> r) -> (Void# -> r) -> r
TY_struct name          <- DirectType (TyComp (CompTypeRef (NamedRef (Ident name _ _)) _ _)) _ _
pattern $mTY_struct_ptr :: forall r. Type -> (String -> r) -> (Void# -> r) -> r
TY_struct_ptr name      <- PtrType (TY_struct name) _ _
pattern $mTY_sockaddr_storage_ptr :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
TY_sockaddr_storage_ptr <- TY_struct_ptr "sockaddr_storage"
pattern $mTY_sockaddr_ptr :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
TY_sockaddr_ptr         <- TY_struct_ptr "sockaddr"
pattern $mTY_sockaddr_in_ptr :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
TY_sockaddr_in_ptr      <- TY_struct_ptr "sockaddr_in"
pattern $mTY_sockaddr_in6_ptr :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
TY_sockaddr_in6_ptr     <- TY_struct_ptr "sockaddr_in6"
pattern $mTY_canon_bool :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
TY_canon_bool           <- (canonicalType -> DirectType (TyIntegral TyBool) _ _)


pattern ArrayTypeSize :: Expr -> Type
pattern $mArrayTypeSize :: forall r. Type -> (Expr -> r) -> (Void# -> r) -> r
ArrayTypeSize arrSize <- ArrayType _ (ArraySize _ arrSize) _ _

pattern ParamName :: String -> ParamDecl
pattern $mParamName :: forall r. ParamDecl -> (String -> r) -> (Void# -> r) -> r
ParamName name <- ParamDecl (VarDecl (VarName (Ident name _ _) _) _ _) _

pattern $mParamType :: forall r. ParamDecl -> (Type -> r) -> (Void# -> r) -> r
ParamType ty <- ParamDecl (VarDecl _ _ ty) _

pattern FunPtrParams :: [ParamDecl] -> Type
pattern $mFunPtrParams :: forall r. Type -> ([ParamDecl] -> r) -> (Void# -> r) -> r
FunPtrParams params <- (canonicalType -> PtrType (FunctionType (FunType _ params _) _) _ _)

pattern $mFunDeclParams :: forall r. IdentDecl -> ([ParamDecl] -> r) -> (Void# -> r) -> r
FunDeclParams params <- Declaration (Decl (VarDecl _ _ (FunctionType (FunType _ params False) [])) _)

isEnum :: Type -> Bool
isEnum :: Type -> Bool
isEnum (Type -> Type
canonicalType -> DirectType TyEnum{} TypeQuals
_ Attributes
_) = Bool
True
isEnum Type
_                                          = Bool
False

isIntegral :: Type -> Bool
isIntegral :: Type -> Bool
isIntegral (Type -> Type
canonicalType -> DirectType TyIntegral{} TypeQuals
_ Attributes
_) = Bool
True
isIntegral Type
_                                              = Bool
False

isFloating :: Type -> Bool
isFloating :: Type -> Bool
isFloating (Type -> Type
canonicalType -> DirectType TyFloating{} TypeQuals
_ Attributes
_) = Bool
True
isFloating Type
_                                              = Bool
False

isNumeric :: Type -> Bool
isNumeric :: Type -> Bool
isNumeric Type
ty = Type -> Bool
isIntegral Type
ty Bool -> Bool -> Bool
|| Type -> Bool
isFloating Type
ty