aboutsummaryrefslogtreecommitdiff
path: root/Verify.hs
blob: 18f90ce1cd7b0ae8fa46d6fffb0ad11a1d5d64b1 (plain)
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"