Merge pull request #35 from expipiplus1/annotate

WIP: Annotate expressions with their location
This commit is contained in:
John Wiegley 2016-06-28 12:06:54 -07:00 committed by GitHub
commit e5f64d5387
8 changed files with 261 additions and 90 deletions

View file

@ -1,8 +1,10 @@
-- | Wraps the expression submodules.
module Nix.Expr (
module Nix.Expr.Types,
module Nix.Expr.Types.Annotated,
module Nix.Expr.Shorthands
) where
import Nix.Expr.Types
import Nix.Expr.Shorthands
import Nix.Expr.Types.Annotated

View file

@ -1,4 +1,7 @@
-- | A bunch of shorthands for making nix expressions.
--
-- Functions with an @F@ suffix return a more general type without the outer
-- 'Fix' wrapper.
module Nix.Expr.Shorthands where
import Prelude
@ -11,7 +14,10 @@ import Nix.Expr.Types
-- | Make an integer literal expression.
mkInt :: Integer -> NExpr
mkInt = Fix . NConstant . NInt
mkInt = Fix . mkIntF
mkIntF :: Integer -> NExprF a
mkIntF = NConstant . NInt
-- | Make a regular (double-quoted) string.
mkStr :: Text -> NExpr
@ -27,34 +33,55 @@ mkIndentedStr = Fix . NStr . Indented . \case
-- | Make a literal URI expression.
mkUri :: Text -> NExpr
mkUri = Fix . NConstant . NUri
mkUri = Fix . mkUriF
mkUriF :: Text -> NExprF a
mkUriF = NConstant . NUri
-- | Make a path. Use 'True' if the path should be read from the
-- environment, else 'False'.
mkPath :: Bool -> FilePath -> NExpr
mkPath False = Fix . NLiteralPath
mkPath True = Fix . NEnvPath
mkPath b = Fix . mkPathF b
mkPathF :: Bool -> FilePath -> NExprF a
mkPathF False = NLiteralPath
mkPathF True = NEnvPath
-- | Make a path expression which pulls from the NIX_PATH env variable.
mkEnvPath :: FilePath -> NExpr
mkEnvPath = mkPath True
mkEnvPath = Fix . mkEnvPathF
mkEnvPathF :: FilePath -> NExprF a
mkEnvPathF = mkPathF True
-- | Make a path expression which references a relative path.
mkRelPath :: FilePath -> NExpr
mkRelPath = mkPath False
mkRelPath = Fix . mkRelPathF
mkRelPathF :: FilePath -> NExprF a
mkRelPathF = mkPathF False
-- | Make a variable (symbol)
mkSym :: Text -> NExpr
mkSym = Fix . NSym
mkSym = Fix . mkSymF
mkSymF :: Text -> NExprF a
mkSymF = NSym
mkSelector :: Text -> NAttrPath NExpr
mkSelector = (:[]) . StaticKey
mkBool :: Bool -> NExpr
mkBool = Fix . NConstant . NBool
mkBool = Fix . mkBoolF
mkBoolF :: Bool -> NExprF a
mkBoolF = NConstant . NBool
mkNull :: NExpr
mkNull = Fix (NConstant NNull)
mkNull = Fix mkNullF
mkNullF :: NExprF a
mkNullF = NConstant NNull
mkOper :: NUnaryOp -> NExpr -> NExpr
mkOper op = Fix . NUnary op

View file

@ -13,6 +13,7 @@ import Control.Monad hiding (forM_, mapM, sequence)
import Data.Data
import Data.Fix
import Data.Foldable
import Data.Functor.Classes (Show1(..))
import Data.Map (Map)
import Data.Text (Text, pack)
import Data.Traversable
@ -71,6 +72,9 @@ data NExprF r
-- ^ Assert that the first returns true before evaluating the second.
deriving (Ord, Eq, Generic, Typeable, Data, Functor, Show)
instance Show1 NExprF where
showsPrec1 = showsPrec
-- | We make an `IsString` for expressions, where the string is interpreted
-- as an identifier. This is the most common use-case...
instance IsString NExpr where

