{-# LANGUAGE FlexibleContexts #-} module CSPM.TypeChecker ( typeCheck, typeCheckExpect, typeOfExp, typeOfName, ErrorOptions, modifyErrorOptions, initTypeChecker, TypeCheckMonad, TypeInferenceState, runTypeChecker, runFromStateToState, ) where import Control.Monad.Trans import CSPM.DataStructures.Names import CSPM.DataStructures.Syntax hiding (getType) import CSPM.DataStructures.Types import CSPM.TypeChecker.BuiltInFunctions import qualified CSPM.TypeChecker.Common as TC import CSPM.TypeChecker.Compressor import CSPM.TypeChecker.Exceptions import CSPM.TypeChecker.Expr() import CSPM.TypeChecker.File() import CSPM.TypeChecker.InteractiveStmt() 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 :: TCExp -> 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 typeOfName :: Name -> TypeCheckMonad TypeScheme typeOfName = getType