2010-06-15 10:49:03 +02:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
|
|
|
(* Heptagon *)
|
|
|
|
(* *)
|
|
|
|
(* Author : Marc Pouzet *)
|
|
|
|
(* Organization : Demons, LRI, University of Paris-Sud, Orsay *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
|
|
|
|
2010-06-18 10:30:23 +02:00
|
|
|
(* Translation from Minils to Obc. *)
|
2010-06-15 10:49:03 +02:00
|
|
|
open Misc
|
2010-06-18 10:30:23 +02:00
|
|
|
open Names
|
2010-07-23 19:45:19 +02:00
|
|
|
open Idents
|
2011-04-14 18:06:54 +02:00
|
|
|
open Clocks
|
2010-06-18 10:30:23 +02:00
|
|
|
open Signature
|
2010-06-15 10:49:03 +02:00
|
|
|
open Obc
|
2011-02-14 15:21:57 +01:00
|
|
|
open Obc_utils
|
|
|
|
open Obc_mapfold
|
2010-07-13 14:03:39 +02:00
|
|
|
open Types
|
2010-06-15 10:49:03 +02:00
|
|
|
open Static
|
2010-08-03 22:38:42 +02:00
|
|
|
open Initial
|
|
|
|
|
2011-04-18 15:38:42 +02:00
|
|
|
|
|
|
|
let build_anon, find_anon =
|
|
|
|
let anon_nodes = ref QualEnv.empty in
|
|
|
|
|
|
|
|
let build_anon nodes =
|
|
|
|
let build env nd =
|
|
|
|
if Itfusion.is_anon_node nd.Minils.n_name then
|
|
|
|
QualEnv.add nd.Minils.n_name nd env
|
|
|
|
else
|
|
|
|
env
|
|
|
|
in
|
|
|
|
anon_nodes := List.fold_left build QualEnv.empty nodes
|
|
|
|
in
|
|
|
|
|
|
|
|
let find_anon qn =
|
|
|
|
QualEnv.find qn !anon_nodes
|
|
|
|
in
|
|
|
|
build_anon, find_anon
|
|
|
|
|
2011-04-14 11:53:39 +02:00
|
|
|
let var_from_name map x =
|
|
|
|
begin try
|
|
|
|
Env.find x map
|
|
|
|
with
|
|
|
|
_ -> assert false
|
|
|
|
end
|
2010-12-14 18:29:55 +01:00
|
|
|
|
2011-01-24 16:07:26 +01:00
|
|
|
let fresh_it () =
|
|
|
|
let id = Idents.gen_var "mls2obc" "i" in
|
|
|
|
id, mk_var_dec id Initial.tint
|
2010-06-30 17:30:24 +02:00
|
|
|
|
2011-01-20 23:05:18 +01:00
|
|
|
let gen_obj_ident n = Idents.gen_var "mls2obc" ((shortname n) ^ "_inst")
|
2011-04-14 15:14:41 +02:00
|
|
|
let fresh_for = fresh_for "mls2obc"
|
2011-04-14 18:06:54 +02:00
|
|
|
(*let copy_array = copy_array "mls2obc"*)
|
2010-06-26 16:53:25 +02:00
|
|
|
|
2011-02-07 14:24:17 +01:00
|
|
|
let op_from_string op = { qual = Pervasives; name = op; }
|
2010-06-26 16:53:25 +02:00
|
|
|
|
2011-01-24 16:07:26 +01:00
|
|
|
let rec pattern_of_idx_list p l =
|
2011-03-23 16:49:32 +01:00
|
|
|
let rec aux p l = match p.pat_ty, l with
|
2011-01-24 16:07:26 +01:00
|
|
|
| _, [] -> p
|
2011-03-23 16:49:32 +01:00
|
|
|
| Tarray (ty',_), idx :: l -> aux (mk_pattern ty' (Larray (p, idx))) l
|
2011-01-24 16:07:26 +01:00
|
|
|
| _ -> internal_error "mls2obc" 1
|
|
|
|
in
|
2011-03-23 16:49:32 +01:00
|
|
|
aux p l
|
2011-03-22 22:12:59 +01:00
|
|
|
|
|
|
|
let rec pattern_of_trunc_idx_list p l =
|
|
|
|
let mk_between idx se =
|
2011-03-23 16:49:32 +01:00
|
|
|
mk_exp_int (Eop (mk_pervasives "between", [idx; mk_exp se.se_ty (Econst se)]))
|
2011-03-22 22:12:59 +01:00
|
|
|
in
|
2011-03-23 16:49:32 +01:00
|
|
|
let rec aux p l = match p.pat_ty, l with
|
2011-03-22 22:12:59 +01:00
|
|
|
| _, [] -> p
|
2011-03-23 16:49:32 +01:00
|
|
|
| Tarray (ty', se), idx :: l -> aux (mk_pattern ty' (Larray (p, mk_between idx se))) l
|
2011-03-22 22:12:59 +01:00
|
|
|
| _ -> internal_error "mls2obc" 1
|
|
|
|
in
|
2011-03-23 16:49:32 +01:00
|
|
|
aux p l
|
2010-06-25 13:42:10 +02:00
|
|
|
|
|
|
|
let array_elt_of_exp idx e =
|
2011-01-24 16:07:26 +01:00
|
|
|
match e.e_desc, Modules.unalias_type e.e_ty with
|
|
|
|
| Econst ({ se_desc = Sarray_power (c, _) }), Tarray (ty,_) ->
|
|
|
|
mk_exp ty (Econst c)
|
|
|
|
| _, Tarray (ty,_) ->
|
|
|
|
mk_pattern_exp ty (Larray(pattern_of_exp e, mk_exp Initial.tint (Epattern idx)))
|
|
|
|
| _ -> internal_error "mls2obc" 2
|
2010-06-26 16:53:25 +02:00
|
|
|
|
2010-06-16 11:32:13 +02:00
|
|
|
(** Creates the expression that checks that the indices
|
|
|
|
in idx_list are in the bounds. If idx_list=[e1;..;ep]
|
|
|
|
and bounds = [n1;..;np], it returns
|
2011-04-14 11:17:12 +02:00
|
|
|
0<= e1 < n1 && .. && 0 <= ep < np *)
|
2010-06-16 11:32:13 +02:00
|
|
|
let rec bound_check_expr idx_list bounds =
|
2011-04-14 11:17:12 +02:00
|
|
|
let mk_comp idx n =
|
|
|
|
let e1 = mk_exp_bool (Eop (op_from_string "<",
|
|
|
|
[idx; mk_exp_int (Econst n)])) in
|
|
|
|
let e2 = mk_exp_bool (Eop (op_from_string "<=",
|
2011-04-14 18:06:54 +02:00
|
|
|
[mk_exp_int (Econst (mk_static_int 0)); idx])) in
|
2011-04-14 11:17:12 +02:00
|
|
|
mk_exp_bool (Eop (op_from_string "&", [e1;e2]))
|
|
|
|
in
|
2010-06-18 10:30:23 +02:00
|
|
|
match (idx_list, bounds) with
|
2011-04-14 11:17:12 +02:00
|
|
|
| [idx], [n] -> mk_comp idx n
|
2010-06-29 11:18:50 +02:00
|
|
|
| (idx :: idx_list, n :: bounds) ->
|
2011-04-14 11:17:12 +02:00
|
|
|
let e = mk_comp idx n in
|
|
|
|
mk_exp_bool (Eop (op_from_string "&",
|
|
|
|
[e; bound_check_expr idx_list bounds]))
|
2011-01-24 16:07:26 +01:00
|
|
|
| (_, _) -> internal_error "mls2obc" 3
|
2010-06-29 11:18:50 +02:00
|
|
|
|
2011-04-18 15:38:42 +02:00
|
|
|
let mk_plus_one e = match e.e_desc with
|
|
|
|
| Econst idx ->
|
|
|
|
let idx_plus_one = mk_static_int_op (mk_pervasives "+") [idx; mk_static_int 1] in
|
|
|
|
{ e with e_desc = Econst idx_plus_one }
|
|
|
|
| _ ->
|
|
|
|
let idx_plus_one = Eop (mk_pervasives "+", [e; mk_exp_const_int 1]) in
|
|
|
|
{ e with e_desc = idx_plus_one }
|
|
|
|
|
2011-04-14 15:14:41 +02:00
|
|
|
(** Creates the action list that copies [src] to [dest],
|
|
|
|
updating the value at index [idx_list] with the value [v]. *)
|
2011-04-14 18:06:54 +02:00
|
|
|
let rec update_array dest src idx_list v = match dest.pat_ty, idx_list with
|
2011-04-14 15:14:41 +02:00
|
|
|
| Tarray (t, n), idx::idx_list ->
|
|
|
|
(*Body of the copy loops*)
|
|
|
|
let copy i =
|
|
|
|
let src_i = mk_pattern_exp t (Larray (src, i)) in
|
|
|
|
let dest_i = mk_pattern t (Larray (dest, i)) in
|
2011-04-14 18:06:54 +02:00
|
|
|
[Aassgn(dest_i, src_i)]
|
2011-04-14 15:14:41 +02:00
|
|
|
in
|
|
|
|
(*Copy values < idx*)
|
2011-04-18 15:38:42 +02:00
|
|
|
let a_lower = fresh_for (mk_exp_const_int 0) idx copy in
|
2011-04-14 15:14:41 +02:00
|
|
|
(* Update the correct element*)
|
2011-04-18 15:38:42 +02:00
|
|
|
let src_idx = mk_pattern t (Larray (src, idx)) in
|
|
|
|
let dest_idx = mk_pattern t (Larray (dest, idx)) in
|
2011-04-14 18:06:54 +02:00
|
|
|
let a_update = update_array dest_idx src_idx idx_list v in
|
2011-04-14 15:14:41 +02:00
|
|
|
(*Copy values > idx*)
|
2011-04-18 15:38:42 +02:00
|
|
|
let idx_plus_one = mk_plus_one idx in
|
|
|
|
let a_upper = fresh_for idx_plus_one (mk_exp_static_int n) copy in
|
2011-04-14 18:06:54 +02:00
|
|
|
[a_lower] @ a_update @ [a_upper]
|
2011-04-14 15:14:41 +02:00
|
|
|
| _, _ ->
|
|
|
|
[Aassgn(dest, v)]
|
|
|
|
|
|
|
|
(** Creates the action list that copies [src] to [dest],
|
|
|
|
updating the value of field [f] with the value [v]. *)
|
|
|
|
let update_record dest src f v =
|
|
|
|
let assgn_act { f_name = l; f_type = ty } =
|
|
|
|
let dest_l = mk_pattern ty (Lfield(dest, l)) in
|
|
|
|
let src_l = mk_pattern_exp ty (Lfield(src, l)) in
|
|
|
|
if f = l then
|
|
|
|
Aassgn(dest_l, v)
|
|
|
|
else
|
|
|
|
Aassgn(dest_l, src_l)
|
|
|
|
in
|
2011-04-14 18:06:54 +02:00
|
|
|
let fields = match dest.pat_ty with
|
|
|
|
| Tid n -> Modules.find_struct n
|
|
|
|
| _ -> Misc.internal_error "mls2obc field of nonstruct" 1
|
|
|
|
in
|
|
|
|
List.map assgn_act fields
|
2011-04-14 15:14:41 +02:00
|
|
|
|
2011-04-14 11:53:39 +02:00
|
|
|
let rec control map ck s =
|
|
|
|
match ck with
|
|
|
|
| Cbase | Cvar { contents = Cindex _ } -> s
|
|
|
|
| Cvar { contents = Clink ck } -> control map ck s
|
|
|
|
| Con(ck, c, n) ->
|
|
|
|
let x = var_from_name map n in
|
|
|
|
control map ck (Acase(mk_exp x.pat_ty (Epattern x), [(c, mk_block [s])]))
|
|
|
|
|
2010-07-13 14:03:39 +02:00
|
|
|
let reinit o =
|
|
|
|
Acall ([], o, Mreset, [])
|
2010-06-29 11:18:50 +02:00
|
|
|
|
2010-06-27 17:24:31 +02:00
|
|
|
let rec translate_pat map = function
|
2011-04-14 11:53:39 +02:00
|
|
|
| Minils.Evarpat x -> [ var_from_name map x ]
|
2010-06-27 17:24:31 +02:00
|
|
|
| Minils.Etuplepat pat_list ->
|
2010-06-29 11:18:50 +02:00
|
|
|
List.fold_right (fun pat acc -> (translate_pat map pat) @ acc)
|
2010-06-27 17:24:31 +02:00
|
|
|
pat_list []
|
2010-06-29 11:18:50 +02:00
|
|
|
|
2010-11-23 17:13:33 +01:00
|
|
|
let translate_var_dec l =
|
2010-07-22 09:36:22 +02:00
|
|
|
let one_var { Minils.v_ident = x; Minils.v_type = t; v_loc = loc } =
|
|
|
|
mk_var_dec ~loc:loc x t
|
|
|
|
in
|
|
|
|
List.map one_var l
|
|
|
|
|
2011-04-14 11:17:12 +02:00
|
|
|
let rec translate_extvalue map w =
|
2011-04-14 18:06:54 +02:00
|
|
|
let desc = match w.Minils.w_desc with
|
|
|
|
| Minils.Wconst v -> Econst v
|
|
|
|
| Minils.Wvar x -> Epattern (var_from_name map x)
|
|
|
|
| Minils.Wfield (w1, f) ->
|
|
|
|
let e = translate_extvalue map w1 in
|
|
|
|
Epattern (mk_pattern w.Minils.w_ty (Lfield (pattern_of_exp e, f)))
|
|
|
|
| Minils.Wwhen (w1, c, x) ->
|
|
|
|
let e1 = translate_extvalue map w1 in
|
2011-04-14 11:17:12 +02:00
|
|
|
e1.e_desc
|
|
|
|
in
|
2011-04-14 18:06:54 +02:00
|
|
|
mk_exp w.Minils.w_ty desc
|
2011-04-14 11:17:12 +02:00
|
|
|
|
2010-06-15 10:49:03 +02:00
|
|
|
(* [translate e = c] *)
|
2010-11-05 16:03:39 +01:00
|
|
|
let rec translate map e =
|
2010-07-13 14:03:39 +02:00
|
|
|
let desc = match e.Minils.e_desc with
|
2011-04-14 11:17:12 +02:00
|
|
|
| Minils.Eextvalue w ->
|
2011-04-14 18:06:54 +02:00
|
|
|
let e = translate_extvalue map w in e.e_desc
|
2010-07-27 17:16:35 +02:00
|
|
|
| Minils.Eapp ({ Minils.a_op = Minils.Eequal }, e_list, _) ->
|
2011-04-14 11:17:12 +02:00
|
|
|
Eop (op_from_string "=", List.map (translate_extvalue map ) e_list)
|
|
|
|
| Minils.Eapp ({ Minils.a_op = Minils.Efun n }, e_list, _)
|
|
|
|
when Mls_utils.is_op n ->
|
|
|
|
Eop (n, List.map (translate_extvalue map ) e_list)
|
2010-06-29 11:18:50 +02:00
|
|
|
| Minils.Estruct f_e_list ->
|
2011-01-05 15:47:53 +01:00
|
|
|
let type_name = (match e.Minils.e_ty with
|
|
|
|
| Tid name -> name
|
|
|
|
| _ -> assert false) in
|
2011-04-14 11:17:12 +02:00
|
|
|
let f_e_list = List.map
|
|
|
|
(fun (f, e) -> (f, (translate_extvalue map e))) f_e_list in
|
2011-01-05 15:47:53 +01:00
|
|
|
Estruct (type_name, f_e_list)
|
|
|
|
(*Remaining array operators*)
|
2010-07-13 14:03:39 +02:00
|
|
|
| Minils.Eapp ({ Minils.a_op = Minils.Earray }, e_list, _) ->
|
2011-04-14 11:17:12 +02:00
|
|
|
Earray (List.map (translate_extvalue map ) e_list)
|
2010-07-13 14:03:39 +02:00
|
|
|
| Minils.Eapp ({ Minils.a_op = Minils.Eselect;
|
2011-01-05 15:47:53 +01:00
|
|
|
Minils.a_params = idx }, e_list, _) ->
|
2011-04-14 11:17:12 +02:00
|
|
|
let e = translate_extvalue map (assert_1 e_list) in
|
2011-01-24 16:07:26 +01:00
|
|
|
let idx_list = List.map (fun idx -> mk_exp tint (Econst idx)) idx in
|
|
|
|
Epattern (pattern_of_idx_list (pattern_of_exp e) idx_list)
|
2011-01-05 15:51:55 +01:00
|
|
|
(* Already treated cases when translating the [eq] *)
|
|
|
|
| Minils.Eiterator _ | Minils.Emerge _ | Minils.Efby _
|
2011-03-22 22:12:59 +01:00
|
|
|
| Minils.Eapp ({Minils.a_op=(Minils.Enode _|Minils.Efun _|Minils.Econcat
|
2011-04-14 18:06:54 +02:00
|
|
|
|Minils.Eupdate|Minils.Eselect_dyn
|
|
|
|
|Minils.Eselect_trunc|Minils.Eselect_slice
|
|
|
|
|Minils.Earray_fill|Minils.Efield_update
|
|
|
|
|Minils.Eifthenelse|Minils.Etuple)}, _, _) ->
|
2011-01-24 16:07:26 +01:00
|
|
|
internal_error "mls2obc" 5
|
2010-07-13 14:03:39 +02:00
|
|
|
in
|
2011-04-14 11:17:12 +02:00
|
|
|
mk_exp e.Minils.e_ty desc
|
2010-06-15 10:49:03 +02:00
|
|
|
|
2011-04-18 15:38:42 +02:00
|
|
|
and translate_act_extvalue map pat w =
|
|
|
|
match pat with
|
|
|
|
| Minils.Evarpat n ->
|
|
|
|
[Aassgn (var_from_name map n, translate_extvalue map w)]
|
|
|
|
| _ -> assert false
|
|
|
|
|
2010-08-04 15:36:20 +02:00
|
|
|
(* [translate pat act = si, d] *)
|
2010-11-05 16:03:39 +01:00
|
|
|
and translate_act map pat
|
2010-06-29 11:18:50 +02:00
|
|
|
({ Minils.e_desc = desc } as act) =
|
2010-08-04 15:36:20 +02:00
|
|
|
match pat, desc with
|
2011-01-20 23:05:18 +01:00
|
|
|
(* When Merge *)
|
2011-04-18 15:38:42 +02:00
|
|
|
| Minils.Evarpat x, Minils.Emerge (y, c_act_list) ->
|
|
|
|
let x = var_from_name map x in
|
|
|
|
let translate_c_extvalue (c, w) =
|
|
|
|
c, mk_block [Aassgn (x, translate_extvalue map w)]
|
|
|
|
in
|
|
|
|
let pattern = var_from_name map y in
|
2011-04-14 11:17:12 +02:00
|
|
|
[Acase (mk_exp pattern.pat_ty (Epattern pattern),
|
2011-04-18 15:38:42 +02:00
|
|
|
List.map translate_c_extvalue c_act_list)]
|
2011-01-20 23:05:18 +01:00
|
|
|
(* Array ops *)
|
2011-04-14 11:17:12 +02:00
|
|
|
| Minils.Evarpat x,
|
|
|
|
Minils.Eapp ({ Minils.a_op = Minils.Econcat }, [e1; e2], _) ->
|
2011-01-24 16:07:26 +01:00
|
|
|
let cpt1, cpt1d = fresh_it () in
|
|
|
|
let cpt2, cpt2d = fresh_it () in
|
2011-04-14 11:53:39 +02:00
|
|
|
let x = var_from_name map x in
|
2011-01-24 16:07:26 +01:00
|
|
|
let t = x.pat_ty in
|
2011-04-18 15:38:42 +02:00
|
|
|
(match e1.Minils.w_ty, e2.Minils.w_ty with
|
2011-01-24 16:07:26 +01:00
|
|
|
| Tarray (t1, n1), Tarray (t2, n2) ->
|
2011-04-14 11:17:12 +02:00
|
|
|
let e1 = translate_extvalue map e1 in
|
|
|
|
let e2 = translate_extvalue map e2 in
|
2010-08-04 15:36:20 +02:00
|
|
|
let a1 =
|
2011-04-18 15:38:42 +02:00
|
|
|
Afor (cpt1d, mk_exp_const_int 0, mk_exp_static_int n1,
|
2011-04-14 11:17:12 +02:00
|
|
|
mk_block [Aassgn (mk_pattern t1 (Larray (x, mk_evar_int cpt1)),
|
|
|
|
mk_pattern_exp t1 (Larray (pattern_of_exp e1,
|
|
|
|
mk_evar_int cpt1)))] ) in
|
|
|
|
let idx = mk_exp_int (Eop (op_from_string "+",
|
|
|
|
[ mk_exp_int (Econst n1); mk_evar_int cpt2])) in
|
|
|
|
let p2 = mk_pattern_exp t2 (Larray (pattern_of_exp e2, mk_evar_int cpt2)) in
|
2011-04-18 15:38:42 +02:00
|
|
|
let a2 = Afor (cpt2d, mk_exp_const_int 0, mk_exp_static_int n2,
|
2011-04-14 11:17:12 +02:00
|
|
|
mk_block [Aassgn (mk_pattern t2 (Larray (x, idx)), p2)] )
|
2010-08-04 15:36:20 +02:00
|
|
|
in
|
|
|
|
[a1; a2]
|
2011-04-14 11:17:12 +02:00
|
|
|
| _ -> assert false)
|
|
|
|
|
|
|
|
| Minils.Evarpat x,
|
|
|
|
Minils.Eapp ({ Minils.a_op = Minils.Earray_fill; Minils.a_params = [n] }, [e], _) ->
|
2011-01-24 16:07:26 +01:00
|
|
|
let cpt, cptd = fresh_it () in
|
2011-04-14 11:17:12 +02:00
|
|
|
let e = translate_extvalue map e in
|
2011-04-14 11:53:39 +02:00
|
|
|
let x = var_from_name map x in
|
2011-03-21 14:30:19 +01:00
|
|
|
let t = match x.pat_ty with
|
|
|
|
| Tarray (t,_) -> t
|
|
|
|
| _ -> Misc.internal_error "mls2obc select slice type" 5
|
|
|
|
in
|
2011-04-14 11:17:12 +02:00
|
|
|
let b = mk_block [Aassgn (mk_pattern t (Larray (x, mk_evar_int cpt)), e) ] in
|
2011-04-18 15:38:42 +02:00
|
|
|
[ Afor (cptd, mk_exp_const_int 0, mk_exp_static_int n, b) ]
|
2011-04-14 11:17:12 +02:00
|
|
|
|
|
|
|
| Minils.Evarpat x,
|
|
|
|
Minils.Eapp ({ Minils.a_op = Minils.Eselect_slice;
|
|
|
|
Minils.a_params = [idx1; idx2] }, [e], _) ->
|
2011-01-24 16:07:26 +01:00
|
|
|
let cpt, cptd = fresh_it () in
|
2011-04-14 11:17:12 +02:00
|
|
|
let e = translate_extvalue map e in
|
2011-04-14 11:53:39 +02:00
|
|
|
let x = var_from_name map x in
|
2011-03-21 14:30:19 +01:00
|
|
|
let t = match x.pat_ty with
|
|
|
|
| Tarray (t,_) -> t
|
|
|
|
| _ -> Misc.internal_error "mls2obc select slice type" 5
|
|
|
|
in
|
2011-04-14 11:17:12 +02:00
|
|
|
let idx = mk_exp_int (Eop (op_from_string "+",
|
|
|
|
[mk_evar_int cpt; mk_exp_int (Econst idx1) ])) in
|
2010-09-13 11:23:39 +02:00
|
|
|
(* bound = (idx2 - idx1) + 1*)
|
|
|
|
let bound = mk_static_int_op (op_from_string "+")
|
2011-04-14 11:17:12 +02:00
|
|
|
[ mk_static_int 1; mk_static_int_op (op_from_string "-") [idx2;idx1] ] in
|
2011-04-18 15:38:42 +02:00
|
|
|
[ Afor (cptd, mk_exp_const_int 0, mk_exp_static_int bound,
|
2011-03-21 14:30:19 +01:00
|
|
|
mk_block [Aassgn (mk_pattern t (Larray (x, mk_evar_int cpt)),
|
|
|
|
mk_pattern_exp t (Larray (pattern_of_exp e, idx)))] ) ]
|
2011-04-14 11:17:12 +02:00
|
|
|
|
2011-01-20 23:05:18 +01:00
|
|
|
| Minils.Evarpat x, Minils.Eapp ({ Minils.a_op = Minils.Eselect_dyn }, e1::e2::idx, _) ->
|
2011-04-14 11:53:39 +02:00
|
|
|
let x = var_from_name map x in
|
2011-04-18 15:38:42 +02:00
|
|
|
let bounds = Mls_utils.bounds_list e1.Minils.w_ty in
|
2011-04-14 11:17:12 +02:00
|
|
|
let e1 = translate_extvalue map e1 in
|
|
|
|
let idx = List.map (translate_extvalue map) idx in
|
2011-01-24 16:07:26 +01:00
|
|
|
let p = pattern_of_idx_list (pattern_of_exp e1) idx in
|
|
|
|
let true_act = Aassgn (x, mk_exp p.pat_ty (Epattern p)) in
|
2011-04-14 11:17:12 +02:00
|
|
|
let false_act = Aassgn (x, translate_extvalue map e2) in
|
2010-09-13 11:23:39 +02:00
|
|
|
let cond = bound_check_expr idx bounds in
|
2011-04-18 15:38:42 +02:00
|
|
|
[ mk_ifthenelse cond [true_act] [false_act] ]
|
2011-03-22 22:12:59 +01:00
|
|
|
|
|
|
|
| Minils.Evarpat x, Minils.Eapp ({ Minils.a_op = Minils.Eselect_trunc }, e1::idx, _) ->
|
2011-04-14 11:53:39 +02:00
|
|
|
let x = var_from_name map x in
|
2011-04-18 15:38:42 +02:00
|
|
|
let bounds = Mls_utils.bounds_list e1.Minils.w_ty in
|
2011-04-14 11:17:12 +02:00
|
|
|
let e1 = translate_extvalue map e1 in
|
|
|
|
let idx = List.map (translate_extvalue map) idx in
|
2011-03-22 22:12:59 +01:00
|
|
|
let p = pattern_of_trunc_idx_list (pattern_of_exp e1) idx in
|
|
|
|
[Aassgn (x, mk_exp p.pat_ty (Epattern p))]
|
|
|
|
|
Decade alpha1
On the road to beta is the new Minils AST, for now :
* Heptagon and Obc AST changes,
* Java code generation,
* Recursives Qualnames,
* Various bug fixes,
* Added partial application for iterators,
For instance:
... = map<<n>> (f<<se>>)((t1, t1'))(t2, t3)
is translated to:
for(int i =...)
... = f(t1, t1', t2[i], t3[i])
2011-01-05 15:51:55 +01:00
|
|
|
| Minils.Evarpat x, Minils.Eapp ({ Minils.a_op = Minils.Eupdate }, e1::e2::idx, _) ->
|
2011-04-14 11:53:39 +02:00
|
|
|
let x = var_from_name map x in
|
2011-04-18 15:38:42 +02:00
|
|
|
let bounds = Mls_utils.bounds_list e1.Minils.w_ty in
|
2011-04-14 11:17:12 +02:00
|
|
|
let idx = List.map (translate_extvalue map) idx in
|
2011-04-18 15:38:42 +02:00
|
|
|
let e1 = translate_extvalue map e1 in
|
|
|
|
let e2 = translate_extvalue map e2 in
|
2010-09-13 11:23:39 +02:00
|
|
|
let cond = bound_check_expr idx bounds in
|
2011-04-18 15:38:42 +02:00
|
|
|
let true_act = update_array x (pattern_of_exp e1) idx e2 in
|
2011-04-14 15:14:41 +02:00
|
|
|
let false_act = Aassgn (x, e1) in
|
2011-04-18 15:38:42 +02:00
|
|
|
[ mk_ifthenelse cond true_act [false_act] ]
|
2010-09-13 11:23:39 +02:00
|
|
|
|
|
|
|
| Minils.Evarpat x,
|
2011-04-14 11:17:12 +02:00
|
|
|
Minils.Eapp ({ Minils.a_op = Minils.Efield_update;
|
|
|
|
Minils.a_params = [{ se_desc = Sfield f }] }, [e1; e2], _) ->
|
2011-04-14 11:53:39 +02:00
|
|
|
let x = var_from_name map x in
|
2011-04-18 15:38:42 +02:00
|
|
|
let e1 = translate_extvalue map e1 in
|
|
|
|
let e2 = translate_extvalue map e2 in
|
|
|
|
update_record x (pattern_of_exp e1) f e2
|
2010-09-13 11:23:39 +02:00
|
|
|
|
2010-06-29 11:18:50 +02:00
|
|
|
| Minils.Evarpat n, _ ->
|
2011-04-14 11:53:39 +02:00
|
|
|
[Aassgn (var_from_name map n, translate map act)]
|
2010-09-13 10:20:24 +02:00
|
|
|
| _ ->
|
2011-01-05 15:47:53 +01:00
|
|
|
Format.eprintf "%a The pattern %a should be a simple var to be translated to obc.@."
|
|
|
|
Location.print_location act.Minils.e_loc Mls_printer.print_pat pat;
|
|
|
|
assert false
|
2010-06-15 10:49:03 +02:00
|
|
|
|
2011-01-20 23:05:18 +01:00
|
|
|
(** In an iteration, objects used are element of object arrays *)
|
|
|
|
type obj_array = { oa_index : Obc.pattern; oa_size : static_exp }
|
|
|
|
|
|
|
|
(** A [None] context is normal, otherwise, we are in an iteration *)
|
|
|
|
type call_context = obj_array option
|
|
|
|
|
|
|
|
let mk_obj_call_from_context c n = match c with
|
|
|
|
| None -> Oobj n
|
|
|
|
| Some oa -> Oarray (n, oa.oa_index)
|
2010-07-21 16:00:06 +02:00
|
|
|
|
2011-01-20 23:05:18 +01:00
|
|
|
let size_from_call_context c = match c with
|
|
|
|
| None -> None
|
|
|
|
| Some oa -> Some (oa.oa_size)
|
2010-07-21 16:00:06 +02:00
|
|
|
|
2011-01-20 23:05:18 +01:00
|
|
|
let empty_call_context = None
|
2010-07-21 16:00:06 +02:00
|
|
|
|
2011-02-14 15:21:57 +01:00
|
|
|
(** [si] the initialization actions used in the reset method,
|
2010-11-05 16:03:39 +01:00
|
|
|
[j] obj decs
|
2011-02-14 15:21:57 +01:00
|
|
|
[s] the actions used in the step method.
|
2010-11-05 16:03:39 +01:00
|
|
|
[v] var decs *)
|
2010-07-21 16:00:06 +02:00
|
|
|
let rec translate_eq map call_context { Minils.eq_lhs = pat; Minils.eq_rhs = e }
|
2010-07-22 09:36:22 +02:00
|
|
|
(v, si, j, s) =
|
2010-09-14 09:39:02 +02:00
|
|
|
let { Minils.e_desc = desc; Minils.e_ck = ck; Minils.e_loc = loc } = e in
|
2010-06-26 16:53:25 +02:00
|
|
|
match (pat, desc) with
|
2010-06-29 11:18:50 +02:00
|
|
|
| Minils.Evarpat n, Minils.Efby (opt_c, e) ->
|
2011-04-14 11:53:39 +02:00
|
|
|
let x = var_from_name map n in
|
2010-06-29 11:18:50 +02:00
|
|
|
let si = (match opt_c with
|
|
|
|
| None -> si
|
2011-01-24 16:07:26 +01:00
|
|
|
| Some c -> (Aassgn (x, mk_exp x.pat_ty (Econst c))) :: si) in
|
2011-04-14 11:53:39 +02:00
|
|
|
let action = Aassgn (var_from_name map n, translate_extvalue map e) in
|
2011-04-14 13:56:24 +02:00
|
|
|
v, si, j, (control map ck action) :: s
|
2011-04-14 11:17:12 +02:00
|
|
|
(* should be unnecessary
|
2010-07-13 14:03:39 +02:00
|
|
|
| Minils.Etuplepat p_list,
|
2010-07-13 14:42:46 +02:00
|
|
|
Minils.Eapp({ Minils.a_op = Minils.Etuple }, act_list, _) ->
|
2010-06-29 11:18:50 +02:00
|
|
|
List.fold_right2
|
|
|
|
(fun pat e ->
|
2010-07-21 16:00:06 +02:00
|
|
|
translate_eq map call_context
|
2010-06-29 11:18:50 +02:00
|
|
|
(Minils.mk_equation pat e))
|
2010-07-22 09:36:22 +02:00
|
|
|
p_list act_list (v, si, j, s)
|
2011-04-14 11:17:12 +02:00
|
|
|
*)
|
2010-07-13 14:42:46 +02:00
|
|
|
| pat, Minils.Eapp({ Minils.a_op = Minils.Eifthenelse }, [e1;e2;e3], _) ->
|
2011-04-14 11:17:12 +02:00
|
|
|
let cond = translate_extvalue map e1 in
|
2011-04-18 15:38:42 +02:00
|
|
|
let true_act = translate_act_extvalue map pat e2 in
|
|
|
|
let false_act = translate_act_extvalue map pat e3 in
|
|
|
|
let action = mk_ifthenelse cond true_act false_act in
|
2011-04-14 13:56:24 +02:00
|
|
|
v, si, j, (control map ck action) :: s
|
2010-07-13 14:42:46 +02:00
|
|
|
|
2011-01-24 16:07:26 +01:00
|
|
|
| pat, Minils.Eapp ({ Minils.a_op = Minils.Efun _ | Minils.Enode _ } as app, e_list, r) ->
|
2010-07-21 16:00:06 +02:00
|
|
|
let name_list = translate_pat map pat in
|
2011-04-14 11:17:12 +02:00
|
|
|
let c_list = List.map (translate_extvalue map) e_list in
|
|
|
|
let v', si', j', action = mk_node_call map call_context
|
|
|
|
app loc name_list c_list e.Minils.e_ty in
|
2011-04-14 13:56:24 +02:00
|
|
|
let action = List.map (control map ck) action in
|
2010-07-21 16:00:06 +02:00
|
|
|
let s = (match r, app.Minils.a_op with
|
|
|
|
| Some r, Minils.Enode _ ->
|
2010-07-27 17:55:45 +02:00
|
|
|
let ck = Clocks.Con (ck, Initial.ptrue, r) in
|
2011-04-14 13:56:24 +02:00
|
|
|
let ra = List.map (control map ck) si' in
|
2010-07-21 16:00:06 +02:00
|
|
|
ra @ action @ s
|
|
|
|
| _, _ -> action @ s) in
|
2010-07-22 09:36:22 +02:00
|
|
|
v' @ v, si'@si, j'@j, s
|
2010-07-21 16:00:06 +02:00
|
|
|
|
2011-03-21 17:22:03 +01:00
|
|
|
| pat, Minils.Eiterator (it, app, n, pe_list, e_list, reset) ->
|
2010-06-29 11:18:50 +02:00
|
|
|
let name_list = translate_pat map pat in
|
2011-04-14 11:17:12 +02:00
|
|
|
let p_list = List.map (translate_extvalue map) pe_list in
|
|
|
|
let c_list = List.map (translate_extvalue map) e_list in
|
2011-01-24 16:07:26 +01:00
|
|
|
let x, xd = fresh_it () in
|
2011-03-21 17:22:03 +01:00
|
|
|
let call_context =
|
|
|
|
Some { oa_index = mk_pattern_int (Lvar x); oa_size = n} in
|
2011-04-18 15:38:42 +02:00
|
|
|
let n = mk_exp_static_int n in
|
2010-07-21 16:00:06 +02:00
|
|
|
let si', j', action = translate_iterator map call_context it
|
2011-03-21 17:22:03 +01:00
|
|
|
name_list app loc n x xd p_list c_list e.Minils.e_ty in
|
2011-04-14 13:56:24 +02:00
|
|
|
let action = List.map (control map ck) action in
|
2010-06-29 11:18:50 +02:00
|
|
|
let s =
|
2010-07-13 14:03:39 +02:00
|
|
|
(match reset, app.Minils.a_op with
|
|
|
|
| Some r, Minils.Enode _ ->
|
2010-07-27 17:55:45 +02:00
|
|
|
let ck = Clocks.Con (ck, Initial.ptrue, r) in
|
2011-04-14 13:56:24 +02:00
|
|
|
let ra = List.map (control map ck) si' in
|
2010-07-21 16:00:06 +02:00
|
|
|
ra @ action @ s
|
2010-07-13 14:03:39 +02:00
|
|
|
| _, _ -> action @ s)
|
2010-07-22 09:36:22 +02:00
|
|
|
in (v, si' @ si, j' @ j, s)
|
2010-06-29 11:18:50 +02:00
|
|
|
|
|
|
|
| (pat, _) ->
|
2010-11-05 16:03:39 +01:00
|
|
|
let action = translate_act map pat e in
|
2011-04-14 13:56:24 +02:00
|
|
|
let action = List.map (control map ck) action in
|
2010-07-22 09:36:22 +02:00
|
|
|
v, si, j, action @ s
|
2010-07-13 14:03:39 +02:00
|
|
|
|
2010-07-21 16:00:06 +02:00
|
|
|
and translate_eq_list map call_context act_list =
|
2010-07-22 09:36:22 +02:00
|
|
|
List.fold_right (translate_eq map call_context) act_list ([], [], [], [])
|
2010-07-21 16:00:06 +02:00
|
|
|
|
2011-01-24 16:07:26 +01:00
|
|
|
and mk_node_call map call_context app loc name_list args ty =
|
2010-07-21 16:00:06 +02:00
|
|
|
match app.Minils.a_op with
|
2010-07-27 17:48:21 +02:00
|
|
|
| Minils.Efun f when Mls_utils.is_op f ->
|
2011-01-24 16:07:26 +01:00
|
|
|
let e = mk_exp ty (Eop(f, args)) in
|
|
|
|
[], [], [], [Aassgn(List.hd name_list, e)]
|
2010-07-27 17:48:21 +02:00
|
|
|
|
2010-09-09 00:35:06 +02:00
|
|
|
| Minils.Enode f when Itfusion.is_anon_node f ->
|
2011-03-21 17:22:03 +01:00
|
|
|
let add_input env vd = Env.add vd.Minils.v_ident
|
|
|
|
(mk_pattern vd.Minils.v_type (Lvar vd.Minils.v_ident)) env in
|
2011-01-20 23:05:18 +01:00
|
|
|
let build env vd a = Env.add vd.Minils.v_ident a env in
|
2010-07-22 09:36:22 +02:00
|
|
|
let subst_act_list env act_list =
|
2010-07-21 16:00:06 +02:00
|
|
|
let exp funs env e = match e.e_desc with
|
2011-01-24 16:07:26 +01:00
|
|
|
| Epattern { pat_desc = Lvar x } ->
|
2010-07-21 16:00:06 +02:00
|
|
|
let e =
|
|
|
|
(try Env.find x env
|
|
|
|
with Not_found -> e) in
|
|
|
|
e, env
|
|
|
|
| _ -> Obc_mapfold.exp funs env e
|
|
|
|
in
|
|
|
|
let funs = { Obc_mapfold.defaults with exp = exp } in
|
2010-07-22 09:36:22 +02:00
|
|
|
let act_list, _ = mapfold (Obc_mapfold.act_it funs) env act_list in
|
|
|
|
act_list
|
2010-07-21 16:00:06 +02:00
|
|
|
in
|
|
|
|
|
2011-04-18 15:38:42 +02:00
|
|
|
let nd = find_anon f in
|
2010-09-06 14:03:47 +02:00
|
|
|
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 ->
|
2011-01-20 23:05:18 +01:00
|
|
|
let o = mk_obj_call_from_context call_context (gen_obj_ident f) in
|
2010-09-06 14:03:47 +02:00
|
|
|
let obj =
|
2011-01-20 23:05:18 +01:00
|
|
|
{ o_ident = obj_ref_name o; o_class = f;
|
2010-09-06 14:03:47 +02:00
|
|
|
o_params = app.Minils.a_params;
|
|
|
|
o_size = size_from_call_context call_context; o_loc = loc } in
|
2011-01-05 15:51:55 +01:00
|
|
|
let si = (match app.Minils.a_op with
|
|
|
|
| Minils.Efun _ -> []
|
|
|
|
| Minils.Enode _ -> [reinit o]
|
|
|
|
| _ -> assert false) in
|
2011-03-09 00:02:30 +01:00
|
|
|
let s = [Acall (name_list, o, Mstep, args)] in
|
2011-01-05 15:51:55 +01:00
|
|
|
[], si, [obj], s
|
2010-07-21 16:00:06 +02:00
|
|
|
| _ -> assert false
|
|
|
|
|
2011-03-21 17:22:03 +01:00
|
|
|
and translate_iterator map call_context it name_list
|
|
|
|
app loc n x xd p_list c_list ty =
|
2011-01-24 16:07:26 +01:00
|
|
|
let unarray ty = match ty with
|
|
|
|
| Tarray (t,_) -> t
|
2011-03-21 17:22:03 +01:00
|
|
|
| _ ->
|
|
|
|
Format.eprintf "%a" Global_printer.print_type ty;
|
|
|
|
internal_error "mls2obc" 6
|
2011-01-24 16:07:26 +01:00
|
|
|
in
|
|
|
|
let array_of_output name_list ty_list =
|
2011-04-14 11:17:12 +02:00
|
|
|
List.map2 (fun l ty -> mk_pattern ty (Larray (l, mk_evar_int x))) name_list ty_list
|
2011-01-24 16:07:26 +01:00
|
|
|
in
|
2010-07-13 14:03:39 +02:00
|
|
|
let array_of_input c_list =
|
2011-03-21 17:22:03 +01:00
|
|
|
List.map (array_elt_of_exp (mk_pattern_int (Lvar x))) c_list in
|
2010-06-16 11:32:13 +02:00
|
|
|
match it with
|
2010-06-26 16:53:25 +02:00
|
|
|
| Minils.Imap ->
|
2010-07-13 14:03:39 +02:00
|
|
|
let c_list = array_of_input c_list in
|
2011-02-07 14:24:17 +01:00
|
|
|
let ty_list = List.map unarray (Types.unprod ty) in
|
2011-01-24 16:07:26 +01:00
|
|
|
let name_list = array_of_output name_list ty_list in
|
2011-02-07 14:24:17 +01:00
|
|
|
let node_out_ty = Types.prod ty_list in
|
2010-07-22 09:36:22 +02:00
|
|
|
let v, si, j, action = mk_node_call map call_context
|
2011-03-21 17:22:03 +01:00
|
|
|
app loc name_list (p_list@c_list) node_out_ty in
|
2010-11-05 16:03:39 +01:00
|
|
|
let v = translate_var_dec v in
|
2010-07-22 09:36:22 +02:00
|
|
|
let b = mk_block ~locals:v action in
|
2011-02-07 14:24:17 +01:00
|
|
|
let bi = mk_block si in
|
2011-04-18 15:38:42 +02:00
|
|
|
[Afor (xd, mk_exp_const_int 0, n, bi)], j,
|
|
|
|
[Afor (xd, mk_exp_const_int 0, n, b)]
|
2010-06-18 10:30:23 +02:00
|
|
|
|
2011-03-22 09:28:41 +01:00
|
|
|
| Minils.Imapi ->
|
|
|
|
let c_list = array_of_input c_list in
|
|
|
|
let ty_list = List.map unarray (Types.unprod ty) in
|
|
|
|
let name_list = array_of_output name_list ty_list in
|
|
|
|
let node_out_ty = Types.prod ty_list in
|
|
|
|
let v, si, j, action = mk_node_call map call_context
|
|
|
|
app loc name_list (p_list@c_list@[mk_evar_int x]) node_out_ty in
|
|
|
|
let v = translate_var_dec v in
|
|
|
|
let b = mk_block ~locals:v action in
|
|
|
|
let bi = mk_block si in
|
2011-04-18 15:38:42 +02:00
|
|
|
[Afor (xd, mk_exp_const_int 0, n, bi)], j,
|
|
|
|
[Afor (xd, mk_exp_const_int 0, n, b)]
|
2011-03-22 09:28:41 +01:00
|
|
|
|
2010-06-26 16:53:25 +02:00
|
|
|
| Minils.Imapfold ->
|
|
|
|
let (c_list, acc_in) = split_last c_list in
|
2010-07-13 14:03:39 +02:00
|
|
|
let c_list = array_of_input c_list in
|
2011-02-07 14:24:17 +01:00
|
|
|
let ty_list = Misc.map_butlast unarray (Types.unprod ty) in
|
|
|
|
let ty_name_list, ty_acc_out = Misc.split_last ty_list in
|
|
|
|
let (name_list, acc_out) = Misc.split_last name_list in
|
|
|
|
let name_list = array_of_output name_list ty_name_list in
|
|
|
|
let node_out_ty = Types.prod ty_list in
|
2011-03-21 17:22:03 +01:00
|
|
|
let v, si, j, action = mk_node_call map call_context app loc
|
|
|
|
(name_list @ [ acc_out ])
|
|
|
|
(p_list @ c_list @ [ mk_exp acc_out.pat_ty (Epattern acc_out) ])
|
|
|
|
node_out_ty
|
2011-01-24 16:07:26 +01:00
|
|
|
in
|
2010-11-05 16:03:39 +01:00
|
|
|
let v = translate_var_dec v in
|
2010-07-22 09:36:22 +02:00
|
|
|
let b = mk_block ~locals:v action in
|
2011-02-07 14:24:17 +01:00
|
|
|
let bi = mk_block si in
|
2011-04-18 15:38:42 +02:00
|
|
|
[Afor (xd, mk_exp_const_int 0, n, bi)], j,
|
|
|
|
[Aassgn (acc_out, acc_in); Afor (xd, mk_exp_const_int 0, n, b)]
|
2010-06-18 10:30:23 +02:00
|
|
|
|
2010-06-26 16:53:25 +02:00
|
|
|
| Minils.Ifold ->
|
|
|
|
let (c_list, acc_in) = split_last c_list in
|
2010-07-13 14:03:39 +02:00
|
|
|
let c_list = array_of_input c_list in
|
2010-06-26 16:53:25 +02:00
|
|
|
let acc_out = last_element name_list in
|
2011-01-24 16:07:26 +01:00
|
|
|
let v, si, j, action =
|
2011-03-21 17:22:03 +01:00
|
|
|
mk_node_call map call_context app loc name_list
|
|
|
|
(p_list @ c_list @ [ mk_exp acc_out.pat_ty (Epattern acc_out) ]) ty
|
2011-01-24 16:07:26 +01:00
|
|
|
in
|
2010-11-05 16:03:39 +01:00
|
|
|
let v = translate_var_dec v in
|
2010-07-22 09:36:22 +02:00
|
|
|
let b = mk_block ~locals:v action in
|
2011-02-07 14:24:17 +01:00
|
|
|
let bi = mk_block si in
|
2011-04-18 15:38:42 +02:00
|
|
|
[Afor (xd, mk_exp_const_int 0, n, bi)], j,
|
|
|
|
[ Aassgn (acc_out, acc_in); Afor (xd, mk_exp_const_int 0, n, b) ]
|
2010-06-26 16:53:25 +02:00
|
|
|
|
2010-07-26 09:33:22 +02:00
|
|
|
| Minils.Ifoldi ->
|
|
|
|
let (c_list, acc_in) = split_last c_list in
|
|
|
|
let c_list = array_of_input c_list in
|
|
|
|
let acc_out = last_element name_list in
|
2011-01-24 16:07:26 +01:00
|
|
|
let v, si, j, action = mk_node_call map call_context app loc name_list
|
2011-03-21 17:22:03 +01:00
|
|
|
(p_list @ c_list @ [ mk_evar_int x;
|
|
|
|
mk_exp acc_out.pat_ty (Epattern acc_out) ]) ty
|
2011-01-24 16:07:26 +01:00
|
|
|
in
|
2010-11-05 16:03:39 +01:00
|
|
|
let v = translate_var_dec v in
|
2010-07-26 09:33:22 +02:00
|
|
|
let b = mk_block ~locals:v action in
|
2011-02-07 14:24:17 +01:00
|
|
|
let bi = mk_block si in
|
2011-04-18 15:38:42 +02:00
|
|
|
[Afor (xd, mk_exp_const_int 0, n, bi)], j,
|
|
|
|
[ Aassgn (acc_out, acc_in); Afor (xd, mk_exp_const_int 0, n, b) ]
|
2010-07-26 09:33:22 +02:00
|
|
|
|
2010-06-15 10:49:03 +02:00
|
|
|
let remove m d_list =
|
2010-06-27 17:24:31 +02:00
|
|
|
List.filter (fun { Minils.v_ident = n } -> not (List.mem_assoc n m)) d_list
|
2010-06-26 16:53:25 +02:00
|
|
|
|
2011-01-24 16:07:26 +01:00
|
|
|
let translate_contract map mem_var_tys =
|
2010-06-18 10:30:23 +02:00
|
|
|
function
|
2010-07-16 09:58:56 +02:00
|
|
|
| None -> ([], [], [], [])
|
2010-06-26 16:53:25 +02:00
|
|
|
| Some
|
|
|
|
{
|
|
|
|
Minils.c_eq = eq_list;
|
|
|
|
Minils.c_local = d_list;
|
|
|
|
} ->
|
2011-01-24 16:07:26 +01:00
|
|
|
let (v, si, j, s_list) = translate_eq_list map empty_call_context eq_list in
|
2010-11-05 16:03:39 +01:00
|
|
|
let d_list = translate_var_dec (v @ d_list) in
|
2010-07-16 09:58:56 +02:00
|
|
|
let d_list = List.filter
|
2011-01-24 16:07:26 +01:00
|
|
|
(fun vd -> not (List.exists (fun (i,_) -> i = vd.v_ident) mem_var_tys)) d_list in
|
2010-07-16 09:58:56 +02:00
|
|
|
(si, j, s_list, d_list)
|
2010-06-26 16:53:25 +02:00
|
|
|
|
2010-06-15 10:49:03 +02:00
|
|
|
(** Returns a map, mapping variables names to the variables
|
2010-06-18 10:30:23 +02:00
|
|
|
where they will be stored. *)
|
2011-01-24 16:07:26 +01:00
|
|
|
let subst_map inputs outputs locals mem_tys =
|
2010-06-18 10:30:23 +02:00
|
|
|
(* Create a map that simply maps each var to itself *)
|
2011-01-24 16:07:26 +01:00
|
|
|
let map =
|
2010-07-13 14:03:39 +02:00
|
|
|
List.fold_left
|
2011-01-24 16:07:26 +01:00
|
|
|
(fun m { Minils.v_ident = x; Minils.v_type = ty } -> Env.add x (mk_pattern ty (Lvar x)) m)
|
2010-06-18 10:30:23 +02:00
|
|
|
Env.empty (inputs @ outputs @ locals)
|
2010-06-26 16:53:25 +02:00
|
|
|
in
|
2011-01-24 16:07:26 +01:00
|
|
|
List.fold_left (fun map (x, x_ty) -> Env.add x (mk_pattern x_ty (Lmem x)) map) map mem_tys
|
2010-06-26 16:53:25 +02:00
|
|
|
|
2010-07-13 14:03:39 +02:00
|
|
|
let translate_node
|
2011-03-21 14:30:19 +01:00
|
|
|
({ Minils.n_name = f; Minils.n_input = i_list; Minils.n_output = o_list;
|
|
|
|
Minils.n_local = d_list; Minils.n_equs = eq_list; Minils.n_stateful = stateful;
|
|
|
|
Minils.n_contract = contract; Minils.n_params = params; Minils.n_loc = loc;
|
2010-07-16 09:58:56 +02:00
|
|
|
} as n) =
|
2011-01-20 23:05:18 +01:00
|
|
|
Idents.enter_node f;
|
2011-01-24 16:07:26 +01:00
|
|
|
let mem_var_tys = Mls_utils.node_memory_vars n in
|
|
|
|
let subst_map = subst_map i_list o_list d_list mem_var_tys in
|
2011-01-20 23:05:18 +01:00
|
|
|
let (v, si, j, s_list) = translate_eq_list subst_map empty_call_context eq_list in
|
2011-01-24 16:07:26 +01:00
|
|
|
let (si', j', s_list', d_list') = translate_contract subst_map mem_var_tys contract in
|
2010-11-05 16:03:39 +01:00
|
|
|
let i_list = translate_var_dec i_list in
|
|
|
|
let o_list = translate_var_dec o_list in
|
|
|
|
let d_list = translate_var_dec (v @ d_list) in
|
2011-04-14 11:17:12 +02:00
|
|
|
let m, d_list = List.partition
|
|
|
|
(fun vd -> List.exists (fun (i,_) -> i = vd.v_ident) mem_var_tys) d_list in
|
2011-04-14 13:56:24 +02:00
|
|
|
let s = s_list @ s_list' in
|
2010-07-22 10:15:11 +02:00
|
|
|
let j = j' @ j in
|
2011-04-14 13:56:24 +02:00
|
|
|
let si = si @ si' in
|
2011-03-21 14:30:19 +01:00
|
|
|
let stepm = { m_name = Mstep; m_inputs = i_list; m_outputs = o_list;
|
|
|
|
m_body = mk_block ~locals:(d_list' @ d_list) s }
|
|
|
|
in
|
|
|
|
let resetm = { m_name = Mreset; m_inputs = []; m_outputs = []; m_body = mk_block si } in
|
|
|
|
if stateful
|
|
|
|
then { cd_name = f; cd_stateful = true; cd_mems = m; cd_params = params;
|
|
|
|
cd_objs = j; cd_methods = [stepm; resetm]; cd_loc = loc; }
|
2011-04-14 11:17:12 +02:00
|
|
|
else (
|
|
|
|
(* Functions won't have [Mreset] or memories,
|
|
|
|
they still have [params] and instances (of functions) *)
|
2011-03-21 14:30:19 +01:00
|
|
|
{ cd_name = f; cd_stateful = false; cd_mems = []; cd_params = params;
|
|
|
|
cd_objs = j; cd_methods = [stepm]; cd_loc = loc; }
|
|
|
|
)
|
2010-07-13 14:03:39 +02:00
|
|
|
|
|
|
|
let translate_ty_def { Minils.t_name = name; Minils.t_desc = tdesc;
|
|
|
|
Minils.t_loc = loc } =
|
2010-09-09 00:35:06 +02:00
|
|
|
let tdesc = match tdesc with
|
|
|
|
| Minils.Type_abs -> Type_abs
|
|
|
|
| Minils.Type_alias ln -> Type_alias ln
|
2010-09-13 13:44:26 +02:00
|
|
|
| Minils.Type_enum tag_name_list -> Type_enum tag_name_list
|
2011-03-21 14:30:19 +01:00
|
|
|
| Minils.Type_struct field_ty_list -> Type_struct field_ty_list
|
|
|
|
in
|
2010-09-13 09:03:15 +02:00
|
|
|
{ t_name = name; t_desc = tdesc; t_loc = loc }
|
2010-07-13 14:03:39 +02:00
|
|
|
|
|
|
|
let translate_const_def { Minils.c_name = name; Minils.c_value = se;
|
|
|
|
Minils.c_type = ty; Minils.c_loc = loc } =
|
2010-09-13 09:03:15 +02:00
|
|
|
{ c_name = name;
|
2010-07-13 14:03:39 +02:00
|
|
|
c_value = se;
|
|
|
|
c_type = ty;
|
|
|
|
c_loc = loc }
|
2010-06-26 16:53:25 +02:00
|
|
|
|
2011-04-14 11:17:12 +02:00
|
|
|
let program { Minils.p_modname = p_modname; Minils.p_opened = p_module_list;
|
|
|
|
Minils.p_types = p_type_list;
|
2011-03-21 14:30:19 +01:00
|
|
|
Minils.p_nodes = p_node_list; Minils.p_consts = p_const_list } =
|
2011-04-18 15:38:42 +02:00
|
|
|
build_anon p_node_list;
|
|
|
|
(* dont't translate anonymous nodes, they will be inlined *)
|
|
|
|
let p_nodes_list = List.filter
|
|
|
|
(fun nd -> not (Itfusion.is_anon_node nd.Minils.n_name)) p_node_list in
|
2011-03-21 14:30:19 +01:00
|
|
|
{ p_modname = p_modname;
|
|
|
|
p_opened = p_module_list;
|
|
|
|
p_types = List.map translate_ty_def p_type_list;
|
|
|
|
p_consts = List.map translate_const_def p_const_list;
|
2011-04-18 15:38:42 +02:00
|
|
|
p_classes = List.map translate_node p_nodes_list; }
|
2010-06-26 16:53:25 +02:00
|
|
|
|
2010-06-18 10:30:23 +02:00
|
|
|
|