[project @ 2003-01-29 10:28:56 by simonmar]
[ghc-hetmet.git] / ghc / compiler / hsSyn / HsExpr.lhs
index 874e4f1..0cdd2b2 100644 (file)
@@ -9,7 +9,7 @@ module HsExpr where
 #include "HsVersions.h"
 
 -- friends:
-import HsDecls         ( HsDecl )
+import HsDecls         ( HsGroup )
 import HsBinds         ( HsBinds(..), nullBinds )
 import HsPat           ( Pat )
 import HsLit           ( HsLit, HsOverLit )
@@ -83,12 +83,9 @@ data HsExpr id
   | HsLet      (HsBinds id)    -- let(rec)
                (HsExpr  id)
 
-  | HsWith     (HsExpr id)     -- implicit parameter binding
-               [(IPName id, HsExpr id)]
-               Bool            -- True <=> this was a 'with' binding
-                               --  (tmp, until 'with' is removed)
-
-  | HsDo       HsStmtContext
+  | HsDo       (HsStmtContext Name)    -- The parameterisation is unimportant
+                                       -- because in this context we never use
+                                       -- the PatGuard or ParStmt variant
                [Stmt id]       -- "do":one or more stmts
                [id]            -- Ids for [return,fail,>>=,>>]
                                --      Brutal but simple
@@ -162,15 +159,17 @@ data HsExpr id
                (HsExpr id)     -- expr whose cost is to be measured
                
   -- MetaHaskell Extensions
-  | HsBracket    (HsBracket id)
+  | HsBracket    (HsBracket id) SrcLoc
 
   | HsBracketOut (HsBracket Name)      -- Output of the type checker is the *original*
                 [PendingSplice]        -- renamed expression, plus *typechecked* splices
                                        -- to be pasted back in by the desugarer
 
-  | HsSplice id (HsExpr id )           -- $z  or $(f 4)
+  | HsSplice id (HsExpr id) SrcLoc     -- $z  or $(f 4)
                                        -- The id is just a unique name to 
                                        -- identify this splice point
+
+  | HsReify (HsReify id)               -- reifyType t, reifyDecl i, reifyFixity
 \end{code}
 
 
@@ -233,8 +232,7 @@ ppr_expr (HsIPVar v)     = ppr v
 ppr_expr (HsLit lit)     = ppr lit
 ppr_expr (HsOverLit lit) = ppr lit
 
-ppr_expr (HsLam match)
-  = hsep [char '\\', nest 2 (pprMatch LambdaExpr match)]
+ppr_expr (HsLam match) = pprMatch LambdaExpr match
 
 ppr_expr expr@(HsApp e1 e2)
   = let (fun, args) = collect_args expr [] in
@@ -308,10 +306,6 @@ ppr_expr (HsLet binds expr)
   = sep [hang (ptext SLIT("let")) 2 (pprBinds binds),
         hang (ptext SLIT("in"))  2 (ppr expr)]
 
-ppr_expr (HsWith expr binds is_with)
-  = sep [hang (ptext SLIT("let")) 2 (pp_ipbinds binds),
-        hang (ptext SLIT("in"))  2 (ppr expr)]
-
 ppr_expr (HsDo do_or_list_comp stmts _ _ _) = pprDo do_or_list_comp stmts
 
 ppr_expr (ExplicitList _ exprs)
@@ -388,9 +382,10 @@ ppr_expr (DictApp expr dnames)
 
 ppr_expr (HsType id) = ppr id
 
-ppr_expr (HsSplice n e)      = char '$' <> brackets (ppr n) <> pprParendExpr e
-ppr_expr (HsBracket b)       = pprHsBracket b
+ppr_expr (HsSplice n e _)    = char '$' <> brackets (ppr n) <> pprParendExpr e
+ppr_expr (HsBracket b _)     = pprHsBracket b
 ppr_expr (HsBracketOut e ps) = ppr e $$ ptext SLIT("where") <+> ppr ps
