-- Data types that are used by more than one intermediate form.
-- See also IR.Name, which defines identifiers, which are also
-- used in more than one IR.
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE LambdaCase #-}
module IR.Common where
import Data.Word
import qualified Capnp.Untyped.Pure as U
newtype TypeId = TypeId Word64
deriving(Show, Read, Eq, Ord)
data IntType = IntType !Sign !IntSize
deriving(Show, Read, Eq)
data Sign
= Signed
| Unsigned
deriving(Show, Read, Eq)
data IntSize
= Sz8
| Sz16
| Sz32
| Sz64
deriving(Show, Read, Eq)
sizeBits :: IntSize -> Int
sizeBits Sz8 = 8
sizeBits Sz16 = 16
sizeBits Sz32 = 32
sizeBits Sz64 = 64
-- | Return the size in bits of a type that belongs in the data section of a struct.
dataFieldSize :: WordType r -> Int
dataFieldSize = \case
EnumType _ -> 16
PrimWord (PrimInt (IntType _ size)) -> sizeBits size
PrimWord PrimFloat32 -> 32
PrimWord PrimFloat64 -> 64
PrimWord PrimBool -> 1
-- Capnproto types. The 'r' type parameter is the type of references to other nodes,
-- which may be different in different stages of the pipeline.
data Type r
= CompositeType (CompositeType r)
| VoidType
| WordType (WordType r)
| PtrType (PtrType r)
deriving(Show, Read, Eq, Functor)
newtype CompositeType r
= StructType r
deriving(Show, Read, Eq, Functor)
data WordType r
= EnumType r
| PrimWord PrimWord
deriving(Show, Read, Eq, Functor)
data PtrType r
= ListOf (Type r)
| PrimPtr PrimPtr
| PtrComposite (CompositeType r)
| PtrInterface r
deriving(Show, Read, Eq, Functor)
data PrimWord
= PrimInt IntType
| PrimFloat32
| PrimFloat64
| PrimBool
deriving(Show, Read, Eq)
data PrimPtr
= PrimText
| PrimData
| PrimAnyPtr AnyPtr
deriving(Show, Read, Eq)
data AnyPtr
= Struct
| List
| Cap
| Ptr
deriving(Show, Read, Eq)
-- | The type and location of a field.
data FieldLocType r
-- | The field is in the struct's data section.
= DataField DataLoc (WordType r)
-- | The field is in the struct's pointer section (the argument is the
-- index).
| PtrField !Word16 (PtrType r)
-- | The field is a group or union; it's "location" is the whole struct.
| HereField (CompositeType r)
-- | The field is of type void (and thus is zero-size).
| VoidField
deriving(Show, Read, Eq, Functor)
-- | The location of a field within a struct's data section.
data DataLoc = DataLoc
{ dataIdx :: !Int
-- ^ The index of the 64-bit word containing the field.
, dataOff :: !Int
-- ^ The bit offset inside the 64-bit word.
, dataDef :: !Word64
-- ^ The value is stored xor-ed with this value. This is used
-- to allow for encoding default values. Note that this is xor-ed
-- with the bits representing the value, not the whole word.
}
deriving(Show, Read, Eq)
data Value r
= VoidValue
| WordValue (WordType r) !Word64
| PtrValue (PtrType r) (Maybe U.Ptr)
deriving(Show, Eq, Functor)
-- | Extract the type from a 'FildLocType'.
fieldType :: FieldLocType r -> Type r
fieldType (DataField _ ty) = WordType ty
fieldType (PtrField _ ty) = PtrType ty
fieldType (HereField ty) = CompositeType ty
fieldType VoidField = VoidType