@@ -1,10 +1,9 @@
1−module Optimize (optimize) where
1+module Transform.Optimize (optimize) where
3−import Ast
3+import SourceSyntax.Everything
5import Control.Arrow (second, (***))
4import Control.Arrow (second, (***))
6import Data.Char (isAlpha)
5import Data.Char (isAlpha)
7−import Substitute
6+import Transform.Substitute
9optimize (Module name ims exs stmts) =
8optimize (Module name ims exs stmts) =
10 Module name ims exs (map optimizeStmt stmts)
9 Module name ims exs (map optimizeStmt stmts)
@@ -15,12 +14,12 @@ optimizeStmt stmt = if stmt == stmt' then stmt' else optimizeStmt stmt'
15class Simplify a where
14class Simplify a where
16 simp :: a -> a
15 simp :: a -> a
18−instance Simplify Statement where
17+instance Simplify (Declaration t v) where
19 simp (Definition def) = Definition (simp def)
18 simp (Definition def) = Definition (simp def)
20 simp (ImportEvent js b elm t) = ImportEvent js (simp b) elm t
19 simp (ImportEvent js b elm t) = ImportEvent js (simp b) elm t
21 simp stmt = stmt
20 simp stmt = stmt
23−instance Simplify Def where
22+instance Simplify (Def t v) where
24 simp (FnDef func args e) = FnDef func args (simp e)
23 simp (FnDef func args e) = FnDef func args (simp e)
25 simp (OpDef op a1 a2 e) = OpDef op a1 a2 (simp e)
24 simp (OpDef op a1 a2 e) = OpDef op a1 a2 (simp e)
26 simp x = x
25 simp x = x
@@ -28,12 +27,12 @@ instance Simplify Def where
28instance Simplify e => Simplify (Located e) where
27instance Simplify e => Simplify (Located e) where
29 simp (L t s e) = L t s (simp e)
28 simp (L t s e) = L t s (simp e)
31−instance Simplify Expr where
30+instance Simplify (Expr t v) where
32 simp expr =
31 simp expr =
33 let f = simp in
32 let f = simp in
34 case expr of
33 case expr of
35 Range e1 e2 -> Range (f e1) (f e2)
34 Range e1 e2 -> Range (f e1) (f e2)
36− Binop op e1 e2 -> simp_binop op (f e1) (f e2)
35+ Binop op e1 e2 -> binop op (f e1) (f e2)
37 Lambda x e -> Lambda x (f e)
36 Lambda x e -> Lambda x (f e)
38 Record fs -> Record (map (\(f,as,e) -> (f, as, simp e)) fs)
37 Record fs -> Record (map (\(f,as,e) -> (f, as, simp e)) fs)
39 App (L t s (Lambda x e1)) e2 ->
38 App (L t s (Lambda x e1)) e2 ->
@@ -51,41 +50,43 @@ instance Simplify Expr where
51clipBranches [] = []
50clipBranches [] = []
52clipBranches (e:es) =
51clipBranches (e:es) =
54− (L _ _ (Boolean True), _) -> [e]
53+ (L _ _ (Literal (Boolean True)), _) -> [e]
55 _ -> e : clipBranches es
54 _ -> e : clipBranches es
58isValue e =
57isValue e =
59− case e of { IntNum _ -> True
58+ case e of
60− ; FloatNum _ -> True
59+ Literal _ -> True
64− ; Var _ -> True
60+ Var _ -> True
65− ; Data _ _ -> True
61+ Data _ _ -> True
66− ; _ -> False }
62+ _ -> False
70binop op ce1@(L t1 s1 e1) ce2@(L t2 s2 e2) =
65binop op ce1@(L t1 s1 e1) ce2@(L t2 s2 e2) =
71− let c1 = L t1 s1 in
66+ let c1 = L t1 s1
72− let c2 = L t2 s2 in
67+ c2 = L t2 s2
68+ int = Literal . IntNum
70+ bool = Literal . Boolean
73 case (op, e1, e2) of
72 case (op, e1, e2) of
74− (_, IntNum n, IntNum m) -> case op of
73+ (_, Literal (IntNum n), Literal (IntNum m)) ->
75− { "+" -> IntNum $ (+) n m
74+ case op of
76− ; "-" -> IntNum $ (-) n m
75+ { "+" -> int $ (+) n m
77− ; "*" -> IntNum $ (*) n m
76+ ; "-" -> int $ (-) n m
78− ; "^" -> IntNum $ n ^ m
77+ ; "*" -> int $ (*) n m
79− ; "div" -> IntNum $ div n m
79+ ; "div" -> int $ div n m
80− ; "mod" -> IntNum $ mod n m
80+ ; "mod" -> int $ mod n m
81− ; "<" -> Boolean $ n < m
81+ ; "rem" -> int $ rem n m
82− ; ">" -> Boolean $ n < m
82+ ; "<" -> bool $ n < m
83− ; "<=" -> Boolean $ n <= m
83+ ; ">" -> bool $ n < m
84− ; ">=" -> Boolean $ n >= m
84+ ; "<=" -> bool $ n <= m
85− ; "==" -> Boolean $ n == m
85+ ; ">=" -> bool $ n >= m
86− ; "/=" -> Boolean $ n /= m
86+ ; "==" -> bool $ n == m
87+ ; "/=" -> bool $ n /= m
87− ; _ -> Binop op ce1 ce2 }
88+ ; _ -> Binop op ce1 ce2 }
89 -- flip order to move lone integers to the left
90 -- flip order to move lone integers to the left
90 ("+", _, IntNum n) -> binop "+" ce2 ce1
91 ("+", _, IntNum n) -> binop "+" ce2 ce1
91 ("*", _, IntNum n) -> binop "*" ce2 ce1
92 ("*", _, IntNum n) -> binop "*" ce2 ce1
@@ -95,47 +96,49 @@ binop op ce1@(L t1 s1 e1) ce2@(L t2 s2 e2) =
95 binop "+" (c1 $ IntNum (n+m)) ce
96 binop "+" (c1 $ IntNum (n+m)) ce
96 ("+", Binop "+" (L _ _ (IntNum n)) ce1'
97 ("+", Binop "+" (L _ _ (IntNum n)) ce1'
97 , Binop "+" (L _ _ (IntNum m)) ce2') ->
98 , Binop "+" (L _ _ (IntNum m)) ce2') ->
98− binop "+" (notLocated $ IntNum (n+m)) (notLocated $ Binop "+" ce1' ce2')
99+ binop "+" (none $ IntNum (n+m)) (none $ Binop "+" ce1' ce2')
100 ("*", IntNum 0, _) -> e1
101 ("*", IntNum 0, _) -> e1
101 ("*", IntNum 1, _) -> e2
102 ("*", IntNum 1, _) -> e2
102 ("*", IntNum n, Binop "*" (L _ _ (IntNum m)) ce) ->
103 ("*", IntNum n, Binop "*" (L _ _ (IntNum m)) ce) ->
103− binop "*" (notLocated $ IntNum (n*m)) ce
104+ binop "*" (none $ IntNum (n*m)) ce
104 ("*", Binop "*" (L _ _ (IntNum n)) ce1'
105 ("*", Binop "*" (L _ _ (IntNum n)) ce1'
105 , Binop "*" (L _ _ (IntNum m)) ce2') ->
106 , Binop "*" (L _ _ (IntNum m)) ce2') ->
106− binop "*" (notLocated $ IntNum (n*m)) (notLocated $ Binop "*" ce1' ce2')
107+ binop "*" (none $ IntNum (n*m)) (none $ Binop "*" ce1' ce2')
108 ("-", _, IntNum 0) -> e1
109 ("-", _, IntNum 0) -> e1
109 ("/", _, IntNum 1) -> e1
110 ("/", _, IntNum 1) -> e1
110 ("div", _, IntNum 1) -> e1
111 ("div", _, IntNum 1) -> e1
112− (_, Boolean n, Boolean m) -> case op of "&&" -> Boolean $ n && m
113+ (_, Literal (Boolean n), Literal (Boolean m)) ->
113− "||" -> Boolean $ n || m
114+ case op of
115+ "&&" -> bool $ n && m
116+ "||" -> bool $ n || m
114− _ -> Binop op ce1 ce2
117+ _ -> Binop op ce1 ce2
116− ("&&", Boolean True, _) -> e2
119+ ("&&", Literal (Boolean True), _) -> e2
117− ("&&", Boolean False, _) -> Boolean False
120+ ("&&", Literal (Boolean False), _) -> bool False
118− ("||", Boolean True, _) -> Boolean True
121+ ("||", Literal (Boolean True), _) -> bool True
119− ("||", Boolean False, _) -> e2
122+ ("||", Literal (Boolean False), _) -> e2
121 ("::", _, _) -> let (L _ _ e) = cons ce1 ce2 in e
124 ("::", _, _) -> let (L _ _ e) = cons ce1 ce2 in e
123− ("++", Str s1, Str s2) -> Str $ s1 ++ s2
126+ ("++", Literal (Str s1), Literal (Str s2)) -> str $ s1 ++ s2
124− ("++", Str s1, Binop "++" (L _ _ (Str s2)) ce) ->
127+ ("++", Literal (Str s1), Binop "++" (L _ _ (Literal (Str s2))) ce) ->
125− Binop "++" (c1 $ Str $ s1 ++ s2) ce
128+ Binop "++" (c1 . str $ s1 ++ s2) ce
126− ("++", Binop "++" e (L _ _ (Str s1)), Str s2) ->
129+ ("++", Binop "++" e (L _ _ (Literal (Str s1))), Literal (Str s2)) ->
127− Binop "++" e (c1 $ Str $ s1 ++ s2)
130+ Binop "++" e (c1 . str $ s1 ++ s2)
129 ("++", Data "Nil" [], _) -> e2
132 ("++", Data "Nil" [], _) -> e2
130 ("++", _, Data "Nil" []) -> e1
133 ("++", _, Data "Nil" []) -> e1
131− ("++", Data "Cons" [h,t], _) -> Data "Cons" [h, notLocated $ binop "++" t ce2]
134+ ("++", Data "Cons" [h,t], _) -> Data "Cons" [h, none $ binop "++" t ce2]
133 ("|>", _, _) -> App ce2 ce1
136 ("|>", _, _) -> App ce2 ce1
134 ("<|", _, _) -> App ce1 ce2
137 ("<|", _, _) -> App ce1 ce2
135 (".", _, _) ->
138 (".", _, _) ->
136− Lambda "x" (notLocated $
139+ Lambda "x" (none $
137− App ce1 (notLocated $ App ce2 (notLocated $ Var "x")))
140+ App ce1 (none $ App ce2 (none $ Var "x")))
139 _ | isAlpha (head op) || '_' == head op ->
142 _ | isAlpha (head op) || '_' == head op ->
140− App (notLocated $ App (notLocated $ Var op) ce1) ce2
143+ App (none $ App (none $ Var op) ce1) ce2
141− | otherwise -> Binop op ce1 ce2
144+ | otherwise -> Binop op ce1 ce2