[project @ 1998-04-06 18:38:36 by sof]
[ghc-hetmet.git] / ghc / compiler / stgSyn / StgSyn.lhs
index 8e08d32..704be4b 100644 (file)
@@ -9,11 +9,9 @@ form of @CoreSyntax@, the style being one that happens to be ideally
 suited to spineless tagless code generation.
 
 \begin{code}
-#include "HsVersions.h"
-
 module StgSyn (
        GenStgArg(..),
-       GenStgLiveVars(..),
+       GenStgLiveVars,
 
        GenStgBinding(..), GenStgExpr(..), GenStgRhs(..),
        GenStgCaseAlts(..), GenStgCaseDefault(..),
@@ -26,34 +24,28 @@ module StgSyn (
        combineStgBinderInfo,
 
        -- a set of synonyms for the most common (only :-) parameterisation
-       StgArg(..), StgLiveVars(..),
-       StgBinding(..), StgExpr(..), StgRhs(..),
-       StgCaseAlts(..), StgCaseDefault(..),
+       StgArg, StgLiveVars,
+       StgBinding, StgExpr, StgRhs,
+       StgCaseAlts, StgCaseDefault,
 
-       pprPlainStgBinding,
+       pprStgBinding, pprStgBindings,
        getArgPrimRep,
        isLitLitArg,
        stgArity,
-       collectExportedStgBinders
-
-       -- and to make the interface self-sufficient...
+       collectFinalStgBinders
     ) where
 
-import Ubiq{-uitous-}
+#include "HsVersions.h"
 
-import CostCentre      ( showCostCentre )
-import Id              ( idPrimRep, GenId{-instance NamedThing-} )
+import CostCentre      ( showCostCentre, CostCentre )
+import Id              ( idPrimRep, DataCon, 
+                         GenId{-instance NamedThing-}, Id )
 import Literal         ( literalPrimRep, isLitLitLit, Literal{-instance Outputable-} )
-import Name            ( isExported, isSymLexeme )
-import Outputable      ( ifPprDebug, interppSP, interpp'SP,
-                         Outputable(..){-instance * Bool-}
-                       )
-import PprStyle                ( PprStyle(..) )
-import PprType         ( GenType{-instance Outputable-} )
-import Pretty          -- all of it
+import Outputable
 import PrimOp          ( PrimOp{-instance Outputable-} )
-import Unique          ( pprUnique )
-import UniqSet         ( isEmptyUniqSet, uniqSetToList, UniqSet(..) )
+import Type             ( Type )
+import Unique          ( pprUnique, Unique )
+import UniqSet         ( isEmptyUniqSet, uniqSetToList, UniqSet )
 import Util            ( panic )
 \end{code}
 
@@ -72,6 +64,7 @@ with respect to binder and occurrence information (just as in
 data GenStgBinding bndr occ
   = StgNonRec  bndr (GenStgRhs bndr occ)
   | StgRec     [(bndr, GenStgRhs bndr occ)]
+  | StgCoerceBinding bndr occ                  -- UNUSED?
 \end{code}
 
 %************************************************************************
@@ -84,10 +77,12 @@ data GenStgBinding bndr occ
 data GenStgArg occ
   = StgVarArg  occ
   | StgLitArg  Literal
+  | StgConArg   DataCon                -- A nullary data constructor
 \end{code}
 
 \begin{code}
 getArgPrimRep (StgVarArg  local) = idPrimRep local
+getArgPrimRep (StgConArg  con)  = idPrimRep con
 getArgPrimRep (StgLitArg  lit)  = literalPrimRep lit
 
 isLitLitArg (StgLitArg x) = isLitLitLit x
@@ -461,8 +456,8 @@ This is also used in @LambdaFormInfo@ in the @ClosureInfo@ module.
 data UpdateFlag = ReEntrant | Updatable | SingleEntry
 
 instance Outputable UpdateFlag where
-    ppr sty u
-      = ppChar (case u of { ReEntrant -> 'r';  Updatable -> 'u';  SingleEntry -> 's' })
+    ppr u
+      = char (case u of { ReEntrant -> 'r';  Updatable -> 'u';  SingleEntry -> 's' })
 \end{code}
 
 %************************************************************************
@@ -477,26 +472,13 @@ final pre-codegen STG code, so as to be sure we have the
 latest/greatest pragma info.
 
 \begin{code}
-collectExportedStgBinders
+collectFinalStgBinders
        :: [StgBinding] -- input program
-       -> [Id]                 -- exported top-level Ids
+       -> [Id]
 
-collectExportedStgBinders binds
-  = ex [] binds
-  where
-    ex es [] = es
-
-    ex es ((StgNonRec b _) : binds)
-      = if not (isExported b) then
-           ex es binds
-       else
-           ex (b:es) binds
-
-    ex es ((StgRec []) : binds) = ex es binds
-
-    ex es ((StgRec ((b, rhs) : pairs)) : binds)
-      = ex es (StgNonRec b rhs : (StgRec pairs : binds))
-           -- OK, a total hack; laziness rules
+collectFinalStgBinders [] = []
+collectFinalStgBinders (StgNonRec b _ : binds) = b : collectFinalStgBinders binds
+collectFinalStgBinders (StgRec bs     : binds) = map fst bs ++ collectFinalStgBinders binds
 \end{code}
 
 %************************************************************************
@@ -509,23 +491,30 @@ Robin Popplestone asked for semi-colon separators on STG binds; here's
 hoping he likes terminators instead...  Ditto for case alternatives.
 
 \begin{code}
-pprStgBinding :: (Outputable bndr, Outputable bdee, Ord bdee) =>
-               PprStyle -> GenStgBinding bndr bdee -> Pretty
+pprGenStgBinding :: (Outputable bndr, Outputable bdee, Ord bdee)
+                => GenStgBinding bndr bdee -> SDoc
+
+pprGenStgBinding (StgNonRec bndr rhs)
+  = hang (hsep [ppr bndr, equals])
+        4 ((<>) (ppr rhs) semi)
 
-pprStgBinding sty (StgNonRec bndr rhs)
-  = ppHang (ppCat [ppr sty bndr, ppEquals])
-        4 (ppBeside (ppr sty rhs) ppSemi)
+pprGenStgBinding (StgCoerceBinding bndr occ)
+  = hang (hsep [ppr bndr, equals, ptext SLIT("{-Coerce-}")])
+        4 ((<>) (ppr occ) semi)
 
-pprStgBinding sty (StgRec pairs)
-  = ppAboves ((ifPprDebug sty (ppStr "{- StgRec -}")) :
-             (map (ppr_bind sty) pairs))
+pprGenStgBinding (StgRec pairs)
+  = vcat ((ifPprDebug (ptext SLIT("{- StgRec (begin) -}"))) :
+             (map (ppr_bind) pairs) ++ [(ifPprDebug (ptext SLIT("{- StgRec (end) -}")))])
   where
-    ppr_bind sty (bndr, expr)
-      = ppHang (ppCat [ppr sty bndr, ppEquals])
-            4 (ppBeside (ppr sty expr) ppSemi)
+    ppr_bind (bndr, expr)
+      = hang (hsep [ppr bndr, equals])
+            4 ((<>) (ppr expr) semi)
 
-pprPlainStgBinding :: PprStyle -> StgBinding -> Pretty
-pprPlainStgBinding sty b = pprStgBinding sty b
+pprStgBinding  :: StgBinding -> SDoc
+pprStgBinding  bind  = pprGenStgBinding bind
+
+pprStgBindings :: [StgBinding] -> SDoc
+pprStgBindings binds = vcat (map (pprGenStgBinding) binds)
 \end{code}
 
 \begin{code}
@@ -534,7 +523,7 @@ instance (Outputable bdee) => Outputable (GenStgArg bdee) where
 
 instance (Outputable bndr, Outputable bdee, Ord bdee)
                => Outputable (GenStgBinding bndr bdee) where
-    ppr = pprStgBinding
+    ppr = pprGenStgBinding
 
 instance (Outputable bndr, Outputable bdee, Ord bdee)
                => Outputable (GenStgExpr bndr bdee) where
@@ -542,37 +531,38 @@ instance (Outputable bndr, Outputable bdee, Ord bdee)
 
 instance (Outputable bndr, Outputable bdee, Ord bdee)
                => Outputable (GenStgRhs bndr bdee) where
-    ppr sty rhs = pprStgRhs sty rhs
+    ppr rhs = pprStgRhs rhs
 \end{code}
 
 \begin{code}
-pprStgArg :: (Outputable bdee) => PprStyle -> GenStgArg bdee -> Pretty
+pprStgArg :: (Outputable bdee) => GenStgArg bdee -> SDoc
 
-pprStgArg sty (StgVarArg var) = ppr sty var
-pprStgArg sty (StgLitArg lit) = ppr sty lit
+pprStgArg (StgVarArg var) = ppr var
+pprStgArg (StgConArg con) = ppr con
+pprStgArg (StgLitArg lit) = ppr lit
 \end{code}
 
 \begin{code}
-pprStgExpr :: (Outputable bndr, Outputable bdee, Ord bdee) =>
-               PprStyle -> GenStgExpr bndr bdee -> Pretty
+pprStgExpr :: (Outputable bndr, Outputable bdee, Ord bdee)
+          => GenStgExpr bndr bdee -> SDoc
 -- special case
-pprStgExpr sty (StgApp func [] lvs)
-  = ppBeside (ppr sty func) (pprStgLVs sty lvs)
+pprStgExpr (StgApp func [] lvs)
+  = (<>) (ppr func) (pprStgLVs lvs)
 
 -- general case
-pprStgExpr sty (StgApp func args lvs)
-  = ppHang (ppBeside (ppr sty func) (pprStgLVs sty lvs))
-        4 (ppSep (map (ppr sty) args))
+pprStgExpr (StgApp func args lvs)
+  = hang ((<>) (ppr func) (pprStgLVs lvs))
+        4 (sep (map (ppr) args))
 \end{code}
 
 \begin{code}
-pprStgExpr sty (StgCon con args lvs)
-  = ppBesides [ ppBeside (ppr sty con) (pprStgLVs sty lvs),
-               ppStr "! [", interppSP sty args, ppStr "]" ]
+pprStgExpr (StgCon con args lvs)
+  = hcat [ (<>) (ppr con) (pprStgLVs lvs),
+               ptext SLIT("! ["), interppSP args, char ']' ]
 
-pprStgExpr sty (StgPrim op args lvs)
-  = ppBesides [ ppr sty op, ppChar '#', pprStgLVs sty lvs,
-               ppStr " [", interppSP sty args, ppStr "]" ]
+pprStgExpr (StgPrim op args lvs)
+  = hcat [ ppr op, char '#', pprStgLVs lvs,
+               ptext SLIT(" ["), interppSP args, char ']' ]
 \end{code}
 
 \begin{code}
@@ -584,140 +574,135 @@ pprStgExpr sty (StgPrim op args lvs)
 --
 -- Very special!  Suspicious! (SLPJ)
 
-pprStgExpr sty (StgLet (StgNonRec bndr (StgRhsClosure cc bi free_vars upd_flag args rhs))
+pprStgExpr (StgLet (StgNonRec bndr (StgRhsClosure cc bi free_vars upd_flag args rhs))
                        expr@(StgLet _ _))
-  = ppAbove
-      (ppHang (ppBesides [ppStr "let { ", ppr sty bndr, ppStr " = ",
-                         ppStr (showCostCentre sty True{-as string-} cc),
-                         pp_binder_info sty bi,
-                         ppStr " [", ifPprDebug sty (interppSP sty free_vars), ppStr "] \\",
-                         ppr sty upd_flag, ppStr " [",
-                         interppSP sty args, ppStr "]"])
-           8 (ppSep [ppCat [ppr sty rhs, ppStr "} in"]]))
-      (ppr sty expr)
+  = ($$)
+      (hang (hcat [ptext SLIT("let { "), ppr bndr, ptext SLIT(" = "),
+                         text (showCostCentre True{-as string-} cc),
+                         pp_binder_info bi,
+                         ptext SLIT(" ["), ifPprDebug (interppSP free_vars), ptext SLIT("] \\"),
+                         ppr upd_flag, ptext SLIT(" ["),
+                         interppSP args, char ']'])
+           8 (sep [hsep [ppr rhs, ptext SLIT("} in")]]))
+      (ppr expr)
 
 -- special case: let ... in let ...
 
-pprStgExpr sty (StgLet bind expr@(StgLet _ _))
-  = ppAbove
-      (ppSep [ppHang (ppStr "let {") 2 (ppCat [pprStgBinding sty bind, ppStr "} in"])])
-      (ppr sty expr)
+pprStgExpr (StgLet bind expr@(StgLet _ _))
+  = ($$)
+      (sep [hang (ptext SLIT("let {")) 2 (hsep [pprGenStgBinding bind, ptext SLIT("} in")])])
+      (ppr expr)
 
 -- general case
-pprStgExpr sty (StgLet bind expr)
-  = ppSep [ppHang (ppStr "let {") 2 (pprStgBinding sty bind),
-          ppHang (ppStr "} in ") 2 (ppr sty expr)]
-
-pprStgExpr sty (StgLetNoEscape lvs_whole lvs_rhss bind expr)
-  = ppSep [ppHang (ppStr "let-no-escape {")
-               2 (pprStgBinding sty bind),
-          ppHang (ppBeside (ppStr "} in ")
-                  (ifPprDebug sty (
-                   ppNest 4 (
-                     ppBesides [ppStr  "-- lvs: [", interppSP sty (uniqSetToList lvs_whole),
-                            ppStr "]; rhs lvs: [", interppSP sty (uniqSetToList lvs_rhss),
-                            ppStr "]"]))))
-               2 (ppr sty expr)]
+pprStgExpr (StgLet bind expr)
+  = sep [hang (ptext SLIT("let {")) 2 (pprGenStgBinding bind),
+          hang (ptext SLIT("} in ")) 2 (ppr expr)]
+
+pprStgExpr (StgLetNoEscape lvs_whole lvs_rhss bind expr)
+  = sep [hang (ptext SLIT("let-no-escape {"))
+               2 (pprGenStgBinding bind),
+          hang ((<>) (ptext SLIT("} in "))
+                  (ifPprDebug (
+                   nest 4 (
+                     hcat [ptext  SLIT("-- lvs: ["), interppSP (uniqSetToList lvs_whole),
+                            ptext SLIT("]; rhs lvs: ["), interppSP (uniqSetToList lvs_rhss),
+                            char ']']))))
+               2 (ppr expr)]
 \end{code}
 
 \begin{code}
-pprStgExpr sty (StgSCC ty cc expr)
-  = ppSep [ ppCat [ppStr "_scc_", ppStr (showCostCentre sty True{-as string-} cc)],
-           pprStgExpr sty expr ]
+pprStgExpr (StgSCC ty cc expr)
+  = sep [ hsep [ptext SLIT("_scc_"), text (showCostCentre True{-as string-} cc)],
+           pprStgExpr expr ]
 \end{code}
 
 \begin{code}
-pprStgExpr sty (StgCase expr lvs_whole lvs_rhss uniq alts)
-  = ppSep [ppSep [ppStr "case",
-          ppNest 4 (ppCat [pprStgExpr sty expr,
-            ifPprDebug sty (ppBeside (ppStr "::") (pp_ty alts))]),
-          ppStr "of {"],
-          ifPprDebug sty (
-          ppNest 4 (
-            ppBesides [ppStr  "-- lvs: [", interppSP sty (uniqSetToList lvs_whole),
-                   ppStr "]; rhs lvs: [", interppSP sty (uniqSetToList lvs_rhss),
-                   ppStr "]; uniq: ", pprUnique uniq])),
-          ppNest 2 (ppr_alts sty alts),
-          ppStr "}"]
+pprStgExpr (StgCase expr lvs_whole lvs_rhss uniq alts)
+  = sep [sep [ptext SLIT("case"),
+          nest 4 (hsep [pprStgExpr expr,
+            ifPprDebug (ptext SLIT("::") <> pp_ty alts)]),
+          ptext SLIT("of {")],
+          ifPprDebug (
+          nest 4 (
+            hcat [ptext  SLIT("-- lvs: ["), interppSP (uniqSetToList lvs_whole),
+                   ptext SLIT("]; rhs lvs: ["), interppSP (uniqSetToList lvs_rhss),
+                   ptext SLIT("]; uniq: "), pprUnique uniq])),
+          nest 2 (ppr_alts alts),
+          char '}']
   where
-    pp_ty (StgAlgAlts  ty _ _) = ppr sty ty
-    pp_ty (StgPrimAlts ty _ _) = ppr sty ty
-
-    ppr_alts sty (StgAlgAlts ty alts deflt)
-      = ppAboves [ ppAboves (map (ppr_bxd_alt sty) alts),
-                  ppr_default sty deflt ]
+    ppr_default StgNoDefault = empty
+    ppr_default (StgBindDefault bndr used expr)
+      = hang (hsep [pp_binder, ptext SLIT("->")]) 4 (ppr expr)
       where
-       ppr_bxd_alt sty (con, params, use_mask, expr)
-         = ppHang (ppCat [ppr_con sty con, interppSP sty params, ppStr "->"])
-                  4 (ppBeside (ppr sty expr) ppSemi)
-         where
-           ppr_con sty con
-             = if isSymLexeme con
-               then ppBesides [ppLparen, ppr sty con, ppRparen]
-               else ppr sty con
-
-    ppr_alts sty (StgPrimAlts ty alts deflt)
-      = ppAboves [ ppAboves (map (ppr_ubxd_alt sty) alts),
-                  ppr_default sty deflt ]
+       pp_binder = if used then ppr bndr else char '_'
+
+    pp_ty (StgAlgAlts  ty _ _) = ppr ty
+    pp_ty (StgPrimAlts ty _ _) = ppr ty
+
+    ppr_alts (StgAlgAlts ty alts deflt)
+      = vcat [ vcat (map (ppr_bxd_alt) alts),
+                  ppr_default deflt ]
       where
-       ppr_ubxd_alt sty (lit, expr)
-         = ppHang (ppCat [ppr sty lit, ppStr "->"])
-                4 (ppBeside (ppr sty expr) ppSemi)
+       ppr_bxd_alt (con, params, use_mask, expr)
+         = hang (hsep [ppr con, interppSP params, ptext SLIT("->")])
+                  4 ((<>) (ppr expr) semi)
 
-    ppr_default sty StgNoDefault = ppNil
-    ppr_default sty (StgBindDefault bndr used expr)
-      = ppHang (ppCat [pp_binder, ppStr "->"]) 4 (ppr sty expr)
+    ppr_alts (StgPrimAlts ty alts deflt)
+      = vcat [ vcat (map (ppr_ubxd_alt) alts),
+                  ppr_default deflt ]
       where
-       pp_binder = if used then ppr sty bndr else ppChar '_'
+       ppr_ubxd_alt (lit, expr)
+         = hang (hsep [ppr lit, ptext SLIT("->")])
+                4 ((<>) (ppr expr) semi)
 \end{code}
 
 \begin{code}
--- pprStgLVs :: PprStyle -> GenStgLiveVars occ -> Pretty
-
-pprStgLVs PprForUser lvs = ppNil
-
-pprStgLVs sty lvs
-  = if isEmptyUniqSet lvs then
-       ppNil
+pprStgLVs :: Outputable occ => GenStgLiveVars occ -> SDoc
+pprStgLVs lvs
+  = getPprStyle $ \ sty ->
+    if userStyle sty || isEmptyUniqSet lvs then
+       empty
     else
-       ppBesides [ppStr "{-lvs:", interpp'SP sty (uniqSetToList lvs), ppStr "-}"]
+       hcat [text "{-lvs:", interpp'SP (uniqSetToList lvs), text "-}"]
 \end{code}
 
 \begin{code}
-pprStgRhs :: (Outputable bndr, Outputable bdee, Ord bdee) =>
-               PprStyle -> GenStgRhs bndr bdee -> Pretty
+pprStgRhs :: (Outputable bndr, Outputable bdee, Ord bdee)
+         => GenStgRhs bndr bdee -> SDoc
 
 -- special case
-pprStgRhs sty (StgRhsClosure cc bi [free_var] upd_flag [{-no args-}] (StgApp func [] lvs))
-  = ppBesides [ ppStr (showCostCentre sty True{-as String-} cc),
-               pp_binder_info sty bi,
-               ppStr " [", ifPprDebug sty (ppr sty free_var),
-           ppStr "] \\", ppr sty upd_flag, ppStr " [] ", ppr sty func ]
+pprStgRhs (StgRhsClosure cc bi [free_var] upd_flag [{-no args-}] (StgApp func [] lvs))
+  = hcat [ text (showCostCentre True{-as String-} cc),
+          pp_binder_info bi,
+          brackets (ifPprDebug (ppr free_var)),
+          ptext SLIT(" \\"), ppr upd_flag, ptext SLIT(" [] "), ppr func ]
+
 -- general case
-pprStgRhs sty (StgRhsClosure cc bi free_vars upd_flag args body)
-  = ppHang (ppBesides [ ppStr (showCostCentre sty True{-as String-} cc),
-               pp_binder_info sty bi,
-               ppStr " [", ifPprDebug sty (interppSP sty free_vars),
-               ppStr "] \\", ppr sty upd_flag, ppStr " [", interppSP sty args, ppStr "]"])
-        4 (ppr sty body)
+pprStgRhs (StgRhsClosure cc bi free_vars upd_flag args body)
+  = hang (hcat [text (showCostCentre True{-as String-} cc),
+               pp_binder_info bi,
+               brackets (ifPprDebug (interppSP free_vars)),
+               ptext SLIT(" \\"), ppr upd_flag, brackets (interppSP args)])
+        4 (ppr body)
 
-pprStgRhs sty (StgRhsCon cc con args)
-  = ppBesides [ ppStr (showCostCentre sty True{-as String-} cc),
-               ppSP, ppr sty con, ppStr " [", interppSP sty args, ppStr "]" ]
+pprStgRhs (StgRhsCon cc con args)
+  = hcat [ text (showCostCentre True{-as String-} cc),
+          space, ppr con, ptext SLIT("! "), brackets (interppSP args)]
 
 --------------
-pp_binder_info PprForUser _ = ppNil
 
-pp_binder_info sty NoStgBinderInfo = ppNil
+pp_binder_info NoStgBinderInfo = empty
 
 -- cases so boring that we print nothing
-pp_binder_info sty (StgBinderInfo True b c d e) = ppNil
+pp_binder_info (StgBinderInfo True b c d e) = empty
 
 -- general case
-pp_binder_info sty (StgBinderInfo a b c d e)
-  = ppBesides [ppChar '(', ppInterleave ppComma (map pp_bool [a,b,c,d,e]), ppChar ')']
-  where
-    pp_bool x = ppr (panic "pp_bool") x
+pp_binder_info (StgBinderInfo a b c d e)
+  = getPprStyle $ \ sty -> 
+    if userStyle sty then
+       empty
+    else
+       parens (hsep (punctuate comma (map ppr [a,b,c,d,e])))
 \end{code}
 
 Collect @IdInfo@ stuff that is most easily just snaffled straight