[project @ 1997-05-19 00:12:10 by sof]
[ghc-hetmet.git] / ghc / compiler / coreSyn / CoreSyn.lhs
index 1599273..6e28cf4 100644 (file)
@@ -8,8 +8,9 @@
 
 module CoreSyn (
        GenCoreBinding(..), GenCoreExpr(..),
-       GenCoreArg(..),GenCoreBinder(..), GenCoreCaseAlts(..),
+       GenCoreArg(..), GenCoreBinder(..), GenCoreCaseAlts(..),
        GenCoreCaseDefault(..),
+       Coercion(..),
 
        bindersOf, pairsFromCoreBinds, rhssOfBind,
 
@@ -17,9 +18,10 @@ module CoreSyn (
        mkApp, mkCon, mkPrim,
        mkValLam, mkTyLam, mkUseLam,
        mkLam,
-       digForLambdas,
+       collectBinders, collectUsageAndTyBinders, collectValBinders, 
+       isValBinder, notValBinder,
        
-       collectArgs, isValArg,
+       collectArgs, initialTyArgs, initialValArgs, isValArg, notValArg, numValArgs,
 
        mkCoLetAny, mkCoLetNoUnboxed, mkCoLetUnboxedToCase,
        mkCoLetsAny, mkCoLetsNoUnboxed, mkCoLetsUnboxedToCase,
@@ -28,42 +30,42 @@ module CoreSyn (
        rhssOfAlts,
 
        -- Common type instantiation...
-       CoreBinding(..),
-       CoreExpr(..),
-       CoreBinder(..),
-       CoreArg(..),
-       CoreCaseAlts(..),
-       CoreCaseDefault(..),
+       SYN_IE(CoreBinding),
+       SYN_IE(CoreExpr),
+       SYN_IE(CoreBinder),
+       SYN_IE(CoreArg),
+       SYN_IE(CoreCaseAlts),
+       SYN_IE(CoreCaseDefault),
 
        -- And not-so-common type instantiations...
-       TaggedCoreBinding(..),
-       TaggedCoreExpr(..),
-       TaggedCoreBinder(..),
-       TaggedCoreArg(..),
-       TaggedCoreCaseAlts(..),
-       TaggedCoreCaseDefault(..),
-
-       SimplifiableCoreBinding(..),
-       SimplifiableCoreExpr(..),
-       SimplifiableCoreBinder(..),
-       SimplifiableCoreArg(..),
-       SimplifiableCoreCaseAlts(..),
-       SimplifiableCoreCaseDefault(..)
-
-       -- and to make the interface self-sufficient ...
-
+       SYN_IE(TaggedCoreBinding),
+       SYN_IE(TaggedCoreExpr),
+       SYN_IE(TaggedCoreBinder),
+       SYN_IE(TaggedCoreArg),
+       SYN_IE(TaggedCoreCaseAlts),
+       SYN_IE(TaggedCoreCaseDefault),
+
+       SYN_IE(SimplifiableCoreBinding),
+       SYN_IE(SimplifiableCoreExpr),
+       SYN_IE(SimplifiableCoreBinder),
+       SYN_IE(SimplifiableCoreArg),
+       SYN_IE(SimplifiableCoreCaseAlts),
+       SYN_IE(SimplifiableCoreCaseDefault)
     ) where
 
-import Ubiq{-uitous-}
+IMP_Ubiq(){-uitous-}
 
 import CostCentre      ( showCostCentre, CostCentre )
-import Id              ( idType )
-import Usage           ( UVar(..) )
-import Util            ( panic, assertPanic )
-
-isUnboxedDataType = panic "CoreSyn.isUnboxedDataType"
---eqId :: Id -> Id -> Bool
-eqId = panic "CoreSyn.eqId"
+import Id              ( idType, GenId{-instance Eq-}, SYN_IE(Id) )
+import Type            ( isUnboxedType,GenType, SYN_IE(Type) )
+import TyVar           ( GenTyVar, SYN_IE(TyVar) )
+import Usage           ( SYN_IE(UVar),GenUsage,SYN_IE(Usage) )
+import Util            ( panic, assertPanic {-pprTrace:ToDo:rm-} )
+#if __GLASGOW_HASKELL__ >= 202
+import Literal          ( Literal )
+import BinderInfo       ( BinderInfo )
+import PrimOp           ( PrimOp )
+#endif
 \end{code}
 
 %************************************************************************
@@ -137,16 +139,17 @@ desugarer sets up constructors as applications of global @Vars@s.
 
      | Prim    PrimOp [GenCoreArg val_occ tyvar uvar]
                -- saturated primitive operation;
+
                -- comment on Cons applies here, too.
 \end{code}
 
 Ye olde abstraction and application operators.
 \begin{code}
      | Lam     (GenCoreBinder val_bdr tyvar uvar)
-               (GenCoreExpr val_bdr val_occ tyvar uvar)
+               (GenCoreExpr   val_bdr val_occ tyvar uvar)
 
      | App     (GenCoreExpr val_bdr val_occ tyvar uvar)
-               (GenCoreArg val_occ tyvar uvar)
+               (GenCoreArg  val_occ tyvar uvar)
 \end{code}
 
 Case expressions (\tr{case <expr> of <List of alternatives>}): there
@@ -181,6 +184,21 @@ transformations of which we are unaware.
                (GenCoreExpr val_bdr val_occ tyvar uvar)    -- scc expression
 \end{code}
 
+Coercions arise from uses of the constructor of a @newtype@
+declaration, either in construction (resulting in a @CoreceIn@) or
+pattern matching (resulting in a @CoerceOut@).
+
+\begin{code}
+    | Coerce   Coercion
+               (GenType tyvar uvar)            -- Type of the whole expression
+               (GenCoreExpr val_bdr val_occ tyvar uvar)
+\end{code}
+
+\begin{code}
+data Coercion  = CoerceIn Id           -- Apply this constructor
+               | CoerceOut Id          -- Strip this constructor
+\end{code}
+
 
 %************************************************************************
 %*                                                                     *
@@ -197,12 +215,13 @@ being bound has unboxed type. We have different variants ...
                                (unboxed bindings in a letrec are still prohibited)
 
 \begin{code}
-mkCoLetAny :: GenCoreBinding val_bdr val_occ tyvar uvar
-          -> GenCoreExpr    val_bdr val_occ tyvar uvar
-          -> GenCoreExpr    val_bdr val_occ tyvar uvar
-mkCoLetsAny :: [GenCoreBinding val_bdr val_occ tyvar uvar] ->
-               GenCoreExpr val_bdr val_occ tyvar uvar ->
-               GenCoreExpr val_bdr val_occ tyvar uvar
+mkCoLetAny :: GenCoreBinding Id Id tyvar uvar
+          -> GenCoreExpr    Id Id tyvar uvar
+          -> GenCoreExpr    Id Id tyvar uvar
+mkCoLetsAny :: [GenCoreBinding Id Id tyvar uvar] ->
+               GenCoreExpr Id Id tyvar uvar ->
+               GenCoreExpr Id Id tyvar uvar
+
 mkCoLetrecAny :: [(val_bdr, GenCoreExpr val_bdr val_occ tyvar uvar)]
              -> GenCoreExpr val_bdr val_occ tyvar uvar
              -> GenCoreExpr val_bdr val_occ tyvar uvar
@@ -213,27 +232,18 @@ mkCoLetrecAny binds body = Let (Rec binds) body
 mkCoLetsAny []    expr = expr
 mkCoLetsAny binds expr = foldr mkCoLetAny expr binds
 
-mkCoLetAny bind@(Rec binds) body = mkCoLetrecAny binds body
-mkCoLetAny bind@(NonRec binder rhs) body
-  = case body of
-      Var binder2 | binder `eqId` binder2
-        -> rhs   -- hey, I have the rhs
-      other
-        -> Let bind body
+mkCoLetAny bind@(Rec binds)         body = mkCoLetrecAny binds body
+mkCoLetAny bind@(NonRec binder rhs) body = Let bind body
 \end{code}
 
 \begin{code}
---mkCoLetNoUnboxed ::
---  GenCoreBinding val_bdr val_occ tyvar uvar ->
---  GenCoreExpr val_bdr val_occ tyvar uvar ->
---  GenCoreExpr val_bdr val_occ tyvar uvar
-
 mkCoLetNoUnboxed bind@(Rec binds) body
   = mkCoLetrecNoUnboxed binds body
+
 mkCoLetNoUnboxed bind@(NonRec binder rhs) body
-  = --ASSERT (not (isUnboxedDataType (idType binder)))
+  = --ASSERT (not (isUnboxedType (idType binder)))
     case body of
-      Var binder2 | binder `eqId` binder2
+      Var binder2 | binder == binder2
         -> rhs   -- hey, I have the rhs
       other
         -> Let bind body
@@ -241,33 +251,25 @@ mkCoLetNoUnboxed bind@(NonRec binder rhs) body
 mkCoLetsNoUnboxed []    expr = expr
 mkCoLetsNoUnboxed binds expr = foldr mkCoLetNoUnboxed expr binds
 
---mkCoLetrecNoUnboxed :: [(Id, CoreExpr)]      -- bindings
---                 -> CoreExpr         -- body
---                 -> CoreExpr                 -- result
-
 mkCoLetrecNoUnboxed []    body = body
 mkCoLetrecNoUnboxed binds body
   = ASSERT (all is_boxed_bind binds)
     Let (Rec binds) body
   where
     is_boxed_bind (binder, rhs)
-      = (not . isUnboxedDataType . idType) binder
+      = (not . isUnboxedType . idType) binder
 \end{code}
 
 \begin{code}
---mkCoLetUnboxedToCase ::
---  GenCoreBinding val_bdr val_occ tyvar uvar ->
---  GenCoreExpr val_bdr val_occ tyvar uvar ->
---  GenCoreExpr val_bdr val_occ tyvar uvar
-
 mkCoLetUnboxedToCase bind@(Rec binds) body
   = mkCoLetrecNoUnboxed binds body
+
 mkCoLetUnboxedToCase bind@(NonRec binder rhs) body
   = case body of
-      Var binder2 | binder `eqId` binder2
+      Var binder2 | binder == binder2
         -> rhs   -- hey, I have the rhs
       other
-        -> if (not (isUnboxedDataType (idType binder))) then
+        -> if (not (isUnboxedType (idType binder))) then
                Let bind body            -- boxed...
            else
                Case rhs                  -- unboxed...
@@ -341,6 +343,11 @@ data GenCoreBinder val_bdr tyvar uvar
   = ValBinder  val_bdr
   | TyBinder   tyvar
   | UsageBinder        uvar
+
+isValBinder (ValBinder _) = True
+isValBinder _            = False
+
+notValBinder = not . isValBinder
 \end{code}
 
 Clump Lams together if possible.
@@ -369,52 +376,37 @@ mkLam tyvars valvars body
 \end{code}
 
 We often want to strip off leading lambdas before getting down to
-business.  @digForLambdas@ is your friend.
+business.  @collectBinders@ is your friend.
 
 We expect (by convention) usage-, type-, and value- lambdas in that
 order.
 
 \begin{code}
-digForLambdas ::
+collectBinders ::
   GenCoreExpr val_bdr val_occ tyvar uvar ->
   ([uvar], [tyvar], [val_bdr], GenCoreExpr val_bdr val_occ tyvar uvar)
 
-digForLambdas (Lam (UsageBinder u) body)
-  = let
-       (uvars, tyvars, args, final_body) = digForLambdas body
-    in
-    (u:uvars, tyvars, args, final_body)
-
-digForLambdas other
-  = let
-       (tyvars, args, body) = dig_for_tyvars other
-    in
-    ([], tyvars, args, body)
+collectBinders expr
+  = case collectValBinders body1 of { (vals,body) -> (usages, tyvars, vals, body) }
   where
-    dig_for_tyvars (Lam (TyBinder tv) body)
-      = let
-           (tyvars, args, body2) = dig_for_tyvars body
-       in
-       (tv : tyvars, args, body2)
-
-    dig_for_tyvars body
-      = ASSERT(not (usage_lambda body))
-       let
-           (args, body2) = dig_for_valvars body
-       in
-       ([], args, body2)
+    (usages, tyvars, body1) = collectUsageAndTyBinders expr
+--    (vals, body)         = collectValBinders body1
 
-    ---------------------------------------
-    dig_for_valvars (Lam (ValBinder v) body)
-      = let
-           (args, body2) = dig_for_valvars body
-       in
-       (v : args, body2)
 
-    dig_for_valvars body
-      = ASSERT(not (usage_lambda body))
-       ASSERT(not (tyvar_lambda body))
-       ([], body)
+collectUsageAndTyBinders expr
+  = case usages expr [] of
+      ([],tyvars,body) -> ([],tyvars,body)
+      v                -> v
+  where
+    usages (Lam (UsageBinder u) body) uacc = usages body (u:uacc)
+    usages other uacc
+      = case (tyvars other []) of { (tacc, expr) ->
+       (reverse uacc, tacc, expr) }
+
+    tyvars (Lam (TyBinder t) body) tacc = tyvars body (t:tacc)
+    tyvars other tacc
+      = ASSERT(not (usage_lambda other))
+       (reverse tacc, other)
 
     ---------------------------------------
     usage_lambda (Lam (UsageBinder _) _) = True
@@ -422,6 +414,18 @@ digForLambdas other
 
     tyvar_lambda (Lam (TyBinder _) _)    = True
     tyvar_lambda _                      = False
+
+
+collectValBinders :: GenCoreExpr val_bdr val_occ tyvar uvar ->
+                    ([val_bdr], GenCoreExpr val_bdr val_occ tyvar uvar)
+collectValBinders expr
+  = case go [] expr of
+      ([],body) -> ([],body)
+      v         -> v
+  where
+    go acc (Lam (ValBinder v) b) = go (v:acc) b
+    go acc body                 = (reverse acc, body)
+
 \end{code}
 
 %************************************************************************
@@ -468,6 +472,10 @@ is_Lit_or_Var a
 isValArg (LitArg _) = True  -- often used for sanity-checking
 isValArg (VarArg _) = True
 isValArg _         = False
+
+notValArg = not . isValArg -- exists only because it's a common use of isValArg
+
+numValArgs as = length [ a | a <- as, isValArg a ] -- again, convenience
 \end{code}
 
 \begin{code}
@@ -485,15 +493,43 @@ and the arguments to which it is applied.
 \begin{code}
 collectArgs :: GenCoreExpr val_bdr val_occ tyvar uvar
            -> (GenCoreExpr val_bdr val_occ tyvar uvar,
-               [GenCoreArg val_occ tyvar uvar])
+               [GenUsage uvar],
+               [GenType tyvar uvar],
+               [GenCoreArg val_occ tyvar uvar]{-ValArgs-})
 
 collectArgs expr
-  = collect expr []
+  = valvars expr []
   where
-    collect (App fun arg) args = collect fun (arg : args)
-    collect fun                  args = (fun, args)
+    valvars (App fun v) vacc | isValArg v = valvars fun (v:vacc)
+    valvars fun vacc
+      = case (tyvars fun []) of { (expr, uacc, tacc) ->
+       (expr, uacc, tacc, vacc) }
+
+    tyvars (App fun (TyArg t))    tacc = tyvars fun (t:tacc)
+    tyvars fun tacc
+      = case (usages fun []) of { (expr, uacc) ->
+       (expr, uacc, tacc) }
+
+    usages (App fun (UsageArg u)) uacc = usages fun (u:uacc)
+    usages fun uacc
+      = (fun,uacc)
 \end{code}
 
+
+\begin{code}
+initialTyArgs :: [GenCoreArg val_occ tyvar uvar]
+             -> ([GenType tyvar uvar], [GenCoreArg val_occ tyvar uvar])
+initialTyArgs (TyArg ty : args) = (ty:tys, args') 
+                               where
+                                 (tys, args') = initialTyArgs args
+initialTyArgs other            = ([],other)
+
+initialValArgs :: [GenCoreArg val_occ tyvar uvar]
+             -> ([GenCoreArg val_occ tyvar uvar], [GenCoreArg val_occ tyvar uvar])
+initialValArgs args = span isValArg args
+\end{code}
+
+
 %************************************************************************
 %*                                                                     *
 \subsection{The main @Core*@ instantiation of the @GenCore*@ types}