Remove Elambda

Replace Elambda with a central repository of 
anonymous nodes. It made the AST unnecessarily 
complex.
This commit is contained in:
Cédric Pasteur 2010-09-06 14:03:47 +02:00
parent 2956e6feb4
commit ffff23b675
7 changed files with 71 additions and 50 deletions

View file

@ -327,19 +327,7 @@ and mk_node_call map call_context app loc name_list args =
let e = mk_exp (Eop(f, args)) in
[], [], [], [Aassgn(List.hd name_list, e) ]
| Minils.Enode f | Minils.Efun f ->
let o = mk_obj_call_from_context call_context (gen_obj_name f) in
let obj =
{ o_name = obj_call_name o; o_class = f;
o_params = app.Minils.a_params;
o_size = size_from_call_context call_context; o_loc = loc } in
let si =
(match app.Minils.a_op with
| Minils.Efun _ -> []
| Minils.Enode _ -> [reinit o]) in
[], si, [obj], [Acall (name_list, o, Mstep, args)]
| Minils.Elambda(inp, outp, locals, eq_list) ->
| Minils.Enode f when Itfusion.is_anon_node f ->
let add_input env vd =
Env.add vd.Minils.v_ident (mk_lhs (Lvar vd.Minils.v_ident)) env in
let build env vd a =
@ -358,12 +346,25 @@ and mk_node_call map call_context app loc name_list args =
act_list
in
let map = List.fold_left add_input map inp in
let map = List.fold_left2 build map outp name_list in
let map = List.fold_left add_input map locals in
let v, si, j, s = translate_eq_list map call_context eq_list in
let env = List.fold_left2 build Env.empty inp args in
v @ locals, si, j, subst_act_list env s
let nd = Itfusion.find_anon_node f in
let map = List.fold_left add_input map nd.Minils.n_input in
let map = List.fold_left2 build map nd.Minils.n_output name_list in
let map = List.fold_left add_input map nd.Minils.n_local in
let v, si, j, s = translate_eq_list map call_context nd.Minils.n_equs in
let env = List.fold_left2 build Env.empty nd.Minils.n_input args in
v @ nd.Minils.n_local, si, j, subst_act_list env s
| Minils.Enode f | Minils.Efun f ->
let o = mk_obj_call_from_context call_context (gen_obj_name f) in
let obj =
{ o_name = obj_call_name o; o_class = f;
o_params = app.Minils.a_params;
o_size = size_from_call_context call_context; o_loc = loc } in
let si =
(match app.Minils.a_op with
| Minils.Efun _ -> []
| Minils.Enode _ -> [reinit o]) in
[], si, [obj], [Acall (name_list, o, Mstep, args)]
| _ -> assert false

View file

@ -88,8 +88,6 @@ and typing_op op args h e ck = match op, args with
| Econcat, [e1; e2] ->
let ct = skeleton ck e.e_ty
in (expect h (Ck ck) e1; expect h ct e2; ct)
| Elambda _, _ -> Format.eprintf "Elambda dans le cloking"; assert false;
and expect h expected_ty e =
let actual_ty = typing h e in

View file

