Types.hs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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 t@(PrimType (AtomType _)) =
  30. let TypeEnv bte = baseTypeEnv in
  31. case lookup t (map swap bte) of
  32. Just n -> n
  33. Nothing -> error "impossible: cannot find name for AtomType in baseTypeEnv"
  34. insertType :: TypeName -> Type -> TypeEnv -> TypeEnv
  35. insertType tn t e@(TypeEnv te) = case lookupTypeName tn e of
  36. Nothing -> TypeEnv ((tn,t):te)
  37. Just _ -> error ("insertType invariant broken: type " ++ tn ++ " already exists")
  38. typeLeaves :: Type -> [Type]
  39. typeLeaves (StructType _ s) = nub (map snd s)
  40. typeLeaves (PrimType (Newtype _ tn)) = [PrimType tn]
  41. typeLeaves _ = []
  42. childTypes :: Type -> [Type]
  43. childTypes t = [t] ++ concat (map childTypes (typeLeaves t))
  44. sizeOf :: Type -> Integer
  45. sizeOf (StructType _ s) = sum [ sizeOf tr | (_, tr) <- s ]
  46. sizeOf (PrimType (Newtype _ tr)) = sizeOf (PrimType tr)
  47. sizeOf (PrimType (EnumType _ bs _)) = bitsSize bs
  48. sizeOf (PrimType (AtomType (AtomInt bs))) = bitsSize bs
  49. sizeOf (PrimType (AtomType (AtomWord bs))) = bitsSize bs
  50. sizeOf (PrimType (AtomType AtomFloat)) = 4
  51. sizeOf (PrimType (AtomType AtomDouble)) = 8
  52. bitsSize :: Bits -> Integer
  53. bitsSize Bits8 = 1
  54. bitsSize Bits16 = 2
  55. bitsSize Bits32 = 4
  56. bitsSize Bits64 = 8
  57. -- Reduce a newtype to the innermost concrete type
  58. basePrimType :: PrimType -> PrimType
  59. basePrimType (Newtype _ t) = basePrimType t
  60. basePrimType a = a