namespace lambda (
using system
using list
def reset: lambda = lambda_comb "_reset"
/** The untry transform compiles out throw/catch statements by
* supplying the 'exception handler' as the first argument to all
* functions. It also introduces a reset combinator for try/catch
* blocks.
*
* - A definition gets one extra argument.
* .. F _ (def f = e) = def f = \x -> F x e
* - A any combinator is passed the handler.
* .. F x (X) = (X x)
* - A throw becomes an application of the exception handler to
* the supplied value.
* .. F x (throw e) = x (F x e)
* - A try/catch block introduces the reset combinator
* .. F x (try e0 catch e1) = R (\s. (\y. F y e0) (\z. s (F x e1 z)))
*/
def untry_transform: lambda_transform lambda =
abs = [ v, l -> lambda_abs (list.single v) (lambda_alts (list.single l)) ];
[ ef, lambda_def f l ->
x = lambda_fresh_name nop;
(_, l) = untry_transform x l;
l = abs x l;
l = lambda_def f l;
(ef, l)
| ef, lambda_comb t ->
l = lambda_app (lambda_comb t) ef;
(ef, l)
| ef, lambda_try l0 l1 ->
y = lambda_fresh_name nop;
s = lambda_fresh_name nop;
z = lambda_fresh_name nop;
(_, l0) = untry_transform y l0;
(_, l1) = untry_transform ef l1;
l0 = abs y l0;
l1 = abs z (lambda_app s (lambda_app l1 z));
l2 = abs s (lambda_app l0 l1);
l = lambda_app reset l2;
(ef, l)
| ef, lambda_throw l ->
(_, l) = untry_transform ef l;
l = lambda_app ef l;
(ef, l)
| ef, l ->
lambda_child untry_transform ef l ]
def untry: lambda -> lambda =
[ l -> (_, l) = untry_transform (lambda_comb "nop") l; l ]
)
No comments:
Post a Comment