[project @ 2002-05-27 15:28:07 by simonpj]
[ghc-hetmet.git] / ghc / compiler / parser / ParseUtil.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1999
3 %
4 \section[ParseUtil]{Parser Utilities}
5
6 \begin{code}
7 module ParseUtil (
8           parseError          -- String -> Pa
9         , mkVanillaCon, mkRecCon,
10
11         , mkRecConstrOrUpdate -- HsExp -> [HsFieldUpdate] -> P HsExp
12         , groupBindings
13         
14         , mkIfaceExports      -- :: [RdrNameTyClDecl] -> [RdrExportItem]
15
16         , CallConv(..)
17         , mkImport            -- CallConv -> Safety 
18                               -- -> (FastString, RdrName, RdrNameHsType)
19                               -- -> SrcLoc 
20                               -- -> P RdrNameHsDecl
21         , mkExport            -- CallConv
22                               -- -> (FastString, RdrName, RdrNameHsType)
23                               -- -> SrcLoc 
24                               -- -> P RdrNameHsDecl
25         , mkExtName           -- RdrName -> CLabelString
26                               
27         , checkPrec           -- String -> P String
28         , checkContext        -- HsType -> P HsContext
29         , checkPred           -- HsType -> P HsPred
30         , checkTyVars         -- [HsTyVar] -> P [HsType]
31         , checkTyClHdr        -- HsType -> (name,[tyvar])
32         , checkInstType       -- HsType -> P HsType
33         , checkPattern        -- HsExp -> P HsPat
34         , checkPatterns       -- SrcLoc -> [HsExp] -> P [HsPat]
35         , checkDo             -- [Stmt] -> P [Stmt]
36         , checkValDef         -- (SrcLoc, HsExp, HsRhs, [HsDecl]) -> P HsDecl
37         , checkValSig         -- (SrcLoc, HsExp, HsRhs, [HsDecl]) -> P HsDecl
38  ) where
39
40 #include "HsVersions.h"
41
42 import List             ( isSuffixOf )
43
44 import Lex
45 import HscTypes         ( RdrAvailInfo, GenAvailInfo(..) )
46 import HsSyn            -- Lots of it
47 import ForeignCall      ( CCallConv, Safety, CCallTarget(..), CExportSpec(..),
48                           DNCallSpec(..))
49 import SrcLoc
50 import RdrHsSyn
51 import RdrName
52 import PrelNames        ( unitTyCon_RDR )
53 import OccName          ( dataName, varName, tcClsName, isDataOcc,
54                           occNameSpace, setOccNameSpace, occNameUserString )
55 import CStrings         ( CLabelString )
56 import FastString
57 import Outputable
58
59 -----------------------------------------------------------------------------
60 -- Misc utils
61
62 parseError :: String -> P a
63 parseError s = 
64   getSrcLocP `thenP` \ loc ->
65   failMsgP (hcat [ppr loc, text ": ", text s])
66
67
68 -----------------------------------------------------------------------------
69 -- mkVanillaCon
70
71 -- When parsing data declarations, we sometimes inadvertently parse
72 -- a constructor application as a type (eg. in data T a b = C a b `D` E a b)
73 -- This function splits up the type application, adds any pending
74 -- arguments, and converts the type constructor back into a data constructor.
75
76 mkVanillaCon :: RdrNameHsType -> [RdrNameBangType] -> P (RdrName, RdrNameConDetails)
77
78 mkVanillaCon ty tys
79  = split ty tys
80  where
81    split (HsAppTy t u)  ts = split t (unbangedType u : ts)
82    split (HsTyVar tc)   ts = tyConToDataCon tc  `thenP` \ data_con ->
83                              returnP (data_con, VanillaCon ts)
84    split _               _ = parseError "Illegal data/newtype declaration"
85
86 mkRecCon :: RdrName -> [([RdrName],RdrNameBangType)] -> P (RdrName, RdrNameConDetails)
87 mkRecCon con fields
88   = tyConToDataCon con  `thenP` \ data_con ->
89     returnP (data_con, RecCon fields)
90
91 tyConToDataCon :: RdrName -> P RdrName
92 tyConToDataCon tc
93   | occNameSpace tc_occ == tcClsName
94   = returnP (setRdrNameOcc tc (setOccNameSpace tc_occ dataName))
95   | otherwise
96   = parseError (showSDoc (text "Not a constructor:" <+> quotes (ppr tc)))
97   where 
98     tc_occ   = rdrNameOcc tc
99
100
101 ----------------------------------------------------------------------------
102 -- Various Syntactic Checks
103
104 checkInstType :: RdrNameHsType -> P RdrNameHsType
105 checkInstType t 
106   = case t of
107         HsForAllTy tvs ctxt ty ->
108                 checkDictTy ty [] `thenP` \ dict_ty ->
109                 returnP (HsForAllTy tvs ctxt dict_ty)
110
111         ty ->   checkDictTy ty [] `thenP` \ dict_ty->
112                 returnP (HsForAllTy Nothing [] dict_ty)
113
114 checkTyVars :: [RdrNameHsType] -> P [RdrNameHsTyVar]
115 checkTyVars tvs = mapP chk tvs
116                 where
117                   chk (HsKindSig (HsTyVar tv) k) = returnP (IfaceTyVar tv k)
118                   chk (HsTyVar tv)               = returnP (UserTyVar tv)
119                   chk other                      = parseError "Type found where type variable expected"
120
121 checkTyClHdr :: RdrNameHsType -> P (RdrName, [RdrNameHsTyVar])
122 -- The header of a type or class decl should look like
123 --      (C a, D b) => T a b
124 -- or   T a b
125 -- or   a + b
126 -- etc
127 checkTyClHdr ty
128   = go ty []
129   where
130     go (HsTyVar tc) acc 
131         | not (isRdrTyVar tc) = checkTyVars acc         `thenP` \ tvs ->
132                                 returnP (tc, tvs)
133     go (HsOpTy t1 (HsTyOp tc) t2) acc  = checkTyVars (t1:t2:acc)        `thenP` \ tvs ->
134                                          returnP (tc, tvs)
135     go (HsAppTy t1 t2) acc    = go t1 (t2:acc)
136     go other           acc    = parseError "Malformed LHS to type of class declaration"
137
138 checkContext :: RdrNameHsType -> P RdrNameContext
139 checkContext (HsTupleTy _ ts)   -- (Eq a, Ord b) shows up as a tuple type
140   = mapP checkPred ts
141
142 checkContext (HsTyVar t)        -- Empty context shows up as a unit type ()
143   | t == unitTyCon_RDR = returnP []
144
145 checkContext t 
146   = checkPred t `thenP` \p ->
147     returnP [p]
148
149 checkPred :: RdrNameHsType -> P (HsPred RdrName)
150 -- Watch out.. in ...deriving( Show )... we use checkPred on 
151 -- the list of partially applied predicates in the deriving,
152 -- so there can be zero args.
153 checkPred (HsPredTy (HsIParam n ty)) = returnP (HsIParam n ty)
154 checkPred ty
155   = go ty []
156   where
157     go (HsTyVar t) args   | not (isRdrTyVar t) 
158                           = returnP (HsClassP t args)
159     go (HsAppTy l r) args = go l (r:args)
160     go _             _    = parseError "Illegal class assertion"
161
162 checkDictTy :: RdrNameHsType -> [RdrNameHsType] -> P RdrNameHsType
163 checkDictTy (HsTyVar t) args@(_:_) | not (isRdrTyVar t) 
164         = returnP (mkHsDictTy t args)
165 checkDictTy (HsAppTy l r) args = checkDictTy l (r:args)
166 checkDictTy _ _ = parseError "Malformed context in instance header"
167
168
169 ---------------------------------------------------------------------------
170 -- Checking statements in a do-expression
171 --      We parse   do { e1 ; e2 ; }
172 --      as [ExprStmt e1, ExprStmt e2]
173 -- checkDo (a) checks that the last thing is an ExprStmt
174 --         (b) transforms it to a ResultStmt
175
176 checkDo []               = parseError "Empty 'do' construct"
177 checkDo [ExprStmt e _ l] = returnP [ResultStmt e l]
178 checkDo [s]              = parseError "The last statement in a 'do' construct must be an expression"
179 checkDo (s:ss)           = checkDo ss   `thenP` \ ss' ->
180                            returnP (s:ss')
181
182 ---------------------------------------------------------------------------
183 -- Checking Patterns.
184
185 -- We parse patterns as expressions and check for valid patterns below,
186 -- converting the expression into a pattern at the same time.
187
188 checkPattern :: SrcLoc -> RdrNameHsExpr -> P RdrNamePat
189 checkPattern loc e = setSrcLocP loc (checkPat e [])
190
191 checkPatterns :: SrcLoc -> [RdrNameHsExpr] -> P [RdrNamePat]
192 checkPatterns loc es = mapP (checkPattern loc) es
193
194 checkPat :: RdrNameHsExpr -> [RdrNamePat] -> P RdrNamePat
195 checkPat (HsVar c) args | isRdrDataCon c = returnP (ConPatIn c args)
196 checkPat (HsApp f x) args = 
197         checkPat x [] `thenP` \x ->
198         checkPat f (x:args)
199 checkPat e [] = case e of
200         EWildPat           -> returnP WildPatIn
201         HsVar x            -> returnP (VarPatIn x)
202         HsLit l            -> returnP (LitPatIn l)
203         HsOverLit l        -> returnP (NPatIn l)
204         ELazyPat e         -> checkPat e [] `thenP` (returnP . LazyPatIn)
205         EAsPat n e         -> checkPat e [] `thenP` (returnP . AsPatIn n)
206         ExprWithTySig e t  -> checkPat e [] `thenP` \e ->
207                               -- Pattern signatures are parsed as sigtypes,
208                               -- but they aren't explicit forall points.  Hence
209                               -- we have to remove the implicit forall here.
210                               let t' = case t of 
211                                           HsForAllTy Nothing [] ty -> ty
212                                           other -> other
213                               in
214                               returnP (SigPatIn e t')
215
216         -- translate out NegApps of literals in patterns.
217         -- NB. negative primitive literals are already handled by
218         -- RdrHsSyn.mkHsNegApp
219         NegApp (HsOverLit (HsIntegral i n)) _
220                 -> returnP (NPatIn (HsIntegral (-i) n))
221         NegApp (HsOverLit (HsFractional f n)) _
222                 -> returnP (NPatIn (HsFractional (-f) n))
223
224         OpApp (HsVar n) (HsVar plus) _ (HsOverLit lit@(HsIntegral _ _)) 
225                            | plus == plus_RDR
226                            -> returnP (mkNPlusKPat n lit)
227                            where
228                               plus_RDR = mkUnqual varName FSLIT("+")    -- Hack
229
230         OpApp l op fix r   -> checkPat l [] `thenP` \l ->
231                               checkPat r [] `thenP` \r ->
232                               case op of
233                                  HsVar c | isDataOcc (rdrNameOcc c)
234                                         -> returnP (ConOpPatIn l c fix r)
235                                  _ -> patFail
236
237         HsPar e            -> checkPat e [] `thenP` (returnP . ParPatIn)
238         ExplicitList _ es  -> mapP (\e -> checkPat e []) es `thenP` \ps ->
239                               returnP (ListPatIn ps)
240         ExplicitPArr _ es  -> mapP (\e -> checkPat e []) es `thenP` \ps ->
241                               returnP (PArrPatIn ps)
242
243         ExplicitTuple es b -> mapP (\e -> checkPat e []) es `thenP` \ps ->
244                               returnP (TuplePatIn ps b)
245
246         RecordCon c fs     -> mapP checkPatField fs `thenP` \fs ->
247                               returnP (RecPatIn c fs)
248 -- Generics 
249         HsType ty          -> returnP (TypePatIn ty) 
250         _ -> patFail
251
252 checkPat _ _ = patFail
253
254 checkPatField :: (RdrName, RdrNameHsExpr, Bool) 
255         -> P (RdrName, RdrNamePat, Bool)
256 checkPatField (n,e,b) =
257         checkPat e [] `thenP` \p ->
258         returnP (n,p,b)
259
260 patFail = parseError "Parse error in pattern"
261
262
263 ---------------------------------------------------------------------------
264 -- Check Equation Syntax
265
266 checkValDef 
267         :: RdrNameHsExpr
268         -> Maybe RdrNameHsType
269         -> RdrNameGRHSs
270         -> SrcLoc
271         -> P RdrBinding
272
273 checkValDef lhs opt_sig grhss loc
274  = case isFunLhs lhs [] of
275            Just (f,inf,es) -> 
276                 checkPatterns loc es `thenP` \ps ->
277                 returnP (RdrValBinding (FunMonoBind f inf [Match ps opt_sig grhss] loc))
278
279            Nothing ->
280                 checkPattern loc lhs `thenP` \lhs ->
281                 returnP (RdrValBinding (PatMonoBind lhs grhss loc))
282
283 checkValSig
284         :: RdrNameHsExpr
285         -> RdrNameHsType
286         -> SrcLoc
287         -> P RdrBinding
288 checkValSig (HsVar v) ty loc = returnP (RdrSig (Sig v ty loc))
289 checkValSig other     ty loc = parseError "Type signature given for an expression"
290
291
292 -- A variable binding is parsed as an RdrNameFunMonoBind.
293 -- See comments with HsBinds.MonoBinds
294
295 isFunLhs :: RdrNameHsExpr -> [RdrNameHsExpr] -> Maybe (RdrName, Bool, [RdrNameHsExpr])
296 isFunLhs (OpApp l (HsVar op) fix r) es  | not (isRdrDataCon op)
297                                 = Just (op, True, (l:r:es))
298                                         | otherwise
299                                 = case isFunLhs l es of
300                                     Just (op', True, j : k : es') ->
301                                       Just (op', True, j : OpApp k (HsVar op) fix r : es')
302                                     _ -> Nothing
303 isFunLhs (HsVar f) es | not (isRdrDataCon f)
304                                 = Just (f,False,es)
305 isFunLhs (HsApp f e) es         = isFunLhs f (e:es)
306 isFunLhs (HsPar e)   es@(_:_)   = isFunLhs e es
307 isFunLhs _ _                    = Nothing
308
309 ---------------------------------------------------------------------------
310 -- Miscellaneous utilities
311
312 checkPrec :: Integer -> P ()
313 checkPrec i | 0 <= i && i <= 9 = returnP ()
314             | otherwise        = parseError "Precedence out of range"
315
316 mkRecConstrOrUpdate 
317         :: RdrNameHsExpr 
318         -> RdrNameHsRecordBinds
319         -> P RdrNameHsExpr
320
321 mkRecConstrOrUpdate (HsVar c) fs | isRdrDataCon c
322   = returnP (RecordCon c fs)
323 mkRecConstrOrUpdate exp fs@(_:_) 
324   = returnP (RecordUpd exp fs)
325 mkRecConstrOrUpdate _ _
326   = parseError "Empty record update"
327
328 -----------------------------------------------------------------------------
329 -- utilities for foreign declarations
330
331 -- supported calling conventions
332 --
333 data CallConv = CCall  CCallConv        -- ccall or stdcall
334               | DNCall                  -- .NET
335
336 -- construct a foreign import declaration
337 --
338 mkImport :: CallConv 
339          -> Safety 
340          -> (FastString, RdrName, RdrNameHsType) 
341          -> SrcLoc 
342          -> P RdrNameHsDecl
343 mkImport (CCall  cconv) safety (entity, v, ty) loc =
344   parseCImport entity cconv safety v                     `thenP` \importSpec ->
345   returnP $ ForD (ForeignImport v ty importSpec                     False loc)
346 mkImport (DNCall      ) _      (entity, v, ty) loc =
347   returnP $ ForD (ForeignImport v ty (DNImport (DNCallSpec entity)) False loc)
348
349 -- parse the entity string of a foreign import declaration for the `ccall' or
350 -- `stdcall' calling convention'
351 --
352 parseCImport :: FastString 
353              -> CCallConv 
354              -> Safety 
355              -> RdrName 
356              -> P ForeignImport
357 parseCImport entity cconv safety v
358   -- FIXME: we should allow white space around `dynamic' and `wrapper' -=chak
359   | entity == FSLIT ("dynamic") = 
360     returnP $ CImport cconv safety nilFS nilFS (CFunction DynamicTarget)
361   | entity == FSLIT ("wrapper") =
362     returnP $ CImport cconv safety nilFS nilFS CWrapper
363   | otherwise                  = parse0 (unpackFS entity)
364     where
365       -- using the static keyword?
366       parse0 (' ':                    rest) = parse0 rest
367       parse0 ('s':'t':'a':'t':'i':'c':rest) = parse1 rest
368       parse0                          rest  = parse1 rest
369       -- check for header file name
370       parse1     ""               = parse4 ""    nilFS        False nilFS
371       parse1     (' ':rest)       = parse1 rest
372       parse1 str@('&':_   )       = parse2 str   nilFS
373       parse1 str@('[':_   )       = parse3 str   nilFS        False
374       parse1 str
375         | ".h" `isSuffixOf` first = parse2 rest  (mkFastString first)
376         | otherwise               = parse4 str   nilFS        False nilFS
377         where
378           (first, rest) = break (\c -> c == ' ' || c == '&' || c == '[') str
379       -- check for address operator (indicating a label import)
380       parse2     ""         header = parse4 ""   header False nilFS
381       parse2     (' ':rest) header = parse2 rest header
382       parse2     ('&':rest) header = parse3 rest header True
383       parse2 str@('[':_   ) header = parse3 str  header False
384       parse2 str            header = parse4 str  header False nilFS
385       -- check for library object name
386       parse3 (' ':rest) header isLbl = parse3 rest header isLbl
387       parse3 ('[':rest) header isLbl = 
388         case break (== ']') rest of 
389           (lib, ']':rest)           -> parse4 rest header isLbl (mkFastString lib)
390           _                         -> parseError "Missing ']' in entity"
391       parse3 str        header isLbl = parse4 str  header isLbl nilFS
392       -- check for name of C function
393       parse4 ""         header isLbl lib = build (mkExtName v) header isLbl lib
394       parse4 (' ':rest) header isLbl lib = parse4 rest         header isLbl lib
395       parse4 str        header isLbl lib
396         | all (== ' ') rest              = build (mkFastString first)  header isLbl lib
397         | otherwise                      = parseError "Malformed entity string"
398         where
399           (first, rest) = break (== ' ') str
400       --
401       build cid header False lib = returnP $
402         CImport cconv safety header lib (CFunction (StaticTarget cid))
403       build cid header True  lib = returnP $
404         CImport cconv safety header lib (CLabel                  cid )
405
406 -- construct a foreign export declaration
407 --
408 mkExport :: CallConv
409          -> (FastString, RdrName, RdrNameHsType) 
410          -> SrcLoc 
411          -> P RdrNameHsDecl
412 mkExport (CCall  cconv) (entity, v, ty) loc = returnP $ 
413   ForD (ForeignExport v ty (CExport (CExportStatic entity' cconv)) False loc)
414   where
415     entity' | nullFastString entity = mkExtName v
416             | otherwise             = entity
417 mkExport DNCall (entity, v, ty) loc =
418   parseError "Foreign export is not yet supported for .NET"
419
420 -- Supplying the ext_name in a foreign decl is optional; if it
421 -- isn't there, the Haskell name is assumed. Note that no transformation
422 -- of the Haskell name is then performed, so if you foreign export (++),
423 -- it's external name will be "++". Too bad; it's important because we don't
424 -- want z-encoding (e.g. names with z's in them shouldn't be doubled)
425 -- (This is why we use occNameUserString.)
426 --
427 mkExtName :: RdrName -> CLabelString
428 mkExtName rdrNm = mkFastString (occNameUserString (rdrNameOcc rdrNm))
429
430 -----------------------------------------------------------------------------
431 -- group function bindings into equation groups
432
433 -- we assume the bindings are coming in reverse order, so we take the srcloc
434 -- from the *last* binding in the group as the srcloc for the whole group.
435
436 groupBindings :: [RdrBinding] -> RdrBinding
437 groupBindings binds = group Nothing binds
438   where group :: Maybe RdrNameMonoBinds -> [RdrBinding] -> RdrBinding
439         group (Just bind) [] = RdrValBinding bind
440         group Nothing [] = RdrNullBind
441
442                 -- don't group together FunMonoBinds if they have
443                 -- no arguments.  This is necessary now that variable bindings
444                 -- with no arguments are now treated as FunMonoBinds rather
445                 -- than pattern bindings (tests/rename/should_fail/rnfail002).
446         group (Just (FunMonoBind f inf1 mtchs ignore_srcloc))
447                     (RdrValBinding (FunMonoBind f' _ 
448                                         [mtch@(Match (_:_) _ _)] loc)
449                         : binds)
450             | f == f' = group (Just (FunMonoBind f inf1 (mtch:mtchs) loc)) binds
451
452         group (Just so_far) binds
453             = RdrValBinding so_far `RdrAndBindings` group Nothing binds
454         group Nothing (bind:binds)
455             = case bind of
456                 RdrValBinding b@(FunMonoBind _ _ _ _) -> group (Just b) binds
457                 other -> bind `RdrAndBindings` group Nothing binds
458
459 -- ---------------------------------------------------------------------------
460 -- Make the export list for an interface
461
462 mkIfaceExports :: [RdrNameTyClDecl] -> [RdrAvailInfo]
463 mkIfaceExports decls = map getExport decls
464   where getExport d = case d of
465                         TyData{}    -> tc_export
466                         ClassDecl{} -> tc_export
467                         _other      -> var_export
468           where 
469                 tc_export  = AvailTC (rdrNameOcc (tcdName d)) 
470                                 (map (rdrNameOcc.fst) (tyClDeclNames d))
471                 var_export = Avail (rdrNameOcc (tcdName d))
472 \end{code}