1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
module Verify(verify) where
import AST
import Defs
import Intermediate
verify :: IRProgram -> Error IRProgram
verify (IRProgram vars funcs) = IRProgram <$> mapM verifyVar vars <*> mapM verifyFunc funcs
verifyVar :: DVar -> Error DVar
verifyVar dvar@(DVar _ n e) = case e of
ELit _ _ -> return dvar
_ -> Left $ "Initialisation of global variable " ++ n ++ " is not a literal"
verifyFunc :: IRFunc -> Error IRFunc
verifyFunc irfunc@(IRFunc mrt name _ bbs _) =
let terms = map (\(BB _ _ term) -> term) bbs
(nret', nretr') = unzip $ flip map terms $ \term -> case term of
IRet -> (1, 0)
IRetr _ -> (0, 1)
_ -> (0, 0)
(nret, nretr) = (sum nret', sum nretr') :: (Int, Int)
in case (mrt, nret, nretr) of
(Nothing, _, 0) -> return irfunc
(Just _, 0, _) -> return irfunc
(Nothing, _, _) -> Left $ "Some code paths of void function '" ++ name ++ "' return a value"
(Just _, _, _) -> Left $ "Not all code paths of non-void function '" ++ name ++ "' return a value"
|