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