module LLVM.Core.Type(
IsType(..),
IsArithmetic,
IsInteger,
IsFloating,
IsPrimitive,
IsFirstClass,
IsSized,
IsFunction,
IsPowerOf2,
TypeDesc(..),
isFloating,
isSigned,
typeRef,
typeName
) where
import Data.List(intercalate)
import Data.Int
import Data.Word
import Data.TypeNumbers
import LLVM.Core.Util(functionType)
import LLVM.Core.Data
import qualified LLVM.FFI.Core as FFI
class (IsTypeNumber n) => IsPowerOf2 n
instance IsPowerOf2 (D1 End)
instance IsPowerOf2 (D2 End)
instance IsPowerOf2 (D4 End)
instance IsPowerOf2 (D8 End)
instance IsPowerOf2 (D1 (D6 End))
instance IsPowerOf2 (D3 (D2 End))
instance IsPowerOf2 (D6 (D4 End))
instance IsPowerOf2 (D1 (D2 (D8 End)))
instance IsPowerOf2 (D2 (D5 (D6 End)))
instance IsPowerOf2 (D5 (D1 (D2 End)))
class IsType a where
typeDesc :: a -> TypeDesc
typeRef :: (IsType a) => a -> FFI.TypeRef
typeRef = code . typeDesc
where code TDFloat = FFI.floatType
code TDDouble = FFI.doubleType
code TDFP128 = FFI.fp128Type
code TDVoid = FFI.voidType
code (TDInt _ n) = FFI.integerType (fromInteger n)
code (TDArray n a) = FFI.arrayType (code a) (fromInteger n)
code (TDVector n a) = FFI.vectorType (code a) (fromInteger n)
code (TDPtr a) = FFI.pointerType (code a) 0
code (TDFunction as b) = functionType False (code b) (map code as)
typeName :: (IsType a) => a -> String
typeName = code . typeDesc
where code TDFloat = "f32"
code TDDouble = "f64"
code TDFP128 = "f128"
code TDVoid = "void"
code (TDInt _ n) = "i" ++ show n
code (TDArray n a) = "[" ++ show n ++ " x " ++ code a ++ "]"
code (TDVector n a) = "<" ++ show n ++ " x " ++ code a ++ ">"
code (TDPtr a) = code a ++ "*"
code (TDFunction as b) = code b ++ "(" ++ intercalate "," (map code as) ++ ")"
data TypeDesc = TDFloat | TDDouble | TDFP128 | TDVoid | TDInt Bool Integer
| TDArray Integer TypeDesc | TDVector Integer TypeDesc
| TDPtr TypeDesc | TDFunction [TypeDesc] TypeDesc
deriving (Eq, Ord, Show)
class IsFirstClass a => IsArithmetic a
class IsArithmetic a => IsInteger a
isSigned :: (IsInteger a) => a -> Bool
isSigned = is . typeDesc
where is (TDInt s _) = s
is (TDVector _ a) = is a
is _ = error "isSigned got impossible input"
class IsArithmetic a => IsFloating a
isFloating :: (IsArithmetic a) => a -> Bool
isFloating = is . typeDesc
where is TDFloat = True
is TDDouble = True
is TDFP128 = True
is (TDVector _ a) = is a
is _ = False
class IsType a => IsPrimitive a
class IsType a => IsFirstClass a
class (IsType a) => IsSized a
class (IsType a) => IsFunction a where
funcType :: [TypeDesc] -> a -> TypeDesc
instance IsType Float where typeDesc _ = TDFloat
instance IsType Double where typeDesc _ = TDDouble
instance IsType FP128 where typeDesc _ = TDFP128
instance IsType () where typeDesc _ = TDVoid
instance (IsTypeNumber n) => IsType (IntN n)
where typeDesc _ = TDInt True (typeNumber (undefined :: n))
instance (IsTypeNumber n) => IsType (WordN n)
where typeDesc _ = TDInt False (typeNumber (undefined :: n))
instance IsType Bool where typeDesc _ = TDInt False 1
instance IsType Word8 where typeDesc _ = TDInt False 8
instance IsType Word16 where typeDesc _ = TDInt False 16
instance IsType Word32 where typeDesc _ = TDInt False 32
instance IsType Word64 where typeDesc _ = TDInt False 64
instance IsType Int8 where typeDesc _ = TDInt True 8
instance IsType Int16 where typeDesc _ = TDInt True 16
instance IsType Int32 where typeDesc _ = TDInt True 32
instance IsType Int64 where typeDesc _ = TDInt True 64
instance (IsTypeNumber n, IsSized a) => IsType (Array n a)
where typeDesc _ = TDArray (typeNumber (undefined :: n))
(typeDesc (undefined :: a))
instance (IsPowerOf2 n, IsPrimitive a) => IsType (Vector n a)
where typeDesc _ = TDVector (typeNumber (undefined :: n))
(typeDesc (undefined :: a))
instance (IsType a) => IsType (Ptr a) where
typeDesc _ = TDPtr (typeDesc (undefined :: a))
instance (IsFirstClass a, IsFunction b) => IsType (a->b) where
typeDesc = funcType []
instance (IsFirstClass a) => IsType (IO a) where
typeDesc = funcType []
instance IsArithmetic Float
instance IsArithmetic Double
instance IsArithmetic FP128
instance (IsTypeNumber n) => IsArithmetic (IntN n)
instance (IsTypeNumber n) => IsArithmetic (WordN n)
instance IsArithmetic Bool
instance IsArithmetic Int8
instance IsArithmetic Int16
instance IsArithmetic Int32
instance IsArithmetic Int64
instance IsArithmetic Word8
instance IsArithmetic Word16
instance IsArithmetic Word32
instance IsArithmetic Word64
instance (IsPowerOf2 n, IsPrimitive a, IsArithmetic a) => IsArithmetic (Vector n a)
instance IsFloating Float
instance IsFloating Double
instance IsFloating FP128
instance (IsPowerOf2 n, IsPrimitive a, IsFloating a) => IsFloating (Vector n a)
instance (IsTypeNumber n) => IsInteger (IntN n)
instance (IsTypeNumber n) => IsInteger (WordN n)
instance IsInteger Bool
instance IsInteger Int8
instance IsInteger Int16
instance IsInteger Int32
instance IsInteger Int64
instance IsInteger Word8
instance IsInteger Word16
instance IsInteger Word32
instance IsInteger Word64
instance (IsPowerOf2 n, IsPrimitive a, IsInteger a) => IsInteger (Vector n a)
instance IsFirstClass Float
instance IsFirstClass Double
instance IsFirstClass FP128
instance (IsTypeNumber n) => IsFirstClass (IntN n)
instance (IsTypeNumber n) => IsFirstClass (WordN n)
instance IsFirstClass Bool
instance IsFirstClass Int8
instance IsFirstClass Int16
instance IsFirstClass Int32
instance IsFirstClass Int64
instance IsFirstClass Word8
instance IsFirstClass Word16
instance IsFirstClass Word32
instance IsFirstClass Word64
instance (IsPowerOf2 n, IsPrimitive a) => IsFirstClass (Vector n a)
instance (IsType a) => IsFirstClass (Ptr a)
instance IsFirstClass ()
instance IsSized Float
instance IsSized Double
instance IsSized FP128
instance (IsTypeNumber n) => IsSized (IntN n)
instance (IsTypeNumber n) => IsSized (WordN n)
instance IsSized Bool
instance IsSized Int8
instance IsSized Int16
instance IsSized Int32
instance IsSized Int64
instance IsSized Word8
instance IsSized Word16
instance IsSized Word32
instance IsSized Word64
instance (IsTypeNumber n, IsSized a) => IsSized (Array n a)
instance (IsPowerOf2 n, IsPrimitive a) => IsSized (Vector n a)
instance (IsType a) => IsSized (Ptr a)
instance IsPrimitive Float
instance IsPrimitive Double
instance IsPrimitive FP128
instance (IsTypeNumber n) => IsPrimitive (IntN n)
instance (IsTypeNumber n) => IsPrimitive (WordN n)
instance IsPrimitive Bool
instance IsPrimitive Int8
instance IsPrimitive Int16
instance IsPrimitive Int32
instance IsPrimitive Int64
instance IsPrimitive Word8
instance IsPrimitive Word16
instance IsPrimitive Word32
instance IsPrimitive Word64
instance IsPrimitive ()
instance (IsFirstClass a, IsFunction b) => IsFunction (a->b) where
funcType ts _ = funcType (typeDesc (undefined :: a) : ts) (undefined :: b)
instance (IsFirstClass a) => IsFunction (IO a) where
funcType ts _ = TDFunction (reverse ts) (typeDesc (undefined :: a))