{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}

{-# OPTIONS_GHC -Wno-missing-fields #-}

module Nix.TH where

import           Data.Fix                       ( Fix(..) )
import           Data.Generics.Aliases          ( extQ )
import qualified Data.Set                      as Set
import           Language.Haskell.TH
import qualified Language.Haskell.TH.Syntax    as TH
import           Language.Haskell.TH.Quote
import           Nix.Atoms
import           Nix.Expr
import           Nix.Parser

quoteExprExp :: String -> ExpQ
quoteExprExp :: String -> ExpQ
quoteExprExp String
s = do
  NExpr
expr <-
    (Doc Void -> Q NExpr)
-> (NExpr -> Q NExpr) -> Either (Doc Void) NExpr -> Q NExpr
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
      (String -> Q NExpr
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q NExpr) -> (Doc Void -> String) -> Doc Void -> Q NExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Void -> String
forall b a. (Show a, IsString b) => a -> b
show)
      NExpr -> Q NExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure
      (VarName -> Either (Doc Void) NExpr
parseNixText (VarName -> Either (Doc Void) NExpr)
-> VarName -> Either (Doc Void) NExpr
forall a b. (a -> b) -> a -> b
$ String -> VarName
forall a. ToText a => a -> VarName
toText String
s)
  (forall b. Data b => b -> Maybe ExpQ) -> NExpr -> ExpQ
forall (m :: * -> *) a.
(Quote m, Data a) =>
(forall b. Data b => b -> Maybe (m Exp)) -> a -> m Exp
dataToExpQ
    (Maybe ExpQ -> b -> Maybe ExpQ
forall a b. a -> b -> a
const Maybe ExpQ
forall a. Maybe a
Nothing (b -> Maybe ExpQ) -> (NExprLoc -> Maybe ExpQ) -> b -> Maybe ExpQ
forall a b q.
(Typeable a, Typeable b) =>
(a -> q) -> (b -> q) -> a -> q
`extQ` Set VarName -> NExprLoc -> Maybe ExpQ
metaExp (NExpr -> Set VarName
freeVars NExpr
expr) (b -> Maybe ExpQ) -> (VarName -> Maybe ExpQ) -> b -> Maybe ExpQ
forall a b q.
(Typeable a, Typeable b) =>
(a -> q) -> (b -> q) -> a -> q
`extQ` (ExpQ -> Maybe ExpQ
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExpQ -> Maybe ExpQ) -> (VarName -> ExpQ) -> VarName -> Maybe ExpQ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VarName -> ExpQ
forall t (m :: * -> *). (Lift t, Quote m) => t -> m Exp
TH.lift :: Text -> Q Exp)))
    NExpr
expr

quoteExprPat :: String -> PatQ
quoteExprPat :: String -> PatQ
quoteExprPat String
s = do
  NExpr
expr <-
    (Doc Void -> Q NExpr)
-> (NExpr -> Q NExpr) -> Either (Doc Void) NExpr -> Q NExpr
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
      (String -> Q NExpr
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q NExpr) -> (Doc Void -> String) -> Doc Void -> Q NExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Void -> String
forall b a. (Show a, IsString b) => a -> b
show)
      NExpr -> Q NExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure
      (VarName -> Either (Doc Void) NExpr
parseNixText (VarName -> Either (Doc Void) NExpr)
-> VarName -> Either (Doc Void) NExpr
forall a b. (a -> b) -> a -> b
$ String -> VarName
forall a. ToText a => a -> VarName
toText String
s)
  (forall b. Data b => b -> Maybe PatQ) -> NExpr -> PatQ
forall (m :: * -> *) a.
(Quote m, Data a) =>
(forall b. Data b => b -> Maybe (m Pat)) -> a -> m Pat
dataToPatQ
    (Maybe PatQ -> b -> Maybe PatQ
forall a b. a -> b -> a
const Maybe PatQ
forall a. Maybe a
Nothing (b -> Maybe PatQ) -> (NExprLoc -> Maybe PatQ) -> b -> Maybe PatQ
forall a b q.
(Typeable a, Typeable b) =>
(a -> q) -> (b -> q) -> a -> q
`extQ` Set VarName -> NExprLoc -> Maybe PatQ
metaPat (NExpr -> Set VarName
freeVars NExpr
expr))
    NExpr
expr

