[project @ 2000-04-20 10:56:05 by simonpj]
[ghc-hetmet.git] / ghc / compiler / deSugar / DsExpr.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[DsExpr]{Matching expressions (Exprs)}
5
6 \begin{code}
7 module DsExpr ( dsExpr, dsLet ) where
8
9 #include "HsVersions.h"
10
11
12 import HsSyn            ( failureFreePat,
13                           HsExpr(..), OutPat(..), HsLit(..), ArithSeqInfo(..),
14                           Stmt(..), StmtCtxt(..), Match(..), HsBinds(..), MonoBinds(..), 
15                           mkSimpleMatch
16                         )
17 import TcHsSyn          ( TypecheckedHsExpr, TypecheckedHsBinds,
18                           TypecheckedStmt
19                         )
20 import CoreSyn
21 import PprCore          ( {- instance Outputable Expr -} )
22 import CoreUtils        ( exprType, mkIfThenElse, bindNonRec )
23
24 import DsMonad
25 import DsBinds          ( dsMonoBinds, AutoScc(..) )
26 import DsGRHSs          ( dsGuarded )
27 import DsCCall          ( dsCCall, resultWrapper )
28 import DsListComp       ( dsListComp )
29 import DsUtils          ( mkErrorAppDs, mkDsLets, mkConsExpr, mkNilExpr )
30 import Match            ( matchWrapper, matchSimply )
31
32 import CostCentre       ( mkUserCC )
33 import FieldLabel       ( FieldLabel )
34 import Id               ( Id, idType, recordSelectorFieldLabel )
35 import DataCon          ( DataCon, dataConWrapId, dataConTyCon, dataConArgTys, dataConFieldLabels )
36 import PrelInfo         ( rEC_CON_ERROR_ID, rEC_UPD_ERROR_ID, iRREFUT_PAT_ERROR_ID, addr2IntegerId )
37 import TyCon            ( isNewTyCon )
38 import DataCon          ( isExistentialDataCon )
39 import Literal          ( Literal(..), inIntRange )
40 import Type             ( splitFunTys, mkTyConApp,
41                           splitAlgTyConApp, splitAlgTyConApp_maybe, splitTyConApp_maybe, 
42                           isNotUsgTy, unUsgTy,
43                           splitAppTy, isUnLiftedType, Type
44                         )
45 import TysWiredIn       ( tupleCon, unboxedTupleCon,
46                           listTyCon, mkListTy,
47                           charDataCon, charTy, stringTy,
48                           smallIntegerDataCon, isIntegerTy
49                         )
50 import BasicTypes       ( RecFlag(..) )
51 import Maybes           ( maybeToBool )
52 import Unique           ( Uniquable(..), ratioTyConKey )
53 import Util             ( zipEqual, zipWithEqual )
54 import Outputable
55
56 import Ratio            ( numerator, denominator )
57 \end{code}
58
59
60 %************************************************************************
61 %*                                                                      *
62 \subsection{dsLet}
63 %*                                                                      *
64 %************************************************************************
65
66 @dsLet@ is a match-result transformer, taking the @MatchResult@ for the body
67 and transforming it into one for the let-bindings enclosing the body.
68
69 This may seem a bit odd, but (source) let bindings can contain unboxed
70 binds like
71 \begin{verbatim}
72         C x# = e
73 \end{verbatim}
74 This must be transformed to a case expression and, if the type has
75 more than one constructor, may fail.
76
77 \begin{code}
78 dsLet :: TypecheckedHsBinds -> CoreExpr -> DsM CoreExpr
79
80 dsLet EmptyBinds body
81   = returnDs body
82
83 dsLet (ThenBinds b1 b2) body
84   = dsLet b2 body       `thenDs` \ body' ->
85     dsLet b1 body'
86   
87 -- Special case for bindings which bind unlifted variables
88 -- Silently ignore INLINE pragmas...
89 dsLet (MonoBind (AbsBinds [] [] binder_triples inlines
90                           (PatMonoBind pat grhss loc)) sigs is_rec) body
91   | or [isUnLiftedType (idType g) | (_, g, l) <- binder_triples]
92   = ASSERT (case is_rec of {NonRecursive -> True; other -> False})
93     putSrcLocDs loc                     $
94     dsGuarded grhss                     `thenDs` \ rhs ->
95     let
96         body' = foldr bind body binder_triples
97         bind (tyvars, g, l) body = ASSERT( null tyvars )
98                                    bindNonRec g (Var l) body
99     in
100     mkErrorAppDs iRREFUT_PAT_ERROR_ID result_ty (showSDoc (ppr pat))
101     `thenDs` \ error_expr ->
102     matchSimply rhs PatBindMatch pat body' error_expr
103   where
104     result_ty = exprType body
105
106 -- Ordinary case for bindings
107 dsLet (MonoBind binds sigs is_rec) body
108   = dsMonoBinds NoSccs binds []  `thenDs` \ prs ->
109     case is_rec of
110       Recursive    -> returnDs (Let (Rec prs) body)
111       NonRecursive -> returnDs (mkDsLets [NonRec b r | (b,r) <- prs] body)
112 \end{code}
113
114 %************************************************************************
115 %*                                                                      *
116 \subsection[DsExpr-vars-and-cons]{Variables and constructors}
117 %*                                                                      *
118 %************************************************************************
119
120 \begin{code}
121 dsExpr :: TypecheckedHsExpr -> DsM CoreExpr
122
123 dsExpr e@(HsVar var) = returnDs (Var var)
124 dsExpr e@(HsIPVar var) = returnDs (Var var)
125 \end{code}
126
127 %************************************************************************
128 %*                                                                      *
129 \subsection[DsExpr-literals]{Literals}
130 %*                                                                      *
131 %************************************************************************
132
133 We give int/float literals type @Integer@ and @Rational@, respectively.
134 The typechecker will (presumably) have put \tr{from{Integer,Rational}s}
135 around them.
136
137 ToDo: put in range checks for when converting ``@i@''
138 (or should that be in the typechecker?)
139
140 For numeric literals, we try to detect there use at a standard type
141 (@Int@, @Float@, etc.) are directly put in the right constructor.
142 [NB: down with the @App@ conversion.]
143
144 See also below where we look for @DictApps@ for \tr{plusInt}, etc.
145
146 \begin{code}
147 dsExpr (HsLitOut (HsString s) _)
148   | _NULL_ s
149   = returnDs (mkNilExpr charTy)
150
151   | _LENGTH_ s == 1
152   = let
153         the_char = mkConApp charDataCon [mkLit (MachChar (_HEAD_ s))]
154         the_nil  = mkNilExpr charTy
155         the_cons = mkConsExpr charTy the_char the_nil
156     in
157     returnDs the_cons
158
159
160 -- "_" => build (\ c n -> c 'c' n)      -- LATER
161
162 dsExpr (HsLitOut (HsString str) _)
163   = returnDs (mkStringLitFS str)
164
165 dsExpr (HsLitOut (HsLitLit str) ty)
166   = ASSERT( maybeToBool maybe_ty )
167     returnDs (wrap_fn (mkLit (MachLitLit str rep_ty)))
168   where
169     (maybe_ty, wrap_fn) = resultWrapper ty
170     Just rep_ty         = maybe_ty
171
172 dsExpr (HsLitOut (HsInt i) ty)
173   = returnDs (mkIntegerLit i)
174
175
176 dsExpr (HsLitOut (HsFrac r) ty)
177   = returnDs (mkConApp ratio_data_con [Type integer_ty,
178                                        mkIntegerLit (numerator r),
179                                        mkIntegerLit (denominator r)])
180   where
181     (ratio_data_con, integer_ty)
182       = case (splitAlgTyConApp_maybe ty) of
183           Just (tycon, [i_ty], [con])
184             -> ASSERT(isIntegerTy i_ty && getUnique tycon == ratioTyConKey)
185                (con, i_ty)
186
187           _ -> (panic "ratio_data_con", panic "integer_ty")
188
189
190
191 -- others where we know what to do:
192
193 dsExpr (HsLitOut (HsIntPrim i) _) 
194   = returnDs (mkIntLit i)
195
196 dsExpr (HsLitOut (HsFloatPrim f) _)
197   = returnDs (mkLit (MachFloat f))
198
199 dsExpr (HsLitOut (HsDoublePrim d) _)
200   = returnDs (mkLit (MachDouble d))
201     -- ToDo: range checking needed!
202
203 dsExpr (HsLitOut (HsChar c) _)
204   = returnDs ( mkConApp charDataCon [mkLit (MachChar c)] )
205
206 dsExpr (HsLitOut (HsCharPrim c) _)
207   = returnDs (mkLit (MachChar c))
208
209 dsExpr (HsLitOut (HsStringPrim s) _)
210   = returnDs (mkLit (MachStr s))
211
212 -- end of literals magic. --
213
214 dsExpr expr@(HsLam a_Match)
215   = matchWrapper LambdaMatch [a_Match] "lambda" `thenDs` \ (binders, matching_code) ->
216     returnDs (mkLams binders matching_code)
217
218 dsExpr expr@(HsApp fun arg)      
219   = dsExpr fun          `thenDs` \ core_fun ->
220     dsExpr arg          `thenDs` \ core_arg ->
221     returnDs (core_fun `App` core_arg)
222
223 \end{code}
224
225 Operator sections.  At first it looks as if we can convert
226 \begin{verbatim}
227         (expr op)
228 \end{verbatim}
229 to
230 \begin{verbatim}
231         \x -> op expr x
232 \end{verbatim}
233
234 But no!  expr might be a redex, and we can lose laziness badly this
235 way.  Consider
236 \begin{verbatim}
237         map (expr op) xs
238 \end{verbatim}
239 for example.  So we convert instead to
240 \begin{verbatim}
241         let y = expr in \x -> op y x
242 \end{verbatim}
243 If \tr{expr} is actually just a variable, say, then the simplifier
244 will sort it out.
245
246 \begin{code}
247 dsExpr (OpApp e1 op _ e2)
248   = dsExpr op                                           `thenDs` \ core_op ->
249     -- for the type of y, we need the type of op's 2nd argument
250     dsExpr e1                           `thenDs` \ x_core ->
251     dsExpr e2                           `thenDs` \ y_core ->
252     returnDs (mkApps core_op [x_core, y_core])
253     
254 dsExpr (SectionL expr op)
255   = dsExpr op                                           `thenDs` \ core_op ->
256     -- for the type of y, we need the type of op's 2nd argument
257     let
258         (x_ty:y_ty:_, _) = splitFunTys (exprType core_op)
259     in
260     dsExpr expr                         `thenDs` \ x_core ->
261     newSysLocalDs x_ty                  `thenDs` \ x_id ->
262     newSysLocalDs y_ty                  `thenDs` \ y_id ->
263
264     returnDs (bindNonRec x_id x_core $
265               Lam y_id (mkApps core_op [Var x_id, Var y_id]))
266
267 -- dsExpr (SectionR op expr)    -- \ x -> op x expr
268 dsExpr (SectionR op expr)
269   = dsExpr op                   `thenDs` \ core_op ->
270     -- for the type of x, we need the type of op's 2nd argument
271     let
272         (x_ty:y_ty:_, _) = splitFunTys (exprType core_op)
273     in
274     dsExpr expr                         `thenDs` \ y_core ->
275     newSysLocalDs x_ty                  `thenDs` \ x_id ->
276     newSysLocalDs y_ty                  `thenDs` \ y_id ->
277
278     returnDs (bindNonRec y_id y_core $
279               Lam x_id (mkApps core_op [Var x_id, Var y_id]))
280
281 dsExpr (HsCCall lbl args may_gc is_asm result_ty)
282   = mapDs dsExpr args           `thenDs` \ core_args ->
283     dsCCall lbl core_args may_gc is_asm result_ty
284         -- dsCCall does all the unboxification, etc.
285
286 dsExpr (HsSCC cc expr)
287   = dsExpr expr                 `thenDs` \ core_expr ->
288     getModuleDs                 `thenDs` \ mod_name ->
289     returnDs (Note (SCC (mkUserCC cc mod_name)) core_expr)
290
291 -- special case to handle unboxed tuple patterns.
292
293 dsExpr (HsCase discrim matches src_loc)
294  | all ubx_tuple_match matches
295  =  putSrcLocDs src_loc $
296     dsExpr discrim                        `thenDs` \ core_discrim ->
297     matchWrapper CaseMatch matches "case" `thenDs` \ ([discrim_var], matching_code) ->
298     case matching_code of
299         Case (Var x) bndr alts | x == discrim_var -> 
300                 returnDs (Case core_discrim bndr alts)
301         _ -> panic ("dsExpr: tuple pattern:\n" ++ showSDoc (ppr matching_code))
302   where
303     ubx_tuple_match (Match _ [TuplePat ps False{-unboxed-}] _ _) = True
304     ubx_tuple_match _ = False
305
306 dsExpr (HsCase discrim matches src_loc)
307   = putSrcLocDs src_loc $
308     dsExpr discrim                        `thenDs` \ core_discrim ->
309     matchWrapper CaseMatch matches "case" `thenDs` \ ([discrim_var], matching_code) ->
310     returnDs (bindNonRec discrim_var core_discrim matching_code)
311
312 dsExpr (HsLet binds body)
313   = dsExpr body         `thenDs` \ body' ->
314     dsLet binds body'
315
316 dsExpr (HsWith expr binds)
317   = dsExpr expr         `thenDs` \ expr' ->
318     foldlDs dsIPBind expr' binds
319     where
320       dsIPBind body (n, e)
321         = dsExpr e      `thenDs` \ e' ->
322           returnDs (Let (NonRec n e') body)
323
324 dsExpr (HsDoOut do_or_lc stmts return_id then_id fail_id result_ty src_loc)
325   | maybeToBool maybe_list_comp
326   =     -- Special case for list comprehensions
327     putSrcLocDs src_loc $
328     dsListComp stmts elt_ty
329
330   | otherwise
331   = putSrcLocDs src_loc $
332     dsDo do_or_lc stmts return_id then_id fail_id result_ty
333   where
334     maybe_list_comp 
335         = case (do_or_lc, splitTyConApp_maybe result_ty) of
336             (ListComp, Just (tycon, [elt_ty]))
337                   | tycon == listTyCon
338                  -> Just elt_ty
339             other -> Nothing
340         -- We need the ListComp form to use deListComp (rather than the "do" form)
341         -- because the "return" in a do block is a call to "PrelBase.return", and
342         -- not a ReturnStmt.  Only the ListComp form has ReturnStmts
343
344     Just elt_ty = maybe_list_comp
345
346 dsExpr (HsIf guard_expr then_expr else_expr src_loc)
347   = putSrcLocDs src_loc $
348     dsExpr guard_expr   `thenDs` \ core_guard ->
349     dsExpr then_expr    `thenDs` \ core_then ->
350     dsExpr else_expr    `thenDs` \ core_else ->
351     returnDs (mkIfThenElse core_guard core_then core_else)
352 \end{code}
353
354
355 \noindent
356 \underline{\bf Type lambda and application}
357 %              ~~~~~~~~~~~~~~~~~~~~~~~~~~~
358 \begin{code}
359 dsExpr (TyLam tyvars expr)
360   = dsExpr expr `thenDs` \ core_expr ->
361     returnDs (mkLams tyvars core_expr)
362
363 dsExpr (TyApp expr tys)
364   = dsExpr expr         `thenDs` \ core_expr ->
365     returnDs (mkTyApps core_expr tys)
366 \end{code}
367
368
369 \noindent
370 \underline{\bf Various data construction things}
371 %              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
372 \begin{code}
373 dsExpr (ExplicitListOut ty xs)
374   = go xs
375   where
376     list_ty   = mkListTy ty
377
378     go []     = returnDs (mkNilExpr ty)
379     go (x:xs) = dsExpr x                                `thenDs` \ core_x ->
380                 go xs                                   `thenDs` \ core_xs ->
381                 ASSERT( isNotUsgTy ty )
382                 returnDs (mkConsExpr ty core_x core_xs)
383
384 dsExpr (ExplicitTuple expr_list boxed)
385   = mapDs dsExpr expr_list        `thenDs` \ core_exprs  ->
386     returnDs (mkConApp ((if boxed 
387                             then tupleCon 
388                             else unboxedTupleCon) (length expr_list))
389                 (map (Type . unUsgTy . exprType) core_exprs ++ core_exprs))
390                 -- the above unUsgTy is *required* -- KSW 1999-04-07
391
392 dsExpr (ArithSeqOut expr (From from))
393   = dsExpr expr           `thenDs` \ expr2 ->
394     dsExpr from           `thenDs` \ from2 ->
395     returnDs (App expr2 from2)
396
397 dsExpr (ArithSeqOut expr (FromTo from two))
398   = dsExpr expr           `thenDs` \ expr2 ->
399     dsExpr from           `thenDs` \ from2 ->
400     dsExpr two            `thenDs` \ two2 ->
401     returnDs (mkApps expr2 [from2, two2])
402
403 dsExpr (ArithSeqOut expr (FromThen from thn))
404   = dsExpr expr           `thenDs` \ expr2 ->
405     dsExpr from           `thenDs` \ from2 ->
406     dsExpr thn            `thenDs` \ thn2 ->
407     returnDs (mkApps expr2 [from2, thn2])
408
409 dsExpr (ArithSeqOut expr (FromThenTo from thn two))
410   = dsExpr expr           `thenDs` \ expr2 ->
411     dsExpr from           `thenDs` \ from2 ->
412     dsExpr thn            `thenDs` \ thn2 ->
413     dsExpr two            `thenDs` \ two2 ->
414     returnDs (mkApps expr2 [from2, thn2, two2])
415 \end{code}
416
417 \noindent
418 \underline{\bf Record construction and update}
419 %              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
420 For record construction we do this (assuming T has three arguments)
421 \begin{verbatim}
422         T { op2 = e }
423 ==>
424         let err = /\a -> recConErr a 
425         T (recConErr t1 "M.lhs/230/op1") 
426           e 
427           (recConErr t1 "M.lhs/230/op3")
428 \end{verbatim}
429 @recConErr@ then converts its arugment string into a proper message
430 before printing it as
431 \begin{verbatim}
432         M.lhs, line 230: missing field op1 was evaluated
433 \end{verbatim}
434
435 We also handle @C{}@ as valid construction syntax for an unlabelled
436 constructor @C@, setting all of @C@'s fields to bottom.
437
438 \begin{code}
439 dsExpr (RecordConOut data_con con_expr rbinds)
440   = dsExpr con_expr     `thenDs` \ con_expr' ->
441     let
442         (arg_tys, _) = splitFunTys (exprType con_expr')
443
444         mk_arg (arg_ty, lbl)
445           = case [rhs | (sel_id,rhs,_) <- rbinds,
446                         lbl == recordSelectorFieldLabel sel_id] of
447               (rhs:rhss) -> ASSERT( null rhss )
448                             dsExpr rhs
449               []         -> mkErrorAppDs rEC_CON_ERROR_ID arg_ty (showSDoc (ppr lbl))
450         unlabelled_bottom arg_ty = mkErrorAppDs rEC_CON_ERROR_ID arg_ty ""
451
452         labels = dataConFieldLabels data_con
453     in
454
455     (if null labels
456         then mapDs unlabelled_bottom arg_tys
457         else mapDs mk_arg (zipEqual "dsExpr:RecordCon" arg_tys labels))
458         `thenDs` \ con_args ->
459
460     returnDs (mkApps con_expr' con_args)
461 \end{code}
462
463 Record update is a little harder. Suppose we have the decl:
464 \begin{verbatim}
465         data T = T1 {op1, op2, op3 :: Int}
466                | T2 {op4, op2 :: Int}
467                | T3
468 \end{verbatim}
469 Then we translate as follows:
470 \begin{verbatim}
471         r { op2 = e }
472 ===>
473         let op2 = e in
474         case r of
475           T1 op1 _ op3 -> T1 op1 op2 op3
476           T2 op4 _     -> T2 op4 op2
477           other        -> recUpdError "M.lhs/230"
478 \end{verbatim}
479 It's important that we use the constructor Ids for @T1@, @T2@ etc on the
480 RHSs, and do not generate a Core constructor application directly, because the constructor
481 might do some argument-evaluation first; and may have to throw away some
482 dictionaries.
483
484 \begin{code}
485 dsExpr (RecordUpdOut record_expr record_out_ty dicts rbinds)
486   = getSrcLocDs         `thenDs` \ src_loc ->
487     dsExpr record_expr          `thenDs` \ record_expr' ->
488
489         -- Desugar the rbinds, and generate let-bindings if
490         -- necessary so that we don't lose sharing
491
492     let
493         record_in_ty               = exprType record_expr'
494         (tycon, in_inst_tys, cons) = splitAlgTyConApp record_in_ty
495         (_,     out_inst_tys, _)   = splitAlgTyConApp record_out_ty
496         cons_to_upd                = filter has_all_fields cons
497
498         mk_val_arg field old_arg_id 
499           = case [rhs | (sel_id, rhs, _) <- rbinds, 
500                         field == recordSelectorFieldLabel sel_id] of
501               (rhs:rest) -> ASSERT(null rest) rhs
502               []         -> HsVar old_arg_id
503
504         mk_alt con
505           = newSysLocalsDs (dataConArgTys con in_inst_tys)      `thenDs` \ arg_ids ->
506                 -- This call to dataConArgTys won't work for existentials
507             let 
508                 val_args = zipWithEqual "dsExpr:RecordUpd" mk_val_arg
509                                         (dataConFieldLabels con) arg_ids
510                 rhs = foldl HsApp (DictApp (TyApp (HsVar (dataConWrapId con)) 
511                                                   out_inst_tys)
512                                            dicts)
513                                   val_args
514             in
515             returnDs (mkSimpleMatch [ConPat con record_in_ty [] [] (map VarPat arg_ids)]
516                                     rhs
517                                     (Just record_out_ty)
518                                     src_loc)
519     in
520         -- Record stuff doesn't work for existentials
521     ASSERT( all (not . isExistentialDataCon) cons )
522
523         -- It's important to generate the match with matchWrapper,
524         -- and the right hand sides with applications of the wrapper Id
525         -- so that everything works when we are doing fancy unboxing on the
526         -- constructor aguments.
527     mapDs mk_alt cons_to_upd                            `thenDs` \ alts ->
528     matchWrapper RecUpdMatch alts "record update"       `thenDs` \ ([discrim_var], matching_code) ->
529
530     returnDs (bindNonRec discrim_var record_expr' matching_code)
531
532   where
533     has_all_fields :: DataCon -> Bool
534     has_all_fields con_id 
535       = all ok rbinds
536       where
537         con_fields        = dataConFieldLabels con_id
538         ok (sel_id, _, _) = recordSelectorFieldLabel sel_id `elem` con_fields
539 \end{code}
540
541
542 \noindent
543 \underline{\bf Dictionary lambda and application}
544 %              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
545 @DictLam@ and @DictApp@ turn into the regular old things.
546 (OLD:) @DictFunApp@ also becomes a curried application, albeit slightly more
547 complicated; reminiscent of fully-applied constructors.
548 \begin{code}
549 dsExpr (DictLam dictvars expr)
550   = dsExpr expr `thenDs` \ core_expr ->
551     returnDs (mkLams dictvars core_expr)
552
553 ------------------
554
555 dsExpr (DictApp expr dicts)     -- becomes a curried application
556   = dsExpr expr                 `thenDs` \ core_expr ->
557     returnDs (foldl (\f d -> f `App` (Var d)) core_expr dicts)
558 \end{code}
559
560 \begin{code}
561
562 #ifdef DEBUG
563 -- HsSyn constructs that just shouldn't be here:
564 dsExpr (HsDo _ _ _)         = panic "dsExpr:HsDo"
565 dsExpr (ExplicitList _)     = panic "dsExpr:ExplicitList"
566 dsExpr (ExprWithTySig _ _)  = panic "dsExpr:ExprWithTySig"
567 dsExpr (ArithSeqIn _)       = panic "dsExpr:ArithSeqIn"
568 #endif
569
570 \end{code}
571
572 %--------------------------------------------------------------------
573
574 Basically does the translation given in the Haskell~1.3 report:
575
576 \begin{code}
577 dsDo    :: StmtCtxt
578         -> [TypecheckedStmt]
579         -> Id           -- id for: return m
580         -> Id           -- id for: (>>=) m
581         -> Id           -- id for: fail m
582         -> Type         -- Element type; the whole expression has type (m t)
583         -> DsM CoreExpr
584
585 dsDo do_or_lc stmts return_id then_id fail_id result_ty
586   = let
587         (_, b_ty) = splitAppTy result_ty        -- result_ty must be of the form (m b)
588         
589         go [ReturnStmt expr] 
590           = dsExpr expr                 `thenDs` \ expr2 ->
591             returnDs (mkApps (Var return_id) [Type b_ty, expr2])
592     
593         go (GuardStmt expr locn : stmts)
594           = do_expr expr locn                   `thenDs` \ expr2 ->
595             go stmts                            `thenDs` \ rest ->
596             let msg = ASSERT( isNotUsgTy b_ty )
597                  "Pattern match failure in do expression, " ++ showSDoc (ppr locn) in
598             returnDs (mkIfThenElse expr2 
599                                    rest 
600                                    (App (App (Var fail_id) 
601                                              (Type b_ty))
602                                              (mkStringLit msg)))
603     
604         go (ExprStmt expr locn : stmts)
605           = do_expr expr locn           `thenDs` \ expr2 ->
606             let
607                 (_, a_ty) = splitAppTy (exprType expr2)  -- Must be of form (m a)
608             in
609             if null stmts then
610                 returnDs expr2
611             else
612                 go stmts                `thenDs` \ rest  ->
613                 newSysLocalDs a_ty              `thenDs` \ ignored_result_id ->
614                 returnDs (mkApps (Var then_id) [Type a_ty, Type b_ty, expr2, 
615                                                 Lam ignored_result_id rest])
616     
617         go (LetStmt binds : stmts )
618           = go stmts            `thenDs` \ rest   ->
619             dsLet binds rest
620             
621         go (BindStmt pat expr locn : stmts)
622           = putSrcLocDs locn $
623             dsExpr expr            `thenDs` \ expr2 ->
624             let
625                 (_, a_ty)  = splitAppTy (exprType expr2) -- Must be of form (m a)
626                 fail_expr  = HsApp (TyApp (HsVar fail_id) [b_ty])
627                                    (HsLitOut (HsString (_PK_ msg)) stringTy)
628                 msg = ASSERT2( isNotUsgTy a_ty, ppr a_ty )
629                       ASSERT2( isNotUsgTy b_ty, ppr b_ty )
630                       "Pattern match failure in do expression, " ++ showSDoc (ppr locn)
631                 main_match = mkSimpleMatch [pat] 
632                                            (HsDoOut do_or_lc stmts return_id then_id
633                                                     fail_id result_ty locn)
634                                            (Just result_ty) locn
635                 the_matches
636                   | failureFreePat pat = [main_match]
637                   | otherwise          =
638                       [ main_match
639                       , mkSimpleMatch [WildPat a_ty] fail_expr (Just result_ty) locn
640                       ]
641             in
642             matchWrapper DoBindMatch the_matches match_msg
643                                 `thenDs` \ (binders, matching_code) ->
644             returnDs (mkApps (Var then_id) [Type a_ty, Type b_ty, expr2,
645                                             mkLams binders matching_code])
646     in
647     go stmts
648
649   where
650     do_expr expr locn = putSrcLocDs locn (dsExpr expr)
651
652     match_msg = case do_or_lc of
653                         DoStmt   -> "`do' statement"
654                         ListComp -> "comprehension"
655 \end{code}
656
657 \begin{code}
658 var_pat (WildPat _) = True
659 var_pat (VarPat _) = True
660 var_pat _ = False
661 \end{code}
662
663 \begin{code}
664 mkIntegerLit :: Integer -> CoreExpr
665 mkIntegerLit i
666   | inIntRange i        -- Small enough, so start from an Int
667   = mkConApp smallIntegerDataCon [mkIntLit i]
668
669   | otherwise           -- Big, so start from a string
670   = App (Var addr2IntegerId) (Lit (MachStr (_PK_ (show i))))
671 \end{code}
672