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
|
module FlatCurry.Transform.Exec
( transformFuncsInProg
, transformExpr, transformExprMax, transformExprN, showTransformExpr )
where
import Control.Search.Unsafe ( oneValue )
import Data.Tuple.Extra ( second )
import FlatCurry.Goodies ( updFuncBody, updProgFuncs )
import FlatCurry.Types
import FlatCurry.Pretty ( ppExp, Options(..), QualMode(..) )
import Text.Pretty ( pPrint )
import FlatCurry.Transform.Types
import FlatCurry.Transform.Utils ( ReWriter(..)
, curVar, newVar, replace, update )
transformFuncsInProg :: (() -> ExprTransformation) -> Prog -> Prog
transformFuncsInProg transf =
updProgFuncs (map (updFuncBody (transformExpr transf)))
transformExpr :: (() -> ExprTransformation) -> Expr -> Expr
transformExpr = transformExprMax (-1)
transformExprMax :: Int -> (() -> ExprTransformation) -> Expr -> Expr
transformExprMax n trans e = fst (runTrExpr trans n (newVar e) e)
transformExprN :: Int -> (() -> ExprTransformation) -> Expr -> (Expr,Int)
transformExprN n trans e =
let (e',steps) = runTrExpr trans n (newVar e) e
in (e', length steps)
showTransformExpr :: Int -> (() -> ExprTransformation) -> Expr
-> (Expr,String,Int)
showTransformExpr n trans e = let (e',steps) = runTrExpr trans n (newVar e) e
in (e', showTransSteps e steps, length steps)
runTrExpr :: (() -> ExprTransformation) -> Int -> VarIndex -> Expr
-> (Expr,[Step])
runTrExpr trans n v e
| n == 0 = (e,[])
| otherwise = let (e', s, v', seen) = runRewriter (run trans [] e) v
in case seen of
False -> (e', s)
True -> second (s++) $ runTrExpr trans (n-1) v' e'
run :: (() -> ExprTransformation) -> Path -> Expr -> ReWriter Expr
run _ _ e@(Var _) = return e
run _ _ e@(Lit _) = return e
run trans p (Comb ct n es) = do es' <- mapM runExp (zip [0..] es)
runExprTransform trans p (Comb ct n es')
where runExp (i,e) = run trans (i:p) e
run trans p (Let vs e) = do e' <- run trans (-1:p) e
vs' <- mapM runVar (zip [0..] vs)
runExprTransform trans p (Let vs' e')
where runVar (n,(v,l)) = do l' <- run trans (n:p) l
return (v,l')
run trans p (Free vs e) = do e' <- run trans (0:p) e
runExprTransform trans p (Free vs e')
run trans p (Or e1 e2) = do e1' <- run trans (0:p) e1
e2' <- run trans (1:p) e2
runExprTransform trans p (Or e1' e2')
run trans p (Case ct e bs) = do e' <- run trans (-1:p) e
bs' <- mapM runBranch (zip [0..] bs)
runExprTransform trans p (Case ct e' bs')
where runBranch (n,Branch q b) = do b' <- run trans (n:p) b
return (Branch q b')
run trans p (Typed e te) = do e' <- run trans (0:p) e
runExprTransform trans p (Typed e' te)
runExprTransform :: (() -> ExprTransformation) -> Path -> Expr -> ReWriter Expr
runExprTransform trans p e = do
v <- curVar
case oneValue (trans () (v,p) e) of
Nothing -> return e
Just (e',r,dv) -> do update e' (r,p,e') dv
run trans p e'
showTransSteps :: Expr -> [Step] -> String
showTransSteps _ [] = ""
showTransSteps e ((rule, p, rhs):steps) =
"=> " ++ rule ++ " " ++ show (reverse p) ++ "\n" ++
pPrint (ppExp (Options 2 QualNone "") e') ++ "\n" ++
showTransSteps e' steps
where
e' = replace e (reverse p) rhs
|