2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[Literal]{@Literal@: Machine literals (unboxed, of course)}
7 #include "HsVersions.h"
12 mkMachInt, mkMachWord,
13 literalType, literalPrimRep,
15 isNoRepLit, isLitLitLit
22 import PrimRep ( PrimRep(..), ppPrimRep ) -- non-abstract
23 import TysPrim ( getPrimRepInfo,
24 addrPrimTy, intPrimTy, floatPrimTy,
25 doublePrimTy, charPrimTy, wordPrimTy )
28 import CStrings ( stringToC, charToC, charToEasyHaskell )
29 import TysWiredIn ( stringTy )
30 import Pretty -- pretty-printing stuff
31 import Outputable ( PprStyle(..), codeStyle, ifaceStyle, Outputable(..) )
32 import Util ( thenCmp, panic, pprPanic, Ord3(..) )
33 #if __GLASGOW_HASKELL__ >= 202
38 So-called @Literals@ are {\em either}:
41 An unboxed (``machine'') literal (type: @IntPrim@, @FloatPrim@, etc.),
42 which is presumed to be surrounded by appropriate constructors
43 (@mKINT@, etc.), so that the overall thing makes sense.
45 An Integer, Rational, or String literal whose representation we are
46 {\em uncommitted} about; i.e., the surrounding with constructors,
47 function applications, etc., etc., has not yet been done.
55 | MachAddr Integer -- whatever this machine thinks is a "pointer"
57 | MachInt Integer -- for the numeric types, these are
58 Bool -- True <=> signed (Int#); False <=> unsigned (Word#)
63 | MachLitLit FAST_STRING
66 | NoRepStr FAST_STRING
67 | NoRepInteger Integer Type -- This Type is always Integer
68 | NoRepRational Rational Type -- This Type is always Rational
69 -- We keep these Types in the literal because Rational isn't
70 -- (currently) wired in, so we can't conjure up its type out of
71 -- thin air. Integer is, so the type here is really redundant.
73 -- deriving (Eq, Ord): no, don't want to compare Types
74 -- The Ord is needed for the FiniteMap used in the lookForConstructor
75 -- in SimplEnv. If you declared that lookForConstructor *ignores*
76 -- constructor-applications with LitArg args, then you could get
79 mkMachInt, mkMachWord :: Integer -> Literal
81 mkMachInt x = MachInt x True{-signed-}
82 mkMachWord x = MachInt x False{-unsigned-}
84 instance Ord3 Literal where
85 cmp (MachChar a) (MachChar b) = a `tcmp` b
86 cmp (MachStr a) (MachStr b) = a `tcmp` b
87 cmp (MachAddr a) (MachAddr b) = a `tcmp` b
88 cmp (MachInt a b) (MachInt c d) = (a `tcmp` c) `thenCmp` (b `tcmp` d)
89 cmp (MachFloat a) (MachFloat b) = a `tcmp` b
90 cmp (MachDouble a) (MachDouble b) = a `tcmp` b
91 cmp (MachLitLit a b) (MachLitLit c d) = (a `tcmp` c) `thenCmp` (b `tcmp` d)
92 cmp (NoRepStr a) (NoRepStr b) = a `tcmp` b
93 cmp (NoRepInteger a _) (NoRepInteger b _) = a `tcmp` b
94 cmp (NoRepRational a _) (NoRepRational b _) = a `tcmp` b
96 -- now we *know* the tags are different, so...
98 | tag1 _LT_ tag2 = LT_
104 tagof (MachChar _) = ILIT(1)
105 tagof (MachStr _) = ILIT(2)
106 tagof (MachAddr _) = ILIT(3)
107 tagof (MachInt _ _) = ILIT(4)
108 tagof (MachFloat _) = ILIT(5)
109 tagof (MachDouble _) = ILIT(6)
110 tagof (MachLitLit _ _) = ILIT(7)
111 tagof (NoRepStr _) = ILIT(8)
112 tagof (NoRepInteger _ _) = ILIT(9)
113 tagof (NoRepRational _ _) = ILIT(10)
115 tcmp x y = case _tagCmp x y of { _LT -> LT_; _EQ -> EQ_; GT__ -> GT_ }
117 instance Eq Literal where
118 a == b = case (a `cmp` b) of { EQ_ -> True; _ -> False }
119 a /= b = case (a `cmp` b) of { EQ_ -> False; _ -> True }
121 instance Ord Literal where
122 a <= b = case (a `cmp` b) of { LT_ -> True; EQ_ -> True; GT__ -> False }
123 a < b = case (a `cmp` b) of { LT_ -> True; EQ_ -> False; GT__ -> False }
124 a >= b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True; GT__ -> True }
125 a > b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True }
126 _tagCmp a b = case (a `cmp` b) of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
130 isNoRepLit (NoRepStr _) = True -- these are not primitive typed!
131 isNoRepLit (NoRepInteger _ _) = True
132 isNoRepLit (NoRepRational _ _) = True
135 isLitLitLit (MachLitLit _ _) = True
136 isLitLitLit _ = False
140 literalType :: Literal -> Type
142 literalType (MachChar _) = charPrimTy
143 literalType (MachStr _) = addrPrimTy
144 literalType (MachAddr _) = addrPrimTy
145 literalType (MachInt _ signed) = if signed then intPrimTy else wordPrimTy
146 literalType (MachFloat _) = floatPrimTy
147 literalType (MachDouble _) = doublePrimTy
148 literalType (MachLitLit _ k) = case (getPrimRepInfo k) of { (_,t,_) -> t }
149 literalType (NoRepInteger _ t) = t
150 literalType (NoRepRational _ t) = t
151 literalType (NoRepStr _) = stringTy
155 literalPrimRep :: Literal -> PrimRep
157 literalPrimRep (MachChar _) = CharRep
158 literalPrimRep (MachStr _) = AddrRep -- specifically: "char *"
159 literalPrimRep (MachAddr _) = AddrRep
160 literalPrimRep (MachInt _ signed) = if signed then IntRep else WordRep
161 literalPrimRep (MachFloat _) = FloatRep
162 literalPrimRep (MachDouble _) = DoubleRep
163 literalPrimRep (MachLitLit _ k) = k
165 literalPrimRep (NoRepInteger _ _) = panic "literalPrimRep:NoRepInteger"
166 literalPrimRep (NoRepRational _ _) = panic "literalPrimRep:NoRepRational"
167 literalPrimRep (NoRepStr _) = panic "literalPrimRep:NoRepString"
171 The boring old output stuff:
173 ppCast :: PprStyle -> FAST_STRING -> Doc
174 ppCast PprForC cast = ptext cast
177 -- MachX (i.e. unboxed) things are printed unadornded (e.g. 3, 'a', "foo")
178 -- exceptions: MachFloat and MachAddr get an initial keyword prefix
180 -- NoRep things get an initial keyword prefix (e.g. _integer_ 3)
182 instance Outputable Literal where
183 ppr sty (MachChar ch)
187 PprForC -> charToC ch
188 PprForAsm _ _ -> charToC ch
189 PprInterface -> charToEasyHaskell ch
192 hcat [ppCast sty SLIT("(C_)"), char '\'', text char_encoding, char '\'']
195 | codeStyle sty = hcat [char '"', text (stringToC (_UNPK_ s)), char '"']
196 | otherwise = text (show (_UNPK_ s))
198 ppr sty lit@(NoRepStr s)
199 | codeStyle sty = pprPanic "NoRep in code style" (ppr PprDebug lit)
200 | otherwise = hcat [ptext SLIT("_string_ "), text (show (_UNPK_ s))]
202 ppr sty (MachInt i signed)
203 | codeStyle sty && out_of_range
204 = panic ("ERROR: Int " ++ show i ++ " out of range [" ++
205 show range_min ++ " .. " ++ show range_max ++ "]\n")
207 | otherwise = integer i
210 range_min = if signed then minInt else 0
212 out_of_range = not (i >= toInteger range_min && i <= toInteger range_max)
214 ppr sty (MachFloat f)
215 | codeStyle sty = hcat [ppCast sty SLIT("(StgFloat)"), rational f]
216 | otherwise = hcat [ptext SLIT("_float_ "), rational f]
218 ppr sty (MachDouble d) = rational d
221 | codeStyle sty = hcat [ppCast sty SLIT("(void*)"), integer p]
222 | otherwise = hcat [ptext SLIT("_addr_ "), integer p]
224 ppr sty lit@(NoRepInteger i _)
225 | codeStyle sty = pprPanic "NoRep in code style" (ppr PprDebug lit)
226 | otherwise = hsep [ptext SLIT("_integer_ "), integer i]
228 ppr sty lit@(NoRepRational r _)
229 | codeStyle sty = pprPanic "NoRep in code style" (ppr PprDebug lit)
230 | otherwise = hsep [ptext SLIT("_rational_ "), integer (numerator r), integer (denominator r)]
232 ppr sty (MachLitLit s k)
233 | codeStyle sty = ptext s
234 | otherwise = hcat [ptext SLIT("_litlit_ "), ppPrimRep k, char ' ', text (show (_UNPK_ s))]
236 showLiteral :: PprStyle -> Literal -> String
237 showLiteral sty lit = show (ppr sty lit)