[commit: ghc] wip/T8584: Add parser for pattern synonym type signatures. Syntax is of the form (b99afa8)

git at git.haskell.org git at git.haskell.org
Wed Nov 12 12:05:54 UTC 2014


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/T8584
Link       : http://ghc.haskell.org/trac/ghc/changeset/b99afa87a790532259e949ed987da50573742daa/ghc

>---------------------------------------------------------------

commit b99afa87a790532259e949ed987da50573742daa
Author: Dr. ERDI Gergo <gergo at erdi.hu>
Date:   Tue Nov 11 18:54:14 2014 +0800

    Add parser for pattern synonym type signatures.
    Syntax is of the form
    
        pattern P :: (Prov b) => (Req a) => a -> b -> Int -> T a
    
    which declares a pattern synonym called `P`, with argument types `a`, `b`,
    and `Int`, and result type `T a`, with provided context `(Prov b)` and required
    context `(Req a)`.


>---------------------------------------------------------------

b99afa87a790532259e949ed987da50573742daa
 compiler/parser/Parser.y    | 51 +++++++++++++++++++++++++++++++--------------
 compiler/parser/RdrHsSyn.hs | 27 +++++-------------------
 2 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/compiler/parser/Parser.y b/compiler/parser/Parser.y
index 1123375..0cceb09 100644
--- a/compiler/parser/Parser.y
+++ b/compiler/parser/Parser.y
@@ -860,29 +860,47 @@ role : VARID             { sL1 $1 $ Just $ getVARID $1 }
 
 -- Glasgow extension: pattern synonyms
 pattern_synonym_decl :: { LHsDecl RdrName }
-        : 'pattern' pat '=' pat
-            {% do { (name, args) <- splitPatSyn $2
-                  ; return $ sLL $1 $> . ValD $ mkPatSynBind name args $4 ImplicitBidirectional
-                  }}
-        | 'pattern' pat '<-' pat
-            {% do { (name, args) <- splitPatSyn $2
-                  ; return $ sLL $1 $> . ValD $ mkPatSynBind name args $4 Unidirectional
-                  }}
-        | 'pattern' pat '<-' pat where_decls
-            {% do { (name, args) <- splitPatSyn $2
-                  ; mg <- toPatSynMatchGroup name $5
+        : 'pattern' pattern_synonym_lhs '=' pat
+            { let (name, args) = $2
+              in sLL $1 $> . ValD $ mkPatSynBind name args $4 ImplicitBidirectional }
+        | 'pattern' pattern_synonym_lhs '<-' pat
+            { let (name, args) = $2
+              in sLL $1 $> . ValD $ mkPatSynBind name args $4 Unidirectional }
+        | 'pattern' pattern_synonym_lhs '<-' pat where_decls
+            {% do { let (name, args) = $2
+                  ; mg <- mkPatSynMatchGroup name $5
                   ; return $ sLL $1 $> . ValD $
-                    mkPatSynBind name args $4 (ExplicitBidirectional mg)
-                  }}
+                    mkPatSynBind name args $4 (ExplicitBidirectional mg) }}
 
-where_decls :: { Located (OrdList (LHsDecl RdrName)) }
-        : 'where' '{' decls '}'       { $3 }
-        | 'where' vocurly decls close { $3 }
+pattern_synonym_lhs :: { (Located RdrName, HsPatSynDetails (Located RdrName)) }
+        : con vars0 { ($1, PrefixPatSyn $2) }
+        | varid consym varid { ($2, InfixPatSyn $1 $3) }
 
 vars0 :: { [Located RdrName] }
         : {- empty -}                 { [] }
         | varid vars0                 { $1 : $2 }
 
