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,
42 #include "HsVersions.h"
47 %************************************************************************
49 \subsection[Unused]{Unused}
51 %************************************************************************
53 Used as a placeholder in types.
59 unused = error "Unused is used!"
63 %************************************************************************
65 \subsection[Arity]{Arity}
67 %************************************************************************
74 %************************************************************************
76 \subsection[Version]{Module and identifier version numbers}
78 %************************************************************************
83 bogusVersion :: Version -- Shouldn't look at these
84 bogusVersion = error "bogusVersion"
86 bumpVersion :: Bool -> Version -> Version
87 -- Bump if the predicate (typically equality between old and new) is false
88 bumpVersion False v = v+1
89 bumpVersion True v = v
91 initialVersion :: Version
96 %************************************************************************
98 \subsection[Fixity]{Fixity info}
100 %************************************************************************
103 data Fixity = Fixity Int FixityDirection
104 data FixityDirection = InfixL | InfixR | InfixN
107 instance Outputable Fixity where
108 ppr (Fixity prec dir) = hcat [ppr dir, space, int prec]
110 instance Outputable FixityDirection where
111 ppr InfixL = ptext SLIT("infixl")
112 ppr InfixR = ptext SLIT("infixr")
113 ppr InfixN = ptext SLIT("infix")
115 instance Eq Fixity where -- Used to determine if two fixities conflict
116 (Fixity p1 dir1) == (Fixity p2 dir2) = p1==p2 && dir1 == dir2
118 maxPrecedence = (9::Int)
119 defaultFixity = Fixity maxPrecedence InfixL
121 negateFixity :: Fixity
122 negateFixity = Fixity negatePrecedence InfixL -- Precedence of unary negate is wired in as infixl 6!
124 negatePrecedence :: Int
129 %************************************************************************
131 \subsection[NewType/DataType]{NewType/DataType flag}
133 %************************************************************************
137 = NewType -- "newtype Blah ..."
138 | DataType -- "data Blah ..."
139 deriving( Eq ) -- Needed because Demand derives Eq
142 %************************************************************************
144 \subsection[Top-level/local]{Top-level/not-top level flag}
146 %************************************************************************
153 isTopLevel, isNotTopLevel :: TopLevelFlag -> Bool
155 isNotTopLevel NotTopLevel = True
156 isNotTopLevel TopLevel = False
158 isTopLevel TopLevel = True
159 isTopLevel NotTopLevel = False
162 %************************************************************************
164 \subsection[Top-level/local]{Top-level/not-top level flag}
166 %************************************************************************
174 isBoxed :: Boxity -> Bool
176 isBoxed Unboxed = False
178 tupleParens :: Boxity -> SDoc -> SDoc
179 tupleParens Boxed p = parens p
180 tupleParens Unboxed p = ptext SLIT("(#") <+> p <+> ptext SLIT("#)")
184 %************************************************************************
186 \subsection[Recursive/Non-Recursive]{Recursive/Non-Recursive flag}
188 %************************************************************************
191 data RecFlag = Recursive
194 isRec :: RecFlag -> Bool
195 isRec Recursive = True
196 isRec NonRecursive = False
198 isNonRec :: RecFlag -> Bool
199 isNonRec Recursive = False
200 isNonRec NonRecursive = True
203 %************************************************************************
205 \subsection[Generic]{Generic flag}
207 %************************************************************************
209 This is the "Embedding-Projection pair" datatype, it contains
210 two pieces of code (normally either RenamedHsExpr's or Id's)
211 If we have a such a pair (EP from to), the idea is that 'from' and 'to'
212 represents functions of type
221 T and Tring are arbitrary, but typically T is the 'main' type while
222 Tring is the 'representation' type. (This just helps us remember
223 whether to use 'from' or 'to'.
226 data EP a = EP { fromEP :: a, -- :: T -> Tring
227 toEP :: a } -- :: Tring -> T
230 Embedding-projection pairs are used in several places:
232 First of all, each type constructor has an EP associated with it, the
233 code in EP converts (datatype T) from T to Tring and back again.
235 Secondly, when we are filling in Generic methods (in the typechecker,
236 tcMethodBinds), we are constructing bimaps by induction on the structure
237 of the type of the method signature.
240 %************************************************************************
242 \subsection{Occurrence information}
244 %************************************************************************
246 This data type is used exclusively by the simplifier, but it appears in a
247 SubstResult, which is currently defined in VarEnv, which is pretty near
248 the base of the module hierarchy. So it seemed simpler to put the
249 defn of OccInfo here, safely at the bottom
255 | IAmDead -- Marks unused variables. Sometimes useful for
256 -- lambda and case-bound variables.
262 | IAmALoopBreaker -- Used by the occurrence analyser to mark loop-breakers
263 -- in a group of recursive definitions
265 seqOccInfo :: OccInfo -> ()
266 seqOccInfo (OneOcc in_lam once) = in_lam `seq` once `seq` ()
269 type InsideLam = Bool -- True <=> Occurs inside a non-linear lambda
270 -- Substituting a redex for this occurrence is
271 -- dangerous because it might duplicate work.
275 type OneBranch = Bool -- True <=> Occurs in only one case branch
276 -- so no code-duplication issue to worry about
280 isLoopBreaker :: OccInfo -> Bool
281 isLoopBreaker IAmALoopBreaker = True
282 isLoopBreaker other = False
284 isDeadOcc :: OccInfo -> Bool
285 isDeadOcc IAmDead = True
286 isDeadOcc other = False
288 isFragileOcc :: OccInfo -> Bool
289 isFragileOcc (OneOcc _ _) = True
290 isFragileOcc other = False
294 instance Outputable OccInfo where
295 -- only used for debugging; never parsed. KSW 1999-07
296 ppr NoOccInfo = empty
297 ppr IAmALoopBreaker = ptext SLIT("_Kx")
298 ppr IAmDead = ptext SLIT("_Kd")
299 ppr (OneOcc inside_lam one_branch) | inside_lam = ptext SLIT("_Kl")
300 | one_branch = ptext SLIT("_Ks")
301 | otherwise = ptext SLIT("_Ks*")
303 instance Show OccInfo where
304 showsPrec p occ = showsPrecSDoc p (ppr occ)