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:
parent
13edc1da30
commit
0d6b6e7807
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue