123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217(* Time-stamp: <modified the 29/08/2019 (at 16:16) by Erwan Jahier> *)(* *)openLicopenLv6errors(* exported *)letget_node_and_int_const(lxm:Lxm.t)(sargs:Lic.static_arglist):(Lic.node_key*int)=matchsargswith|(NodeStaticArgLic(_,nk))::(ConstStaticArgLiccarg)::_->(letc=matchcargwith|(_,Int_const_effc)->c|(_,Abstract_const_eff(_,_,Int_const_effc,true))->c|(_,zcl)->letmsg="immediate integer expected, but get \""^(LicDump.string_of_const_efffalsezcl)^"\"\n"inraise(Compile_error(lxm,msg))in(nk,int_of_stringc))|_->letmsg="*** an integer and a node are expected.\n"inraise(Compile_error(lxm,msg))(* transforme en array une variable *)letvar_to_array(c:int)(vi:Lic.var_info):Lic.var_info={viwithvar_type_eff=Array_type_eff(vi.var_type_eff,c)}(*
On a éventuellement besoin du node_exp des args
*)letrecdo_node(nk2nd:Lic.node_key->Lic.node_exp)(nk:Lic.node_key)(lxm:Lxm.t):(Lic.node_exp)=let(pk,id)=fstnkinmatch(pk,id)with|("Lustre","map")->do_mapnk2ndnklxm|("Lustre","red")|("Lustre","fill")|("Lustre","fillred")->do_fillrednk2ndnklxm|("Lustre","boolred")->do_boolrednk2ndnklxm|("Lustre","condact")->do_condactnk2ndnklxm|_->raiseNot_found(*--------------------------------------------------------------------
MAP
----------------------------------------------------------------------
Given :
- A node n of type: a_1 * ... * a_n -> b_1 * ... * b_k
- A (int) const c
Gen a node of type : a_1^c * ... * a_n^c -> b_1^c * ... * b_k^c
--------------------------------------------------------------------*)anddo_mapnk2ndnklxm=letsargs=sndnkinlet(np,c)=get_node_and_int_constlxmsargsinletnd=nk2ndnpinletins=nd.inlist_effinletouts=nd.outlist_effin{node_key_eff=nk;inlist_eff=List.map(var_to_arrayc)ins;outlist_eff=List.map(var_to_arrayc)outs;loclist_eff=None;def_eff=MetaOpLic;has_mem_eff=nd.has_mem_eff;is_safe_eff=nd.is_safe_eff;lxm=lxm;}(*--------------------------------------------------------------------
FILLRED
----------------------------------------------------------------------
Given :
- A node : aa * a_1 * ... * a_n -> aa * b_1 * ... * b_k
- An int c
Gen a node : aa * a_1^c * ... * a_n^c -> aa * b_1^c * ... * b_k^c
--------------------------------------------------------------------*)anddo_fillrednk2ndnklxm=letsargs=sndnkinlet(np,c)=get_node_and_int_constlxmsargsinletnd=nk2ndnpinletins=nd.inlist_effinletouts=nd.outlist_effinlet_=assert(ins<>[]&&outs<>[])inletins'=(List.hdins)::(List.map(var_to_arrayc)(List.tlins))inletouts'=(List.hdouts)::(List.map(var_to_arrayc)(List.tlouts))in(* pas d'unif : egalité et c'est tout ! *)lett1=(List.hdins').var_type_effinlett2=(List.hdouts').var_type_effinift1<>t2thenletmsg=Printf.sprintf"node can't be used in iterator, first input type '%s' differs from first output type '%s'"(LicDump.string_of_type_efffalset1)(LicDump.string_of_type_efffalset2)inraise(Compile_error(lxm,msg))else{node_key_eff=nk;inlist_eff=ins';outlist_eff=outs';loclist_eff=None;def_eff=MetaOpLic;has_mem_eff=nd.has_mem_eff;is_safe_eff=nd.is_safe_eff;lxm=lxm;}(*--------------------------------------------------------------------
CONDACT
----------------------------------------------------------------------
Given :
- A node n of type: a_1 * ... * a_n -> b_1 * ... * b_k
- A (tuple) const: b_1 * ... * b_k
Gen a node of type : bool * a_1 * ... * a_n -> b_1 * ... * b_k
---------------------------------------------------------------------*)(*
nb :
node condact_xx(c,i1,...,in) returns(res1,...,resk);
let
res1,...,resk = condact<<node,(dft_res1,...,dft_resk)>>(c,i1,...,in)
tel
could be translated into
node condact_xx(c,i1,...,in) returns(res1,...,resk);
let
res1,...,resk =
merge c (true -> node(i1,...,in))
(false -> (dft_res1,...,dft_resk) fby (res1,...,resk)
tel
is it a good idea?
*)and(do_condact:(Lic.node_key->Lic.node_exp)->node_key->Lxm.t->Lic.node_exp)=funnk2ndnklxm->tryletsargs=sndnkinletnp,dflt=matchsargswith|[NodeStaticArgLic(_,np);ConstStaticArgLic(_,dflt)]->np,dflt|_->assertfalsein(* recherche le profil de np ... *)letne=nk2ndnpinletinlist=ne.inlist_effinletoutlist=ne.outlist_effin(* dflt_types doit êre compatiple avec outlist *)letdflt_types=types_of_constdfltinletout_types=List.map(funx->x.var_type_eff)outlistinletmatches=tryUnifyType.is_matchedout_typesdflt_typeswithUnifyType.Match_failedmsg->raise(Compile_error(lxm,"in condact default output "^msg))inletout_types=Lic.apply_type_matchesmatchesout_typesinletin_types=Lic.apply_type_matchesmatches(Bool_type_eff::(List.map(funx->x.var_type_eff)inlist))in(* ok pour les args statiques, le profil dynamique est : *)letclk=Lic.create_varAstCore.VarInputBool_type_eff"activate"inassert(in_types<>[]);letins=clk::Lic.create_var_listAstCore.VarInput(List.tlin_types)inletouts=Lic.create_var_listAstCore.VarOutputout_typesin{node_key_eff=nk;inlist_eff=ins;outlist_eff=outs;loclist_eff=None;def_eff=MetaOpLic;has_mem_eff=ne.has_mem_eff;is_safe_eff=ne.is_safe_eff;lxm=lxm;}with|LicEvalType.EvalType_errormsg->raise(Compile_error(lxm,"type error: "^msg))(*--------------------------------------------------------------------
BOOLRED
----------------------------------------------------------------------
Given
- 3 integer constant i, j, k
returns the profile bool^k -> bool
---------------------------------------------------------------------*)anddo_boolred_nk2ndnklxm=letsargs=sndnkinlet(_i,_j,k)=matchsargswith|[ConstStaticArgLic(_,Int_const_effi);ConstStaticArgLic(_,Int_const_effj);ConstStaticArgLic(_,Int_const_effk)]->i,j,k|_->raise(Compile_error(lxm,"\n*** type error: 3 int were expected"))inletk=int_of_stringkinletins=Lic.create_varAstCore.VarInput(Array_type_eff(Bool_type_eff,k))"i1"inletouts=Lic.create_varAstCore.VarOutputBool_type_eff"out"in{node_key_eff=nk;inlist_eff=[ins];outlist_eff=[outs];loclist_eff=None;def_eff=MetaOpLic;has_mem_eff=false;is_safe_eff=true;lxm=lxm;}