ddc-core-salt-0.3.1.1: DDC/Core/Salt/Name/PrimTyCon.hs
module DDC.Core.Salt.Name.PrimTyCon
( PrimTyCon (..)
, readPrimTyCon
, primTyConIsIntegral
, primTyConIsFloating
, primTyConIsUnsigned
, primTyConIsSigned
, primTyConWidth)
where
import DDC.Base.Pretty
import DDC.Core.Salt.Platform
import Data.Char
import Data.List
import Control.DeepSeq
-- PrimTyCon -----------------------------------------------------------------
-- | Primitive type constructors.
data PrimTyCon
-- | @Void#@ the Void type has no values.
= PrimTyConVoid
-- | @Bool#@ unboxed booleans.
| PrimTyConBool
-- | @Nat#@ natural numbers.
-- Big enough to count every addressable byte in the store.
| PrimTyConNat
-- | @Int#@ signed integers.
| PrimTyConInt
-- | @WordN#@ machine words of the given width.
| PrimTyConWord Int
-- | @FloatN#@ floating point numbers of the given width.
| PrimTyConFloat Int
-- | @Tag#@ data constructor tags.
| PrimTyConTag
-- | @Addr#@ raw machine addresses. Unlike pointers below,
-- a raw @Addr#@ need not to refer to memory owned
-- by the current process.
| PrimTyConAddr
-- | @Ptr#@ should point to a well-formed object owned by the
-- current process.
| PrimTyConPtr
-- | @String#@ of UTF8 characters.
--
-- These are primitive until we can define our own unboxed types.
| PrimTyConString
deriving (Eq, Ord, Show)
instance NFData PrimTyCon where
rnf tc
= case tc of
PrimTyConWord i -> rnf i
PrimTyConFloat i -> rnf i
_ -> ()
instance Pretty PrimTyCon where
ppr tc
= case tc of
PrimTyConVoid -> text "Void#"
PrimTyConBool -> text "Bool#"
PrimTyConNat -> text "Nat#"
PrimTyConInt -> text "Int#"
PrimTyConWord bits -> text "Word" <> int bits <> text "#"
PrimTyConFloat bits -> text "Float" <> int bits <> text "#"
PrimTyConTag -> text "Tag#"
PrimTyConAddr -> text "Addr#"
PrimTyConPtr -> text "Ptr#"
PrimTyConString -> text "String#"
-- | Read a primitive type constructor.
--
-- Words are limited to 8, 16, 32, or 64 bits.
--
-- Floats are limited to 32 or 64 bits.
readPrimTyCon :: String -> Maybe PrimTyCon
readPrimTyCon str
| str == "Void#" = Just $ PrimTyConVoid
| str == "Bool#" = Just $ PrimTyConBool
| str == "Nat#" = Just $ PrimTyConNat
| str == "Int#" = Just $ PrimTyConInt
| str == "Tag#" = Just $ PrimTyConTag
| str == "Addr#" = Just $ PrimTyConAddr
| str == "Ptr#" = Just $ PrimTyConPtr
| str == "String#" = Just $ PrimTyConString
-- WordN#
| Just rest <- stripPrefix "Word" str
, (ds, "#") <- span isDigit rest
, not $ null ds
, n <- read ds
, elem n [8, 16, 32, 64]
= Just $ PrimTyConWord n
-- FloatN#
| Just rest <- stripPrefix "Float" str
, (ds, "#") <- span isDigit rest
, not $ null ds
, n <- read ds
, elem n [32, 64]
= Just $ PrimTyConFloat n
| otherwise
= Nothing
-- | Integral constructors are the ones that we can reasonably
-- convert from integers of the same size.
--
-- These are @Bool#@ @Nat#@ @Int#@ @WordN#@ and @Tag#@.
--
primTyConIsIntegral :: PrimTyCon -> Bool
primTyConIsIntegral tc
= case tc of
PrimTyConBool -> True
PrimTyConNat -> True
PrimTyConInt -> True
PrimTyConWord{} -> True
PrimTyConTag -> True
_ -> False
-- | Floating point constructors.
--
-- These are @FloatN@.
primTyConIsFloating :: PrimTyCon -> Bool
primTyConIsFloating tc
= case tc of
PrimTyConFloat{} -> True
_ -> False
-- | Unsigned integral constructors.
--
-- These are @Bool@ @Nat@ @WordN@ @Tag@.
primTyConIsUnsigned :: PrimTyCon -> Bool
primTyConIsUnsigned tc
= case tc of
PrimTyConBool -> True
PrimTyConNat -> True
PrimTyConWord{} -> True
PrimTyConTag -> True
_ -> False
-- | Signed integral constructors.
--
-- This is just @Int@.
primTyConIsSigned :: PrimTyCon -> Bool
primTyConIsSigned tc
= case tc of
PrimTyConInt -> True
PrimTyConFloat{} -> True
_ -> False
-- | Get the representation width of a primitive type constructor,
-- in bits. This is how much space it takes up in an object payload.
--
-- Bools are representable with a single bit, but we unpack
-- them into a whole word.
--
-- The abstract constructors `Void` and `String` have no width.
primTyConWidth :: Platform -> PrimTyCon -> Maybe Integer
primTyConWidth pp tc
= case tc of
PrimTyConBool -> Just $ 8 * platformNatBytes pp
PrimTyConNat -> Just $ 8 * platformNatBytes pp
PrimTyConInt -> Just $ 8 * platformNatBytes pp
PrimTyConWord bits -> Just $ fromIntegral bits
PrimTyConFloat bits -> Just $ fromIntegral bits
PrimTyConTag -> Just $ 8 * platformTagBytes pp
PrimTyConAddr -> Just $ 8 * platformAddrBytes pp
PrimTyConPtr -> Just $ 8 * platformAddrBytes pp
PrimTyConVoid -> Nothing
PrimTyConString -> Nothing