[project @ 2003-11-03 16:00:57 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcHsSyn.lhs
index a09eb59..dcdb63a 100644 (file)
@@ -13,6 +13,7 @@ module TcHsSyn (
        TcStmt, TcArithSeqInfo, TcRecordBinds,
        TcHsModule, TcDictBinds,
        TcForeignDecl,
+       TcCmd, TcCmdTop,
        
        TypecheckedHsBinds, TypecheckedRuleDecl,
        TypecheckedMonoBinds, TypecheckedPat,
@@ -22,11 +23,17 @@ module TcHsSyn (
        TypecheckedGRHSs, TypecheckedGRHS,
        TypecheckedRecordBinds, TypecheckedDictBinds,
        TypecheckedMatchContext, TypecheckedCoreBind,
+       TypecheckedHsCmd, TypecheckedHsCmdTop,
 
        mkHsTyApp, mkHsDictApp, mkHsConApp,
        mkHsTyLam, mkHsDictLam, mkHsLet,
        hsLitType, hsPatType, 
 
+       -- Coercions
+       Coercion, ExprCoFn, PatCoFn, 
+       (<$>), (<.>), mkCoercion, 
+       idCoercion, isIdCoercion,
+
        -- re-exported from TcMonad
        TcId, TcIdSet,
 
@@ -53,7 +60,7 @@ import TcMType          ( zonkTcTyVarToTyVar, zonkType, zonkTcType, zonkTcTyVars,
 import TysPrim   ( charPrimTy, intPrimTy, floatPrimTy,
                    doublePrimTy, addrPrimTy
                  )
-import TysWiredIn ( charTy, stringTy, intTy, integerTy,
+import TysWiredIn ( charTy, stringTy, intTy, 
                    mkListTy, mkPArrTy, mkTupleTy, unitTy,
                    voidTy, listTyCon, tupleTyCon )
 import TyCon     ( mkPrimTyCon, tyConKind )
@@ -65,6 +72,7 @@ import VarSet
 import VarEnv
 import BasicTypes ( RecFlag(..), Boxity(..), IPName(..), ipNameName, mapIPName )
 import Maybes    ( orElse )
+import Maybe     ( isNothing )
 import Unique    ( Uniquable(..) )
 import SrcLoc    ( noSrcLoc )
 import Bag
@@ -97,6 +105,8 @@ type TcRecordBinds   = HsRecordBinds TcId
 type TcHsModule                = HsModule      TcId
 type TcForeignDecl      = ForeignDecl  TcId
 type TcRuleDecl        = RuleDecl     TcId
+type TcCmd             = HsCmd         TcId 
+type TcCmdTop          = HsCmdTop      TcId 
 
 type TypecheckedPat            = OutPat        Id
 type TypecheckedMonoBinds      = MonoBinds     Id
@@ -113,6 +123,8 @@ type TypecheckedHsModule    = HsModule      Id
 type TypecheckedForeignDecl     = ForeignDecl   Id
 type TypecheckedRuleDecl       = RuleDecl      Id
 type TypecheckedCoreBind        = (Id, CoreExpr)
+type TypecheckedHsCmd          = HsCmd         Id
+type TypecheckedHsCmdTop       = HsCmdTop      Id
 
 type TypecheckedMatchContext   = HsMatchContext Name   -- Keeps consistency with 
                                                        -- HsDo arg StmtContext
@@ -175,19 +187,43 @@ hsLitType (HsString str)   = stringTy
 hsLitType (HsStringPrim s) = addrPrimTy
 hsLitType (HsInt i)       = intTy
 hsLitType (HsIntPrim i)    = intPrimTy
-hsLitType (HsInteger i)    = integerTy
+hsLitType (HsInteger i ty) = ty
 hsLitType (HsRat _ ty)    = ty
 hsLitType (HsFloatPrim f)  = floatPrimTy
 hsLitType (HsDoublePrim d) = doublePrimTy
-hsLitType (HsLitLit _ ty)  = ty
 \end{code}
 
+%************************************************************************
+%*                                                                     *
+\subsection{Coercion functions}
+%*                                                                     *
+%************************************************************************
+
 \begin{code}
--- zonkId is used *during* typechecking just to zonk the Id's type
-zonkId :: TcId -> TcM TcId
-zonkId id
-  = zonkTcType (idType id) `thenM` \ ty' ->
-    returnM (setIdType id ty')
+type Coercion a = Maybe (a -> a)
+       -- Nothing => identity fn
+
+type ExprCoFn = Coercion TypecheckedHsExpr
+type PatCoFn  = Coercion TcPat
+
+(<.>) :: Coercion a -> Coercion a -> Coercion a        -- Composition
+Nothing <.> Nothing = Nothing
+Nothing <.> Just f  = Just f
+Just f  <.> Nothing = Just f
+Just f1 <.> Just f2 = Just (f1 . f2)
+
+(<$>) :: Coercion a -> a -> a
+Just f  <$> e = f e
+Nothing <$> e = e
+
+mkCoercion :: (a -> a) -> Coercion a
+mkCoercion f = Just f
+
+idCoercion :: Coercion a
+idCoercion = Nothing
+
+isIdCoercion :: Coercion a -> Bool
+isIdCoercion = isNothing
 \end{code}
 
 
@@ -197,7 +233,16 @@ zonkId id
 %*                                                                     *
 %************************************************************************
 
-This zonking pass runs over the bindings
+\begin{code}
+-- zonkId is used *during* typechecking just to zonk the Id's type
+zonkId :: TcId -> TcM TcId
+zonkId id
+  = zonkTcType (idType id) `thenM` \ ty' ->
+    returnM (setIdType id ty')
+\end{code}
+
+The rest of the zonking is done *after* typechecking.
+The main zonking pass runs over the bindings
 
  a) to convert TcTyVars to TyVars etc, dereferencing any bindings etc
  b) convert unbound TcTyVar to Void
@@ -317,12 +362,12 @@ zonkBinds env (MonoBind bind sigs is_rec)
     )                          `thenM` \ (env1, new_bind, _) ->
    returnM (env1, mkMonoBind is_rec new_bind)
 
-zonkBinds env (IPBinds binds is_with)
+zonkBinds env (IPBinds binds)
   = mappM zonk_ip_bind binds   `thenM` \ new_binds ->
     let
        env1 = extendZonkEnv env (map (ipNameName . fst) new_binds)
     in
-    returnM (env1, IPBinds new_binds is_with)
+    returnM (env1, IPBinds new_binds)
   where
     zonk_ip_bind (n, e)
        = mapIPNameTc (zonkIdBndr env) n        `thenM` \ n' ->
@@ -442,10 +487,6 @@ zonkExpr env (HsLit (HsRat f ty))
   = zonkTcTypeToType env ty       `thenM` \ new_ty  ->
     returnM (HsLit (HsRat f new_ty))
 
-zonkExpr env (HsLit (HsLitLit lit ty))
-  = zonkTcTypeToType env ty        `thenM` \ new_ty  ->
-    returnM (HsLit (HsLitLit lit new_ty))
-
 zonkExpr env (HsLit lit)
   = returnM (HsLit lit)
 
@@ -513,9 +554,9 @@ zonkExpr env (HsLet binds expr)
 zonkExpr env (HsDo do_or_lc stmts ids ty src_loc)
   = zonkStmts env stmts        `thenM` \ new_stmts ->
     zonkTcTypeToType env ty    `thenM` \ new_ty   ->
-    returnM (HsDo do_or_lc new_stmts 
-                     (zonkIdOccs env ids) 
-                     new_ty src_loc)
+    zonkReboundNames env ids   `thenM` \ new_ids ->
+    returnM (HsDo do_or_lc new_stmts new_ids
+                 new_ty src_loc)
 
 zonkExpr env (ExplicitList ty exprs)
   = zonkTcTypeToType env ty    `thenM` \ new_ty ->
@@ -559,11 +600,6 @@ zonkExpr env (PArrSeqOut expr info)
     zonkArithSeq env info      `thenM` \ new_info ->
     returnM (PArrSeqOut new_expr new_info)
 
-zonkExpr env (HsCCall fun args may_gc is_casm result_ty)
-  = zonkExprs env args                 `thenM` \ new_args ->
-    zonkTcTypeToType env result_ty     `thenM` \ new_result_ty ->
-    returnM (HsCCall fun new_args may_gc is_casm new_result_ty)
-
 zonkExpr env (HsSCC lbl expr)
   = zonkExpr env expr  `thenM` \ new_expr ->
     returnM (HsSCC lbl new_expr)
@@ -597,6 +633,42 @@ zonkExpr env (DictApp expr dicts)
   = zonkExpr env expr                  `thenM` \ new_expr ->
     returnM (DictApp new_expr (zonkIdOccs env dicts))
 
+-- arrow notation extensions
+zonkExpr env (HsProc pat body src_loc)
+  = zonkPat env pat                    `thenM` \ (new_pat, new_ids) ->
+    let
+       env1 = extendZonkEnv env (bagToList new_ids)
+    in
+    zonkCmdTop env1 body               `thenM` \ new_body ->
+    returnM (HsProc new_pat new_body src_loc)
+
+zonkExpr env (HsArrApp e1 e2 ty ho rl src_loc)
+  = zonkExpr env e1                    `thenM` \ new_e1 ->
+    zonkExpr env e2                    `thenM` \ new_e2 ->
+    zonkTcTypeToType env ty            `thenM` \ new_ty ->
+    returnM (HsArrApp new_e1 new_e2 new_ty ho rl src_loc)
+
+zonkExpr env (HsArrForm op fixity args src_loc)
+  = zonkExpr env op                    `thenM` \ new_op ->
+    mappM (zonkCmdTop env) args                `thenM` \ new_args ->
+    returnM (HsArrForm new_op fixity new_args src_loc)
+
+zonkCmdTop :: ZonkEnv -> TcCmdTop -> TcM TypecheckedHsCmdTop
+zonkCmdTop env (HsCmdTop cmd stack_tys ty ids)
+  = zonkExpr env cmd                   `thenM` \ new_cmd ->
+    mappM (zonkTcTypeToType env) stack_tys
+                                       `thenM` \ new_stack_tys ->
+    zonkTcTypeToType env ty            `thenM` \ new_ty ->
+    zonkReboundNames env ids           `thenM` \ new_ids ->
+    returnM (HsCmdTop new_cmd new_stack_tys new_ty new_ids)
+
+-------------------------------------------------------------------------
+zonkReboundNames :: ZonkEnv -> ReboundNames Id -> TcM (ReboundNames Id)
+zonkReboundNames env prs 
+  = mapM zonk prs
+  where
+    zonk (n, e) = zonkExpr env e `thenM` \ new_e ->
+                 returnM (n, new_e)
 
 
 -------------------------------------------------------------------------
@@ -633,29 +705,33 @@ zonk_stmts :: ZonkEnv -> [TcStmt] -> TcM (ZonkEnv, [TypecheckedStmt])
 
 zonk_stmts env [] = returnM (env, [])
 
-zonk_stmts env (ParStmtOut bndrstmtss : stmts)
-  = mappM (mappM zonkId) bndrss                `thenM` \ new_bndrss ->
-    mappM (zonkStmts env) stmtss       `thenM` \ new_stmtss ->
+zonk_stmts env (ParStmt stmts_w_bndrs : stmts)
+  = mappM zonk_branch stmts_w_bndrs    `thenM` \ new_stmts_w_bndrs ->
     let 
-       new_binders = concat new_bndrss
+       new_binders = concat (map snd new_stmts_w_bndrs)
        env1 = extendZonkEnv env new_binders
     in
     zonk_stmts env1 stmts              `thenM` \ (env2, new_stmts) ->
-    returnM (env2, ParStmtOut (zip new_bndrss new_stmtss) : new_stmts)
+    returnM (env2, ParStmt new_stmts_w_bndrs : new_stmts)
   where
-    (bndrss, stmtss) = unzip bndrstmtss
+    zonk_branch (stmts, bndrs) = zonk_stmts env stmts  `thenM` \ (env1, new_stmts) ->
+                                returnM (new_stmts, zonkIdOccs env1 bndrs)
 
-zonk_stmts env (RecStmt vs segStmts rets : stmts)
-  = mappM zonkId vs            `thenM` \ new_vs ->
+zonk_stmts env (RecStmt segStmts lvs rvs rets : stmts)
+  = zonkIdBndrs env rvs                `thenM` \ new_rvs ->
     let
-       env1 = extendZonkEnv env new_vs
+       env1 = extendZonkEnv env new_rvs
     in
     zonk_stmts env1 segStmts   `thenM` \ (env2, new_segStmts) ->
        -- Zonk the ret-expressions in an envt that 
        -- has the polymorphic bindings in the envt
     zonkExprs env2 rets                `thenM` \ new_rets ->
-    zonk_stmts env1 stmts      `thenM` \ (env3, new_stmts) ->
-    returnM (env3, RecStmt new_vs new_segStmts new_rets : new_stmts)
+    let
+       new_lvs = zonkIdOccs env2 lvs
+       env3 = extendZonkEnv env new_lvs        -- Only the lvs are needed
+    in
+    zonk_stmts env3 stmts      `thenM` \ (env4, new_stmts) ->
+    returnM (env4, RecStmt new_segStmts new_lvs new_rvs new_rets : new_stmts)
 
 zonk_stmts env (ResultStmt expr locn : stmts)
   = ASSERT( null stmts )
@@ -752,7 +828,7 @@ zonkPat env (ConPatOut n stuff ty tvs dicts)
     let
        env1 = extendZonkEnv env new_dicts
     in
-    zonkConStuff env stuff             `thenM` \ (new_stuff, ids) ->
+    zonkConStuff env1 stuff            `thenM` \ (new_stuff, ids) ->
     returnM (ConPatOut n new_stuff new_ty new_tvs new_dicts, 
                 listToBag new_dicts `unionBags` ids)
 
@@ -872,9 +948,6 @@ zonkRule env (HsRule name act vars lhs rhs loc)
    zonk_bndr (RuleBndr v) 
        | isId v    = zonkIdBndr env v
        | otherwise = zonkTcTyVarToTyVar v
-
-zonkRule env (IfaceRuleOut fun rule)
-  = returnM (IfaceRuleOut (zonkIdOcc env fun) rule)
 \end{code}