------------------------------------------------------------------ -- | -- Module : IdlFQMonad -- Copyright : (c) Dmitry Golubovsky, 2009 -- License : BSD-style -- -- Maintainer : golubovsky@gmail.com -- Stability : experimental -- Portability : portable -- -- -- -- A RWS Monad to help convert IDL to intermediate format. ------------------------------------------------------------------ module IdlFQMonad where import Data.List import Data.Maybe import Data.Either import qualified Data.Map as M import Control.Monad.RWS import Text.ParserCombinators.Parsec.Pos import Language.WebIDL import IdlGlobal -- A RWS monad to implement the algorithm. The reader part is program options, -- the writer part is the flat list of IDL modules, and the state part is the current -- stack of enclosing modules. data FQST = FQST { root :: [IDLDef] -- root namespace (stack of definitions: modules [+interface]) ,srcpos :: [SourcePos] -- source position of the current module ,defdecl :: M.Map String IDLDef -- existing definitions } type FQ a = RWS ICGlobal [Either String IDLDefinition] FQST a -- Write an error message in the log. If source position is available, it wil be shown. errMsg :: String -> FQ () errMsg s = do pos <- gets srcpos let sps = if null pos then "" else show (head pos) ++ ": " (tell . return . Left) (sps ++ s) pushdef :: IDLDef -> FQ () pushdef md = do st <- get put st {root = md : root st} popdef :: FQ () popdef = do st <- get put st {root = tail (root st)} pushpos :: SourcePos -> FQ () pushpos sp = do st <- get put st {srcpos = sp : srcpos st} poppos :: FQ () poppos = do st <- get put st {srcpos = tail (srcpos st)}