2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[ParseUtils]{Help the interface parser}
7 #include "HsVersions.h"
9 module ParseUtils where
13 import HsSyn -- quite a bit of stuff
14 import RdrHsSyn -- oodles of synonyms
15 import HsPragmas ( noDataPragmas, noClassPragmas, noClassOpPragmas,
19 import ErrUtils ( Error(..) )
20 import FiniteMap ( unitFM, listToFM, lookupFM, plusFM, FiniteMap )
21 import Maybes ( maybeToBool, MaybeErr(..) )
22 import Name ( isLexConId, isLexVarId, isLexConSym,
24 RdrName(..){-instance Outputable:ToDo:rm-}
26 import PprStyle ( PprStyle(..) ) -- ToDo: rm debugging
27 import PrelMods ( fromPrelude )
28 import Pretty ( ppCat, ppPStr, ppInt, ppShow, ppStr )
29 import SrcLoc ( mkIfaceSrcLoc )
30 import Util ( startsWith, isIn, panic, assertPanic )
34 type LocalVersionsMap = FiniteMap FAST_STRING Version
35 type ExportsMap = FiniteMap FAST_STRING (RdrName, ExportFlag)
36 type FixitiesMap = FiniteMap FAST_STRING RdrNameFixityDecl
37 type LocalTyDefsMap = FiniteMap FAST_STRING RdrIfaceDecl -- for TyCon/Class
38 type LocalValDefsMap = FiniteMap FAST_STRING RdrIfaceDecl -- for values incl DataCon
39 type LocalPragmasMap = FiniteMap FAST_STRING PragmaStuff
41 type PragmaStuff = String
46 Version -- Module version number
47 (Maybe Version) -- Source version number
48 LocalVersionsMap -- Local version numbers
49 ExportsMap -- Exported names
50 (Bag Module) -- Special instance modules
51 FixitiesMap -- fixities of local things
52 LocalTyDefsMap -- Local TyCon/Class names defined
53 LocalValDefsMap -- Local value names defined
54 (Bag RdrIfaceInst)-- Local instance declarations
55 LocalPragmasMap -- Pragmas for local names
57 -----------------------------------------------------------------
60 = TypeSig RdrName SrcLoc RdrNameTyDecl
61 | NewTypeSig RdrName RdrName SrcLoc RdrNameTyDecl
62 | DataSig RdrName [RdrName] SrcLoc RdrNameTyDecl
63 | ClassSig RdrName [RdrName] SrcLoc RdrNameClassDecl
64 | ValSig RdrName SrcLoc RdrNamePolyType
67 = InstSig RdrName RdrName SrcLoc RdrNameInstDecl
71 -----------------------------------------------------------------
73 = ITinterface -- keywords
90 | ITbang -- magic symbols
106 | ITinteger Integer -- numbers and names
107 | ITvarid FAST_STRING
108 | ITconid FAST_STRING
109 | ITvarsym FAST_STRING
110 | ITconsym FAST_STRING
115 deriving Text -- debugging
117 instance Text RdrName where -- debugging
118 showsPrec _ rn = showString (ppShow 80 (ppr PprDebug rn))
120 -----------------------------------------------------------------
121 de_qual (Unqual n) = n
122 de_qual (Qual _ n) = n
124 en_mono :: FAST_STRING -> RdrNameMonoType
125 en_mono tv = MonoTyVar (Unqual tv)
127 type2context (MonoTupleTy tys) = map type2class_assertion tys
128 type2context other_ty = [ type2class_assertion other_ty ]
130 type2class_assertion (MonoTyApp clas [MonoTyVar tyvar]) = (clas, tyvar)
131 type2class_assertion _ = panic "type2class_assertion: bad format"
133 -----------------------------------------------------------------
134 mk_type :: (RdrName, [FAST_STRING])
138 mk_type (qtycon, tyvars) ty
140 tycon = de_qual qtycon
141 qtyvars = map Unqual tyvars
143 unitFM tycon (TypeSig qtycon mkIfaceSrcLoc (
144 TySynonym qtycon qtyvars ty mkIfaceSrcLoc))
146 mk_data :: RdrNameContext
147 -> (RdrName, [FAST_STRING])
148 -> [(RdrName, RdrNameConDecl)]
149 -> (LocalTyDefsMap, LocalValDefsMap)
151 mk_data ctxt (qtycon, tyvars) names_and_constrs
153 (qconnames, constrs) = unzip names_and_constrs
154 tycon = de_qual qtycon
155 connames = map de_qual qconnames
156 qtyvars = map Unqual tyvars
158 decl = DataSig qtycon qconnames mkIfaceSrcLoc (
159 TyData ctxt qtycon qtyvars constrs Nothing noDataPragmas mkIfaceSrcLoc)
161 (unitFM tycon decl, listToFM [(c,decl) | c <- connames])
163 mk_new :: RdrNameContext
164 -> (RdrName, [FAST_STRING])
165 -> (RdrName, RdrNameMonoType)
166 -> (LocalTyDefsMap, LocalValDefsMap)
168 mk_new ctxt (qtycon, tyvars) (qconname, ty)
170 tycon = de_qual qtycon
171 conname = de_qual qconname
172 qtyvars = map Unqual tyvars
173 constr = NewConDecl qconname ty mkIfaceSrcLoc
175 decl = NewTypeSig qtycon qconname mkIfaceSrcLoc (
176 TyNew ctxt qtycon qtyvars [constr] Nothing noDataPragmas mkIfaceSrcLoc)
178 (unitFM tycon decl, unitFM conname decl)
180 mk_class :: RdrNameContext
181 -> (RdrName, RdrName)
182 -> [(FAST_STRING, RdrNameSig)]
183 -> (LocalTyDefsMap, LocalValDefsMap)
185 mk_class ctxt (qclas, tyvar) ops_and_sigs
186 = case (unzip ops_and_sigs) of { (opnames, sigs) ->
188 qopnames = map Unqual opnames
190 op_sigs = map opify sigs
192 decl = ClassSig qclas qopnames mkIfaceSrcLoc (
193 ClassDecl ctxt qclas tyvar op_sigs EmptyMonoBinds noClassPragmas mkIfaceSrcLoc)
195 (unitFM clas decl, listToFM [(o,decl) | o <- opnames]) }
197 opify (Sig f ty _ loc) = ClassOpSig f ty noClassOpPragmas loc
199 mk_inst :: RdrNameContext
201 -> RdrNameMonoType -- fish the tycon out yourself...
204 mk_inst ctxt clas mono_ty
205 = InstSig clas (tycon_name mono_ty) mkIfaceSrcLoc (
206 InstDecl clas (HsPreForAllTy ctxt mono_ty)
207 EmptyMonoBinds False Nothing{-lying-} [{-sigs-}]
208 noInstancePragmas mkIfaceSrcLoc)
210 tycon_name (MonoTyApp tc _) = tc
211 tycon_name (MonoListTy _) = Unqual SLIT("[]")
212 tycon_name (MonoFunTy _ _) = Unqual SLIT("->")
213 tycon_name (MonoTupleTy ts) = Unqual (mkTupNameStr (length ts))
215 -----------------------------------------------------------------
216 lexIface :: String -> [IfaceToken]
222 -- whitespace and comments
223 ' ' : cs -> lexIface cs
224 '\t' : cs -> lexIface cs
225 '\n' : cs -> lexIface cs
226 '-' : '-' : cs -> lex_comment cs
227 '{' : '-' : cs -> lex_nested_comment 1{-one seen-} cs
229 '(' : '.' : '.' : ')' : cs -> ITdotdot : lexIface cs
230 '(' : cs -> IToparen : lexIface cs
231 ')' : cs -> ITcparen : lexIface cs
232 '[' : cs -> ITobrack : lexIface cs
233 ']' : cs -> ITcbrack : lexIface cs
234 '{' : cs -> ITocurly : lexIface cs
235 '}' : cs -> ITccurly : lexIface cs
236 ',' : cs -> ITcomma : lexIface cs
237 ';' : cs -> ITsemi : lexIface cs
238 '`' : cs -> ITbquote : lexIface cs
240 '_' : cs -> lex_name Nothing is_var_sym str
241 c : cs | isUpper c -> lex_word str -- don't know if "Module." on front or not
242 | isDigit c -> lex_num str
243 | isAlpha c -> lex_name Nothing is_var_sym str
244 | is_sym_sym c -> lex_name Nothing is_sym_sym str
246 other -> error ("lexing:"++other)
249 = case (span ((/=) '\n') str) of { (junk, rest) ->
253 lex_nested_comment lvl [] = error "EOF in nested comment in interface"
254 lex_nested_comment lvl str
256 '{' : '-' : xs -> lex_nested_comment (lvl+1) xs
257 '-' : '}' : xs -> if lvl == 1
259 else lex_nested_comment (lvl-1) xs
260 _ : xs -> lex_nested_comment lvl xs
264 = case (span isDigit str) of { (num, rest) ->
265 ITinteger (read num) : lexIface rest }
268 is_var_sym '_' = True
269 is_var_sym c = isAlphanum c
271 is_sym_sym c = c `elem` ":!#$%&*+./<=>?@\\^|-~" -- ToDo: add ISOgraphic
274 lex_word str@(c:cs) -- we know we have a capital letter to start
275 = -- we first try for "<module>." on the front...
276 case (module_dot str) of
277 Nothing -> lex_name Nothing is_var_sym str
278 Just (m,rest) -> lex_name (Just m) (in_the_club rest) rest
280 in_the_club [] = panic "lex_word:in_the_club"
281 in_the_club (c:_) | isAlpha c = is_var_sym
282 | is_sym_sym c = is_sym_sym
283 | otherwise = panic ("lex_word:in_the_club="++[c])
286 = if not (isUpper c) then
289 case (span is_var_sym cs) of { (word, rest) ->
292 (r:rs) | r == '.' -> Just (_PK_ (c:word), rs)
296 lex_name module_dot in_the_club str
297 = case (span in_the_club str) of { (word, rest) ->
298 case (lookupFM keywordsFM word) of
299 Just xx -> ASSERT( not (maybeToBool module_dot) )
303 f = head word -- first char
308 categ n (ITconid n) (ITvarid n) (ITconsym n) (ITvarsym n)
311 q = if fromPrelude m then Unqual n else Qual m n
313 categ n (ITqconid q) (ITqvarid q) (ITqconsym q) (ITqvarsym q)
318 categ n conid varid consym varsym
319 = if isLexConId n then conid
320 else if isLexVarId n then varid
321 else if isLexConSym n then consym
325 keywordsFM :: FiniteMap String IfaceToken
326 keywordsFM = listToFM [
327 ("interface", ITinterface)
329 ,("__versions__", ITversions)
330 ,("__exports__", ITexports)
331 ,("__instance_modules__",ITinstance_modules)
332 ,("__instances__", ITinstances)
333 ,("__fixities__", ITfixities)
334 ,("__declarations__", ITdeclarations)
335 ,("__pragmas__", ITpragmas)
339 ,("newtype", ITnewtype)
342 ,("instance", ITinstance)
343 ,("infixl", ITinfixl)
344 ,("infixr", ITinfixr)
355 -----------------------------------------------------------------
356 type IfM a = MaybeErr a Error
358 returnIf :: a -> IfM a
359 thenIf :: IfM a -> (a -> IfM b) -> IfM b
360 happyError :: Int -> [IfaceToken] -> IfM a
362 returnIf a = Succeeded a
364 thenIf (Succeeded a) k = k a
365 thenIf (Failed err) _ = Failed err
367 happyError ln toks = Failed (ifaceParseErr ln toks)
368 -----------------------------------------------------------------
370 ifaceParseErr ln toks sty
371 = ppCat [ppPStr SLIT("Interface-file parse error: line"), ppInt ln, ppStr "toks=", ppStr (show toks)]