2 % (c) The GRASP/AQUA Project, Glasgow University, 1997-1998
4 \section[BasicTypes]{Miscellanous types}
6 This module defines a miscellaneously collection of very simple
10 \item have no other obvious home
11 \item don't depend on any other complicated types
12 \item are used in more than one "part" of the compiler
17 Version, bumpVersion, initialVersion, bogusVersion,
23 Fixity(..), FixityDirection(..),
24 defaultFixity, maxPrecedence, negateFixity, negatePrecedence,
28 RecFlag(..), isRec, isNonRec,
30 TopLevelFlag(..), isTopLevel, isNotTopLevel,
32 Boxity(..), isBoxed, tupleParens,
34 OccInfo(..), seqOccInfo, isFragileOcc, isDeadOcc, isLoopBreaker,
36 InsideLam, insideLam, notInsideLam,
37 OneBranch, oneBranch, notOneBranch,
41 StrictnessMark(..), isMarkedUnboxed, isMarkedStrict
44 #include "HsVersions.h"
49 %************************************************************************
51 \subsection[Unused]{Unused}
53 %************************************************************************
55 Used as a placeholder in types.
61 unused = error "Unused is used!"
65 %************************************************************************
67 \subsection[Arity]{Arity}
69 %************************************************************************
76 %************************************************************************
78 \subsection[Version]{Module and identifier version numbers}
80 %************************************************************************
85 bogusVersion :: Version -- Shouldn't look at these
86 bogusVersion = error "bogusVersion"
88 bumpVersion :: Bool -> Version -> Version
89 -- Bump if the predicate (typically equality between old and new) is false
90 bumpVersion False v = v+1
91 bumpVersion True v = v
93 initialVersion :: Version
98 %************************************************************************
100 \subsection[Fixity]{Fixity info}
102 %************************************************************************
105 data Fixity = Fixity Int FixityDirection
106 data FixityDirection = InfixL | InfixR | InfixN
109 instance Outputable Fixity where
110 ppr (Fixity prec dir) = hcat [ppr dir, space, int prec]
112 instance Outputable FixityDirection where
113 ppr InfixL = ptext SLIT("infixl")
114 ppr InfixR = ptext SLIT("infixr")
115 ppr InfixN = ptext SLIT("infix")
117 instance Eq Fixity where -- Used to determine if two fixities conflict
118 (Fixity p1 dir1) == (Fixity p2 dir2) = p1==p2 && dir1 == dir2
120 maxPrecedence = (9::Int)
121 defaultFixity = Fixity maxPrecedence InfixL
123 negateFixity :: Fixity
124 negateFixity = Fixity negatePrecedence InfixL -- Precedence of unary negate is wired in as infixl 6!
126 negatePrecedence :: Int
131 %************************************************************************
133 \subsection[NewType/DataType]{NewType/DataType flag}
135 %************************************************************************
139 = NewType -- "newtype Blah ..."
140 | DataType -- "data Blah ..."
141 deriving( Eq ) -- Needed because Demand derives Eq
144 %************************************************************************
146 \subsection[Top-level/local]{Top-level/not-top level flag}
148 %************************************************************************
155 isTopLevel, isNotTopLevel :: TopLevelFlag -> Bool
157 isNotTopLevel NotTopLevel = True
158 isNotTopLevel TopLevel = False
160 isTopLevel TopLevel = True
161 isTopLevel NotTopLevel = False
164 %************************************************************************
166 \subsection[Top-level/local]{Top-level/not-top level flag}
168 %************************************************************************
176 isBoxed :: Boxity -> Bool
178 isBoxed Unboxed = False
180 tupleParens :: Boxity -> SDoc -> SDoc
181 tupleParens Boxed p = parens p
182 tupleParens Unboxed p = ptext SLIT("(#") <+> p <+> ptext SLIT("#)")
186 %************************************************************************
188 \subsection[Recursive/Non-Recursive]{Recursive/Non-Recursive flag}
190 %************************************************************************
193 data RecFlag = Recursive
196 isRec :: RecFlag -> Bool
197 isRec Recursive = True
198 isRec NonRecursive = False
200 isNonRec :: RecFlag -> Bool
201 isNonRec Recursive = False
202 isNonRec NonRecursive = True
205 %************************************************************************
207 \subsection[Generic]{Generic flag}
209 %************************************************************************
211 This is the "Embedding-Projection pair" datatype, it contains
212 two pieces of code (normally either RenamedHsExpr's or Id's)
213 If we have a such a pair (EP from to), the idea is that 'from' and 'to'
214 represents functions of type
223 T and Tring are arbitrary, but typically T is the 'main' type while
224 Tring is the 'representation' type. (This just helps us remember
225 whether to use 'from' or 'to'.
228 data EP a = EP { fromEP :: a, -- :: T -> Tring
229 toEP :: a } -- :: Tring -> T
232 Embedding-projection pairs are used in several places:
234 First of all, each type constructor has an EP associated with it, the
235 code in EP converts (datatype T) from T to Tring and back again.
237 Secondly, when we are filling in Generic methods (in the typechecker,
238 tcMethodBinds), we are constructing bimaps by induction on the structure
239 of the type of the method signature.
242 %************************************************************************
244 \subsection{Occurrence information}
246 %************************************************************************
248 This data type is used exclusively by the simplifier, but it appears in a
249 SubstResult, which is currently defined in VarEnv, which is pretty near
250 the base of the module hierarchy. So it seemed simpler to put the
251 defn of OccInfo here, safely at the bottom
257 | IAmDead -- Marks unused variables. Sometimes useful for
258 -- lambda and case-bound variables.
264 | IAmALoopBreaker -- Used by the occurrence analyser to mark loop-breakers
265 -- in a group of recursive definitions
267 seqOccInfo :: OccInfo -> ()
268 seqOccInfo (OneOcc in_lam once) = in_lam `seq` once `seq` ()
271 type InsideLam = Bool -- True <=> Occurs inside a non-linear lambda
272 -- Substituting a redex for this occurrence is
273 -- dangerous because it might duplicate work.
277 type OneBranch = Bool -- True <=> Occurs in only one case branch
278 -- so no code-duplication issue to worry about
282 isLoopBreaker :: OccInfo -> Bool
283 isLoopBreaker IAmALoopBreaker = True
284 isLoopBreaker other = False
286 isDeadOcc :: OccInfo -> Bool
287 isDeadOcc IAmDead = True
288 isDeadOcc other = False
290 isFragileOcc :: OccInfo -> Bool
291 isFragileOcc (OneOcc _ _) = True
292 isFragileOcc other = False
296 instance Outputable OccInfo where
297 -- only used for debugging; never parsed. KSW 1999-07
298 ppr NoOccInfo = empty
299 ppr IAmALoopBreaker = ptext SLIT("_Kx")
300 ppr IAmDead = ptext SLIT("_Kd")
301 ppr (OneOcc inside_lam one_branch) | inside_lam = ptext SLIT("_Kl")
302 | one_branch = ptext SLIT("_Ks")
303 | otherwise = ptext SLIT("_Ks*")
305 instance Show OccInfo where
306 showsPrec p occ = showsPrecSDoc p (ppr occ)
309 %************************************************************************
311 \subsection{Strictness indication}
313 %************************************************************************
315 The strictness annotations on types in data type declarations
316 e.g. data T = MkT !Int !(Bool,Bool)
320 = MarkedUserStrict -- "!" in a source decl
321 | MarkedStrict -- "!" in an interface decl: strict but not unboxed
322 | MarkedUnboxed -- "!!" in an interface decl: unboxed
323 | NotMarkedStrict -- No annotation at all
326 isMarkedUnboxed MarkedUnboxed = True
327 isMarkedUnboxed other = False
329 isMarkedStrict NotMarkedStrict = False
330 isMarkedStrict other = True -- All others are strict
332 instance Outputable StrictnessMark where
333 ppr MarkedUserStrict = ptext SLIT("!u")
334 ppr MarkedStrict = ptext SLIT("!")
335 ppr MarkedUnboxed = ptext SLIT("! !")
336 ppr NotMarkedStrict = empty