parsley-garnish 0.1.0.1 → 1.0.0.0
raw patch · 4 files changed
+73/−14 lines, 4 filesdep +parsley-coredep −parsleyPVP ok
version bump matches the API change (PVP)
Dependencies added: parsley-core
Dependencies removed: parsley
API changes (from Hackage documentation)
+ Parsley.Internal.Bridge: _code :: Quapplicative q => q a -> Code a
+ Parsley.Internal.Bridge: _val :: Quapplicative q => q a -> a
+ Parsley.Internal.Bridge: makeQ :: Quapplicative q => a -> Code a -> q a
+ Parsley.Internal.Bridge: mkCode :: Quapplicative q => Code a -> q a
+ Parsley.Internal.Bridge: mkVal :: Quapplicative q => a -> q a
Files
- ChangeLog.md +5/−0
- parsley-garnish.cabal +7/−2
- src/Parsley/Internal/Bridge.hs +45/−0
- src/Parsley/OverloadedQuotesPlugin/Plugin.hs +16/−12
ChangeLog.md view
@@ -7,3 +7,8 @@ ## 0.1.0.1 -- 2021-06-11 * Support for GHC 9.0 in place.++## 1.0.0.0 -- 2021-06-12++* Switched to support `parsley-core` as the base+* Introduced the `Parsley.Internal.Bridge` module to provide functions for the plugin to latch onto
parsley-garnish.cabal view
@@ -1,5 +1,5 @@ name: parsley-garnish-version: 0.1.0.1+version: 1.0.0.0 synopsis: A collection of GHC plugins to work with parsley description: This package contains a collection (for now one) to help remove boilerplate when writing parsers using @parsley@.@@ -16,6 +16,10 @@ extra-doc-files: ChangeLog.md README.md cabal-version: 1.18+tested-with: GHC == 8.6.5,+ GHC == 8.8.4,+ GHC == 8.10.5,+ GHC == 9.0.1 library exposed-modules: @@ -23,6 +27,7 @@ -- Parsley.LiftPlugin -- Parsley.OverloadedSyntaxPlugin Parsley.OverloadedQuotesPlugin+ Parsley.Internal.Bridge other-modules: Parsley.PluginUtils -- -- Lift Plugin -- Parsley.LiftPlugin.Plugin@@ -36,7 +41,7 @@ Parsley.OverloadedQuotesPlugin.Plugin build-depends: base >= 4.10 && < 5,- parsley >= 0.1 && < 0.2,+ parsley-core >= 1 && < 2, template-haskell >= 2.14 && < 3, ghc-tcplugins-extra >= 0.3 && < 0.5, ghc >= 8.6 && < 9.2,
+ src/Parsley/Internal/Bridge.hs view
@@ -0,0 +1,45 @@+{-|+Module : Parsley.Internal.Bridge+Description : Stable and package independent names for portions of the @parsley-core@ API+License : BSD-3-CLAUSE+Maintainer : Jamie Willis+Stability : stable++The plugins in this package depend on internals defined in @parsley-core@. This+is fine, but we'd prefer our users to not have to explicitly depend on @parsley-core@+to use the plugins. This module is used to provide stable names for the plugins+to latch onto. It should not be imported by users of the plugins!+-}+module Parsley.Internal.Bridge (_code, _val, makeQ, mkVal, mkCode) where++import qualified Parsley.Internal (Quapplicative(..), Code)++{-|+Re-export of `Parsley.Internal._code`+-}+_code :: Parsley.Internal.Quapplicative q => q a -> Parsley.Internal.Code a+_code = Parsley.Internal._code++{-|+Re-export of `Parsley.Internal._val`+-}+_val :: Parsley.Internal.Quapplicative q => q a -> a+_val = Parsley.Internal._val++{-|+Re-export of `Parsley.Internal.makeQ`+-}+makeQ :: Parsley.Internal.Quapplicative q => a -> Parsley.Internal.Code a -> q a+makeQ = Parsley.Internal.makeQ++{-|+Produces `Parsley.Internal.Quapplicative` values without code (unsafe!)+-}+mkVal :: Parsley.Internal.Quapplicative q => a -> q a+mkVal x = Parsley.Internal.makeQ x undefined++{-|+Produces `Parsley.Internal.Quapplicative` values without values (unsafe!)+-}+mkCode :: Parsley.Internal.Quapplicative q => Parsley.Internal.Code a -> q a+mkCode qx = Parsley.Internal.makeQ undefined qx
src/Parsley/OverloadedQuotesPlugin/Plugin.hs view
@@ -12,7 +12,7 @@ import Data.Generics (GenericT, GenericQ, mkT, mkQ, everywhere, gmapT) import GHC.Generics (Generic) -import Parsley.PluginUtils (lookupModuleInPackage, lookupName, lookupNames)+import Parsley.PluginUtils (lookupModule, lookupNames) #if __GLASGOW_HASKELL__ >= 900 import GHC.Driver.Plugins (Plugin (..), defaultPlugin, purePlugin)@@ -58,27 +58,29 @@ data QOps a = QOps { _code :: a, _val :: a,- makeQ :: a+ makeQ :: a,+ mkCode :: a,+ mkVal :: a } deriving (Functor, Foldable, Traversable, Generic) quapplicativeStrings :: QOps String quapplicativeStrings = QOps { _code = "_code", _val = "_val",- makeQ = "makeQ"+ makeQ = "makeQ",+ mkCode = "mkCode",+ mkVal = "mkVal" } overloadedQuotes :: [GHC.CommandLineOption] -> TcGblEnv -> GHC.HsGroup GHC.GhcRn -> TcM (TcGblEnv, GHC.HsGroup GHC.GhcRn) overloadedQuotes _ gEnv rn = do hscEnv <- GHC.getTopEnv- parsley <- lookupModuleInPackage hscEnv "parsley" "Parsley.Internal.Common.Utils"+ parsley <- lookupModule hscEnv "Parsley.Internal.Bridge" qops <- lookupNames parsley quapplicativeStrings- prelude <- lookupModuleInPackage hscEnv "base" "GHC.Err"- undef <- lookupName prelude "undefined" -- This is a little inefficient, since the top-down transformation means no quotes can be -- found under a top-level one: we use a top-down version of everywhereBut to stop traversal -- of this whenever it fires- return (gEnv, onlyTopmost (mkQ False isQuote) (mkT (transformUTHQuote qops undef)) rn)+ return (gEnv, onlyTopmost (mkQ False isQuote) (mkT (transformUTHQuote qops)) rn) mkApp :: GHC.SrcSpan -> Expr -> Expr -> Expr mkApp s f = GHC.L s . Expr.HsApp noExt f . mkPar s@@ -103,17 +105,19 @@ -- the original quote. Perhaps in that case we could just inline the definition into both holes... -- As `transform` works bottom up, we can always assume nested quotes are already handled: this might -- get tricky, however.-transformUTHQuote :: QOps GHC.Name -> GHC.Name -> Expr -> Expr-transformUTHQuote ops undef (LUTHQuote s ex ex' x) = --pprTouch "new quote" $+transformUTHQuote :: QOps GHC.Name -> Expr -> Expr+transformUTHQuote ops (LUTHQuote s ex ex' x) = --pprTouch "new quote" $ mkPar s (makeQS `mkAppS` everywhere (mkT (transformUTHQuoteVar (_val ops) makeVal)) x `mkAppS` mkQuote (everywhere (mkT (transformUTHQuoteCode (_code ops) makeCode)) x)) where mkQuote y = GHC.L s (Expr.HsBracket ex (Expr.TExpBr ex' y)) mkAppS = mkApp s makeQS = mkVar s (makeQ ops)- makeVal y = mkPar s (makeQS `mkAppS` y `mkAppS` mkVar s undef)- makeCode y = mkPar s (makeQS `mkAppS` mkVar s undef `mkAppS` y)-transformUTHQuote _ _ x = x+ mkValS = mkVar s (mkVal ops)+ mkCodeS = mkVar s (mkCode ops)+ makeVal y = mkPar s (mkValS `mkAppS` y)+ makeCode y = mkPar s (mkCodeS `mkAppS` y)+transformUTHQuote _ x = x transformUTHQuoteVar :: GHC.Name -> (Expr -> Expr) -> Expr -> Expr transformUTHQuoteVar _ makeVal (LUTHQuote _ _ _ x) = makeVal x