1module Type.Environment where
3import Control.Applicative ((<$>), (<*>))
4import Control.Monad (forM)
5import qualified Control.Monad.State as State
6import qualified Data.Traversable as Traverse
7import qualified Data.Map as Map
8import qualified Data.Set as Set
9import Data.List (isPrefixOf)
11import qualified AST.Type as T
12import qualified AST.Variable as V
13import qualified AST.Module as Module
17type TypeDict = Map.Map String Type
18type VarDict = Map.Map String Variable
21data Environment = Environment
22 { constructor :: Map.Map String (IO (Int, [Variable], [Type], Type))
28initialEnvironment :: [Module.CanonicalAdt] -> IO Environment
29initialEnvironment datatypes =
30 do types <- makeTypes datatypes
33 { constructor = Map.empty
37 return $ env { constructor = makeConstructors env datatypes }
40makeTypes :: [Module.CanonicalAdt] -> IO TypeDict
42 do adts <- mapM makeImported datatypes
43 bs <- mapM makeBuiltin builtins
44 return (Map.fromList (adts ++ bs))
46 makeImported :: (V.Canonical, Module.AdtInfo V.Canonical) -> IO (String, Type)
47 makeImported (var, _) =
48 do tvar <- namedVar Constant var
49 return (V.toString var, varN tvar)
51 makeBuiltin :: (String, Int) -> IO (String, Type)
52 makeBuiltin (name, _) =
53 do name' <- namedVar Constant (V.builtin name)
54 return (name, varN name')
56 builtins :: [(String, Int)]
61 , kind 0 ["Int","Float","Char","String","Bool"]
64 tuple n = ("_Tuple" ++ show n, n)
65 kind n names = map (\name -> (name, n)) names
70 -> [Module.CanonicalAdt]
71 -> Map.Map String (IO (Int, [Variable], [Type], Type))
72makeConstructors env datatypes =
76 (types env Map.! "List") <| t
78 inst :: Int -> ([Type] -> ([Type], Type)) -> IO (Int, [Variable], [Type], Type)
80 do vars <- forM [1..numTVars] $ \_ -> variable Flexible
81 let (args, result) = tipe (map (varN) vars)
82 return (length args, vars, args, result)
85 let name = "_Tuple" ++ show n
86 in (name, inst n $ \vs -> (vs, foldl (<|) (types env Map.! name) vs))
88 builtins :: [ (String, IO (Int, [Variable], [Type], Type)) ]
90 [ ("[]", inst 1 $ \ [t] -> ([], list t))
91 , ("::", inst 1 $ \ [t] -> ([t, list t], list t))
92 ] ++ map tupleCtor [0..9]
93 ++ concatMap (ctorToType env) datatypes
98 -> (V.Canonical, Module.AdtInfo V.Canonical)
99 -> [(String, IO (Int, [Variable], [Type], Type))]
100ctorToType env (name, (tvars, ctors)) =
101 zip (map (V.toString . fst) ctors) (map inst ctors)
103 inst :: (V.Canonical, [T.Canonical]) -> IO (Int, [Variable], [Type], Type)
105 do ((args, tipe), dict) <- State.runStateT (go ctor) Map.empty
106 return (length args, Map.elems dict, args, tipe)
109 go :: (V.Canonical, [T.Canonical]) -> State.StateT VarDict IO ([Type], Type)
111 do types <- mapM (instantiator env) args
112 returnType <- instantiator env (T.App (T.Type name) (map T.Var tvars))
113 return (types, returnType)
116get :: Environment -> (Environment -> Map.Map String a) -> String -> a
118 Map.findWithDefault (error msg) key (subDict env)
120 msg = "Could not find type constructor `" ++ key ++ "` while checking types."
126 -> IO (Int, [Variable], [Type], Type)
127freshDataScheme env name =
128 get env constructor name
135 -> IO ([Variable], Type)
136instantiateType env sourceType dict =
137 do (tipe, dict') <- State.runStateT (instantiator env sourceType) dict
138 return (Map.elems dict', tipe)
144 -> State.StateT VarDict IO Type
145instantiator env sourceType =
146 instantiatorHelp env Set.empty sourceType
153 -> State.StateT VarDict IO Type
154instantiatorHelp env aliasVars sourceType =
155 let go = instantiatorHelp env aliasVars
159 (==>) <$> go t1 <*> go t2
163 case Set.member x aliasVars of
165 return (PlaceHolder x)
167 case Map.lookup x dict of
172 do v <- State.liftIO $ namedVar flex (V.local x)
173 State.put (Map.insert x v dict)
176 flex | "number" `isPrefixOf` x = Is Number
177 | "comparable" `isPrefixOf` x = Is Comparable
178 | "appendable" `isPrefixOf` x = Is Appendable
179 | otherwise = Flexible
181 T.Aliased name args aliasType ->
182 do args' <- mapM (\(arg,tipe) -> (,) arg <$> go tipe) args
186 instantiatorHelp env Set.empty tipe
188 instantiatorHelp env (Set.fromList (map fst args)) tipe
192 error "problem instantiating type"
194 VarN maybeSubAlias v ->
195 case maybeSubAlias of
197 return (VarN (Just (name,args')) v)
199 return (TermN (Just (name,args')) (Var1 aliasedType'))
201 TermN maybeSubAlias t ->
202 case maybeSubAlias of
204 return (TermN (Just (name, args')) t)
206 return (TermN (Just (name,args')) (Var1 aliasedType'))
209 case Map.lookup (V.toString name) (types env) of
213 "Could not find type constructor `" ++
214 V.toString name ++ "` while checking types."
219 return $ foldl (<|) t' ts'
221 T.Record fields ext ->
222 do fields' <- Traverse.traverse (mapM go) (T.fieldMap fields)
225 Nothing -> return $ termN EmptyRecord1
227 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