@@ -1,18 +1,14 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2module Type.State
2module Type.State
3− ( Solver
3+ ( Solver(..)
5 , State(..)
5 , State(..)
8 , modifyEnv
8 , modifyEnv
13 , saveLocalEnv
11 , saveLocalEnv
16 , register
12 , register
17 , introduce
13 , introduce
@@ -21,11 +17,12 @@ module Type.State
24−import Control.Monad (liftM, liftM2)
20+import Control.Monad (forM_, liftM, liftM2)
25import Control.Monad.Trans (MonadIO, liftIO)
21import Control.Monad.Trans (MonadIO, liftIO)
26import qualified Data.Map as Map
22import qualified Data.Map as Map
27import Data.Map ((!))
23import Data.Map ((!))
28import Data.Text (Text)
24import Data.Text (Text)
25+import qualified Data.Vector.Mutable as MVector
30import qualified Reporting.Annotation as A
27import qualified Reporting.Annotation as A
31import qualified Reporting.Error.Type as Error
28import qualified Reporting.Error.Type as Error
@@ -42,53 +39,32 @@ newtype Solver a =
42 Solver { _solve :: State -> IO (a, State) }
39 Solver { _solve :: State -> IO (a, State) }
49−run :: Solver () -> IO State
51− do (_, state) <- solver initialState
58− { sEnv = Map.empty
44+ { _env :: Env
59− , sSavedEnv = Map.empty
45+ , _savedEnv :: Env
60− , sPool = Pool outermostRank []
46+ , _rank :: Int
61− , sMark = Type.nextMark noMark -- The mark must never be equal to noMark!
47+ , _pools :: Pools
62− , sError = []
48+ , _mark :: Mark
49+ , _errors :: [A.Located Error.Error]
53+type Pools = MVector.IOVector [Variable]
56+type Env = Map.Map Text (A.Located Variable)
76− , sError :: [A.Located Error.Error]
80−{-| A pool holds a bunch of variables
60+-- RUN SOLVER
81−The rank of each variable is less than or equal to the pool's "maxRank"
82−The young pool exists to make it possible to identify these vars in constant time.
87− , _inhabitants :: [Variable]
91−type Env = Map.Map Text (A.Located Variable)
63+run :: Solver () -> IO State
65+ do pools <- MVector.replicate 8 []
66+ (_, state) <- solver (SS Map.empty Map.empty outermostRank pools (Type.nextMark noMark) [])
@@ -99,96 +75,54 @@ type Env = Map.Map Text (A.Located Variable)
99modifyEnv :: (Env -> Env) -> Solver ()
75modifyEnv :: (Env -> Env) -> Solver ()
100modifyEnv f =
76modifyEnv f =
101 Solver $ \state ->
77 Solver $ \state ->
102− return ( (), state { sEnv = f (sEnv state) } )
78+ return ( (), state { _env = f (_env state) } )
105−{-# INLINE modifyPool #-}
106−modifyPool :: (Pool -> Pool) -> Solver ()
109− return ( (), state { sPool = f (sPool state) } )
112{-# INLINE addError #-}
81{-# INLINE addError #-}
113addError :: R.Region -> Error.Error -> Solver ()
82addError :: R.Region -> Error.Error -> Solver ()
114addError region err =
83addError region err =
115 Solver $ \state ->
84 Solver $ \state ->
116− return ( (), state { sError = A.A region err : sError state } )
85+ return ( (), state { _errors = A.A region err : _errors state } )
119−{-# INLINE switchToPool #-}
120−switchToPool :: Pool -> Solver ()
122− modifyPool (\_ -> pool)
125−{-# INLINE getPool #-}
126−getPool :: Solver Pool
129− return ( sPool state, state )
132−{-# INLINE getMaxRank #-}
133−getMaxRank :: Solver Int
135− Solver $ \state@(SS _ _ (Pool maxRank _) _ _) ->
136− return ( maxRank, state )
139{-# INLINE getEnv #-}
88{-# INLINE getEnv #-}
140getEnv :: Solver Env
89getEnv :: Solver Env
142 Solver $ \state ->
91 Solver $ \state ->
143− return ( sEnv state, state )
92+ return ( _env state, state )
146{-# INLINE saveLocalEnv #-}
95{-# INLINE saveLocalEnv #-}
147saveLocalEnv :: Solver ()
96saveLocalEnv :: Solver ()
148saveLocalEnv =
97saveLocalEnv =
149 Solver $ \state ->
98 Solver $ \state ->
150− return ( (), state { sSavedEnv = sEnv state } )
99+ return ( (), state { _savedEnv = _env state } )
153−{-# INLINE uniqueMark #-}
154−uniqueMark :: Solver Mark
156− Solver $ \(SS env savedEnv pool mark errors) ->
157− return ( mark, SS env savedEnv pool (Type.nextMark mark) errors )
160−{-# INLINE nextRankPool #-}
161−nextRankPool :: Solver Pool
163− Solver $ \state@(SS _ _ (Pool maxRank _) _ _) ->
164− return ( Pool (maxRank + 1) [], state )
168-- REGISTER VARIABLES
103-- REGISTER VARIABLES
171−{-# INLINE register #-}
172−register :: Variable -> Solver Variable
106+register :: Variable -> Solver ()
173−register variable =
107+register var =
174− {-# SCC elm_compiler_type_register #-}
175− Solver $ \state ->
108+ Solver $ \state@(SS _ _ maxRank pools _ _) ->
176− let
109+ {-# SCC elm_compiler_type_register #-}
177− (Pool maxRank inhabitants) =
110+ do MVector.modify pools (var:) maxRank
178− sPool state
111+ return ( (), state )
180− return ( variable, state { sPool = Pool maxRank (variable : inhabitants) } )
183−{-# INLINE introduce #-}
184introduce :: [Variable] -> Solver ()
114introduce :: [Variable] -> Solver ()
185introduce variables =
115introduce variables =
116+ Solver $ \state@(SS _ _ maxRank pools _ _) ->
186− {-# SCC elm_compiler_type_introduce #-}
117+ {-# SCC elm_compiler_type_introduce #-}
187− Solver $ \(SS env savedEnv (Pool maxRank inhabitants) mark errors) ->
118+ do
188− do let toMaxRank (Descriptor c _ m cp) = Descriptor c maxRank m cp
119+ forM_ variables $ \var ->
189− mapM_ (\var -> UF.modifyDescriptor var toMaxRank) variables
120+ UF.modifyDescriptor var $ \(Descriptor content _ mark cp) ->
190− let newPool = Pool maxRank (variables ++ inhabitants)
121+ Descriptor content maxRank mark cp
191− return ( (), SS env savedEnv newPool mark errors )
122+
123+ MVector.modify pools (variables++) maxRank
125+ return ( (), state )
@@ -196,47 +130,50 @@ introduce variables =
198flatten :: Type -> Solver Variable
132flatten :: Type -> Solver Variable
199−flatten term =
133+flatten tipe =
134+ Solver $ \state@(SS _ _ maxRank pools _ _) ->
200− {-# SCC elm_compiler_type_flatten #-}
135+ {-# SCC elm_compiler_type_flatten #-}
201− do maxRank <- getMaxRank
202− flattenHelp maxRank Map.empty term
136+ do var <- flattenHelp maxRank pools Map.empty tipe
205−flattenHelp :: Int -> Map.Map Text Variable -> Type -> Solver Variable
140+flattenHelp :: Int -> Pools -> Map.Map Text Variable -> Type -> IO Variable
206−flattenHelp maxRank aliasDict termN =
141+flattenHelp maxRank pools aliasDict tipe =
207− case termN of
142+ case tipe of
208 PlaceHolder name ->
143 PlaceHolder name ->
209 return (aliasDict ! name)
144 return (aliasDict ! name)
211 AliasN name args realType ->
146 AliasN name args realType ->
212− do flatArgs <- mapM (traverse (flattenHelp maxRank aliasDict)) args
147+ do flatArgs <- mapM (traverse (flattenHelp maxRank pools aliasDict)) args
213− flatVar <- flattenHelp maxRank (Map.fromList flatArgs) realType
148+ flatVar <- flattenHelp maxRank pools (Map.fromList flatArgs) realType
214− makeFlatType maxRank (Alias name flatArgs flatVar)
149+ registerFlatType maxRank pools (Alias name flatArgs flatVar)
216 VarN v ->
151 VarN v ->
219 AppN name args ->
154 AppN name args ->
220− do flatArgs <- traverse (flattenHelp maxRank aliasDict) args
155+ do flatArgs <- traverse (flattenHelp maxRank pools aliasDict) args
221− makeFlatType maxRank (Structure (App1 name flatArgs))
156+ registerFlatType maxRank pools (Structure (App1 name flatArgs))
223 FunN a b ->
158 FunN a b ->
224− do flatA <- flattenHelp maxRank aliasDict a
159+ do flatA <- flattenHelp maxRank pools aliasDict a
225− flatB <- flattenHelp maxRank aliasDict b
160+ flatB <- flattenHelp maxRank pools aliasDict b
226− makeFlatType maxRank (Structure (Fun1 flatA flatB))
161+ registerFlatType maxRank pools (Structure (Fun1 flatA flatB))
228 EmptyRecordN ->
163 EmptyRecordN ->
229− makeFlatType maxRank (Structure EmptyRecord1)
164+ registerFlatType maxRank pools (Structure EmptyRecord1)
231 RecordN fields ext ->
166 RecordN fields ext ->
232− do flatFields <- traverse (flattenHelp maxRank aliasDict) fields
167+ do flatFields <- traverse (flattenHelp maxRank pools aliasDict) fields
233− flatExt <- flattenHelp maxRank aliasDict ext
168+ flatExt <- flattenHelp maxRank pools aliasDict ext
234− makeFlatType maxRank (Structure (Record1 flatFields flatExt))
169+ registerFlatType maxRank pools (Structure (Record1 flatFields flatExt))
237−makeFlatType :: Int -> Content -> Solver Variable
172+registerFlatType :: Int -> Pools -> Content -> IO Variable
238−makeFlatType maxRank content =
173+registerFlatType maxRank pools content =
239− register =<< liftIO (UF.fresh (Descriptor content maxRank noMark Nothing))
174+ do var <- UF.fresh (Descriptor content maxRank noMark Nothing)
175+ MVector.modify pools (var:) maxRank
@@ -245,16 +182,16 @@ makeFlatType maxRank content =
246copy :: Variable -> Solver Variable
183copy :: Variable -> Solver Variable
247copy var =
184copy var =
185+ Solver $ \state@(SS _ _ maxRank pools _ _) ->
248− {-# SCC elm_compiler_type_copy #-}
186+ {-# SCC elm_compiler_type_copy #-}
249− do maxRank <- getMaxRank
250− copyVar <- copyHelp maxRank var
187+ do copyVar <- copyHelp maxRank pools var
251− _ <- restore var
188+ _ <- restore var
252− return copyVar
189+ return ( copyVar, state )
255−copyHelp :: Int -> Variable -> Solver Variable
192+copyHelp :: Int -> Pools -> Variable -> IO Variable
256−copyHelp maxRank variable =
193+copyHelp maxRank pools variable =
257− do (Descriptor content rank _mark maybeCopy) <- liftIO $ UF.descriptor variable
194+ do (Descriptor content rank _mark maybeCopy) <- UF.descriptor variable
258 case maybeCopy of
195 case maybeCopy of
259 Just copiedVariable ->
196 Just copiedVariable ->
260 return copiedVariable
197 return copiedVariable
@@ -265,15 +202,15 @@ copyHelp maxRank variable =
267 do let mkCopyDesc cont = Descriptor cont maxRank noMark Nothing
204 do let mkCopyDesc cont = Descriptor cont maxRank noMark Nothing
268− newVar <- liftIO $ UF.fresh $ mkCopyDesc content
205+ newVar <- UF.fresh $ mkCopyDesc content
269− _ <- register newVar
206+ MVector.modify pools (newVar:) maxRank
271 -- Link the original variable to the new variable. This lets us
208 -- Link the original variable to the new variable. This lets us
272 -- avoid making multiple copies of the variable we are instantiating.
209 -- avoid making multiple copies of the variable we are instantiating.
274 -- Need to do this before recursively copying the content of
211 -- Need to do this before recursively copying the content of
275 -- the variable to avoid looping on cyclic terms.
212 -- the variable to avoid looping on cyclic terms.
276− liftIO $ UF.setDescriptor variable $
213+ UF.setDescriptor variable $
277 Descriptor content rank noMark (Just newVar)
214 Descriptor content rank noMark (Just newVar)
279 -- Now we recursively copy the content of the variable.
216 -- Now we recursively copy the content of the variable.
@@ -281,19 +218,19 @@ copyHelp maxRank variable =
281 -- will not repeat this work or crawl this variable again.
218 -- will not repeat this work or crawl this variable again.
282 case content of
219 case content of
283 Structure term ->
220 Structure term ->
284− do newTerm <- traverseFlatType (copyHelp maxRank) term
221+ do newTerm <- traverseFlatType (copyHelp maxRank pools) term
285− liftIO $ UF.setDescriptor newVar $ mkCopyDesc (Structure newTerm)
222+ UF.setDescriptor newVar $ mkCopyDesc (Structure newTerm)
287 Var Rigid maybeSuper maybeName ->
224 Var Rigid maybeSuper maybeName ->
288− liftIO $ UF.setDescriptor newVar $ mkCopyDesc $ Var Flex maybeSuper maybeName
225+ UF.setDescriptor newVar $ mkCopyDesc $ Var Flex maybeSuper maybeName
290 Var Flex _ _ ->
227 Var Flex _ _ ->
291 return ()
228 return ()
293 Alias name args realType ->
230 Alias name args realType ->
294− do newArgs <- mapM (traverse (copyHelp maxRank)) args
231+ do newArgs <- mapM (traverse (copyHelp maxRank pools)) args
295− newRealType <- copyHelp maxRank realType
232+ newRealType <- copyHelp maxRank pools realType
296− liftIO $ UF.setDescriptor newVar $ mkCopyDesc (Alias name newArgs newRealType)
233+ UF.setDescriptor newVar $ mkCopyDesc (Alias name newArgs newRealType)
298 Error _ ->
235 Error _ ->
299 return ()
236 return ()
@@ -305,21 +242,21 @@ copyHelp maxRank variable =
305-- RESTORE
242-- RESTORE
308−restore :: Variable -> Solver Variable
245+restore :: Variable -> IO Variable
309restore variable =
246restore variable =
310− do (Descriptor content _rank _mark maybeCopy) <- liftIO $ UF.descriptor variable
247+ do (Descriptor content _rank _mark maybeCopy) <- UF.descriptor variable
311 case maybeCopy of
248 case maybeCopy of
312 Nothing ->
249 Nothing ->
313 return variable
250 return variable
315 Just _ ->
252 Just _ ->
316 do restoredContent <- restoreContent content
253 do restoredContent <- restoreContent content
317− liftIO $ UF.setDescriptor variable $
254+ UF.setDescriptor variable $
318 Descriptor restoredContent noRank noMark Nothing
255 Descriptor restoredContent noRank noMark Nothing
319 return variable
256 return variable
322−restoreContent :: Content -> Solver Content
259+restoreContent :: Content -> IO Content
323restoreContent content =
260restoreContent content =
324 case content of
261 case content of
325 Structure term ->
262 Structure term ->
@@ -341,7 +278,7 @@ restoreContent content =
341-- TRAVERSE FLAT TYPE
278-- TRAVERSE FLAT TYPE
344−traverseFlatType :: (Variable -> Solver Variable) -> FlatType -> Solver FlatType
281+traverseFlatType :: (Variable -> IO Variable) -> FlatType -> IO FlatType
345traverseFlatType f flatType =
282traverseFlatType f flatType =
346 case flatType of
283 case flatType of
347 App1 name args ->
284 App1 name args ->