-- 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)