diff options
author | Geoffrey Mainland <mainland@apeiron.net> | 2013-05-20 11:37:59 +0100 |
---|---|---|
committer | Geoffrey Mainland <mainland@apeiron.net> | 2013-10-04 17:22:48 -0400 |
commit | 5246e123b2877ee69ad26e8b14cbac5feb0ec7ca (patch) | |
tree | 54d07cd5ad6f22c2c746b2d1c5f194298de87c30 /compiler/parser | |
parent | db6cb1139cb2149e9fb5815e381e0cd9032ad9f8 (diff) | |
download | haskell-5246e123b2877ee69ad26e8b14cbac5feb0ec7ca.tar.gz |
Add full support for declaration splices.
Since declaration splices are now untyped, they can be used anywhere a
declaration is valid, including in declaration brackets.
Diffstat (limited to 'compiler/parser')
-rw-r--r-- | compiler/parser/Parser.y.pp | 34 | ||||
-rw-r--r-- | compiler/parser/RdrHsSyn.lhs | 12 |
2 files changed, 29 insertions, 17 deletions
diff --git a/compiler/parser/Parser.y.pp b/compiler/parser/Parser.y.pp index 97276b8350..b520d62fbc 100644 --- a/compiler/parser/Parser.y.pp +++ b/compiler/parser/Parser.y.pp @@ -599,13 +599,13 @@ topdecl :: { OrdList (LHsDecl RdrName) } VectD (HsVectTypeIn True $3 (Just $5)) } | '{-# VECTORISE' 'class' gtycon '#-}' { unitOL $ LL $ VectD (HsVectClassIn $3) } | annotation { unitOL $1 } - | decl { unLoc $1 } + | decl_no_th { unLoc $1 } -- Template Haskell Extension -- The $(..) form is one possible form of infixexp -- but we treat an arbitrary expression just as if -- it had a $(..) wrapped around it - | infixexp { unitOL (LL $ mkTopSpliceDecl $1) } + | infixexp { unitOL (LL $ mkSpliceDecl $1) } -- Type classes -- @@ -1367,7 +1367,7 @@ docdecld :: { LDocDecl } | docnamed { L1 (case (unLoc $1) of (n, doc) -> DocCommentNamed n doc) } | docsection { L1 (case (unLoc $1) of (n, doc) -> DocGroup n doc) } -decl :: { Located (OrdList (LHsDecl RdrName)) } +decl_no_th :: { Located (OrdList (LHsDecl RdrName)) } : sigdecl { $1 } | '!' aexp rhs {% do { let { e = LL (SectionR (LL (HsVar bang_RDR)) $2) }; @@ -1383,6 +1383,14 @@ decl :: { Located (OrdList (LHsDecl RdrName)) } return $! (sL l (unitOL $! (sL l $ ValD r))) } } | docdecl { LL $ unitOL $1 } +decl :: { Located (OrdList (LHsDecl RdrName)) } + : decl_no_th { $1 } + + -- Why do we only allow naked declaration splices in top-level + -- declarations and not here? Short answer: because readFail009 + -- fails terribly with a panic in cvBindsAndSigs otherwise. + | splice_exp { LL $ unitOL (LL $ mkSpliceDecl $1) } + rhs :: { Located (GRHSs RdrName (LHsExpr RdrName)) } : '=' exp wherebinds { sL (comb3 $1 $2 $3) $ GRHSs (unguardedRHS $2) (unLoc $3) } | gdrhs wherebinds { LL $ GRHSs (reverse (unLoc $1)) (unLoc $2) } @@ -1552,15 +1560,7 @@ aexp2 :: { LHsExpr RdrName } | '_' { L1 EWildPat } -- Template Haskell Extension - | TH_ID_SPLICE { L1 $ mkHsSpliceE - (L1 $ HsVar (mkUnqual varName - (getTH_ID_SPLICE $1))) } - | '$(' exp ')' { LL $ mkHsSpliceE $2 } - | TH_ID_TY_SPLICE { L1 $ mkHsSpliceTE - (L1 $ HsVar (mkUnqual varName - (getTH_ID_TY_SPLICE $1))) } - | '$$(' exp ')' { LL $ mkHsSpliceTE $2 } - + | splice_exp { $1 } | SIMPLEQUOTE qvar { LL $ HsBracket (VarBr True (unLoc $2)) } | SIMPLEQUOTE qcon { LL $ HsBracket (VarBr True (unLoc $2)) } @@ -1577,6 +1577,16 @@ aexp2 :: { LHsExpr RdrName } -- arrow notation extension | '(|' aexp2 cmdargs '|)' { LL $ HsArrForm $2 Nothing (reverse $3) } +splice_exp :: { LHsExpr RdrName } + : TH_ID_SPLICE { L1 $ mkHsSpliceE + (L1 $ HsVar (mkUnqual varName + (getTH_ID_SPLICE $1))) } + | '$(' exp ')' { LL $ mkHsSpliceE $2 } + | TH_ID_TY_SPLICE { L1 $ mkHsSpliceTE + (L1 $ HsVar (mkUnqual varName + (getTH_ID_TY_SPLICE $1))) } + | '$$(' exp ')' { LL $ mkHsSpliceTE $2 } + cmdargs :: { [LHsCmdTop RdrName] } : cmdargs acmd { $2 : $1 } | {- empty -} { [] } diff --git a/compiler/parser/RdrHsSyn.lhs b/compiler/parser/RdrHsSyn.lhs index b80a3424c0..f024d5c6e6 100644 --- a/compiler/parser/RdrHsSyn.lhs +++ b/compiler/parser/RdrHsSyn.lhs @@ -7,7 +7,7 @@ Functions over HsSyn specialised to RdrName. module RdrHsSyn ( mkHsOpApp, mkHsIntegral, mkHsFractional, mkHsIsString, - mkHsDo, mkTopSpliceDecl, + mkHsDo, mkSpliceDecl, mkRoleAnnotDecl, mkClassDecl, mkTyData, mkFamInstData, @@ -215,16 +215,18 @@ reLocate :: SrcSpan -> Located a -> Located a -- a whole, rather than just the binding site reLocate loc (L _ x) = L loc x -mkTopSpliceDecl :: LHsExpr RdrName -> HsDecl RdrName +mkSpliceDecl :: LHsExpr RdrName -> HsDecl RdrName -- If the user wrote -- [pads| ... ] then return a QuasiQuoteD -- $(e) then return a SpliceD -- but if she wrote, say, -- f x then behave as if she'd written $(f x) -- ie a SpliceD -mkTopSpliceDecl (L _ (HsQuasiQuoteE qq)) = QuasiQuoteD qq -mkTopSpliceDecl (L _ (HsSpliceE (HsSplice _ _ expr))) = SpliceD (SpliceDecl expr Explicit) -mkTopSpliceDecl other_expr = SpliceD (SpliceDecl other_expr Implicit) +mkSpliceDecl (L _ (HsQuasiQuoteE qq)) = QuasiQuoteD qq +mkSpliceDecl (L loc (HsSpliceE splice)) = SpliceD (SpliceDecl (L loc splice) Explicit) +mkSpliceDecl other_expr = SpliceD (SpliceDecl (L (getLoc other_expr) splice) Implicit) + where + HsSpliceE splice = mkHsSpliceE other_expr -- Ensure a type literal is used correctly; notably, we need the proper extension enabled, -- and if it's an integer literal, the literal must be >= 0. This can occur with |