summaryrefslogtreecommitdiff
path: root/compiler/parser
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/parser')
-rw-r--r--compiler/parser/Parser.y52
-rw-r--r--compiler/parser/RdrHsSyn.hs54
2 files changed, 83 insertions, 23 deletions
diff --git a/compiler/parser/Parser.y b/compiler/parser/Parser.y
index d72f50d871..e4ff162181 100644
--- a/compiler/parser/Parser.y
+++ b/compiler/parser/Parser.y
@@ -33,6 +33,7 @@ import Control.Monad ( unless, liftM )
import GHC.Exts
import Data.Char
import Control.Monad ( mplus )
+import Control.Applicative ((<$))
-- compiler/hsSyn
import HsSyn
@@ -79,6 +80,7 @@ import TysWiredIn ( unitTyCon, unitDataCon, tupleTyCon, tupleDataCon, nilD
-- compiler/utils
import Util ( looksLikePackageName )
+import Prelude
}
@@ -632,9 +634,8 @@ exp_doc :: { OrdList (LIE RdrName) }
-- No longer allow things like [] and (,,,) to be exported
-- They are built in syntax, always available
export :: { OrdList (LIE RdrName) }
- : qcname_ext export_subspec {% amsu (sLL $1 $> (mkModuleImpExp $1
- (snd $ unLoc $2)))
- (fst $ unLoc $2) }
+ : qcname_ext export_subspec {% mkModuleImpExp $1 (snd $ unLoc $2)
+ >>= \ie -> amsu (sLL $1 $> ie) (fst $ unLoc $2) }
| 'module' modid {% amsu (sLL $1 $> (IEModuleContents $2))
[mj AnnModule $1] }
| 'pattern' qcon {% amsu (sLL $1 $> (IEVar $2))
@@ -642,18 +643,34 @@ export :: { OrdList (LIE RdrName) }
export_subspec :: { Located ([AddAnn],ImpExpSubSpec) }
: {- empty -} { sL0 ([],ImpExpAbs) }
- | '(' '..' ')' { sLL $1 $> ([mop $1,mcp $3,mj AnnDotdot $2]
- , ImpExpAll) }
- | '(' ')' { sLL $1 $> ([mop $1,mcp $2],ImpExpList []) }
- | '(' qcnames ')' { sLL $1 $> ([mop $1,mcp $3],ImpExpList (reverse $2)) }
-
-qcnames :: { [Located RdrName] } -- A reversed list
- : qcnames ',' qcname_ext {% (aa (head $1) (AnnComma, $2)) >>
- return ($3 : $1) }
- | qcname_ext { [$1] }
-
-qcname_ext :: { Located RdrName } -- Variable or data constructor
- -- or tagged type constructor
+ | '(' qcnames ')' {% mkImpExpSubSpec (reverse (snd $2))
+ >>= \(as,ie) -> return $ sLL $1 $>
+ (as ++ [mop $1,mcp $3] ++ fst $2, ie) }
+
+
+qcnames :: { ([AddAnn], [Located (Maybe RdrName)]) }
+ : {- empty -} { ([],[]) }
+ | qcnames1 { $1 }
+
+qcnames1 :: { ([AddAnn], [Located (Maybe RdrName)]) } -- A reversed list
+ : qcnames1 ',' qcname_ext_w_wildcard {% case (last (snd $1)) of
+ l@(L _ Nothing) ->
+ return ([mj AnnComma $2, mj AnnDotdot l]
+ ,($3 : snd $1))
+ l -> (aa l (AnnComma, $2) >>
+ return (fst $1, $3 : snd $1)) }
+
+
+ -- Annotations readded in mkImpExpSubSpec
+ | qcname_ext_w_wildcard { ([],[$1]) }
+
+-- Variable, data constructor or wildcard
+-- or tagged type constructor
+qcname_ext_w_wildcard :: { Located (Maybe RdrName) }
+ : qcname_ext { Just `fmap` $1 }
+ | '..' { Nothing <$ $1 }
+
+qcname_ext :: { Located RdrName }
: qcname { $1 }
| 'type' oqtycon {% amms (mkTypeImpExp (sLL $1 $> (unLoc $2)))
[mj AnnType $1,mj AnnVal $2] }
@@ -726,7 +743,10 @@ maybeas :: { ([AddAnn],Located (Maybe ModuleName)) }
| {- empty -} { ([],noLoc Nothing) }
maybeimpspec :: { Located (Maybe (Bool, Located [LIE RdrName])) }
- : impspec { L (gl $1) (Just (unLoc $1)) }
+ : impspec {% let (b, ie) = unLoc $1 in
+ checkImportSpec ie
+ >>= \checkedIe ->
+ return (L (gl $1) (Just (b, checkedIe))) }
| {- empty -} { noLoc Nothing }
impspec :: { Located (Bool, Located [LIE RdrName]) }
diff --git a/compiler/parser/RdrHsSyn.hs b/compiler/parser/RdrHsSyn.hs
index 2d2b43b480..b24ba0968a 100644
--- a/compiler/parser/RdrHsSyn.hs
+++ b/compiler/parser/RdrHsSyn.hs
@@ -56,7 +56,9 @@ module RdrHsSyn (
-- Help with processing exports
ImpExpSubSpec(..),
mkModuleImpExp,
- mkTypeImpExp
+ mkTypeImpExp,
+ mkImpExpSubSpec,
+ checkImportSpec
) where
@@ -87,6 +89,7 @@ import FastString
import Maybes
import Util
import ApiAnnotation
+import Data.List
#if __GLASGOW_HASKELL__ < 709
import Control.Applicative ((<$>))
@@ -1328,16 +1331,31 @@ mkExtName rdrNm = mkFastString (occNameString (rdrNameOcc rdrNm))
--------------------------------------------------------------------------------
-- Help with module system imports/exports
-data ImpExpSubSpec = ImpExpAbs | ImpExpAll | ImpExpList [Located RdrName]
+data ImpExpSubSpec = ImpExpAbs
+ | ImpExpAll
+ | ImpExpList [Located RdrName]
+ | ImpExpAllWith [Located (Maybe RdrName)]
-mkModuleImpExp :: Located RdrName -> ImpExpSubSpec -> IE RdrName
+mkModuleImpExp :: Located RdrName -> ImpExpSubSpec -> P (IE RdrName)
mkModuleImpExp n@(L l name) subs =
case subs of
ImpExpAbs
- | isVarNameSpace (rdrNameSpace name) -> IEVar n
- | otherwise -> IEThingAbs (L l name)
- ImpExpAll -> IEThingAll (L l name)
- ImpExpList xs -> IEThingWith (L l name) xs []
+ | isVarNameSpace (rdrNameSpace name) -> return $ IEVar n
+ | otherwise -> return $ IEThingAbs (L l name)
+ ImpExpAll -> return $ IEThingAll (L l name)
+ ImpExpList xs ->
+ return $ IEThingWith (L l name) NoIEWildcard xs []
+ ImpExpAllWith xs ->
+ do allowed <- extension patternSynonymsEnabled
+ if allowed
+ then
+ let withs = map unLoc xs
+ pos = maybe NoIEWildcard IEWildcard
+ (findIndex isNothing withs)
+ ies = [L l n | L l (Just n) <- xs]
+ in return (IEThingWith (L l name) pos ies [])
+ else parseErrorSDoc l
+ (text "Illegal export form (use PatternSynonyms to enable)")
mkTypeImpExp :: Located RdrName -- TcCls or Var name space
-> P (Located RdrName)
@@ -1348,6 +1366,28 @@ mkTypeImpExp name =
else parseErrorSDoc (getLoc name)
(text "Illegal keyword 'type' (use ExplicitNamespaces to enable)")
+checkImportSpec :: Located [LIE RdrName] -> P (Located [LIE RdrName])
+checkImportSpec ie@(L _ specs) =
+ case [l | (L l (IEThingWith _ (IEWildcard _) _ _)) <- specs] of
+ [] -> return ie
+ (l:_) -> importSpecError l
+ where
+ importSpecError l =
+ parseErrorSDoc l
+ (text "Illegal import form, this syntax can only be used to bundle"
+ $+$ text "pattern synonyms with types in module exports.")
+
+-- In the correct order
+mkImpExpSubSpec :: [Located (Maybe RdrName)] -> P ([AddAnn], ImpExpSubSpec)
+mkImpExpSubSpec [] = return ([], ImpExpList [])
+mkImpExpSubSpec [L l Nothing] =
+ return ([\s -> addAnnotation l AnnDotdot s], ImpExpAll)
+mkImpExpSubSpec xs =
+ if (any (isNothing . unLoc) xs)
+ then return $ ([], ImpExpAllWith xs)
+ else return $ ([], ImpExpList ([L l x | L l (Just x) <- xs]))
+
+
-----------------------------------------------------------------------------
-- Misc utils