@@ -53,13 +53,13 @@ import Control.Applicative hiding ( many
5353import Control.DeepSeq
5454import Control.Monad
5555import Control.Monad.Combinators.Expr
56+ import Control.Monad.State.Strict
5657import Data.Char ( isAlpha
5758 , isDigit
5859 , isSpace
5960 )
6061import Data.Data ( Data (.. ) )
6162import Data.Functor
62- import Data.Functor.Identity
6363import Data.HashSet ( HashSet )
6464import qualified Data.HashSet as HashSet
6565import Data.List.NonEmpty ( NonEmpty (.. ) )
@@ -81,7 +81,7 @@ import Nix.Render
8181import Prettyprinter ( Doc
8282 , pretty
8383 )
84- import Text.Megaparsec
84+ import Text.Megaparsec hiding ( State )
8585import Text.Megaparsec.Char
8686import qualified Text.Megaparsec.Char.Lexer as L
8787
@@ -439,7 +439,9 @@ skipLineComment' prefix = string prefix
439439 *> void (takeWhileP (Just " character" ) (\ x -> x /= ' \n ' && x /= ' \r ' ))
440440
441441whiteSpace :: Parser ()
442- whiteSpace = L. space space1 lineCmnt blockCmnt
442+ whiteSpace = do
443+ put =<< getSourcePos
444+ L. space space1 lineCmnt blockCmnt
443445 where
444446 lineCmnt = skipLineComment' " #"
445447 blockCmnt = L. skipBlockComment " /*" " */"
@@ -513,20 +515,24 @@ reservedNames :: HashSet Text
513515reservedNames = HashSet. fromList
514516 [" let" , " in" , " if" , " then" , " else" , " assert" , " with" , " rec" , " inherit" ]
515517
516- type Parser = ParsecT Void Text Identity
518+ type Parser = ParsecT Void Text ( State SourcePos )
517519
518520data Result a = Success a | Failure (Doc Void ) deriving (Show , Functor )
519521
520522parseFromFileEx :: MonadFile m => Parser a -> FilePath -> m (Result a )
521523parseFromFileEx p path = do
522524 txt <- decodeUtf8 <$> readFile path
523- pure $ either (Failure . pretty . errorBundlePretty) Success $ parse p
524- path
525- txt
525+ pure
526+ $ either (Failure . pretty . errorBundlePretty) Success
527+ . flip evalState (initialPos path)
528+ $ runParserT p path txt
526529
527530parseFromText :: Parser a -> Text -> Result a
528531parseFromText p txt =
529- either (Failure . pretty . errorBundlePretty) Success $ parse p " <string>" txt
532+ let file = " <string>"
533+ in either (Failure . pretty . errorBundlePretty) Success
534+ . flip evalState (initialPos file)
535+ $ runParserT p file txt
530536
531537{- Parser.Operators -}
532538
@@ -546,7 +552,7 @@ annotateLocation :: Parser a -> Parser (Ann SrcSpan a)
546552annotateLocation p = do
547553 begin <- getSourcePos
548554 res <- p
549- end <- getSourcePos
555+ end <- get -- The state set before the last whitespace
550556 pure $ Ann (SrcSpan begin end) res
551557
552558annotateLocation1 :: Parser (NExprF NExprLoc ) -> Parser NExprLoc
0 commit comments