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
108
|
module CurryBrowseAnalysis.PatternComplete(CompletenessType(..),
analyseCompleteness,
analyseTotallyDefined) where
import FlatCurry.Types
import CurryBrowseAnalysis.Dependency(analyseWithDependencies)
data CompletenessType =
Complete
| InComplete
| InCompleteOr
analyseTotallyDefined :: [TypeDecl] -> [FuncDecl] -> [(QName,CompletenessType)]
analyseTotallyDefined types = analyseWithDependencies (analyseCompleteness types) cAnd
where cAnd = foldr combineAndResults Complete
analyseCompleteness :: [TypeDecl] -> FuncDecl -> CompletenessType
analyseCompleteness types fdecl = anaFun fdecl
where
anaFun (Func _ _ _ _ (Rule _ e)) = isComplete types e
anaFun (Func _ _ _ _ (External _)) = Complete
isComplete :: [TypeDecl] -> Expr -> CompletenessType
isComplete _ (Var _) = Complete
isComplete _ (Lit _) = Complete
isComplete types (Comb _ f es) =
if f==("Prelude","commit") && length es == 1
then isComplete types (head es)
else Complete
isComplete _ (Free _ _) = Complete
isComplete _ (Let _ _) = Complete
isComplete types (Or e1 e2) =
combineOrResults (isComplete types e1) (isComplete types e2)
isComplete _ (Case _ _ []) = InComplete
isComplete _ (Case _ _ (Branch (LPattern _) _ : _)) = InComplete
isComplete types (Case _ _ (Branch (Pattern cons pvs) bexp : ces)) =
checkAllCons (getConstructors cons types) (Branch (Pattern cons pvs) bexp : ces)
where
checkAllCons [] _ = Complete
checkAllCons (_:_) [] = InComplete
checkAllCons (_:_) (Branch (LPattern _) _ : _) = InComplete
checkAllCons (c:cs) (Branch (Pattern i _) e : ps) =
combineAndResults (checkAllCons (removeConstructor i (c:cs)) ps)
(isComplete types e)
isComplete types (Typed e _) = isComplete types e
combineOrResults :: CompletenessType -> CompletenessType -> CompletenessType
combineOrResults Complete _ = Complete
combineOrResults InComplete Complete = Complete
combineOrResults InComplete InComplete = InCompleteOr
combineOrResults InComplete InCompleteOr = InCompleteOr
combineOrResults InCompleteOr Complete = Complete
combineOrResults InCompleteOr InComplete = InCompleteOr
combineOrResults InCompleteOr InCompleteOr = InCompleteOr
combineAndResults :: CompletenessType -> CompletenessType -> CompletenessType
combineAndResults InComplete _ = InComplete
combineAndResults Complete Complete = Complete
combineAndResults Complete InComplete = InComplete
combineAndResults Complete InCompleteOr = InCompleteOr
combineAndResults InCompleteOr Complete = InCompleteOr
combineAndResults InCompleteOr InComplete = InComplete
combineAndResults InCompleteOr InCompleteOr = InCompleteOr
getConstructors :: QName -> [TypeDecl] -> [ConsDecl]
getConstructors _ [] = error "Internal compiler error: case datatype not found!"
getConstructors cons (TypeSyn _ _ _ _ : types) = getConstructors cons types
getConstructors cons (Type _ _ _ cdecls : types) =
if hasCons cdecls then cdecls
else getConstructors cons types
where
hasCons [] = False
hasCons (Cons cs _ _ _ : cstrs) = cons==cs || hasCons cstrs
removeConstructor :: QName -> [ConsDecl] -> [ConsDecl]
removeConstructor c1 [] = error ("Constructor "++show c1++" not found!!")
removeConstructor c1 ((Cons c2 a vis ts):cs)
| c1==c2 = cs
| otherwise = (Cons c2 a vis ts):(removeConstructor c1 cs)
|