[project @ 2003-12-10 14:15:16 by simonmar]
[ghc-hetmet.git] / ghc / compiler / deSugar / DsUtils.lhs
index d7b55f5..79e757c 100644 (file)
@@ -12,7 +12,7 @@ module DsUtils (
 
        tidyLitPat, tidyNPat,
 
-       mkDsLet, mkDsLets,
+       mkDsLet,
 
        cantFailMatchResult, extractMatchResult,
        combineMatchResults, 
@@ -26,20 +26,20 @@ module DsUtils (
 
        mkSelectorBinds, mkTupleExpr, mkTupleSelector, 
        mkTupleType, mkTupleCase, mkBigCoreTup,
-       mkCoreTup, mkCoreSel, mkCoreTupTy,
+       mkCoreTup, mkCoreTupTy,
        
        dsReboundNames, lookupReboundName,
 
-       selectMatchVar
+       selectMatchVarL, selectMatchVar
     ) where
 
 #include "HsVersions.h"
 
 import {-# SOURCE #-}  Match ( matchSimply )
-import {-# SOURCE #-}  DsExpr( dsExpr )
+import {-# SOURCE #-}  DsExpr( dsLExpr )
 
 import HsSyn
-import TcHsSyn         ( TypecheckedPat, hsPatType )
+import TcHsSyn         ( hsPatType )
 import CoreSyn
 import Constants       ( mAX_TUPLE_SIZE )
 import DsMonad
@@ -58,18 +58,19 @@ import TysWiredIn   ( nilDataCon, consDataCon,
                           tupleCon, mkTupleTy,
                          unitDataConId, unitTy,
                           charTy, charDataCon, 
-                          intTy, intDataCon, smallIntegerDataCon, 
+                          intTy, intDataCon, 
                          floatDataCon, 
                           doubleDataCon,
                          stringTy, isPArrFakeCon )
 import BasicTypes      ( Boxity(..) )
 import UniqSet         ( mkUniqSet, minusUniqSet, isEmptyUniqSet, UniqSet )
-import UniqSupply      ( splitUniqSupply, uniqFromSupply )
+import UniqSupply      ( splitUniqSupply, uniqFromSupply, uniqsFromSupply )
 import PrelNames       ( unpackCStringName, unpackCStringUtf8Name, 
-                         plusIntegerName, timesIntegerName, 
+                         plusIntegerName, timesIntegerName, smallIntegerDataConName, 
                          lengthPName, indexPName )
 import Outputable
 import UnicodeUtil      ( intsToUtf8, stringToUtf8 )
+import SrcLoc          ( Located(..), unLoc, noLoc )
 import Util             ( isSingleton, notNull, zipEqual )
 import ListSetOps      ( assocDefault )
 import FastString
@@ -94,10 +95,11 @@ dsReboundNames rebound_ids
   where
        -- The cheapo special case can happen when we 
        -- make an intermediate HsDo when desugaring a RecStmt
-    mk_bind (std_name, HsVar id) = return ([], (std_name, id))
-    mk_bind (std_name, expr)    = dsExpr expr                          `thenDs` \ rhs ->
-                                  newSysLocalDs (exprType rhs)         `thenDs` \ id ->
-                                  return ([NonRec id rhs], (std_name, id))
+    mk_bind (std_name, L _ (HsVar id)) = return ([], (std_name, id))
+    mk_bind (std_name, expr)
+        = dsLExpr expr                         `thenDs` \ rhs ->
+          newSysLocalDs (exprType rhs)         `thenDs` \ id ->
+          return ([NonRec id rhs], (std_name, id))
 
 lookupReboundName :: [(Name,Id)] -> Name -> CoreExpr
 lookupReboundName prs std_name
@@ -114,33 +116,33 @@ lookupReboundName prs std_name
 %************************************************************************
 
 \begin{code}
-tidyLitPat :: HsLit -> TypecheckedPat -> TypecheckedPat
+tidyLitPat :: HsLit -> LPat Id -> LPat Id
 tidyLitPat (HsChar c) pat = mkCharLitPat c
-tidyLitPat lit        pat = pat
+tidyLitPat lit       pat = pat
 
-tidyNPat :: HsLit -> Type -> TypecheckedPat -> TypecheckedPat
+tidyNPat :: HsLit -> Type -> LPat Id -> LPat Id
 tidyNPat (HsString s) _ pat
   | lengthFS s <= 1    -- Short string literals only
   = foldr (\c pat -> mkPrefixConPat consDataCon [mkCharLitPat c,pat] stringTy)
-         (mkNilPat stringTy) (unpackIntFS s)
+         (mkNilPat stringTy) (unpackFS s)
        -- The stringTy is the type of the whole pattern, not 
        -- the type to instantiate (:) or [] with!
   where
 
 tidyNPat lit lit_ty default_pat
-  | isIntTy lit_ty             = mkPrefixConPat intDataCon    [LitPat (mk_int lit)]    lit_ty 
-  | isFloatTy lit_ty   = mkPrefixConPat floatDataCon  [LitPat (mk_float lit)]  lit_ty 
-  | isDoubleTy lit_ty  = mkPrefixConPat doubleDataCon [LitPat (mk_double lit)] lit_ty 
+  | isIntTy lit_ty             = mkPrefixConPat intDataCon    [noLoc $ LitPat (mk_int lit)]    lit_ty 
+  | isFloatTy lit_ty   = mkPrefixConPat floatDataCon  [noLoc $ LitPat (mk_float lit)]  lit_ty 
+  | isDoubleTy lit_ty  = mkPrefixConPat doubleDataCon [noLoc $ LitPat (mk_double lit)] lit_ty 
   | otherwise          = default_pat
 
   where
-    mk_int    (HsInteger i) = HsIntPrim i
+    mk_int    (HsInteger i _) = HsIntPrim i
 
-    mk_float  (HsInteger i) = HsFloatPrim (fromInteger i)
-    mk_float  (HsRat f _)   = HsFloatPrim f
+    mk_float  (HsInteger i _) = HsFloatPrim (fromInteger i)
+    mk_float  (HsRat f _)     = HsFloatPrim f
 
-    mk_double (HsInteger i) = HsDoublePrim (fromInteger i)
-    mk_double (HsRat f _)   = HsDoublePrim f
+    mk_double (HsInteger i _) = HsDoublePrim (fromInteger i)
+    mk_double (HsRat f _)     = HsDoublePrim f
 \end{code}
 
 
@@ -177,11 +179,14 @@ hand, which should indeed be bound to the pattern as a whole, then use it;
 otherwise, make one up.
 
 \begin{code}
-selectMatchVar :: TypecheckedPat -> DsM Id
+selectMatchVarL :: LPat Id -> DsM Id
+selectMatchVarL pat = selectMatchVar (unLoc pat)
+
 selectMatchVar (VarPat var)     = returnDs var
-selectMatchVar (AsPat var pat)         = returnDs var
-selectMatchVar (LazyPat pat)           = selectMatchVar pat
-selectMatchVar other_pat               = newSysLocalDs (hsPatType other_pat) -- OK, better make up one...
+selectMatchVar (AsPat var pat)  = returnDs (unLoc var)
+selectMatchVar (LazyPat pat)    = selectMatchVarL pat
+selectMatchVar other_pat        = newSysLocalDs (hsPatType (noLoc other_pat))
+                                -- OK, better make up one...
 \end{code}
 
 
@@ -209,7 +214,7 @@ data EquationInfo
                        -- of the *first* thing matched in this group.
                        -- Should perhaps be a list of them all!
 
-       [TypecheckedPat]    -- The patterns for an eqn
+       [Pat Id]        -- The patterns for an eqn
 
        MatchResult         -- Encapsulates the guards and bindings
 \end{code}
@@ -287,7 +292,7 @@ mkCoPrimCaseMatchResult var match_alts
   = MatchResult CanFail mk_case
   where
     mk_case fail
-      = mapDs (mk_alt fail) match_alts         `thenDs` \ alts ->
+      = mappM (mk_alt fail) match_alts         `thenDs` \ alts ->
        returnDs (Case (Var var) var ((DEFAULT, [], fail) : alts))
 
     mk_alt fail (lit, MatchResult _ body_fn) = body_fn fail    `thenDs` \ body ->
@@ -328,13 +333,13 @@ mkCoAlgCaseMatchResult var match_alts
              = CanFail
 
     wild_var = mkWildId (idType var)
-    mk_case fail = mapDs (mk_alt fail) match_alts      `thenDs` \ alts ->
+    mk_case fail = mappM (mk_alt fail) match_alts      `thenDs` \ alts ->
                   returnDs (Case (Var var) wild_var (mk_default fail ++ alts))
 
     mk_alt fail (con, args, MatchResult _ body_fn)
        = body_fn fail                          `thenDs` \ body ->
-         getUniquesDs                          `thenDs` \ us ->
-         returnDs (mkReboxingAlt us con args body)
+         newUniqueSupply                       `thenDs` \ us ->
+         returnDs (mkReboxingAlt (uniqsFromSupply us) con args body)
 
     mk_default fail | exhaustive_case = []
                    | otherwise       = [(DEFAULT, [], fail)]
@@ -387,7 +392,7 @@ mkCoAlgCaseMatchResult var match_alts
        unboxAlt = 
          newSysLocalDs intPrimTy                       `thenDs` \l        ->
          dsLookupGlobalId indexPName           `thenDs` \indexP   ->
-         mapDs (mkAlt indexP) match_alts               `thenDs` \alts     ->
+         mappM (mkAlt indexP) match_alts               `thenDs` \alts     ->
          returnDs (DataAlt intDataCon, [l], (Case (Var l) wild (dft : alts)))
           where
            wild = mkWildId intPrimTy
@@ -423,7 +428,7 @@ mkErrorAppDs :: Id          -- The error function
             -> DsM CoreExpr
 
 mkErrorAppDs err_id ty msg
-  = getSrcLocDs                        `thenDs` \ src_loc ->
+  = getSrcSpanDs               `thenDs` \ src_loc ->
     let
        full_msg = showSDoc (hcat [ppr src_loc, text "|", text msg])
        core_msg = Lit (MachStr (mkFastString (stringToUtf8 full_msg)))
@@ -439,7 +444,7 @@ mkErrorAppDs err_id ty msg
 %************************************************************************
 
 \begin{code}
-mkCharExpr    :: Int       -> CoreExpr      -- Returns C# c :: Int
+mkCharExpr    :: Char      -> CoreExpr      -- Returns C# c :: Int
 mkIntExpr     :: Integer    -> CoreExpr             -- Returns I# i :: Int
 mkIntegerExpr :: Integer    -> DsM CoreExpr  -- Result :: Integer
 mkStringLit   :: String     -> DsM CoreExpr  -- Result :: String
@@ -450,7 +455,8 @@ mkCharExpr c = mkConApp charDataCon [mkLit (MachChar c)]
 
 mkIntegerExpr i
   | inIntRange i       -- Small enough, so start from an Int
-  = returnDs (mkSmallIntegerLit i)
+  = dsLookupDataCon  smallIntegerDataConName   `thenDs` \ integer_dc ->
+    returnDs (mkSmallIntegerLit integer_dc i)
 
 -- Special case for integral literals with a large magnitude:
 -- They are transformed into an expression involving only smaller
@@ -458,25 +464,27 @@ mkIntegerExpr i
 
   | otherwise          -- Big, so start from a string
   = dsLookupGlobalId plusIntegerName           `thenDs` \ plus_id ->
-    dsLookupGlobalId timesIntegerName  `thenDs` \ times_id ->
+    dsLookupGlobalId timesIntegerName          `thenDs` \ times_id ->
+    dsLookupDataCon  smallIntegerDataConName   `thenDs` \ integer_dc ->
     let 
+       lit i = mkSmallIntegerLit integer_dc i
         plus a b  = Var plus_id  `App` a `App` b
         times a b = Var times_id `App` a `App` b
 
        -- Transform i into (x1 + (x2 + (x3 + (...) * b) * b) * b) with abs xi <= b
        horner :: Integer -> Integer -> CoreExpr
        horner b i | abs q <= 1 = if r == 0 || r == i 
-                                 then mkSmallIntegerLit i 
-                                 else mkSmallIntegerLit r `plus` mkSmallIntegerLit (i-r)
-                  | r == 0     =                             horner b q `times` mkSmallIntegerLit b
-                  | otherwise  = mkSmallIntegerLit r `plus` (horner b q `times` mkSmallIntegerLit b)
+                                 then lit i 
+                                 else lit r `plus` lit (i-r)
+                  | r == 0     =               horner b q `times` lit b
+                  | otherwise  = lit r `plus` (horner b q `times` lit b)
                   where
                     (q,r) = i `quotRem` b
 
     in
     returnDs (horner tARGET_MAX_INT i)
 
-mkSmallIntegerLit i = mkConApp smallIntegerDataCon [mkIntLit i]
+mkSmallIntegerLit small_integer_data_con i = mkConApp small_integer_data_con [mkIntLit i]
 
 mkStringLit str        = mkStringLitFS (mkFastString str)
 
@@ -486,7 +494,7 @@ mkStringLitFS str
 
   | lengthFS str == 1
   = let
-       the_char = mkCharExpr (headIntFS str)
+       the_char = mkCharExpr (headFS str)
     in
     returnDs (mkConsExpr charTy the_char (mkNilExpr charTy))
 
@@ -527,15 +535,15 @@ even more helpful.  Something very similar happens for pattern-bound
 expressions.
 
 \begin{code}
-mkSelectorBinds :: TypecheckedPat      -- The pattern
-               -> CoreExpr             -- Expression to which the pattern is bound
+mkSelectorBinds :: LPat Id     -- The pattern
+               -> CoreExpr     -- Expression to which the pattern is bound
                -> DsM [(Id,CoreExpr)]
 
-mkSelectorBinds (VarPat v) val_expr
+mkSelectorBinds (L _ (VarPat v)) val_expr
   = returnDs [(v, val_expr)]
 
 mkSelectorBinds pat val_expr
-  | isSingleton binders || is_simple_pat pat
+  | isSingleton binders || is_simple_lpat pat
   =    -- Given   p = e, where p binds x,y
        -- we are going to make
        --      v = p   (where v is fresh)
@@ -547,7 +555,7 @@ mkSelectorBinds pat val_expr
        -- This does not matter after desugaring, but there's a subtle 
        -- issue with implicit parameters. Consider
        --      (x,y) = ?i
-       -- Then, ?i is given type {?i :: Int}, a SourceType, which is opaque
+       -- Then, ?i is given type {?i :: Int}, a PredType, which is opaque
        -- to the desugarer.  (Why opaque?  Because newtypes have to be.  Why
        -- does it get that type?  So that when we abstract over it we get the
        -- right top-level type  (?i::Int) => ...)
@@ -561,7 +569,7 @@ mkSelectorBinds pat val_expr
     mkErrorAppDs iRREFUT_PAT_ERROR_ID 
                 unitTy (showSDoc (ppr pat))    `thenDs` \ err_expr ->
     newSysLocalDs unitTy                       `thenDs` \ err_var ->
-    mapDs (mk_bind val_var err_var) binders    `thenDs` \ binds ->
+    mappM (mk_bind val_var err_var) binders    `thenDs` \ binds ->
     returnDs ( (val_var, val_expr) : 
               (err_var, err_expr) :
               binds )
@@ -592,15 +600,19 @@ mkSelectorBinds pat val_expr
       where
         error_expr = mkCoerce (idType bndr_var) (Var err_var)
 
-    is_simple_pat (TuplePat ps Boxed)    = all is_triv_pat ps
-    is_simple_pat (ConPatOut _ ps _ _ _) = all is_triv_pat (hsConArgs ps)
+    is_simple_lpat p = is_simple_pat (unLoc p)
+
+    is_simple_pat (TuplePat ps Boxed)    = all is_triv_lpat ps
+    is_simple_pat (ConPatOut _ ps _ _ _) = all is_triv_lpat (hsConArgs ps)
     is_simple_pat (VarPat _)            = True
-    is_simple_pat (ParPat p)            = is_simple_pat p
+    is_simple_pat (ParPat p)            = is_simple_lpat p
     is_simple_pat other                         = False
 
+    is_triv_lpat p = is_triv_pat (unLoc p)
+
     is_triv_pat (VarPat v)  = True
     is_triv_pat (WildPat _) = True
-    is_triv_pat (ParPat p)  = is_triv_pat p
+    is_triv_pat (ParPat p)  = is_triv_lpat p
     is_triv_pat other       = False
 \end{code}