]> ruin.nu Git - proglang.git/blob - Typecheck.hs
streamlined the binary operators
[proglang.git] / Typecheck.hs
1 module Typecheck (typeCheckExp, typeCheckStm, typeCheckVar) where 
2
3 import Abssyntax
4 import Control.Monad.State
5 import Data.Map as Map
6 import Prelude hiding (lookup)
7
8
9 type Types = Map Ident Type
10
11 inList :: Eq a => a -> [a] -> Bool
12 inList _ [] = False
13 inList a (x:xs) = if a == x then True else inList a xs
14
15 typeCheckExp :: (MonadState Types m) => Exp -> m Type
16 typeCheckExp (BiOpExp e o e') = do
17         t1 <- typeCheckExp e
18         t2 <- typeCheckExp e'
19         if not(t1 == t2) then fail "" 
20                 else case inList o [Eq,NEq] of
21                         True -> return TBool
22                         False -> if not(t1 == TInt) then fail "" 
23                                 else case inList o [Plus,Minus,Times,Div] of
24                                         True -> return TInt
25                                         False -> return TBool
26 typeCheckExp (EVar i) = typeCheckVar i
27 typeCheckExp (EAss i e) = do
28         a <- typeCheckVar i
29         b <- typeCheckExp e
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
36         t2 <- typeCheckExp e
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
41         return TInt
42 typeCheckExp (ENeg e) = do
43         TInt <- typeCheckExp e
44         return TInt
45
46
47 typeCheckVar :: (MonadState Types m) => Ident -> m Type 
48 typeCheckVar i = do
49         e <- get
50         lookup i e
51
52 typeCheckStm :: (MonadState Types m) => Stm -> m Type 
53 typeCheckStm SNoop = return NoType
54 typeCheckStm (SExp e) = do 
55         typeCheckExp e
56         return NoType
57 typeCheckStm (SBlock ss) = do 
58         mapM typeCheckStm ss
59         return NoType
60 typeCheckStm (SIf e s s') = do
61         TBool <- typeCheckExp e
62         NoType <- typeCheckStm s
63         NoType <- typeCheckStm s
64         return NoType
65 typeCheckStm (SWhile e s) = do
66         TBool <- typeCheckExp e
67         NoType <- typeCheckStm s
68         return NoType
69 typeCheckStm (SDecl t i e) = do
70         t2 <- typeCheckExp e
71         if t == t2 || t2 == NoType then do
72                 m <- get
73                 put (insert i t m)
74                 return NoType
75                 else fail $ "Illegal to assign an expression of type "++show t2++" to variable "++show i++" of type "++show t
76 typeCheckStm (SPrint e) = do
77         typeCheckExp e
78         return NoType
79