| 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
 | 
{-# OPTIONS_FRONTEND -Wno-incomplete-patterns #-}
module Analysis.SensibleTypes
  ( Sensible(..), showSensible, sensibleType )
 where
import Data.Maybe
import FlatCurry.Types
import FlatCurry.Goodies
import RW.Base
import System.IO
import Analysis.Types
import Analysis.ProgInfo
data Sensible = NotSensible | PSensible | Sensible
  deriving (Show, Read, Eq)
showSensible :: AOutFormat -> Sensible -> String
showSensible _ Sensible    = "sensible"
showSensible _ PSensible   = "parametric sensible"
showSensible _ NotSensible = "not sensible"
lubSens :: Sensible -> Sensible -> Sensible
lubSens Sensible    _           = Sensible
lubSens PSensible   Sensible    = Sensible
lubSens PSensible   PSensible   = PSensible
lubSens PSensible   NotSensible = PSensible
lubSens NotSensible x           = x
sensibleType :: Analysis Sensible
sensibleType = dependencyTypeAnalysis "SensibleType" NotSensible sensOfType
predefinedSensibles :: [QName]
predefinedSensibles = [pre "Int", pre "Float", pre "Char", pre "IO"]
 where pre tc = ("Prelude",tc)
sensOfType :: TypeDecl -> [(QName,Sensible)] -> Sensible
sensOfType (TypeSyn _ _ _ typeExpr) usedtypes =
  sensOfTypeExpr usedtypes typeExpr
sensOfType (TypeNew _ _ _ (NewCons _ _ typeExpr)) usedtypes =
  sensOfTypeExpr usedtypes typeExpr
sensOfType (Type tc _ _ conDecls) usedtypes
  | tc `elem` predefinedSensibles = Sensible
  | otherwise = foldr lubSens NotSensible (map sensOfConsDecl conDecls)
 where
   sensOfConsDecl (Cons _ _ _ typeExprs)
     | all (== Sensible)    senstargs = Sensible
     | all (/= NotSensible) senstargs = PSensible
     | otherwise                      = NotSensible
    where senstargs = map (sensOfTypeExpr usedtypes) typeExprs
sensOfTypeExpr :: [(QName,Sensible)] -> TypeExpr -> Sensible
sensOfTypeExpr _ (TVar _)       = PSensible
sensOfTypeExpr _ (FuncType _ _) = NotSensible 
                                              
sensOfTypeExpr usedtypes (TCons tc typeExprs)
  | senstc == Sensible || (senstc == PSensible && all (==Sensible) senstargs)
  = Sensible
  | senstc == PSensible && all (/=NotSensible) senstargs
  = PSensible
  | otherwise
  = NotSensible
 where
  senstc    = maybe NotSensible id (lookup tc usedtypes)
  senstargs = map (sensOfTypeExpr usedtypes) typeExprs
sensOfTypeExpr usedtypes (ForallType _ texp) = sensOfTypeExpr usedtypes texp
instance ReadWrite Sensible where
  readRW _ ('0' : r0) = (NotSensible,r0)
  readRW _ ('1' : r0) = (PSensible,r0)
  readRW _ ('2' : r0) = (Sensible,r0)
  showRW _ strs0 NotSensible = (strs0,showChar '0')
  showRW _ strs0 PSensible = (strs0,showChar '1')
  showRW _ strs0 Sensible = (strs0,showChar '2')
  writeRW _ h NotSensible strs = hPutChar h '0' >> return strs
  writeRW _ h PSensible strs = hPutChar h '1' >> return strs
  writeRW _ h Sensible strs = hPutChar h '2' >> return strs
  typeOf _ = monoRWType "Sensible"
 |