1 module Typecheck (typeCheckExp, typeCheckStm, typeCheckVar) where
4 import Control.Monad.State
6 import Prelude hiding (lookup)
9 type Types = Map Ident Type
11 inList :: Eq a => a -> [a] -> Bool
13 inList a (x:xs) = if a == x then True else inList a xs
15 typeCheckExp :: (MonadState Types m) => Exp -> m Type
16 typeCheckExp (BiOpExp e o e') = do
19 if not(t1 == t2) then fail ""
20 else case inList o [Eq,NEq] of
22 False -> if not(t1 == TInt) then fail ""
23 else case inList o [Plus,Minus,Times,Div] of
26 typeCheckExp (EVar i) = typeCheckVar i
27 typeCheckExp (EAss i e) = do
30 if a == b then return a else fail "FEL!"
31 typeCheckExp (EInt i) = return TInt
32 typeCheckExp (EBool b) = return TBool
33 typeCheckExp EReadI = return TInt
34 typeCheckExp EReadB = return TBool
35 typeCheckExp (ExpT t e) = do
37 if t == t2 then return t else fail "FEL!"
38 typeCheckExp EDefault = return NoType
39 typeCheckExp (EPost i op) = do
40 TInt <- typeCheckVar i
42 typeCheckExp (ENeg e) = do
43 TInt <- typeCheckExp e
47 typeCheckVar :: (MonadState Types m) => Ident -> m Type
52 typeCheckStm :: (MonadState Types m) => Stm -> m Type
53 typeCheckStm SNoop = return NoType
54 typeCheckStm (SExp e) = do
57 typeCheckStm (SBlock ss) = do
60 typeCheckStm (SIf e s s') = do
61 TBool <- typeCheckExp e
62 NoType <- typeCheckStm s
63 NoType <- typeCheckStm s
65 typeCheckStm (SWhile e s) = do
66 TBool <- typeCheckExp e
67 NoType <- typeCheckStm s
69 typeCheckStm (SDecl t i e) = do
71 if t == t2 || t2 == NoType then do
73 case insertLookupWithKey (\k a1 a2 -> a1) i t m of
74 (Nothing,m') -> put m'
75 _ -> fail $ "Duplicate variable declaration: "++show i
77 else fail $ "Illegal to assign an expression of type "++show t2++" to variable "++show i++" of type "++show t
78 typeCheckStm (SPrint e) = do