1 %************************************************************************
3 \section[ProtoName]{@ProtoName@: name type used early in the compiler}
5 %************************************************************************
8 #include "HsVersions.h"
15 cmpProtoName, eqProtoName, elemProtoNames,
16 cmpByLocalName, eqByLocalName, elemByLocalNames,
20 -- and to make the module self-sufficient...
22 #ifndef __GLASGOW_HASKELL__
27 IMPORT_Trace -- ToDo: rm (debugging)
29 import Name ( cmpName, Name
30 IF_ATTACK_PRAGMAS(COMMA eqName)
37 %************************************************************************
39 \subsection{The main type declaration}
41 %************************************************************************
45 = Unk FAST_STRING -- local name in module
47 | Imp FAST_STRING -- name of defining module
48 FAST_STRING -- name used in defining name
49 [FAST_STRING] -- name of the module whose interfaces
50 -- told me about this thing
51 FAST_STRING -- occurrence name; Nothing => same as field 2
54 | Unk2 FAST_INT -- same as Unk but this FAST_INT is
55 -- the index into hash table (makes for
56 -- superbly great equality comparisons!)
61 %************************************************************************
63 \subsection{Construction}
65 %************************************************************************
68 mkPreludeProtoName :: Name -> ProtoName
70 mkPreludeProtoName prel_name = Prel prel_name
73 %************************************************************************
77 %************************************************************************
79 Comparing @ProtoNames@. These functions are used to bring together
80 duplicate declarations for things, and eliminate all but one.
82 In general, the things thus manipulated are not prelude things, but we
83 still need to be able to compare prelude classes and type constructors
84 so that we can compare instance declarations. However, since all
85 Prelude classes and type constructors come from @PreludeCore@, and
86 hence can't not be in scope, they will always be of the form (@Prel@
87 n), so we don't need to compare @Prel@ things against @Imp@ or @Unk@
90 (Later the same night...: but, oh yes, you do:
92 Given two instance decls
95 instance Eq {-PreludeCore-} Foo
96 instance Bar {-user-defined-} Foo
99 you will get a comparison of "Eq" (a Prel) with "Bar" (an {Unk,Imp}))
101 @cmp_name@ compares either by ``local name'' (the string by which
102 the entity is known in this module, renaming and all) or by original
103 name, in which case the module name is also taken into account.
104 (Just watch what happens on @Imps@...)
107 cmp_name :: Bool -> ProtoName -> ProtoName -> TAG_
109 cmp_name by_local (Unk n1) (Unk n2) = _CMP_STRING_ n1 n2
110 cmp_name by_local (Unk n1) (Imp m n2 _ o2) = _CMP_STRING_ n1 (if by_local then o2 else n2)
111 cmp_name by_local (Unk n1) (Prel nm)
112 = let (_, n2) = getOrigName nm in
115 cmp_name by_local (Prel n1) (Prel n2) = cmpName n1 n2
117 -- in ordering these things, it's *most* important to have "names" (vs "modules")
118 -- as the primary comparison key; otherwise, a list of ProtoNames like...
120 -- Imp H.T , Imp P.I , Unk T
122 -- will *not* be re-ordered to bring the "Imp H.T" and "Unk T" `next to each other'...
125 cmp_name True (Imp _ _ _ o1) (Imp _ _ _ o2) = _CMP_STRING_ o1 o2
127 cmp_name False (Imp m1 n1 _ _) (Imp m2 n2 _ _)
128 = case _CMP_STRING_ n1 n2 of {
130 EQ_ -> case _CMP_STRING_ m1 m2 of {
132 xxx -> if _NULL_ m1 || _NULL_ m2
138 -- That's a real **HACK** on comparing "original module" names!
139 -- The thing is: we `make up' ProtoNames for instances for
140 -- sorting-out-interfaces purposes, but we *may* not know the
141 -- original module, so it will be Nil. This is the *ONLY* way
142 -- that a "" `module name' can arise! Rather than say "not equal",
143 -- we want that Nil to compare as a `wildcard', matching anything.
145 -- We could do this elsewhere in the compiler, but there is
146 -- an efficiency issue -- we plow through *piles* of instances.
148 cmp_name True (Imp _ _ _ o1) (Prel nm)
150 n2 = case (getOrigName nm) of { (_, x) -> x } -- stricter for speed
154 cmp_name False (Imp m1 n1 _ _) (Prel nm)
155 = case getOrigName nm of { (m2, n2) ->
156 case _CMP_STRING_ n1 n2 of { LT_ -> LT_; EQ_ -> _CMP_STRING_ m1 m2; GT__ -> GT_ }}
158 cmp_name by_local other_p1 other_p2
159 = case cmp_name by_local other_p2 other_p1 of -- compare the other way around
166 eqProtoName, eqByLocalName :: ProtoName -> ProtoName -> Bool
169 = case cmp_name False a b of { EQ_ -> True; _ -> False }
171 cmpProtoName a b = cmp_name False a b
174 = case cmp_name True a b of { EQ_ -> True; _ -> False }
176 cmpByLocalName a b = cmp_name True a b
180 elemProtoNames, elemByLocalNames :: ProtoName -> [ProtoName] -> Bool
182 elemProtoNames _ [] = False
183 elemProtoNames x (y:ys)
184 = case cmp_name False x y of
185 LT_ -> elemProtoNames x ys
187 GT__ -> elemProtoNames x ys
189 elemByLocalNames _ [] = False
190 elemByLocalNames x (y:ys)
191 = case cmp_name True x y of
192 LT_ -> elemByLocalNames x ys
194 GT__ -> elemByLocalNames x ys
196 isConopPN :: ProtoName -> Bool
197 isConopPN (Unk s) = isConop s
198 isConopPN (Imp _ n _ _) = isConop n -- ToDo: should use occurrence name???
201 %************************************************************************
203 \subsection{Instances}
205 %************************************************************************
207 ********** REMOVE THESE WHEN WE FIX THE SET-ery IN RenameBinds4 *********
210 {- THESE INSTANCES ARE TOO DELICATE TO BE USED!
211 Use eqByLocalName, ...., etc. instead
213 instance Eq ProtoName where
214 a == b = case cmp_name False a b of { EQ_ -> True; _ -> False }
216 instance Ord ProtoName where
217 a < b = case cmp_name False a b of { LT_ -> True; EQ_ -> False; GT__ -> False }
218 a <= b = case cmp_name False a b of { LT_ -> True; EQ_ -> True; GT__ -> False }
223 instance NamedThing ProtoName where
225 getOrigName (Unk _) = panic "NamedThing.ProtoName.getOrigName (Unk)"
226 getOrigName (Imp m s _ _) = (m, s)
227 getOrigName (Prel name) = getOrigName name
229 getOccurrenceName (Unk s) = s
230 getOccurrenceName (Imp m s _ o) = o
231 getOccurrenceName (Prel name) = getOccurrenceName name
236 getSrcLoc pn = panic "NamedThing.ProtoName.getSrcLoc"
237 getInformingModules pn = panic "NamedThing.ProtoName.getInformingModule"
238 getTheUnique pn = panic "NamedThing.ProtoName.getUnique"
239 fromPreludeCore pn = panic "NamedThing.ProtoName.fromPreludeCore"
240 getExportFlag pn = panic "NamedThing.ProtoName.getExportFlag"
241 isLocallyDefined pn = panic "NamedThing.ProtoName.isLocallyDefined"
242 getType pn = panic "NamedThing.ProtoName.getType"
247 instance Outputable ProtoName where
248 ppr sty (Unk s) = ppPStr s
249 ppr sty (Prel name) = ppBeside (ppr sty name) (ifPprShowAll sty (ppPStr SLIT("/PREL")))
250 ppr sty (Imp mod dec imod loc)
251 = ppBesides [ppPStr mod, ppChar '.', ppPStr dec, pp_occur_name dec loc ]
252 -- ToDo: print "informant modules" if high debugging level
254 pp_occur_name s o | s /= o = ppBesides [ppChar '{', ppPStr o, ppChar '}']