View file

@ -0,0 +1,87 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
-- | The source location annotated nix expression type and supporting types.
--
module Nix.Expr.Types.Annotated
( module Nix.Expr.Types.Annotated
, Delta(..)
)where
import Control.Monad hiding (forM_, mapM, sequence)
import Data.Data
import Data.Fix
import Data.Function (on)
import Data.Functor.Classes (Show1(..))
import Data.Functor.Compose
import Data.Semigroup
import GHC.Generics
import Nix.Expr.Types
import Nix.Parser.Library (Delta(..))
import Prelude hiding (concat, concatMap, elem, foldr,
mapM, minimum, readFile, sequence)
-- | A location in a source file
data SrcSpan = SrcSpan{ spanBegin :: Delta
, spanEnd :: Delta
}
deriving (Ord, Eq, Generic, Typeable, Data, Show)
-- | A type constructor applied to a type along with an annotation
--
-- Intended to be used with 'Fix':
-- @type MyType = Fix (Compose (Ann Annotation) F)@
data Ann ann a = Ann{ annotation :: ann
, annotated :: a
}
deriving (Ord, Eq, Data, Generic, Typeable, Functor, Read, Show)
instance Show ann => Show1 (Ann ann) where
showsPrec1 = showsPrec
instance Semigroup SrcSpan where
s1 <> s2 = SrcSpan ((min `on` spanBegin) s1 s2)
((max `on` spanEnd) s1 s2)
type AnnF ann f = Compose (Ann ann) f
annToAnnF :: Ann ann (f (Fix (AnnF ann f))) -> Fix (AnnF ann f)
annToAnnF (Ann ann a) = AnnE ann a
type NExprLocF = AnnF SrcSpan NExprF
-- | A nix expression with source location at each subexpression.
type NExprLoc = Fix NExprLocF
pattern AnnE ann a = Fix (Compose (Ann ann a))
stripAnnotation :: Functor f => Fix (AnnF ann f) -> Fix f
stripAnnotation = ana (annotated . getCompose . unFix)
nApp :: NExprLoc -> NExprLoc -> NExprLoc
nApp e1@(AnnE s1 _) e2@(AnnE s2 _) = AnnE (s1 <> s2) (NApp e1 e2)
nUnary :: Ann SrcSpan NUnaryOp -> NExprLoc -> NExprLoc
nUnary (Ann s1 u) e1@(AnnE s2 _) = AnnE (s1 <> s2) (NUnary u e1)
nBinary :: Ann SrcSpan NBinaryOp -> NExprLoc -> NExprLoc -> NExprLoc
nBinary (Ann s1 b) e1@(AnnE s2 _) e2@(AnnE s3 _) =
AnnE (s1 <> s2 <> s3) (NBinary b e1 e2)
nSelectLoc :: NExprLoc -> Ann SrcSpan (NAttrPath NExprLoc) -> Maybe NExprLoc -> NExprLoc
nSelectLoc e1@(AnnE s1 _) (Ann s2 ats) d = case d of
Nothing -> AnnE (s1 <> s2) (NSelect e1 ats Nothing)
Just (e2@(AnnE s3 _)) -> AnnE (s1 <> s2 <> s3) (NSelect e1 ats (Just e2))
nHasAttr :: NExprLoc -> Ann SrcSpan (NAttrPath NExprLoc) -> NExprLoc
nHasAttr e1@(AnnE s1 _) (Ann s2 ats) = AnnE (s1 <> s2) (NHasAttr e1 ats)
nAbs :: Ann SrcSpan (Params NExprLoc) -> NExprLoc -> NExprLoc
nAbs (Ann s1 ps) e1@(AnnE s2 _) = AnnE (s1 <> s2) (NAbs ps e1)
nStr :: Ann SrcSpan (NString NExprLoc) -> NExprLoc
nStr (Ann s1 s) = AnnE s1 (NStr s)

View file

