module Text.HPaco.Readers.Paco.ParserInternals
( PacoState (..)
, defaultPacoState
, Text.Parsec.Error.ParseError
, Parser
, addDef, resolveDef
, fillExtension
)
where
import Control.Exception (Exception)
import Control.Monad
import Control.Monad.IO.Class
import Data.Typeable
import Text.HPaco.Reader
import Text.HPaco.AST.AST
import Text.HPaco.AST.Expression
import Text.HPaco.AST.Statement
import Text.Parsec.Error (ParseError)
import Text.Parsec.Prim
import Text.Parsec.Char
import Text.Parsec.String hiding (Parser)
import System.FilePath
instance Exception ParseError
deriving instance Typeable ParseError
data PacoState = PacoState
{ psBasePath :: FilePath
, psDefs :: [(String, Statement)]
, psDeps :: [String]
, psIncludeExtension :: Maybe String
, psHandleInclude :: Reader
}
type Parser a = ParsecT String PacoState IO a
defaultPacoState :: PacoState
defaultPacoState = PacoState
{ psBasePath = ""
, psDefs = []
, psDeps = []
, psIncludeExtension = Nothing
, psHandleInclude = (\s t -> return defAST)
}
addDef :: String -> Statement -> Parser ()
addDef name value =
modifyState (\s -> s { psDefs = ((name, value):psDefs s) })
resolveDef :: String -> Parser Statement
resolveDef name = do
defs <- psDefs `liftM` getState
let val = lookup name defs
maybe
(unexpected $ name ++ " is not defined.")
return
val
fillExtension :: FilePath -> String -> FilePath
fillExtension fp ext =
let ext0 = takeExtension fp
in if null ext0
then replaceExtension fp ext
else fp