1+ {- HLINT ignore "Functor law" -}
2+
13module HsBindgen.Backend.Hs.AST.Type (
24 HsPrimType (.. ),
5+ HsTypRefKind (.. ),
36 HsType (.. ),
7+ -- * Foreign types
8+ HsForeignType (.. ),
9+ HsForeignResultType (.. ),
10+ HsForeignArgType (.. ),
11+ -- * Foreign types: parsing utils
12+ withEscapeHatch ,
13+ withEscapeHatchF ,
14+ -- * Foreign types: parsing
15+ isForeignType ,
16+ isForeignResultType ,
17+ isForeignArgType ,
418) where
519
20+ import HsBindgen.Runtime.IsForeignType as RT
21+
622import HsBindgen.BindingSpec qualified as BindingSpec
723import HsBindgen.Imports
824import HsBindgen.Language.Haskell qualified as Hs
@@ -48,9 +64,17 @@ data HsPrimType
4864 -- Word8 Word16 Word32 Word64
4965 deriving stock (Eq , Ord , Generic , Show )
5066
67+ data HsTypRefKind =
68+ HsTypRefKindUnion
69+ | HsTypRefKindStruct
70+ | HsTypRefKindMacro
71+ | HsTypRefKindEnum
72+ | HsTypRefKindTypedef HsType -- ^ Underlying type
73+ deriving stock (Generic , Show , Eq )
74+
5175data HsType =
5276 HsPrimType HsPrimType
53- | HsTypRef (Hs. Name Hs. NsTypeConstr )
77+ | HsTypRef (Hs. Name Hs. NsTypeConstr ) HsTypRefKind
5478 | HsConstArray Natural HsType
5579 | HsIncompleteArray HsType
5680 | HsPtr HsType
@@ -65,3 +89,85 @@ data HsType =
6589 | HsStrLit String
6690 deriving stock (Generic , Show , Eq )
6791
92+ {- ------------------------------------------------------------------------------
93+ Foreign types
94+ -------------------------------------------------------------------------------}
95+
96+ newtype HsForeignType = HsForeignType { unHsForeignType :: RT. ForeignType }
97+ deriving stock (Show , Eq )
98+
99+ newtype HsForeignResultType = HsForeignResultType { unHsForeignResultType :: RT. ForeignResultType }
100+ deriving stock (Show , Eq )
101+
102+ newtype HsForeignArgType = HsForeignArgType { unHsForeignArgType :: RT. ForeignArgType }
103+ deriving stock (Show , Eq )
104+
105+ {- ------------------------------------------------------------------------------
106+ Foreign types: parsing utils
107+ -------------------------------------------------------------------------------}
108+
109+ withEscapeHatchF :: Functor f => (f a -> Either s (f b )) -> f a -> f (Either a b )
110+ withEscapeHatchF f x = case f x of
111+ Left _ -> Left <$> x
112+ Right y -> Right <$> y
113+
114+ withEscapeHatch :: (a -> Either s b ) -> a -> (Either a b )
115+ withEscapeHatch f x = case f x of
116+ Left _s -> Left x
117+ Right y -> Right y
118+
119+ {- ------------------------------------------------------------------------------
120+ Foreign types: parsing
121+ -------------------------------------------------------------------------------}
122+
123+ isForeignType :: HsType -> Either String HsForeignType
124+ isForeignType = fmap HsForeignType . \ case
125+ HsFun x y -> FT_FunArrow <$> (unHsForeignArgType <$> isForeignArgType x)
126+ <*> (unHsForeignType <$> isForeignType y)
127+ x -> FT_FunResult <$> (unHsForeignResultType <$> isForeignResultType x)
128+
129+ isForeignResultType :: HsType -> Either String HsForeignResultType
130+ isForeignResultType = fmap HsForeignResultType . \ case
131+ HsPrimType HsPrimUnit -> Right RT. FRT_Unit
132+ HsIO (HsPrimType HsPrimUnit ) -> Right RT. FRT_IOUnit
133+ HsIO x -> RT. FRT_IO <$> (unHsForeignArgType <$> isForeignArgType x)
134+ x -> RT. FRT_Pure <$> (unHsForeignArgType <$> isForeignArgType x)
135+
136+ isForeignArgType :: HsType -> Either String HsForeignArgType
137+ isForeignArgType = \ case
138+ HsPrimType x -> HsForeignArgType <$> go x
139+ HsPtr _ -> Right $ HsForeignArgType RT. FAT_Ptr
140+ HsFunPtr _ -> Right $ HsForeignArgType RT. FAT_FunPtr
141+ HsTypRef _ kind ->
142+ case kind of
143+ HsTypRefKindStruct -> Left " structs not supported"
144+ HsTypRefKindUnion -> Left " unions not supported"
145+ HsTypRefKindEnum -> Left " enums not supported"
146+ HsTypRefKindMacro -> Left " macros not supported"
147+ HsTypRefKindTypedef uTy -> isForeignArgType uTy
148+ HsBlock _ -> Right $ HsForeignArgType RT. FAT_Ptr
149+ HsExtBinding {} -> Left " external bindings not supported"
150+ _ -> Left " impossible foreign arg type"
151+ where
152+ go :: HsPrimType -> Either String RT. ForeignArgType
153+ go = \ case
154+ HsPrimVoid -> Left " impossible foreign arg type"
155+ HsPrimUnit -> Left " impossible foreign arg type"
156+ HsPrimCChar -> Right RT. FAT_CChar
157+ HsPrimCSChar -> Right RT. FAT_CSChar
158+ HsPrimCUChar -> Right RT. FAT_CUChar
159+ HsPrimCInt -> Right RT. FAT_CInt
160+ HsPrimCUInt -> Right RT. FAT_CUInt
161+ HsPrimCShort -> Right RT. FAT_CShort
162+ HsPrimCUShort -> Right RT. FAT_CUShort
163+ HsPrimCLong -> Right RT. FAT_CLong
164+ HsPrimCULong -> Right RT. FAT_CULong
165+ HsPrimCPtrDiff -> Right RT. FAT_CPtrdiff
166+ HsPrimCSize -> Right RT. FAT_CSize
167+ HsPrimCLLong -> Right RT. FAT_CLLong
168+ HsPrimCULLong -> Right RT. FAT_CULLong
169+ HsPrimCBool -> Right RT. FAT_CBool
170+ HsPrimCFloat -> Right RT. FAT_CFloat
171+ HsPrimCDouble -> Right RT. FAT_CDouble
172+ HsPrimCStringLen -> Left " impossible foreign arg type"
173+ HsPrimInt -> Right RT. FAT_Int
0 commit comments