{-# LANGUAGE CPP, DeriveDataTypeable, PatternGuards, RelaxedPolyRec #-} module Language.Java.Paragon.TypeCheck.Monad.CodeEnv where import Language.Java.Paragon.Syntax --import Language.Java.Paragon.Pretty import Language.Java.Paragon.Interaction --import Language.Java.Paragon.TypeCheck.Actors import Language.Java.Paragon.TypeCheck.Policy import Language.Java.Paragon.TypeCheck.Locks import Language.Java.Paragon.TypeCheck.Types import Language.Java.Paragon.TypeCheck.TypeMap import qualified Data.Map as Map import Data.Data codeEnvModule :: String codeEnvModule = typeCheckerBase ++ ".Monad.CodeEnv" data CodeEnv = CodeEnv { vars :: Map (Ident ()) VarFieldSig, lockstate :: [TcLock], returnI :: Maybe (TcType, (TcPolicy TcActor)), exnsE :: Map TcType ((TcPolicy TcActor), (TcPolicy TcActor)), branchPCE :: (Map Entity [((TcPolicy TcActor), String)], [((TcPolicy TcActor), String)]) } deriving (Show, Data, Typeable) -- Env to use when typechecking expressions not inside method -- bodies, e.g. in field initializers and policy modifiers simpleEnv :: (TcPolicy TcActor) -> String -> CodeEnv simpleEnv brPol str = CodeEnv { vars = Map.empty, lockstate = [], returnI = Nothing, exnsE = Map.empty, branchPCE = (Map.empty, [(brPol,str)]) } data Entity = VarEntity (Name ()) | ThisFieldEntity (Ident ()) | ExnEntity TcType | LockEntity (Name ()) | BreakE | ContinueE | ReturnE deriving (Show, Eq, Ord, Data, Typeable) varE, lockE :: Name () -> Entity varE = VarEntity lockE = LockEntity exnE :: TcType -> Entity exnE = ExnEntity thisFE :: Ident () -> Entity thisFE = ThisFieldEntity breakE, continueE, returnE :: Entity breakE = BreakE continueE = ContinueE returnE = ReturnE -------------------------------------- -- Working with the branchPC -- -------------------------------------- branchPC :: Maybe Entity -> CodeEnv -> [((TcPolicy TcActor), String)] branchPC men (CodeEnv { branchPCE = (bm, def) }) = flip (maybe def) men $ \en -> maybe def id (Map.lookup en bm) joinBranchPC :: (TcPolicy TcActor) -> String -> CodeEnv -> CodeEnv joinBranchPC p str env = let (bm, def) = branchPCE env in env { branchPCE = (Map.map ((p, str):) bm, (p,str):def) }