+where_decls :: { Located (OrdList (LHsDecl RdrName)) }
+        : 'where' '{' decls '}'       { $3 }
+        | 'where' vocurly decls close { $3 }
+
+pattern_synonym_sig :: { LSig RdrName }
+        : 'pattern' con '::' ptype
+            { let (flag, qtvs, prov, req, ty) = unLoc $4
+              in sLL $1 $> $ PatSynSig $2 (flag, mkHsQTvs qtvs) prov req ty }
+
+ptype :: { Located (HsExplicitFlag, [LHsTyVarBndr RdrName], LHsContext RdrName, LHsContext RdrName, LHsType RdrName) }
+        : 'forall' tv_bndrs '.' ptype
+            {% do { hintExplicitForall (getLoc $1)
+                  ; let (_, qtvs', prov, req, ty) = unLoc $4
+                  ; return $ sLL $1 $> (Explicit, $2 ++ qtvs', prov, req ,ty) }}
+        | context '=>' context '=>' type
+            { sLL $1 $> (Implicit, [], $1, $3, $5) }
+        | context '=>' type
+            { sLL $1 $> (Implicit, [], $1, noLoc [], $3) }
+        | type
+            { sL1 $1 (Implicit, [], noLoc [], noLoc [], $1) }
+
 -----------------------------------------------------------------------------
 -- Nested declarations
 
@@ -1490,6 +1508,7 @@ sigdecl :: { Located (OrdList (LHsDecl RdrName)) }
                                 { sLL $1 $> $ toOL [ sLL $1 $> $ SigD (TypeSig ($1 : reverse (unLoc $3)) $5) ] }
         | infix prec ops        { sLL $1 $> $ toOL [ sLL $1 $> $ SigD (FixSig (FixitySig n (Fixity $2 (unLoc $1))))
                                              | n <- unLoc $3 ] }
+        | pattern_synonym_sig   { sLL $1 $> $ unitOL $ sLL $1 $> . SigD . unLoc $ $1 }
         | '{-# INLINE' activation qvar '#-}'
                 { sLL $1 $> $ unitOL (sLL $1 $> $ SigD (InlineSig $3 (mkInlinePragma (getINLINE $1) $2))) }
         | '{-# SPECIALISE' activation qvar '::' sigtypes1 '#-}'
diff --git a/compiler/parser/RdrHsSyn.hs b/compiler/parser/RdrHsSyn.hs
index 625c4dc..e945e43 100644
--- a/compiler/parser/RdrHsSyn.hs
+++ b/compiler/parser/RdrHsSyn.hs
@@ -18,7 +18,7 @@ module RdrHsSyn (
         mkTyFamInst,
         mkFamDecl,
         splitCon, mkInlinePragma,
-        splitPatSyn, toPatSynMatchGroup,
+        mkPatSynMatchGroup,
         mkRecConstrOrUpdate, -- HsExp -> [HsFieldUpdate] -> P HsExp
         mkTyClD, mkInstD,
 
@@ -414,33 +414,16 @@ splitCon ty
    mk_rest [L _ (HsRecTy flds)] = RecCon flds
    mk_rest ts                   = PrefixCon ts
 
-splitPatSyn :: LPat RdrName
-      -> P (Located RdrName, HsPatSynDetails (Located RdrName))
-splitPatSyn (L _ (ParPat pat)) = splitPatSyn pat
-splitPatSyn pat@(L loc (ConPatIn con details)) = do
-    details' <- case details of
-        PrefixCon pats     -> liftM PrefixPatSyn (mapM patVar pats)
-        InfixCon pat1 pat2 -> liftM2 InfixPatSyn (patVar pat1) (patVar pat2)
-        RecCon{}           -> recordPatSynErr loc pat
-    return (con, details')
-  where
-    patVar :: LPat RdrName -> P (Located RdrName)
-    patVar (L loc (VarPat v))   = return $ L loc v
-    patVar (L _   (ParPat pat)) = patVar pat
-    patVar (L loc pat)          = parseErrorSDoc loc $
-                                  text "Pattern synonym arguments must be variable names:" $$
-                                  ppr pat
-splitPatSyn pat@(L loc _) = parseErrorSDoc loc $
-                            text "invalid pattern synonym declaration:" $$ ppr pat
-
 recordPatSynErr :: SrcSpan -> LPat RdrName -> P a
 recordPatSynErr loc pat =
     parseErrorSDoc loc $
     text "record syntax not supported for pattern synonym declarations:" $$
     ppr pat
 
-toPatSynMatchGroup :: Located RdrName -> Located (OrdList (LHsDecl RdrName)) -> P (MatchGroup RdrName (LHsExpr RdrName))
-toPatSynMatchGroup (L _ patsyn_name) (L _ decls) =
+mkPatSynMatchGroup :: Located RdrName
+                   -> Located (OrdList (LHsDecl RdrName))
+                   -> P (MatchGroup RdrName (LHsExpr RdrName))
+mkPatSynMatchGroup (L _ patsyn_name) (L _ decls) =
     do { matches <- mapM fromDecl (fromOL decls)
        ; return $ mkMatchGroup FromSource matches }
   where



More information about the ghc-commits mailing list