@@ -8,8 +8,8 @@ import qualified Type.Environment as Env
8import qualified Type.Constrain.Expression as TcExpr
8import qualified Type.Constrain.Expression as TcExpr
9import qualified Type.Solve as Solve
9import qualified Type.Solve as Solve
11+import qualified AST.Annotation as A
11import AST.Module as Module
12import AST.Module as Module
12−import AST.Annotation (noneNoDocs)
13import AST.Type (CanonicalType)
13import AST.Type (CanonicalType)
14import qualified AST.Variable as Var
14import qualified AST.Variable as Var
15import Text.PrettyPrint
15import Text.PrettyPrint
@@ -17,45 +17,50 @@ import qualified Type.State as TS
17import qualified Type.ExtraChecks as Check
17import qualified Type.ExtraChecks as Check
18import Control.Arrow (first, second)
18import Control.Arrow (first, second)
19import Control.Monad.State (execStateT, forM)
19import Control.Monad.State (execStateT, forM)
20−import Control.Monad.Error (ErrorT, runErrorT, liftIO)
20+import Control.Monad.Error (ErrorT, runErrorT, liftIO, throwError)
22import System.IO.Unsafe -- Possible to switch over to the ST monad instead of
22import System.IO.Unsafe -- Possible to switch over to the ST monad instead of
23 -- the IO monad. I don't think that'd be worthwhile.
23 -- the IO monad. I don't think that'd be worthwhile.
26infer :: Interfaces -> CanonicalModule -> Either [Doc] (Map.Map String CanonicalType)
26infer :: Interfaces -> CanonicalModule -> Either [Doc] (Map.Map String CanonicalType)
27−infer interfaces modul = unsafePerformIO $ do
27+infer interfaces modul = unsafePerformIO $ runErrorT $ do
28− let moduleBody = body modul
28+ (header, constraint) <- genConstraints interfaces modul
30+ state <- liftIO $ execStateT (Solve.solve constraint) TS.initialState
32+ () <- case TS.sErrors state of
33+ errors@(_:_) -> throwError errors
36+ () <- Check.portTypes (program (body modul))
38+ let header' = Map.delete "::" header
39+ types = Map.difference (TS.sSavedEnv state) header'
44+genConstraints :: Interfaces -> CanonicalModule
45+ -> ErrorT [Doc] IO (Env.TypeDict, T.TypeConstraint)
46+genConstraints interfaces modul = do
30− env <- Env.initialEnvironment (canonicalizeAdts interfaces modul)
47+ env <- liftIO $ Env.initialEnvironment (canonicalizeAdts interfaces modul)
31− ctors <- forM (Map.keys (Env.constructor env)) $ \name ->
49+ ctors <- forM (Map.keys (Env.constructor env)) $ \name -> do
32− do (_, vars, args, result) <- Env.freshDataScheme env name
50+ (_, vars, args, result) <- liftIO $ Env.freshDataScheme env name
33− return (name, (vars, foldr (T.==>) result args))
51+ return (name, (vars, foldr (T.==>) result args))
35− attemptConstraint <- runErrorT $ do
36− importedVars <- mapM (canonicalizeValues env) (Map.toList interfaces)
53+ importedVars <- mapM (canonicalizeValues env) (Map.toList interfaces)
38− let allTypes = concat (ctors : importedVars)
55+ let allTypes = concat (ctors : importedVars)
39− vars = concatMap (fst . snd) allTypes
56+ vars = concatMap (fst . snd) allTypes
40− header = Map.map snd (Map.fromList allTypes)
57+ header = Map.map snd (Map.fromList allTypes)
41− environ = noneNoDocs . T.CLet [ T.Scheme vars [] (noneNoDocs T.CTrue) header ]
58+ environ = A.noneNoDocs . T.CLet [ T.Scheme vars [] (A.noneNoDocs T.CTrue) header ]
43− fvar <- liftIO $ T.variable T.Flexible
60+ fvar <- liftIO $ T.variable T.Flexible
44− c <- TcExpr.constrain env (program moduleBody) (T.varN fvar)
61+ c <- TcExpr.constrain env (program (body modul)) (T.varN fvar)
45− return (header, environ c)
62+ return (header, environ c)
47− case attemptConstraint of
48− Left err -> return $ Left err
49− Right (header, constraint) -> do
50− state <- execStateT (Solve.solve constraint) TS.initialState
51− case TS.sErrors state of
52− errors@(_:_) -> return (Left errors)
53− [] -> case Check.portTypes (program moduleBody) of
54− Left err -> return (Left err)
55− Right () -> Check.mainType types
57− header' = Map.delete "::" header
58− types = Map.difference (TS.sSavedEnv state) header'
60canonicalizeValues :: Env.Environment -> (String, Interface)
65canonicalizeValues :: Env.Environment -> (String, Interface)
61 -> ErrorT [Doc] IO [(String, ([T.Variable], T.Type))]
66 -> ErrorT [Doc] IO [(String, ([T.Variable], T.Type))]