+ppr_expr (HsReify r)        = ppr r
 
 -- add parallel array brackets around a document
 --
@@ -441,12 +436,6 @@ pp_rbinds thing rbinds
     pp_rbind (v, e) = hsep [pprBndr LetBind v, char '=', ppr e]
 \end{code}
 
-\begin{code}
-pp_ipbinds :: OutputableBndr id => [(IPName id, HsExpr id)] -> SDoc
-pp_ipbinds pairs = hsep (punctuate semi (map pp_item pairs))
-                where
-                  pp_item (id,rhs) = pprBndr LetBind id <+> equals <+> ppr_expr rhs
-\end{code}
 
 
 %************************************************************************
@@ -529,7 +518,9 @@ pprMatch ctxt (Match pats maybe_ty grhss)
   where
     pp_name (FunRhs fun) = ppr fun     -- Not pprBndr; the AbsBinds will
                                        -- have printed the signature
+    pp_name LambdaExpr   = char '\\'
     pp_name other       = empty
+
     ppr_maybe_ty = case maybe_ty of
                        Just ty -> dcolon <+> ppr ty
                        Nothing -> empty
@@ -582,8 +573,13 @@ data Stmt id
        -- The ids are a subset of the variables bound by the stmts that
        -- either (a) are used before they are bound in the stmts
        -- or     (b) are used in stmts that follow the RecStmt
-  | RecStmt  [id]      
+  | RecStmt  [id]
             [Stmt id] 
+            [HsExpr id]        -- Post type-checking only; these expressions correspond
+                               -- 1-to-1 with the [id], and are the expresions that should
+                               -- be returned by the recursion.  They may not quite be the
+                               -- Ids themselves, because the Id may be polymorphic, but
+                               -- the returned thing has to be monomorphic.
 \end{code}
 
 ExprStmts and ResultStmts are a bit tricky, because what they mean
@@ -641,9 +637,9 @@ pprStmt (ParStmt stmtss)
  = hsep (map (\stmts -> ptext SLIT("| ") <> ppr stmts) stmtss)
 pprStmt (ParStmtOut stmtss)
  = hsep (map (\stmts -> ptext SLIT("| ") <> ppr stmts) stmtss)
-pprStmt (RecStmt _ segment) = vcat (map ppr segment)
+pprStmt (RecStmt _ segment _) = vcat (map ppr segment)
 
-pprDo :: OutputableBndr id => HsStmtContext -> [Stmt id] -> SDoc
+pprDo :: OutputableBndr id => HsStmtContext any -> [Stmt id] -> SDoc
 pprDo DoExpr stmts   = hang (ptext SLIT("do")) 2 (vcat (map ppr stmts))
 pprDo MDoExpr stmts  = hang (ptext SLIT("mdo")) 3 (vcat (map ppr stmts))
 pprDo ListComp stmts = pprComp brackets   stmts
@@ -667,7 +663,7 @@ pprComp brack stmts = brack $
 \begin{code}
 data HsBracket id = ExpBr (HsExpr id)
                  | PatBr (Pat id)
-                 | DecBr [HsDecl id]
+                 | DecBr (HsGroup id)
                  | TypBr (HsType id)
 
 instance OutputableBndr id => Outputable (HsBracket id) where
@@ -676,12 +672,28 @@ instance OutputableBndr id => Outputable (HsBracket id) where
 
 pprHsBracket (ExpBr e) = thBrackets empty (ppr e)
 pprHsBracket (PatBr p) = thBrackets (char 'p') (ppr p)
-pprHsBracket (DecBr d) = thBrackets (char 'd') (vcat (map ppr d))
+pprHsBracket (DecBr d) = thBrackets (char 'd') (ppr d)
 pprHsBracket (TypBr t) = thBrackets (char 't') (ppr t)
 
 
 thBrackets pp_kind pp_body = char '[' <> pp_kind <> char '|' <+> 
                             pp_body <+> ptext SLIT("|]")
