From 6d0e2f288a34f12f5e3228415351d5bb4280c814 Mon Sep 17 00:00:00 2001 From: Mikhail Vorozhtsov <mikhail.vorozhtsov@gmail.com> Date: Tue, 10 Jul 2012 21:37:42 +0700 Subject: [PATCH] TH: Pragmas refactoring. Also adds RULES and 'SPECIALIZE instance' support. MERGED from commit 1993ee4ba8d30d6774c2330477a1eecf865dfa1f --- compiler/basicTypes/BasicTypes.lhs | 2 +- compiler/deSugar/DsMeta.hs | 253 ++++++++++++++++++----------- compiler/hsSyn/Convert.lhs | 92 +++++++---- 3 files changed, 216 insertions(+), 131 deletions(-) diff --git a/compiler/basicTypes/BasicTypes.lhs b/compiler/basicTypes/BasicTypes.lhs index 86b93ab9a245..2760156e1cf3 100644 --- a/compiler/basicTypes/BasicTypes.lhs +++ b/compiler/basicTypes/BasicTypes.lhs @@ -71,7 +71,7 @@ module BasicTypes( Activation(..), isActive, isActiveIn, isNeverActive, isAlwaysActive, isEarlyActive, RuleMatchInfo(..), isConLike, isFunLike, - InlineSpec(..), + InlineSpec(..), isEmptyInlineSpec, InlinePragma(..), defaultInlinePragma, alwaysInlinePragma, neverInlinePragma, dfunInlinePragma, isDefaultInlinePragma, diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs index 4d07c8c34e36..874f8b0f4100 100644 --- a/compiler/deSugar/DsMeta.hs +++ b/compiler/deSugar/DsMeta.hs @@ -131,11 +131,12 @@ repTopDs group val_ds <- rep_val_binds (hs_valds group) ; tycl_ds <- mapM repTyClD (concat (hs_tyclds group)) ; inst_ds <- mapM repInstD (hs_instds group) ; - for_ds <- mapM repForD (hs_fords group) ; + rule_ds <- mapM repRuleD (hs_ruleds group) ; + for_ds <- mapM repForD (hs_fords group) ; -- more needed return (de_loc $ sort_by_loc $ val_ds ++ catMaybes tycl_ds ++ fix_ds - ++ inst_ds ++ for_ds) }) ; + ++ inst_ds ++ rule_ds ++ for_ds) }) ; decl_ty <- lookupType decQTyConName ; let { core_list = coreList' decl_ty decls } ; @@ -411,6 +412,25 @@ repFixD (L loc (FixitySig name (Fixity prec dir))) ; dec <- rep2 rep_fn [prec', name'] ; return (loc, dec) } +repRuleD :: LRuleDecl Name -> DsM (SrcSpan, Core TH.DecQ) +repRuleD (L loc (HsRule n act bndrs lhs _ rhs _)) + = do { n' <- coreStringLit $ unpackFS n + ; phases <- repPhases act + ; bndrs' <- mapM repRuleBndr bndrs >>= coreList ruleBndrQTyConName + ; lhs' <- repLE lhs + ; rhs' <- repLE rhs + ; pragma <- repPragRule n' bndrs' lhs' rhs' phases + ; return (loc, pragma) } + +repRuleBndr :: RuleBndr Name -> DsM (Core TH.RuleBndrQ) +repRuleBndr (RuleBndr n) + = do { MkC n' <- lookupLOcc n + ; rep2 ruleVarName [n'] } +repRuleBndr (RuleBndrSig n (HsWB { hswb_cts = ty })) + = do { MkC n' <- lookupLOcc n + ; MkC ty' <- repLTy ty + ; rep2 typedRuleVarName [n', ty'] } + ds_msg :: SDoc ds_msg = ptext (sLit "Cannot desugar this Template Haskell declaration:") @@ -541,6 +561,7 @@ rep_sig (L _ (GenericSig nm _)) = failWithDs msg rep_sig (L loc (InlineSig nm ispec)) = rep_inline nm ispec loc rep_sig (L loc (SpecSig nm ty ispec)) = rep_specialise nm ty ispec loc +rep_sig (L loc (SpecInstSig ty)) = rep_specialiseInst ty loc rep_sig _ = return [] rep_ty_sig :: SrcSpan -> LHsType Name -> Located Name @@ -570,9 +591,11 @@ rep_inline :: Located Name -> SrcSpan -> DsM [(SrcSpan, Core TH.DecQ)] rep_inline nm ispec loc - = do { nm1 <- lookupLOcc nm - ; ispec1 <- rep_InlinePrag ispec - ; pragma <- repPragInl nm1 ispec1 + = do { nm1 <- lookupLOcc nm + ; inline <- repInline $ inl_inline ispec + ; rm <- repRuleMatch $ inl_rule ispec + ; phases <- repPhases $ inl_act ispec + ; pragma <- repPragInl nm1 inline rm phases ; return [(loc, pragma)] } @@ -581,43 +604,39 @@ rep_specialise :: Located Name -> LHsType Name -> InlinePragma -> SrcSpan rep_specialise nm ty ispec loc = do { nm1 <- lookupLOcc nm ; ty1 <- repLTy ty - ; pragma <- if isDefaultInlinePragma ispec - then repPragSpec nm1 ty1 -- SPECIALISE - else do { ispec1 <- rep_InlinePrag ispec -- SPECIALISE INLINE - ; repPragSpecInl nm1 ty1 ispec1 } + ; phases <- repPhases $ inl_act ispec + ; let inline = inl_inline ispec + ; pragma <- if isEmptyInlineSpec inline + then -- SPECIALISE + repPragSpec nm1 ty1 phases + else -- SPECIALISE INLINE + do { inline1 <- repInline inline + ; repPragSpecInl nm1 ty1 inline1 phases } ; return [(loc, pragma)] } +rep_specialiseInst :: LHsType Name -> SrcSpan -> DsM [(SrcSpan, Core TH.DecQ)] +rep_specialiseInst ty loc + = do { ty1 <- repLTy ty + ; pragma <- repPragSpecInst ty1 + ; return [(loc, pragma)] } + repInline :: InlineSpec -> DsM (Core TH.Inline) repInline NoInline = dataCon noInlineDataConName repInline Inline = dataCon inlineDataConName repInline Inlinable = dataCon inlinableDataConName repInline spec = notHandled "repInline" (ppr spec) --- Extract all the information needed to build a TH.InlinePrag --- -rep_InlinePrag :: InlinePragma -- Never defaultInlinePragma - -> DsM (Core TH.InlineSpecQ) -rep_InlinePrag (InlinePragma { inl_act = activation, inl_rule = match, inl_inline = inline }) - | Just (flag, phase) <- activation1 - = do { inline1 <- repInline inline - ; repInlineSpecPhase inline1 match1 flag phase } - | otherwise - = do { inline1 <- repInline inline - ; repInlineSpecNoPhase inline1 match1 } - where - match1 = coreBool (rep_RuleMatchInfo match) - activation1 = rep_Activation activation - rep_RuleMatchInfo FunLike = False - rep_RuleMatchInfo ConLike = True - - rep_Activation NeverActive = Nothing -- We never have NOINLINE/AlwaysActive - rep_Activation AlwaysActive = Nothing -- or INLINE/NeverActive - rep_Activation (ActiveBefore phase) = Just (coreBool False, - MkC $ mkIntExprInt phase) - rep_Activation (ActiveAfter phase) = Just (coreBool True, - MkC $ mkIntExprInt phase) +repRuleMatch :: RuleMatchInfo -> DsM (Core TH.RuleMatch) +repRuleMatch ConLike = dataCon conLikeDataConName +repRuleMatch FunLike = dataCon funLikeDataConName +repPhases :: Activation -> DsM (Core TH.Phases) +repPhases (ActiveBefore i) = do { MkC arg <- coreIntLit i + ; dataCon' beforePhaseDataConName [arg] } +repPhases (ActiveAfter i) = do { MkC arg <- coreIntLit i + ; dataCon' fromPhaseDataConName [arg] } +repPhases _ = dataCon allPhasesDataConName ------------------------------------------------------- -- Types @@ -1389,9 +1408,12 @@ rep2 :: Name -> [ CoreExpr ] -> DsM (Core a) rep2 n xs = do { id <- dsLookupGlobalId n ; return (MkC (foldl App (Var id) xs)) } +dataCon' :: Name -> [CoreExpr] -> DsM (Core a) +dataCon' n args = do { id <- dsLookupDataCon n + ; return $ MkC $ mkConApp id args } + dataCon :: Name -> DsM (Core a) -dataCon n = do { id <- dsLookupDataCon n - ; return $ MkC $ mkConApp id [] } +dataCon n = dataCon' n [] -- Then we make "repConstructors" which use the phantom types for each of the -- smart constructors of the Meta.Meta datatypes. @@ -1603,16 +1625,28 @@ repClass :: Core TH.CxtQ -> Core TH.Name -> Core [TH.TyVarBndr] repClass (MkC cxt) (MkC cls) (MkC tvs) (MkC fds) (MkC ds) = rep2 classDName [cxt, cls, tvs, fds, ds] -repPragInl :: Core TH.Name -> Core TH.InlineSpecQ -> DsM (Core TH.DecQ) -repPragInl (MkC nm) (MkC ispec) = rep2 pragInlDName [nm, ispec] +repPragInl :: Core TH.Name -> Core TH.Inline -> Core TH.RuleMatch + -> Core TH.Phases -> DsM (Core TH.DecQ) +repPragInl (MkC nm) (MkC inline) (MkC rm) (MkC phases) + = rep2 pragInlDName [nm, inline, rm, phases] + +repPragSpec :: Core TH.Name -> Core TH.TypeQ -> Core TH.Phases + -> DsM (Core TH.DecQ) +repPragSpec (MkC nm) (MkC ty) (MkC phases) + = rep2 pragSpecDName [nm, ty, phases] -repPragSpec :: Core TH.Name -> Core TH.TypeQ -> DsM (Core TH.DecQ) -repPragSpec (MkC nm) (MkC ty) = rep2 pragSpecDName [nm, ty] +repPragSpecInl :: Core TH.Name -> Core TH.TypeQ -> Core TH.Inline + -> Core TH.Phases -> DsM (Core TH.DecQ) +repPragSpecInl (MkC nm) (MkC ty) (MkC inline) (MkC phases) + = rep2 pragSpecInlDName [nm, ty, inline, phases] -repPragSpecInl :: Core TH.Name -> Core TH.TypeQ -> Core TH.InlineSpecQ - -> DsM (Core TH.DecQ) -repPragSpecInl (MkC nm) (MkC ty) (MkC ispec) - = rep2 pragSpecInlDName [nm, ty, ispec] +repPragSpecInst :: Core TH.TypeQ -> DsM (Core TH.DecQ) +repPragSpecInst (MkC ty) = rep2 pragSpecInstDName [ty] + +repPragRule :: Core String -> Core [TH.RuleBndrQ] -> Core TH.ExpQ + -> Core TH.ExpQ -> Core TH.Phases -> DsM (Core TH.DecQ) +repPragRule (MkC nm) (MkC bndrs) (MkC lhs) (MkC rhs) (MkC phases) + = rep2 pragRuleDName [nm, bndrs, lhs, rhs, phases] repFamilyNoKind :: Core TH.FamFlavour -> Core TH.Name -> Core [TH.TyVarBndr] -> DsM (Core TH.DecQ) @@ -1625,16 +1659,6 @@ repFamilyKind :: Core TH.FamFlavour -> Core TH.Name -> Core [TH.TyVarBndr] repFamilyKind (MkC flav) (MkC nm) (MkC tvs) (MkC ki) = rep2 familyKindDName [flav, nm, tvs, ki] -repInlineSpecNoPhase :: Core TH.Inline -> Core Bool - -> DsM (Core TH.InlineSpecQ) -repInlineSpecNoPhase (MkC inline) (MkC conlike) - = rep2 inlineSpecNoPhaseName [inline, conlike] - -repInlineSpecPhase :: Core TH.Inline -> Core Bool -> Core Bool -> Core Int - -> DsM (Core TH.InlineSpecQ) -repInlineSpecPhase (MkC inline) (MkC conlike) (MkC beforeFrom) (MkC phase) - = rep2 inlineSpecPhaseName [inline, conlike, beforeFrom, phase] - repFunDep :: Core [TH.Name] -> Core [TH.Name] -> DsM (Core TH.FunDep) repFunDep (MkC xs) (MkC ys) = rep2 funDepName [xs, ys] @@ -1851,11 +1875,7 @@ nonEmptyCoreList xs@(MkC x:_) = MkC (mkListExpr (exprType x) (map unC xs)) coreStringLit :: String -> DsM (Core String) coreStringLit s = do { z <- mkStringExpr s; return(MkC z) } ------------- Bool, Literals & Variables ------------------- - -coreBool :: Bool -> Core Bool -coreBool False = MkC $ mkConApp falseDataCon [] -coreBool True = MkC $ mkConApp trueDataCon [] +------------ Literals & Variables ------------------- coreIntLit :: Int -> DsM (Core Int) coreIntLit i = return (MkC (mkIntExprInt i)) @@ -1923,7 +1943,8 @@ templateHaskellNames = [ -- Dec funDName, valDName, dataDName, newtypeDName, tySynDName, classDName, instanceDName, sigDName, forImpDName, - pragInlDName, pragSpecDName, pragSpecInlDName, + pragInlDName, pragSpecDName, pragSpecInlDName, pragSpecInstDName, + pragRuleDName, familyNoKindDName, familyKindDName, dataInstDName, newtypeInstDName, tySynInstDName, infixLDName, infixRDName, infixNDName, -- Cxt @@ -1957,8 +1978,12 @@ templateHaskellNames = [ interruptibleName, -- Inline noInlineDataConName, inlineDataConName, inlinableDataConName, - -- InlineSpec - inlineSpecNoPhaseName, inlineSpecPhaseName, + -- RuleMatch + conLikeDataConName, funLikeDataConName, + -- Phases + allPhasesDataConName, fromPhaseDataConName, beforePhaseDataConName, + -- RuleBndr + ruleVarName, typedRuleVarName, -- FunDep funDepName, -- FamFlavour @@ -1971,7 +1996,7 @@ templateHaskellNames = [ varStrictTypeQTyConName, typeQTyConName, expTyConName, decTyConName, typeTyConName, tyVarBndrTyConName, matchTyConName, clauseTyConName, patQTyConName, fieldPatQTyConName, fieldExpQTyConName, funDepTyConName, - predQTyConName, decsQTyConName, + predQTyConName, decsQTyConName, ruleBndrQTyConName, -- Quasiquoting quoteDecName, quoteTypeName, quoteExpName, quotePatName] @@ -2130,29 +2155,31 @@ parSName = libFun (fsLit "parS") parSIdKey -- data Dec = ... funDName, valDName, dataDName, newtypeDName, tySynDName, classDName, instanceDName, sigDName, forImpDName, pragInlDName, pragSpecDName, - pragSpecInlDName, familyNoKindDName, familyKindDName, dataInstDName, - newtypeInstDName, tySynInstDName, + pragSpecInlDName, pragSpecInstDName, pragRuleDName, familyNoKindDName, + familyKindDName, dataInstDName, newtypeInstDName, tySynInstDName, infixLDName, infixRDName, infixNDName :: Name -funDName = libFun (fsLit "funD") funDIdKey -valDName = libFun (fsLit "valD") valDIdKey -dataDName = libFun (fsLit "dataD") dataDIdKey -newtypeDName = libFun (fsLit "newtypeD") newtypeDIdKey -tySynDName = libFun (fsLit "tySynD") tySynDIdKey -classDName = libFun (fsLit "classD") classDIdKey -instanceDName = libFun (fsLit "instanceD") instanceDIdKey -sigDName = libFun (fsLit "sigD") sigDIdKey -forImpDName = libFun (fsLit "forImpD") forImpDIdKey -pragInlDName = libFun (fsLit "pragInlD") pragInlDIdKey -pragSpecDName = libFun (fsLit "pragSpecD") pragSpecDIdKey -pragSpecInlDName = libFun (fsLit "pragSpecInlD") pragSpecInlDIdKey -familyNoKindDName= libFun (fsLit "familyNoKindD")familyNoKindDIdKey -familyKindDName = libFun (fsLit "familyKindD") familyKindDIdKey -dataInstDName = libFun (fsLit "dataInstD") dataInstDIdKey -newtypeInstDName = libFun (fsLit "newtypeInstD") newtypeInstDIdKey -tySynInstDName = libFun (fsLit "tySynInstD") tySynInstDIdKey -infixLDName = libFun (fsLit "infixLD") infixLDIdKey -infixRDName = libFun (fsLit "infixRD") infixRDIdKey -infixNDName = libFun (fsLit "infixND") infixNDIdKey +funDName = libFun (fsLit "funD") funDIdKey +valDName = libFun (fsLit "valD") valDIdKey +dataDName = libFun (fsLit "dataD") dataDIdKey +newtypeDName = libFun (fsLit "newtypeD") newtypeDIdKey +tySynDName = libFun (fsLit "tySynD") tySynDIdKey +classDName = libFun (fsLit "classD") classDIdKey +instanceDName = libFun (fsLit "instanceD") instanceDIdKey +sigDName = libFun (fsLit "sigD") sigDIdKey +forImpDName = libFun (fsLit "forImpD") forImpDIdKey +pragInlDName = libFun (fsLit "pragInlD") pragInlDIdKey +pragSpecDName = libFun (fsLit "pragSpecD") pragSpecDIdKey +pragSpecInlDName = libFun (fsLit "pragSpecInlD") pragSpecInlDIdKey +pragSpecInstDName = libFun (fsLit "pragSpecInstD") pragSpecInstDIdKey +pragRuleDName = libFun (fsLit "pragRuleD") pragRuleDIdKey +familyNoKindDName = libFun (fsLit "familyNoKindD") familyNoKindDIdKey +familyKindDName = libFun (fsLit "familyKindD") familyKindDIdKey +dataInstDName = libFun (fsLit "dataInstD") dataInstDIdKey +newtypeInstDName = libFun (fsLit "newtypeInstD") newtypeInstDIdKey +tySynInstDName = libFun (fsLit "tySynInstD") tySynInstDIdKey +infixLDName = libFun (fsLit "infixLD") infixLDIdKey +infixRDName = libFun (fsLit "infixRD") infixRDIdKey +infixNDName = libFun (fsLit "infixND") infixNDIdKey -- type Ctxt = ... cxtName :: Name @@ -2243,10 +2270,21 @@ noInlineDataConName = thCon (fsLit "NoInline") noInlineDataConKey inlineDataConName = thCon (fsLit "Inline") inlineDataConKey inlinableDataConName = thCon (fsLit "Inlinable") inlinableDataConKey --- data InlineSpec = ... -inlineSpecNoPhaseName, inlineSpecPhaseName :: Name -inlineSpecNoPhaseName = libFun (fsLit "inlineSpecNoPhase") inlineSpecNoPhaseIdKey -inlineSpecPhaseName = libFun (fsLit "inlineSpecPhase") inlineSpecPhaseIdKey +-- data RuleMatch = ... +conLikeDataConName, funLikeDataConName :: Name +conLikeDataConName = thCon (fsLit "ConLike") conLikeDataConKey +funLikeDataConName = thCon (fsLit "FunLike") funLikeDataConKey + +-- data Phases = ... +allPhasesDataConName, fromPhaseDataConName, beforePhaseDataConName :: Name +allPhasesDataConName = thCon (fsLit "AllPhases") allPhasesDataConKey +fromPhaseDataConName = thCon (fsLit "FromPhase") fromPhaseDataConKey +beforePhaseDataConName = thCon (fsLit "BeforePhase") beforePhaseDataConKey + +-- data RuleBndr = ... +ruleVarName, typedRuleVarName :: Name +ruleVarName = libFun (fsLit ("ruleVar")) ruleVarIdKey +typedRuleVarName = libFun (fsLit ("typedRuleVar")) typedRuleVarIdKey -- data FunDep = ... funDepName :: Name @@ -2260,12 +2298,13 @@ dataFamName = libFun (fsLit "dataFam") dataFamIdKey matchQTyConName, clauseQTyConName, expQTyConName, stmtQTyConName, decQTyConName, conQTyConName, strictTypeQTyConName, varStrictTypeQTyConName, typeQTyConName, fieldExpQTyConName, - patQTyConName, fieldPatQTyConName, predQTyConName, decsQTyConName :: Name -matchQTyConName = libTc (fsLit "MatchQ") matchQTyConKey -clauseQTyConName = libTc (fsLit "ClauseQ") clauseQTyConKey -expQTyConName = libTc (fsLit "ExpQ") expQTyConKey -stmtQTyConName = libTc (fsLit "StmtQ") stmtQTyConKey -decQTyConName = libTc (fsLit "DecQ") decQTyConKey + patQTyConName, fieldPatQTyConName, predQTyConName, decsQTyConName, + ruleBndrQTyConName :: Name +matchQTyConName = libTc (fsLit "MatchQ") matchQTyConKey +clauseQTyConName = libTc (fsLit "ClauseQ") clauseQTyConKey +expQTyConName = libTc (fsLit "ExpQ") expQTyConKey +stmtQTyConName = libTc (fsLit "StmtQ") stmtQTyConKey +decQTyConName = libTc (fsLit "DecQ") decQTyConKey decsQTyConName = libTc (fsLit "DecsQ") decsQTyConKey -- Q [Dec] conQTyConName = libTc (fsLit "ConQ") conQTyConKey strictTypeQTyConName = libTc (fsLit "StrictTypeQ") strictTypeQTyConKey @@ -2275,6 +2314,7 @@ fieldExpQTyConName = libTc (fsLit "FieldExpQ") fieldExpQTyConKey patQTyConName = libTc (fsLit "PatQ") patQTyConKey fieldPatQTyConName = libTc (fsLit "FieldPatQ") fieldPatQTyConKey predQTyConName = libTc (fsLit "PredQ") predQTyConKey +ruleBndrQTyConName = libTc (fsLit "RuleBndrQ") ruleBndrQTyConKey -- quasiquoting quoteExpName, quotePatName, quoteDecName, quoteTypeName :: Name @@ -2292,7 +2332,7 @@ expTyConKey, matchTyConKey, clauseTyConKey, qTyConKey, expQTyConKey, decTyConKey, varStrictTypeQTyConKey, strictTypeQTyConKey, fieldExpTyConKey, fieldPatTyConKey, nameTyConKey, patQTyConKey, fieldPatQTyConKey, fieldExpQTyConKey, funDepTyConKey, predTyConKey, - predQTyConKey, decsQTyConKey :: Unique + predQTyConKey, decsQTyConKey, ruleBndrQTyConKey :: Unique expTyConKey = mkPreludeTyConUnique 200 matchTyConKey = mkPreludeTyConUnique 201 clauseTyConKey = mkPreludeTyConUnique 202 @@ -2320,6 +2360,7 @@ predTyConKey = mkPreludeTyConUnique 223 predQTyConKey = mkPreludeTyConUnique 224 tyVarBndrTyConKey = mkPreludeTyConUnique 225 decsQTyConKey = mkPreludeTyConUnique 226 +ruleBndrQTyConKey = mkPreludeTyConUnique 227 -- IdUniques available: 200-499 -- If you want to change this, make sure you check in PrelNames @@ -2443,7 +2484,8 @@ parSIdKey = mkPreludeMiscIdUnique 323 -- data Dec = ... funDIdKey, valDIdKey, dataDIdKey, newtypeDIdKey, tySynDIdKey, classDIdKey, instanceDIdKey, sigDIdKey, forImpDIdKey, pragInlDIdKey, - pragSpecDIdKey, pragSpecInlDIdKey, familyNoKindDIdKey, familyKindDIdKey, + pragSpecDIdKey, pragSpecInlDIdKey, pragSpecInstDIdKey, pragRuleDIdKey, + familyNoKindDIdKey, familyKindDIdKey, dataInstDIdKey, newtypeInstDIdKey, tySynInstDIdKey, infixLDIdKey, infixRDIdKey, infixNDIdKey :: Unique funDIdKey = mkPreludeMiscIdUnique 330 @@ -2458,6 +2500,8 @@ forImpDIdKey = mkPreludeMiscIdUnique 338 pragInlDIdKey = mkPreludeMiscIdUnique 339 pragSpecDIdKey = mkPreludeMiscIdUnique 340 pragSpecInlDIdKey = mkPreludeMiscIdUnique 341 +pragSpecInstDIdKey = mkPreludeMiscIdUnique 412 +pragRuleDIdKey = mkPreludeMiscIdUnique 413 familyNoKindDIdKey = mkPreludeMiscIdUnique 342 familyKindDIdKey = mkPreludeMiscIdUnique 343 dataInstDIdKey = mkPreludeMiscIdUnique 344 @@ -2556,10 +2600,16 @@ noInlineDataConKey = mkPreludeDataConUnique 40 inlineDataConKey = mkPreludeDataConUnique 41 inlinableDataConKey = mkPreludeDataConUnique 42 --- data InlineSpec = -inlineSpecNoPhaseIdKey, inlineSpecPhaseIdKey :: Unique -inlineSpecNoPhaseIdKey = mkPreludeMiscIdUnique 412 -inlineSpecPhaseIdKey = mkPreludeMiscIdUnique 413 +-- data RuleMatch = ... +conLikeDataConKey, funLikeDataConKey :: Unique +conLikeDataConKey = mkPreludeDataConUnique 43 +funLikeDataConKey = mkPreludeDataConUnique 44 + +-- data Phases = ... +allPhasesDataConKey, fromPhaseDataConKey, beforePhaseDataConKey :: Unique +allPhasesDataConKey = mkPreludeDataConUnique 45 +fromPhaseDataConKey = mkPreludeDataConUnique 46 +beforePhaseDataConKey = mkPreludeDataConUnique 47 -- data FunDep = ... funDepIdKey :: Unique @@ -2576,3 +2626,8 @@ quoteExpKey = mkPreludeMiscIdUnique 418 quotePatKey = mkPreludeMiscIdUnique 419 quoteDecKey = mkPreludeMiscIdUnique 420 quoteTypeKey = mkPreludeMiscIdUnique 421 + +-- data RuleBndr = ... +ruleVarIdKey, typedRuleVarIdKey :: Unique +ruleVarIdKey = mkPreludeMiscIdUnique 422 +typedRuleVarIdKey = mkPreludeMiscIdUnique 423 diff --git a/compiler/hsSyn/Convert.lhs b/compiler/hsSyn/Convert.lhs index 376ff236b7f8..847d90b94403 100644 --- a/compiler/hsSyn/Convert.lhs +++ b/compiler/hsSyn/Convert.lhs @@ -157,8 +157,7 @@ cvtDec (TH.InfixD fx nm) ; returnL (Hs.SigD (FixSig (FixitySig nm' (cvtFixity fx)))) } cvtDec (PragmaD prag) - = do { prag' <- cvtPragmaD prag - ; returnL $ Hs.SigD prag' } + = cvtPragmaD prag cvtDec (TySynD tc tvs rhs) = do { (_, tc', tvs') <- cvt_tycl_hdr [] tc tvs @@ -410,38 +409,69 @@ cvt_conv TH.StdCall = StdCallConv -- Pragmas ------------------------------------------ -cvtPragmaD :: Pragma -> CvtM (Sig RdrName) -cvtPragmaD (InlineP nm ispec) - = do { nm' <- vNameL nm - ; return $ InlineSig nm' (cvtInlineSpec (Just ispec)) } - -cvtPragmaD (SpecialiseP nm ty opt_ispec) +cvtPragmaD :: Pragma -> CvtM (LHsDecl RdrName) +cvtPragmaD (InlineP nm inline rm phases) + = do { nm' <- vNameL nm + ; let dflt = dfltActivation inline + ; let ip = InlinePragma { inl_inline = cvtInline inline + , inl_rule = cvtRuleMatch rm + , inl_act = cvtPhases phases dflt + , inl_sat = Nothing } + ; returnL $ Hs.SigD $ InlineSig nm' ip } + +cvtPragmaD (SpecialiseP nm ty inline phases) = do { nm' <- vNameL nm ; ty' <- cvtType ty - ; return $ SpecSig nm' ty' (cvtInlineSpec opt_ispec) } - -cvtInlineSpec :: Maybe TH.InlineSpec -> Hs.InlinePragma -cvtInlineSpec Nothing - = defaultInlinePragma -cvtInlineSpec (Just (TH.InlineSpec inline conlike opt_activation)) - = InlinePragma { inl_act = opt_activation', inl_rule = matchinfo - , inl_inline = inl_spec, inl_sat = Nothing } - where - matchinfo = cvtRuleMatchInfo conlike - opt_activation' = cvtActivation opt_activation - - cvtRuleMatchInfo False = FunLike - cvtRuleMatchInfo True = ConLike - - inl_spec = case inline of - TH.NoInline -> Hs.NoInline - TH.Inline -> Hs.Inline - TH.Inlinable -> Hs.Inlinable + ; let (inline', dflt) = case inline of + Just inline1 -> (cvtInline inline1, dfltActivation inline1) + Nothing -> (EmptyInlineSpec, AlwaysActive) + ; let ip = InlinePragma { inl_inline = inline' + , inl_rule = Hs.FunLike + , inl_act = cvtPhases phases dflt + , inl_sat = Nothing } + ; returnL $ Hs.SigD $ SpecSig nm' ty' ip } + +cvtPragmaD (SpecialiseInstP ty) + = do { ty' <- cvtType ty + ; returnL $ Hs.SigD $ SpecInstSig ty' } + +cvtPragmaD (RuleP nm bndrs lhs rhs phases) + = do { let nm' = mkFastString nm + ; let act = cvtPhases phases AlwaysActive + ; bndrs' <- mapM cvtRuleBndr bndrs + ; lhs' <- cvtl lhs + ; rhs' <- cvtl rhs + ; returnL $ Hs.RuleD $ HsRule nm' act bndrs' + lhs' placeHolderNames + rhs' placeHolderNames + } - cvtActivation Nothing | inline == TH.NoInline = NeverActive - | otherwise = AlwaysActive - cvtActivation (Just (False, phase)) = ActiveBefore phase - cvtActivation (Just (True , phase)) = ActiveAfter phase +dfltActivation :: TH.Inline -> Activation +dfltActivation TH.NoInline = NeverActive +dfltActivation _ = AlwaysActive + +cvtInline :: TH.Inline -> Hs.InlineSpec +cvtInline TH.NoInline = Hs.NoInline +cvtInline TH.Inline = Hs.Inline +cvtInline TH.Inlinable = Hs.Inlinable + +cvtRuleMatch :: TH.RuleMatch -> RuleMatchInfo +cvtRuleMatch TH.ConLike = Hs.ConLike +cvtRuleMatch TH.FunLike = Hs.FunLike + +cvtPhases :: TH.Phases -> Activation -> Activation +cvtPhases AllPhases dflt = dflt +cvtPhases (FromPhase i) _ = ActiveAfter i +cvtPhases (BeforePhase i) _ = ActiveBefore i + +cvtRuleBndr :: TH.RuleBndr -> CvtM (Hs.RuleBndr RdrName) +cvtRuleBndr (RuleVar n) + = do { n' <- vNameL n + ; return $ Hs.RuleBndr n' } +cvtRuleBndr (TypedRuleVar n ty) + = do { n' <- vNameL n + ; ty' <- cvtType ty + ; return $ Hs.RuleBndrSig n' $ mkHsWithBndrs ty' } --------------------------------------------------- -- Declarations -- GitLab