123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157(*
* Copyright (c) 2019 Nathan Rebours <nathan.p.rebours@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)moduleResult=structmoduleInfix=structlet(>>=)rf=matchrwithOkx->fx|Error_ase->elet(>>|)rf=matchrwithOkx->Ok(fx)|Error_ase->elet(>>!)rf=matchrwith|Okx->fx|Errorl->List.iter(fun(`Msgm)->Printf.eprintf"[mdx] Fatal error: %s\n"m)l;1let(let*)=(>>=)let(let+)=(>>|)endleterrorffmt=Format.ksprintf(funs->Error(`Msgs))fmtletto_error_list=functionOkx->Okx|Errorerr->Error[err]moduleList=structopenInfixletfold~f~initl=letrecgoacc=function|[]->Okacc|hd::tl->let*acc=facchdingoacctlingoinitlletmap ~fl=fold~f:(funaccelm->let+elm'=felminelm'::acc)~init:[]l>>|List.revletsplitl=letrecsplit_recokserrorsl=matchlwith|[]->(List.revoks,List.reverrors)|Okx:: tl->split_rec(x:: oks)errorstl|Errorx::tl->split_recoks(x::errors)tlinsplit_rec[][]lendendmoduleFile=structletread_linesfile=letic=open_in fileinletr=ref []intrywhiletruedor:=input_lineic::!rdone;assertfalsewithEnd_of_file->close_inic;List.rev!rendmoduleOption=structletis_some=functionSome_->true|None->falseletvalue~default=functionSomev->v|None->defaultendmoduleSexp=structtypet=Atomofstring|ListoftlistendmoduleCsexp=Csexp.Make(Sexp)moduleString =structletenglish_concat~last_sepwords=letpf=Printf.sprintfinletrecaux acc=function|[]->acc|[last]->pf"%s %s %s"acclast_seplast|hd::tl->aux(pf"%s, %s"acchd)tlinmatchwordswith|[]->invalid_arg"Util.String.english_concat"|hd::tl->auxhdtllet english_conjonctionwords=english_concat~last_sep:"and"wordsletall_blank=Astring.String.for_allAstring.Char.Ascii.is_whiteendmoduleList=structletfind_mapfl=letrecaux=function|[]->None|h::t->(matchfhwithSomex->Somex|None->auxt)inauxlletpartition_untilfxs=letrecloop=function|[]->([],[])|x::xs->(matchfxwith|true->lettrueish,falseish=loopxsin(x::trueish,falseish)|false ->([],x::xs))inlettrueish,falseish=loopxsin(List.revtrueish,falseish)endmodule Array =structletslicet~from~to_=letstart_index,length=(from,to_-from+1)inArray.subtstart_indexlengthendmoduleProcess =structletrecwaitpid_non_intrpid=tryUnix.waitpid []pidwithUnix.Unix_error(Unix.EINTR,_,_)->waitpid_non_intrpidletwait~pid=matchsnd(waitpid_non_intrpid)withWEXITEDn-> n|_->255endmoduleInt=structletminab=ifa<bthenaelsebendmoduleSeq=struct(* [Seq.append] was added in 4.11, implement it for older versions *)letrecappendseq1seq2()=match seq1 ()with|Seq.Nil->seq2()|Seq.Cons(x,next)->Seq.Cons(x,appendnextseq2)end