Allow Nix quasi-patterns

For example:

    foo [nix| 2 + 3 |] = ...

Is equivalent to pattern matching on the constructors that make up the parsed
version of the expression. This can make it much quicker to identify pattern
you're looking for in a parsed body of Nix code.
This commit is contained in:
John Wiegley 2018-05-10 01:18:28 -07:00
parent 13edc1da30
commit 0d6b6e7807
No known key found for this signature in database
GPG key ID: C144D8F4F19FE630

View file

@ -27,35 +27,48 @@ quoteExprExp s = do
Success e -> return e
dataToExpQ (const Nothing `extQ` metaExp (freeVars expr)) expr
quoteExprPat :: String -> PatQ
quoteExprPat s = do
expr <- case parseNixTextLoc (Text.pack s) of
Failure err -> fail $ show err
Success e -> return e
dataToPatQ (const Nothing `extQ` metaPat (freeVars expr)) expr
freeVars :: NExprLoc -> Set VarName
freeVars = cata $ \case
NSym_ _ var -> Set.singleton var
Compose (Ann _ x) -> fold x
class ToExpr a where
toExpr :: a -> NExprLoc
toExpr :: a -> NExprLoc
instance ToExpr NExprLoc where
toExpr = id
toExpr = id
instance ToExpr VarName where
toExpr = Fix . NSym_ nullSpan
toExpr = Fix . NSym_ nullSpan
instance ToExpr Int where
toExpr = Fix . NConstant_ nullSpan . NInt . fromIntegral
toExpr = Fix . NConstant_ nullSpan . NInt . fromIntegral
instance ToExpr Integer where
toExpr = Fix . NConstant_ nullSpan . NInt
toExpr = Fix . NConstant_ nullSpan . NInt
instance ToExpr Float where
toExpr = Fix . NConstant_ nullSpan . NFloat
toExpr = Fix . NConstant_ nullSpan . NFloat
metaExp :: Set VarName -> NExprLoc -> Maybe ExpQ
metaExp fvs (Fix (NSym_ _ x)) | x `Set.member` fvs =
Just [| toExpr $(varE (mkName (Text.unpack x))) |]
Just [| toExpr $(varE (mkName (Text.unpack x))) |]
metaExp _ _ = Nothing
metaPat :: Set VarName -> NExprLoc -> Maybe PatQ
metaPat fvs (Fix (NSym_ _ x)) | x `Set.member` fvs =
Just (varP (mkName (Text.unpack x)))
metaPat _ _ = Nothing
nix :: QuasiQuoter
nix = QuasiQuoter
{ quoteExp = quoteExprExp
, quotePat = quoteExprPat
}