libcspm-0.1: src/CSPM/TypeChecker.hs
{-# LANGUAGE FlexibleContexts #-}
module CSPM.TypeChecker (
typeCheck, typeCheckExpect,
typeOfExp, dependenciesOfExp,
initTypeChecker,
TypeCheckMonad, TypeInferenceState,
runTypeChecker, runFromStateToState,
) where
import Control.Monad.Trans
import CSPM.DataStructures.Names
import CSPM.DataStructures.Syntax
import CSPM.DataStructures.Types
import CSPM.TypeChecker.BuiltInFunctions
import qualified CSPM.TypeChecker.Common as TC
import CSPM.TypeChecker.Compressor
import CSPM.TypeChecker.Dependencies
import CSPM.TypeChecker.Environment
import CSPM.TypeChecker.Expr
import CSPM.TypeChecker.InteractiveStmt
import CSPM.TypeChecker.Module
import CSPM.TypeChecker.Monad
import CSPM.TypeChecker.Unification
import Util.Annotated
import Util.Exception
runFromStateToState :: TypeInferenceState -> TypeCheckMonad a ->
IO (a, [ErrorMessage], TypeInferenceState)
runFromStateToState st prog = runTypeChecker st $ do
r <- prog
ws <- getWarnings
resetWarnings
s <- getState
return (r, ws, s)
initTypeChecker :: IO TypeInferenceState
initTypeChecker = runTypeChecker newTypeInferenceState $ do
injectBuiltInFunctions
-- Add a blank level in the environment to allow built in functions
-- to be overriden.
local [] getState
typeCheckExpect :: (Compressable a, TC.TypeCheckable a Type) => Type -> a -> TypeCheckMonad a
typeCheckExpect t exp = TC.typeCheckExpect exp t >> mcompress exp
typeCheck :: (Compressable a, TC.TypeCheckable a b) => a -> TypeCheckMonad a
typeCheck exp = TC.typeCheck exp >> mcompress exp
typeOfExp :: PExp -> TypeCheckMonad Type
typeOfExp exp = do
-- See if has been type checked, if so, return type,
-- else type check
mt <- liftIO $ readPType (snd (annotation exp))
case mt of
Just t -> evaluateDots t >>= compress
Nothing -> typeCheck exp >> typeOfExp exp
-- | Returns the list of names that this expression depends on
dependenciesOfExp :: TCExp -> TypeCheckMonad [Name]
dependenciesOfExp exp = dependencies exp