clr-inline-0.2.0.1: src/Clr/Inline/Types.hs
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeInType #-}
module Clr.Inline.Types
( ClrPtr(..)
, Clr(..)
, ClrType(Con, Unit, ..)
, ClrTypeSymbol(..)
, renderClrType
, TextBStr(..)
) where
import Clr.Host.GCHandle
import Clr.Host.BStr
import Clr.Marshal
import Data.Coerce
import Data.List
import Data.Text (Text)
import Foreign
import GHC.TypeLits
import System.IO.Unsafe
data ClrType = TyCon String [ClrType]
| Fun [ClrType] ClrType
| Array Int ClrType
deriving (Eq, Show)
renderClrType :: ClrType -> String
renderClrType = show where
show (Array dim x) = concat [show x, "[", replicate (pred dim) ',', "]"]
show (TyCon con []) = con
show (TyCon con args) = concat [con,"<",intercalate "," (map show args),">"]
show (Fun args res) = intercalate "->" $ map show (args ++ [res])
pattern Unit :: ClrType
pattern Unit = TyCon "unit" []
pattern Con :: String -> ClrType
pattern Con x = TyCon x []
-- | A type indexed pointer to a Clr object.
newtype ClrPtr (name::Symbol)= ClrPtr (GCHandle Int)
-- | A type indexed pointer to a Clr object with GC managed lifetime.
newtype Clr (name::Symbol) = Clr (ForeignPtr Int)
-- Returning from a CLR function that was called from Haskell
instance Unmarshal (ClrPtr n) (Clr n) where
unmarshal (ClrPtr id) = do
ptr <- newForeignPtr (unsafeDupablePerformIO gcHandleFinalizer) (coerce id)
return (Clr ptr)
-- Returning from a Haskell function that was called by the CLR
instance {-# OVERLAPPING #-} Unmarshal (Clr t) (ClrPtr t) where
unmarshal (Clr x) = withForeignPtr x $ \x'-> ClrPtr <$> newHandle (coerce x')
-- Calling a CLR function from Haskell
instance Marshal (Clr n) (ClrPtr n) where
marshal (Clr ptr) f = withForeignPtr ptr $ \p -> f (ClrPtr $ coerce p)
-- Calling a Haskell function from the CLR
instance {-# OVERLAPPING #-} Marshal (ClrPtr t) (Clr t) where
marshal (ClrPtr x) f = do
x' <- newHandle x
fp <- newForeignPtr (unsafeDupablePerformIO gcHandleFinalizer) (coerce x')
f $ Clr fp
newtype ClrTypeSymbol = ClrTypeSymbol {getClrTypeSymbol :: String} deriving Show
newtype TextBStr = TextBStr BStr
instance Unmarshal TextBStr Text where unmarshal (TextBStr t) = unmarshal t
instance Marshal Text TextBStr where marshal x f = marshal x (f . TextBStr)