2 % (c) The GRASP/AQUA Project, Glasgow University, 1998
4 \section[Literal]{@Literal@: Machine literals (unboxed, of course)}
10 conOkForApp, conOkForAlt, isWHNFCon, isDataCon,
11 conIsTrivial, conIsCheap,
13 DataCon, PrimOp, -- For completeness
16 Literal(..), -- Exported to ParseIface
17 mkMachInt, mkMachWord,
18 mkMachInt_safe, mkMachInt64, mkMachWord64,
19 mkStrLit, -- ToDo: rm (not used anywhere)
20 isNoRepLit, isLitLitLit,
21 literalType, literalPrimRep
24 #include "HsVersions.h"
26 import TysPrim ( charPrimTy, addrPrimTy, floatPrimTy, doublePrimTy,
27 intPrimTy, wordPrimTy, int64PrimTy, word64PrimTy
29 import PrimOp ( PrimOp, primOpType, primOpIsCheap )
30 import PrimRep ( PrimRep(..) )
31 import DataCon ( DataCon, dataConType, dataConTyCon, isNullaryDataCon )
32 import TyCon ( isNewTyCon )
33 import Type ( Type, typePrimRep )
34 import PprType ( pprParendType )
35 import CStrings ( stringToC, charToC, charToEasyHaskell )
38 import Util ( thenCmp )
40 import Ratio ( numerator, denominator )
44 %************************************************************************
46 \subsection{The main data type}
48 %************************************************************************
55 | DEFAULT -- Used in case clauses
58 -- The Ord is needed for the FiniteMap used in the lookForConstructor
59 -- in SimplEnv. If you declared that lookForConstructor *ignores*
60 -- constructor-applications with LitArg args, then you could get
63 instance Outputable Con where
64 ppr (DataCon dc) = ppr dc
65 ppr (Literal lit) = ppr lit
66 ppr (PrimOp op) = ppr op
67 ppr DEFAULT = ptext SLIT("__DEFAULT")
69 instance Show Con where
70 showsPrec p con = showsPrecSDoc p (ppr con)
72 conType :: Con -> Type
73 conType (DataCon dc) = dataConType dc
74 conType (Literal lit) = literalType lit
75 conType (PrimOp op) = primOpType op
77 conPrimRep :: Con -> PrimRep -- Only data valued constants
78 conPrimRep (DataCon dc) = ASSERT( isNullaryDataCon dc) PtrRep
79 conPrimRep (Literal lit) = literalPrimRep lit
81 conOkForApp, conOkForAlt :: Con -> Bool
83 -- OK for appliation site
84 conOkForApp (DataCon dc) = not (isNewTyCon (dataConTyCon dc))
85 conOkForApp (Literal _) = True
86 conOkForApp (PrimOp op) = True
87 conOkForApp DEFAULT = False
89 -- OK for case alternative pattern
90 conOkForAlt (DataCon dc) = not (isNewTyCon (dataConTyCon dc))
91 conOkForAlt (Literal lit) = not (isNoRepLit lit)
92 conOkForAlt (PrimOp _) = False
93 conOkForAlt DEFAULT = True
95 -- isWHNFCon is false for PrimOps, which contain work
96 -- Ditto for newtype constructors, which can occur in the output
97 -- of the desugarer, but which will be inlined right away thereafter
98 isWHNFCon (DataCon dc) = not (isNewTyCon (dataConTyCon dc))
99 isWHNFCon (Literal _) = True
100 isWHNFCon (PrimOp _) = False
102 isDataCon (DataCon dc) = True
103 isDataCon other = False
105 -- conIsTrivial is true for constants we are unconditionally happy to duplicate
106 -- cf CoreUtils.exprIsTrivial
107 conIsTrivial (Literal lit) = not (isNoRepLit lit)
108 conIsTrivial (PrimOp _) = False
109 conIsTrivial con = True
111 -- conIsCheap is true for constants whose applications we are willing
112 -- to duplicate in exchange for some modest gain. cf CoreUtils.exprIsCheap
113 conIsCheap (Literal lit) = not (isNoRepLit lit)
114 conIsCheap (DataCon con) = True
115 conIsCheap (PrimOp op) = primOpIsCheap op
119 %************************************************************************
121 \subsection{Literals}
123 %************************************************************************
125 So-called @Literals@ are {\em either}:
128 An unboxed (``machine'') literal (type: @IntPrim@, @FloatPrim@, etc.),
129 which is presumed to be surrounded by appropriate constructors
130 (@mKINT@, etc.), so that the overall thing makes sense.
132 An Integer, Rational, or String literal whose representation we are
133 {\em uncommitted} about; i.e., the surrounding with constructors,
134 function applications, etc., etc., has not yet been done.
140 -- First the primitive guys
142 | MachStr FAST_STRING
144 | MachAddr Integer -- Whatever this machine thinks is a "pointer"
146 | MachInt Integer -- For the numeric types, these are
147 Bool -- True <=> signed (Int#); False <=> unsigned (Word#)
149 | MachInt64 Integer -- guaranteed 64-bit versions of the above.
150 Bool -- True <=> signed (Int#); False <=> unsigned (Word#)
154 | MachDouble Rational
156 | MachLitLit FAST_STRING Type -- Type might be Add# or Int# etc
160 | NoRepStr FAST_STRING Type -- This Type is always String
161 | NoRepInteger Integer Type -- This Type is always Integer
162 | NoRepRational Rational Type -- This Type is always Rational
163 -- We keep these Types in the literal because Rational isn't
164 -- (currently) wired in, so we can't conjure up its type out of
165 -- thin air. Integer is, so the type here is really redundant.
170 instance Outputable Literal where
173 instance Show Literal where
174 showsPrec p lit = showsPrecSDoc p (ppr lit)
176 instance Eq Literal where
177 a == b = case (a `compare` b) of { EQ -> True; _ -> False }
178 a /= b = case (a `compare` b) of { EQ -> False; _ -> True }
180 instance Ord Literal where
181 a <= b = case (a `compare` b) of { LT -> True; EQ -> True; GT -> False }
182 a < b = case (a `compare` b) of { LT -> True; EQ -> False; GT -> False }
183 a >= b = case (a `compare` b) of { LT -> False; EQ -> True; GT -> True }
184 a > b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True }
185 compare a b = cmpLit a b
192 mkMachInt, mkMachWord :: Integer -> Literal
194 mkMachInt x = MachInt x True{-signed-}
195 mkMachWord x = MachInt x False{-unsigned-}
197 -- check if the int is within range
198 mkMachInt_safe :: Integer -> Literal
201 pprPanic "mkMachInt_safe"
202 (hsep [text "ERROR: Int ", text (show i), text "out of range",
203 brackets (int minInt <+> text ".." <+> int maxInt)])
204 | otherwise = MachInt i True{-signed-}
207 -- i < fromInt minBound ||
210 mkMachInt64 x = MachInt64 x True{-signed-}
211 mkMachWord64 x = MachInt64 x False{-unsigned-}
213 mkStrLit :: String -> Type -> Literal
214 mkStrLit s ty = NoRepStr (_PK_ s) ty
221 isNoRepLit (NoRepStr _ _) = True -- these are not primitive typed!
222 isNoRepLit (NoRepInteger _ _) = True
223 isNoRepLit (NoRepRational _ _) = True
226 isLitLitLit (MachLitLit _ _) = True
227 isLitLitLit _ = False
233 literalType :: Literal -> Type
234 literalType (MachChar _) = charPrimTy
235 literalType (MachStr _) = addrPrimTy
236 literalType (MachAddr _) = addrPrimTy
237 literalType (MachInt _ signed) = if signed then intPrimTy else wordPrimTy
238 literalType (MachInt64 _ signed) = if signed then int64PrimTy else word64PrimTy
239 literalType (MachFloat _) = floatPrimTy
240 literalType (MachDouble _) = doublePrimTy
241 literalType (MachLitLit _ ty) = ty
242 literalType (NoRepInteger _ ty) = ty
243 literalType (NoRepRational _ ty) = ty
244 literalType (NoRepStr _ ty) = ty
248 literalPrimRep :: Literal -> PrimRep
250 literalPrimRep (MachChar _) = CharRep
251 literalPrimRep (MachStr _) = AddrRep -- specifically: "char *"
252 literalPrimRep (MachAddr _) = AddrRep
253 literalPrimRep (MachInt _ signed) = if signed then IntRep else WordRep
254 literalPrimRep (MachInt64 _ signed) = if signed then Int64Rep else Word64Rep
255 literalPrimRep (MachFloat _) = FloatRep
256 literalPrimRep (MachDouble _) = DoubleRep
257 literalPrimRep (MachLitLit _ ty) = typePrimRep ty
259 literalPrimRep (NoRepInteger _ _) = panic "literalPrimRep:NoRepInteger"
260 literalPrimRep (NoRepRational _ _) = panic "literalPrimRep:NoRepRational"
261 literalPrimRep (NoRepStr _ _) = panic "literalPrimRep:NoRepString"
269 cmpLit (MachChar a) (MachChar b) = a `compare` b
270 cmpLit (MachStr a) (MachStr b) = a `compare` b
271 cmpLit (MachAddr a) (MachAddr b) = a `compare` b
272 cmpLit (MachInt a b) (MachInt c d) = (a `compare` c) `thenCmp` (b `compare` d)
273 cmpLit (MachFloat a) (MachFloat b) = a `compare` b
274 cmpLit (MachDouble a) (MachDouble b) = a `compare` b
275 cmpLit (MachLitLit a b) (MachLitLit c d) = (a `compare` c) `thenCmp` (b `compare` d)
276 cmpLit (NoRepStr a _) (NoRepStr b _) = a `compare` b
277 cmpLit (NoRepInteger a _) (NoRepInteger b _) = a `compare` b
278 cmpLit (NoRepRational a _) (NoRepRational b _) = a `compare` b
279 cmpLit lit1 lit2 | litTag lit1 _LT_ litTag lit2 = LT
282 litTag (MachChar _) = ILIT(1)
283 litTag (MachStr _) = ILIT(2)
284 litTag (MachAddr _) = ILIT(3)
285 litTag (MachInt _ _) = ILIT(4)
286 litTag (MachFloat _) = ILIT(5)
287 litTag (MachDouble _) = ILIT(6)
288 litTag (MachLitLit _ _) = ILIT(7)
289 litTag (NoRepStr _ _) = ILIT(8)
290 litTag (NoRepInteger _ _) = ILIT(9)
291 litTag (NoRepRational _ _) = ILIT(10)
296 * MachX (i.e. unboxed) things are printed unadornded (e.g. 3, 'a', "foo")
297 exceptions: MachFloat and MachAddr get an initial keyword prefix
299 * NoRep things get an initial keyword prefix (e.g. _integer_ 3)
303 = getPprStyle $ \ sty ->
305 code_style = codeStyle sty
308 MachChar ch | code_style -> hcat [ptext SLIT("(C_)"), char '\'',
309 text (charToC ch), char '\'']
310 | ifaceStyle sty -> char '\'' <> text (charToEasyHaskell ch) <> char '\''
311 | otherwise -> text ['\'', ch, '\'']
313 MachStr s | code_style -> doubleQuotes (text (stringToC (_UNPK_ s)))
314 | otherwise -> pprFSAsString s
317 NoRepStr s ty | code_style -> pprPanic "NoRep in code style" (ppr lit)
318 | otherwise -> ptext SLIT("__string") <+> pprFSAsString s
320 MachInt i signed | code_style && out_of_range
321 -> pprPanic "" (hsep [text "ERROR: Int ", text (show i),
323 brackets (ppr range_min <+> text ".."
325 | otherwise -> integer i
328 range_min = if signed then minInt else 0
330 out_of_range = not (i >= toInteger range_min && i <= toInteger range_max)
332 MachFloat f | code_style -> ptext SLIT("(StgFloat)") <> rational f
333 | otherwise -> ptext SLIT("__float") <+> rational f
335 MachDouble d -> rational d
337 MachAddr p | code_style -> ptext SLIT("(void*)") <> integer p
338 | otherwise -> ptext SLIT("__addr") <+> integer p
340 NoRepInteger i _ | code_style -> pprPanic "NoRep in code style" (ppr lit)
341 | otherwise -> ptext SLIT("__integer") <+> integer i
343 NoRepRational r _ | code_style -> pprPanic "NoRep in code style" (ppr lit)
344 | otherwise -> hsep [ptext SLIT("__rational"), integer (numerator r),
345 integer (denominator r)]
347 MachLitLit s ty | code_style -> ptext s
348 | otherwise -> parens (hsep [ptext SLIT("__litlit"),