{-# OPTIONS -Wall #-} -------------------------------------------------------------------------------- -- | -- Module : Data.ParserCombinators.KangarooRWS -- Copyright : (c) Stephen Tetley 2009-2010 -- License : BSD3 -- -- Maintainer : Stephen Tetley -- Stability : highly unstable -- Portability : to be determined. -- -- Kangaroo parse monad with user env, logging and state. -- -------------------------------------------------------------------------------- module Data.ParserCombinators.KangarooRWS ( Kangaroo , parse , runKangaroo , evalKangaroo , execKangaroo , put , get , modify , gets , tell , ask , asks , local -- Re-exports from ParseMonad -- * Parser types , ParseErr -- * Region types , RegionCoda(..) , RegionName -- * Lift IO actions , liftIOAction -- * Error reporting and exception handling , reportError , substError -- * Primitive parsers , word8 , satisfy , checkWord8 , opt , skip -- * Query the cursor position , position , region , atEnd , lengthRemaining , regionSize -- * Parse within a region , intraparse , advance , advanceRelative , restrict , restrictToPos -- * Debug , printHexAll , printHexRange , printRegionStack , module Data.ParserCombinators.Kangaroo.Combinators , module Data.ParserCombinators.Kangaroo.Prim ) where import Data.ParserCombinators.Kangaroo.Combinators import Data.ParserCombinators.Kangaroo.ParseMonad import Data.ParserCombinators.Kangaroo.Prim import Data.ParserCombinators.Kangaroo.Utils import Control.Monad import Data.Monoid type Kangaroo r w st a = GenKangaroo (r,w,st) a values :: (a,(r,w,st)) -> (a,w,st) values (ans,(_,w,ust)) = (ans,w,ust) state3 :: (r,w,st) -> st state3 (_,_,st) = st env3 :: (r,w,st) -> r env3 (r,_,_) = r parse :: Monoid w => Kangaroo r w st a -> r -> st -> FilePath -> IO (Either ParseErr a) parse = liftM fst `oooo` evalKangaroo runKangaroo :: Monoid w => Kangaroo r w st a -> r -> st -> FilePath -> IO (Either ParseErr a,w,st) runKangaroo p env st filename = liftM values $ runGenKangaroo p (env,mempty,st) filename -- answer, no state evalKangaroo :: Monoid w => Kangaroo r w st a -> r -> st -> FilePath -> IO (Either ParseErr a,w) evalKangaroo = liftM fn `oooo` runKangaroo where fn (a,w,_) = (a,w) -- state, no answer execKangaroo :: Monoid w => Kangaroo r w st a -> r -> st -> FilePath -> IO st execKangaroo = liftM state3 `oooo` runKangaroo put :: st -> Kangaroo r w st () put st = getUserSt >>= \(r,w,_) -> putUserSt (r,w,st) get :: Kangaroo r w st st get = liftM state3 getUserSt modify :: (st -> st) -> Kangaroo r w st () modify f = getUserSt >>= \(r,w,st) -> putUserSt (r,w,f st) gets :: (st -> a) -> Kangaroo r w st a gets f = liftM f get tell :: Monoid w => w -> Kangaroo r w st () tell s = getUserSt >>= \(r,w,st) -> putUserSt (r,w `mappend` s,st) -- | Retrieve the environment. -- ask :: Kangaroo r w st r ask = liftM env3 getUserSt asks :: (r -> a) -> Kangaroo r w st a asks f = liftM (f . env3) getUserSt -- | Execute a computation in a modified environment. -- local :: (r -> r) -> Kangaroo r w st a -> Kangaroo r w st a local upd ma = do st@(e,_,_) <- getUserSt putUserSt $ fmap3a upd st ans <- ma putUserSt $ fmap3a (const e) st return ans where fmap3a f (a,b,c) = (f a,b,c)