diff options
author | Mikhail Vorozhtsov <mikhail.vorozhtsov@gmail.com> | 2012-07-15 00:53:52 +0700 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2012-07-16 11:09:40 +0100 |
commit | cc456b0be3f20a1c1cef4154ae40ac18f4f6711e (patch) | |
tree | 0ca2bc0cdfabd6f4c6e3e0a94170baae71d634c0 /compiler/deSugar | |
parent | b1e97f2f325537664f09eee7ea0e7c53264b061e (diff) | |
download | haskell-cc456b0be3f20a1c1cef4154ae40ac18f4f6711e.tar.gz |
Implemented MultiWayIf extension.
Diffstat (limited to 'compiler/deSugar')
-rw-r--r-- | compiler/deSugar/Coverage.lhs | 5 | ||||
-rw-r--r-- | compiler/deSugar/DsExpr.lhs | 13 | ||||
-rw-r--r-- | compiler/deSugar/DsGRHSs.lhs | 10 | ||||
-rw-r--r-- | compiler/deSugar/DsMeta.hs | 73 | ||||
-rw-r--r-- | compiler/deSugar/Match.lhs | 1 |
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 |