lentil-0.1.2.3: src/Lentil/Parse/Run.hs
-----------------------------------------------------------------------------
-- |
-- Module : Lentil.Parse.Run
-- Copyright : © 2015 Francesco Ariis
-- License : GPLv3 (see the LICENSE file)
--
-- Parsing functions interface
-----------------------------------------------------------------------------
module Lentil.Parse.Run where
import Lentil.Types
import Lentil.Parse.Issue
import Lentil.Parse.Source
import Lentil.Parse.Syntaxes
import Text.Parsec
import Control.Applicative hiding (many, (<|>))
import qualified System.IO as I
import qualified System.Directory as D
import Prelude -- 7.8 hack
-- main function with wich to parse issues; errors on stderr
issueFinder :: [FilePath] -> IO [Issue]
issueFinder fps = fmap concat (mapM fileParser fps)
-- todo a function String -> [Issue] (w/o IO) [debug] [refactor]
-----------------
-- ANCILLARIES --
-----------------
-- errors to stderr
fileParser :: FilePath -> IO [Issue]
fileParser fp = D.doesFileExist fp >>= \fb ->
-- file exists
if fb == False
then perr (fp ++ " : no such file") >> return []
else
-- parser exists
case langParser fp of
Nothing -> return [] -- no error just empy list
Just p -> readFile fp >>=
runParIO p fp >>=
parIssues fp . comms2Tuple
-- generic parsing --
runParIO :: Parsec String () [a] -> FilePath -> String -> IO [a]
runParIO p fp t = case runParser p () fp t of
Left l -> perr (fp ++ " : parse error " ++
show l) >> return []
Right r -> return r
-- output errors
perr :: String -> IO ()
perr cs = I.hPutStrLn I.stderr cs
-- issue parsing --
parIssues :: FilePath -> [Comment] -> IO [Issue]
parIssues fp cs = concat <$> mapM (parIssue fp) cs
-- todo change '\n' trick [refactor] [duct]
-- why '\n'? see setRow comment
parIssue :: FilePath -> Comment -> IO [Issue]
parIssue fp (r, t) = runParIO (setRow r >> issues) fp ('\n':t)
-- why (r-1)? Every TODO must start on a newline, so we have to add a top
-- '\n' in case there immediately is one
setRow :: Row -> ParIssue ()
setRow r = getPosition >>= setPosition . flip setSourceLine (r-1)