+
+data HsReify id = Reify    ReifyFlavour id     -- Pre typechecking
+               | ReifyOut ReifyFlavour Name    -- Post typechecking
+                                               -- The Name could be the name of
+                                               -- an Id, TyCon, or Class
+
+data ReifyFlavour = ReifyDecl | ReifyType | ReifyFixity
+
+instance Outputable id => Outputable (HsReify id) where
+   ppr (Reify flavour id) = ppr flavour <+> ppr id
+   ppr (ReifyOut flavour thing) = ppr flavour <+> ppr thing
+
+instance Outputable ReifyFlavour where
+   ppr ReifyDecl   = ptext SLIT("reifyDecl")
+   ppr ReifyType   = ptext SLIT("reifyType")
+   ppr ReifyFixity = ptext SLIT("reifyFixity")
 \end{code}
 
 %************************************************************************
@@ -721,24 +733,27 @@ pp_dotdot = ptext SLIT(" .. ")
 %************************************************************************
 
 \begin{code}
-data HsMatchContext id -- Context of a Match or Stmt
-  = StmtCtxt HsStmtContext     -- Do-stmt or list comprehension
-  | FunRhs id          -- Function binding for f
-  | CaseAlt            -- Guard on a case alternative
-  | LambdaExpr         -- Lambda
-  | PatBindRhs         -- Pattern binding
-  | RecUpd             -- Record update
+data HsMatchContext id -- Context of a Match
+  = FunRhs id                  -- Function binding for f
+  | CaseAlt                    -- Guard on a case alternative
+  | LambdaExpr                 -- Pattern of a lambda
+  | PatBindRhs                 -- Pattern binding
+  | RecUpd                     -- Record update [used only in DsExpr to tell matchWrapper
+                               --      what sort of runtime error message to generate]
+  | StmtCtxt (HsStmtContext id)        -- Pattern of a do-stmt or list comprehension
   deriving ()
 
-data HsStmtContext 
-       = ListComp 
-       | DoExpr 
-       | MDoExpr      -- recursive do-expression
-       | PArrComp      -- parallel array comprehension
-       | PatGuard      -- Never occurs in an HsDo expression, of course
+data HsStmtContext id
+  = ListComp 
+  | DoExpr 
+  | MDoExpr                            -- Recursive do-expression
+  | PArrComp                           -- Parallel array comprehension
+  | PatGuard (HsMatchContext id)       -- Pattern guard for specified thing
+  | ParStmtCtxt (HsStmtContext id)     -- A branch of a parallel stmt 
 \end{code}
 
 \begin{code}
+isDoExpr :: HsStmtContext id -> Bool
 isDoExpr DoExpr  = True
 isDoExpr MDoExpr = True
 isDoExpr other   = False
@@ -749,33 +764,48 @@ matchSeparator (FunRhs _)   = ptext SLIT("=")
 matchSeparator CaseAlt      = ptext SLIT("->") 
 matchSeparator LambdaExpr   = ptext SLIT("->") 
 matchSeparator PatBindRhs   = ptext SLIT("=") 
-matchSeparator (StmtCtxt _)   = ptext SLIT("<-")  
-matchSeparator RecUpd       = panic "When is this used?"
+matchSeparator (StmtCtxt _) = ptext SLIT("<-")  
+matchSeparator RecUpd       = panic "unused"
 \end{code}
 
 \begin{code}
