[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / compiler / hsSyn / HsExpr.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[HsExpr]{Abstract Haskell syntax: expressions}
5
6 \begin{code}
7 module HsExpr where
8
9 #include "HsVersions.h"
10
11 -- friends:
12 import {-# SOURCE #-} HsMatches ( pprMatches, pprMatch, Match )
13
14 import HsBinds          ( HsBinds )
15 import HsBasic          ( HsLit )
16 import BasicTypes       ( Fixity(..), FixityDirection(..) )
17 import HsTypes          ( HsType )
18
19 -- others:
20 import Name             ( Name, NamedThing(..), isLexSym, occNameString )
21 import Outputable       
22 import PprType          ( pprType, pprParendType )
23 import Type             ( GenType )
24 import Var              ( GenTyVar, Id )
25 import DataCon          ( DataCon )
26 import SrcLoc           ( SrcLoc )
27 \end{code}
28
29 %************************************************************************
30 %*                                                                      *
31 \subsection{Expressions proper}
32 %*                                                                      *
33 %************************************************************************
34
35 \begin{code}
36 data HsExpr flexi id pat
37   = HsVar       id                              -- variable
38   | HsLit       HsLit                           -- literal
39   | HsLitOut    HsLit                           -- TRANSLATION
40                 (GenType flexi)         -- (with its type)
41
42   | HsLam       (Match  flexi id pat)   -- lambda
43   | HsApp       (HsExpr flexi id pat)   -- application
44                 (HsExpr flexi id pat)
45
46   -- Operator applications:
47   -- NB Bracketed ops such as (+) come out as Vars.
48
49   -- NB We need an expr for the operator in an OpApp/Section since
50   -- the typechecker may need to apply the operator to a few types.
51
52   | OpApp       (HsExpr flexi id pat)   -- left operand
53                 (HsExpr flexi id pat)   -- operator
54                 Fixity                          -- Renamer adds fixity; bottom until then
55                 (HsExpr flexi id pat)   -- right operand
56
57   -- We preserve prefix negation and parenthesis for the precedence parser.
58   -- They are eventually removed by the type checker.
59
60   | NegApp      (HsExpr flexi id pat)   -- negated expr
61                 (HsExpr flexi id pat)   -- the negate id (in a HsVar)
62
63   | HsPar       (HsExpr flexi id pat)   -- parenthesised expr
64
65   | SectionL    (HsExpr flexi id pat)   -- operand
66                 (HsExpr flexi id pat)   -- operator
67   | SectionR    (HsExpr flexi id pat)   -- operator
68                 (HsExpr flexi id pat)   -- operand
69                                 
70   | HsCase      (HsExpr flexi id pat)
71                 [Match  flexi id pat]   -- must have at least one Match
72                 SrcLoc
73
74   | HsIf        (HsExpr flexi id pat)   --  predicate
75                 (HsExpr flexi id pat)   --  then part
76                 (HsExpr flexi id pat)   --  else part
77                 SrcLoc
78
79   | HsLet       (HsBinds flexi id pat)  -- let(rec)
80                 (HsExpr  flexi id pat)
81
82   | HsDo        StmtCtxt
83                 [Stmt flexi id pat]     -- "do":one or more stmts
84                 SrcLoc
85
86   | HsDoOut     StmtCtxt
87                 [Stmt   flexi id pat]   -- "do":one or more stmts
88                 id                              -- id for return
89                 id                              -- id for >>=
90                 id                              -- id for zero
91                 (GenType flexi)         -- Type of the whole expression
92                 SrcLoc
93
94   | ExplicitList                -- syntactic list
95                 [HsExpr flexi id pat]
96   | ExplicitListOut             -- TRANSLATION
97                 (GenType flexi) -- Gives type of components of list
98                 [HsExpr flexi id pat]
99
100   | ExplicitTuple               -- tuple
101                 [HsExpr flexi id pat]
102                                 -- NB: Unit is ExplicitTuple []
103                                 -- for tuples, we can get the types
104                                 -- direct from the components
105                 Bool            -- boxed?
106
107   | HsCon DataCon               -- TRANSLATION; a saturated constructor application
108           [GenType flexi]
109           [HsExpr flexi id pat]
110
111         -- Record construction
112   | RecordCon   id                              -- The constructor
113                 (HsRecordBinds flexi id pat)
114
115   | RecordConOut DataCon
116                 (HsExpr flexi id pat)           -- Data con Id applied to type args
117                 (HsRecordBinds flexi id pat)
118
119
120         -- Record update
121   | RecordUpd   (HsExpr flexi id pat)
122                 (HsRecordBinds flexi id pat)
123
124   | RecordUpdOut (HsExpr flexi id pat)  -- TRANSLATION
125                  (GenType flexi)                -- Type of *result* record (may differ from
126                                                 -- type of input record)
127                  [id]                           -- Dicts needed for construction
128                  (HsRecordBinds flexi id pat)
129
130   | ExprWithTySig               -- signature binding
131                 (HsExpr flexi id pat)
132                 (HsType id)
133   | ArithSeqIn                  -- arithmetic sequence
134                 (ArithSeqInfo flexi id pat)
135   | ArithSeqOut
136                 (HsExpr       flexi id pat) -- (typechecked, of course)
137                 (ArithSeqInfo flexi id pat)
138
139   | CCall       FAST_STRING     -- call into the C world; string is
140                 [HsExpr flexi id pat]   -- the C function; exprs are the
141                                 -- arguments to pass.
142                 Bool            -- True <=> might cause Haskell
143                                 -- garbage-collection (must generate
144                                 -- more paranoid code)
145                 Bool            -- True <=> it's really a "casm"
146                                 -- NOTE: this CCall is the *boxed*
147                                 -- version; the desugarer will convert
148                                 -- it into the unboxed "ccall#".
149                 (GenType flexi) -- The result type; will be *bottom*
150                                 -- until the typechecker gets ahold of it
151
152   | HsSCC       FAST_STRING     -- "set cost centre" (_scc_) annotation
153                 (HsExpr flexi id pat) -- expr whose cost is to be measured
154 \end{code}
155
156 Everything from here on appears only in typechecker output.
157
158 \begin{code}
159   | TyLam                       -- TRANSLATION
160                 [GenTyVar flexi]
161                 (HsExpr flexi id pat)
162   | TyApp                       -- TRANSLATION
163                 (HsExpr  flexi id pat) -- generated by Spec
164                 [GenType flexi]
165
166   -- DictLam and DictApp are "inverses"
167   |  DictLam
168                 [id]
169                 (HsExpr flexi id pat)
170   |  DictApp
171                 (HsExpr flexi id pat)
172                 [id]
173
174 type HsRecordBinds flexi id pat
175   = [(id, HsExpr flexi id pat, Bool)]
176         -- True <=> source code used "punning",
177         -- i.e. {op1, op2} rather than {op1=e1, op2=e2}
178 \end{code}
179
180 A @Dictionary@, unless of length 0 or 1, becomes a tuple.  A
181 @ClassDictLam dictvars methods expr@ is, therefore:
182 \begin{verbatim}
183 \ x -> case x of ( dictvars-and-methods-tuple ) -> expr
184 \end{verbatim}
185
186 \begin{code}
187 instance (NamedThing id, Outputable id, Outputable pat) =>
188                 Outputable (HsExpr flexi id pat) where
189     ppr expr = pprExpr expr
190 \end{code}
191
192 \begin{code}
193 pprExpr :: (NamedThing id, Outputable id, Outputable pat)
194         => HsExpr flexi id pat -> SDoc
195
196 pprExpr e = pprDeeper (ppr_expr e)
197 pprBinds b = pprDeeper (ppr b)
198
199 ppr_expr (HsVar v) = ppr v
200
201 ppr_expr (HsLit    lit)   = ppr lit
202 ppr_expr (HsLitOut lit _) = ppr lit
203
204 ppr_expr (HsLam match)
205   = hsep [char '\\', nest 2 (pprMatch True match)]
206
207 ppr_expr expr@(HsApp e1 e2)
208   = let (fun, args) = collect_args expr [] in
209     (ppr_expr fun) <+> (sep (map ppr_expr args))
210   where
211     collect_args (HsApp fun arg) args = collect_args fun (arg:args)
212     collect_args fun             args = (fun, args)
213
214 ppr_expr (OpApp e1 op fixity e2)
215   = case op of
216       HsVar v -> pp_infixly v
217       _       -> pp_prefixly
218   where
219     pp_e1 = pprParendExpr e1            -- Add parens to make precedence clear
220     pp_e2 = pprParendExpr e2
221
222     pp_prefixly
223       = hang (pprExpr op) 4 (sep [pp_e1, pp_e2])
224
225     pp_infixly v
226       = sep [pp_e1, hsep [pp_v, pp_e2]]
227       where
228         pp_v | isLexSym (occNameString (getOccName v)) = ppr v
229              | otherwise                               = char '`' <> ppr v <> char '`'
230
231 ppr_expr (NegApp e _)
232   = char '-' <+> pprParendExpr e
233
234 ppr_expr (HsPar e) = parens (ppr_expr e)
235
236 ppr_expr (SectionL expr op)
237   = case op of
238       HsVar v -> pp_infixly v
239       _       -> pp_prefixly
240   where
241     pp_expr = pprParendExpr expr
242
243     pp_prefixly = hang (hsep [text " \\ x_ ->", ppr op])
244                        4 (hsep [pp_expr, ptext SLIT("x_ )")])
245     pp_infixly v = parens (sep [pp_expr, ppr v])
246
247 ppr_expr (SectionR op expr)
248   = case op of
249       HsVar v -> pp_infixly v
250       _       -> pp_prefixly
251   where
252     pp_expr = pprParendExpr expr
253
254     pp_prefixly = hang (hsep [text "( \\ x_ ->", ppr op, ptext SLIT("x_")])
255                        4 ((<>) pp_expr rparen)
256     pp_infixly v
257       = parens (sep [ppr v, pp_expr])
258
259 ppr_expr (HsCase expr matches _)
260   = sep [ sep [ptext SLIT("case"), nest 4 (pprExpr expr), ptext SLIT("of")],
261             nest 2 (pprMatches (True, empty) matches) ]
262
263 ppr_expr (HsIf e1 e2 e3 _)
264   = sep [hsep [ptext SLIT("if"), nest 2 (pprExpr e1), ptext SLIT("then")],
265            nest 4 (pprExpr e2),
266            ptext SLIT("else"),
267            nest 4 (pprExpr e3)]
268
269 -- special case: let ... in let ...
270 ppr_expr (HsLet binds expr@(HsLet _ _))
271   = sep [hang (ptext SLIT("let")) 2 (hsep [pprBinds binds, ptext SLIT("in")]),
272          pprExpr expr]
273
274 ppr_expr (HsLet binds expr)
275   = sep [hang (ptext SLIT("let")) 2 (pprBinds binds),
276          hang (ptext SLIT("in"))  2 (ppr expr)]
277
278 ppr_expr (HsDo do_or_list_comp stmts _)            = pprDo do_or_list_comp stmts
279 ppr_expr (HsDoOut do_or_list_comp stmts _ _ _ _ _) = pprDo do_or_list_comp stmts
280
281 ppr_expr (ExplicitList exprs)
282   = brackets (fsep (punctuate comma (map ppr_expr exprs)))
283 ppr_expr (ExplicitListOut ty exprs)
284   = hcat [ brackets (fsep (punctuate comma (map ppr_expr exprs))),
285            ifNotPprForUser ((<>) space (parens (pprType ty))) ]
286
287 ppr_expr (ExplicitTuple exprs True)
288   = parens (sep (punctuate comma (map ppr_expr exprs)))
289
290 ppr_expr (ExplicitTuple exprs False)
291   = ptext SLIT("(#") <> sep (punctuate comma (map ppr_expr exprs)) <> ptext SLIT("#)")
292
293 ppr_expr (HsCon con_id tys args)
294   = ppr con_id <+> sep (map pprParendType tys ++
295                         map pprParendExpr args)
296
297 ppr_expr (RecordCon con_id rbinds)
298   = pp_rbinds (ppr con_id) rbinds
299 ppr_expr (RecordConOut data_con con rbinds)
300   = pp_rbinds (ppr con) rbinds
301
302 ppr_expr (RecordUpd aexp rbinds)
303   = pp_rbinds (pprParendExpr aexp) rbinds
304 ppr_expr (RecordUpdOut aexp _ _ rbinds)
305   = pp_rbinds (pprParendExpr aexp) rbinds
306
307 ppr_expr (ExprWithTySig expr sig)
308   = hang (nest 2 (ppr_expr expr) <+> ptext SLIT("::"))
309          4 (ppr sig)
310
311 ppr_expr (ArithSeqIn info)
312   = brackets (ppr info)
313 ppr_expr (ArithSeqOut expr info)
314   = brackets (ppr info)
315
316 ppr_expr (CCall fun args _ is_asm result_ty)
317   = hang (if is_asm
318           then ptext SLIT("_casm_ ``") <> ptext fun <> ptext SLIT("''")
319           else ptext SLIT("_ccall_") <+> ptext fun)
320        4 (sep (map pprParendExpr args))
321
322 ppr_expr (HsSCC label expr)
323   = sep [ ptext SLIT("_scc_") <+> doubleQuotes (ptext label), pprParendExpr expr ]
324
325 ppr_expr (TyLam tyvars expr)
326   = hang (hsep [ptext SLIT("/\\"), interppSP tyvars, ptext SLIT("->")])
327          4 (ppr_expr expr)
328
329 ppr_expr (TyApp expr [ty])
330   = hang (ppr_expr expr) 4 (pprParendType ty)
331
332 ppr_expr (TyApp expr tys)
333   = hang (ppr_expr expr)
334          4 (brackets (interpp'SP tys))
335
336 ppr_expr (DictLam dictvars expr)
337   = hang (hsep [ptext SLIT("\\{-dict-}"), interppSP dictvars, ptext SLIT("->")])
338          4 (ppr_expr expr)
339
340 ppr_expr (DictApp expr [dname])
341   = hang (ppr_expr expr) 4 (ppr dname)
342
343 ppr_expr (DictApp expr dnames)
344   = hang (ppr_expr expr)
345          4 (brackets (interpp'SP dnames))
346
347 \end{code}
348
349 Parenthesize unless very simple:
350 \begin{code}
351 pprParendExpr :: (NamedThing id, Outputable id, Outputable pat)
352               => HsExpr flexi id pat -> SDoc
353
354 pprParendExpr expr
355   = let
356         pp_as_was = pprExpr expr
357     in
358     case expr of
359       HsLit l               -> ppr l
360       HsLitOut l _          -> ppr l
361
362       HsVar _               -> pp_as_was
363       ExplicitList _        -> pp_as_was
364       ExplicitListOut _ _   -> pp_as_was
365       ExplicitTuple _ _     -> pp_as_was
366       HsPar _               -> pp_as_was
367
368       _                     -> parens pp_as_was
369 \end{code}
370
371 %************************************************************************
372 %*                                                                      *
373 \subsection{Record binds}
374 %*                                                                      *
375 %************************************************************************
376
377 \begin{code}
378 pp_rbinds :: (NamedThing id, Outputable id, Outputable pat)
379               => SDoc 
380               -> HsRecordBinds flexi id pat -> SDoc
381
382 pp_rbinds thing rbinds
383   = hang thing 
384          4 (braces (hsep (punctuate comma (map (pp_rbind) rbinds))))
385   where
386     pp_rbind (v, e, pun_flag) 
387       = getPprStyle $ \ sty ->
388         if pun_flag && userStyle sty then
389            ppr v
390         else
391            hsep [ppr v, char '=', ppr e]
392 \end{code}
393
394 %************************************************************************
395 %*                                                                      *
396 \subsection{Do stmts and list comprehensions}
397 %*                                                                      *
398 %************************************************************************
399
400 \begin{code}
401 data StmtCtxt   -- Context of a Stmt
402   = DoStmt              -- Do Statment
403   | ListComp            -- List comprehension
404   | CaseAlt             -- Guard on a case alternative
405   | PatBindRhs          -- Guard on a pattern binding
406   | FunRhs Name         -- Guard on a function defn for f
407   | LambdaBody          -- Body of a lambda abstraction
408                 
409 pprDo DoStmt stmts
410   = hang (ptext SLIT("do")) 2 (vcat (map ppr stmts))
411 pprDo ListComp stmts
412   = brackets $
413     hang (pprExpr expr <+> char '|')
414        4 (interpp'SP quals)
415   where
416     ReturnStmt expr = last stmts        -- Last stmt should be a ReturnStmt for list comps
417     quals           = init stmts
418 \end{code}
419
420 \begin{code}
421 data Stmt flexi id pat
422   = BindStmt    pat
423                 (HsExpr  flexi id pat)
424                 SrcLoc
425
426   | LetStmt     (HsBinds flexi id pat)
427
428   | GuardStmt   (HsExpr  flexi id pat)          -- List comps only
429                 SrcLoc
430
431   | ExprStmt    (HsExpr  flexi id pat)          -- Do stmts; and guarded things at the end
432                 SrcLoc
433
434   | ReturnStmt  (HsExpr  flexi id pat)          -- List comps only, at the end
435 \end{code}
436
437 \begin{code}
438 instance (NamedThing id, Outputable id, Outputable pat) =>
439                 Outputable (Stmt flexi id pat) where
440     ppr stmt = pprStmt stmt
441
442 pprStmt (BindStmt pat expr _)
443  = hsep [ppr pat, ptext SLIT("<-"), ppr expr]
444 pprStmt (LetStmt binds)
445  = hsep [ptext SLIT("let"), pprBinds binds]
446 pprStmt (ExprStmt expr _)
447  = ppr expr
448 pprStmt (GuardStmt expr _)
449  = ppr expr
450 pprStmt (ReturnStmt expr)
451  = hsep [ptext SLIT("return"), ppr expr]    
452 \end{code}
453
454 %************************************************************************
455 %*                                                                      *
456 \subsection{Enumerations and list comprehensions}
457 %*                                                                      *
458 %************************************************************************
459
460 \begin{code}
461 data ArithSeqInfo  flexi id pat
462   = From            (HsExpr flexi id pat)
463   | FromThen        (HsExpr flexi id pat)
464                     (HsExpr flexi id pat)
465   | FromTo          (HsExpr flexi id pat)
466                     (HsExpr flexi id pat)
467   | FromThenTo      (HsExpr flexi id pat)
468                     (HsExpr flexi id pat)
469                     (HsExpr flexi id pat)
470 \end{code}
471
472 \begin{code}
473 instance (NamedThing id, Outputable id, Outputable pat) =>
474                 Outputable (ArithSeqInfo flexi id pat) where
475     ppr (From e1)               = hcat [ppr e1, pp_dotdot]
476     ppr (FromThen e1 e2)        = hcat [ppr e1, comma, space, ppr e2, pp_dotdot]
477     ppr (FromTo e1 e3)  = hcat [ppr e1, pp_dotdot, ppr e3]
478     ppr (FromThenTo e1 e2 e3)
479       = hcat [ppr e1, comma, space, ppr e2, pp_dotdot, ppr e3]
480
481 pp_dotdot = ptext SLIT(" .. ")
482 \end{code}