blabla
[cc1516.git] / sem.icl
1 implementation module sem
2
3 import qualified Data.Map as Map
4
5 from Data.Func import $
6 from StdFunc import o, flip, const, id
7
8 import Control.Monad
9 import Control.Monad.Trans
10 import Control.Monad.State
11 import Data.Either
12 import Data.Maybe
13 import Data.Monoid
14 import Data.List
15 import Data.Functor
16 import Data.Tuple
17
18 import StdString
19 import StdTuple
20 import StdList
21 import StdMisc
22 import StdEnum
23 import GenEq
24
25 from Text import class Text(concat), instance Text String
26
27 import AST
28
29 :: Scheme = Forall [TVar] Type
30 :: Gamma :== 'Map'.Map String Scheme //map from Variables! to types
31 :: Typing a :== StateT (Gamma, [TVar]) (Either SemError) a
32 :: Substitution :== 'Map'.Map TVar Type
33 :: Constraints :== [(Type, Type)]
34 :: SemError
35 = ParseError Pos String
36 | UnifyError Pos Type Type
37 | InfiniteTypeError Pos Type
38 | FieldSelectorError Pos Type FieldSelector
39 | OperatorError Pos Op2 Type
40 | UndeclaredVariableError Pos String
41 | ArgumentMisMatchError Pos String
42 | SanityError Pos String
43 | Error String
44
45 instance zero Gamma where
46 zero = 'Map'.newMap
47
48 variableStream :: [TVar]
49 variableStream = map toString [1..]
50
51 defaultGamma :: Gamma //includes all default functions
52 defaultGamma = extend "print" (Forall ["a"] ((IdType "a") ->> VoidType))
53 $ extend "isEmpty" (Forall ["a"] ((ListType (IdType "a")) ->> BoolType))
54 $ extend "read" (Forall [] CharType)
55 zero
56
57 sem :: AST -> Either [SemError] AST
58 sem (AST fd) = case foldM (const $ hasNoDups fd) () fd
59 >>| foldM (const isNiceMain) () fd
60 >>| hasMain fd
61 >>| evalStateT (type fd) (defaultGamma, variableStream) of
62 Left e = Left [e]
63 Right (_,fds) = Right (AST fds)
64 where
65 hasNoDups :: [FunDecl] FunDecl -> Either SemError ()
66 hasNoDups fds (FunDecl p n _ _ _ _)
67 # mbs = map (\(FunDecl p` n` _ _ _ _)->if (n == n`) (Just p`) Nothing) fds
68 = case catMaybes mbs of
69 [] = Left $ SanityError p "HUH THIS SHOULDN'T HAPPEN"
70 [x] = pure ()
71 [_:x] = Left $ SanityError p (concat
72 [n, " multiply defined at ", toString p])
73
74 hasMain :: [FunDecl] -> Either SemError ()
75 hasMain [(FunDecl _ "main" _ _ _ _):fd] = pure ()
76 hasMain [_:fd] = hasMain fd
77 hasMain [] = Left $ SanityError zero "no main function defined"
78
79 isNiceMain :: FunDecl -> Either SemError ()
80 isNiceMain (FunDecl p "main" as mt _ _) = case (as, mt) of
81 ([_:_], _) = Left $ SanityError p "main must have arity 0"
82 ([], t) = (case t of
83 Nothing = pure ()
84 Just VoidType = pure ()
85 _ = Left $ SanityError p "main has to return Void")
86 isNiceMain _ = pure ()
87
88 class Typeable a where
89 ftv :: a -> [TVar]
90 subst :: Substitution a -> a
91
92 instance Typeable Scheme where
93 ftv (Forall bound t) = difference (ftv t) bound
94 subst s (Forall bound t) = Forall bound $ subst s_ t
95 where s_ = 'Map'.filterWithKey (\k _ -> not (elem k bound)) s
96
97 instance Typeable [a] | Typeable a where
98 ftv types = foldr (\t ts-> ftv t ++ ts) [] types
99 subst s ts = map (\t->subst s t) ts
100
101 instance Typeable Type where
102 ftv (TupleType (t1, t2)) = ftv t1 ++ ftv t2
103 ftv (ListType t) = ftv t
104 ftv (IdType tvar) = [tvar]
105 ftv (t1 ->> t2) = ftv t1 ++ ftv t2
106 ftv _ = []
107 subst s (TupleType (t1, t2))= TupleType (subst s t1, subst s t2)
108 subst s (ListType t1) = ListType (subst s t1)
109 subst s (t1 ->> t2) = (subst s t1) ->> (subst s t2)
110 subst s t1=:(IdType tvar) = 'Map'.findWithDefault t1 tvar s
111 subst s t = t
112
113 instance Typeable Gamma where
114 ftv gamma = concatMap id $ map ftv ('Map'.elems gamma)
115 subst s gamma = Mapmap (subst s) gamma
116
117 extend :: String Scheme Gamma -> Gamma
118 extend k t g = 'Map'.put k t g
119
120 //// ------------------------
121 //// algorithm U, Unification
122 //// ------------------------
123 instance zero Substitution where zero = 'Map'.newMap
124
125 compose :: Substitution Substitution -> Substitution
126 compose s1 s2 = 'Map'.union (Mapmap (subst s1) s2) s1
127 //Note: just like function compositon compose does snd first
128
129 occurs :: TVar a -> Bool | Typeable a
130 occurs tvar a = elem tvar (ftv a)
131
132 unify :: Type Type -> Either SemError Substitution
133 unify t1 t2=:(IdType tv) | t1 == (IdType tv) = Right zero
134 | occurs tv t1 = Left $ InfiniteTypeError zero t1
135 | otherwise = Right $ 'Map'.singleton tv t1
136 unify t1=:(IdType tv) t2 = unify t2 t1
137 unify (ta1->>ta2) (tb1->>tb2) = unify ta1 tb1 >>= \s1->
138 unify ta2 tb2 >>= \s2->
139 Right $ compose s1 s2
140 unify (TupleType (ta1,ta2)) (TupleType (tb1,tb2)) = unify ta1 tb1 >>= \s1->
141 unify ta2 tb2 >>= \s2->
142 Right $ compose s1 s2
143 unify (ListType t1) (ListType t2) = unify t1 t2
144 unify t1 t2 | t1 == t2 = Right zero
145 | otherwise = Left $ UnifyError zero t1 t2
146
147 //// ------------------------
148 //// Algorithm M, Inference and Solving
149 //// ------------------------
150 gamma :: Typing Gamma
151 gamma = gets fst
152 putGamma :: Gamma -> Typing ()
153 putGamma g = modify (appFst $ const g) >>| pure ()
154 changeGamma :: (Gamma -> Gamma) -> Typing Gamma
155 changeGamma f = modify (appFst f) >>| gamma
156 withGamma :: (Gamma -> a) -> Typing a
157 withGamma f = f <$> gamma
158 fresh :: Typing Type
159 fresh = gets snd >>= \vars->
160 modify (appSnd $ const $ tail vars) >>|
161 pure (IdType (head vars))
162
163 lift :: (Either SemError a) -> Typing a
164 lift (Left e) = liftT $ Left e
165 lift (Right v) = pure v
166
167 //instantiate maps a schemes type variables to variables with fresh names
168 //and drops the quantification: i.e. forall a,b.a->[b] becomes c->[d]
169 instantiate :: Scheme -> Typing Type
170 instantiate (Forall bound t) =
171 mapM (const fresh) bound >>= \newVars->
172 let s = 'Map'.fromList (zip (bound,newVars)) in
173 pure (subst s t)
174
175 //generalize quentifies all free type variables in a type which are not
176 //in the gamma
177 generalize :: Type -> Typing Scheme
178 generalize t = gamma >>= \g-> pure $ Forall (difference (ftv t) (ftv g)) t
179
180 lookup :: String -> Typing Type
181 lookup k = gamma >>= \g-> case 'Map'.member k g of
182 False = liftT (Left $ UndeclaredVariableError zero k)
183 True = instantiate $ 'Map'.find k g
184
185 //The inference class
186 //When tying it all together we will treat the program is a big
187 //let x=e1 in let y=e2 in ....
188 class infer a :: a -> Typing (Substitution, Type)
189
190 ////---- Inference for Expressions ----
191
192 instance infer Expr where
193 infer e = case e of
194 VarExpr _ (VarDef k fs) = lookup k >>= \t ->
195 foldM foldFieldSelectors t fs >>= \finalT ->
196 pure (zero, finalT)
197
198 Op2Expr _ e1 op e2 =
199 infer e1 >>= \(s1, t1) ->
200 infer e2 >>= \(s2, t2) ->
201 fresh >>= \tv ->
202 let given = t1 ->> t2 ->> tv in
203 op2Type op >>= \expected ->
204 lift (unify expected given) >>= \s3 ->
205 pure ((compose s3 $ compose s2 s1), subst s3 tv)
206
207 Op1Expr _ op e1 =
208 infer e1 >>= \(s1, t1) ->
209 fresh >>= \tv ->
210 let given = t1 ->> tv in
211 op1Type op >>= \expected ->
212 lift (unify expected given) >>= \s2 ->
213 pure (compose s2 s1, subst s2 tv)
214
215 EmptyListExpr _ = (\tv->(zero,tv)) <$> fresh
216
217 TupleExpr _ (e1, e2) =
218 infer e1 >>= \(s1, t1) ->
219 infer e2 >>= \(s2, t2) ->
220 pure (compose s2 s1, TupleType (t1,t2))
221
222 FunExpr _ f args fs = //todo: fieldselectors
223 lookup f >>= \expected ->
224 let accST = (\(s,ts) e->infer e >>= \(s_,et)->pure (compose s_ s,ts++[et])) in
225 foldM accST (zero,[]) args >>= \(s1, argTs)->
226 fresh >>= \tv->
227 let given = foldr (->>) tv argTs in
228 lift (unify expected given) >>= \s2->
229 let fReturnType = subst s2 tv in
230 foldM foldFieldSelectors fReturnType fs >>= \returnType ->
231 pure (compose s2 s1, returnType)
232
233 IntExpr _ _ = pure $ (zero, IntType)
234 BoolExpr _ _ = pure $ (zero, BoolType)
235 CharExpr _ _ = pure $ (zero, CharType)
236
237 foldFieldSelectors :: Type FieldSelector -> Typing Type
238 foldFieldSelectors (ListType t) (FieldHd) = pure t
239 foldFieldSelectors t=:(ListType _) (FieldTl) = pure t
240 foldFieldSelectors (TupleType (t1, _)) (FieldFst) = pure t1
241 foldFieldSelectors (TupleType (_, t2)) (FieldSnd) = pure t2
242 foldFieldSelectors t fs = liftT $ Left $ FieldSelectorError zero t fs
243
244 op2Type :: Op2 -> Typing Type
245 op2Type op
246 | elem op [BiPlus, BiMinus, BiTimes, BiDivide, BiMod]
247 = pure (IntType ->> IntType ->> IntType)
248 | elem op [BiEquals, BiUnEqual]
249 = fresh >>= \t1-> fresh >>= \t2-> pure (t1 ->> t2 ->> BoolType)
250 | elem op [BiLesser, BiGreater, BiLesserEq, BiGreaterEq]
251 = pure (IntType ->> IntType ->> BoolType)
252 | elem op [BiAnd, BiOr]
253 = pure (BoolType ->> BoolType ->> BoolType)
254 | op == BiCons
255 = fresh >>= \t1-> pure (t1 ->> ListType t1 ->> ListType t1)
256
257 op1Type :: Op1 -> Typing Type
258 op1Type UnNegation = pure $ (BoolType ->> BoolType)
259 op1Type UnMinus = pure $ (IntType ->> IntType)
260
261 ////----- Inference for Statements -----
262 applySubst :: Substitution -> Typing Gamma
263 applySubst s = changeGamma (subst s)
264
265 instance infer Stmt where
266 infer s = case s of
267 IfStmt e th el =
268 infer e >>= \(s1, et)->
269 lift (unify et BoolType) >>= \s2 ->
270 applySubst (compose s2 s1) >>|
271 infer th >>= \(s3, tht)->
272 applySubst s3 >>|
273 infer el >>= \(s4, elt)->
274 applySubst s4 >>|
275 lift (unify tht elt) >>= \s5->
276 pure (compose s5 $ compose s4 $ compose s3 $ compose s2 s1, subst s5 tht)
277
278 WhileStmt e wh =
279 infer e >>= \(s1, et)->
280 lift (unify et BoolType) >>= \s2 ->
281 applySubst (compose s2 s1) >>|
282 infer wh >>= \(s3, wht)->
283 pure (compose s3 $ compose s2 s1, subst s3 wht)
284
285 AssStmt (VarDef k fs) e =
286 lookup k >>= \expected ->
287 infer e >>= \(s1, given)->
288 foldM reverseFs given (reverse fs) >>= \varType->
289 lift (unify expected varType) >>= \s2->
290 let s = compose s2 s1 in
291 applySubst s >>|
292 changeGamma (extend k (Forall [] (subst s varType))) >>|
293 pure (s, VoidType)
294
295 FunStmt f es _ = pure (zero, VoidType) //Fix for print & check number of args
296 FunStmt f args fs =
297 lookup f >>= \expected ->
298 let accST = (\(s,ts) e->infer e >>= \(s_,et)->pure (compose s_ s,ts++[et])) in
299 foldM accST (zero,[]) args >>= \(s1, argTs)->
300 fresh >>= \tv->
301 let given = foldr (->>) tv argTs in
302 lift (unify expected given) >>= \s2->
303 let fReturnType = subst s2 tv in
304 foldM foldFieldSelectors fReturnType fs >>= \_ ->
305 pure (compose s2 s1, VoidType)
306
307 ReturnStmt Nothing = pure (zero, VoidType)
308 ReturnStmt (Just e) = infer e
309
310 reverseFs :: Type FieldSelector -> Typing Type
311 reverseFs t FieldHd = pure $ ListType t
312 reverseFs t FieldTl = pure $ ListType t
313 reverseFs t FieldFst = fresh >>= \tv -> pure $ TupleType (t, tv)
314 reverseFs t FieldSnd = fresh >>= \tv -> pure $ TupleType (tv, t)
315
316 //The type of a list of statements is either an encountered
317 //return, or VoidType
318 instance infer [a] | infer a where
319 infer [] = pure (zero, VoidType)
320 infer [stmt:ss] =
321 infer stmt >>= \(s1, t1) ->
322 applySubst s1 >>|
323 infer ss >>= \(s2, t2) ->
324 applySubst s2 >>|
325 case t1 of
326 VoidType = pure (compose s2 s1, t2)
327 _ = case t2 of
328 VoidType = pure (compose s2 s1, t1)
329 _ = lift (unify t1 t2) >>= \s3 ->
330 pure (compose s3 $ compose s2 s1, t1)
331
332 //the type class inferes the type of an AST element (VarDecl or FunDecl)
333 //and adds it to the AST element
334 class type a :: a -> Typing (Substitution, a)
335
336 instance type VarDecl where
337 type (VarDecl p expected k e) =
338 infer e >>= \(s1, given) ->
339 applySubst s1 >>|
340 case expected of
341 Nothing = pure zero
342 Just expected_ = lift (unify expected_ given)
343 >>= \s2->
344 applySubst s2 >>|
345 let vtype = subst (compose s2 s1) given in
346 generalize vtype >>= \t ->
347 changeGamma (extend k t) >>|
348 pure (compose s2 s1, VarDecl p (Just vtype) k e)
349
350 instance type FunDecl where
351 type (FunDecl p f args expected vds stmts) =
352 gamma >>= \outerScope-> //functions are infered in their own scopde
353 introduce f >>|
354 mapM introduce args >>= \argTs->
355 type vds >>= \(s1, tVds)->
356 applySubst s1 >>|
357 infer stmts >>= \(s2, result)->
358 applySubst s1 >>|
359 let argTs_ = map (subst $ compose s2 s1) argTs in
360 let given = foldr (->>) result argTs_ in
361 (case expected of
362 Nothing = pure zero
363 Just expected_ = lift (unify expected_ given))
364 >>= \s3 ->
365 let ftype = subst (compose s3 $ compose s2 s1) given in
366 generalize ftype >>= \t->
367 putGamma outerScope >>|
368 changeGamma (extend f t) >>|
369 pure (compose s3 $ compose s2 s1, FunDecl p f args (Just ftype) tVds stmts)
370
371 instance type [a] | type a where
372 type [] = pure (zero, [])
373 type [v:vs] =
374 type v >>= \(s1, v_)->
375 applySubst s1 >>|
376 type vs >>= \(s2, vs_)->
377 applySubst (compose s2 s1) >>|
378 pure (compose s2 s1, [v_:vs_])
379
380 introduce :: String -> Typing Type
381 introduce k =
382 fresh >>= \tv ->
383 changeGamma (extend k (Forall [] tv)) >>|
384 pure tv
385
386 instance toString Scheme where
387 toString (Forall x t) =
388 concat ["Forall ": intersperse "," x] +++ concat [". ", toString t];
389
390 instance toString Gamma where
391 toString mp =
392 concat [concat [k, ": ", toString v, "\n"]\\(k, v)<-'Map'.toList mp]
393
394 instance toString Substitution where
395 toString subs =
396 concat [concat [k, ": ", toString t, "\n"]\\(k, t)<-'Map'.toList subs]
397
398 instance toString SemError where
399 toString (SanityError p e) = concat [toString p,
400 "SemError: SanityError: ", e]
401 toString (ParseError p s) = concat [toString p,
402 "ParseError: ", s]
403 toString (UnifyError p t1 t2) = concat [toString p,
404 "Can not unify types, expected|given:\n", toString t1,
405 "\n", toString t2]
406 toString (InfiniteTypeError p t) = concat [toString p,
407 "Infinite type: ", toString t]
408 toString (FieldSelectorError p t fs) = concat [toString p,
409 "Can not run fieldselector '", toString fs, "' on type: ",
410 toString t]
411 toString (OperatorError p op t) = concat [toString p,
412 "Operator error, operator '", toString op, "' can not be",
413 "used on type: ", toString t]
414 toString (UndeclaredVariableError p k) = concat [toString p,
415 "Undeclared identifier: ", k]
416 toString (ArgumentMisMatchError p str) = concat [toString p,
417 "Argument mismatch: ", str]
418 toString (Error e) = concat ["Unknown error during semantical",
419 "analysis: ", e]
420
421 instance toString (Maybe a) | toString a where
422 toString Nothing = "Nothing"
423 toString (Just e) = concat ["Just ", toString e]
424
425 instance MonadTrans (StateT (Gamma, [TVar])) where
426 liftT m = StateT \s-> m >>= \a-> return (a, s)
427
428 Mapmap :: (a->b) ('Map'.Map k a) -> ('Map'.Map k b)
429 Mapmap _ 'Map'.Tip = 'Map'.Tip
430 Mapmap f ('Map'.Bin sz k v ml mr) = 'Map'.Bin sz k (f v)
431 (Mapmap f ml)
432 (Mapmap f mr)