module Language.Haskell.Liquid.Bare.Env (
BareM
, Warn
, TCEnv
, BareEnv(..)
, TInline(..), InlnEnv
, inModule
, withVArgs
, setRTAlias
, setREAlias
, execBare
, insertLogicEnv
, insertAxiom
) where
import Prelude hiding (error)
import HscTypes
import TyCon
import Var
import Control.Monad.Except
import Control.Monad.State
import Control.Monad.Writer
import qualified Control.Exception as Ex
import qualified Data.HashMap.Strict as M
import Language.Fixpoint.Types (Expr(..), Symbol, symbol)
import Language.Haskell.Liquid.UX.Errors ()
import Language.Haskell.Liquid.Types
import Language.Haskell.Liquid.Types.Bounds
type BareM = WriterT [Warn] (ExceptT Error (StateT BareEnv IO))
type Warn = String
type TCEnv = M.HashMap TyCon RTyCon
type InlnEnv = M.HashMap Symbol TInline
data TInline = TI { tiargs :: [Symbol]
, tibody :: Expr
} deriving (Show)
data BareEnv = BE { modName :: !ModName
, tcEnv :: !TCEnv
, rtEnv :: !RTEnv
, varEnv :: ![(Symbol,Var)]
, hscEnv :: HscEnv
, logicEnv :: LogicMap
, inlines :: InlnEnv
, bounds :: RBEnv
}
insertLogicEnv x ys e
= modify $ \be -> be {logicEnv = (logicEnv be) {logic_map = M.insert x (LMap x ys e) $ logic_map $ logicEnv be}}
insertAxiom x s
= modify $ \be -> be {logicEnv = (logicEnv be){axiom_map = M.insert x s $ axiom_map $ logicEnv be}}
setModule m b = b { modName = m }
inModule m act = do
old <- gets modName
modify $ setModule m
res <- act
modify $ setModule old
return res
withVArgs l l' vs act = do
old <- gets rtEnv
mapM_ (mkExprAlias l l' . symbol . showpp) vs
res <- act
modify $ \be -> be { rtEnv = old }
return res
mkExprAlias l l' v
= setRTAlias v (RTA v [] [] (RExprArg (Loc l l' $ EVar $ symbol v)) l l')
setRTAlias s a =
modify $ \b -> b { rtEnv = mapRT (M.insert s a) $ rtEnv b }
setREAlias s a =
modify $ \b -> b { rtEnv = mapRE (M.insert s a) $ rtEnv b }
execBare :: BareM a -> BareEnv -> IO (Either Error a)
execBare act benv =
do z <- evalStateT (runExceptT (runWriterT act)) benv `Ex.catch` (return . Left)
case z of
Left s -> return $ Left s
Right (x, ws) -> do forM_ ws $ putStrLn . ("WARNING: " ++)
return $ Right x