-pprMatchContext (FunRhs fun)     = ptext SLIT("In the definition of") <+> quotes (ppr fun)
-pprMatchContext CaseAlt                  = ptext SLIT("In a case alternative")
-pprMatchContext RecUpd           = ptext SLIT("In a record-update construct")
-pprMatchContext PatBindRhs       = ptext SLIT("In a pattern binding")
-pprMatchContext LambdaExpr       = ptext SLIT("In a lambda abstraction")
-pprMatchContext (StmtCtxt ctxt)   = pprStmtCtxt ctxt
-
-pprStmtCtxt PatGuard = ptext SLIT("In a pattern guard")
-pprStmtCtxt DoExpr   = ptext SLIT("In a 'do' expression pattern binding")
-pprStmtCtxt MDoExpr  = ptext SLIT("In an 'mdo' expression pattern binding")
-pprStmtCtxt ListComp = ptext SLIT("In a 'list comprehension' pattern binding")
-pprStmtCtxt PArrComp = ptext SLIT("In an 'array comprehension' pattern binding")
+pprMatchContext (FunRhs fun)     = ptext SLIT("the definition of") <+> quotes (ppr fun)
+pprMatchContext CaseAlt                  = ptext SLIT("a case alternative")
+pprMatchContext RecUpd           = ptext SLIT("a record-update construct")
+pprMatchContext PatBindRhs       = ptext SLIT("a pattern binding")
+pprMatchContext LambdaExpr       = ptext SLIT("a lambda abstraction")
+pprMatchContext (StmtCtxt ctxt)   = ptext SLIT("a pattern binding in") $$ pprStmtContext ctxt
+
+pprMatchRhsContext (FunRhs fun) = ptext SLIT("a right-hand side of function") <+> quotes (ppr fun)
+pprMatchRhsContext CaseAlt     = ptext SLIT("the body of a case alternative")
+pprMatchRhsContext PatBindRhs  = ptext SLIT("the right-hand side of a pattern binding")
+pprMatchRhsContext LambdaExpr  = ptext SLIT("the body of a lambda")
+pprMatchRhsContext RecUpd      = panic "pprMatchRhsContext"
+
+pprStmtContext (ParStmtCtxt c) = sep [ptext SLIT("a parallel branch of"), pprStmtContext c]
+pprStmtContext (PatGuard ctxt) = ptext SLIT("a pattern guard for") $$ pprMatchContext ctxt
+pprStmtContext DoExpr          = ptext SLIT("a 'do' expression")
+pprStmtContext MDoExpr         = ptext SLIT("an 'mdo' expression")
+pprStmtContext ListComp        = ptext SLIT("a list comprehension")
+pprStmtContext PArrComp        = ptext SLIT("an array comprehension")
+
+-- Used for the result statement of comprehension
+-- e.g. the 'e' in     [ e | ... ]
+--     or the 'r' in   f x = r
+pprStmtResultContext (PatGuard ctxt) = pprMatchRhsContext ctxt
+pprStmtResultContext other          = ptext SLIT("the result of") <+> pprStmtContext other
+
 
 -- Used to generate the string for a *runtime* error message
-matchContextErrString (FunRhs fun)     = "function " ++ showSDoc (ppr fun)
-matchContextErrString CaseAlt          = "case"
-matchContextErrString PatBindRhs       = "pattern binding"
-matchContextErrString RecUpd           = "record update"
-matchContextErrString LambdaExpr       = "lambda"
-matchContextErrString (StmtCtxt PatGuard) = "pattern gaurd"
-matchContextErrString (StmtCtxt DoExpr)   = "'do' expression"
-matchContextErrString (StmtCtxt MDoExpr)  = "'mdo' expression"
-matchContextErrString (StmtCtxt ListComp) = "list comprehension"
-matchContextErrString (StmtCtxt PArrComp) = "array comprehension"
+matchContextErrString (FunRhs fun)              = "function " ++ showSDoc (ppr fun)
+matchContextErrString CaseAlt                   = "case"
+matchContextErrString PatBindRhs                = "pattern binding"
+matchContextErrString RecUpd                    = "record update"
+matchContextErrString LambdaExpr                = "lambda"
+matchContextErrString (StmtCtxt (ParStmtCtxt c)) = matchContextErrString (StmtCtxt c)
+matchContextErrString (StmtCtxt (PatGuard _))   = "pattern guard"
+matchContextErrString (StmtCtxt DoExpr)         = "'do' expression"
+matchContextErrString (StmtCtxt MDoExpr)        = "'mdo' expression"
+matchContextErrString (StmtCtxt ListComp)       = "list comprehension"
+matchContextErrString (StmtCtxt PArrComp)       = "array comprehension"
 \end{code}