freeVars :: NExpr -> Set VarName
freeVars :: NExpr -> Set VarName
freeVars NExpr
e = case NExpr -> NExprF NExpr
forall (f :: * -> *). Fix f -> f (Fix f)
unFix NExpr
e of
  (NConstant    NAtom
_               ) -> Set VarName
forall a. Monoid a => a
mempty
  (NStr         NString NExpr
string          ) -> NString NExpr -> Set VarName
forall (t :: * -> *). Foldable t => t NExpr -> Set VarName
mapFreeVars NString NExpr
string
  (NSym         VarName
var             ) -> OneItem (Set VarName) -> Set VarName
forall x. One x => OneItem x -> x
one VarName
OneItem (Set VarName)
var
  (NList        [NExpr]
list            ) -> [NExpr] -> Set VarName
forall (t :: * -> *). Foldable t => t NExpr -> Set VarName
mapFreeVars [NExpr]
list
  (NSet   NRecordType
NNonRecursive [Binding NExpr]
bindings) -> [Binding NExpr] -> Set VarName
forall (t :: * -> *).
Foldable t =>
t (Binding NExpr) -> Set VarName
bindFreeVars [Binding NExpr]
bindings
  (NSet   NRecordType
NRecursive    [Binding NExpr]
bindings) -> Set VarName -> Set VarName -> Set VarName
forall a. Ord a => Set a -> Set a -> Set a
Set.difference ([Binding NExpr] -> Set VarName
forall (t :: * -> *).
Foldable t =>
t (Binding NExpr) -> Set VarName
bindFreeVars [Binding NExpr]
bindings) ([Binding NExpr] -> Set VarName
forall (t :: * -> *).
Foldable t =>
t (Binding NExpr) -> Set VarName
bindDefs [Binding NExpr]
bindings)
  (NLiteralPath String
_               ) -> Set VarName
forall a. Monoid a => a
mempty
  (NEnvPath     String
_               ) -> Set VarName
forall a. Monoid a => a
mempty
  (NUnary       NUnaryOp
_    NExpr
expr       ) -> NExpr -> Set VarName
freeVars NExpr
expr
  (NBinary      NBinaryOp
_    NExpr
left NExpr
right ) -> (Set VarName -> Set VarName -> Set VarName
forall a. Semigroup a => a -> a -> a
(<>) (Set VarName -> Set VarName -> Set VarName)
-> (NExpr -> Set VarName) -> NExpr -> NExpr -> Set VarName
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` NExpr -> Set VarName
freeVars) NExpr
left NExpr
right
  (NSelect      NExpr
expr NAttrPath NExpr
path Maybe NExpr
orExpr) ->
    [Set VarName] -> Set VarName
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions
      [ NExpr -> Set VarName
freeVars NExpr
expr
      , NAttrPath NExpr -> Set VarName
pathFree NAttrPath NExpr
path
      , Set VarName -> (NExpr -> Set VarName) -> Maybe NExpr -> Set VarName
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Set VarName
forall a. Monoid a => a
mempty NExpr -> Set VarName
freeVars Maybe NExpr
orExpr
      ]
  (NHasAttr NExpr
expr            NAttrPath NExpr
path) -> NExpr -> Set VarName
freeVars NExpr
expr Set VarName -> Set VarName -> Set VarName
forall a. Semigroup a => a -> a -> a
<> NAttrPath NExpr -> Set VarName
pathFree NAttrPath NExpr
path
  (NAbs     (Param VarName
varname) NExpr
expr) -> VarName -> Set VarName -> Set VarName
forall a. Ord a => a -> Set a -> Set a
Set.delete VarName
varname (NExpr -> Set VarName
freeVars NExpr
expr)
  (NAbs (ParamSet ParamSet NExpr
set Bool
_ Maybe VarName
varname) NExpr
expr) ->
    -- Include all free variables from the expression and the default arguments
    NExpr -> Set VarName
freeVars NExpr
expr Set VarName -> Set VarName -> Set VarName
forall a. Semigroup a => a -> a -> a
<>
    -- But remove the argument name if existing, and all arguments in the parameter set
    Set VarName -> Set VarName -> Set VarName
forall a. Ord a => Set a -> Set a -> Set a
Set.difference
      ([Set VarName] -> Set VarName
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions ([Set VarName] -> Set VarName) -> [Set VarName] -> Set VarName
forall a b. (a -> b) -> a -> b
$ NExpr -> Set VarName
freeVars (NExpr -> Set VarName) -> [NExpr] -> [Set VarName]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((VarName, Maybe NExpr) -> Maybe NExpr)
-> ParamSet NExpr -> [NExpr]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (VarName, Maybe NExpr) -> Maybe NExpr
forall a b. (a, b) -> b
snd ParamSet NExpr
set)
      (Set VarName -> Set VarName -> Set VarName
forall a. Ord a => Set a -> Set a -> Set a
Set.difference
        (Set VarName
-> (VarName -> Set VarName) -> Maybe VarName -> Set VarName
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Set VarName
forall a. Monoid a => a
mempty VarName -> Set VarName
forall x. One x => OneItem x -> x
one Maybe VarName
varname)
        ([VarName] -> Set VarName
forall a. Ord a => [a] -> Set a
Set.fromList ([VarName] -> Set VarName) -> [VarName] -> Set VarName
forall a b. (a -> b) -> a -> b
$ (VarName, Maybe NExpr) -> VarName
forall a b. (a, b) -> a
fst ((VarName, Maybe NExpr) -> VarName) -> ParamSet NExpr -> [VarName]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParamSet NExpr
set)
      )
  (NLet         [Binding NExpr]
bindings NExpr
expr   ) ->
    NExpr -> Set VarName
freeVars NExpr
expr Set VarName -> Set VarName -> Set VarName
forall a. Semigroup a => a -> a -> a
<>
    Set VarName -> Set VarName -> Set VarName
forall a. Ord a => Set a -> Set a -> Set a
Set.difference
      ([Binding NExpr] -> Set VarName
forall (t :: * -> *).
Foldable t =>
t (Binding NExpr) -> Set VarName
bindFreeVars [Binding NExpr]
bindings)
      ([Binding NExpr] -> Set VarName
forall (t :: * -> *).
Foldable t =>
t (Binding NExpr) -> Set VarName
bindDefs  [Binding NExpr]
bindings)
  (NIf          NExpr
cond NExpr
th   NExpr
el    ) -> [Set VarName] -> Set VarName
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions ([Set VarName] -> Set VarName) -> [Set VarName] -> Set VarName
forall a b. (a -> b) -> a -> b
$ NExpr -> Set VarName
freeVars (NExpr -> Set VarName) -> [NExpr] -> [Set VarName]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [NExpr
cond, NExpr
th, NExpr
el]
  -- Evaluation is needed to find out whether x is a "real" free variable in `with y; x`, we just include it
  -- This also makes sense because its value can be overridden by `x: with y; x`
  (NWith        NExpr
set  NExpr
expr       ) -> (Set VarName -> Set VarName -> Set VarName
forall a. Semigroup a => a -> a -> a
(<>) (Set VarName -> Set VarName -> Set VarName)
-> (NExpr -> Set VarName) -> NExpr -> NExpr -> Set VarName
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` NExpr -> Set VarName
freeVars) NExpr
set NExpr
expr
  (NAssert      NExpr
assertion NExpr
expr  ) -> (Set VarName -> Set VarName -> Set VarName
forall a. Semigroup a => a -> a -> a
(<>) (Set VarName -> Set VarName -> Set VarName)
-> (NExpr -> Set VarName) -> NExpr -> NExpr -> Set VarName
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` NExpr -> Set VarName
freeVars) NExpr
assertion NExpr
expr
  (NSynHole     VarName
_               ) -> Set VarName
forall a. Monoid a => a
mempty

 where

  bindDefs :: Foldable t => t (Binding NExpr) -> Set VarName
  bindDefs :: forall (t :: * -> *).
Foldable t =>
t (Binding NExpr) -> Set VarName
bindDefs = (Binding NExpr -> Set VarName) -> t (Binding NExpr) -> Set VarName
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Binding NExpr -> Set VarName
forall r. Binding r -> Set VarName
bind1Def
   where
    bind1Def :: Binding r -> Set VarName
    bind1Def :: forall r. Binding r -> Set VarName
bind1Def (Inherit   Maybe r
Nothing                  [NKeyName r]
_    SourcePos
_) = Set VarName
forall a. Monoid a => a
mempty
    bind1Def (Inherit  (Just r
_                 ) [NKeyName r]
keys SourcePos
_) = [VarName] -> Set VarName
forall a. Ord a => [a] -> Set a
Set.fromList ([VarName] -> Set VarName) -> [VarName] -> Set VarName
forall a b. (a -> b) -> a -> b
$ (NKeyName r -> Maybe VarName) -> [NKeyName r] -> [VarName]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe NKeyName r -> Maybe VarName
forall r. NKeyName r -> Maybe VarName
staticKey [NKeyName r]
keys
    bind1Def (NamedVar (StaticKey  VarName
varname :| [NKeyName r]
_) r
_    SourcePos
_) = OneItem (Set VarName) -> Set VarName
forall x. One x => OneItem x -> x
one VarName
OneItem (Set VarName)
varname
    bind1Def (NamedVar (DynamicKey Antiquoted (NString r) r
_       :| [NKeyName r]
_) r
_    SourcePos
_) = Set VarName
forall a. Monoid a => a
mempty

  bindFreeVars :: Foldable t => t (Binding NExpr) -> Set VarName
  bindFreeVars :: forall (t :: * -> *).
Foldable t =>
t (Binding NExpr) -> Set VarName
bindFreeVars = (Binding NExpr -> Set VarName) -> t (Binding NExpr) -> Set VarName
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Binding NExpr -> Set VarName
bind1Free
   where
    bind1Free :: Binding NExpr -> Set VarName
    bind1Free :: Binding NExpr -> Set VarName
bind1Free (Inherit  Maybe NExpr
Nothing     [NKeyName NExpr]
keys SourcePos
_) = [VarName] -> Set VarName
forall a. Ord a => [a] -> Set a
Set.fromList ([VarName] -> Set VarName) -> [VarName] -> Set VarName
forall a b. (a -> b) -> a -> b
$ (NKeyName NExpr -> Maybe VarName) -> [NKeyName NExpr] -> [VarName]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe NKeyName NExpr -> Maybe VarName
forall r. NKeyName r -> Maybe VarName
staticKey [NKeyName NExpr]
keys
    bind1Free (Inherit (Just NExpr
scope) [NKeyName NExpr]
_    SourcePos
_) = NExpr -> Set VarName
freeVars NExpr
scope
    bind1Free (NamedVar NAttrPath NExpr
path        NExpr
expr SourcePos
_) = NAttrPath NExpr -> Set VarName
pathFree NAttrPath NExpr
path Set VarName -> Set VarName -> Set VarName
forall a. Semigroup a => a -> a -> a
<> NExpr -> Set VarName
freeVars NExpr
expr

  staticKey :: NKeyName r -> Maybe VarName
  staticKey :: forall r. NKeyName r -> Maybe VarName
staticKey (StaticKey  VarName
varname) = VarName -> Maybe VarName
forall (f :: * -> *) a. Applicative f => a -> f a
pure VarName
varname
  staticKey (DynamicKey Antiquoted (NString r) r
_      ) = Maybe VarName
forall a. Monoid a => a
mempty

  pathFree :: NAttrPath NExpr -> Set VarName
  pathFree :: NAttrPath NExpr -> Set VarName
pathFree = (NKeyName NExpr -> Set VarName) -> NAttrPath NExpr -> Set VarName
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap NKeyName NExpr -> Set VarName
forall (t :: * -> *). Foldable t => t NExpr -> Set VarName
mapFreeVars

  mapFreeVars :: Foldable t => t NExpr -> Set VarName
  mapFreeVars :: forall (t :: * -> *). Foldable t => t NExpr -> Set VarName
mapFreeVars = (NExpr -> Set VarName) -> t NExpr -> Set VarName
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap NExpr -> Set VarName
freeVars


class ToExpr a where
  toExpr :: a -> NExprLoc

instance ToExpr NExprLoc where
  toExpr :: NExprLoc -> NExprLoc
toExpr = NExprLoc -> NExprLoc
forall a. a -> a
id

instance ToExpr VarName where
  toExpr :: VarName -> NExprLoc
toExpr = Compose (Ann SrcSpan) NExprF NExprLoc -> NExprLoc
forall (f :: * -> *). f (Fix f) -> Fix f
Fix (Compose (Ann SrcSpan) NExprF NExprLoc -> NExprLoc)
-> (VarName -> Compose (Ann SrcSpan) NExprF NExprLoc)
-> VarName
-> NExprLoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcSpan -> VarName -> Compose (Ann SrcSpan) NExprF NExprLoc
forall r. SrcSpan -> VarName -> NExprLocF r
NSym_ SrcSpan
nullSpan

instance ToExpr Int where
  toExpr :: Int -> NExprLoc
toExpr = Compose (Ann SrcSpan) NExprF NExprLoc -> NExprLoc
forall (f :: * -> *). f (Fix f) -> Fix f
Fix (Compose (Ann SrcSpan) NExprF NExprLoc -> NExprLoc)
-> (Int -> Compose (Ann SrcSpan) NExprF NExprLoc)
-> Int
-> NExprLoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcSpan -> NAtom -> Compose (Ann SrcSpan) NExprF NExprLoc
forall r. SrcSpan -> NAtom -> NExprLocF r
NConstant_ SrcSpan
nullSpan (NAtom -> Compose (Ann SrcSpan) NExprF NExprLoc)
-> (Int -> NAtom) -> Int -> Compose (Ann SrcSpan) NExprF NExprLoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> NAtom
NInt (Integer -> NAtom) -> (Int -> Integer) -> Int -> NAtom
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral

instance ToExpr Integer where
  toExpr :: Integer -> NExprLoc
toExpr = Compose (Ann SrcSpan) NExprF NExprLoc -> NExprLoc
forall (f :: * -> *). f (Fix f) -> Fix f
Fix (Compose (Ann SrcSpan) NExprF NExprLoc -> NExprLoc)
-> (Integer -> Compose (Ann SrcSpan) NExprF NExprLoc)
-> Integer
-> NExprLoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcSpan -> NAtom -> Compose (Ann SrcSpan) NExprF NExprLoc
forall r. SrcSpan -> NAtom -> NExprLocF r
NConstant_ SrcSpan
nullSpan (NAtom -> Compose (Ann SrcSpan) NExprF NExprLoc)
-> (Integer -> NAtom)
-> Integer
-> Compose (Ann SrcSpan) NExprF NExprLoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> NAtom
NInt

instance ToExpr Float where
  toExpr :: Float -> NExprLoc
toExpr = Compose (Ann SrcSpan) NExprF NExprLoc -> NExprLoc
forall (f :: * -> *). f (Fix f) -> Fix f
Fix (Compose (Ann SrcSpan) NExprF NExprLoc -> NExprLoc)
-> (Float -> Compose (Ann SrcSpan) NExprF NExprLoc)
-> Float
-> NExprLoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcSpan -> NAtom -> Compose (Ann SrcSpan) NExprF NExprLoc
forall r. SrcSpan -> NAtom -> NExprLocF r
NConstant_ SrcSpan
nullSpan (NAtom -> Compose (Ann SrcSpan) NExprF NExprLoc)
-> (Float -> NAtom)
-> Float
-> Compose (Ann SrcSpan) NExprF NExprLoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> NAtom
NFloat

metaExp :: Set VarName -> NExprLoc -> Maybe ExpQ
metaExp :: Set VarName -> NExprLoc -> Maybe ExpQ
metaExp Set VarName
fvs (Fix (NSym_ SrcSpan
_ VarName
x)) | VarName
x VarName -> Set VarName -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set VarName
fvs =
  ExpQ -> Maybe ExpQ
forall (f :: * -> *) a. Applicative f => a -> f a
pure [| toExpr $(varE (mkName $ toString x)) |]
metaExp Set VarName
_ NExprLoc
_ = Maybe ExpQ
forall a. Maybe a
Nothing

metaPat :: Set VarName -> NExprLoc -> Maybe PatQ
metaPat :: Set VarName -> NExprLoc -> Maybe PatQ
metaPat Set VarName
fvs (Fix (NSym_ SrcSpan
_ VarName
x)) | VarName
x VarName -> Set VarName -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set VarName
fvs =
  PatQ -> Maybe PatQ
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PatQ -> Maybe PatQ) -> PatQ -> Maybe PatQ
forall a b. (a -> b) -> a -> b
$ Name -> PatQ
forall (m :: * -> *). Quote m => Name -> m Pat
varP (Name -> PatQ) -> Name -> PatQ
forall a b. (a -> b) -> a -> b
$ String -> Name
mkName (String -> Name) -> String -> Name
forall a b. (a -> b) -> a -> b
$ VarName -> String
forall a. ToString a => a -> String
toString VarName
x
metaPat Set VarName
_ NExprLoc
_ = Maybe PatQ
forall a. Maybe a
Nothing

-- Use of @QuasiQuoter@ requires @String@.
-- After @Text -> String@ migrations done, _maybe_ think to use @QuasiText@.
nix :: QuasiQuoter
nix :: QuasiQuoter
nix = QuasiQuoter :: (String -> ExpQ)
-> (String -> PatQ)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter { quoteExp :: String -> ExpQ
quoteExp = String -> ExpQ
quoteExprExp, quotePat :: String -> PatQ
quotePat = String -> PatQ
quoteExprPat }