[project @ 1998-02-10 14:15:51 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcPat.lhs
index dfd92d1..061b09a 100644 (file)
@@ -4,46 +4,44 @@
 \section[TcPat]{Typechecking patterns}
 
 \begin{code}
-#include "HsVersions.h"
-
 module TcPat ( tcPat ) where
 
-import Ubiq{-uitous-}
+#include "HsVersions.h"
 
-import HsSyn           ( InPat(..), OutPat(..), HsExpr(..), HsLit(..),
-                         Match, HsBinds, Qual, PolyType,
-                         ArithSeqInfo, Stmt, Fake )
-import RnHsSyn         ( RenamedPat(..) )
-import TcHsSyn         ( TcPat(..), TcIdOcc(..) )
+import HsSyn           ( InPat(..), OutPat(..), HsLit(..), HsExpr(..) )
+import RnHsSyn         ( RenamedPat )
+import TcHsSyn         ( TcPat )
 
 import TcMonad
 import Inst            ( Inst, OverloadedLit(..), InstOrigin(..),
-                         emptyLIE, plusLIE, plusLIEs, LIE(..),
+                         emptyLIE, plusLIE, plusLIEs, LIE,
                          newMethod, newOverloadedLit
                        )
-import TcEnv           ( tcLookupGlobalValue, tcLookupGlobalValueByKey, 
-                         tcLookupLocalValueOK, tcGlobalOcc )
-import TcType          ( TcType(..), TcMaybe, tcInstType, newTyVarTy, newTyVarTys )
+import Name            ( Name {- instance Outputable -} )
+import TcEnv           ( TcIdOcc(..), tcLookupGlobalValue, tcLookupGlobalValueByKey, 
+                         tcLookupLocalValueOK, tcInstId
+                       )
+import TcType          ( TcType, TcMaybe, newTyVarTy, newTyVarTys )
 import Unify           ( unifyTauTy, unifyTauTyList, unifyTauTyLists )
 
+import Maybes          ( maybeToBool )
 import Bag             ( Bag )
 import CmdLineOpts     ( opt_IrrefutableTuples )
-import Id              ( GenId, idType )
+import Id              ( GenId, idType, Id )
 import Kind            ( Kind, mkBoxedTypeKind, mkTypeKind )
-import Maybes          ( maybeToBool )
-import Name            ( Name )
 import PprType         ( GenType, GenTyVar )
-import PrelInfo                ( charPrimTy, intPrimTy, floatPrimTy,
-                         doublePrimTy, charTy, stringTy, mkListTy,
-                         mkTupleTy, addrTy, addrPrimTy )
-import Pretty
-import Type            ( splitFunTy, splitRhoTy, splitSigmaTy, mkTyVarTys,
-                         getFunTy_maybe, maybeAppDataTyCon,
-                         Type(..), GenType
+import Type            ( splitFunTys, splitRhoTy,
+                         splitFunTy_maybe, splitAlgTyConApp_maybe,
+                         Type, GenType
                        )
 import TyVar           ( GenTyVar )
-import Unique          ( Unique, eqClassOpKey )
-import Util            ( assertPanic, panic{-ToDo:rm-} )
+import TysPrim         ( charPrimTy, intPrimTy, floatPrimTy,
+                         doublePrimTy, addrPrimTy
+                       )
+import TysWiredIn      ( charTy, stringTy, mkListTy, mkTupleTy )
+import Unique          ( Unique, eqClassOpKey, geClassOpKey, minusClassOpKey )
+import Util            ( assertPanic, panic )
+import Outputable
 \end{code}
 
 \begin{code}
@@ -58,7 +56,7 @@ tcPat :: RenamedPat -> TcM s (TcPat s, LIE s, TcType s)
 
 \begin{code}
 tcPat (VarPatIn name)
-  = tcLookupLocalValueOK "tcPat1" name `thenNF_Tc` \ id ->
+  = tcLookupLocalValueOK "tcPat1:" name                `thenNF_Tc` \ id ->
     returnTc (VarPat (TcId id), emptyLIE, idType id)
 
 tcPat (LazyPatIn pat)
@@ -72,9 +70,19 @@ tcPat pat_in@(AsPatIn name pat)
     unifyTauTy (idType id) ty          `thenTc_`
     returnTc (AsPat (TcId id) pat', lie, ty)
 
-tcPat (WildPatIn)
+tcPat WildPatIn
   = newTyVarTy mkTypeKind      `thenNF_Tc` \ tyvar_ty ->
     returnTc (WildPat tyvar_ty, emptyLIE, tyvar_ty)
+
+tcPat (NegPatIn pat)
+  = tcPat (negate_lit pat)
+  where
+    negate_lit (LitPatIn (HsInt  i)) = LitPatIn (HsInt  (-i))
+    negate_lit (LitPatIn (HsFrac f)) = LitPatIn (HsFrac (-f))
+    negate_lit _                     = panic "TcPat:negate_pat"
+
+tcPat (ParPatIn parend_pat)
+  = tcPat parend_pat
 \end{code}
 
 %************************************************************************
@@ -161,7 +169,7 @@ tcPat pat_in@(ConPatIn name pats)
              lie, 
              data_ty)
 
-tcPat pat_in@(ConOpPatIn pat1 op pat2) -- & in binary-op form...
+tcPat pat_in@(ConOpPatIn pat1 op _ pat2)       -- in binary-op form...
   = tcPat pat1                         `thenTc` \ (pat1', lie1, ty1) ->
     tcPat pat2                         `thenTc` \ (pat2', lie2, ty2) ->
 
@@ -181,33 +189,34 @@ tcPat pat_in@(ConOpPatIn pat1 op pat2) -- & in binary-op form...
 
 \begin{code}
 tcPat pat_in@(RecPatIn name rpats)
-  = tcGlobalOcc name           `thenNF_Tc` \ (con_id, _, con_rho) ->
+  = tcLookupGlobalValue name           `thenNF_Tc` \ con_id ->
+    tcInstId con_id                    `thenNF_Tc` \ (_, _, con_tau) ->
     let
-       (_, con_tau) = splitRhoTy con_rho
             -- Ignore the con_theta; overloaded constructors only
             -- behave differently when called, not when used for
             -- matching.
-       (_, record_ty) = splitFunTy con_tau
+       (_, record_ty) = splitFunTys con_tau
     in
        -- Con is syntactically constrained to be a data constructor
-    ASSERT( maybeToBool (maybeAppDataTyCon record_ty ) )
+    ASSERT( maybeToBool (splitAlgTyConApp_maybe record_ty) )
 
     mapAndUnzipTc (do_bind record_ty) rpats    `thenTc` \ (rpats', lies) ->
 
-    returnTc (panic "tcPat:RecPatIn:avoid type errors"{-RecPat con_id record_ty rpats', 
+    returnTc (RecPat con_id record_ty rpats', 
              plusLIEs lies, 
-             record_ty-})
+             record_ty)
 
   where
     do_bind expected_record_ty (field_label, rhs_pat, pun_flag)
-      = tcGlobalOcc field_label                `thenNF_Tc` \ (sel_id, _, tau) ->
+      = tcLookupGlobalValue field_label                `thenNF_Tc` \ sel_id ->
+       tcInstId sel_id                         `thenNF_Tc` \ (_, _, tau) ->
 
                -- Record selectors all have type
                --      forall a1..an.  T a1 .. an -> tau
-       ASSERT( maybeToBool (getFunTy_maybe tau) )
+       ASSERT( maybeToBool (splitFunTy_maybe tau) )
        let
                -- Selector must have type RecordType -> FieldType
-         Just (record_ty, field_ty) = getFunTy_maybe tau
+         Just (record_ty, field_ty) = splitFunTy_maybe tau
        in
        tcAddErrCtxt (recordLabel field_label) (
          unifyTauTy expected_record_ty record_ty
@@ -260,13 +269,13 @@ tcPat (LitPatIn lit@(HsDoublePrim _))
 tcPat (LitPatIn lit@(HsInt i))
   = newTyVarTy mkBoxedTypeKind                         `thenNF_Tc` \ tyvar_ty ->
     newOverloadedLit origin  
-                    (OverloadedIntegral i) tyvar_ty    `thenNF_Tc` \ (lie1, over_lit_id) ->
+                    (OverloadedIntegral i) tyvar_ty    `thenNF_Tc` \ (over_lit_expr, lie1) ->
 
     tcLookupGlobalValueByKey eqClassOpKey              `thenNF_Tc` \ eq_sel_id ->
     newMethod origin (RealId eq_sel_id) [tyvar_ty]     `thenNF_Tc` \ (lie2, eq_id) ->
 
     returnTc (NPat lit tyvar_ty (HsApp (HsVar eq_id)
-                                      (HsVar over_lit_id)),
+                                      over_lit_expr),
              lie1 `plusLIE` lie2,
              tyvar_ty)
   where
@@ -275,13 +284,13 @@ tcPat (LitPatIn lit@(HsInt i))
 tcPat (LitPatIn lit@(HsFrac f))
   = newTyVarTy mkBoxedTypeKind                         `thenNF_Tc` \ tyvar_ty ->
     newOverloadedLit origin
-                    (OverloadedFractional f) tyvar_ty  `thenNF_Tc` \ (lie1, over_lit_id) ->
+                    (OverloadedFractional f) tyvar_ty  `thenNF_Tc` \ (over_lit_expr, lie1) ->
 
     tcLookupGlobalValueByKey eqClassOpKey              `thenNF_Tc` \ eq_sel_id ->
     newMethod origin (RealId eq_sel_id) [tyvar_ty]     `thenNF_Tc` \ (lie2, eq_id) ->
 
     returnTc (NPat lit tyvar_ty (HsApp (HsVar eq_id)
-                                      (HsVar over_lit_id)),
+                                      over_lit_expr),
              lie1 `plusLIE` lie2,
              tyvar_ty)
   where
@@ -289,6 +298,30 @@ tcPat (LitPatIn lit@(HsFrac f))
 
 tcPat (LitPatIn lit@(HsLitLit s))
   = error "tcPat: can't handle ``literal-literal'' patterns"
+
+tcPat (NPlusKPatIn name lit@(HsInt i))
+  = tcLookupLocalValueOK "tcPat1:n+k" name     `thenNF_Tc` \ local ->
+    let
+       local_ty = idType local
+    in
+    tcLookupGlobalValueByKey geClassOpKey              `thenNF_Tc` \ ge_sel_id ->
+    tcLookupGlobalValueByKey minusClassOpKey           `thenNF_Tc` \ minus_sel_id ->
+
+    newOverloadedLit origin
+                    (OverloadedIntegral i) local_ty    `thenNF_Tc` \ (over_lit_expr, lie1) ->
+
+    newMethod origin (RealId ge_sel_id)    [local_ty]  `thenNF_Tc` \ (lie2, ge_id) ->
+    newMethod origin (RealId minus_sel_id) [local_ty]  `thenNF_Tc` \ (lie3, minus_id) ->
+
+    returnTc (NPlusKPat (TcId local) lit local_ty
+                       (SectionR (HsVar ge_id) over_lit_expr)
+                       (SectionR (HsVar minus_id) over_lit_expr),
+             lie1 `plusLIE` lie2 `plusLIE` lie3,
+             local_ty)
+  where
+    origin = LiteralOrigin lit -- Not very good!
+
+tcPat (NPlusKPatIn pat other) = panic "TcPat:NPlusKPat: not an HsInt literal"
 \end{code}
 
 %************************************************************************
@@ -316,21 +349,20 @@ unifies the actual args against the expected ones.
 matchConArgTys :: Name -> [TcType s] -> TcM s (Id, TcType s)
 
 matchConArgTys con arg_tys
-  = tcGlobalOcc con            `thenNF_Tc` \ (con_id, _, con_rho) ->
-    let
-       (con_theta, con_tau) = splitRhoTy con_rho
+  = tcLookupGlobalValue con            `thenNF_Tc` \ con_id ->
+    tcInstId con_id                    `thenNF_Tc` \ (_, _, con_tau) ->
             -- Ignore the con_theta; overloaded constructors only
             -- behave differently when called, not when used for
             -- matching.
-
-       (con_args, con_result) = splitFunTy con_tau
+    let
+       (con_args, con_result) = splitFunTys con_tau
        con_arity  = length con_args
        no_of_args = length arg_tys
     in
     checkTc (con_arity == no_of_args)
            (arityErr "Constructor" con_id con_arity no_of_args)        `thenTc_`
 
-    unifyTauTyLists arg_tys con_args                                   `thenTc_`
+    unifyTauTyLists con_args arg_tys                                   `thenTc_`
     returnTc (con_id, con_result)
 \end{code}
 
@@ -340,13 +372,14 @@ matchConArgTys con arg_tys
 Errors and contexts
 ~~~~~~~~~~~~~~~~~~~
 \begin{code}
-patCtxt pat sty = ppHang (ppStr "In the pattern:") 4 (ppr sty pat)
+patCtxt pat = hang (ptext SLIT("In the pattern:")) 
+                4 (ppr pat)
 
-recordLabel field_label sty
-  = ppHang (ppBesides [ppStr "When matching record field", ppr sty field_label])
-        4 (ppBesides [ppStr "with its immediately enclosing constructor"])
+recordLabel field_label
+  = hang (hcat [ptext SLIT("When matching record field"), ppr field_label])
+        4 (hcat [ptext SLIT("with its immediately enclosing constructor")])
 
-recordRhs field_label pat sty
-  = ppHang (ppStr "In the record field pattern")
-        4 (ppSep [ppr sty field_label, ppStr "=", ppr sty pat])
+recordRhs field_label pat
+  = hang (ptext SLIT("In the record field pattern"))
+        4 (sep [ppr field_label, char '=', ppr pat])
 \end{code}