@ -3,15 +3,17 @@
module Nix.Parser (
parseNixFile,
parseNixFileLoc,
parseNixString,
parseNixStringLoc,
parseNixText,
parseNixTextLoc,
Result(..)
) where
import Control.Applicative
import Control.Monad
import Control.Monad.IO.Class
import Data.Fix
import Data.Foldable hiding (concat)
import qualified Data.Map as Map
import Data.Text hiding (head, map, foldl1', foldl', concat)
@ -21,76 +23,99 @@ import Nix.Expr
import Nix.StringOperations
import Prelude hiding (elem)
-- | The lexer for this parser is defined in 'Nix.Parser.Library'.
--------------------------------------------------------------------------------
annotateLocation :: Parser a -> Parser (Ann SrcSpan a)
annotateLocation p = do
begin <- position
res <- p
end <- position
let span = SrcSpan begin end
pure $ Ann span res
annotateLocation1 :: Parser (NExprF NExprLoc) -> Parser NExprLoc
annotateLocation1 = fmap annToAnnF . annotateLocation
--------------------------------------------------------------------------------
nixExpr :: Parser NExpr
nixExpr = whiteSpace *> (nixToplevelForm <|> foldl' makeParser nixTerm nixOperators)
nixExpr = stripAnnotation <$> nixExprLoc
-- | The lexer for this parser is defined in 'Nix.Parser.Library'.
nixExprLoc :: Parser NExprLoc
nixExprLoc = whiteSpace *> (nixToplevelForm <|> foldl' makeParser nixTerm nixOperators)
where
makeParser :: Parser NExprLoc -> Either NSpecialOp NOperatorDef -> Parser NExprLoc
makeParser term (Left NSelectOp) = nixSelect term
makeParser term (Left NAppOp) = chainl1 term $ pure $ \a b -> Fix (NApp a b)
makeParser term (Left NAppOp) = chainl1 term $ pure $ \a b -> (nApp a b)
makeParser term (Left NHasAttrOp) = nixHasAttr term
makeParser term (Right (NUnaryDef name op))
= build <$> many (void $ symbol name) <*> term
where build = flip $ foldl' (\t' () -> mkOper op t')
= build <$> many (annotateLocation (void $ symbol name)) <*> term
where build :: [Ann SrcSpan ()] -> NExprLoc -> NExprLoc
build = flip $ foldl' (\t' (Ann s ()) -> nUnary (Ann s op) t')
makeParser term (Right (NBinaryDef assoc ops)) = case assoc of
NAssocLeft -> chainl1 term op
NAssocRight -> chainr1 term op
NAssocNone -> term <**> (flip <$> op <*> term <|> pure id)
where op = choice . map (\(n,o) -> mkOper2 o <$ reservedOp n) $ ops
where op :: Parser (NExprLoc -> NExprLoc -> NExprLoc)
op = choice . map (\(n,o) -> (\(Ann a ()) -> nBinary (Ann a o)) <$> annotateLocation (reservedOp n)) $ ops
antiStart :: Parser String
antiStart = try (string "${") <?> show ("${" :: String)
nixAntiquoted :: Parser a -> Parser (Antiquoted a NExpr)
nixAntiquoted p = Antiquoted <$> (antiStart *> nixExpr <* symbolic '}') <|> Plain <$> p
nixAntiquoted :: Parser a -> Parser (Antiquoted a NExprLoc)
nixAntiquoted p = Antiquoted <$> (antiStart *> nixExprLoc <* symbolic '}') <|> Plain <$> p
selDot :: Parser ()
selDot = try (char '.' *> notFollowedBy (("path" :: String) <$ nixPath)) *> whiteSpace
<?> "."
nixSelector :: Parser (NAttrPath NExpr)
nixSelector = keyName `sepBy1` selDot where
nixSelector :: Parser (Ann SrcSpan (NAttrPath NExprLoc))
nixSelector = annotateLocation $ keyName `sepBy1` selDot
nixSelect :: Parser NExpr -> Parser NExpr
nixSelect :: Parser NExprLoc -> Parser NExprLoc
nixSelect term = build
<$> term
<*> optional ((,) <$> (selDot *> nixSelector) <*> optional (reserved "or" *> nixExpr))
<*> optional ((,) <$> (selDot *> nixSelector) <*> optional (reserved "or" *> nixExprLoc))
where
build :: NExprLoc -> Maybe (Ann SrcSpan (NAttrPath NExprLoc), Maybe NExprLoc) -> NExprLoc
build t Nothing = t
build t (Just (s,o)) = Fix $ NSelect t s o
build t (Just (s,o)) = nSelectLoc t s o
nixHasAttr :: Parser NExpr -> Parser NExpr
nixHasAttr :: Parser NExprLoc -> Parser NExprLoc
nixHasAttr term = build <$> term <*> optional (reservedOp "?" *> nixSelector) where
build :: NExprLoc -> Maybe (Ann SrcSpan (NAttrPath NExprLoc)) -> NExprLoc
build t Nothing = t
build t (Just s) = Fix $ NHasAttr t s
build t (Just s) = nHasAttr t s
-- | A self-contained unit.
nixTerm :: Parser NExpr
nixTerm :: Parser NExprLoc
nixTerm = nixSelect $ choice
[ nixInt, nixBool, nixNull, nixParens, nixList, nixPath, nixSPath, nixUri
, nixStringExpr, nixSet, nixSym ]
nixToplevelForm :: Parser NExpr
nixToplevelForm :: Parser NExprLoc
nixToplevelForm = choice [nixLambda, nixLet, nixIf, nixAssert, nixWith]
nixSym :: Parser NExpr
nixSym = mkSym <$> identifier
nixSym :: Parser NExprLoc
nixSym = annotateLocation1 $ mkSymF <$> identifier
nixInt :: Parser NExpr
nixInt = mkInt <$> token decimal <?> "integer"
nixInt :: Parser NExprLoc
nixInt = annotateLocation1 $ mkIntF <$> token decimal <?> "integer"
nixBool :: Parser NExpr
nixBool = try (true <|> false) <?> "bool" where
true = mkBool True <$ symbol "true"
false = mkBool False <$ symbol "false"
nixBool :: Parser NExprLoc
nixBool = annotateLocation1 $ try (true <|> false) <?> "bool" where
true = mkBoolF True <$ symbol "true"
false = mkBoolF False <$ symbol "false"
nixNull :: Parser NExpr
nixNull = mkNull <$ try (symbol "null") <?> "null"
nixNull :: Parser NExprLoc
nixNull = annotateLocation1 $ mkNullF <$ try (symbol "null") <?> "null"
nixParens :: Parser NExpr
nixParens = parens nixExpr <?> "parens"
nixParens :: Parser NExprLoc
nixParens = parens nixExprLoc <?> "parens"
nixList :: Parser NExpr
nixList = brackets (Fix . NList <$> many nixTerm) <?> "list"
nixList :: Parser NExprLoc
nixList = annotateLocation1 $ brackets (NList <$> many nixTerm) <?> "list"
pathChars :: String
pathChars = ['A'..'Z'] ++ ['a'..'z'] ++ "._-+" ++ ['0'..'9']
@ -100,12 +125,12 @@ slash = try (char '/' <* notFollowedBy (char '/')) <?> "slash"
-- | A path surrounded by angle brackets, indicating that it should be
-- looked up in the NIX_PATH environment variable at evaluation.
nixSPath :: Parser NExpr
nixSPath = mkPath True <$> try (char '<' *> some (oneOf pathChars <|> slash) <* symbolic '>')
nixSPath :: Parser NExprLoc
nixSPath = annotateLocation1 $ mkPathF True <$> try (char '<' *> some (oneOf pathChars <|> slash) <* symbolic '>')
<?> "spath"
nixPath :: Parser NExpr
nixPath = token $ fmap (mkPath False) $ ((++)
nixPath :: Parser NExprLoc
nixPath = annotateLocation1 $ token $ fmap (mkPathF False) $ ((++)
<$> (try ((++) <$> many (oneOf pathChars) <*> fmap (:[]) slash) <?> "path")
<*> fmap concat
( some (some (oneOf pathChars)
@ -114,48 +139,49 @@ nixPath = token $ fmap (mkPath False) $ ((++)
)
<?> "path"
nixLet :: Parser NExpr
nixLet = fmap Fix $ NLet
nixLet :: Parser NExprLoc
nixLet = annotateLocation1 $ NLet
<$> (reserved "let" *> nixBinders)
<*> (whiteSpace *> reserved "in" *> nixExpr)
<*> (whiteSpace *> reserved "in" *> nixExprLoc)
<?> "let"
nixIf :: Parser NExpr
nixIf = fmap Fix $ NIf
<$> (reserved "if" *> nixExpr)
<*> (whiteSpace *> reserved "then" *> nixExpr)
<*> (whiteSpace *> reserved "else" *> nixExpr)
nixIf :: Parser NExprLoc
nixIf = annotateLocation1 $ NIf
<$> (reserved "if" *> nixExprLoc)
<*> (whiteSpace *> reserved "then" *> nixExprLoc)
<*> (whiteSpace *> reserved "else" *> nixExprLoc)
<?> "if"
nixAssert :: Parser NExpr
nixAssert = fmap Fix $ NAssert
<$> (reserved "assert" *> nixExpr)
<*> (semi *> nixExpr)
nixAssert :: Parser NExprLoc
nixAssert = annotateLocation1 $ NAssert
<$> (reserved "assert" *> nixExprLoc)
<*> (semi *> nixExprLoc)
nixWith :: Parser NExpr
nixWith = fmap Fix $ NWith
<$> (reserved "with" *> nixExpr)
<*> (semi *> nixExpr)
nixWith :: Parser NExprLoc
nixWith = annotateLocation1 $ NWith
<$> (reserved "with" *> nixExprLoc)
<*> (semi *> nixExprLoc)
nixLambda :: Parser NExpr
nixLambda = Fix <$> (NAbs <$> (try argExpr <?> "lambda arguments") <*> nixExpr) <?> "lambda"
nixLambda :: Parser NExprLoc
nixLambda = (nAbs <$> annotateLocation (try argExpr <?> "lambda arguments") <*> nixExprLoc) <?> "lambda"
nixStringExpr :: Parser NExpr
nixStringExpr = Fix . NStr <$> nixString
nixStringExpr :: Parser NExprLoc
nixStringExpr = nStr <$> annotateLocation nixString
uriAfterColonC :: Parser Char
uriAfterColonC = alphaNum <|> oneOf "%/?:@&=+$,-_.!~*'"
nixUri :: Parser NExpr
nixUri = token $ fmap (mkUri . pack) $ (++)
nixUri :: Parser NExprLoc
nixUri = annotateLocation1 $ token $ fmap (mkUriF . pack) $ (++)
<$> try ((++) <$> (scheme <* char ':') <*> fmap (\x -> [':',x]) uriAfterColonC)
<*> many uriAfterColonC
where
scheme = (:) <$> letter <*> many (alphaNum <|> oneOf "+-.")
nixString :: Parser (NString NExpr)
nixString :: Parser (NString NExprLoc)
nixString = doubleQuoted <|> indented <?> "string"
where
doubleQuoted :: Parser (NString NExprLoc)
doubleQuoted = DoubleQuoted . removePlainEmpty . mergePlain
<$> (doubleQ *> many (stringChar doubleQ (void $ char '\\') doubleEscape)
<* token doubleQ)
@ -164,6 +190,7 @@ nixString = doubleQuoted <|> indented <?> "string"
doubleQ = void $ char '"'
doubleEscape = Plain . singleton <$> (char '\\' *> escapeCode)
indented :: Parser (NString NExprLoc)
indented = stripIndent
<$> (indentedQ *> many (stringChar indentedQ indentedQ indentedEscape)
<* token indentedQ)
@ -176,7 +203,7 @@ nixString = doubleQuoted <|> indented <?> "string"
stringChar end escStart esc
= esc
<|> Antiquoted <$> (antiStart *> nixExpr <* char '}') -- don't skip trailing space
<|> Antiquoted <$> (antiStart *> nixExprLoc <* char '}') -- don't skip trailing space
<|> Plain . singleton <$> char '$'
<|> Plain . pack <$> some plainChar
where plainChar = notFollowedBy (end <|> void (char '$') <|> escStart) *> anyChar
@ -184,7 +211,7 @@ nixString = doubleQuoted <|> indented <?> "string"
escapeCode = choice [ c <$ char e | (c,e) <- escapeCodes ] <|> anyChar
-- | Gets all of the arguments for a function.
argExpr :: Parser (Params NExpr)
argExpr :: Parser (Params NExprLoc)
argExpr = choice [atLeft, onlyname, atRight] <* symbolic ':' where
-- An argument not in curly braces. There's some potential ambiguity
-- in the case of, for example `x:y`. Is it a lambda function `x: y`, or
@ -213,45 +240,54 @@ argExpr = choice [atLeft, onlyname, atRight] <* symbolic ':' where
-- Collects the parameters within curly braces. Returns the parameters and
-- a boolean indicating if the parameters are variadic.
getParams :: Parser ([(Text, Maybe NExpr)], Bool)
getParams :: Parser ([(Text, Maybe NExprLoc)], Bool)
getParams = go [] where
-- Attempt to parse `...`. If this succeeds, stop and return True.
-- Otherwise, attempt to parse an argument, optionally with a
-- default. If this fails, then return what has been accumulated
-- so far.
go acc = (token (string "...") >> return (acc, True)) <|> getMore acc
getMore acc = do
getMore acc =
-- Could be nothing, in which just return what we have so far.
option (acc, False) $ do
-- Get an argument name and an optional default.
pair <- liftA2 (,) identifier (optional $ symbolic '?' *> nixExpr)
pair <- liftA2 (,) identifier (optional $ symbolic '?' *> nixExprLoc)
-- Either return this, or attempt to get a comma and restart.
option (acc ++ [pair], False) $ symbolic ',' >> go (acc ++ [pair])
nixBinders :: Parser [Binding NExpr]
nixBinders :: Parser [Binding NExprLoc]
nixBinders = (inherit <|> namedVar) `endBy` symbolic ';' where
inherit = Inherit <$> (reserved "inherit" *> optional scope)
<*> many (keyName)
<*> many keyName
<?> "inherited binding"
namedVar = NamedVar <$> nixSelector <*> (symbolic '=' *> nixExpr)
namedVar = NamedVar <$> (annotated <$> nixSelector) <*> (symbolic '=' *> nixExprLoc)
<?> "variable binding"
scope = parens nixExpr <?> "inherit scope"
scope = parens nixExprLoc <?> "inherit scope"
keyName :: Parser (NKeyName NExpr)
keyName :: Parser (NKeyName NExprLoc)
keyName = dynamicKey <|> staticKey where
staticKey = StaticKey <$> identifier
dynamicKey = DynamicKey <$> nixAntiquoted nixString
nixSet :: Parser NExpr
nixSet = Fix <$> (isRec <*> braces nixBinders) <?> "set" where
nixSet :: Parser NExprLoc
nixSet = annotateLocation1 $ (isRec <*> braces nixBinders) <?> "set" where
isRec = (try (reserved "rec" *> pure NRecSet) <?> "recursive set")
<|> pure NSet
parseNixFile :: MonadIO m => FilePath -> m (Result NExpr)
parseNixFile = parseFromFileEx $ nixExpr <* eof
parseNixFileLoc :: MonadIO m => FilePath -> m (Result NExprLoc)
parseNixFileLoc = parseFromFileEx $ nixExprLoc <* eof
parseNixString :: String -> Result NExpr
parseNixString = parseFromString $ nixExpr <* eof
parseNixStringLoc :: String -> Result NExprLoc
parseNixStringLoc = parseFromString $ nixExprLoc <* eof
parseNixText :: Text -> Result NExpr
parseNixText = parseNixString . unpack
parseNixTextLoc :: Text -> Result NExprLoc
parseNixTextLoc = parseNixStringLoc . unpack

View file

@ -1,7 +1,11 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
module Nix.Parser.Library ( module Nix.Parser.Library, module X) where
module Nix.Parser.Library
( module Nix.Parser.Library
, module X
, Trifecta.Delta(..)
) where
import Prelude
import Control.Applicative
@ -31,7 +35,7 @@ import Text.Trifecta as X (Result(..))
#endif
newtype NixParser p a = NixParser { runNixParser :: p a }
deriving (Functor, Applicative, Alternative, Monad, MonadPlus, Parsing, CharParsing, LookAheadParsing)
deriving (Functor, Applicative, Alternative, Monad, MonadPlus, Parsing, CharParsing, LookAheadParsing, Trifecta.DeltaParsing)
instance TokenParsing p => TokenParsing (NixParser p) where
someSpace = NixParser $ buildSomeSpaceParser someSpace commentStyle
@ -104,6 +108,7 @@ someTill p end = go
--------------------------------------------------------------------------------
parseFromFileEx :: MonadIO m => Parser a -> FilePath -> m (Result a)
parseFromString :: Parser a -> String -> Result a
position :: Parser Trifecta.Delta
#if USE_PARSEC
data Result a = Success a
@ -118,6 +123,8 @@ parseFromFileEx p path =
parseFromString p = either (Failure . text . show) Success . Parsec.parse (runNixParser p) "<string>" . pack
position = error "position not implemented for Parsec parser"
#else
type Parser = NixParser Trifecta.Parser
@ -125,4 +132,7 @@ type Parser = NixParser Trifecta.Parser
parseFromFileEx p = Trifecta.parseFromFileEx (runNixParser p)
parseFromString p = Trifecta.parseString (runNixParser p) (Trifecta.Directed "<string>" 0 0 0 0)
position = Trifecta.position
#endif

View file

@ -1,5 +1,5 @@
Name: hnix
Version: 0.3.0
Version: 0.3.1
Synopsis: Haskell implementation of the Nix language
Description:
Haskell implementation of the Nix language.
@ -32,6 +32,7 @@ Library
Other-modules:
Nix.Parser.Library
Nix.Expr.Types
Nix.Expr.Types.Annotated
Nix.Expr.Shorthands
Default-extensions:
DataKinds
@ -59,6 +60,7 @@ Library
, unordered-containers
, data-fix
, deepseq
, semigroups >= 0.18 && < 0.19
if flag(parsec)
Cpp-options: -DUSE_PARSEC
Build-depends: parsec

View file

@ -1,5 +1,5 @@
{ mkDerivation, ansi-wl-pprint, base, containers, data-fix, parsers
, stdenv, tasty, tasty-hunit, tasty-th, text, transformers
{ mkDerivation, ansi-wl-pprint, base, containers, data-fix, deepseq
, parsers, stdenv, tasty, tasty-hunit, tasty-th, text, transformers
, trifecta, unordered-containers, cabal-install, criterion, pkgs
}:
@ -10,17 +10,20 @@ in
mkDerivation {
pname = "hnix";
version = "0.3.0";
version = "0.3.1";
src = let
notNamed = list: name: !(elem (baseNameOf name) list);
in filterSource (n: _: notNamed [".git" "dist" "benchmarks"] n) ./.;
isLibrary = true;
isExecutable = true;
buildDepends = [
ansi-wl-pprint base containers data-fix parsers text transformers
trifecta unordered-containers cabal-install criterion
libraryHaskellDepends = [
ansi-wl-pprint base containers data-fix deepseq parsers text
transformers trifecta unordered-containers cabal-install criterion
];
testDepends = [
executableHaskellDepends = [
ansi-wl-pprint base containers data-fix deepseq
];
testHaskellDepends = [
base containers data-fix tasty tasty-hunit tasty-th text
];
homepage = "http://github.com/jwiegley/hnix";