on master help sign in
Change the representation of SolverState to have a "saved environment", recognize the "Save the Environment" variable
commit4c0f716aef4006f285c97e460fca4817fbb277af authorEvan Czaplicki <info@elm-lang.org> dateFri 19 Jul 2013, 17:50 (13 years ago) parent807076a
2 files changed+36−20
compiler/Type/Constrain/Expression.hs+7−4 compiler/Type/State.hs+29−16
compiler/Type/Constrain/Expression.hs+7−4
@@ -38,8 +38,9 @@ test str =
3838 print (pretty expr)
3939 constraint <- constrain env expr (VarN var)
4040 print =<< extraPretty constraint
41− (env,_,_,errors) <- execStateT (solve constraint) TS.initialState
42− forM (Map.toList env) $ \(n,t) -> do
41+ state <- execStateT (solve constraint) TS.initialState
42+ let errors = TS.sErrors state
43+ forM (Map.toList (TS.sSavedEnv state)) $ \(n,t) -> do
4344 pt <- extraPretty t
4445 print $ P.text n <+> P.text ":" <+> pt
4546 if null errors then return () else do
@@ -53,7 +54,7 @@ constrain env (L _ _ expr) tipe =
5354 case expr of
5455 Literal lit -> return $ Literal.constrain env lit tipe
5556
56− Var name -> return $ name <? tipe
57+ Var name -> return (name <? tipe)
5758
5859 Range lo hi ->
5960 exists $ \x -> do
@@ -167,7 +168,9 @@ constrain env (L _ _ expr) tipe =
167168 return $ tipe === Env.get env Env.types "Element"
168169
169170 Let defs body ->
170− do c <- constrain env body tipe
171+ do c <- case body of
172+ L _ _ (Var name) | name == saveEnvName -> return CSaveEnv
173+ _ -> constrain env body tipe
171174 (schemes, rqs, fqs, header, c2, c1) <-
172175 Monad.foldM (constrainDef env)
173176 ([], [], [], Map.empty, CTrue, CTrue)
compiler/Type/State.hs+29−16
@@ -25,15 +25,26 @@ data Pool = Pool {
2525emptyPool = Pool { maxRank = outermostRank, inhabitants = [] }
2626
2727-- Keeps track of the environment, type variable pool, and a list of errors
28−type SolverState = (Map.Map String Variable, Pool, Int, [IO P.Doc])
29−
30−-- The mark must never be equal to noMark!
31−initialState = (Map.empty, emptyPool, noMark + 1, [])
32−
33−modifyEnv f = modify $ \(env, pool, mark, errors) -> (f env, pool, mark, errors)
34−modifyPool f = modify $ \(env, pool, mark, errors) -> (env, f pool, mark, errors)
28+data SolverState = SS {
29+ sEnv :: Map.Map String Variable,
30+ sSavedEnv :: Map.Map String Variable,
31+ sPool :: Pool,
32+ sMark :: Int,
33+ sErrors :: [IO P.Doc]
34+}
35+
36+initialState = SS {
37+ sEnv = Map.empty,
38+ sSavedEnv = Map.empty,
39+ sPool = emptyPool,
40+ sMark = noMark + 1, -- The mark must never be equal to noMark!
41+ sErrors = []
42+}
43+
44+modifyEnv f = modify $ \state -> state { sEnv = f (sEnv state) }
45+modifyPool f = modify $ \state -> state { sPool = f (sPool state) }
3546addError message t1 t2 =
36− modify $ \(env, pool, mark, errors) -> (env, pool, mark, err : errors)
47+ modify $ \state -> state { sErrors = err : sErrors state }
3748 where
3849 wordify = P.fsep . map P.text . words
3950 msg = wordify message
@@ -53,19 +64,21 @@ addError message t1 t2 =
5364switchToPool pool = modifyPool (\_ -> pool)
5465
5566getPool :: StateT SolverState IO Pool
56−getPool = do
57− (_, pool, _, _) <- get
58− return pool
67+getPool = sPool <$> get
5968
6069getEnv :: StateT SolverState IO (Map.Map String Variable)
61−getEnv = do
62− (env, _, _, _) <- get
63− return env
70+getEnv = sEnv <$> get
71+
72+saveLocalEnv :: StateT SolverState IO ()
73+saveLocalEnv = do
74+ env <- sEnv <$> get
75+ modify $ \state -> state { sSavedEnv = env }
6476
6577uniqueMark :: StateT SolverState IO Int
6678uniqueMark = do
67− (env, pool, mark, errs) <- get
68− put (env, pool, mark+1, errs)
79+ state <- get
80+ let mark = sMark state
81+ put $ state { sMark = mark + 1 }
6982 return mark
7083
7184nextRankPool :: StateT SolverState IO Pool