@ -79,19 +79,17 @@ and op =
| Eselect_dyn (** arg1.[arg3...] default arg2 *)
| Eupdate (** [ arg1 with arg3..arg_n = arg2 ] *)
| Econcat (** arg1@@arg2 *)
| Elambda of var_dec list * var_dec list * var_dec list * eq list
(* inputs, outputs, locals, body *)
and pat =
type pat =
| Etuplepat of pat list
| Evarpat of var_ident
and eq = {
type eq = {
eq_lhs : pat;
eq_rhs : exp;
eq_loc : location }
and var_dec = {
type var_dec = {
v_ident : var_ident;
v_type : ty;
v_clock : ck;

View file

@ -137,10 +137,6 @@ and print_app ff (app, args) = match app.a_op, app.a_params, args with
print_exp e1 print_dyn_index idx print_exp e2
| Econcat, _,[e1; e2] ->
fprintf ff "@[<2>%a@ @@ %a@]" print_exp e1 print_exp e2
| Elambda(inp, outp, _, eq_list), _, e_list ->
fprintf ff "(%a -> %a with %a)@,%a"
print_vd_tuple inp print_vd_tuple outp
print_eqs eq_list print_exp_tuple e_list
and print_handler ff c =
fprintf ff "@[<2>%a@]" (print_couple print_longname print_exp "("" -> "")") c

View file

@ -6,6 +6,28 @@ open Mls_mapfold
open Minils
(* Iterator fusion *)
(* Functions to temporarily store anonymous nodes*)
let mk_fresh_node_name () =
longname (Idents.name (Idents.fresh "_n_"))
let anon_nodes = ref LongNameEnv.empty
let add_anon_node inputs outputs locals eqs =
let n = mk_fresh_node_name () in
let nd = mk_node ~input:inputs ~output:outputs ~local:locals
~eq:eqs (shortname n) in
anon_nodes := LongNameEnv.add n nd !anon_nodes;
n
let replace_anon_node n nd =
anon_nodes := LongNameEnv.add n nd !anon_nodes
let find_anon_node n =
LongNameEnv.find n !anon_nodes
let is_anon_node n =
LongNameEnv.mem n !anon_nodes
let are_equal n m =
let n = simplify NamesEnv.empty n in
let m = simplify NamesEnv.empty m in
@ -28,13 +50,17 @@ let vd_of_arg ad =
(** @return the lists of inputs and outputs (as var_dec) of
an app object. *)
let get_node_inp_outp app = match app.a_op with
| (Enode f | Efun f) when is_anon_node f ->
(* first check if it is an anonymous node *)
let nd = find_anon_node f in
nd.n_input, nd.n_output
| Enode f | Efun f ->
let { info = ty_desc } = find_value f in
let new_inp = List.map vd_of_arg ty_desc.node_outputs in
let new_outp = List.map vd_of_arg ty_desc.node_outputs in
new_inp, new_outp
| Elambda(inp, outp, _, _) ->
inp, outp
(* it is a regular node*)
let { info = ty_desc } = find_value f in
let new_inp = List.map vd_of_arg ty_desc.node_outputs in
let new_outp = List.map vd_of_arg ty_desc.node_outputs in
new_inp, new_outp
| _ -> assert false
(** Creates the equation to call the node [app].
@return the list of new inputs required by the call, the expression
@ -87,9 +113,8 @@ let edesc funs acc ed =
let _, outp = get_node_inp_outp f in
let eq = mk_equation (pat_of_vd_list outp) call in
(* create the lambda *)
let lambda = mk_app (Elambda(inp, outp, [],
eq::acc_eq_list)) in
Eiterator(Imap, lambda, n, args, r), acc
let anon = mk_app (Enode (add_anon_node inp outp [] (eq::acc_eq_list))) in
Eiterator(Imap, anon, n, args, r), acc
) else
ed, acc

View file

@ -191,12 +191,14 @@ let rec translate kind context e =
let context, e_list = translate_app kind context app.a_op e_list in
context, { e with e_desc = Eapp(app, e_list, r) }
| Eiterator (it, app, n, e_list, reset) ->
let app =
(match app.a_op with
| Elambda(inp, outp, [], eq_list) ->
let d_list, eq_list = translate_eq_list [] eq_list in
{ app with a_op = Elambda(inp, outp, d_list, eq_list) }
| _ -> app) in
(* normalize anonymous nodes *)
(match app.a_op with
| Enode f when Itfusion.is_anon_node f ->
let nd = Itfusion.find_anon_node f in
let d_list, eq_list = translate_eq_list nd.n_local nd.n_equs in
let nd = { nd with n_equs = eq_list; n_local = d_list } in
Itfusion.replace_anon_node f nd
| _ -> () );
(* Add an intermediate equation for each array lit argument. *)
let translate_iterator_arg_list context e_list =

View file

@ -78,11 +78,12 @@ let eqs funs () eq_list =
schedule eqs, ()
let edesc funs () = function
| Eiterator(it, ({ a_op = Elambda(inp, outp, locals, eq_list) } as app),
n, e_list, r) ->
let app = { app with a_op = Elambda(inp, outp,
locals, schedule eq_list) } in
Eiterator(it, app, n, e_list, r), ()
| Eiterator(it, ({ a_op = Enode f } as app),
n, e_list, r) when Itfusion.is_anon_node f ->
let nd = Itfusion.find_anon_node f in
let nd = { nd with n_equs = schedule nd.n_equs } in
Itfusion.replace_anon_node f nd;
Eiterator(it, app, n, e_list, r), ()
| _ -> raise Fallback
let program p =