Mercurial > urweb
comparison src/monoize.sml @ 179:3bbed533fbd2
Cases through monoize
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sun, 03 Aug 2008 10:48:36 -0400 |
parents | eb3f9913bf31 |
children | d11754ffe252 |
comparison
equal
deleted
inserted
replaced
178:eb3f9913bf31 | 179:3bbed533fbd2 |
---|---|
85 | L.CUnit => poly () | 85 | L.CUnit => poly () |
86 end | 86 end |
87 | 87 |
88 val dummyExp = (L'.EPrim (Prim.Int 0), E.dummySpan) | 88 val dummyExp = (L'.EPrim (Prim.Int 0), E.dummySpan) |
89 | 89 |
90 fun fooifyExp name env = | 90 structure IM = IntBinaryMap |
91 | |
92 datatype foo_kind = | |
93 Attr | |
94 | Url | |
95 | |
96 fun fk2s fk = | |
97 case fk of | |
98 Attr => "attr" | |
99 | Url => "url" | |
100 | |
101 structure Fm :> sig | |
102 type t | |
103 | |
104 val empty : int -> t | |
105 | |
106 val lookup : t -> foo_kind -> int -> (int -> t -> L'.decl * t) -> t * int | |
107 val enter : t -> t | |
108 val decls : t -> L'.decl list | |
109 end = struct | |
110 | |
111 structure M = BinaryMapFn(struct | |
112 type ord_key = foo_kind | |
113 fun compare x = | |
114 case x of | |
115 (Attr, Attr) => EQUAL | |
116 | (Attr, _) => LESS | |
117 | (_, Attr) => GREATER | |
118 | |
119 | (Url, Url) => EQUAL | |
120 end) | |
121 | |
122 type t = { | |
123 count : int, | |
124 map : int IM.map M.map, | |
125 decls : L'.decl list | |
126 } | |
127 | |
128 fun empty count = { | |
129 count = count, | |
130 map = M.empty, | |
131 decls = [] | |
132 } | |
133 | |
134 fun enter ({count, map, ...} : t) = {count = count, map = map, decls = []} | |
135 fun decls ({decls, ...} : t) = decls | |
136 | |
137 fun lookup (t as {count, map, decls}) k n thunk = | |
91 let | 138 let |
92 fun fooify (e, tAll as (t, loc)) = | 139 val im = Option.getOpt (M.find (map, k), IM.empty) |
140 in | |
141 case IM.find (im, n) of | |
142 NONE => | |
143 let | |
144 val n' = count | |
145 val (d, {count, map, decls}) = thunk count {count = count + 1, | |
146 map = M.insert (map, k, IM.insert (im, n, n')), | |
147 decls = decls} | |
148 in | |
149 ({count = count, | |
150 map = map, | |
151 decls = d :: decls}, n') | |
152 end | |
153 | SOME n' => (t, n') | |
154 end | |
155 | |
156 end | |
157 | |
158 | |
159 fun fooifyExp fk env = | |
160 let | |
161 fun fooify fm (e, tAll as (t, loc)) = | |
93 case #1 e of | 162 case #1 e of |
94 L'.EClosure (fnam, [(L'.ERecord [], _)]) => | 163 L'.EClosure (fnam, [(L'.ERecord [], _)]) => |
95 let | 164 let |
96 val (_, _, _, s) = Env.lookupENamed env fnam | 165 val (_, _, _, s) = Env.lookupENamed env fnam |
97 in | 166 in |
98 (L'.EPrim (Prim.String s), loc) | 167 ((L'.EPrim (Prim.String s), loc), fm) |
99 end | 168 end |
100 | L'.EClosure (fnam, args) => | 169 | L'.EClosure (fnam, args) => |
101 let | 170 let |
102 val (_, ft, _, s) = Env.lookupENamed env fnam | 171 val (_, ft, _, s) = Env.lookupENamed env fnam |
103 val ft = monoType env ft | 172 val ft = monoType env ft |
104 | 173 |
105 fun attrify (args, ft, e) = | 174 fun attrify (args, ft, e, fm) = |
106 case (args, ft) of | 175 case (args, ft) of |
107 ([], _) => e | 176 ([], _) => (e, fm) |
108 | (arg :: args, (L'.TFun (t, ft), _)) => | 177 | (arg :: args, (L'.TFun (t, ft), _)) => |
109 attrify (args, ft, | 178 let |
110 (L'.EStrcat (e, | 179 val (arg', fm) = fooify fm (arg, t) |
111 (L'.EStrcat ((L'.EPrim (Prim.String "/"), loc), | 180 in |
112 fooify (arg, t)), loc)), loc)) | 181 attrify (args, ft, |
182 (L'.EStrcat (e, | |
183 (L'.EStrcat ((L'.EPrim (Prim.String "/"), loc), | |
184 arg'), loc)), loc), | |
185 fm) | |
186 end | |
113 | _ => (E.errorAt loc "Type mismatch encoding attribute"; | 187 | _ => (E.errorAt loc "Type mismatch encoding attribute"; |
114 e) | 188 (e, fm)) |
115 in | 189 in |
116 attrify (args, ft, (L'.EPrim (Prim.String s), loc)) | 190 attrify (args, ft, (L'.EPrim (Prim.String s), loc), fm) |
117 end | 191 end |
118 | _ => | 192 | _ => |
119 case t of | 193 case t of |
120 L'.TFfi ("Basis", "string") => (L'.EFfiApp ("Basis", name ^ "ifyString", [e]), loc) | 194 L'.TFfi ("Basis", "string") => ((L'.EFfiApp ("Basis", fk2s fk ^ "ifyString", [e]), loc), fm) |
121 | L'.TFfi ("Basis", "int") => (L'.EFfiApp ("Basis", name ^ "ifyInt", [e]), loc) | 195 | L'.TFfi ("Basis", "int") => ((L'.EFfiApp ("Basis", fk2s fk ^ "ifyInt", [e]), loc), fm) |
122 | L'.TFfi ("Basis", "float") => (L'.EFfiApp ("Basis", name ^ "ifyFloat", [e]), loc) | 196 | L'.TFfi ("Basis", "float") => ((L'.EFfiApp ("Basis", fk2s fk ^ "ifyFloat", [e]), loc), fm) |
123 | L'.TRecord [] => (L'.EPrim (Prim.String ""), loc) | 197 | L'.TRecord [] => ((L'.EPrim (Prim.String ""), loc), fm) |
124 | 198 |
125 | L'.TDatatype _ => (L'.EPrim (Prim.String "A"), loc) | 199 | L'.TDatatype (i, _) => |
200 let | |
201 fun makeDecl n fm = | |
202 let | |
203 val (x, xncs) = Env.lookupDatatype env i | |
204 | |
205 val (branches, fm) = | |
206 ListUtil.foldlMap | |
207 (fn ((x, n, to), fm) => | |
208 case to of | |
209 NONE => | |
210 (((L'.PCon (L'.PConVar n, NONE), loc), | |
211 (L'.EPrim (Prim.String x), loc)), | |
212 fm) | |
213 | SOME t => | |
214 let | |
215 val (arg, fm) = fooify fm ((L'.ERel 0, loc), | |
216 monoType env t) | |
217 in | |
218 (((L'.PCon (L'.PConVar n, SOME (L'.PVar "a", loc)), loc), | |
219 (L'.EStrcat ((L'.EPrim (Prim.String (x ^ "/")), loc), | |
220 arg), loc)), | |
221 fm) | |
222 end) | |
223 fm xncs | |
224 | |
225 val dom = tAll | |
226 val ran = (L'.TFfi ("Basis", "string"), loc) | |
227 in | |
228 ((L'.DValRec [(fk2s fk ^ "ify_" ^ x, | |
229 n, | |
230 (L'.TFun (dom, ran), loc), | |
231 (L'.EAbs ("x", | |
232 dom, | |
233 ran, | |
234 (L'.ECase ((L'.ERel 0, loc), | |
235 branches, | |
236 ran), loc)), loc), | |
237 "")], loc), | |
238 fm) | |
239 end | |
240 | |
241 val (fm, n) = Fm.lookup fm fk i makeDecl | |
242 in | |
243 ((L'.EApp ((L'.ENamed n, loc), e), loc), fm) | |
244 end | |
126 | 245 |
127 | _ => (E.errorAt loc "Don't know how to encode attribute type"; | 246 | _ => (E.errorAt loc "Don't know how to encode attribute type"; |
128 Print.eprefaces' [("Type", MonoPrint.p_typ MonoEnv.empty tAll)]; | 247 Print.eprefaces' [("Type", MonoPrint.p_typ MonoEnv.empty tAll)]; |
129 dummyExp) | 248 (dummyExp, fm)) |
130 in | 249 in |
131 fooify | 250 fooify |
132 end | 251 end |
133 | 252 |
134 val attrifyExp = fooifyExp "attr" | 253 val attrifyExp = fooifyExp Attr |
135 val urlifyExp = fooifyExp "url" | 254 val urlifyExp = fooifyExp Url |
136 | 255 |
137 datatype 'a failable_search = | 256 datatype 'a failable_search = |
138 Found of 'a | 257 Found of 'a |
139 | NotFound | 258 | NotFound |
140 | Error | 259 | Error |
171 | L.PVar x => (L'.PVar x, loc) | 290 | L.PVar x => (L'.PVar x, loc) |
172 | L.PPrim p => (L'.PPrim p, loc) | 291 | L.PPrim p => (L'.PPrim p, loc) |
173 | L.PCon (pc, po) => (L'.PCon (monoPatCon pc, Option.map monoPat po), loc) | 292 | L.PCon (pc, po) => (L'.PCon (monoPatCon pc, Option.map monoPat po), loc) |
174 | L.PRecord xps => (L'.PRecord (map (fn (x, p) => (x, monoPat p)) xps), loc) | 293 | L.PRecord xps => (L'.PRecord (map (fn (x, p) => (x, monoPat p)) xps), loc) |
175 | 294 |
176 fun monoExp (env, st) (all as (e, loc)) = | 295 fun monoExp (env, st, fm) (all as (e, loc)) = |
177 let | 296 let |
178 fun poly () = | 297 fun poly () = |
179 (E.errorAt loc "Unsupported expression"; | 298 (E.errorAt loc "Unsupported expression"; |
180 Print.eprefaces' [("Expression", CorePrint.p_exp env all)]; | 299 Print.eprefaces' [("Expression", CorePrint.p_exp env all)]; |
181 dummyExp) | 300 (dummyExp, fm)) |
182 in | 301 in |
183 case e of | 302 case e of |
184 L.EPrim p => (L'.EPrim p, loc) | 303 L.EPrim p => ((L'.EPrim p, loc), fm) |
185 | L.ERel n => (L'.ERel n, loc) | 304 | L.ERel n => ((L'.ERel n, loc), fm) |
186 | L.ENamed n => (L'.ENamed n, loc) | 305 | L.ENamed n => ((L'.ENamed n, loc), fm) |
187 | L.ECon (n, eo) => (L'.ECon (n, Option.map (monoExp (env, st)) eo), loc) | 306 | L.ECon (n, eo) => |
188 | L.EFfi mx => (L'.EFfi mx, loc) | 307 let |
189 | L.EFfiApp (m, x, es) => (L'.EFfiApp (m, x, map (monoExp (env, st)) es), loc) | 308 val (eo, fm) = |
309 case eo of | |
310 NONE => (NONE, fm) | |
311 | SOME e => | |
312 let | |
313 val (e, fm) = monoExp (env, st, fm) e | |
314 in | |
315 (SOME e, fm) | |
316 end | |
317 in | |
318 ((L'.ECon (n, eo), loc), fm) | |
319 end | |
320 | L.EFfi mx => ((L'.EFfi mx, loc), fm) | |
321 | L.EFfiApp (m, x, es) => | |
322 let | |
323 val (es, fm) = ListUtil.foldlMap (fn (e, fm) => monoExp (env, st, fm) e) fm es | |
324 in | |
325 ((L'.EFfiApp (m, x, es), loc), fm) | |
326 end | |
190 | 327 |
191 | L.EApp ( | 328 | L.EApp ( |
192 (L.ECApp ( | 329 (L.ECApp ( |
193 (L.ECApp ((L.EFfi ("Basis", "cdata"), _), _), _), | 330 (L.ECApp ((L.EFfi ("Basis", "cdata"), _), _), _), |
194 _), _), | 331 _), _), |
195 se) => (L'.EFfiApp ("Basis", "htmlifyString", [monoExp (env, st) se]), loc) | 332 se) => |
333 let | |
334 val (se, fm) = monoExp (env, st, fm) se | |
335 in | |
336 ((L'.EFfiApp ("Basis", "htmlifyString", [se]), loc), fm) | |
337 end | |
338 | |
196 | L.EApp ( | 339 | L.EApp ( |
197 (L.EApp ( | 340 (L.EApp ( |
198 (L.ECApp ( | 341 (L.ECApp ( |
199 (L.ECApp ( | 342 (L.ECApp ( |
200 (L.ECApp ( | 343 (L.ECApp ( |
203 _), _), _), | 346 _), _), _), |
204 _), _), | 347 _), _), |
205 _), _), | 348 _), _), |
206 _), _), | 349 _), _), |
207 xml1), _), | 350 xml1), _), |
208 xml2) => (L'.EStrcat (monoExp (env, st) xml1, monoExp (env, st) xml2), loc) | 351 xml2) => |
352 let | |
353 val (xml1, fm) = monoExp (env, st, fm) xml1 | |
354 val (xml2, fm) = monoExp (env, st, fm) xml2 | |
355 in | |
356 ((L'.EStrcat (xml1, xml2), loc), fm) | |
357 end | |
209 | 358 |
210 | L.EApp ( | 359 | L.EApp ( |
211 (L.EApp ( | 360 (L.EApp ( |
212 (L.EApp ( | 361 (L.EApp ( |
213 (L.ECApp ( | 362 (L.ECApp ( |
244 Print.eprefaces' [("Expression", CorePrint.p_exp env tag)]; | 393 Print.eprefaces' [("Expression", CorePrint.p_exp env tag)]; |
245 ("", [])) | 394 ("", [])) |
246 | 395 |
247 val (tag, targs) = getTag tag | 396 val (tag, targs) = getTag tag |
248 | 397 |
249 val attrs = monoExp (env, st) attrs | 398 val (attrs, fm) = monoExp (env, st, fm) attrs |
250 | 399 |
251 fun tagStart tag = | 400 fun tagStart tag = |
252 case #1 attrs of | 401 case #1 attrs of |
253 L'.ERecord xes => | 402 L'.ERecord xes => |
254 let | 403 let |
256 | lowercaseFirst s = str (Char.toLower (String.sub (s, 0))) | 405 | lowercaseFirst s = str (Char.toLower (String.sub (s, 0))) |
257 ^ String.extract (s, 1, NONE) | 406 ^ String.extract (s, 1, NONE) |
258 | 407 |
259 val s = (L'.EPrim (Prim.String (String.concat ["<", tag])), loc) | 408 val s = (L'.EPrim (Prim.String (String.concat ["<", tag])), loc) |
260 in | 409 in |
261 foldl (fn ((x, e, t), s) => | 410 foldl (fn ((x, e, t), (s, fm)) => |
262 let | 411 let |
263 val xp = " " ^ lowercaseFirst x ^ "=\"" | 412 val xp = " " ^ lowercaseFirst x ^ "=\"" |
264 | 413 |
265 val fooify = | 414 val fooify = |
266 case x of | 415 case x of |
267 "Link" => urlifyExp | 416 "Link" => urlifyExp |
268 | "Action" => urlifyExp | 417 | "Action" => urlifyExp |
269 | _ => attrifyExp | 418 | _ => attrifyExp |
419 | |
420 val (e, fm) = fooify env fm (e, t) | |
270 in | 421 in |
271 (L'.EStrcat (s, | 422 ((L'.EStrcat (s, |
272 (L'.EStrcat ((L'.EPrim (Prim.String xp), loc), | 423 (L'.EStrcat ((L'.EPrim (Prim.String xp), loc), |
273 (L'.EStrcat (fooify env (e, t), | 424 (L'.EStrcat (e, |
274 (L'.EPrim (Prim.String "\""), | 425 (L'.EPrim (Prim.String "\""), |
275 loc)), | 426 loc)), |
276 loc)), | 427 loc)), |
277 loc)), loc) | 428 loc)), loc), |
429 fm) | |
278 end) | 430 end) |
279 s xes | 431 (s, fm) xes |
280 end | 432 end |
281 | _ => raise Fail "Non-record attributes!" | 433 | _ => raise Fail "Non-record attributes!" |
282 | 434 |
283 fun input typ = | 435 fun input typ = |
284 case targs of | 436 case targs of |
285 [_, (L.CName name, _)] => | 437 [_, (L.CName name, _)] => |
286 (L'.EStrcat (tagStart "input", | 438 let |
287 (L'.EPrim (Prim.String (" type=\"" ^ typ ^ "\" name=\"" ^ name ^ "\"/>")), | 439 val (ts, fm) = tagStart "input" |
288 loc)), loc) | 440 in |
441 ((L'.EStrcat (ts, | |
442 (L'.EPrim (Prim.String (" type=\"" ^ typ ^ "\" name=\"" ^ name ^ "\"/>")), | |
443 loc)), loc), fm) | |
444 end | |
289 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); | 445 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); |
290 raise Fail "No name passed to input tag") | 446 raise Fail "No name passed to input tag") |
291 | 447 |
292 fun normal (tag, extra) = | 448 fun normal (tag, extra) = |
293 let | 449 let |
294 val tagStart = tagStart tag | 450 val (tagStart, fm) = tagStart tag |
295 val tagStart = case extra of | 451 val tagStart = case extra of |
296 NONE => tagStart | 452 NONE => tagStart |
297 | SOME extra => (L'.EStrcat (tagStart, extra), loc) | 453 | SOME extra => (L'.EStrcat (tagStart, extra), loc) |
298 | 454 |
299 fun normal () = | 455 fun normal () = |
300 (L'.EStrcat ((L'.EStrcat (tagStart, (L'.EPrim (Prim.String ">"), loc)), loc), | 456 let |
301 (L'.EStrcat (monoExp (env, st) xml, | 457 val (xml, fm) = monoExp (env, st, fm) xml |
302 (L'.EPrim (Prim.String (String.concat ["</", tag, ">"])), | 458 in |
303 loc)), loc)), | 459 ((L'.EStrcat ((L'.EStrcat (tagStart, (L'.EPrim (Prim.String ">"), loc)), loc), |
304 loc) | 460 (L'.EStrcat (xml, |
461 (L'.EPrim (Prim.String (String.concat ["</", tag, ">"])), | |
462 loc)), loc)), | |
463 loc), | |
464 fm) | |
465 end | |
305 in | 466 in |
306 case xml of | 467 case xml of |
307 (L.EApp ((L.ECApp ( | 468 (L.EApp ((L.ECApp ( |
308 (L.ECApp ((L.EFfi ("Basis", "cdata"), _), | 469 (L.ECApp ((L.EFfi ("Basis", "cdata"), _), |
309 _), _), | 470 _), _), |
310 _), _), | 471 _), _), |
311 (L.EPrim (Prim.String s), _)), _) => | 472 (L.EPrim (Prim.String s), _)), _) => |
312 if CharVector.all Char.isSpace s then | 473 if CharVector.all Char.isSpace s then |
313 (L'.EStrcat (tagStart, (L'.EPrim (Prim.String "/>"), loc)), loc) | 474 ((L'.EStrcat (tagStart, (L'.EPrim (Prim.String "/>"), loc)), loc), fm) |
314 else | 475 else |
315 normal () | 476 normal () |
316 | _ => normal () | 477 | _ => normal () |
317 end | 478 end |
318 in | 479 in |
319 case tag of | 480 case tag of |
320 "submit" => (L'.EPrim (Prim.String "<input type=\"submit\"/>"), loc) | 481 "submit" => ((L'.EPrim (Prim.String "<input type=\"submit\"/>"), loc), fm) |
321 | 482 |
322 | "textbox" => | 483 | "textbox" => |
323 (case targs of | 484 (case targs of |
324 [_, (L.CName name, _)] => | 485 [_, (L.CName name, _)] => |
325 (L'.EStrcat (tagStart "input", | 486 let |
326 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\"/>")), | 487 val (ts, fm) = tagStart "input" |
327 loc)), loc) | 488 in |
489 ((L'.EStrcat (ts, | |
490 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\"/>")), | |
491 loc)), loc), fm) | |
492 end | |
328 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); | 493 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); |
329 raise Fail "No name passed to textarea tag")) | 494 raise Fail "No name passed to textarea tag")) |
330 | "password" => input "password" | 495 | "password" => input "password" |
331 | "ltextarea" => | 496 | "ltextarea" => |
332 (case targs of | 497 (case targs of |
333 [_, (L.CName name, _)] => | 498 [_, (L.CName name, _)] => |
334 (L'.EStrcat ((L'.EStrcat (tagStart "textarea", | 499 let |
335 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\">")), loc)), loc), | 500 val (ts, fm) = tagStart "textarea" |
336 (L'.EStrcat (monoExp (env, st) xml, | 501 val (xml, fm) = monoExp (env, st, fm) xml |
337 (L'.EPrim (Prim.String "</textarea>"), | 502 in |
338 loc)), loc)), | 503 ((L'.EStrcat ((L'.EStrcat (ts, |
339 loc) | 504 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\">")), loc)), loc), |
505 (L'.EStrcat (xml, | |
506 (L'.EPrim (Prim.String "</textarea>"), | |
507 loc)), loc)), | |
508 loc), fm) | |
509 end | |
340 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); | 510 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); |
341 raise Fail "No name passed to ltextarea tag")) | 511 raise Fail "No name passed to ltextarea tag")) |
342 | 512 |
343 | "radio" => | 513 | "radio" => |
344 (case targs of | 514 (case targs of |
345 [_, (L.CName name, _)] => | 515 [_, (L.CName name, _)] => |
346 monoExp (env, St.setRadioGroup (st, name)) xml | 516 monoExp (env, St.setRadioGroup (st, name), fm) xml |
347 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); | 517 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); |
348 raise Fail "No name passed to radio tag")) | 518 raise Fail "No name passed to radio tag")) |
349 | "radioOption" => | 519 | "radioOption" => |
350 (case St.radioGroup st of | 520 (case St.radioGroup st of |
351 NONE => raise Fail "No name for radioGroup" | 521 NONE => raise Fail "No name for radioGroup" |
354 SOME (L'.EPrim (Prim.String (" type=\"radio\" name=\"" ^ name ^ "\"")), loc))) | 524 SOME (L'.EPrim (Prim.String (" type=\"radio\" name=\"" ^ name ^ "\"")), loc))) |
355 | 525 |
356 | "lselect" => | 526 | "lselect" => |
357 (case targs of | 527 (case targs of |
358 [_, (L.CName name, _)] => | 528 [_, (L.CName name, _)] => |
359 (L'.EStrcat ((L'.EStrcat (tagStart "select", | 529 let |
360 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\">")), loc)), loc), | 530 val (ts, fm) = tagStart "select" |
361 (L'.EStrcat (monoExp (env, st) xml, | 531 val (xml, fm) = monoExp (env, st, fm) xml |
362 (L'.EPrim (Prim.String "</select>"), | 532 in |
363 loc)), loc)), | 533 ((L'.EStrcat ((L'.EStrcat (ts, |
364 loc) | 534 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\">")), loc)), loc), |
535 (L'.EStrcat (xml, | |
536 (L'.EPrim (Prim.String "</select>"), | |
537 loc)), loc)), | |
538 loc), | |
539 fm) | |
540 end | |
365 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); | 541 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); |
366 raise Fail "No name passed to lselect tag")) | 542 raise Fail "No name passed to lselect tag")) |
367 | 543 |
368 | "loption" => normal ("option", NONE) | 544 | "loption" => normal ("option", NONE) |
369 | 545 |
428 NotFound => raise Fail "No submit found" | 604 NotFound => raise Fail "No submit found" |
429 | Error => raise Fail "Not ready for multi-submit lforms yet" | 605 | Error => raise Fail "Not ready for multi-submit lforms yet" |
430 | Found et => et | 606 | Found et => et |
431 | 607 |
432 val actionT = monoType env actionT | 608 val actionT = monoType env actionT |
433 val action = monoExp (env, st) action | 609 val (action, fm) = monoExp (env, st, fm) action |
434 in | 610 val (action, fm) = urlifyExp env fm (action, actionT) |
435 (L'.EStrcat ((L'.EStrcat ((L'.EPrim (Prim.String "<form action=\""), loc), | 611 val (xml, fm) = monoExp (env, st, fm) xml |
436 (L'.EStrcat (urlifyExp env (action, actionT), | 612 in |
437 (L'.EPrim (Prim.String "\">"), loc)), loc)), loc), | 613 ((L'.EStrcat ((L'.EStrcat ((L'.EPrim (Prim.String "<form action=\""), loc), |
438 (L'.EStrcat (monoExp (env, st) xml, | 614 (L'.EStrcat (action, |
439 (L'.EPrim (Prim.String "</form>"), loc)), loc)), loc) | 615 (L'.EPrim (Prim.String "\">"), loc)), loc)), loc), |
616 (L'.EStrcat (xml, | |
617 (L'.EPrim (Prim.String "</form>"), loc)), loc)), loc), | |
618 fm) | |
440 end | 619 end |
441 | 620 |
442 | L.EApp ((L.ECApp ( | 621 | L.EApp ((L.ECApp ( |
443 (L.ECApp ( | 622 (L.ECApp ( |
444 (L.ECApp ( | 623 (L.ECApp ( |
445 (L.ECApp ( | 624 (L.ECApp ( |
446 (L.EFfi ("Basis", "useMore"), _), _), _), | 625 (L.EFfi ("Basis", "useMore"), _), _), _), |
447 _), _), | 626 _), _), |
448 _), _), | 627 _), _), |
449 _), _), | 628 _), _), |
450 xml) => monoExp (env, st) xml | 629 xml) => monoExp (env, st, fm) xml |
451 | 630 |
452 | 631 | L.EApp (e1, e2) => |
453 | L.EApp (e1, e2) => (L'.EApp (monoExp (env, st) e1, monoExp (env, st) e2), loc) | 632 let |
633 val (e1, fm) = monoExp (env, st, fm) e1 | |
634 val (e2, fm) = monoExp (env, st, fm) e2 | |
635 in | |
636 ((L'.EApp (e1, e2), loc), fm) | |
637 end | |
454 | L.EAbs (x, dom, ran, e) => | 638 | L.EAbs (x, dom, ran, e) => |
455 (L'.EAbs (x, monoType env dom, monoType env ran, monoExp (Env.pushERel env x dom, st) e), loc) | 639 let |
640 val (e, fm) = monoExp (Env.pushERel env x dom, st, fm) e | |
641 in | |
642 ((L'.EAbs (x, monoType env dom, monoType env ran, e), loc), fm) | |
643 end | |
456 | L.ECApp _ => poly () | 644 | L.ECApp _ => poly () |
457 | L.ECAbs _ => poly () | 645 | L.ECAbs _ => poly () |
458 | 646 |
459 | L.ERecord xes => (L'.ERecord (map (fn (x, e, t) => (monoName env x, | 647 | L.ERecord xes => |
460 monoExp (env, st) e, | 648 let |
461 monoType env t)) xes), loc) | 649 val (xes, fm) = ListUtil.foldlMap |
462 | L.EField (e, x, _) => (L'.EField (monoExp (env, st) e, monoName env x), loc) | 650 (fn ((x, e, t), fm) => |
651 let | |
652 val (e, fm) = monoExp (env, st, fm) e | |
653 in | |
654 ((monoName env x, | |
655 e, | |
656 monoType env t), fm) | |
657 end) fm xes | |
658 in | |
659 ((L'.ERecord xes, loc), fm) | |
660 end | |
661 | L.EField (e, x, _) => | |
662 let | |
663 val (e, fm) = monoExp (env, st, fm) e | |
664 in | |
665 ((L'.EField (e, monoName env x), loc), fm) | |
666 end | |
463 | L.ECut _ => poly () | 667 | L.ECut _ => poly () |
464 | L.EFold _ => poly () | 668 | L.EFold _ => poly () |
465 | 669 |
466 | L.ECase (e, pes, t) => (L'.ECase (monoExp (env, st) e, | 670 | L.ECase (e, pes, t) => |
467 map (fn (p, e) => (monoPat p, monoExp (env, st) e)) pes, | 671 let |
468 monoType env t), loc) | 672 val (e, fm) = monoExp (env, st, fm) e |
469 | 673 val (pes, fm) = ListUtil.foldlMap |
470 | L.EWrite e => (L'.EWrite (monoExp (env, st) e), loc) | 674 (fn ((p, e), fm) => |
471 | 675 let |
472 | L.EClosure (n, es) => (L'.EClosure (n, map (monoExp (env, st)) es), loc) | 676 val (e, fm) = monoExp (env, st, fm) e |
677 in | |
678 ((monoPat p, e), fm) | |
679 end) fm pes | |
680 in | |
681 ((L'.ECase (e, pes, monoType env t), loc), fm) | |
682 end | |
683 | |
684 | L.EWrite e => | |
685 let | |
686 val (e, fm) = monoExp (env, st, fm) e | |
687 in | |
688 ((L'.EWrite e, loc), fm) | |
689 end | |
690 | |
691 | L.EClosure (n, es) => | |
692 let | |
693 val (es, fm) = ListUtil.foldlMap (fn (e, fm) => | |
694 monoExp (env, st, fm) e) | |
695 fm es | |
696 in | |
697 ((L'.EClosure (n, es), loc), fm) | |
698 end | |
473 end | 699 end |
474 | 700 |
475 fun monoDecl env (all as (d, loc)) = | 701 fun monoDecl (env, fm) (all as (d, loc)) = |
476 let | 702 let |
477 fun poly () = | 703 fun poly () = |
478 (E.errorAt loc "Unsupported declaration"; | 704 (E.errorAt loc "Unsupported declaration"; |
479 Print.eprefaces' [("Declaration", CorePrint.p_decl env all)]; | 705 Print.eprefaces' [("Declaration", CorePrint.p_decl env all)]; |
480 NONE) | 706 NONE) |
483 L.DCon _ => NONE | 709 L.DCon _ => NONE |
484 | L.DDatatype (x, n, xncs) => | 710 | L.DDatatype (x, n, xncs) => |
485 let | 711 let |
486 val d = (L'.DDatatype (x, n, map (fn (x, n, to) => (x, n, Option.map (monoType env) to)) xncs), loc) | 712 val d = (L'.DDatatype (x, n, map (fn (x, n, to) => (x, n, Option.map (monoType env) to)) xncs), loc) |
487 in | 713 in |
488 SOME (Env.declBinds env all, d) | 714 SOME (Env.declBinds env all, fm, d) |
489 end | 715 end |
490 | L.DVal (x, n, t, e, s) => SOME (Env.pushENamed env x n t (SOME e) s, | 716 | L.DVal (x, n, t, e, s) => |
491 (L'.DVal (x, n, monoType env t, monoExp (env, St.empty) e, s), loc)) | 717 let |
718 val (e, fm) = monoExp (env, St.empty, fm) e | |
719 in | |
720 SOME (Env.pushENamed env x n t NONE s, | |
721 fm, | |
722 (L'.DVal (x, n, monoType env t, e, s), loc)) | |
723 end | |
492 | L.DValRec vis => | 724 | L.DValRec vis => |
493 let | 725 let |
494 val env = foldl (fn ((x, n, t, e, s), env) => Env.pushENamed env x n t NONE s) env vis | 726 val env = foldl (fn ((x, n, t, e, s), env) => Env.pushENamed env x n t NONE s) env vis |
727 | |
728 val (vis, fm) = ListUtil.foldlMap | |
729 (fn ((x, n, t, e, s), fm) => | |
730 let | |
731 val (e, fm) = monoExp (env, St.empty, fm) e | |
732 in | |
733 ((x, n, monoType env t, e, s), fm) | |
734 end) | |
735 fm vis | |
495 in | 736 in |
496 SOME (env, | 737 SOME (env, |
497 (L'.DValRec (map (fn (x, n, t, e, s) => (x, n, monoType env t, | 738 fm, |
498 monoExp (env, St.empty) e, s)) vis), loc)) | 739 (L'.DValRec vis, loc)) |
499 end | 740 end |
500 | L.DExport (ek, n) => | 741 | L.DExport (ek, n) => |
501 let | 742 let |
502 val (_, t, _, s) = Env.lookupENamed env n | 743 val (_, t, _, s) = Env.lookupENamed env n |
503 | 744 |
506 L.TFun (dom, ran) => dom :: unwind ran | 747 L.TFun (dom, ran) => dom :: unwind ran |
507 | _ => [] | 748 | _ => [] |
508 | 749 |
509 val ts = map (monoType env) (unwind t) | 750 val ts = map (monoType env) (unwind t) |
510 in | 751 in |
511 SOME (env, (L'.DExport (ek, s, n, ts), loc)) | 752 SOME (env, fm, (L'.DExport (ek, s, n, ts), loc)) |
512 end | 753 end |
513 end | 754 end |
514 | 755 |
515 fun monoize env ds = | 756 fun monoize env ds = |
516 let | 757 let |
517 val (_, ds) = List.foldl (fn (d, (env, ds)) => | 758 val (_, _, ds) = List.foldl (fn (d, (env, fm, ds)) => |
518 case monoDecl env d of | 759 case monoDecl (env, fm) d of |
519 NONE => (env, ds) | 760 NONE => (env, fm, ds) |
520 | SOME (env, d) => (env, d :: ds)) (env, []) ds | 761 | SOME (env, fm, d) => |
762 (env, | |
763 Fm.enter fm, | |
764 d :: Fm.decls fm @ ds)) | |
765 (env, Fm.empty (CoreUtil.File.maxName ds + 1), []) ds | |
521 in | 766 in |
522 rev ds | 767 rev ds |
523 end | 768 end |
524 | 769 |
525 end | 770 end |