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,
23 Fixity(..), FixityDirection(..),
24 defaultFixity, maxPrecedence,
25 negateFixity, funTyFixity,
28 IPName(..), ipNameName, mapIPName,
30 RecFlag(..), isRec, isNonRec, boolToRecFlag,
32 TopLevelFlag(..), isTopLevel, isNotTopLevel,
36 TupCon(..), tupleParens,
38 OccInfo(..), seqOccInfo, isFragileOcc, isOneOcc,
39 isDeadOcc, isLoopBreaker,
41 InsideLam, insideLam, notInsideLam,
42 OneBranch, oneBranch, notOneBranch,
47 StrictnessMark(..), isMarkedUnboxed, isMarkedStrict,
50 Activation(..), isActive, isNeverActive, isAlwaysActive,
52 SuccessFlag(..), succeeded, failed, successIf
55 #include "HsVersions.h"
57 import FastString( FastString )
61 %************************************************************************
63 \subsection[Arity]{Arity}
65 %************************************************************************
72 %************************************************************************
74 \subsection[Version]{Module and identifier version numbers}
76 %************************************************************************
81 bumpVersion :: Version -> Version
84 initialVersion :: Version
88 %************************************************************************
92 %************************************************************************
96 type DeprecTxt = FastString -- reason/explanation for deprecation
99 %************************************************************************
101 \subsection{Implicit parameter identity}
103 %************************************************************************
105 The @IPName@ type is here because it is used in TypeRep (i.e. very
106 early in the hierarchy), but also in HsSyn.
110 = Dupable name -- ?x: you can freely duplicate this implicit parameter
111 | Linear name -- %x: you must use the splitting function to duplicate it
112 deriving( Eq, Ord ) -- Ord is used in the IP name cache finite map
113 -- (used in HscTypes.OrigIParamCache)
116 ipNameName :: IPName name -> name
117 ipNameName (Dupable n) = n
118 ipNameName (Linear n) = n
120 mapIPName :: (a->b) -> IPName a -> IPName b
121 mapIPName f (Dupable n) = Dupable (f n)
122 mapIPName f (Linear n) = Linear (f n)
124 instance Outputable name => Outputable (IPName name) where
125 ppr (Dupable n) = char '?' <> ppr n -- Ordinary implicit parameters
126 ppr (Linear n) = char '%' <> ppr n -- Splittable implicit parameters
130 %************************************************************************
132 \subsection[Fixity]{Fixity info}
134 %************************************************************************
137 ------------------------
138 data Fixity = Fixity Int FixityDirection
140 instance Outputable Fixity where
141 ppr (Fixity prec dir) = hcat [ppr dir, space, int prec]
143 instance Eq Fixity where -- Used to determine if two fixities conflict
144 (Fixity p1 dir1) == (Fixity p2 dir2) = p1==p2 && dir1 == dir2
146 ------------------------
147 data FixityDirection = InfixL | InfixR | InfixN
150 instance Outputable FixityDirection where
151 ppr InfixL = ptext SLIT("infixl")
152 ppr InfixR = ptext SLIT("infixr")
153 ppr InfixN = ptext SLIT("infix")
155 ------------------------
156 maxPrecedence = (9::Int)
157 defaultFixity = Fixity maxPrecedence InfixL
159 negateFixity, funTyFixity :: Fixity
161 negateFixity = Fixity 6 InfixL -- Fixity of unary negate
162 funTyFixity = Fixity 0 InfixR -- Fixity of '->'
170 @(compareFixity op1 op2)@ tells which way to arrange appication, or
171 whether there's an error.
174 compareFixity :: Fixity -> Fixity
175 -> (Bool, -- Error please
176 Bool) -- Associate to the right: a op1 (b op2 c)
177 compareFixity (Fixity prec1 dir1) (Fixity prec2 dir2)
178 = case prec1 `compare` prec2 of
181 EQ -> case (dir1, dir2) of
182 (InfixR, InfixR) -> right
183 (InfixL, InfixL) -> left
186 right = (False, True)
187 left = (False, False)
188 error_please = (True, False)
192 %************************************************************************
194 \subsection[Top-level/local]{Top-level/not-top level flag}
196 %************************************************************************
203 isTopLevel, isNotTopLevel :: TopLevelFlag -> Bool
205 isNotTopLevel NotTopLevel = True
206 isNotTopLevel TopLevel = False
208 isTopLevel TopLevel = True
209 isTopLevel NotTopLevel = False
211 instance Outputable TopLevelFlag where
212 ppr TopLevel = ptext SLIT("<TopLevel>")
213 ppr NotTopLevel = ptext SLIT("<NotTopLevel>")
217 %************************************************************************
219 \subsection[Top-level/local]{Top-level/not-top level flag}
221 %************************************************************************
229 isBoxed :: Boxity -> Bool
231 isBoxed Unboxed = False
235 %************************************************************************
237 \subsection[Recursive/Non-Recursive]{Recursive/Non-Recursive flag}
239 %************************************************************************
242 data RecFlag = Recursive
246 isRec :: RecFlag -> Bool
247 isRec Recursive = True
248 isRec NonRecursive = False
250 isNonRec :: RecFlag -> Bool
251 isNonRec Recursive = False
252 isNonRec NonRecursive = True
254 boolToRecFlag :: Bool -> RecFlag
255 boolToRecFlag True = Recursive
256 boolToRecFlag False = NonRecursive
258 instance Outputable RecFlag where
259 ppr Recursive = ptext SLIT("Recursive")
260 ppr NonRecursive = ptext SLIT("NonRecursive")
263 %************************************************************************
267 %************************************************************************
270 data TupCon = TupCon Boxity Arity
272 instance Eq TupCon where
273 (TupCon b1 a1) == (TupCon b2 a2) = b1==b2 && a1==a2
275 tupleParens :: Boxity -> SDoc -> SDoc
276 tupleParens Boxed p = parens p
277 tupleParens Unboxed p = ptext SLIT("(#") <+> p <+> ptext SLIT("#)")
280 %************************************************************************
282 \subsection[Generic]{Generic flag}
284 %************************************************************************
286 This is the "Embedding-Projection pair" datatype, it contains
287 two pieces of code (normally either RenamedExpr's or Id's)
288 If we have a such a pair (EP from to), the idea is that 'from' and 'to'
289 represents functions of type
298 T and Tring are arbitrary, but typically T is the 'main' type while
299 Tring is the 'representation' type. (This just helps us remember
300 whether to use 'from' or 'to'.
303 data EP a = EP { fromEP :: a, -- :: T -> Tring
304 toEP :: a } -- :: Tring -> T
307 Embedding-projection pairs are used in several places:
309 First of all, each type constructor has an EP associated with it, the
310 code in EP converts (datatype T) from T to Tring and back again.
312 Secondly, when we are filling in Generic methods (in the typechecker,
313 tcMethodBinds), we are constructing bimaps by induction on the structure
314 of the type of the method signature.
317 %************************************************************************
319 \subsection{Occurrence information}
321 %************************************************************************
323 This data type is used exclusively by the simplifier, but it appears in a
324 SubstResult, which is currently defined in VarEnv, which is pretty near
325 the base of the module hierarchy. So it seemed simpler to put the
326 defn of OccInfo here, safely at the bottom
332 | IAmDead -- Marks unused variables. Sometimes useful for
333 -- lambda and case-bound variables.
339 | IAmALoopBreaker -- Used by the occurrence analyser to mark loop-breakers
340 -- in a group of recursive definitions
342 seqOccInfo :: OccInfo -> ()
343 seqOccInfo occ = occ `seq` ()
346 type InterestingCxt = Bool -- True <=> Function: is applied
347 -- Data value: scrutinised by a case with
348 -- at least one non-DEFAULT branch
351 type InsideLam = Bool -- True <=> Occurs inside a non-linear lambda
352 -- Substituting a redex for this occurrence is
353 -- dangerous because it might duplicate work.
358 type OneBranch = Bool -- True <=> Occurs in only one case branch
359 -- so no code-duplication issue to worry about
363 isLoopBreaker :: OccInfo -> Bool
364 isLoopBreaker IAmALoopBreaker = True
365 isLoopBreaker other = False
367 isDeadOcc :: OccInfo -> Bool
368 isDeadOcc IAmDead = True
369 isDeadOcc other = False
371 isOneOcc (OneOcc _ _ _) = True
372 isOneOcc other = False
374 isFragileOcc :: OccInfo -> Bool
375 isFragileOcc (OneOcc _ _ _) = True
376 isFragileOcc other = False
380 instance Outputable OccInfo where
381 -- only used for debugging; never parsed. KSW 1999-07
382 ppr NoOccInfo = empty
383 ppr IAmALoopBreaker = ptext SLIT("LoopBreaker")
384 ppr IAmDead = ptext SLIT("Dead")
385 ppr (OneOcc inside_lam one_branch int_cxt)
386 = ptext SLIT("Once") <> pp_lam <> pp_br <> pp_args
388 pp_lam | inside_lam = char 'L'
390 pp_br | one_branch = empty
391 | otherwise = char '*'
392 pp_args | int_cxt = char '!'
395 instance Show OccInfo where
396 showsPrec p occ = showsPrecSDoc p (ppr occ)
399 %************************************************************************
401 \subsection{Strictness indication}
403 %************************************************************************
405 The strictness annotations on types in data type declarations
406 e.g. data T = MkT !Int !(Bool,Bool)
409 data StrictnessMark -- Used in interface decls only
415 isMarkedUnboxed MarkedUnboxed = True
416 isMarkedUnboxed other = False
418 isMarkedStrict NotMarkedStrict = False
419 isMarkedStrict other = True -- All others are strict
421 instance Outputable StrictnessMark where
422 ppr MarkedStrict = ptext SLIT("!")
423 ppr MarkedUnboxed = ptext SLIT("!!")
424 ppr NotMarkedStrict = ptext SLIT("_")
428 %************************************************************************
430 \subsection{Success flag}
432 %************************************************************************
435 data SuccessFlag = Succeeded | Failed
437 successIf :: Bool -> SuccessFlag
438 successIf True = Succeeded
439 successIf False = Failed
441 succeeded, failed :: SuccessFlag -> Bool
442 succeeded Succeeded = True
443 succeeded Failed = False
445 failed Succeeded = False
450 %************************************************************************
452 \subsection{Activation}
454 %************************************************************************
456 When a rule or inlining is active
459 type CompilerPhase = Int -- Compilation phase
460 -- Phases decrease towards zero
461 -- Zero is the last phase
463 data Activation = NeverActive
465 | ActiveBefore CompilerPhase -- Active only *before* this phase
466 | ActiveAfter CompilerPhase -- Active in this phase and later
467 deriving( Eq ) -- Eq used in comparing rules in HsDecls
469 instance Outputable Activation where
470 ppr AlwaysActive = empty -- The default
471 ppr (ActiveBefore n) = brackets (char '~' <> int n)
472 ppr (ActiveAfter n) = brackets (int n)
473 ppr NeverActive = ptext SLIT("NEVER")
475 isActive :: CompilerPhase -> Activation -> Bool
476 isActive p NeverActive = False
477 isActive p AlwaysActive = True
478 isActive p (ActiveAfter n) = p <= n
479 isActive p (ActiveBefore n) = p > n
481 isNeverActive, isAlwaysActive :: Activation -> Bool
482 isNeverActive NeverActive = True
483 isNeverActive act = False
485 isAlwaysActive AlwaysActive = True
486 isAlwaysActive other = False