mirror of
https://github.com/zap-proto/haskell.git
synced 2026-10-30 15:05:00 +00:00
215 lines
5.9 KiB
Haskell
215 lines
5.9 KiB
Haskell
-- 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.New.Basics as B
|
|
import Capnp.Repr.Parsed (Parsed)
|
|
import Data.Bifunctor (Bifunctor(..))
|
|
import qualified Data.Map.Strict as M
|
|
import qualified Data.Vector as V
|
|
import qualified IR.Name as Name
|
|
|
|
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. Likewise, the 'b'
|
|
-- parameter is the "Brand."
|
|
|
|
bothMap :: (Bifunctor p, Functor f) => (a -> b) -> p (f a) a -> p (f b) b
|
|
bothMap f = bimap (fmap f) f
|
|
|
|
newtype ListBrand r = ListBrand [PtrType (ListBrand r) r]
|
|
deriving(Show, Read, Eq)
|
|
|
|
instance Functor ListBrand where
|
|
fmap f (ListBrand ps) = ListBrand (fmap (bothMap f) ps)
|
|
|
|
newtype MapBrand r = MapBrand (M.Map Word64 (BrandScope r))
|
|
deriving(Show, Eq)
|
|
|
|
instance Functor MapBrand where
|
|
fmap f (MapBrand m) = MapBrand $ fmap (fmap f) m
|
|
|
|
newtype BrandScope r = Bind (V.Vector (Binding r))
|
|
deriving(Show, Eq)
|
|
|
|
instance Functor BrandScope where
|
|
fmap f (Bind bs) = Bind $ fmap (fmap f) bs
|
|
|
|
data Binding r = Unbound | BoundType (PtrType (MapBrand r) r)
|
|
deriving(Show, Eq)
|
|
|
|
instance Functor Binding where
|
|
fmap _ Unbound = Unbound
|
|
fmap f (BoundType ty) = BoundType $ bothMap f ty
|
|
|
|
data TypeParamRef r = TypeParamRef
|
|
{ paramScope :: r
|
|
, paramIndex :: !Int
|
|
, paramName :: Name.UnQ
|
|
}
|
|
deriving(Show, Read, Eq, Functor)
|
|
|
|
data Type b r
|
|
= CompositeType (CompositeType b r)
|
|
| VoidType
|
|
| WordType (WordType r)
|
|
| PtrType (PtrType b r)
|
|
deriving(Show, Read, Eq, Functor)
|
|
|
|
instance Bifunctor Type where
|
|
second = fmap
|
|
first f = \case
|
|
CompositeType x -> CompositeType (first f x)
|
|
VoidType -> VoidType
|
|
WordType x -> WordType x
|
|
PtrType x -> PtrType (first f x)
|
|
|
|
data CompositeType b r
|
|
= StructType r b
|
|
deriving(Show, Read, Eq, Functor)
|
|
|
|
instance Bifunctor CompositeType where
|
|
second = fmap
|
|
first f (StructType r b) = StructType r (f b)
|
|
|
|
data InterfaceType b r
|
|
= InterfaceType r b
|
|
deriving(Show, Read, Eq, Functor)
|
|
|
|
instance Bifunctor InterfaceType where
|
|
second = fmap
|
|
first f (InterfaceType r b) = InterfaceType r (f b)
|
|
|
|
data WordType r
|
|
= EnumType r
|
|
| PrimWord PrimWord
|
|
deriving(Show, Read, Eq, Functor)
|
|
|
|
data PtrType b r
|
|
= ListOf (Type b r)
|
|
| PrimPtr PrimPtr
|
|
| PtrComposite (CompositeType b r)
|
|
| PtrInterface (InterfaceType b r)
|
|
| PtrParam (TypeParamRef r)
|
|
deriving(Show, Read, Eq, Functor)
|
|
|
|
instance Bifunctor PtrType where
|
|
second = fmap
|
|
first f = \case
|
|
ListOf x -> ListOf (first f x)
|
|
PrimPtr x -> PrimPtr x
|
|
PtrComposite x -> PtrComposite (first f x)
|
|
PtrInterface x -> PtrInterface (first f x)
|
|
PtrParam p -> PtrParam p
|
|
|
|
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 b 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 b r)
|
|
-- | The field is a group or union; it's "location" is the whole struct.
|
|
| HereField (CompositeType b r)
|
|
-- | The field is of type void (and thus is zero-size).
|
|
| VoidField
|
|
deriving(Show, Read, Eq, Functor)
|
|
|
|
instance Bifunctor FieldLocType where
|
|
second = fmap
|
|
first f = \case
|
|
DataField l t -> DataField l t
|
|
PtrField idx t -> PtrField idx (first f t)
|
|
HereField t -> HereField (first f t)
|
|
VoidField -> VoidField
|
|
|
|
-- | 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 b r
|
|
= VoidValue
|
|
| WordValue (WordType r) !Word64
|
|
| PtrValue (PtrType b r) (Maybe (Parsed B.AnyPointer))
|
|
deriving(Show, Eq, Functor)
|
|
|
|
instance Bifunctor Value where
|
|
second = fmap
|
|
first f = \case
|
|
VoidValue -> VoidValue
|
|
WordValue t v -> WordValue t v
|
|
PtrValue t v -> PtrValue (first f t) v
|
|
|
|
-- | Extract the type from a 'FildLocType'.
|
|
fieldType :: FieldLocType r b -> Type r b
|
|
fieldType (DataField _ ty) = WordType ty
|
|
fieldType (PtrField _ ty) = PtrType ty
|
|
fieldType (HereField ty) = CompositeType ty
|
|
fieldType VoidField = VoidType
|