[project @ 1999-07-05 15:30:25 by simonpj]
[ghc-hetmet.git] / ghc / compiler / deSugar / DsExpr.lhs
index 30c8fb6..a8421fd 100644 (file)
@@ -26,7 +26,7 @@ import DsBinds                ( dsMonoBinds, AutoScc(..) )
 import DsGRHSs         ( dsGuarded )
 import DsCCall         ( dsCCall )
 import DsListComp      ( dsListComp )
-import DsUtils         ( mkErrorAppDs )
+import DsUtils         ( mkErrorAppDs, mkDsLets, mkConsExpr, mkNilExpr )
 import Match           ( matchWrapper, matchSimply )
 
 import CoreUtils       ( coreExprType )
@@ -36,7 +36,7 @@ import Id             ( Id, idType, recordSelectorFieldLabel )
 import Const           ( Con(..) )
 import DataCon         ( DataCon, dataConId, dataConTyCon, dataConArgTys, dataConFieldLabels )
 import Const           ( mkMachInt, Literal(..), mkStrLit )
-import PrelVals                ( rEC_CON_ERROR_ID, rEC_UPD_ERROR_ID, iRREFUT_PAT_ERROR_ID )
+import PrelInfo                ( rEC_CON_ERROR_ID, rEC_UPD_ERROR_ID, iRREFUT_PAT_ERROR_ID )
 import TyCon           ( isNewTyCon )
 import DataCon         ( isExistentialDataCon )
 import Type            ( splitFunTys, mkTyConApp,
@@ -44,7 +44,7 @@ import Type           ( splitFunTys, mkTyConApp,
                          splitAppTy, isUnLiftedType, Type
                        )
 import TysWiredIn      ( tupleCon, unboxedTupleCon,
-                         consDataCon, listTyCon, mkListTy,
+                         listTyCon, mkListTy,
                          charDataCon, charTy, stringTy
                        )
 import BasicTypes      ( RecFlag(..) )
@@ -60,14 +60,14 @@ import Outputable
 %*                                                                     *
 %************************************************************************
 
-@dsLet@ is a match-result transformer, taking the MatchResult for the body
+@dsLet@ is a match-result transformer, taking the @MatchResult@ for the body
 and transforming it into one for the let-bindings enclosing the body.
 
 This may seem a bit odd, but (source) let bindings can contain unboxed
 binds like
-
+\begin{verbatim}
        C x# = e
-
+\end{verbatim}
 This must be transformed to a case expression and, if the type has
 more than one constructor, may fail.
 
@@ -82,7 +82,9 @@ dsLet (ThenBinds b1 b2) body
     dsLet b1 body'
   
 -- Special case for bindings which bind unlifted variables
-dsLet (MonoBind (AbsBinds [] [] binder_triples (PatMonoBind pat grhss loc)) sigs is_rec) body
+-- Silently ignore INLINE pragmas...
+dsLet (MonoBind (AbsBinds [] [] binder_triples inlines
+                          (PatMonoBind pat grhss loc)) sigs is_rec) body
   | or [isUnLiftedType (idType g) | (_, g, l) <- binder_triples]
   = ASSERT (case is_rec of {NonRecursive -> True; other -> False})
     putSrcLocDs loc                    $
@@ -92,7 +94,8 @@ dsLet (MonoBind (AbsBinds [] [] binder_triples (PatMonoBind pat grhss loc)) sigs
        bind (tyvars, g, l) body = ASSERT( null tyvars )
                                   bindNonRec g (Var l) body
     in
-    mkErrorAppDs iRREFUT_PAT_ERROR_ID result_ty (showSDoc (ppr pat))   `thenDs` \ error_expr ->
+    mkErrorAppDs iRREFUT_PAT_ERROR_ID result_ty (showSDoc (ppr pat))
+    `thenDs` \ error_expr ->
     matchSimply rhs PatBindMatch pat body' error_expr
   where
     result_ty = coreExprType body
@@ -102,9 +105,7 @@ dsLet (MonoBind binds sigs is_rec) body
   = dsMonoBinds NoSccs binds []  `thenDs` \ prs ->
     case is_rec of
       Recursive    -> returnDs (Let (Rec prs) body)
-      NonRecursive -> returnDs (foldr mk_let body prs)
-  where
-    mk_let (bndr,rhs) body = Let (NonRec bndr rhs) body
+      NonRecursive -> returnDs (mkDsLets [NonRec b r | (b,r) <- prs] body)
 \end{code}
 
 %************************************************************************
@@ -125,17 +126,17 @@ dsExpr e@(HsVar var) = returnDs (Var var)
 %*                                                                     *
 %************************************************************************
 
-We give int/float literals type Integer and Rational, respectively.
+We give int/float literals type @Integer@ and @Rational@, respectively.
 The typechecker will (presumably) have put \tr{from{Integer,Rational}s}
 around them.
 
-ToDo: put in range checks for when converting "i"
+ToDo: put in range checks for when converting ``@i@''
 (or should that be in the typechecker?)
 
 For numeric literals, we try to detect there use at a standard type
-(Int, Float, etc.) are directly put in the right constructor.
+(@Int@, @Float@, etc.) are directly put in the right constructor.
 [NB: down with the @App@ conversion.]
-Otherwise, we punt, putting in a "NoRep" Core literal (where the
+Otherwise, we punt, putting in a @NoRep@ Core literal (where the
 representation decisions are delayed)...
 
 See also below where we look for @DictApps@ for \tr{plusInt}, etc.
@@ -149,7 +150,7 @@ dsExpr (HsLitOut (HsString s) _)
   = let
        the_char = mkConApp charDataCon [mkLit (MachChar (_HEAD_ s))]
        the_nil  = mkNilExpr charTy
-       the_cons = mkConApp consDataCon [Type charTy, the_char, the_nil]
+       the_cons = mkConsExpr charTy the_char the_nil
     in
     returnDs the_cons
 
@@ -277,9 +278,6 @@ will sort it out.
 dsExpr (OpApp e1 op _ e2)
   = dsExpr op                                          `thenDs` \ core_op ->
     -- for the type of y, we need the type of op's 2nd argument
-    let
-       (x_ty:y_ty:_, _) = splitFunTys (coreExprType core_op)
-    in
     dsExpr e1                          `thenDs` \ x_core ->
     dsExpr e2                          `thenDs` \ y_core ->
     returnDs (mkApps core_op [x_core, y_core])
@@ -326,8 +324,8 @@ dsExpr (HsSCC cc expr)
 dsExpr (HsCase discrim matches@[Match _ [TuplePat ps boxed] _ _] src_loc)
  | not boxed && all var_pat ps 
  =  putSrcLocDs src_loc $
-    dsExpr discrim                             `thenDs` \ core_discrim ->
-    matchWrapper CaseMatch matches "case"      `thenDs` \ ([discrim_var], matching_code) ->
+    dsExpr discrim                       `thenDs` \ core_discrim ->
+    matchWrapper CaseMatch matches "case" `thenDs` \ ([discrim_var], matching_code) ->
     case matching_code of
        Case (Var x) bndr alts | x == discrim_var -> 
                returnDs (Case core_discrim bndr alts)
@@ -335,8 +333,8 @@ dsExpr (HsCase discrim matches@[Match _ [TuplePat ps boxed] _ _] src_loc)
 
 dsExpr (HsCase discrim matches src_loc)
   = putSrcLocDs src_loc $
-    dsExpr discrim                             `thenDs` \ core_discrim ->
-    matchWrapper CaseMatch matches "case"      `thenDs` \ ([discrim_var], matching_code) ->
+    dsExpr discrim                       `thenDs` \ core_discrim ->
+    matchWrapper CaseMatch matches "case" `thenDs` \ ([discrim_var], matching_code) ->
     returnDs (bindNonRec discrim_var core_discrim matching_code)
 
 dsExpr (HsLet binds body)
@@ -374,8 +372,9 @@ dsExpr (HsIf guard_expr then_expr else_expr src_loc)
 \end{code}
 
 
-Type lambda and application
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+\noindent
+\underline{\bf Type lambda and application}
+%              ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 \begin{code}
 dsExpr (TyLam tyvars expr)
   = dsExpr expr `thenDs` \ core_expr ->
@@ -387,8 +386,9 @@ dsExpr (TyApp expr tys)
 \end{code}
 
 
-Various data construction things
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+\noindent
+\underline{\bf Various data construction things}
+%              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 \begin{code}
 dsExpr (ExplicitListOut ty xs)
   = go xs
@@ -399,7 +399,7 @@ dsExpr (ExplicitListOut ty xs)
     go (x:xs) = dsExpr x                               `thenDs` \ core_x ->
                go xs                                   `thenDs` \ core_xs ->
                 ASSERT( isNotUsgTy ty )
-               returnDs (mkConApp consDataCon [Type ty, core_x, core_xs])
+               returnDs (mkConsExpr ty core_x core_xs)
 
 dsExpr (ExplicitTuple expr_list boxed)
   = mapDs dsExpr expr_list       `thenDs` \ core_exprs  ->
@@ -447,22 +447,26 @@ dsExpr (ArithSeqOut expr (FromThenTo from thn two))
     returnDs (mkApps expr2 [from2, thn2, two2])
 \end{code}
 
-Record construction and update
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+\noindent
+\underline{\bf Record construction and update}
+%              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 For record construction we do this (assuming T has three arguments)
-
+\begin{verbatim}
        T { op2 = e }
 ==>
        let err = /\a -> recConErr a 
        T (recConErr t1 "M.lhs/230/op1") 
          e 
          (recConErr t1 "M.lhs/230/op3")
-
-recConErr then converts its arugment string into a proper message
+\end{verbatim}
+@recConErr@ then converts its arugment string into a proper message
 before printing it as
-
+\begin{verbatim}
        M.lhs, line 230: missing field op1 was evaluated
+\end{verbatim}
 
+We also handle @C{}@ as valid construction syntax for an unlabelled
+constructor @C@, setting all of @C@'s fields to bottom.
 
 \begin{code}
 dsExpr (RecordConOut data_con con_expr rbinds)
@@ -476,19 +480,27 @@ dsExpr (RecordConOut data_con con_expr rbinds)
              (rhs:rhss) -> ASSERT( null rhss )
                            dsExpr rhs
              []         -> mkErrorAppDs rEC_CON_ERROR_ID arg_ty (showSDoc (ppr lbl))
+       unlabelled_bottom arg_ty = mkErrorAppDs rEC_CON_ERROR_ID arg_ty ""
+
+       labels = dataConFieldLabels data_con
     in
-    mapDs mk_arg (zipEqual "dsExpr:RecordCon" arg_tys (dataConFieldLabels data_con)) `thenDs` \ con_args ->
+
+    (if null labels
+       then mapDs unlabelled_bottom arg_tys
+       else mapDs mk_arg (zipEqual "dsExpr:RecordCon" arg_tys labels))
+       `thenDs` \ con_args ->
+
     returnDs (mkApps con_expr' con_args)
 \end{code}
 
 Record update is a little harder. Suppose we have the decl:
-
+\begin{verbatim}
        data T = T1 {op1, op2, op3 :: Int}
               | T2 {op4, op2 :: Int}
               | T3
-
+\end{verbatim}
 Then we translate as follows:
-
+\begin{verbatim}
        r { op2 = e }
 ===>
        let op2 = e in
@@ -496,9 +508,9 @@ Then we translate as follows:
          T1 op1 _ op3 -> T1 op1 op2 op3
          T2 op4 _     -> T2 op4 op2
          other        -> recUpdError "M.lhs/230"
-
-It's important that we use the constructor Ids for T1, T2 etc on the
-RHSs, and do not generate a Core Con directly, because the constructor
+\end{verbatim}
+It's important that we use the constructor Ids for @T1@, @T2@ etc on the
+RHSs, and do not generate a Core @Con@ directly, because the constructor
 might do some argument-evaluation first; and may have to throw away some
 dictionaries.
 
@@ -562,8 +574,10 @@ dsExpr (RecordUpdOut record_expr record_out_ty dicts rbinds)
        ok (sel_id, _, _) = recordSelectorFieldLabel sel_id `elem` con_fields
 \end{code}
 
-Dictionary lambda and application
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+\noindent
+\underline{\bf Dictionary lambda and application}
+%              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 @DictLam@ and @DictApp@ turn into the regular old things.
 (OLD:) @DictFunApp@ also becomes a curried application, albeit slightly more
 complicated; reminiscent of fully-applied constructors.
@@ -618,7 +632,7 @@ dsDo do_or_lc stmts return_id then_id fail_id result_ty
          = do_expr expr locn                   `thenDs` \ expr2 ->
            go stmts                            `thenDs` \ rest ->
            let msg = ASSERT( isNotUsgTy b_ty )
-                      "Pattern match failure in do expression, " ++ showSDoc (ppr locn) in
+                 "Pattern match failure in do expression, " ++ showSDoc (ppr locn) in
            returnDs (mkIfThenElse expr2 
                                   rest 
                                   (App (App (Var fail_id) 
@@ -628,7 +642,7 @@ dsDo do_or_lc stmts return_id then_id fail_id result_ty
        go (ExprStmt expr locn : stmts)
          = do_expr expr locn           `thenDs` \ expr2 ->
            let
-               (_, a_ty) = splitAppTy (coreExprType expr2)     -- Must be of form (m a)
+               (_, a_ty) = splitAppTy (coreExprType expr2)  -- Must be of form (m a)
            in
            if null stmts then
                returnDs expr2
@@ -646,13 +660,15 @@ dsDo do_or_lc stmts return_id then_id fail_id result_ty
          = putSrcLocDs locn $
            dsExpr expr            `thenDs` \ expr2 ->
            let
-               (_, a_ty)  = splitAppTy (coreExprType expr2)    -- Must be of form (m a)
-               fail_expr  = HsApp (TyApp (HsVar fail_id) [b_ty]) (HsLitOut (HsString (_PK_ msg)) stringTy)
+               (_, a_ty)  = splitAppTy (coreExprType expr2) -- Must be of form (m a)
+               fail_expr  = HsApp (TyApp (HsVar fail_id) [b_ty])
+                                   (HsLitOut (HsString (_PK_ msg)) stringTy)
                msg = ASSERT2( isNotUsgTy a_ty, ppr a_ty )
                       ASSERT2( isNotUsgTy b_ty, ppr b_ty )
                       "Pattern match failure in do expression, " ++ showSDoc (ppr locn)
                main_match = mkSimpleMatch [pat] 
-                                          (HsDoOut do_or_lc stmts return_id then_id fail_id result_ty locn)
+                                          (HsDoOut do_or_lc stmts return_id then_id
+                                                    fail_id result_ty locn)
                                           (Just result_ty) locn
                the_matches
                  | failureFreePat pat = [main_match]