Mercurial > urweb
comparison src/reduce_local.sml @ 1062:3bc726a822fb
Shake bug fix; pattern reduction in ReduceLocal
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 08 Dec 2009 11:45:19 -0500 |
parents | dfe34fad749d |
children | b2311dfb3158 |
comparison
equal
deleted
inserted
replaced
1061:e8a35d710ab9 | 1062:3bc726a822fb |
---|---|
31 | 31 |
32 open Core | 32 open Core |
33 | 33 |
34 structure IM = IntBinaryMap | 34 structure IM = IntBinaryMap |
35 | 35 |
36 fun multiLiftExpInExp n e = | |
37 if n = 0 then | |
38 e | |
39 else | |
40 multiLiftExpInExp (n - 1) (CoreEnv.liftExpInExp 0 e) | |
41 | |
36 datatype env_item = | 42 datatype env_item = |
37 Unknown | 43 Unknown |
38 | Known of exp | 44 | Known of exp |
39 | 45 |
40 | Lift of int | 46 | Lift of int |
41 | 47 |
42 type env = env_item list | 48 type env = env_item list |
43 | 49 |
44 val deKnown = List.filter (fn Known _ => false | 50 val deKnown = List.filter (fn Known _ => false |
45 | _ => true) | 51 | _ => true) |
52 | |
53 datatype result = Yes of env | No | Maybe | |
54 | |
55 fun match (env, p : pat, e : exp) = | |
56 let | |
57 val baseline = length env | |
58 | |
59 fun match (env, p, e) = | |
60 case (#1 p, #1 e) of | |
61 (PWild, _) => Yes env | |
62 | (PVar (x, t), _) => Yes (Known (multiLiftExpInExp (length env - baseline) e) :: env) | |
63 | |
64 | (PPrim p, EPrim p') => | |
65 if Prim.equal (p, p') then | |
66 Yes env | |
67 else | |
68 No | |
69 | |
70 | (PCon (_, PConVar n1, _, NONE), ECon (_, PConVar n2, _, NONE)) => | |
71 if n1 = n2 then | |
72 Yes env | |
73 else | |
74 No | |
75 | |
76 | (PCon (_, PConVar n1, _, SOME p), ECon (_, PConVar n2, _, SOME e)) => | |
77 if n1 = n2 then | |
78 match (env, p, e) | |
79 else | |
80 No | |
81 | |
82 | (PCon (_, PConFfi {mod = m1, con = con1, ...}, _, NONE), | |
83 ECon (_, PConFfi {mod = m2, con = con2, ...}, _, NONE)) => | |
84 if m1 = m2 andalso con1 = con2 then | |
85 Yes env | |
86 else | |
87 No | |
88 | |
89 | (PCon (_, PConFfi {mod = m1, con = con1, ...}, _, SOME ep), | |
90 ECon (_, PConFfi {mod = m2, con = con2, ...}, _, SOME e)) => | |
91 if m1 = m2 andalso con1 = con2 then | |
92 match (env, p, e) | |
93 else | |
94 No | |
95 | |
96 | (PRecord xps, ERecord xes) => | |
97 if List.exists (fn ((CName _, _), _, _) => false | |
98 | _ => true) xes then | |
99 Maybe | |
100 else | |
101 let | |
102 fun consider (xps, env) = | |
103 case xps of | |
104 [] => Yes env | |
105 | (x, p, _) :: rest => | |
106 case List.find (fn ((CName x', _), _, _) => x' = x | |
107 | _ => false) xes of | |
108 NONE => No | |
109 | SOME (_, e, _) => | |
110 case match (env, p, e) of | |
111 No => No | |
112 | Maybe => Maybe | |
113 | Yes env => consider (rest, env) | |
114 in | |
115 consider (xps, env) | |
116 end | |
117 | |
118 | _ => Maybe | |
119 in | |
120 match (env, p, e) | |
121 end | |
46 | 122 |
47 fun exp env (all as (e, loc)) = | 123 fun exp env (all as (e, loc)) = |
48 case e of | 124 case e of |
49 EPrim _ => all | 125 EPrim _ => all |
50 | ERel n => | 126 | ERel n => |
125 | PVar _ => 1 | 201 | PVar _ => 1 |
126 | PPrim _ => 0 | 202 | PPrim _ => 0 |
127 | PCon (_, _, _, NONE) => 0 | 203 | PCon (_, _, _, NONE) => 0 |
128 | PCon (_, _, _, SOME p) => patBinds p | 204 | PCon (_, _, _, SOME p) => patBinds p |
129 | PRecord xpts => foldl (fn ((_, p, _), n) => n + patBinds p) 0 xpts | 205 | PRecord xpts => foldl (fn ((_, p, _), n) => n + patBinds p) 0 xpts |
130 in | 206 |
131 (ECase (exp env e, | 207 fun push () = |
132 map (fn (p, e) => (p, | 208 (ECase (exp env e, |
133 exp (List.tabulate (patBinds p, fn _ => Unknown) @ env) e)) | 209 map (fn (p, e) => (p, |
134 pes, others), loc) | 210 exp (List.tabulate (patBinds p, |
211 fn _ => Unknown) @ env) e)) | |
212 pes, others), loc) | |
213 | |
214 fun search pes = | |
215 case pes of | |
216 [] => push () | |
217 | (p, body) :: pes => | |
218 case match (env, p, e) of | |
219 No => search pes | |
220 | Maybe => push () | |
221 | Yes env' => exp env' body | |
222 in | |
223 search pes | |
135 end | 224 end |
136 | 225 |
137 | EWrite e => (EWrite (exp env e), loc) | 226 | EWrite e => (EWrite (exp env e), loc) |
138 | EClosure (n, es) => (EClosure (n, map (exp env) es), loc) | 227 | EClosure (n, es) => (EClosure (n, map (exp env) es), loc) |
139 | 228 |