123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180(*
Tools shared between code generators for the biniou serialization format.
(xb means X-Biniou)
*)openPrintfopenAg_erroropenAg_mappingtype'aexpr=('a,Ag_biniou.biniou_repr)Ag_mapping.mappingtype'adef=('a,Ag_biniou.biniou_repr)Ag_mapping.deftype'agrouped_defs=(bool*'adeflist)listtypename=(loc*string)typenames={field_names:namelistlist;variant_names:namelistlist;}letrecextract_names_from_expracc(x:'aexpr)=matchxwith`Unit_|`Bool_|`Int_|`Float_|`String_->acc|`Sum(loc,va,_,_)->letl,(fn,vn)=Array.fold_leftextract_names_from_variant([],acc)vain(fn,List.revl::vn)|`Record(loc,fa,_,_)->letl,(fn,vn)=Array.fold_leftextract_names_from_field([],acc)fain(List.revl::fn,vn)|`Tuple(loc,ca,_,_)->Array.fold_leftextract_names_from_cellaccca|`List(loc,x,_,_)|`Option(loc,x,_,_)|`Nullable(loc,x,_,_)|`Wrap(loc,x,_,_)->extract_names_from_expraccx|`Name(loc,_,l,_,_)->List.fold_leftextract_names_from_expraccl|`External(loc,_,l,_,_)->List.fold_leftextract_names_from_expraccl|`Tvar_->accandextract_names_from_variant(l,acc)x=letl=(x.var_loc,x.var_cons)::linmatchx.var_argwithNone->(l,acc)|Somex->(l,extract_names_from_expraccx)andextract_names_from_field(l,acc)x=letl=(x.f_loc,x.f_name)::lin(l,extract_names_from_expraccx.f_value)andextract_names_from_cellaccx=extract_names_from_expraccx.cel_valueletextract_ocaml_names_from_defsl=letfn,vn=List.fold_left(funaccdef->matchdef.def_valuewithNone->acc|Somex->extract_names_from_expraccx)([],[])lin{field_names=List.revfn;variant_names=List.revvn;}letflatten_defs(grouped_defs:'agrouped_defs):'adeflist=List.flatten(List.mapsndgrouped_defs)letcheck_duplicate_hasheskindl=lettbl=Hashtbl.create100inList.iter(fun(loc,s)->leth=Bi_io.hash_namesintryletloc0,s0=Hashtbl.findtblhinerror2loc0(sprintf"Definition of %s %s."kinds0)loc(sprintf"\
Definition of %s %s.
Both %s and %s have the same hash %i which
makes them indistinguishable once in the Biniou format.
Use different names."kindss0sh)withNot_found->Hashtbl.addtblh(loc,s))lletcheck_hashesx=List.iter(check_duplicate_hashes"record field name")x.field_names;List.iter(check_duplicate_hashes"variant name")x.variant_namesletcheck(l:'agrouped_defs)=letx=extract_ocaml_names_from_defs(flatten_defsl)incheck_hashesx(*
let find_clashes () =
let l = Mikmatch.Text.lines_of_file "/tmp/dictionary.txt" in
(*
let l1 = List.rev_map (fun s -> s ^ "1") l in
let l2 = List.rev_map (fun s -> s ^ "2") l in
let l3 = List.rev_map (fun s -> s ^ "3") l in
let l4 = List.rev_map (fun s -> s ^ "4") l in
let l = List.flatten [l; l1; l2; l3; l4] in
*)
let tbl = Hashtbl.create (2 * List.length l) in
List.iter (
fun s ->
let h = Bi_io.hash_name s in
let r =
try Hashtbl.find tbl h
with Not_found ->
let r = ref [] in
Hashtbl.add tbl h r;
r
in
r := s :: !r
) l;
let clashes =
Hashtbl.fold (
fun h r acc ->
let l = !r in
if List.length l >= 2 then
List.rev l :: acc
else
acc
) tbl []
in
let clashes = List.sort compare clashes in
List.iter (fun l -> print_endline (String.concat " " l)) clashes
*)(*
Groups of words with identical biniou hashes obtained with find_clashes:
bind1 classroom's3
bind2 classroom's4
commutes1 funerals4
expect1 tantalus4
idea chaw2
interval's1 middling2
interval's2 middling3
interval's3 middling4
militarily1 scheduled4
overviews neglects3
shea crew2
vacating maxine3
workshop1 examples3
workshop2 examples4
bevel reconveyed
cogitate jutties
premiums squigglier
representationalists supervene
*)