123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207(* Time-stamp: <modified the 12/03/2020 (at 15:40) by Erwan Jahier> *)typeident=stringtypev=Iofint|Foffloat|Bofbool|Eofident*int|Aofvarray|Sof(ident*v)list|U|Strofstringtypet=|Bool|Int|Real|Externofident|Enumof(ident*identlist)|Structofident*(ident*t)list|Arrayof(t*int)|Alphaofint|Aliasof(string*t)|Stringlet(val_to_string_type:v->string)=function|I_->"int"|F_->"real"|B_->"bool"|E(e,_)->e|S_->"struct"|A_->"array"|U->"nil"|Str_->"string"letrec(val_to_string:(float->string)->v->string)=funs2f->function|Ii->(trystring_of_intiwith_->assertfalse)|Ff->s2ff|Btrue->"t"|Bfalse->"f"|E(e,_)->e|Sfl->"{"^(String.concat";"(List.map(fun(fn,fv)->fn^"="^(val_to_strings2ffv))fl))^"}"|Aa->letstr=ref"["inletfia=str:=!str^(ifi=0then""else",")^(val_to_strings2fa)inArray.iterifa;(!str^"]")|U->"nil"|Strstr->strlet(val_to_rif_string:(float->string)->v->string)=funs2f->function|Ii->(trystring_of_intiwith_->assertfalse)|Ff->s2ff|Btrue->"t"|Bfalse->"f"|E(e,_)->e|Sfl->""^(String.concat";"(List.map(fun(_fn,fv)->" "^(val_to_strings2ffv))fl))^""|Aa->letstr=ref""inletfia=str:=!str^(ifi=0then""else" ")^(val_to_strings2fa)inArray.iterifa;(!str)|U->"nil"|Strstr->strletrec(type_to_string_gen:bool->t->string)=funaliasv->letstr=matchvwith|String->"string"|Bool->"bool"|Int->"int"|Real->"real"|Extern_s->"string"(* what else should be done? *)(* | Enum (s, sl) -> "enum " ^ s ^ " {" ^ (String.concat ", " sl) ^ "}" *)|Enum(s,_sl)->s|Struct(sid,_)->sid|Array(ty,sz)->Printf.sprintf"%s^%d"(type_to_string_genaliasty)sz|Alphanb->(* On génère des "types" à la Caml : 'a, 'b, 'c, etc. *)leta_value=Char.code('a')inletz_value=Char.code('z')inletstr=if(nb>=0&&nb<=(z_value-a_value))then("'"^(Char.escaped(Char.chr(a_value+nb))))else("'a"^(string_of_intnb))instr|Alias(n,t)->ifaliasthennelsetype_to_string_genaliastinstrlet(type_to_string:t->string)=type_to_string_genfalselet(type_to_string_alias:t->string)=type_to_string_gentruelet(type_of_string:string->t)=function|"bool"->Bool|"real"->Real|"float"->Real|"int"->Int|"string"->String|s->failwith(s^": unsupported type.\n")typevntl=(string*t)listtypesubst=(string*v)typeaccess=Idxofint|Fldofident|Sleofint*int*int*int(* exported *)letrec(update_val:v->v->accesslist->v)=funpre_vvaccess->matchpre_v,accesswith|_,[]->v|Aa,(Sle(f,l,s,w))::access->(leta=Array.copyainletj=ref0inletsub_array=Array.makewUinfori=ftoldoif(i-f)mods=0then(sub_array.(!j)<-a.(i);incrj);done;letsub_array=matchupdate_val(Asub_array)vaccesswithAsub_array->sub_array|_->assertfalseinj:=0;fori=ftoldoif(i-f)mods=0then(a.(i)<-sub_array.(!j);incrj);done;Aa)|Aa,(Idxi)::access->leta=Array.copya(* necessary for arrays of arrays. It would probably more
clever to only copy a_i though. *)inleta_i=update_vala.(i)vaccessina.(i)<-a_i;Aa|S(fl),(Fldfn)::access->S(List.map(fun(fn2,v2)->iffn=fn2thenfn,update_valv2vaccesselse(fn2,v2))fl)|U,_->assertfalse(* create_val v access *)|_,_->assertfalse(* finish me *)(* exported *)letrec(create_u_val:t->v)=funvt->matchvtwith|Array(vt,size)->leta=Array.makesizeUinfori=0tosize-1doa.(i)<-create_u_valvtdone;Aa|Struct(_sn,fl)->S(List.map(fun(fn,ft)->fn,create_u_valft)fl)|_->U(* seems slower (??) *)let(create_val:t->v->accesslist->v)=funvtvaccess->letu_val=create_u_valvtinupdate_valu_valvaccesslet(_create_val_alt:t->v->accesslist->v)=funvtvaccess->matchvt,accesswith|_,[]->v|Array(vt,size),(Sle(f,l,s,w))::access->(letj=ref0inleta=Array.makesizeUinletvt=Array(vt,w)inletsub_array=matchcreate_valvtvaccesswithAsa->sa|_->assertfalseinfori=ftoldoif(i-f)mods=0then(a.(i)<-sub_array.(!j);incrj);done;Aa)|Array(vt,size),(Idxi)::access->leta=Array.makesizeUinleta_i=create_valvtvaccessina.(i)<-a_i;Aa|Struct(_sn,fl),(Fldfn)::access->S(List.map(fun(fn2,vt2)->iffn=fn2thenfn,create_valvt2vaccesselsefn2,U)fl)|_,_->assertfalse