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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
module TypedFlatCurryGoodies where
import FlatCurry.Files
import List ( find, nub )
import Maybe ( fromJust )
import System ( exitWith )
import FlatCurry.Annotated.Goodies
import FlatCurry.Annotated.Types
import FlatCurry.Annotated.TypeInference ( inferProg )
type TAProg = AProg TypeExpr
type TAFuncDecl = AFuncDecl TypeExpr
type TARule = ARule TypeExpr
type TAExpr = AExpr TypeExpr
type TABranchExpr = ABranchExpr TypeExpr
type TAPattern = APattern TypeExpr
readTypedFlatCurry :: String -> IO TAProg
readTypedFlatCurry mname = do
prog <- readFlatCurry mname
inferProg prog >>=
either (\e -> putStrLn ("Error during FlatCurry type inference:\n" ++ e) >>
exitWith 1)
return
getAllFunctions :: [TAFuncDecl] -> [TAProg] -> [QName]
-> IO [TAFuncDecl]
getAllFunctions currfuncs _ [] = return (reverse currfuncs)
getAllFunctions currfuncs currmods (newfun:newfuncs)
| newfun `elem` standardConstructors ++ map funcName currfuncs
|| isPrimOp newfun
= getAllFunctions currfuncs currmods newfuncs
| fst newfun `elem` map progName currmods
= maybe
(
getAllFunctions currfuncs currmods newfuncs)
(\fdecl -> getAllFunctions
(fdecl : currfuncs)
currmods (newfuncs ++ nub (funcsOfFuncDecl fdecl)))
(find (\fd -> funcName fd == newfun)
(progFuncs
(fromJust (find (\m -> progName m == fst newfun) currmods))))
| otherwise
= do let mname = fst newfun
putStrLn $ "Loading module '" ++ mname ++ "'..."
newmod <- readTypedFlatCurry mname
getAllFunctions currfuncs (newmod:currmods) (newfun:newfuncs)
funcsOfFuncDecl :: TAFuncDecl -> [QName]
funcsOfFuncDecl fd =
nub (trRule (\_ _ e -> funcsOfExp e) (\_ _ -> []) (funcRule fd))
where
funcsOfExp = trExpr (\_ _ -> [])
(\_ _ -> [])
(\_ _ (qn,_) fs -> qn : concat fs)
(\_ bs fs -> concatMap snd bs ++ fs)
(\_ _ -> id)
(\_ -> (++))
(\_ _ fs fss -> concat (fs:fss))
(\_ -> id)
(\_ fs _ -> fs)
ndExpr :: TAExpr -> Bool
ndExpr = trExpr (\_ _ -> False)
(\_ _ -> False)
(\_ _ _ nds -> or nds)
(\_ bs nd -> nd || any snd bs)
(\_ _ _ -> True)
(\_ _ _ -> True)
(\_ _ nd bs -> nd || or bs)
(\_ -> id)
(\_ nd _ -> nd)
isPrimOp :: QName -> Bool
isPrimOp (mn,fn) = mn=="Prelude" && fn `elem` map fst preludePrimOps
preludePrimOps :: [(String,String)]
preludePrimOps =
[("==","=")
,("+","+")
,("-","-")
,("negate","-")
,("*","*")
,("div","div")
,("mod","mod")
,("rem","rem")
,(">",">")
,(">=",">=")
,("<","<")
,("<=","<=")
,("not","not")
,("&&","and")
,("||","or")
,("apply","")
]
primCons :: [(String,String)]
primCons =
[("True","true")
,("False","false")
,("[]","nil")
,(":","insert")
]
standardConstructors :: [QName]
standardConstructors = [pre "[]", pre ":", pre "()"]
pre :: String -> QName
pre f = ("Prelude",f)
showQName :: QName -> String
showQName (mn,fn) = mn ++ "." ++ fn
|