1module Type.Environment where
3import Control.Monad (forM)
4import qualified Control.Monad.State as State
5import qualified Data.Traversable as Traverse
6import qualified Data.Map as Map
7import qualified Data.Set as Set
8import Data.List (isPrefixOf)
10import qualified AST.Type as T
11import qualified AST.Variable as V
12import qualified AST.Module as Module
16type TypeDict = Map.Map String Type
17type VarDict = Map.Map String Variable
20data Environment = Environment
21 { constructor :: Map.Map String (IO (Int, [Variable], [Type], Type))
27initialEnvironment :: [Module.CanonicalAdt] -> IO Environment
28initialEnvironment datatypes =
29 do types <- makeTypes datatypes
32 { constructor = Map.empty
36 return $ env { constructor = makeConstructors env datatypes }
39makeTypes :: [Module.CanonicalAdt] -> IO TypeDict
41 do adts <- mapM makeImported datatypes
42 bs <- mapM makeBuiltin builtins
43 return (Map.fromList (adts ++ bs))
45 makeImported :: (V.Canonical, Module.AdtInfo V.Canonical) -> IO (String, Type)
46 makeImported (var, _) =
47 do tvar <- namedVar Constant var
48 return (V.toString var, varN tvar)
50 makeBuiltin :: (String, Int) -> IO (String, Type)
51 makeBuiltin (name, _) =
52 do name' <- namedVar Constant (V.builtin name)
53 return (name, varN name')
55 builtins :: [(String, Int)]
60 , kind 0 ["Int","Float","Char","String","Bool"]
63 tuple n = ("_Tuple" ++ show n, n)
64 kind n names = map (\name -> (name, n)) names
69 -> [Module.CanonicalAdt]
70 -> Map.Map String (IO (Int, [Variable], [Type], Type))
71makeConstructors env datatypes =
75 (types env Map.! "List") <| t
77 inst :: Int -> ([Type] -> ([Type], Type)) -> IO (Int, [Variable], [Type], Type)
79 do vars <- forM [1..numTVars] $ \_ -> variable Flexible
80 let (args, result) = tipe (map (varN) vars)
81 return (length args, vars, args, result)
84 let name = "_Tuple" ++ show n
85 in (name, inst n $ \vs -> (vs, foldl (<|) (types env Map.! name) vs))
87 builtins :: [ (String, IO (Int, [Variable], [Type], Type)) ]
89 [ ("[]", inst 1 $ \ [t] -> ([], list t))
90 , ("::", inst 1 $ \ [t] -> ([t, list t], list t))
91 ] ++ map tupleCtor [0..9]
92 ++ concatMap (ctorToType env) datatypes
97 -> (V.Canonical, Module.AdtInfo V.Canonical)
98 -> [(String, IO (Int, [Variable], [Type], Type))]
99ctorToType env (name, (tvars, ctors)) =
100 zip (map (V.toString . fst) ctors) (map inst ctors)
102 inst :: (V.Canonical, [T.Canonical]) -> IO (Int, [Variable], [Type], Type)
104 do ((args, tipe), dict) <- State.runStateT (go ctor) Map.empty
105 return (length args, Map.elems dict, args, tipe)
108 go :: (V.Canonical, [T.Canonical]) -> State.StateT VarDict IO ([Type], Type)
110 do types <- mapM (instantiator env) args
111 returnType <- instantiator env (T.App (T.Type name) (map T.Var tvars))
112 return (types, returnType)
115get :: Environment -> (Environment -> Map.Map String a) -> String -> a
117 Map.findWithDefault (error msg) key (subDict env)
119 msg = "Could not find type constructor `" ++ key ++ "` while checking types."
125 -> IO (Int, [Variable], [Type], Type)
126freshDataScheme env name =
127 get env constructor name
134 -> IO ([Variable], Type)
135instantiateType env sourceType dict =
136 do (tipe, dict') <- State.runStateT (instantiator env sourceType) dict
137 return (Map.elems dict', tipe)
143 -> State.StateT VarDict IO Type
144instantiator env sourceType =
145 instantiatorHelp env Set.empty sourceType
152 -> State.StateT VarDict IO Type
153instantiatorHelp env aliasVars sourceType =
154 let go = instantiatorHelp env aliasVars
158 (==>) <$> go t1 <*> go t2
162 case Set.member x aliasVars of
164 return (PlaceHolder x)
166 case Map.lookup x dict of
171 do v <- State.liftIO $ namedVar flex (V.local x)
172 State.put (Map.insert x v dict)
175 flex | "number" `isPrefixOf` x = Is Number
176 | "comparable" `isPrefixOf` x = Is Comparable
177 | "appendable" `isPrefixOf` x = Is Appendable
178 | otherwise = Flexible
180 T.Aliased name args aliasType ->
181 do args' <- mapM (\(arg,tipe) -> (,) arg <$> go tipe) args
185 instantiatorHelp env Set.empty tipe
187 instantiatorHelp env (Set.fromList (map fst args)) tipe
191 error "problem instantiating type"
193 VarN maybeSubAlias v ->
194 case maybeSubAlias of
196 return (VarN (Just (name,args')) v)
198 return (TermN (Just (name,args')) (Var1 aliasedType'))
200 TermN maybeSubAlias t ->
201 case maybeSubAlias of
203 return (TermN (Just (name, args')) t)
205 return (TermN (Just (name,args')) (Var1 aliasedType'))
208 case Map.lookup (V.toString name) (types env) of
212 "Could not find type constructor `" ++
213 V.toString name ++ "` while checking types."
218 return $ foldl (<|) t' ts'
220 T.Record fields ext ->
221 do fields' <- Traverse.traverse (mapM go) (T.fieldMap fields)
224 Nothing -> return $ termN EmptyRecord1
226 return $ termN (Record1 fields' ext')
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list