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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
module UsageCheck(checkSetUse, checkBlacklistUse) where
import Char(isDigit)
import Read(readNat)
import qualified AbstractCurry.Types as AC
import AbstractCurryMatch
import FlatCurry.Types
import FlatCurryMatch
import Control.SetFunctions
checkSetUse :: Prog -> IO [(QName,String)]
checkSetUse (Prog _ _ _ fdecls _) = do
seterrors <- values2list (set1 setUse fdecls)
return (map showSetError seterrors)
where
showSetError (qf,sar) =
(qf, "wrong use of set function `set" ++ sar ++ "'!")
setUse :: [FuncDecl] -> (QName, String)
setUse (_ ++
[funWithinExp qf _ _ (Comb ct ("Control.SetFunctions","set"++n) args)]
++ _)
| not (validSetFunCall ct n args) = (qf,n)
validSetFunCall :: CombType -> String -> [Expr] -> Bool
validSetFunCall ct n args
| ct==FuncCall && all isDigit n && not (null args)
= if arity==0 then isFuncCall (head args)
else isFuncPartCall arity (head args)
where
arity = readNat n
isFuncCall :: Expr -> Bool
isFuncCall e = case e of
Comb FuncCall qf [] -> isID qf
_ -> False
isFuncPartCall :: Int -> Expr -> Bool
isFuncPartCall n e = case e of
Comb (FuncPartCall p) qf _ -> p==n && isID qf
_ -> False
isID :: QName -> Bool
isID (_,n) = all (`elem` infixIDs) n || '.' `notElem` n
where
infixIDs :: String
infixIDs = "~!@#$%^&*+-=<>?./|\\:"
checkBlacklistUse :: AC.CurryProg -> IO [(QName,String)]
checkBlacklistUse (AC.CurryProg _ _ _ _ _ _ cfdecls _) = do
blerrors <- values2list (set1 blacklistUsage cfdecls)
return (map showBlacklistError blerrors)
where
showBlacklistError (qf,(q,f)) =
(qf, "direct use of `" ++ q++"."++f ++ "' not allowed!")
blacklistUsage :: [AC.CFuncDecl] -> (AC.QName, AC.QName)
blacklistUsage (_ ++ [cfunWithExp qf (AC.CSymbol qop)] ++ _)
| isBlacklistedOperation qop
= (qf,qop)
isBlacklistedOperation :: AC.QName -> Bool
isBlacklistedOperation (q,f) =
q == AC.preludeName &&
(take 5 f == "prim_"
|| f `elem` ["=:<=", "=:<<="])
|