Skip to content
Snippets Groups Projects
astRecognizePredef.ml 5.97 KiB
Newer Older
(* Time-stamp: <modified the 22/08/2017 (at 14:57) by Erwan Jahier> *)
let (get_predef : Lv6Id.idref -> AstPredef.op option) =
  let get_op () = (* XXX if a user node is named "plus", this does not work *)
      try Some (AstPredef.string_to_op (Lv6Id.to_string (Lv6Id.name_of_idref idref)))
      with Not_found -> None
    in
    match Lv6Id.pack_of_idref idref with
      | None -> None
(*         get_op () (* The Lustre package is used by default *)  *)
      | Some p -> if (Lv6Id.pack_name_to_string p) = "Lustre" then get_op () else None
open AstV6
open AstCore
open Lxm

let flag f x_flg = Lxm.flagit (f x_flg.it) x_flg.src

let flag2 f x_flg = Lxm.flagit (f x_flg) x_flg.src

let fopt f = function None -> None | Some x -> Some (f x)


(* just a tedious recursive traversal of the syntax tree, replacing idref
   that match predef op with the Predef constructor *)
(* exported *)
let rec (f : AstV6.t -> AstV6.t) = function
  | PRPackBody(sl,pb) -> PRPackBody(sl, r_packbody pb)
  | PRPack_or_models(sl,pml) -> PRPack_or_models(sl,List.map r_pack_or_model pml)

and r_pack_or_model = function   
  | NSPack(pi) -> NSPack(flag r_pack_info pi)
  | NSModel(mi) -> NSModel(flag r_model_info mi)

and r_pack_info pi = { pi with pa_def = r_pack_def pi.pa_def } 

and r_model_info mi = 
  { mi with 
    mo_needs = List.map (flag r_static_param) mi.mo_needs;
    mo_provides = r_item_info_flg_list mi.mo_provides;
    mo_body = r_packbody  mi.mo_body;
  }

and r_pack_def = function
  | PackGiven(pg) -> PackGiven(r_pack_given pg)
  | PackInstance(pi) -> PackInstance(r_pack_instance pi)

and r_pack_given pg = { 
  pg with
    pg_provides = r_item_info_flg_list pg.pg_provides;
    pg_body = r_packbody pg.pg_body;
}

and r_pack_instance pi = { pi with pi_args = List.map r_by_name_static_arg pi.pi_args }

and r_static_param sp = sp 

and r_by_name_static_arg (id,arg) = 
  let arg_it = 
    match arg.it with
	       | Some predef -> StaticArgNode (Predef_n (flagit predef arg.src))
      )
      | StaticArgConst(ve) -> StaticArgConst(r_val_exp ve)
      | StaticArgType(te) -> StaticArgType(te)
      | StaticArgNode(by_pos_op) -> StaticArgNode(r_by_pos_op (flagit by_pos_op arg.src))
	     | Some predef -> StaticArgNode (Predef_n (flagit predef arg.src))
    )
    | StaticArgConst(ve) -> StaticArgConst(r_val_exp ve)
    | StaticArgType(te) -> StaticArgType(te)
    | StaticArgNode(by_pos_op) -> StaticArgNode(r_by_pos_op (flagit by_pos_op arg.src))
  match arg.it with
    | CALL_n { src=lxm;it=(idref,sargs) } -> (
      match get_predef idref with
	     | None -> CALL_n { src=lxm;it= r_node_exp (idref,sargs) }
	     | Some op -> assert (sargs=[]); Predef_n (flagit op arg.src)
      match get_predef idref with
	     | None -> IDENT_n(idref)
	     | Some op -> Predef_n (flagit op arg.src)
    | ARRAY_ACCES_n(val_exp) -> ARRAY_ACCES_n(r_val_exp val_exp)
    | ARRAY_SLICE_n(slice_info) -> ARRAY_SLICE_n(r_slice_info slice_info)

and r_node_exp (idref, sargs) =
  (idref, List.map (flag2 r_static_arg) sargs)
and r_slice_info si = {
  si_first = r_val_exp si.si_first;
  si_last  = r_val_exp si.si_last;
  si_step  = fopt r_val_exp si.si_step;
}

and r_val_exp = function
  | CallByPos (by_pos_op, Oper vel) -> 
    CallByPos(flag2 r_by_pos_op by_pos_op, Oper (List.map r_val_exp vel))
  | CallByName(by_name_op, args) -> 
    CallByName(by_name_op, List.map (fun (id, ve) -> id, r_val_exp ve) args)
  | Merge_n (ec,cl) -> 
    let cl = List.map (fun (id,ve) ->  (id, r_val_exp ve)) cl in
    Merge_n (ec,cl) 
  | Merge_bool_n(id, t, f) -> Merge_bool_n(id, r_val_exp t, r_val_exp f) 
and r_item_info_flg_list = function
  | None -> None
  | Some iil -> Some (List.map (flag r_item_info) iil)

and r_item_info = function
  | ConstInfo ci -> ConstInfo(r_const_info ci)
  | TypeInfo  ti -> TypeInfo (r_type_info ti)
  | NodeInfo  ni -> NodeInfo (r_node_info ni)

and r_const_info = function
  | ExternalConst(id,te,ve_opt) -> ExternalConst(id,te, fopt r_val_exp ve_opt)
  | EnumConst(id,te) -> EnumConst(id,te)
  | DefinedConst(id,te,ve) -> DefinedConst(id,te, r_val_exp ve)

and r_type_info = function 
  | ExternalType(id) -> ExternalType(id)
  | AliasedType(id,te) -> AliasedType(id,te)
  | EnumType(id,te) -> EnumType(id,te)
  | StructType(sti) -> StructType(r_struct_type_info sti)
  | ArrayType(id,te,ve) -> ArrayType(id,te, r_val_exp ve)

and r_node_info ni = {
  ni with
    static_params = List.map (flag r_static_param) ni.static_params;
    def = r_node_def ni.def;
}
and r_struct_type_info sti =
  Hashtbl.iter 
    (fun id fi -> Hashtbl.replace sti.st_ftable id (flag r_field_info fi)) 
    sti.st_ftable;
  sti

and r_field_info fi = { fi with fd_value = fopt r_val_exp fi.fd_value }

and r_node_def = function
  | Extern -> Extern
  | Abstract -> Abstract
  | Body(node_body) -> Body(r_node_body node_body)
  | Alias(by_pos_op) -> Alias(flag2 r_by_pos_op by_pos_op)

and r_packbody pb = 
  Hashtbl.iter 
    (fun id i -> Hashtbl.replace pb.pk_const_table id (flag r_const_info i))
  Hashtbl.iter
    (fun id i -> Hashtbl.replace pb.pk_type_table id (flag r_type_info i)) 
    pb.pk_type_table;
  Hashtbl.iter 
    (fun id i -> Hashtbl.replace pb.pk_node_table id (flag r_node_info i)) 
    pb.pk_node_table;
  pb

and r_node_body nb = {
  asserts = List.map (flag r_val_exp) nb.asserts;
  eqs     = List.map (flag r_eq_info) nb.eqs;
}
and r_eq_info (lpl,ve) = (List.map r_left_part lpl, r_val_exp ve)

and r_left_part = function 
  | LeftVar(id) -> LeftVar(id)
  | LeftField(lp,id) -> LeftField(r_left_part lp,id)
  | LeftArray(lp,ve) -> LeftArray(r_left_part lp, flag r_val_exp ve)  
  | LeftSlice(lp,si) -> LeftSlice(r_left_part lp, flag r_slice_info si)