]> ruin.nu Git - proglang.git/blob - Typecheck.hs
922264061337362de5dab48dcbdb8163b9bee8d4
[proglang.git] / Typecheck.hs
1 module Typecheck 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 typeCheckExp :: (MonadState Types m) => Exp -> m Type
12 typeCheckExp (BExp e o e') = do
13         TInt <- typeCheckExp e
14         TInt <- typeCheckExp e'
15         return TBool
16 typeCheckExp (OpExp e o e') = do
17         TInt <- typeCheckExp e
18         TInt <- typeCheckExp e'
19         return TInt
20 typeCheckExp (EVar i) = typeCheckVar i
21 typeCheckExp (EAss i e) = do
22         a <- typeCheckVar i
23         b <- typeCheckExp e
24         if a == b then return a else fail "FEL!"
25 typeCheckExp (EInt i) = return TInt
26 typeCheckExp (EBool b) = return TBool
27 typeCheckExp EReadI = return TInt
28 typeCheckExp EReadB = return TBool
29 typeCheckExp (ExpT t e) = do
30         t2 <- typeCheckExp e
31         if t == t2 then return t else fail "FEL!"
32 typeCheckExp EDefault = return NoType
33 typeCheckExp (EPost i op) = do
34         TInt <- typeCheckVar i
35         return TInt
36 typeCheckExp (ENeg e) = do
37         TInt <- typeCheckExp e
38         return TInt
39
40
41 typeCheckVar :: (MonadState Types m) => Ident -> m Type 
42 typeCheckVar i = do
43         e <- get
44         lookup i e
45
46 typeCheckStm :: (MonadState Types m) => Stm -> m Type 
47 typeCheckStm SNoop = return NoType
48 typeCheckStm (SExp e) = do 
49         typeCheckExp e
50         return NoType
51 typeCheckStm (SBlock ss) = do 
52         mapM typeCheckStm ss
53         return NoType
54 typeCheckStm (SIf e s s') = do
55         TBool <- typeCheckExp e
56         NoType <- typeCheckStm s
57         NoType <- typeCheckStm s
58         return NoType
59 typeCheckStm (SWhile e s) = do
60         TBool <- typeCheckExp e
61         NoType <- typeCheckStm s
62         return NoType
63 typeCheckStm (SDecl t i e) = do
64         t2 <- typeCheckExp e
65         if t == t2 || t2 == NoType then do
66                 m <- get
67                 put (insert i t m)
68                 return NoType
69                 else fail $ "Illegal to assign an expression of type "++show t2++" to variable "++show i++" of type "++show t
70 typeCheckStm (SPrint e) = do
71         typeCheckExp e
72         return NoType
73