1 module Typecheck (typeCheckExp, typeCheckStm, typeCheckVar) where
4 import Control.Monad.State
6 import Prelude hiding (lookup)
8 type Types = Map Ident Type
10 inList :: Eq a => a -> [a] -> Bool
12 inList a (x:xs) = if a == x then True else inList a xs
14 typeCheckExp :: (MonadState Types m) => Exp -> m Type
15 typeCheckExp (BiOpExp e o e') = do
18 if not(t1 == t2) then fail "The parameters for the binary operator aren't equal"
19 else if inList o [Eq,NEq] then return TBool
20 else if not(t1 == TInt) then fail "The parameters need to be of type int"
21 else if inList o [Plus,Minus,Times,Div]
24 typeCheckExp (EVar i) = typeCheckVar i
25 typeCheckExp (EAss i e) = do
28 if a == b then return a else fail "FEL!"
29 typeCheckExp (EInt i) = return TInt
30 typeCheckExp (EBool b) = return TBool
31 typeCheckExp EReadI = return TInt
32 typeCheckExp EReadB = return TBool
33 typeCheckExp (ExpT t e) = do
35 if t == t2 then return t else fail "FEL!"
36 typeCheckExp EDefault = return NoType
37 typeCheckExp (EPost i op) = do
38 TInt <- typeCheckVar i
40 typeCheckExp (ENeg e) = do
41 TInt <- typeCheckExp e
44 typeCheckVar :: (MonadState Types m) => Ident -> m Type
49 typeCheckStm :: (MonadState Types m) => Stm -> m Type
50 typeCheckStm SNoop = return NoType
51 typeCheckStm (SExp e) = do
54 typeCheckStm (SBlock ss) = do
57 typeCheckStm (SIf e s s') = do
58 TBool <- typeCheckExp e
59 NoType <- typeCheckStm s
60 NoType <- typeCheckStm s
62 typeCheckStm (SWhile e s) = do
63 TBool <- typeCheckExp e
64 NoType <- typeCheckStm s
66 typeCheckStm (SDecl t i e) = do
68 if t == t2 || t2 == NoType then do
70 case insertLookupWithKey (\k a1 a2 -> a1) i t m of
71 (Nothing,m') -> put m'
72 _ -> fail $ "Duplicate variable declaration: "++show i
74 else fail $ "Illegal to assign an expression of type "++show t2++" to variable "++show i++" of type "++show t
75 typeCheckStm (SPrint e) = do