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
|
module DefaultRuleUsage
( containsDefaultRules, checkDefaultRules
, isDefaultFunc, isDefaultName, fromDefaultName
) where
import AbstractCurry.Types
import AbstractCurry.Select
import Data.List
containsDefaultRules :: CurryProg -> Bool
containsDefaultRules = not . null . filter isDefaultFunc . functions
checkDefaultRules :: CurryProg -> [(QName,String)]
checkDefaultRules prog =
let allfunctions = functions prog
(defruledecls,fdecls) = partition isDefaultFunc allfunctions
in concatMap (checkDefaultRule fdecls) defruledecls ++
concatMap checkLocalDefaultRule allfunctions
checkDefaultRule :: [CFuncDecl] -> CFuncDecl -> [(QName,String)]
checkDefaultRule funcs (CmtFunc _ qf ar vis texp rules) =
checkDefaultRule funcs (CFunc qf ar vis texp rules)
checkDefaultRule funcs (CFunc defqn@(mn,deffn) ar _ _ rules)
| null rules
= [(defqn,"Default rule without right-hand side!")]
| length rules > 1
= [(defqn,"More than one default rule for function '" ++ orgfn ++ "'!")]
| otherwise
= maybe [(defqn,"Default rule given but function '" ++ orgfn ++ "' not defined!")]
(\fd -> if funcArity fd == ar
then []
else [(defqn,"Default rule has wrong arity!")])
(find (\fd -> funcName fd == orgqn) funcs)
where
orgfn = fromDefaultName deffn
orgqn = (mn, orgfn)
checkLocalDefaultRule :: CFuncDecl -> [(QName,String)]
checkLocalDefaultRule (CmtFunc _ qf ar vis texp rules) =
checkLocalDefaultRule (CFunc qf ar vis texp rules)
checkLocalDefaultRule (CFunc defqn _ _ _ rules) =
checkLocalRules (concatMap allLocalDecls rules)
where
checkLocalRules ldecls =
map (\ (_,fn) -> (defqn, "Local default rule '" ++ fn ++ "' is not allowed!"))
(filter (isDefaultName . snd) (concatMap funcNamesOfLDecl ldecls))
allLocalDecls :: CRule -> [CLocalDecl]
allLocalDecls (CRule _ rhs) = localsInRHS rhs
where
localsInRHS (CSimpleRhs _ ldecls) = concatMap localsInLDecls ldecls
localsInRHS (CGuardedRhs _ ldecls) = concatMap localsInLDecls ldecls
localsInLDecls ldecl = ldecl : case ldecl of
CLocalFunc fd -> concatMap allLocalDecls (funcRules fd)
CLocalPat _ e -> localsInRHS e
CLocalVars _ -> []
isDefaultFunc :: CFuncDecl -> Bool
isDefaultFunc = isDefaultName . snd . funcName
isDefaultName :: String -> Bool
isDefaultName f = "'default" `isSuffixOf` f
fromDefaultName :: String -> String
fromDefaultName f =
let rf = reverse f
in reverse (drop (if take 8 rf == "tluafed'" then 8 else 0) rf)
|