X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FdeSugar%2FDsListComp.lhs;h=9f19dd152f22059592871fe9e880d7c6e4f46856;hb=d7c402a3cedbe49345a34f2e58a3f3050638dcb4;hp=e9c455da71b0ffb6457348615cd352ffec0bacd0;hpb=16e4ce4c0c02650082f2e11982017c903c549ad5;p=ghc-hetmet.git diff --git a/ghc/compiler/deSugar/DsListComp.lhs b/ghc/compiler/deSugar/DsListComp.lhs index e9c455d..9f19dd1 100644 --- a/ghc/compiler/deSugar/DsListComp.lhs +++ b/ghc/compiler/deSugar/DsListComp.lhs @@ -8,21 +8,17 @@ module DsListComp ( dsListComp, dsPArrComp ) where #include "HsVersions.h" -import {-# SOURCE #-} DsExpr ( dsExpr, dsLet ) +import {-# SOURCE #-} DsExpr ( dsLExpr, dsLet ) import BasicTypes ( Boxity(..) ) -import TyCon ( tyConName ) -import HsSyn ( Pat(..), HsExpr(..), Stmt(..), - HsMatchContext(..), HsStmtContext(..), - collectHsBinders ) -import TcHsSyn ( TypecheckedStmt, TypecheckedPat, TypecheckedHsExpr, - hsPatType ) +import HsSyn +import TcHsSyn ( hsPatType ) import CoreSyn import DsMonad -- the monadery used in the desugarer import DsUtils -import CmdLineOpts ( opt_FoldrBuildOn ) +import CmdLineOpts ( DynFlag(..), dopt, opt_RulesOff ) import CoreUtils ( exprType, mkIfThenElse ) import Id ( idType ) import Var ( Id ) @@ -30,12 +26,12 @@ import Type ( mkTyVarTy, mkFunTys, mkFunTy, Type, splitTyConApp_maybe ) import TysPrim ( alphaTyVar ) import TysWiredIn ( nilDataCon, consDataCon, trueDataConId, falseDataConId, - unitDataConId, unitTy, mkListTy ) + unitDataConId, unitTy, mkListTy, parrTyCon ) import Match ( matchSimply ) import PrelNames ( foldrName, buildName, replicatePName, mapPName, - filterPName, zipPName, crossPName, parrTyConName ) + filterPName, zipPName, crossPName ) import PrelInfo ( pAT_ERROR_ID ) -import SrcLoc ( noSrcLoc ) +import SrcLoc ( noLoc, unLoc ) import Panic ( panic ) \end{code} @@ -46,17 +42,26 @@ turned on'' (if you read Gill {\em et al.}'s paper on the subject). There will be at least one ``qualifier'' in the input. \begin{code} -dsListComp :: [TypecheckedStmt] +dsListComp :: [LStmt Id] -> Type -- Type of list elements -> DsM CoreExpr - -dsListComp quals elt_ty - | not opt_FoldrBuildOn -- Be boring - || isParallelComp quals - = deListComp quals (mkNilExpr elt_ty) - - | otherwise -- foldr/build lives! - = newTyVarsDs [alphaTyVar] `thenDs` \ [n_tyvar] -> +dsListComp lquals elt_ty + = getDOptsDs `thenDs` \dflags -> + let + quals = map unLoc lquals + in + if opt_RulesOff || dopt Opt_IgnoreInterfacePragmas dflags + -- Either rules are switched off, or we are ignoring what there are; + -- Either way foldr/build won't happen, so use the more efficient + -- Wadler-style desugaring + || isParallelComp quals + -- Foldr-style desugaring can't handle + -- parallel list comprehensions + then deListComp quals (mkNilExpr elt_ty) + + else -- Foldr/build should be enabled, so desugar + -- into foldrs and builds + newTyVarsDs [alphaTyVar] `thenDs` \ [n_tyvar] -> let n_ty = mkTyVarTy n_tyvar c_ty = mkFunTys [elt_ty, n_ty] n_ty @@ -136,11 +141,10 @@ The introduced tuples are Boxed, but only because I couldn't get it to work with the Unboxed variety. \begin{code} - -deListComp :: [TypecheckedStmt] -> CoreExpr -> DsM CoreExpr +deListComp :: [Stmt Id] -> CoreExpr -> DsM CoreExpr deListComp (ParStmt stmtss_w_bndrs : quals) list - = mapDs do_list_comp stmtss_w_bndrs `thenDs` \ exps -> + = mappM do_list_comp stmtss_w_bndrs `thenDs` \ exps -> mkZipBind qual_tys `thenDs` \ (zip_fn, zip_rhs) -> -- Deal with [e | pat <- zip l1 .. ln] in example above @@ -151,26 +155,26 @@ deListComp (ParStmt stmtss_w_bndrs : quals) list bndrs_s = map snd stmtss_w_bndrs -- pat is the pattern ((x1,..,xn), (y1,..,ym)) in the example above - pat = TuplePat pats Boxed + pat = noLoc (TuplePat pats Boxed) pats = map mk_hs_tuple_pat bndrs_s -- Types of (x1,..,xn), (y1,..,yn) etc qual_tys = map mk_bndrs_tys bndrs_s do_list_comp (stmts, bndrs) - = dsListComp (stmts ++ [ResultStmt (mk_hs_tuple_expr bndrs) noSrcLoc]) + = dsListComp (stmts ++ [noLoc $ ResultStmt (mk_hs_tuple_expr bndrs)]) (mk_bndrs_tys bndrs) mk_bndrs_tys bndrs = mkCoreTupTy (map idType bndrs) -- Last: the one to return -deListComp [ResultStmt expr locn] list -- Figure 7.4, SLPJ, p 135, rule C above - = dsExpr expr `thenDs` \ core_expr -> +deListComp [ResultStmt expr] list -- Figure 7.4, SLPJ, p 135, rule C above + = dsLExpr expr `thenDs` \ core_expr -> returnDs (mkConsExpr (exprType core_expr) core_expr list) -- Non-last: must be a guard -deListComp (ExprStmt guard ty locn : quals) list -- rule B above - = dsExpr guard `thenDs` \ core_guard -> +deListComp (ExprStmt guard ty : quals) list -- rule B above + = dsLExpr guard `thenDs` \ core_guard -> deListComp quals list `thenDs` \ core_rest -> returnDs (mkIfThenElse core_guard core_rest list) @@ -179,8 +183,8 @@ deListComp (LetStmt binds : quals) list = deListComp quals list `thenDs` \ core_rest -> dsLet binds core_rest -deListComp (BindStmt pat list1 locn : quals) core_list2 -- rule A' above - = dsExpr list1 `thenDs` \ core_list1 -> +deListComp (BindStmt pat list1 : quals) core_list2 -- rule A' above + = dsLExpr list1 `thenDs` \ core_list1 -> deBindComp pat core_list1 quals core_list2 \end{code} @@ -208,8 +212,10 @@ deBindComp pat core_list1 quals core_list2 rest_expr core_fail `thenDs` \ core_match -> let rhs = Lam u1 $ - Case (Var u1) u1 [(DataAlt nilDataCon, [], core_list2), - (DataAlt consDataCon, [u2, u3], core_match)] + Case (Var u1) u1 res_ty + [(DataAlt nilDataCon, [], core_list2), + (DataAlt consDataCon, [u2, u3], core_match)] + -- Increasing order of tag in returnDs (Let (Rec [(h, rhs)]) letrec_body) \end{code} @@ -226,9 +232,9 @@ mkZipBind :: [Type] -> DsM (Id, CoreExpr) -- (a2:as'2) -> (a2,a2) : zip as'1 as'2)] mkZipBind elt_tys - = mapDs newSysLocalDs list_tys `thenDs` \ ass -> - mapDs newSysLocalDs elt_tys `thenDs` \ as' -> - mapDs newSysLocalDs list_tys `thenDs` \ as's -> + = mappM newSysLocalDs list_tys `thenDs` \ ass -> + mappM newSysLocalDs elt_tys `thenDs` \ as' -> + mappM newSysLocalDs list_tys `thenDs` \ as's -> newSysLocalDs zip_fn_ty `thenDs` \ zip_fn -> let inner_rhs = mkConsExpr ret_elt_ty @@ -238,23 +244,25 @@ mkZipBind elt_tys in returnDs (zip_fn, mkLams ass zip_body) where - list_tys = map mkListTy elt_tys - ret_elt_ty = mkCoreTupTy elt_tys - zip_fn_ty = mkFunTys list_tys (mkListTy ret_elt_ty) + list_tys = map mkListTy elt_tys + ret_elt_ty = mkCoreTupTy elt_tys + list_ret_ty = mkListTy ret_elt_ty + zip_fn_ty = mkFunTys list_tys list_ret_ty mk_case (as, a', as') rest - = Case (Var as) as [(DataAlt nilDataCon, [], mkNilExpr ret_elt_ty), - (DataAlt consDataCon, [a', as'], rest)] - + = Case (Var as) as list_ret_ty + [(DataAlt nilDataCon, [], mkNilExpr ret_elt_ty), + (DataAlt consDataCon, [a', as'], rest)] + -- Increasing order of tag -- Helper functions that makes an HsTuple only for non-1-sized tuples -mk_hs_tuple_expr :: [Id] -> TypecheckedHsExpr -mk_hs_tuple_expr [] = HsVar unitDataConId -mk_hs_tuple_expr [id] = HsVar id -mk_hs_tuple_expr ids = ExplicitTuple [ HsVar i | i <- ids ] Boxed - -mk_hs_tuple_pat :: [Id] -> TypecheckedPat -mk_hs_tuple_pat [b] = VarPat b -mk_hs_tuple_pat bs = TuplePat (map VarPat bs) Boxed +mk_hs_tuple_expr :: [Id] -> LHsExpr Id +mk_hs_tuple_expr [] = nlHsVar unitDataConId +mk_hs_tuple_expr [id] = nlHsVar id +mk_hs_tuple_expr ids = noLoc $ ExplicitTuple [ nlHsVar i | i <- ids ] Boxed + +mk_hs_tuple_pat :: [Id] -> LPat Id +mk_hs_tuple_pat [b] = nlVarPat b +mk_hs_tuple_pat bs = noLoc $ TuplePat (map nlVarPat bs) Boxed \end{code} @@ -279,17 +287,17 @@ TE[ e | p <- l , q ] c n = let \begin{code} dfListComp :: Id -> Id -- 'c' and 'n' - -> [TypecheckedStmt] -- the rest of the qual's + -> [Stmt Id] -- the rest of the qual's -> DsM CoreExpr -- Last: the one to return -dfListComp c_id n_id [ResultStmt expr locn] - = dsExpr expr `thenDs` \ core_expr -> +dfListComp c_id n_id [ResultStmt expr] + = dsLExpr expr `thenDs` \ core_expr -> returnDs (mkApps (Var c_id) [core_expr, Var n_id]) -- Non-last: must be a guard -dfListComp c_id n_id (ExprStmt guard ty locn : quals) - = dsExpr guard `thenDs` \ core_guard -> +dfListComp c_id n_id (ExprStmt guard ty : quals) + = dsLExpr guard `thenDs` \ core_guard -> dfListComp c_id n_id quals `thenDs` \ core_rest -> returnDs (mkIfThenElse core_guard core_rest (Var n_id)) @@ -298,9 +306,9 @@ dfListComp c_id n_id (LetStmt binds : quals) = dfListComp c_id n_id quals `thenDs` \ core_rest -> dsLet binds core_rest -dfListComp c_id n_id (BindStmt pat list1 locn : quals) +dfListComp c_id n_id (BindStmt pat list1 : quals) -- evaluate the two lists - = dsExpr list1 `thenDs` \ core_list1 -> + = dsLExpr list1 `thenDs` \ core_list1 -> -- find the required type let x_ty = hsPatType pat @@ -314,7 +322,7 @@ dfListComp c_id n_id (BindStmt pat list1 locn : quals) dfListComp c_id b quals `thenDs` \ core_rest -> -- build the pattern match - matchSimply (Var x) (StmtCtxt ListComp) + matchSimply (Var x) (StmtCtxt ListComp) pat core_rest (Var b) `thenDs` \ core_expr -> -- now build the outermost foldr, and return @@ -340,7 +348,7 @@ dfListComp c_id n_id (BindStmt pat list1 locn : quals) -- -- [:e | qss:] = <<[:e | qss:]>> () [:():] -- -dsPArrComp :: [TypecheckedStmt] +dsPArrComp :: [Stmt Id] -> Type -- Don't use; called with `undefined' below -> DsM CoreExpr dsPArrComp qs _ = @@ -349,18 +357,18 @@ dsPArrComp qs _ = mkIntExpr 1, mkCoreTup []] in - dePArrComp qs (TuplePat [] Boxed) unitArray + dePArrComp qs (noLoc (TuplePat [] Boxed)) unitArray -- the work horse -- -dePArrComp :: [TypecheckedStmt] - -> TypecheckedPat -- the current generator pattern - -> CoreExpr -- the current generator expression +dePArrComp :: [Stmt Id] + -> LPat Id -- the current generator pattern + -> CoreExpr -- the current generator expression -> DsM CoreExpr -- -- <<[:e' | :]>> pa ea = mapP (\pa -> e') ea -- -dePArrComp [ResultStmt e' _] pa cea = +dePArrComp [ResultStmt e'] pa cea = dsLookupGlobalId mapPName `thenDs` \mapP -> let ty = parrElemType cea in @@ -370,7 +378,7 @@ dePArrComp [ResultStmt e' _] pa cea = -- -- <<[:e' | b, qs:]>> pa ea = <<[:e' | qs:]>> pa (filterP (\pa -> b) ea) -- -dePArrComp (ExprStmt b _ _ : qs) pa cea = +dePArrComp (ExprStmt b _ : qs) pa cea = dsLookupGlobalId filterPName `thenDs` \filterP -> let ty = parrElemType cea in @@ -382,10 +390,10 @@ dePArrComp (ExprStmt b _ _ : qs) pa cea = -- in -- <<[:e' | qs:]>> (pa, p) (crossP ea ef) -- -dePArrComp (BindStmt p e _ : qs) pa cea = +dePArrComp (BindStmt p e : qs) pa cea = dsLookupGlobalId filterPName `thenDs` \filterP -> dsLookupGlobalId crossPName `thenDs` \crossP -> - dsExpr e `thenDs` \ce -> + dsLExpr e `thenDs` \ce -> let ty'cea = parrElemType cea ty'ce = parrElemType ce false = Var falseDataConId @@ -395,7 +403,7 @@ dePArrComp (BindStmt p e _ : qs) pa cea = matchSimply (Var v) (StmtCtxt PArrComp) p true false `thenDs` \pred -> let cef = mkApps (Var filterP) [Type ty'ce, mkLams [v] pred, ce] ty'cef = ty'ce -- filterP preserves the type - pa' = TuplePat [pa, p] Boxed + pa' = noLoc (TuplePat [pa, p] Boxed) in dePArrComp qs pa' (mkApps (Var crossP) [Type ty'cea, Type ty'cef, cea, cef]) -- @@ -407,7 +415,7 @@ dePArrComp (BindStmt p e _ : qs) pa cea = -- dePArrComp (LetStmt ds : qs) pa cea = dsLookupGlobalId mapPName `thenDs` \mapP -> - let xs = collectHsBinders ds + let xs = map unLoc (collectGroupBinders ds) ty'cea = parrElemType cea in newSysLocalDs ty'cea `thenDs` \v -> @@ -420,7 +428,7 @@ dePArrComp (LetStmt ds : qs) pa cea = in mkErrorAppDs pAT_ERROR_ID errTy errMsg `thenDs` \cerr -> matchSimply (Var v) (StmtCtxt PArrComp) pa projBody cerr `thenDs` \ccase -> - let pa' = TuplePat [pa, TuplePat (map VarPat xs) Boxed] Boxed + let pa' = noLoc $ TuplePat [pa, noLoc (TuplePat (map nlVarPat xs) Boxed)] Boxed proj = mkLams [v] ccase in dePArrComp qs pa' (mkApps (Var mapP) [Type ty'cea, proj, cea]) @@ -434,11 +442,11 @@ dePArrComp (LetStmt ds : qs) pa cea = dePArrComp (ParStmt [] : qss2) pa cea = dePArrComp qss2 pa cea dePArrComp (ParStmt ((qs, xs):qss) : qss2) pa cea = dsLookupGlobalId zipPName `thenDs` \zipP -> - let pa' = TuplePat [pa, TuplePat (map VarPat xs) Boxed] Boxed + let pa' = noLoc $ TuplePat [pa, noLoc (TuplePat (map nlVarPat xs) Boxed)] Boxed ty'cea = parrElemType cea - resStmt = ResultStmt (ExplicitTuple (map HsVar xs) Boxed) noSrcLoc + resStmt = ResultStmt (noLoc $ ExplicitTuple (map nlHsVar xs) Boxed) in - dsPArrComp (qs ++ [resStmt]) undefined `thenDs` \cqs -> + dsPArrComp (map unLoc qs ++ [resStmt]) undefined `thenDs` \cqs -> let ty'cqs = parrElemType cqs cea' = mkApps (Var zipP) [Type ty'cea, Type ty'cqs, cea, cqs] in @@ -447,16 +455,16 @@ dePArrComp (ParStmt ((qs, xs):qss) : qss2) pa cea = -- generate Core corresponding to `\p -> e' -- deLambda :: Type -- type of the argument - -> TypecheckedPat -- argument pattern - -> TypecheckedHsExpr -- body + -> LPat Id -- argument pattern + -> LHsExpr Id -- body -> DsM (CoreExpr, Type) deLambda ty p e = newSysLocalDs ty `thenDs` \v -> - dsExpr e `thenDs` \ce -> + dsLExpr e `thenDs` \ce -> let errTy = exprType ce errMsg = "DsListComp.deLambda: internal error!" in - mkErrorAppDs pAT_ERROR_ID errTy errMsg `thenDs` \cerr -> + mkErrorAppDs pAT_ERROR_ID errTy errMsg `thenDs` \cerr -> matchSimply (Var v) (StmtCtxt PArrComp) p ce cerr `thenDs` \res -> returnDs (mkLams [v] res, errTy) @@ -466,7 +474,7 @@ deLambda ty p e = parrElemType :: CoreExpr -> Type parrElemType e = case splitTyConApp_maybe (exprType e) of - Just (tycon, [ty]) | tyConName tycon == parrTyConName -> ty + Just (tycon, [ty]) | tycon == parrTyCon -> ty _ -> panic "DsListComp.parrElemType: not a parallel array type" \end{code}