2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
4 \section[BasicLit]{@BasicLit@: Machine literals (unboxed, of course)}
7 #include "HsVersions.h"
11 mkMachInt, mkMachWord,
12 typeOfBasicLit, kindOfBasicLit,
14 isNoRepLit, isLitLitLit,
16 -- and to make the interface self-sufficient....
20 import AbsPrel ( addrPrimTy, intPrimTy, floatPrimTy, doublePrimTy,
21 charPrimTy, wordPrimTy,
22 integerTy, rationalTy, stringTy, UniType,
24 IF_ATTACK_PRAGMAS(COMMA mkListTy COMMA charTy)
25 IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
26 IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
28 import AbsUniType ( TyCon IF_ATTACK_PRAGMAS(COMMA cmpTyCon) )
29 import PrimKind ( getKindInfo ) -- ToDo: *** HACK import ****
30 import CLabelInfo ( stringToC, charToC, charToEasyHaskell )
31 import Outputable -- class for printing, forcing
32 import Pretty -- pretty-printing stuff
33 import PrimKind ( PrimKind(..) )
37 So-called @BasicLits@ are {\em either}:
40 An unboxed (``machine'') literal (type: @IntPrim@, @FloatPrim@, etc.),
41 which is presumed to be surrounded by appropriate constructors
42 (@mKINT@, etc.), so that the overall thing makes sense.
44 An Integer, Rational, or String literal whose representation we are
45 {\em uncommitted} about; i.e., the surrounding with constructors,
46 function applications, etc., etc., has not yet been done.
53 | MachAddr Integer -- whatever this machine thinks is a "pointer"
54 | MachInt Integer -- for the numeric types, these are
55 Bool -- True <=> signed (Int#); False <=> unsigned (Word#)
58 | MachLitLit FAST_STRING
61 | NoRepStr FAST_STRING -- the uncommitted ones
62 | NoRepInteger Integer
63 | NoRepRational Rational
66 -- The Ord is needed for the FiniteMap used in the lookForConstructor
67 -- in SimplEnv. If you declared that lookForConstructor *ignores*
68 -- constructor-applications with CoLitAtom args, then you could get
71 mkMachInt, mkMachWord :: Integer -> BasicLit
73 mkMachInt x = MachInt x True{-signed-}
74 mkMachWord x = MachInt x False{-unsigned-}
78 isNoRepLit (NoRepStr _) = True -- these are not primitive typed!
79 isNoRepLit (NoRepInteger _) = True
80 isNoRepLit (NoRepRational _) = True
83 isLitLitLit (MachLitLit _ _) = True
88 typeOfBasicLit :: BasicLit -> UniType
90 typeOfBasicLit (MachChar _) = charPrimTy
91 typeOfBasicLit (MachStr _) = addrPrimTy
92 typeOfBasicLit (MachAddr _) = addrPrimTy
93 typeOfBasicLit (MachInt _ signed) = if signed then intPrimTy else wordPrimTy
94 typeOfBasicLit (MachFloat _) = floatPrimTy
95 typeOfBasicLit (MachDouble _) = doublePrimTy
96 typeOfBasicLit (MachLitLit _ k) = case (getKindInfo k) of { (_,t,_) -> t }
97 typeOfBasicLit (NoRepInteger _) = integerTy
98 typeOfBasicLit (NoRepRational _)= rationalTy
99 typeOfBasicLit (NoRepStr _) = stringTy
103 kindOfBasicLit :: BasicLit -> PrimKind
105 kindOfBasicLit (MachChar _) = CharKind
106 kindOfBasicLit (MachStr _) = AddrKind -- specifically: "char *"
107 kindOfBasicLit (MachAddr _) = AddrKind
108 kindOfBasicLit (MachInt _ signed) = if signed then IntKind else WordKind
109 kindOfBasicLit (MachFloat _) = FloatKind
110 kindOfBasicLit (MachDouble _) = DoubleKind
111 kindOfBasicLit (MachLitLit _ k) = k
112 kindOfBasicLit (NoRepInteger _) = panic "kindOfBasicLit:NoRepInteger"
113 kindOfBasicLit (NoRepRational _)= panic "kindOfBasicLit:NoRepRational"
114 kindOfBasicLit (NoRepStr _) = panic "kindOfBasicLit:NoRepString"
117 The boring old output stuff:
119 ppCast :: PprStyle -> FAST_STRING -> Pretty
120 ppCast (PprForC _) cast = ppPStr cast
123 instance Outputable BasicLit where
124 ppr sty (MachChar ch)
128 PprForC _ -> charToC ch
129 PprForAsm _ _ _ -> charToC ch
130 PprUnfolding _ -> charToEasyHaskell ch
133 ppBeside (ppBesides [ppCast sty SLIT("(C_)"), ppChar '\'', ppStr char_encoding, ppChar '\''])
137 = ppBeside (if codeStyle sty
138 then ppBesides [ppChar '"', ppStr (stringToC (_UNPK_ s)), ppChar '"']
139 else ppStr (show (_UNPK_ s)))
142 ppr sty (MachAddr p) = ppBesides [ppCast sty SLIT("(void*)"), ppInteger p, if_ubxd sty]
143 ppr sty (MachInt i signed)
145 && ((signed && (i >= toInteger minInt && i <= toInteger maxInt))
146 || (not signed && (i >= toInteger 0 && i <= toInteger maxInt)))
147 -- ToDo: Think about these ranges!
148 = ppBesides [ppInteger i, if_ubxd sty]
150 | not (codeStyle sty) -- we'd prefer the code to the error message
151 = ppBesides [ppInteger i, if_ubxd sty]
154 = error ("ERROR: Int " ++ show i ++ " out of range [" ++
155 show range_min ++ " .. " ++ show maxInt ++ "]\n")
157 range_min = if signed then minInt else 0
159 ppr sty (MachFloat f) = ppBesides [ppCast sty SLIT("(StgFloat)"), ppRational f, if_ubxd sty]
160 ppr sty (MachDouble d) = ppBesides [ppRational d, if_ubxd sty, if_ubxd sty]
163 -- I know that this thing shouldnt pop out of the compiler, but the
164 -- native code generator tries to generate code to initilialise a closure
165 -- with this value... (in glaExts/PreludeGlaInOut.lhs)
166 ppr sty MachVoid = ppStr "0 ! {- void# -}"
167 #endif {- Data Parallel Haskell -}
169 ppr sty (NoRepInteger i)
170 | codeStyle sty = ppInteger i
171 | ufStyle sty = ppCat [ppStr "_NOREP_I_", ppInteger i]
172 | otherwise = ppBesides [ppInteger i, ppChar 'I']
174 ppr sty (NoRepRational r)
175 | ufStyle sty = ppCat [ppStr "_NOREP_R_", ppInteger (numerator r), ppInteger (denominator r)]
176 | codeStyle sty = panic "ppr.ForC.NoRepRational"
177 | otherwise = ppBesides [ppRational r, ppChar 'R']
180 | codeStyle sty = ppBesides [ppStr (show (_UNPK_ s))]
181 | ufStyle sty = ppCat [ppStr "_NOREP_S_", ppStr (show (_UNPK_ s))]
182 | otherwise = ppBesides [ppStr (show (_UNPK_ s)), ppChar 'S']
184 ppr sty (MachLitLit s k)
185 | codeStyle sty = ppPStr s
186 | ufStyle sty = ppBesides [ppStr "``", ppPStr s, ppStr "'' _K_ ", ppr sty k]
187 | otherwise = ppBesides [ppStr "``", ppPStr s, ppStr "''"]
189 ufStyle (PprUnfolding _) = True
192 if_ubxd sty = if codeStyle sty then ppNil else ppChar '#'
194 showBasicLit :: PprStyle -> BasicLit -> String
196 showBasicLit sty lit = ppShow 80 (ppr sty lit)