Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
GHC.Types.Literal
Description
Core literals
Synopsis
- data Literal
- = LitChar Char
- | LitNumber !LitNumType !Integer
- | LitString !ByteString
- | LitNullAddr
- | LitRubbish TypeOrConstraint RuntimeRepType
- | LitFloat Rational
- | LitDouble Rational
- | LitLabel FastString (Maybe Int) FunctionOrData
- data LitNumType
- mkLitInt :: Platform -> Integer -> Literal
- mkLitIntWrap :: Platform -> Integer -> Literal
- mkLitIntWrapC :: Platform -> Integer -> (Literal, Bool)
- mkLitIntUnchecked :: Integer -> Literal
- mkLitWord :: Platform -> Integer -> Literal
- mkLitWordWrap :: Platform -> Integer -> Literal
- mkLitWordWrapC :: Platform -> Integer -> (Literal, Bool)
- mkLitWordUnchecked :: Integer -> Literal
- mkLitInt8 :: Integer -> Literal
- mkLitInt8Wrap :: Integer -> Literal
- mkLitInt8Unchecked :: Integer -> Literal
- mkLitWord8 :: Integer -> Literal
- mkLitWord8Wrap :: Integer -> Literal
- mkLitWord8Unchecked :: Integer -> Literal
- mkLitInt16 :: Integer -> Literal
- mkLitInt16Wrap :: Integer -> Literal
- mkLitInt16Unchecked :: Integer -> Literal
- mkLitWord16 :: Integer -> Literal
- mkLitWord16Wrap :: Integer -> Literal
- mkLitWord16Unchecked :: Integer -> Literal
- mkLitInt32 :: Integer -> Literal
- mkLitInt32Wrap :: Integer -> Literal
- mkLitInt32Unchecked :: Integer -> Literal
- mkLitWord32 :: Integer -> Literal
- mkLitWord32Wrap :: Integer -> Literal
- mkLitWord32Unchecked :: Integer -> Literal
- mkLitInt64 :: Integer -> Literal
- mkLitInt64Wrap :: Integer -> Literal
- mkLitInt64Unchecked :: Integer -> Literal
- mkLitWord64 :: Integer -> Literal
- mkLitWord64Wrap :: Integer -> Literal
- mkLitWord64Unchecked :: Integer -> Literal
- mkLitFloat :: Rational -> Literal
- mkLitDouble :: Rational -> Literal
- mkLitChar :: Char -> Literal
- mkLitString :: String -> Literal
- mkLitBigNat :: Integer -> Literal
- mkLitNumber :: Platform -> LitNumType -> Integer -> Literal
- mkLitNumberWrap :: Platform -> LitNumType -> Integer -> Literal
- mkLitNumberMaybe :: Platform -> LitNumType -> Integer -> Maybe Literal
- literalType :: Literal -> Type
- pprLiteral :: (SDoc -> SDoc) -> Literal -> SDoc
- litNumIsSigned :: LitNumType -> Bool
- litNumRange :: Platform -> LitNumType -> (Maybe Integer, Maybe Integer)
- litNumCheckRange :: Platform -> LitNumType -> Integer -> Bool
- litNumWrap :: Platform -> Literal -> Literal
- litNumCoerce :: LitNumType -> Platform -> Literal -> Literal
- litNumNarrow :: LitNumType -> Platform -> Literal -> Literal
- litNumBitSize :: Platform -> LitNumType -> Maybe Word
- isMinBound :: Platform -> Literal -> Bool
- isMaxBound :: Platform -> Literal -> Bool
- litIsDupable :: Platform -> Literal -> Bool
- litIsTrivial :: Literal -> Bool
- litIsLifted :: Literal -> Bool
- inCharRange :: Char -> Bool
- isZeroLit :: Literal -> Bool
- isOneLit :: Literal -> Bool
- litFitsInChar :: Literal -> Bool
- litValue :: Literal -> Integer
- mapLitValue :: Platform -> (Integer -> Integer) -> Literal -> Literal
- isLitValue_maybe :: Literal -> Maybe Integer
- isLitRubbish :: Literal -> Bool
- narrowInt8Lit :: Literal -> Literal
- narrowInt16Lit :: Literal -> Literal
- narrowInt32Lit :: Literal -> Literal
- narrowInt64Lit :: Literal -> Literal
- narrowWord8Lit :: Literal -> Literal
- narrowWord16Lit :: Literal -> Literal
- narrowWord32Lit :: Literal -> Literal
- narrowWord64Lit :: Literal -> Literal
- convertToIntLit :: Platform -> Literal -> Literal
- convertToWordLit :: Platform -> Literal -> Literal
- charToIntLit :: Literal -> Literal
- intToCharLit :: Literal -> Literal
- floatToIntLit :: Literal -> Literal
- intToFloatLit :: Literal -> Literal
- doubleToIntLit :: Literal -> Literal
- intToDoubleLit :: Literal -> Literal
- nullAddrLit :: Literal
- floatToDoubleLit :: Literal -> Literal
- doubleToFloatLit :: Literal -> Literal
Main data type
So-called Literal
s are one of:
- An unboxed numeric literal or floating-point literal which is presumed
to be surrounded by appropriate constructors (
Int#
, etc.), so that the overall thing makes sense.
We maintain the invariant that the Integer
in the LitNumber
constructor is actually in the (possibly target-dependent) range.
The mkLit{Int,Word}*Wrap smart constructors ensure this by applying
the target machine's wrapping semantics. Use these in situations
where you know the wrapping semantics are correct.
- The literal derived from the label mentioned in a "foreign label"
declaration (
LitLabel
) - A
LitRubbish
to be used in place of values that are never used. - A character
- A string
- The NULL pointer
Constructors
LitChar Char |
|
LitNumber !LitNumType !Integer | Any numeric literal that can be internally represented with an Integer. |
LitString !ByteString | A string-literal: stored and emitted
UTF-8 encoded, we'll arrange to decode it
at runtime. Also emitted with a |
LitNullAddr | The |
LitRubbish TypeOrConstraint RuntimeRepType | A nonsense value; See Note [Rubbish literals]. |
LitFloat Rational |
|
LitDouble Rational |
|
LitLabel FastString (Maybe Int) FunctionOrData | A label literal. Parameters: 1) The name of the symbol mentioned in the declaration 2) The size (in bytes) of the arguments
the label expects. Only applicable with
3) Flag indicating whether the symbol references a function or a data |
Instances
Data Literal # | |
Defined in GHC.Types.Literal Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Literal -> c Literal gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Literal dataTypeOf :: Literal -> DataType dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Literal) dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Literal) gmapT :: (forall b. Data b => b -> b) -> Literal -> Literal gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Literal -> r gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Literal -> r gmapQ :: (forall d. Data d => d -> u) -> Literal -> [u] gmapQi :: Int -> (forall d. Data d => d -> u) -> Literal -> u gmapM :: Monad m => (forall d. Data d => d -> m d) -> Literal -> m Literal gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Literal -> m Literal gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Literal -> m Literal | |
Binary Literal # | |
Outputable Literal # | |
Defined in GHC.Types.Literal | |
Eq Literal # | |
Ord Literal # | Needed for the |
data LitNumType #
Numeric literal type
Constructors
LitNumBigNat |
|
LitNumInt |
|
LitNumInt8 |
|
LitNumInt16 |
|
LitNumInt32 |
|
LitNumInt64 |
|
LitNumWord |
|
LitNumWord8 |
|
LitNumWord16 |
|
LitNumWord32 |
|
LitNumWord64 |
|
Instances
Data LitNumType # | |
Defined in GHC.Types.Literal Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> LitNumType -> c LitNumType gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c LitNumType toConstr :: LitNumType -> Constr dataTypeOf :: LitNumType -> DataType dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c LitNumType) dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LitNumType) gmapT :: (forall b. Data b => b -> b) -> LitNumType -> LitNumType gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> LitNumType -> r gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> LitNumType -> r gmapQ :: (forall d. Data d => d -> u) -> LitNumType -> [u] gmapQi :: Int -> (forall d. Data d => d -> u) -> LitNumType -> u gmapM :: Monad m => (forall d. Data d => d -> m d) -> LitNumType -> m LitNumType gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> LitNumType -> m LitNumType gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> LitNumType -> m LitNumType | |
Enum LitNumType # | |
Defined in GHC.Types.Literal Methods succ :: LitNumType -> LitNumType # pred :: LitNumType -> LitNumType # toEnum :: Int -> LitNumType # fromEnum :: LitNumType -> Int # enumFrom :: LitNumType -> [LitNumType] # enumFromThen :: LitNumType -> LitNumType -> [LitNumType] # enumFromTo :: LitNumType -> LitNumType -> [LitNumType] # enumFromThenTo :: LitNumType -> LitNumType -> LitNumType -> [LitNumType] # | |
Binary LitNumType # | |
Defined in GHC.Types.Literal Methods put_ :: BinHandle -> LitNumType -> IO () # put :: BinHandle -> LitNumType -> IO (Bin LitNumType) # get :: BinHandle -> IO LitNumType # | |
Eq LitNumType # | |
Defined in GHC.Types.Literal | |
Ord LitNumType # | |
Defined in GHC.Types.Literal Methods compare :: LitNumType -> LitNumType -> Ordering # (<) :: LitNumType -> LitNumType -> Bool # (<=) :: LitNumType -> LitNumType -> Bool # (>) :: LitNumType -> LitNumType -> Bool # (>=) :: LitNumType -> LitNumType -> Bool # max :: LitNumType -> LitNumType -> LitNumType # min :: LitNumType -> LitNumType -> LitNumType # |
Creating Literals
mkLitIntWrap :: Platform -> Integer -> Literal #
Creates a Literal
of type Int#
.
If the argument is out of the (target-dependent) range, it is wrapped.
See Note [WordInt underflowoverflow]
mkLitIntUnchecked :: Integer -> Literal #
Creates a Literal
of type Int#
without checking its range.
mkLitWordWrap :: Platform -> Integer -> Literal #
Creates a Literal
of type Word#
.
If the argument is out of the (target-dependent) range, it is wrapped.
See Note [WordInt underflowoverflow]
mkLitWordUnchecked :: Integer -> Literal #
Creates a Literal
of type Word#
without checking its range.
mkLitInt8Wrap :: Integer -> Literal #
Creates a Literal
of type Int8#
.
If the argument is out of the range, it is wrapped.
mkLitInt8Unchecked :: Integer -> Literal #
Creates a Literal
of type Int8#
without checking its range.
mkLitWord8 :: Integer -> Literal #
Creates a Literal
of type Word8#
mkLitWord8Wrap :: Integer -> Literal #
Creates a Literal
of type Word8#
.
If the argument is out of the range, it is wrapped.
mkLitWord8Unchecked :: Integer -> Literal #
Creates a Literal
of type Word8#
without checking its range.
mkLitInt16 :: Integer -> Literal #
Creates a Literal
of type Int16#
mkLitInt16Wrap :: Integer -> Literal #
Creates a Literal
of type Int16#
.
If the argument is out of the range, it is wrapped.
mkLitInt16Unchecked :: Integer -> Literal #
Creates a Literal
of type Int16#
without checking its range.
mkLitWord16 :: Integer -> Literal #
Creates a Literal
of type Word16#
mkLitWord16Wrap :: Integer -> Literal #
Creates a Literal
of type Word16#
.
If the argument is out of the range, it is wrapped.
mkLitWord16Unchecked :: Integer -> Literal #
Creates a Literal
of type Word16#
without checking its range.
mkLitInt32 :: Integer -> Literal #
Creates a Literal
of type Int32#
mkLitInt32Wrap :: Integer -> Literal #
Creates a Literal
of type Int32#
.
If the argument is out of the range, it is wrapped.
mkLitInt32Unchecked :: Integer -> Literal #
Creates a Literal
of type Int32#
without checking its range.
mkLitWord32 :: Integer -> Literal #
Creates a Literal
of type Word32#
mkLitWord32Wrap :: Integer -> Literal #
Creates a Literal
of type Word32#
.
If the argument is out of the range, it is wrapped.
mkLitWord32Unchecked :: Integer -> Literal #
Creates a Literal
of type Word32#
without checking its range.
mkLitInt64 :: Integer -> Literal #
Creates a Literal
of type Int64#
mkLitInt64Wrap :: Integer -> Literal #
Creates a Literal
of type Int64#
.
If the argument is out of the range, it is wrapped.
mkLitInt64Unchecked :: Integer -> Literal #
Creates a Literal
of type Int64#
without checking its range.
mkLitWord64 :: Integer -> Literal #
Creates a Literal
of type Word64#
mkLitWord64Wrap :: Integer -> Literal #
Creates a Literal
of type Word64#
.
If the argument is out of the range, it is wrapped.
mkLitWord64Unchecked :: Integer -> Literal #
Creates a Literal
of type Word64#
without checking its range.
mkLitFloat :: Rational -> Literal #
Creates a Literal
of type Float#
mkLitDouble :: Rational -> Literal #
Creates a Literal
of type Double#
mkLitString :: String -> Literal #
Creates a Literal
of type Addr#
, which is appropriate for passing to
e.g. some of the "error" functions in GHC.Err such as GHC.Err.runtimeError
mkLitBigNat :: Integer -> Literal #
mkLitNumber :: Platform -> LitNumType -> Integer -> Literal #
Create a numeric Literal
of the given type
mkLitNumberWrap :: Platform -> LitNumType -> Integer -> Literal #
Make a literal number using wrapping semantics if the value is out of bound.
mkLitNumberMaybe :: Platform -> LitNumType -> Integer -> Maybe Literal #
Create a numeric Literal
of the given type if it is in range
Operations on Literals
literalType :: Literal -> Type #
Find the Haskell Type
the literal occupies
litNumIsSigned :: LitNumType -> Bool #
Indicate if a numeric literal type supports negative numbers
litNumRange :: Platform -> LitNumType -> (Maybe Integer, Maybe Integer) #
Get the literal range
litNumCheckRange :: Platform -> LitNumType -> Integer -> Bool #
Check that a given number is in the range of a numeric literal
litNumWrap :: Platform -> Literal -> Literal #
Wrap a literal number according to its type using wrapping semantics.
litNumCoerce :: LitNumType -> Platform -> Literal -> Literal #
Coerce a literal number into another using wrapping semantics.
litNumNarrow :: LitNumType -> Platform -> Literal -> Literal #
Narrow a literal number by converting it into another number type and then converting it back to its original type.
litNumBitSize :: Platform -> LitNumType -> Maybe Word #
Number of bits
isMinBound :: Platform -> Literal -> Bool #
isMaxBound :: Platform -> Literal -> Bool #
Predicates on Literals and their contents
litIsDupable :: Platform -> Literal -> Bool #
True if code space does not go bad if we duplicate this literal
litIsTrivial :: Literal -> Bool #
True if there is absolutely no penalty to duplicating the literal. False principally of strings.
"Why?", you say? I'm glad you asked. Well, for one duplicating strings would blow up code sizes. Not only this, it's also unsafe.
Consider a program that wants to traverse a string. One way it might do this is to first compute the Addr# pointing to the end of the string, and then, starting from the beginning, bump a pointer using eqAddr# to determine the end. For instance,
-- Given pointers to the start and end of a string, count how many zeros -- the string contains. countZeros :: Addr# -> Addr# -> -> Int countZeros start end = go start 0 where go off n | offaddrEq#
end = n | otherwise = go (offplusAddr#
1) n' where n' | isTrue# (indexInt8OffAddr# off 0# ==# 0#) = n + 1 | otherwise = n
Consider what happens if we considered strings to be trivial (and therefore
duplicable) and emitted a call like countZeros "hello"# ("hello"#
. The beginning and end pointers do not belong to the same
string, meaning that an iteration like the above would blow up terribly.
This is what happened in #12757.plusAddr
# 5)
Ultimately the solution here is to make primitive strings a bit more structured, ensuring that the compiler can't inline in ways that will break user code. One approach to this is described in #8472.
litIsLifted :: Literal -> Bool #
inCharRange :: Char -> Bool #
litFitsInChar :: Literal -> Bool #
isLitValue_maybe :: Literal -> Maybe Integer #
isLitRubbish :: Literal -> Bool #
Coercions
narrowInt8Lit :: Literal -> Literal #
narrowInt16Lit :: Literal -> Literal #
narrowInt32Lit :: Literal -> Literal #
narrowInt64Lit :: Literal -> Literal #
narrowWord8Lit :: Literal -> Literal #
narrowWord16Lit :: Literal -> Literal #
narrowWord32Lit :: Literal -> Literal #
narrowWord64Lit :: Literal -> Literal #
convertToIntLit :: Platform -> Literal -> Literal #
Extend or narrow a fixed-width literal (e.g. Int16#
) to a target
word-sized literal (Int#
or Word#
). Narrowing can only happen on 32-bit
architectures when we convert a 64-bit literal into a 32-bit one.
convertToWordLit :: Platform -> Literal -> Literal #
Extend or narrow a fixed-width literal (e.g. Int16#
) to a target
word-sized literal (Int#
or Word#
). Narrowing can only happen on 32-bit
architectures when we convert a 64-bit literal into a 32-bit one.
charToIntLit :: Literal -> Literal #
intToCharLit :: Literal -> Literal #
floatToIntLit :: Literal -> Literal #
intToFloatLit :: Literal -> Literal #
doubleToIntLit :: Literal -> Literal #
intToDoubleLit :: Literal -> Literal #
nullAddrLit :: Literal #
floatToDoubleLit :: Literal -> Literal #
doubleToFloatLit :: Literal -> Literal #