Mercurial > urweb
comparison src/reduce.sml @ 508:04053089878a
Start of new Reduce
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Wed, 26 Nov 2008 12:13:00 -0500 |
parents | ae03d09043c1 |
children | 140c68046598 |
comparison
equal
deleted
inserted
replaced
507:ca95f9e4d45f | 508:04053089878a |
---|---|
29 | 29 |
30 structure Reduce :> REDUCE = struct | 30 structure Reduce :> REDUCE = struct |
31 | 31 |
32 open Core | 32 open Core |
33 | 33 |
34 structure E = CoreEnv | 34 structure IM = IntBinaryMap |
35 structure U = CoreUtil | |
36 | 35 |
37 val liftConInCon = E.liftConInCon | 36 datatype env_item = |
38 val subConInCon = E.subConInCon | 37 UnknownC |
39 val liftConInExp = E.liftConInExp | 38 | KnownC of con |
40 val liftExpInExp = E.liftExpInExp | |
41 val subExpInExp = E.subExpInExp | |
42 val liftConInExp = E.liftConInExp | |
43 val subConInExp = E.subConInExp | |
44 | 39 |
45 fun bindC (env, b) = | 40 | UnknownE |
46 case b of | 41 | KnownE of exp |
47 U.Con.Rel (x, k) => E.pushCRel env x k | |
48 | U.Con.Named (x, n, k, co) => E.pushCNamed env x n k co | |
49 | 42 |
50 fun bind (env, b) = | 43 | Lift of int * int |
51 case b of | |
52 U.Decl.RelC (x, k) => E.pushCRel env x k | |
53 | U.Decl.NamedC (x, n, k, co) => E.pushCNamed env x n k co | |
54 | U.Decl.RelE (x, t) => E.pushERel env x t | |
55 | U.Decl.NamedE (x, n, t, eo, s) => E.pushENamed env x n t eo s | |
56 | 44 |
57 fun kind k = k | 45 type env = env_item list |
58 | 46 |
59 fun con env c = | 47 fun conAndExp (namedC, namedE) = |
60 case c of | 48 let |
61 CApp ((CApp ((CApp ((CFold ks, _), f), _), i), loc), (CRecord (k, xcs), _)) => | 49 fun con env (all as (c, loc)) = |
62 (case xcs of | 50 case c of |
63 [] => #1 i | 51 TFun (c1, c2) => (TFun (con env c1, con env c2), loc) |
64 | (n, v) :: rest => | 52 | TCFun (x, k, c2) => (TCFun (x, k, con (UnknownC :: env) c2), loc) |
65 #1 (reduceCon env (CApp ((CApp ((CApp (f, n), loc), v), loc), | 53 | TRecord c => (TRecord (con env c), loc) |
66 (CApp ((CApp ((CApp ((CFold ks, loc), f), loc), i), loc), | |
67 (CRecord (k, rest), loc)), loc)), loc))) | |
68 | CApp ((CAbs (_, _, c1), loc), c2) => | |
69 #1 (reduceCon env (subConInCon (0, c2) c1)) | |
70 | CNamed n => | |
71 (case E.lookupCNamed env n of | |
72 (_, _, SOME c') => #1 c' | |
73 | _ => c) | |
74 | CConcat ((CRecord (k, xcs1), loc), (CRecord (_, xcs2), _)) => CRecord (k, xcs1 @ xcs2) | |
75 | 54 |
76 | CProj ((CTuple cs, _), n) => #1 (List.nth (cs, n - 1)) | 55 | CRel n => |
56 let | |
57 fun find (n', env, lift) = | |
58 if n' = 0 then | |
59 case env of | |
60 UnknownC :: _ => (CRel (n + lift), loc) | |
61 | KnownC c :: _ => con (Lift (lift, 0) :: env) c | |
62 | _ => raise Fail "Reduce.con: CRel [1]" | |
63 else | |
64 case env of | |
65 UnknownC :: rest => find (n' - 1, rest, lift + 1) | |
66 | KnownC _ :: rest => find (n' - 1, rest, lift) | |
67 | UnknownE :: rest => find (n' - 1, rest, lift) | |
68 | KnownE _ :: rest => find (n' - 1, rest, lift) | |
69 | Lift (lift', _) :: rest => find (n' - 1, rest, lift + lift') | |
70 | [] => raise Fail "Reduce.con: CRel [2]" | |
71 in | |
72 find (n, env, 0) | |
73 end | |
74 | CNamed n => | |
75 (case IM.find (namedC, n) of | |
76 NONE => all | |
77 | SOME c => c) | |
78 | CFfi _ => all | |
79 | CApp (c1, c2) => | |
80 let | |
81 val c1 = con env c1 | |
82 val c2 = con env c2 | |
83 in | |
84 case #1 c1 of | |
85 CAbs (_, _, b) => | |
86 con (KnownC c2 :: env) b | |
77 | 87 |
78 | _ => c | 88 | CApp ((CApp (fold as (CFold _, _), f), _), i) => |
89 (case #1 c2 of | |
90 CRecord (_, []) => i | |
91 | CRecord (k, (x, c) :: rest) => | |
92 con env (CApp ((CApp ((CApp (f, x), loc), c), loc), | |
93 (CApp ((CApp ((CApp (fold, f), loc), i), loc), | |
94 (CRecord (k, rest), loc)), loc)), loc) | |
95 | _ => (CApp (c1, c2), loc)) | |
79 | 96 |
80 and reduceCon env = U.Con.mapB {kind = kind, con = con, bind = bindC} env | 97 | _ => (CApp (c1, c2), loc) |
98 end | |
99 | CAbs (x, k, b) => (CAbs (x, k, con (UnknownC :: env) b), loc) | |
81 | 100 |
82 fun exp env e = | 101 | CName _ => all |
83 let | |
84 (*val () = Print.prefaces "exp" [("e", CorePrint.p_exp env (e, ErrorMsg.dummySpan))]*) | |
85 | 102 |
86 val r = case e of | 103 | CRecord (k, xcs) => (CRecord (k, map (fn (x, c) => (con env x, con env c)) xcs), loc) |
87 ENamed n => | 104 | CConcat (c1, c2) => |
88 (case E.lookupENamed env n of | 105 let |
89 (_, _, SOME e', _) => #1 e' | 106 val c1 = con env c1 |
90 | _ => e) | 107 val c2 = con env c2 |
108 in | |
109 case (#1 c1, #1 c2) of | |
110 (CRecord (k, xcs1), CRecord (_, xcs2)) => | |
111 (CRecord (k, xcs1 @ xcs2), loc) | |
112 | _ => (CConcat (c1, c2), loc) | |
113 end | |
114 | CFold _ => all | |
91 | 115 |
92 | ECApp ((EApp ((EApp ((ECApp ((EFold ks, _), ran), _), f), _), i), _), (CRecord (k, xcs), loc)) => | 116 | CUnit => all |
93 (case xcs of | |
94 [] => #1 i | |
95 | (n, v) :: rest => | |
96 #1 (reduceExp env (EApp ((ECApp ((ECApp ((ECApp (f, n), loc), v), loc), (CRecord (k, rest), loc)), loc), | |
97 (ECApp ((EApp ((EApp ((ECApp ((EFold ks, loc), ran), loc), f), loc), i), loc), | |
98 (CRecord (k, rest), loc)), loc)), loc))) | |
99 | 117 |
100 | EApp ((EAbs (_, _, _, e1), loc), e2) => | 118 | CTuple cs => (CTuple (map (con env) cs), loc) |
101 #1 (reduceExp env (subExpInExp (0, e2) e1)) | 119 | CProj (c, n) => |
102 | ECApp ((ECAbs (_, _, e1), loc), c) => | 120 let |
103 #1 (reduceExp env (subConInExp (0, c) e1)) | 121 val c = con env c |
122 in | |
123 case #1 c of | |
124 CTuple cs => List.nth (cs, n - 1) | |
125 | _ => (CProj (c, n), loc) | |
126 end | |
104 | 127 |
105 | EField ((ERecord xes, _), (CName x, _), _) => | 128 fun exp env e = e |
106 (case List.find (fn ((CName x', _), _, _) => x' = x | |
107 | _ => false) xes of | |
108 SOME (_, e, _) => #1 e | |
109 | NONE => e) | |
110 | EConcat (r1 as (_, loc), (CRecord (k, xts1), _), r2, (CRecord (_, xts2), _)) => | |
111 let | |
112 fun fields (r, remaining, passed) = | |
113 case remaining of | |
114 [] => [] | |
115 | (x, t) :: rest => | |
116 (x, | |
117 (EField (r, x, {field = t, | |
118 rest = (CRecord (k, List.revAppend (passed, rest)), loc)}), loc), | |
119 t) :: fields (r, rest, (x, t) :: passed) | |
120 in | |
121 #1 (reduceExp env (ERecord (fields (r1, xts1, []) @ fields (r2, xts2, [])), loc)) | |
122 end | |
123 | ECut (r as (_, loc), _, {rest = (CRecord (k, xts), _), ...}) => | |
124 let | |
125 fun fields (remaining, passed) = | |
126 case remaining of | |
127 [] => [] | |
128 | (x, t) :: rest => | |
129 (x, | |
130 (EField (r, x, {field = t, | |
131 rest = (CRecord (k, List.revAppend (passed, rest)), loc)}), loc), | |
132 t) :: fields (rest, (x, t) :: passed) | |
133 in | |
134 #1 (reduceExp env (ERecord (fields (xts, [])), loc)) | |
135 end | |
136 | ECutMulti (r as (_, loc), _, {rest = (CRecord (k, xts), _), ...}) => | |
137 let | |
138 fun fields (remaining, passed) = | |
139 case remaining of | |
140 [] => [] | |
141 | (x, t) :: rest => | |
142 (x, | |
143 (EField (r, x, {field = t, | |
144 rest = (CRecord (k, List.revAppend (passed, rest)), loc)}), loc), | |
145 t) :: fields (rest, (x, t) :: passed) | |
146 in | |
147 #1 (reduceExp env (ERecord (fields (xts, [])), loc)) | |
148 end | |
149 | |
150 | _ => e | |
151 in | 129 in |
152 (*Print.prefaces "exp'" [("e", CorePrint.p_exp env (e, ErrorMsg.dummySpan)), | 130 {con = con, exp = exp} |
153 ("r", CorePrint.p_exp env (r, ErrorMsg.dummySpan))];*) | |
154 | |
155 r | |
156 end | 131 end |
157 | 132 |
158 and reduceExp env = U.Exp.mapB {kind = kind, con = con, exp = exp, bind = bind} env | 133 fun con namedC c = #con (conAndExp (namedC, IM.empty)) [] c |
134 fun exp (namedC, namedE) e = #exp (conAndExp (namedC, namedE)) [] e | |
159 | 135 |
160 fun decl env d = | 136 fun reduce file = |
161 case d of | 137 let |
162 DValRec [vi as (_, n, _, e, _)] => | 138 fun doDecl (d as (_, loc), st as (namedC, namedE)) = |
163 let | 139 case #1 d of |
164 fun kind _ = false | 140 DCon (x, n, k, c) => |
165 fun con _ = false | 141 let |
166 fun exp e = | 142 val c = con namedC c |
167 case e of | 143 in |
168 ENamed n' => n' = n | 144 ((DCon (x, n, k, c), loc), |
169 | _ => false | 145 (IM.insert (namedC, n, c), namedE)) |
170 in | 146 end |
171 if U.Exp.exists {kind = kind, con = con, exp = exp} e then | 147 | DDatatype (x, n, ps, cs) => |
172 d | 148 ((DDatatype (x, n, ps, map (fn (x, n, co) => (x, n, Option.map (con namedC) co)) cs), loc), |
173 else | 149 st) |
174 DVal vi | 150 | DVal (x, n, t, e, s) => |
175 end | 151 let |
176 | _ => d | 152 val t = con namedC t |
153 val e = exp (namedC, namedE) e | |
154 in | |
155 ((DVal (x, n, t, e, s), loc), | |
156 (namedC, IM.insert (namedE, n, e))) | |
157 end | |
158 | DValRec vis => | |
159 ((DValRec (map (fn (x, n, t, e, s) => (x, n, con namedC t, exp (namedC, namedE) e, s)) vis), loc), | |
160 st) | |
161 | DExport _ => (d, st) | |
162 | DTable (s, n, c, s') => ((DTable (s, n, con namedC c, s'), loc), st) | |
163 | DSequence _ => (d, st) | |
164 | DDatabase _ => (d, st) | |
165 | DCookie (s, n, c, s') => ((DCookie (s, n, con namedC c, s'), loc), st) | |
177 | 166 |
178 val reduce = U.File.mapB {kind = kind, con = con, exp = exp, decl = decl, bind = bind} E.empty | 167 val (file, _) = ListUtil.foldlMap doDecl (IM.empty, IM.empty) file |
168 in | |
169 file | |
170 end | |
179 | 171 |
180 end | 172 end |