summaryrefslogtreecommitdiff
path: root/compiler/deSugar
diff options
context:
space:
mode:
authorMikhail Vorozhtsov <mikhail.vorozhtsov@gmail.com>2012-07-15 00:53:52 +0700
committerSimon Marlow <marlowsd@gmail.com>2012-07-16 11:09:40 +0100
commitcc456b0be3f20a1c1cef4154ae40ac18f4f6711e (patch)
tree0ca2bc0cdfabd6f4c6e3e0a94170baae71d634c0 /compiler/deSugar
parentb1e97f2f325537664f09eee7ea0e7c53264b061e (diff)
downloadhaskell-cc456b0be3f20a1c1cef4154ae40ac18f4f6711e.tar.gz
Implemented MultiWayIf extension.
Diffstat (limited to 'compiler/deSugar')
-rw-r--r--compiler/deSugar/Coverage.lhs5
-rw-r--r--compiler/deSugar/DsExpr.lhs13
-rw-r--r--compiler/deSugar/DsGRHSs.lhs10
-rw-r--r--compiler/deSugar/DsMeta.hs73
-rw-r--r--compiler/deSugar/Match.lhs1
5 files changed, 65 insertions, 37 deletions
diff --git a/compiler/deSugar/Coverage.lhs b/compiler/deSugar/Coverage.lhs
index 28d83c9dc5..ff3cfc5189 100644
--- a/compiler/deSugar/Coverage.lhs
+++ b/compiler/deSugar/Coverage.lhs
@@ -423,6 +423,7 @@ isGoodBreakExpr (HsApp {}) = True
isGoodBreakExpr (OpApp {}) = True
isGoodBreakExpr (NegApp {}) = True
isGoodBreakExpr (HsIf {}) = True
+isGoodBreakExpr (HsMultiIf {}) = True
isGoodBreakExpr (HsCase {}) = True
isGoodBreakExpr (RecordCon {}) = True
isGoodBreakExpr (RecordUpd {}) = True
@@ -496,6 +497,10 @@ addTickHsExpr (HsIf cnd e1 e2 e3) =
(addBinTickLHsExpr (BinBox CondBinBox) e1)
(addTickLHsExprOptAlt True e2)
(addTickLHsExprOptAlt True e3)
+addTickHsExpr (HsMultiIf ty alts)
+ = do { let isOneOfMany = case alts of [_] -> False; _ -> True
+ ; alts' <- mapM (liftL $ addTickGRHS isOneOfMany False) alts
+ ; return $ HsMultiIf ty alts' }
addTickHsExpr (HsLet binds e) =
bindLocals (collectLocalBinders binds) $
liftM2 HsLet
diff --git a/compiler/deSugar/DsExpr.lhs b/compiler/deSugar/DsExpr.lhs
index 4795b5f68c..f8bd213c3f 100644
--- a/compiler/deSugar/DsExpr.lhs
+++ b/compiler/deSugar/DsExpr.lhs
@@ -337,6 +337,19 @@ dsExpr (HsIf mb_fun guard_expr then_expr else_expr)
Just fun -> do { core_fun <- dsExpr fun
; return (mkCoreApps core_fun [pred,b1,b2]) }
Nothing -> return $ mkIfThenElse pred b1 b2 }
+
+dsExpr (HsMultiIf res_ty alts)
+ | null alts
+ = mkErrorExpr
+
+ | otherwise
+ = do { match_result <- liftM (foldr1 combineMatchResults)
+ (mapM (dsGRHS IfAlt res_ty) alts)
+ ; error_expr <- mkErrorExpr
+ ; extractMatchResult match_result error_expr }
+ where
+ mkErrorExpr = mkErrorAppDs nON_EXHAUSTIVE_GUARDS_ERROR_ID res_ty
+ (ptext (sLit "multi-way if"))
\end{code}
diff --git a/compiler/deSugar/DsGRHSs.lhs b/compiler/deSugar/DsGRHSs.lhs
index ed87d186af..9e84e46e9f 100644
--- a/compiler/deSugar/DsGRHSs.lhs
+++ b/compiler/deSugar/DsGRHSs.lhs
@@ -6,7 +6,7 @@
Matching guarded right-hand-sides (GRHSs)
\begin{code}
-module DsGRHSs ( dsGuarded, dsGRHSs ) where
+module DsGRHSs ( dsGuarded, dsGRHSs, dsGRHS ) where
#include "HsVersions.h"
@@ -55,8 +55,8 @@ dsGRHSs :: HsMatchContext Name -> [Pat Id] -- These are to build a MatchCon
-> GRHSs Id -- Guarded RHSs
-> Type -- Type of RHS
-> DsM MatchResult
-dsGRHSs hs_ctx pats (GRHSs grhss binds) rhs_ty = do
- match_results <- mapM (dsGRHS hs_ctx pats rhs_ty) grhss
+dsGRHSs hs_ctx _ (GRHSs grhss binds) rhs_ty = do
+ match_results <- mapM (dsGRHS hs_ctx rhs_ty) grhss
let
match_result1 = foldr1 combineMatchResults match_results
match_result2 = adjustMatchResultDs
@@ -66,8 +66,8 @@ dsGRHSs hs_ctx pats (GRHSs grhss binds) rhs_ty = do
--
return match_result2
-dsGRHS :: HsMatchContext Name -> [Pat Id] -> Type -> LGRHS Id -> DsM MatchResult
-dsGRHS hs_ctx _ rhs_ty (L _ (GRHS guards rhs))
+dsGRHS :: HsMatchContext Name -> Type -> LGRHS Id -> DsM MatchResult
+dsGRHS hs_ctx rhs_ty (L _ (GRHS guards rhs))
= matchGuards (map unLoc guards) (PatGuard hs_ctx) rhs rhs_ty
\end{code}
diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs
index 7a60ae4ae1..4d07c8c34e 100644
--- a/compiler/deSugar/DsMeta.hs
+++ b/compiler/deSugar/DsMeta.hs
@@ -890,6 +890,10 @@ repE (HsIf _ x y z) = do
b <- repLE y
c <- repLE z
repCond a b c
+repE (HsMultiIf _ alts)
+ = do { (binds, alts') <- liftM unzip $ mapM repLGRHS alts
+ ; expr' <- repMultiIf (nonEmptyCoreList alts')
+ ; wrapGenSyms (concat binds) expr' }
repE (HsLet bs e) = do { (ss,ds) <- repBinds bs
; e2 <- addBinds ss (repLE e)
; z <- repLetE ds e2
@@ -980,22 +984,22 @@ repClauseTup (L _ (Match ps _ (GRHSs guards wheres))) =
repGuards :: [LGRHS Name] -> DsM (Core TH.BodyQ)
repGuards [L _ (GRHS [] e)]
- = do {a <- repLE e; repNormal a }
-repGuards other
- = do { zs <- mapM process other;
- let {(xs, ys) = unzip zs};
- gd <- repGuarded (nonEmptyCoreList ys);
- wrapGenSyms (concat xs) gd }
- where
- process :: LGRHS Name -> DsM ([GenSymBind], (Core (TH.Q (TH.Guard, TH.Exp))))
- process (L _ (GRHS [L _ (ExprStmt e1 _ _ _)] e2))
- = do { x <- repLNormalGE e1 e2;
- return ([], x) }
- process (L _ (GRHS ss rhs))
- = do (gs, ss') <- repLSts ss
- rhs' <- addBinds gs $ repLE rhs
- g <- repPatGE (nonEmptyCoreList ss') rhs'
- return (gs, g)
+ = do { a <- repLE e
+ ; repNormal a }
+repGuards alts
+ = do { (binds, alts') <- liftM unzip $ mapM repLGRHS alts
+ ; body <- repGuarded (nonEmptyCoreList alts')
+ ; wrapGenSyms (concat binds) body }
+
+repLGRHS :: LGRHS Name -> DsM ([GenSymBind], (Core (TH.Q (TH.Guard, TH.Exp))))
+repLGRHS (L _ (GRHS [L _ (ExprStmt guard _ _ _)] rhs))
+ = do { guarded <- repLNormalGE guard rhs
+ ; return ([], guarded) }
+repLGRHS (L _ (GRHS stmts rhs))
+ = do { (gs, stmts') <- repLSts stmts
+ ; rhs' <- addBinds gs $ repLE rhs
+ ; guarded <- repPatGE (nonEmptyCoreList stmts') rhs'
+ ; return (gs, guarded) }
repFields :: HsRecordBinds Name -> DsM (Core [TH.Q TH.FieldExp])
repFields (HsRecFields { rec_flds = flds })
@@ -1471,6 +1475,9 @@ repUnboxedTup (MkC es) = rep2 unboxedTupEName [es]
repCond :: Core TH.ExpQ -> Core TH.ExpQ -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
repCond (MkC x) (MkC y) (MkC z) = rep2 condEName [x,y,z]
+repMultiIf :: Core [TH.Q (TH.Guard, TH.Exp)] -> DsM (Core TH.ExpQ)
+repMultiIf (MkC alts) = rep2 multiIfEName [alts]
+
repLetE :: Core [TH.DecQ] -> Core TH.ExpQ -> DsM (Core TH.ExpQ)
repLetE (MkC ds) (MkC e) = rep2 letEName [ds, e]
@@ -1902,7 +1909,7 @@ templateHaskellNames = [
varEName, conEName, litEName, appEName, infixEName,
infixAppName, sectionLName, sectionRName, lamEName, lamCaseEName,
tupEName, unboxedTupEName,
- condEName, letEName, caseEName, doEName, compEName,
+ condEName, multiIfEName, letEName, caseEName, doEName, compEName,
fromEName, fromThenEName, fromToEName, fromThenToEName,
listEName, sigEName, recConEName, recUpdEName,
-- FieldExp
@@ -2066,8 +2073,8 @@ clauseName = libFun (fsLit "clause") clauseIdKey
-- data Exp = ...
varEName, conEName, litEName, appEName, infixEName, infixAppName,
sectionLName, sectionRName, lamEName, lamCaseEName, tupEName,
- unboxedTupEName, condEName, letEName, caseEName, doEName,
- compEName :: Name
+ unboxedTupEName, condEName, multiIfEName, letEName, caseEName,
+ doEName, compEName :: Name
varEName = libFun (fsLit "varE") varEIdKey
conEName = libFun (fsLit "conE") conEIdKey
litEName = libFun (fsLit "litE") litEIdKey
@@ -2081,6 +2088,7 @@ lamCaseEName = libFun (fsLit "lamCaseE") lamCaseEIdKey
tupEName = libFun (fsLit "tupE") tupEIdKey
unboxedTupEName = libFun (fsLit "unboxedTupE") unboxedTupEIdKey
condEName = libFun (fsLit "condE") condEIdKey
+multiIfEName = libFun (fsLit "multiIfE") multiIfEIdKey
letEName = libFun (fsLit "letE") letEIdKey
caseEName = libFun (fsLit "caseE") caseEIdKey
doEName = libFun (fsLit "doE") doEIdKey
@@ -2380,7 +2388,7 @@ clauseIdKey = mkPreludeMiscIdUnique 262
-- data Exp = ...
varEIdKey, conEIdKey, litEIdKey, appEIdKey, infixEIdKey, infixAppIdKey,
sectionLIdKey, sectionRIdKey, lamEIdKey, lamCaseEIdKey, tupEIdKey,
- unboxedTupEIdKey, condEIdKey,
+ unboxedTupEIdKey, condEIdKey, multiIfEIdKey,
letEIdKey, caseEIdKey, doEIdKey, compEIdKey,
fromEIdKey, fromThenEIdKey, fromToEIdKey, fromThenToEIdKey,
listEIdKey, sigEIdKey, recConEIdKey, recUpdEIdKey :: Unique
@@ -2397,18 +2405,19 @@ lamCaseEIdKey = mkPreludeMiscIdUnique 279
tupEIdKey = mkPreludeMiscIdUnique 280
unboxedTupEIdKey = mkPreludeMiscIdUnique 281
condEIdKey = mkPreludeMiscIdUnique 282
-letEIdKey = mkPreludeMiscIdUnique 283
-caseEIdKey = mkPreludeMiscIdUnique 284
-doEIdKey = mkPreludeMiscIdUnique 285
-compEIdKey = mkPreludeMiscIdUnique 286
-fromEIdKey = mkPreludeMiscIdUnique 287
-fromThenEIdKey = mkPreludeMiscIdUnique 288
-fromToEIdKey = mkPreludeMiscIdUnique 289
-fromThenToEIdKey = mkPreludeMiscIdUnique 290
-listEIdKey = mkPreludeMiscIdUnique 291
-sigEIdKey = mkPreludeMiscIdUnique 292
-recConEIdKey = mkPreludeMiscIdUnique 293
-recUpdEIdKey = mkPreludeMiscIdUnique 294
+multiIfEIdKey = mkPreludeMiscIdUnique 283
+letEIdKey = mkPreludeMiscIdUnique 284
+caseEIdKey = mkPreludeMiscIdUnique 285
+doEIdKey = mkPreludeMiscIdUnique 286
+compEIdKey = mkPreludeMiscIdUnique 287
+fromEIdKey = mkPreludeMiscIdUnique 288
+fromThenEIdKey = mkPreludeMiscIdUnique 289
+fromToEIdKey = mkPreludeMiscIdUnique 290
+fromThenToEIdKey = mkPreludeMiscIdUnique 291
+listEIdKey = mkPreludeMiscIdUnique 292
+sigEIdKey = mkPreludeMiscIdUnique 293
+recConEIdKey = mkPreludeMiscIdUnique 294
+recUpdEIdKey = mkPreludeMiscIdUnique 295
-- type FieldExp = ...
fieldExpIdKey :: Unique
diff --git a/compiler/deSugar/Match.lhs b/compiler/deSugar/Match.lhs
index c80446a751..8fd3a203f3 100644
--- a/compiler/deSugar/Match.lhs
+++ b/compiler/deSugar/Match.lhs
@@ -88,6 +88,7 @@ matchCheck_really dflags ctx@(DsMatchContext hs_ctx _) vars ty qs
incomplete_flag :: HsMatchContext id -> Bool
incomplete_flag (FunRhs {}) = wopt Opt_WarnIncompletePatterns dflags
incomplete_flag CaseAlt = wopt Opt_WarnIncompletePatterns dflags
+ incomplete_flag IfAlt = False
incomplete_flag LambdaExpr = wopt Opt_WarnIncompleteUniPatterns dflags
incomplete_flag PatBindRhs = wopt Opt_WarnIncompleteUniPatterns dflags