PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/compiler/basicTypes/Literal.hs

http://github.com/ghc/ghc
Haskell | 500 lines | 290 code | 62 blank | 148 comment | 6 complexity | fd40c8e2058def3e68bf9a3d7e932c5d MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, GPL-3.0
  1. {-
  2. (c) The University of Glasgow 2006
  3. (c) The GRASP/AQUA Project, Glasgow University, 1998
  4. \section[Literal]{@Literal@: Machine literals (unboxed, of course)}
  5. -}
  6. {-# LANGUAGE CPP, DeriveDataTypeable #-}
  7. module Literal
  8. (
  9. -- * Main data type
  10. Literal(..) -- Exported to ParseIface
  11. -- ** Creating Literals
  12. , mkMachInt, mkMachWord
  13. , mkMachInt64, mkMachWord64
  14. , mkMachFloat, mkMachDouble
  15. , mkMachChar, mkMachString
  16. , mkLitInteger
  17. -- ** Operations on Literals
  18. , literalType
  19. , absentLiteralOf
  20. , pprLiteral
  21. -- ** Predicates on Literals and their contents
  22. , litIsDupable, litIsTrivial, litIsLifted
  23. , inIntRange, inWordRange, tARGET_MAX_INT, inCharRange
  24. , isZeroLit
  25. , litFitsInChar
  26. , litValue
  27. -- ** Coercions
  28. , word2IntLit, int2WordLit
  29. , narrow8IntLit, narrow16IntLit, narrow32IntLit
  30. , narrow8WordLit, narrow16WordLit, narrow32WordLit
  31. , char2IntLit, int2CharLit
  32. , float2IntLit, int2FloatLit, double2IntLit, int2DoubleLit
  33. , nullAddrLit, float2DoubleLit, double2FloatLit
  34. ) where
  35. #include "HsVersions.h"
  36. import TysPrim
  37. import PrelNames
  38. import Type
  39. import TyCon
  40. import Outputable
  41. import FastString
  42. import BasicTypes
  43. import Binary
  44. import Constants
  45. import DynFlags
  46. import UniqFM
  47. import Util
  48. import Data.ByteString (ByteString)
  49. import Data.Int
  50. import Data.Word
  51. import Data.Char
  52. import Data.Data ( Data )
  53. import Numeric ( fromRat )
  54. {-
  55. ************************************************************************
  56. * *
  57. \subsection{Literals}
  58. * *
  59. ************************************************************************
  60. -}
  61. -- | So-called 'Literal's are one of:
  62. --
  63. -- * An unboxed (/machine/) literal ('MachInt', 'MachFloat', etc.),
  64. -- which is presumed to be surrounded by appropriate constructors
  65. -- (@Int#@, etc.), so that the overall thing makes sense.
  66. --
  67. -- * The literal derived from the label mentioned in a \"foreign label\"
  68. -- declaration ('MachLabel')
  69. data Literal
  70. = ------------------
  71. -- First the primitive guys
  72. MachChar Char -- ^ @Char#@ - at least 31 bits. Create with 'mkMachChar'
  73. | MachStr ByteString -- ^ A string-literal: stored and emitted
  74. -- UTF-8 encoded, we'll arrange to decode it
  75. -- at runtime. Also emitted with a @'\0'@
  76. -- terminator. Create with 'mkMachString'
  77. | MachNullAddr -- ^ The @NULL@ pointer, the only pointer value
  78. -- that can be represented as a Literal. Create
  79. -- with 'nullAddrLit'
  80. | MachInt Integer -- ^ @Int#@ - at least @WORD_SIZE_IN_BITS@ bits. Create with 'mkMachInt'
  81. | MachInt64 Integer -- ^ @Int64#@ - at least 64 bits. Create with 'mkMachInt64'
  82. | MachWord Integer -- ^ @Word#@ - at least @WORD_SIZE_IN_BITS@ bits. Create with 'mkMachWord'
  83. | MachWord64 Integer -- ^ @Word64#@ - at least 64 bits. Create with 'mkMachWord64'
  84. | MachFloat Rational -- ^ @Float#@. Create with 'mkMachFloat'
  85. | MachDouble Rational -- ^ @Double#@. Create with 'mkMachDouble'
  86. | MachLabel FastString
  87. (Maybe Int)
  88. FunctionOrData
  89. -- ^ A label literal. Parameters:
  90. --
  91. -- 1) The name of the symbol mentioned in the declaration
  92. --
  93. -- 2) The size (in bytes) of the arguments
  94. -- the label expects. Only applicable with
  95. -- @stdcall@ labels. @Just x@ => @\<x\>@ will
  96. -- be appended to label name when emitting assembly.
  97. | LitInteger Integer Type -- ^ Integer literals
  98. -- See Note [Integer literals]
  99. deriving Data
  100. {-
  101. Note [Integer literals]
  102. ~~~~~~~~~~~~~~~~~~~~~~~
  103. An Integer literal is represented using, well, an Integer, to make it
  104. easier to write RULEs for them. They also contain the Integer type, so
  105. that e.g. literalType can return the right Type for them.
  106. They only get converted into real Core,
  107. mkInteger [c1, c2, .., cn]
  108. during the CorePrep phase, although TidyPgm looks ahead at what the
  109. core will be, so that it can see whether it involves CAFs.
  110. When we initally build an Integer literal, notably when
  111. deserialising it from an interface file (see the Binary instance
  112. below), we don't have convenient access to the mkInteger Id. So we
  113. just use an error thunk, and fill in the real Id when we do tcIfaceLit
  114. in TcIface.
  115. Binary instance
  116. -}
  117. instance Binary Literal where
  118. put_ bh (MachChar aa) = do putByte bh 0; put_ bh aa
  119. put_ bh (MachStr ab) = do putByte bh 1; put_ bh ab
  120. put_ bh (MachNullAddr) = do putByte bh 2
  121. put_ bh (MachInt ad) = do putByte bh 3; put_ bh ad
  122. put_ bh (MachInt64 ae) = do putByte bh 4; put_ bh ae
  123. put_ bh (MachWord af) = do putByte bh 5; put_ bh af
  124. put_ bh (MachWord64 ag) = do putByte bh 6; put_ bh ag
  125. put_ bh (MachFloat ah) = do putByte bh 7; put_ bh ah
  126. put_ bh (MachDouble ai) = do putByte bh 8; put_ bh ai
  127. put_ bh (MachLabel aj mb fod)
  128. = do putByte bh 9
  129. put_ bh aj
  130. put_ bh mb
  131. put_ bh fod
  132. put_ bh (LitInteger i _) = do putByte bh 10; put_ bh i
  133. get bh = do
  134. h <- getByte bh
  135. case h of
  136. 0 -> do
  137. aa <- get bh
  138. return (MachChar aa)
  139. 1 -> do
  140. ab <- get bh
  141. return (MachStr ab)
  142. 2 -> do
  143. return (MachNullAddr)
  144. 3 -> do
  145. ad <- get bh
  146. return (MachInt ad)
  147. 4 -> do
  148. ae <- get bh
  149. return (MachInt64 ae)
  150. 5 -> do
  151. af <- get bh
  152. return (MachWord af)
  153. 6 -> do
  154. ag <- get bh
  155. return (MachWord64 ag)
  156. 7 -> do
  157. ah <- get bh
  158. return (MachFloat ah)
  159. 8 -> do
  160. ai <- get bh
  161. return (MachDouble ai)
  162. 9 -> do
  163. aj <- get bh
  164. mb <- get bh
  165. fod <- get bh
  166. return (MachLabel aj mb fod)
  167. _ -> do
  168. i <- get bh
  169. -- See Note [Integer literals]
  170. return $ mkLitInteger i (panic "Evaluated the place holder for mkInteger")
  171. instance Outputable Literal where
  172. ppr lit = pprLiteral (\d -> d) lit
  173. instance Eq Literal where
  174. a == b = case (a `compare` b) of { EQ -> True; _ -> False }
  175. a /= b = case (a `compare` b) of { EQ -> False; _ -> True }
  176. instance Ord Literal where
  177. a <= b = case (a `compare` b) of { LT -> True; EQ -> True; GT -> False }
  178. a < b = case (a `compare` b) of { LT -> True; EQ -> False; GT -> False }
  179. a >= b = case (a `compare` b) of { LT -> False; EQ -> True; GT -> True }
  180. a > b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True }
  181. compare a b = cmpLit a b
  182. {-
  183. Construction
  184. ~~~~~~~~~~~~
  185. -}
  186. -- | Creates a 'Literal' of type @Int#@
  187. mkMachInt :: DynFlags -> Integer -> Literal
  188. mkMachInt dflags x = ASSERT2( inIntRange dflags x, integer x )
  189. MachInt x
  190. -- | Creates a 'Literal' of type @Word#@
  191. mkMachWord :: DynFlags -> Integer -> Literal
  192. mkMachWord dflags x = ASSERT2( inWordRange dflags x, integer x )
  193. MachWord x
  194. -- | Creates a 'Literal' of type @Int64#@
  195. mkMachInt64 :: Integer -> Literal
  196. mkMachInt64 x = MachInt64 x
  197. -- | Creates a 'Literal' of type @Word64#@
  198. mkMachWord64 :: Integer -> Literal
  199. mkMachWord64 x = MachWord64 x
  200. -- | Creates a 'Literal' of type @Float#@
  201. mkMachFloat :: Rational -> Literal
  202. mkMachFloat = MachFloat
  203. -- | Creates a 'Literal' of type @Double#@
  204. mkMachDouble :: Rational -> Literal
  205. mkMachDouble = MachDouble
  206. -- | Creates a 'Literal' of type @Char#@
  207. mkMachChar :: Char -> Literal
  208. mkMachChar = MachChar
  209. -- | Creates a 'Literal' of type @Addr#@, which is appropriate for passing to
  210. -- e.g. some of the \"error\" functions in GHC.Err such as @GHC.Err.runtimeError@
  211. mkMachString :: String -> Literal
  212. -- stored UTF-8 encoded
  213. mkMachString s = MachStr (fastStringToByteString $ mkFastString s)
  214. mkLitInteger :: Integer -> Type -> Literal
  215. mkLitInteger = LitInteger
  216. inIntRange, inWordRange :: DynFlags -> Integer -> Bool
  217. inIntRange dflags x = x >= tARGET_MIN_INT dflags && x <= tARGET_MAX_INT dflags
  218. inWordRange dflags x = x >= 0 && x <= tARGET_MAX_WORD dflags
  219. inCharRange :: Char -> Bool
  220. inCharRange c = c >= '\0' && c <= chr tARGET_MAX_CHAR
  221. -- | Tests whether the literal represents a zero of whatever type it is
  222. isZeroLit :: Literal -> Bool
  223. isZeroLit (MachInt 0) = True
  224. isZeroLit (MachInt64 0) = True
  225. isZeroLit (MachWord 0) = True
  226. isZeroLit (MachWord64 0) = True
  227. isZeroLit (MachFloat 0) = True
  228. isZeroLit (MachDouble 0) = True
  229. isZeroLit _ = False
  230. -- | Returns the 'Integer' contained in the 'Literal', for when that makes
  231. -- sense, i.e. for 'Char', 'Int', 'Word' and 'LitInteger'.
  232. litValue :: Literal -> Integer
  233. litValue (MachChar c) = toInteger $ ord c
  234. litValue (MachInt i) = i
  235. litValue (MachInt64 i) = i
  236. litValue (MachWord i) = i
  237. litValue (MachWord64 i) = i
  238. litValue (LitInteger i _) = i
  239. litValue l = pprPanic "litValue" (ppr l)
  240. {-
  241. Coercions
  242. ~~~~~~~~~
  243. -}
  244. narrow8IntLit, narrow16IntLit, narrow32IntLit,
  245. narrow8WordLit, narrow16WordLit, narrow32WordLit,
  246. char2IntLit, int2CharLit,
  247. float2IntLit, int2FloatLit, double2IntLit, int2DoubleLit,
  248. float2DoubleLit, double2FloatLit
  249. :: Literal -> Literal
  250. word2IntLit, int2WordLit :: DynFlags -> Literal -> Literal
  251. word2IntLit dflags (MachWord w)
  252. | w > tARGET_MAX_INT dflags = MachInt (w - tARGET_MAX_WORD dflags - 1)
  253. | otherwise = MachInt w
  254. word2IntLit _ l = pprPanic "word2IntLit" (ppr l)
  255. int2WordLit dflags (MachInt i)
  256. | i < 0 = MachWord (1 + tARGET_MAX_WORD dflags + i) -- (-1) ---> tARGET_MAX_WORD
  257. | otherwise = MachWord i
  258. int2WordLit _ l = pprPanic "int2WordLit" (ppr l)
  259. narrow8IntLit (MachInt i) = MachInt (toInteger (fromInteger i :: Int8))
  260. narrow8IntLit l = pprPanic "narrow8IntLit" (ppr l)
  261. narrow16IntLit (MachInt i) = MachInt (toInteger (fromInteger i :: Int16))
  262. narrow16IntLit l = pprPanic "narrow16IntLit" (ppr l)
  263. narrow32IntLit (MachInt i) = MachInt (toInteger (fromInteger i :: Int32))
  264. narrow32IntLit l = pprPanic "narrow32IntLit" (ppr l)
  265. narrow8WordLit (MachWord w) = MachWord (toInteger (fromInteger w :: Word8))
  266. narrow8WordLit l = pprPanic "narrow8WordLit" (ppr l)
  267. narrow16WordLit (MachWord w) = MachWord (toInteger (fromInteger w :: Word16))
  268. narrow16WordLit l = pprPanic "narrow16WordLit" (ppr l)
  269. narrow32WordLit (MachWord w) = MachWord (toInteger (fromInteger w :: Word32))
  270. narrow32WordLit l = pprPanic "narrow32WordLit" (ppr l)
  271. char2IntLit (MachChar c) = MachInt (toInteger (ord c))
  272. char2IntLit l = pprPanic "char2IntLit" (ppr l)
  273. int2CharLit (MachInt i) = MachChar (chr (fromInteger i))
  274. int2CharLit l = pprPanic "int2CharLit" (ppr l)
  275. float2IntLit (MachFloat f) = MachInt (truncate f)
  276. float2IntLit l = pprPanic "float2IntLit" (ppr l)
  277. int2FloatLit (MachInt i) = MachFloat (fromInteger i)
  278. int2FloatLit l = pprPanic "int2FloatLit" (ppr l)
  279. double2IntLit (MachDouble f) = MachInt (truncate f)
  280. double2IntLit l = pprPanic "double2IntLit" (ppr l)
  281. int2DoubleLit (MachInt i) = MachDouble (fromInteger i)
  282. int2DoubleLit l = pprPanic "int2DoubleLit" (ppr l)
  283. float2DoubleLit (MachFloat f) = MachDouble f
  284. float2DoubleLit l = pprPanic "float2DoubleLit" (ppr l)
  285. double2FloatLit (MachDouble d) = MachFloat d
  286. double2FloatLit l = pprPanic "double2FloatLit" (ppr l)
  287. nullAddrLit :: Literal
  288. nullAddrLit = MachNullAddr
  289. {-
  290. Predicates
  291. ~~~~~~~~~~
  292. -}
  293. -- | True if there is absolutely no penalty to duplicating the literal.
  294. -- False principally of strings
  295. litIsTrivial :: Literal -> Bool
  296. -- c.f. CoreUtils.exprIsTrivial
  297. litIsTrivial (MachStr _) = False
  298. litIsTrivial (LitInteger {}) = False
  299. litIsTrivial _ = True
  300. -- | True if code space does not go bad if we duplicate this literal
  301. -- Currently we treat it just like 'litIsTrivial'
  302. litIsDupable :: DynFlags -> Literal -> Bool
  303. -- c.f. CoreUtils.exprIsDupable
  304. litIsDupable _ (MachStr _) = False
  305. litIsDupable dflags (LitInteger i _) = inIntRange dflags i
  306. litIsDupable _ _ = True
  307. litFitsInChar :: Literal -> Bool
  308. litFitsInChar (MachInt i) = i >= toInteger (ord minBound)
  309. && i <= toInteger (ord maxBound)
  310. litFitsInChar _ = False
  311. litIsLifted :: Literal -> Bool
  312. litIsLifted (LitInteger {}) = True
  313. litIsLifted _ = False
  314. {-
  315. Types
  316. ~~~~~
  317. -}
  318. -- | Find the Haskell 'Type' the literal occupies
  319. literalType :: Literal -> Type
  320. literalType MachNullAddr = addrPrimTy
  321. literalType (MachChar _) = charPrimTy
  322. literalType (MachStr _) = addrPrimTy
  323. literalType (MachInt _) = intPrimTy
  324. literalType (MachWord _) = wordPrimTy
  325. literalType (MachInt64 _) = int64PrimTy
  326. literalType (MachWord64 _) = word64PrimTy
  327. literalType (MachFloat _) = floatPrimTy
  328. literalType (MachDouble _) = doublePrimTy
  329. literalType (MachLabel _ _ _) = addrPrimTy
  330. literalType (LitInteger _ t) = t
  331. absentLiteralOf :: TyCon -> Maybe Literal
  332. -- Return a literal of the appropriate primtive
  333. -- TyCon, to use as a placeholder when it doesn't matter
  334. absentLiteralOf tc = lookupUFM absent_lits (tyConName tc)
  335. absent_lits :: UniqFM Literal
  336. absent_lits = listToUFM [ (addrPrimTyConKey, MachNullAddr)
  337. , (charPrimTyConKey, MachChar 'x')
  338. , (intPrimTyConKey, MachInt 0)
  339. , (int64PrimTyConKey, MachInt64 0)
  340. , (floatPrimTyConKey, MachFloat 0)
  341. , (doublePrimTyConKey, MachDouble 0)
  342. , (wordPrimTyConKey, MachWord 0)
  343. , (word64PrimTyConKey, MachWord64 0) ]
  344. {-
  345. Comparison
  346. ~~~~~~~~~~
  347. -}
  348. cmpLit :: Literal -> Literal -> Ordering
  349. cmpLit (MachChar a) (MachChar b) = a `compare` b
  350. cmpLit (MachStr a) (MachStr b) = a `compare` b
  351. cmpLit (MachNullAddr) (MachNullAddr) = EQ
  352. cmpLit (MachInt a) (MachInt b) = a `compare` b
  353. cmpLit (MachWord a) (MachWord b) = a `compare` b
  354. cmpLit (MachInt64 a) (MachInt64 b) = a `compare` b
  355. cmpLit (MachWord64 a) (MachWord64 b) = a `compare` b
  356. cmpLit (MachFloat a) (MachFloat b) = a `compare` b
  357. cmpLit (MachDouble a) (MachDouble b) = a `compare` b
  358. cmpLit (MachLabel a _ _) (MachLabel b _ _) = a `compare` b
  359. cmpLit (LitInteger a _) (LitInteger b _) = a `compare` b
  360. cmpLit lit1 lit2 | litTag lit1 < litTag lit2 = LT
  361. | otherwise = GT
  362. litTag :: Literal -> Int
  363. litTag (MachChar _) = 1
  364. litTag (MachStr _) = 2
  365. litTag (MachNullAddr) = 3
  366. litTag (MachInt _) = 4
  367. litTag (MachWord _) = 5
  368. litTag (MachInt64 _) = 6
  369. litTag (MachWord64 _) = 7
  370. litTag (MachFloat _) = 8
  371. litTag (MachDouble _) = 9
  372. litTag (MachLabel _ _ _) = 10
  373. litTag (LitInteger {}) = 11
  374. {-
  375. Printing
  376. ~~~~~~~~
  377. * See Note [Printing of literals in Core]
  378. -}
  379. pprLiteral :: (SDoc -> SDoc) -> Literal -> SDoc
  380. pprLiteral _ (MachChar c) = pprPrimChar c
  381. pprLiteral _ (MachStr s) = pprHsBytes s
  382. pprLiteral _ (MachNullAddr) = text "__NULL"
  383. pprLiteral _ (MachInt i) = pprPrimInt i
  384. pprLiteral _ (MachInt64 i) = pprPrimInt64 i
  385. pprLiteral _ (MachWord w) = pprPrimWord w
  386. pprLiteral _ (MachWord64 w) = pprPrimWord64 w
  387. pprLiteral _ (MachFloat f) = float (fromRat f) <> primFloatSuffix
  388. pprLiteral _ (MachDouble d) = double (fromRat d) <> primDoubleSuffix
  389. pprLiteral add_par (LitInteger i _) = pprIntegerVal add_par i
  390. pprLiteral add_par (MachLabel l mb fod) = add_par (text "__label" <+> b <+> ppr fod)
  391. where b = case mb of
  392. Nothing -> pprHsString l
  393. Just x -> doubleQuotes (text (unpackFS l ++ '@':show x))
  394. pprIntegerVal :: (SDoc -> SDoc) -> Integer -> SDoc
  395. -- See Note [Printing of literals in Core].
  396. pprIntegerVal add_par i | i < 0 = add_par (integer i)
  397. | otherwise = integer i
  398. {-
  399. Note [Printing of literals in Core]
  400. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  401. The function `add_par` is used to wrap parenthesis around negative integers
  402. (`LitInteger`) and labels (`MachLabel`), if they occur in a context requiring
  403. an atomic thing (for example function application).
  404. Although not all Core literals would be valid Haskell, we are trying to stay
  405. as close as possible to Haskell syntax in the printing of Core, to make it
  406. easier for a Haskell user to read Core.
  407. To that end:
  408. * We do print parenthesis around negative `LitInteger`, because we print
  409. `LitInteger` using plain number literals (no prefix or suffix), and plain
  410. number literals in Haskell require parenthesis in contexts like function
  411. application (i.e. `1 - -1` is not valid Haskell).
  412. * We don't print parenthesis around other (negative) literals, because they
  413. aren't needed in GHC/Haskell either (i.e. `1# -# -1#` is accepted by GHC's
  414. parser).
  415. Literal Output Output if context requires
  416. an atom (if different)
  417. ------- ------- ----------------------
  418. MachChar 'a'#
  419. MachStr "aaa"#
  420. MachNullAddr "__NULL"
  421. MachInt -1#
  422. MachInt64 -1L#
  423. MachWord 1##
  424. MachWord64 1L##
  425. MachFloat -1.0#
  426. MachDouble -1.0##
  427. LitInteger -1 (-1)
  428. MachLabel "__label" ... ("__label" ...)
  429. -}