-
Erwan Jahier authoredErwan Jahier authored
l2lAliasType.ml 3.56 KiB
(* Time-stamp: <modified the 18/12/2012 (at 10:10) by Erwan Jahier> *)
(**
Source 2 source transformation :
- toutes les expressions de type sans NOM
(donc uniquement des tableaux immédiats ?)
sont traquées et remplacées par un alias
*)
open Lic
let doit (inp : LicPrg.t) : LicPrg.t =
(* n.b. on fait un minumum d'effet de bord pour
pas avoir trop d'acummulateur ... *)
let atab = Hashtbl.create 10 in
let res = ref inp in
(** UTILE : nommage des alias d'array *)
let array_ident ty sz =
let tid = Lic.ident_of_type ty in
let sfx = Printf.sprintf "%s_%d" (snd tid) sz in
let id = LicPrg.fresh_type_id !res (fst tid) sfx in
id
in
(** UTILE : cherche/crée un alias de type *)
let rec alias_type te =
match te with
| Array_type_eff (ty, sz) -> (
let ty = alias_type ty in
let te = Array_type_eff (ty, sz) in
try
let ref_te = Hashtbl.find atab te in
(*
Verbose.printf "--> alias_type %s = %s ^ %d FOUND : %s\n"
(LicDump.string_of_type_eff te)
(LicDump.string_of_type_eff ty)
sz
(LicDump.string_of_type_eff ref_te);
*)
ref_te
with Not_found -> (
let id = array_ident ty sz in
let ref_te = Abstract_type_eff (id, te) in
res := LicPrg.add_type id ref_te !res;
Hashtbl.add atab te ref_te;
(*
Verbose.printf "--> alias_type %s = %s ^ %d NOT FOUND, gives: %s\n"
(LicDump.string_of_type_eff te)
(LicDump.string_of_type_eff ty)
sz
(LicDump.string_of_type_eff ref_te);
*)
ref_te
)
) | _ -> te
in
(** TRAITE LES TYPES *)
let do_type k te =
let te' = match te with
| Array_type_eff (tel, sz) ->
let tel' = alias_type tel in
Array_type_eff (tel', sz)
| Struct_type_eff (id, fields) ->
let do_field (id, (tf, co)) =
(id, (alias_type tf, co))
in
Struct_type_eff (id, List.map do_field fields)
| _ -> te
in
if (te = te') then ()
else
res := LicPrg.add_type k te' !res
in
LicPrg.iter_types do_type inp;
(** TRAITE LES CONSTANTES *)
let do_const k ec =
let ec' = match ec with
| Extern_const_eff (i, te) ->
let te' = alias_type te in
Extern_const_eff (i, te')
| Abstract_const_eff (i, te, c, b) ->
let te' = alias_type te in
Abstract_const_eff (i, te', c, b)
| Array_const_eff (cl, te) ->
let te' = alias_type te in
Array_const_eff (cl, te')
| Bool_const_eff _
| Int_const_eff _
| Real_const_eff _
| Enum_const_eff _
| Struct_const_eff _
| Tuple_const_eff _ -> ec
in
if (ec = ec') then ()
else
(* n.b. add=replace *)
res := LicPrg.add_const k ec' !res
in
LicPrg.iter_consts do_const inp ;
(** TRAITE LES NOEUDS *)
let do_node k en =
(* n.b. les Lic.type_ apparraissent uniquement dans les var infos *)
let do_var vi =
let ty = alias_type vi.var_type_eff in
{vi with var_type_eff = ty}
in
let en' = { en with
inlist_eff = (List.map do_var en.inlist_eff);
outlist_eff = (List.map do_var en.outlist_eff);
loclist_eff = (
match en.loclist_eff with
| Some vl -> Some (List.map do_var vl)
| None -> None
)
} in
(* on fait pas dans la dentelle, on remplace ... *)
res := LicPrg.add_node k en' !res
in
LicPrg.iter_nodes do_node inp;
!res