| 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
 |