mirror of
https://github.com/zap-proto/haskell.git
synced 2026-10-30 15:05:00 +00:00
113 lines
3.4 KiB
Haskell
113 lines
3.4 KiB
Haskell
-- IR for a high-level representation of the low-level API modules.
|
|
--
|
|
-- This talks about things like getters, setters, wrapper types for structs,
|
|
-- etc. It's still not at the level of detail of actual Haskell, but encodes
|
|
-- the constructs to be generated, as opposed to the declarative description
|
|
-- of the schema.
|
|
{-# LANGUAGE DuplicateRecordFields #-}
|
|
module IR.Raw (File(..), Decl(..), Variant(..), TagSetter(..), NewFnType(..), tagOffsetToDataLoc) where
|
|
|
|
import Data.Word
|
|
|
|
import qualified IR.Common as Common
|
|
import qualified IR.Name as Name
|
|
|
|
data File = File
|
|
{ fileId :: !Word64
|
|
, fileName :: FilePath
|
|
, decls :: [Decl]
|
|
}
|
|
deriving(Show, Eq)
|
|
|
|
data Decl
|
|
-- | Define a newtype wrapper around a struct. This also defines
|
|
-- some instances of type classes that exist for all such wrappers.
|
|
= StructWrapper
|
|
{ typeCtor :: Name.LocalQ
|
|
}
|
|
-- | Define instances of several type classes which should only
|
|
-- exist for "real" structs, i.e. not groups.
|
|
| StructInstances
|
|
{ typeCtor :: Name.LocalQ
|
|
-- ^ The type constructor for the type to generate instances for.
|
|
|
|
-- Needed for some instances:
|
|
, dataWordCount :: !Word16
|
|
, pointerCount :: !Word16
|
|
}
|
|
| InterfaceWrapper
|
|
{ typeCtor :: Name.LocalQ
|
|
}
|
|
| UnionVariant
|
|
{ parentTypeCtor :: Name.LocalQ
|
|
-- ^ The type constructor of the parent, i.e. the enclosing struct.
|
|
-- we can derive the type constructor for the union proper from this,
|
|
-- and it is useful to have for other things (like unknown' variants).
|
|
, tagOffset :: !Word32
|
|
, unionDataCtors :: [Variant]
|
|
}
|
|
| Enum
|
|
{ typeCtor :: Name.LocalQ
|
|
, dataCtors :: [Name.LocalQ]
|
|
}
|
|
| Getter -- get_* function
|
|
{ fieldName :: Name.LocalQ
|
|
, containerType :: Name.LocalQ
|
|
, fieldLocType :: Common.FieldLocType Name.CapnpQ
|
|
}
|
|
| Setter -- set_* function
|
|
{ fieldName :: Name.LocalQ
|
|
, containerType :: Name.LocalQ
|
|
, fieldLocType :: Common.FieldLocType Name.CapnpQ
|
|
|
|
, tag :: Maybe TagSetter
|
|
-- ^ Info for setting the tag, if this is a union.
|
|
}
|
|
| HasFn -- has_* function
|
|
{ fieldName :: Name.LocalQ
|
|
, containerType :: Name.LocalQ
|
|
, ptrIndex :: !Word16
|
|
}
|
|
| NewFn -- new_* function
|
|
{ fieldName :: Name.LocalQ
|
|
, containerType :: Name.LocalQ
|
|
, fieldLocType :: Common.FieldLocType Name.CapnpQ
|
|
|
|
, newFnType :: NewFnType
|
|
}
|
|
| Constant
|
|
{ name :: Name.LocalQ
|
|
, value :: Common.Value Name.CapnpQ
|
|
}
|
|
deriving(Show, Eq)
|
|
|
|
data NewFnType
|
|
= NewList
|
|
| NewText
|
|
| NewData
|
|
| NewStruct
|
|
deriving(Show, Eq)
|
|
|
|
data TagSetter = TagSetter
|
|
{ tagOffset :: !Word32
|
|
, tagValue :: !Word16
|
|
}
|
|
deriving(Show, Eq)
|
|
|
|
-- | Convert a tag offset (as in the 'tagOffset' field of 'TagSetter') to a
|
|
-- corresponding 'Common.DataLoc', with the default value set to zero.
|
|
tagOffsetToDataLoc :: Word32 -> Common.DataLoc
|
|
tagOffsetToDataLoc tagOffset =
|
|
Common.DataLoc
|
|
{ dataIdx = fromIntegral tagOffset `div` 4
|
|
, dataOff = (fromIntegral tagOffset `mod` 4) * 16
|
|
, dataDef = 0
|
|
}
|
|
|
|
data Variant = Variant
|
|
{ name :: Name.LocalQ
|
|
, tagValue :: !Word16
|
|
, locType :: Common.FieldLocType Name.CapnpQ
|
|
}
|
|
deriving(Show, Eq)
|