assignment recognizer

This commit is contained in:
Armin Friedl 2016-08-28 23:14:24 +02:00
parent ac8b6c282d
commit 8249503206

View file

@ -180,18 +180,28 @@ invalidReads s = [] -- do magic here
invalidWrites s = [] -- do magic here invalidWrites s = [] -- do magic here
-- (alternative if easier than invalid read/invalid write separated) -- (alternative if easier than invalid read/invalid write separated)
invAcc :: [(String,Slice,Bool)] -> CheckString -> Slices invAcc :: [(String,Slice,Bool)] -> String -> CheckString -> Slices
invAcc a ('{':t) = invAcc (enterBlock a) t invAcc a _ ('{':t) = invAcc (enterBlock a) "" t
invAcc a ('}':t) = invAcc (leaveBlock a) t invAcc a accumStr ('}':t) = invAcc (leaveBlock a) "" t
invAcc a ('[':t) = invAcc a (drop g t) -- TODO check reads in first part invAcc a accumStr ('[':t) = invAcc a accumStr (drop g t) -- TODO check reads in first part
where g = fromJust (elemIndex ':' t) where g = fromJust (elemIndex ':' t)
-- when reading a assignment :word: = -- when reading an assignment :word: =
-- put :word:, slice, false in the list -- put :word:, slice, false in the list
-- when reading a read access scan the list for the variable -- when reading a read access scan the list for the variable
-- if it is found set its boolean value to true -- if it is found set its boolean value to true
-- if it is not found add its slice to the result -- if it is not found add its slice to the result
-- all variables with false at the end of a block are unused -- all variables with false at the end of a block are unused
invAcc _ _ = [] invAcc a accumStr (c:t) = let chkAccum = checkAccum 0 accumStr -- we need to track the actual index position in the string
in if isNothing chkAccum
then invAcc a (accumStr ++ [c]) t -- no assignment in accumStr
else invAcc (a ++ [fromJust chkAccum]) "" t -- assignment in accumStr
invAcc _ _ _ = []
checkAccum :: Int -> String -> Maybe (String, Slice, Bool)
checkAccum offset accumStr = ((Tdfa.matchOnceText §~ "(\\**[[:word:]]+)[[:blank:]]*=") accumStr) >>= matchToA
where matchToA (before, match, after) =
let m = match ! 1 -- extract the match group (0 = the whole match)
in Just (fst m, (offset+(fst (snd m)), offset+(fst (snd m))+(snd (snd m))), False)
enterBlock :: [(String,Slice,Bool)] -> [(String,Slice,Bool)] enterBlock :: [(String,Slice,Bool)] -> [(String,Slice,Bool)]
enterBlock = map (\(v,s,b) -> ('*':v,s,b)) enterBlock = map (\(v,s,b) -> ('*':v,s,b))