Types.hs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. module Gidl.Types
  2. ( module Gidl.Types.AST
  3. , module Gidl.Types.Base
  4. , lookupTypeName
  5. , insertType
  6. , typeLeaves
  7. , childTypes
  8. , sizeOf
  9. , basePrimType
  10. , typeName
  11. ) where
  12. import Data.Tuple (swap)
  13. import Data.List (nub)
  14. import Gidl.Types.AST
  15. import Gidl.Types.Base
  16. lookupTypeName :: TypeName -> TypeEnv -> Maybe Type
  17. lookupTypeName tn te =
  18. case aux te of
  19. Just a -> Just a
  20. Nothing -> case aux baseTypeEnv of
  21. Just a -> Just a
  22. Nothing -> Nothing
  23. where
  24. aux (TypeEnv e) = lookup tn e
  25. typeName :: Type -> TypeName
  26. typeName (StructType n _) = n
  27. typeName (PrimType (EnumType n _ _)) = n
  28. typeName (PrimType (Newtype n _)) = n
  29. typeName (PrimType VoidType) = error "XXX"
  30. typeName t@(PrimType (AtomType _)) =
  31. let TypeEnv bte = baseTypeEnv in
  32. case lookup t (map swap bte) of
  33. Just n -> n
  34. Nothing -> error "impossible: cannot find name for AtomType in baseTypeEnv"
  35. insertType :: TypeName -> Type -> TypeEnv -> TypeEnv
  36. insertType tn t e@(TypeEnv te) = case lookupTypeName tn e of
  37. Nothing -> TypeEnv ((tn,t):te)
  38. Just _ -> error ("insertType invariant broken: type " ++ tn ++ " already exists")
  39. typeLeaves :: Type -> [Type]
  40. typeLeaves (StructType _ s) = nub (map snd s)
  41. typeLeaves (PrimType (Newtype _ tn)) = [PrimType tn]
  42. typeLeaves _ = []
  43. childTypes :: Type -> [Type]
  44. childTypes t = [t] ++ concat (map childTypes (typeLeaves t))
  45. sizeOf :: Type -> Integer
  46. sizeOf (StructType _ s) = sum [ sizeOf tr | (_, tr) <- s ]
  47. sizeOf (PrimType (Newtype _ tr)) = sizeOf (PrimType tr)
  48. sizeOf (PrimType (EnumType _ bs _)) = bitsSize bs
  49. sizeOf (PrimType (AtomType (AtomInt bs))) = bitsSize bs
  50. sizeOf (PrimType (AtomType (AtomWord bs))) = bitsSize bs
  51. sizeOf (PrimType (AtomType AtomFloat)) = 4
  52. sizeOf (PrimType (AtomType AtomDouble)) = 8
  53. sizeOf (PrimType VoidType) = 0
  54. bitsSize :: Bits -> Integer
  55. bitsSize Bits8 = 1
  56. bitsSize Bits16 = 2
  57. bitsSize Bits32 = 4
  58. bitsSize Bits64 = 8
  59. -- Reduce a newtype to the innermost concrete type
  60. basePrimType :: PrimType -> PrimType
  61. basePrimType (Newtype _ t) = basePrimType t
  62. basePrimType a = a