Mercurial > urweb
comparison src/rpcify.sml @ 651:bab524996fca
Noisy demo
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 10 Mar 2009 17:29:03 -0400 |
parents | fcf0bd3d1667 |
children | b0c1a46b1f15 |
comparison
equal
deleted
inserted
replaced
650:fcf0bd3d1667 | 651:bab524996fca |
---|---|
186 | 186 |
187 val e' = EServerCall (n, args, trans2, ran) | 187 val e' = EServerCall (n, args, trans2, ran) |
188 in | 188 in |
189 (e', st) | 189 (e', st) |
190 end | 190 end |
191 | |
192 fun newCps (t1, t2, trans1, trans2, st) = | |
193 let | |
194 val loc = #2 trans1 | |
195 | |
196 val (n, args) = getApp (trans1, []) | |
197 | |
198 fun makeCall n' = | |
199 let | |
200 val e = (ENamed n', loc) | |
201 val e = (EApp (e, trans2), loc) | |
202 in | |
203 #1 (foldl (fn (arg, e) => (EApp (e, arg), loc)) e args) | |
204 end | |
205 in | |
206 case IM.find (#cpsed_range st, n) of | |
207 SOME kdom => | |
208 (case args of | |
209 [] => raise Fail "Rpcify: cps'd function lacks first argument" | |
210 | ke :: args => | |
211 let | |
212 val ke' = (EFfi ("Basis", "bind"), loc) | |
213 val ke' = (ECApp (ke', (CFfi ("Basis", "transaction"), loc)), loc) | |
214 val ke' = (ECApp (ke', kdom), loc) | |
215 val ke' = (ECApp (ke', t2), loc) | |
216 val ke' = (EApp (ke', (EFfi ("Basis", "transaction_monad"), loc)), loc) | |
217 val ke' = (EApp (ke', (EApp (E.liftExpInExp 0 ke, (ERel 0, loc)), loc)), loc) | |
218 val ke' = (EApp (ke', E.liftExpInExp 0 trans2), loc) | |
219 val ke' = (EAbs ("x", kdom, | |
220 (CApp ((CFfi ("Basis", "transaction"), loc), t2), loc), | |
221 ke'), loc) | |
222 | |
223 val e' = (ENamed n, loc) | |
224 val e' = (EApp (e', ke'), loc) | |
225 val e' = foldl (fn (arg, e') => (EApp (e', arg), loc)) e' args | |
226 val (e', st) = doExp (e', st) | |
227 in | |
228 (#1 e', st) | |
229 end) | |
230 | NONE => | |
231 case IM.find (#cpsed st, n) of | |
232 SOME n' => (makeCall n', st) | |
233 | NONE => | |
234 let | |
235 val (name, fargs, ran, e) = | |
236 case IM.find (tfuncs, n) of | |
237 NONE => (Print.prefaces "BAD" [("e", | |
238 CorePrint.p_exp CoreEnv.empty (e, loc))]; | |
239 raise Fail "Rpcify: Undetected transaction function [2]") | |
240 | SOME x => x | |
241 | |
242 val n' = #maxName st | |
243 | |
244 val st = {cpsed = IM.insert (#cpsed st, n, n'), | |
245 cpsed_range = IM.insert (#cpsed_range st, n', ran), | |
246 cps_decls = #cps_decls st, | |
247 exported = #exported st, | |
248 export_decls = #export_decls st, | |
249 maxName = n' + 1} | |
250 | |
251 val unit = (TRecord (CRecord ((KType, loc), []), loc), loc) | |
252 val body = (EFfi ("Basis", "bind"), loc) | |
253 val body = (ECApp (body, (CFfi ("Basis", "transaction"), loc)), loc) | |
254 val body = (ECApp (body, t1), loc) | |
255 val body = (ECApp (body, unit), loc) | |
256 val body = (EApp (body, (EFfi ("Basis", "transaction_monad"), loc)), loc) | |
257 val body = (EApp (body, e), loc) | |
258 val body = (EApp (body, (ERel (length args), loc)), loc) | |
259 val bt = (CApp ((CFfi ("Basis", "transaction"), loc), unit), loc) | |
260 val (body, bt) = foldr (fn ((x, t), (body, bt)) => | |
261 ((EAbs (x, t, bt, body), loc), | |
262 (TFun (t, bt), loc))) | |
263 (body, bt) fargs | |
264 val kt = (TFun (ran, (CApp ((CFfi ("Basis", "transaction"), loc), | |
265 unit), | |
266 loc)), loc) | |
267 val body = (EAbs ("k", kt, bt, body), loc) | |
268 val bt = (TFun (kt, bt), loc) | |
269 | |
270 val (body, st) = doExp (body, st) | |
271 | |
272 val vi = (name ^ "_cps", | |
273 n', | |
274 bt, | |
275 body, | |
276 "") | |
277 | |
278 val st = {cpsed = #cpsed st, | |
279 cpsed_range = #cpsed_range st, | |
280 cps_decls = vi :: #cps_decls st, | |
281 exported = #exported st, | |
282 export_decls = #export_decls st, | |
283 maxName = #maxName st} | |
284 in | |
285 (makeCall n', st) | |
286 end | |
287 end | |
288 | |
289 fun dummyK loc = | |
290 let | |
291 val unit = (TRecord (CRecord ((KType, loc), []), loc), loc) | |
292 | |
293 val k = (EFfi ("Basis", "return"), loc) | |
294 val k = (ECApp (k, (CFfi ("Basis", "transaction"), loc)), loc) | |
295 val k = (ECApp (k, unit), loc) | |
296 val k = (EApp (k, (EFfi ("Basis", "transaction_monad"), loc)), loc) | |
297 val k = (EApp (k, (ERecord [], loc)), loc) | |
298 in | |
299 (EAbs ("_", unit, unit, k), loc) | |
300 end | |
191 in | 301 in |
192 case e of | 302 case e of |
193 EApp ( | 303 EApp ( |
194 (EApp | 304 (EApp |
195 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _), t1), _), t2), _), | 305 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _), t1), _), t2), _), |
285 trans1), loc), | 395 trans1), loc), |
286 trans2) => | 396 trans2) => |
287 (case (serverSide (#cpsed_range st) trans1, clientSide (#cpsed_range st) trans1, | 397 (case (serverSide (#cpsed_range st) trans1, clientSide (#cpsed_range st) trans1, |
288 serverSide (#cpsed_range st) trans2, clientSide (#cpsed_range st) trans2) of | 398 serverSide (#cpsed_range st) trans2, clientSide (#cpsed_range st) trans2) of |
289 (true, false, _, true) => newRpc (trans1, trans2, st) | 399 (true, false, _, true) => newRpc (trans1, trans2, st) |
290 | (true, true, _, _) => | 400 | (_, true, true, false) => |
291 let | 401 (case #1 trans2 of |
292 val (n, args) = getApp (trans1, []) | 402 EAbs (x, dom, ran, trans2) => |
293 | 403 let |
294 fun makeCall n' = | 404 val (trans2, st) = newRpc (trans2, dummyK loc, st) |
295 let | 405 val trans2 = (EAbs (x, dom, ran, (trans2, loc)), loc) |
296 val e = (ENamed n', loc) | 406 |
297 val e = (EApp (e, trans2), loc) | 407 val e = (EFfi ("Basis", "bind"), loc) |
298 in | 408 val e = (ECApp (e, (CFfi ("Basis", "transaction"), loc)), loc) |
299 #1 (foldl (fn (arg, e) => (EApp (e, arg), loc)) e args) | 409 val e = (ECApp (e, t1), loc) |
300 end | 410 val e = (ECApp (e, t2), loc) |
301 in | 411 val e = (EApp (e, (EFfi ("Basis", "transaction_monad"), loc)), loc) |
302 case IM.find (#cpsed_range st, n) of | 412 val e = (EApp (e, trans1), loc) |
303 SOME kdom => | 413 val e = EApp (e, trans2) |
304 (case args of | 414 in |
305 [] => raise Fail "Rpcify: cps'd function lacks first argument" | 415 (e, st) |
306 | ke :: args => | 416 end |
307 let | 417 | _ => (e, st)) |
308 val ke' = (EFfi ("Basis", "bind"), loc) | 418 | (true, true, _, _) => newCps (t1, t2, trans1, trans2, st) |
309 val ke' = (ECApp (ke', (CFfi ("Basis", "transaction"), loc)), loc) | 419 |
310 val ke' = (ECApp (ke', kdom), loc) | |
311 val ke' = (ECApp (ke', t2), loc) | |
312 val ke' = (EApp (ke', (EFfi ("Basis", "transaction_monad"), loc)), loc) | |
313 val ke' = (EApp (ke', (EApp (E.liftExpInExp 0 ke, (ERel 0, loc)), loc)), loc) | |
314 val ke' = (EApp (ke', E.liftExpInExp 0 trans2), loc) | |
315 val ke' = (EAbs ("x", kdom, | |
316 (CApp ((CFfi ("Basis", "transaction"), loc), t2), loc), | |
317 ke'), loc) | |
318 | |
319 val e' = (ENamed n, loc) | |
320 val e' = (EApp (e', ke'), loc) | |
321 val e' = foldl (fn (arg, e') => (EApp (e', arg), loc)) e' args | |
322 val (e', st) = doExp (e', st) | |
323 in | |
324 (#1 e', st) | |
325 end) | |
326 | NONE => | |
327 case IM.find (#cpsed st, n) of | |
328 SOME n' => (makeCall n', st) | |
329 | NONE => | |
330 let | |
331 val (name, fargs, ran, e) = | |
332 case IM.find (tfuncs, n) of | |
333 NONE => (Print.prefaces "BAD" [("e", | |
334 CorePrint.p_exp CoreEnv.empty (e, loc))]; | |
335 raise Fail "Rpcify: Undetected transaction function [2]") | |
336 | SOME x => x | |
337 | |
338 val () = Print.prefaces "Double true" | |
339 [("trans1", CorePrint.p_exp CoreEnv.empty trans1), | |
340 ("e", CorePrint.p_exp CoreEnv.empty e)] | |
341 | |
342 val n' = #maxName st | |
343 | |
344 val st = {cpsed = IM.insert (#cpsed st, n, n'), | |
345 cpsed_range = IM.insert (#cpsed_range st, n', ran), | |
346 cps_decls = #cps_decls st, | |
347 exported = #exported st, | |
348 export_decls = #export_decls st, | |
349 maxName = n' + 1} | |
350 | |
351 val unit = (TRecord (CRecord ((KType, loc), []), loc), loc) | |
352 val body = (EFfi ("Basis", "bind"), loc) | |
353 val body = (ECApp (body, (CFfi ("Basis", "transaction"), loc)), loc) | |
354 val body = (ECApp (body, t1), loc) | |
355 val body = (ECApp (body, unit), loc) | |
356 val body = (EApp (body, (EFfi ("Basis", "transaction_monad"), loc)), loc) | |
357 val body = (EApp (body, e), loc) | |
358 val body = (EApp (body, (ERel (length args), loc)), loc) | |
359 val bt = (CApp ((CFfi ("Basis", "transaction"), loc), unit), loc) | |
360 val (body, bt) = foldr (fn ((x, t), (body, bt)) => | |
361 ((EAbs (x, t, bt, body), loc), | |
362 (TFun (t, bt), loc))) | |
363 (body, bt) fargs | |
364 val kt = (TFun (ran, (CApp ((CFfi ("Basis", "transaction"), loc), | |
365 unit), | |
366 loc)), loc) | |
367 val body = (EAbs ("k", kt, bt, body), loc) | |
368 val bt = (TFun (kt, bt), loc) | |
369 | |
370 val (body, st) = doExp (body, st) | |
371 | |
372 val vi = (name ^ "_cps", | |
373 n', | |
374 bt, | |
375 body, | |
376 "") | |
377 | |
378 val st = {cpsed = #cpsed st, | |
379 cpsed_range = #cpsed_range st, | |
380 cps_decls = vi :: #cps_decls st, | |
381 exported = #exported st, | |
382 export_decls = #export_decls st, | |
383 maxName = #maxName st} | |
384 in | |
385 (makeCall n', st) | |
386 end | |
387 end | |
388 | _ => (e, st)) | 420 | _ => (e, st)) |
389 | 421 |
390 | ERecord xes => | 422 | ERecord xes => |
391 let | 423 let |
392 val loc = case xes of | 424 val loc = case xes of |
399 andalso not (clientSide (#cpsed_range st) e) | 431 andalso not (clientSide (#cpsed_range st) e) |
400 in | 432 in |
401 if List.exists (fn ((CName x, _), e, _) => candidate (x, e) | 433 if List.exists (fn ((CName x, _), e, _) => candidate (x, e) |
402 | _ => false) xes then | 434 | _ => false) xes then |
403 let | 435 let |
404 val unit = (TRecord (CRecord ((KType, loc), []), loc), loc) | |
405 | |
406 val k = (EFfi ("Basis", "return"), loc) | |
407 val k = (ECApp (k, (CFfi ("Basis", "transaction"), loc)), loc) | |
408 val k = (ECApp (k, unit), loc) | |
409 val k = (EApp (k, (EFfi ("Basis", "transaction_monad"), loc)), loc) | |
410 val k = (EApp (k, (ERecord [], loc)), loc) | |
411 val k = (EAbs ("_", unit, unit, k), loc) | |
412 | |
413 val (xes, st) = ListUtil.foldlMap | 436 val (xes, st) = ListUtil.foldlMap |
414 (fn (y as (nm as (CName x, _), e, t), st) => | 437 (fn (y as (nm as (CName x, _), e, t), st) => |
415 if candidate (x, e) then | 438 if candidate (x, e) then |
416 let | 439 let |
417 val (n, args) = getApp (e, []) | 440 val (e, st) = newRpc (e, dummyK loc, st) |
418 | |
419 val (e, st) = newRpc (e, k, st) | |
420 in | 441 in |
421 ((nm, (e, loc), t), st) | 442 ((nm, (e, loc), t), st) |
422 end | 443 end |
423 else | 444 else |
424 (y, st) | 445 (y, st) |