summaryrefslogtreecommitdiff
path: root/compiler/parser
diff options
context:
space:
mode:
authorGeoffrey Mainland <mainland@apeiron.net>2013-05-20 11:37:59 +0100
committerGeoffrey Mainland <mainland@apeiron.net>2013-10-04 17:22:48 -0400
commit5246e123b2877ee69ad26e8b14cbac5feb0ec7ca (patch)
tree54d07cd5ad6f22c2c746b2d1c5f194298de87c30 /compiler/parser
parentdb6cb1139cb2149e9fb5815e381e0cd9032ad9f8 (diff)
downloadhaskell-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.pp34
-rw-r--r--compiler/parser/RdrHsSyn.lhs12
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