123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252moduleList=structincludeListLabelsletmap~ft=rev(rev_map~ft)endmoduleString=StringLabelsmoduleAst=structtype+'at=|Nop|Seqof'at*'at|Concatof'at*'atlist|Boxofint*'at|Vboxofint*'at|Hboxof'at|Hvboxofint*'at|Hovboxofint*'at|Verbatimofstring|Charofchar|Breakof(string*int*string)*(string*int*string)|Newline|Textofstring|Tagof'a*'atendincludeAstletof_ast=Fun.idletto_ast=Fun.idtype('a,'tag)format_string=('a,unit,string,'tagt)format4letrecmap_tagst~f=matchtwith|Nop->Nop|Seq(a,b)->Seq(map_tagsa~f,map_tagsb~f)|Concat(sep,l)->Concat(map_tagssep~f,List.mapl~f:(map_tags~f))|Box(indent,t)->Box(indent,map_tagst~f)|Vbox(indent,t)->Vbox(indent,map_tagst~f)|Hboxt->Hbox(map_tagst~f)|Hvbox(indent,t)->Hvbox(indent,map_tagst~f)|Hovbox(indent,t)->Hovbox(indent,map_tagst~f)|(Verbatim_|Char_|Break_|Newline|Text_)ast->t|Tag(tag,t)->Tag(ftag,map_tagst~f)letrecfilter_map_tagst~f=matchtwith|Nop->Nop|Seq(a,b)->Seq(filter_map_tagsa~f,filter_map_tagsb~f)|Concat(sep,l)->Concat(filter_map_tagssep~f,List.mapl~f:(filter_map_tags~f))|Box(indent,t)->Box(indent,filter_map_tagst~f)|Vbox(indent,t)->Vbox(indent,filter_map_tagst~f)|Hboxt->Hbox(filter_map_tagst~f)|Hvbox(indent,t)->Hvbox(indent,filter_map_tagst~f)|Hovbox(indent,t)->Hovbox(indent,filter_map_tagst~f)|(Verbatim_|Char_|Break_|Newline|Text_)ast->t|Tag(tag,t)->(lett=filter_map_tagst~finmatchftagwith|None->t|Sometag->Tag(tag,t))moduleRender=structopenFormatletrecrenderppft~tag_handler=matchtwith|Nop->()|Seq(a,b)->renderppf~tag_handlera;renderppf~tag_handlerb|Concat(_,[])->()|Concat(sep,x::l)->renderppf~tag_handlerx;List.iterl~f:(funx->renderppf~tag_handlersep;renderppf~tag_handlerx)|Box(indent,t)->pp_open_boxppfindent;renderppf~tag_handlert;pp_close_boxppf()|Vbox(indent,t)->pp_open_vboxppfindent;renderppf~tag_handlert;pp_close_boxppf()|Hboxt->pp_open_hboxppf();renderppf~tag_handlert;pp_close_boxppf()|Hvbox(indent,t)->pp_open_hvboxppfindent;renderppf~tag_handlert;pp_close_boxppf()|Hovbox(indent,t)->pp_open_hovboxppfindent;renderppf~tag_handlert;pp_close_boxppf()|Verbatimx->pp_print_stringppfx|Charx->pp_print_charppfx|Break(fits,breaks)->pp_print_custom_breakppf~fits~breaks|Newline->pp_force_newlineppf()|Texts->pp_print_textppfs|Tag(tag,t)->tag_handlerppftagtendletto_fmt_with_tags=Render.renderletrecto_fmtppft=Render.renderppft~tag_handler:(funppf_tagt->to_fmtppft)letnop=Nopletseqab=Seq(a,b)letconcat?(sep=Nop)=function|[]->Nop|[x]->x|l->Concat(sep,l)letconcat_map?(sep=Nop)l~f=matchlwith|[]->Nop|[x]->fx|l->Concat(sep,List.mapl~f)letconcat_mapi?(sep=Nop)l~f=matchlwith|[]->Nop|[x]->f0x|l->Concat(sep,List.mapil~f)letbox?(indent=0)t=Box(indent,t)letvbox?(indent=0)t=Vbox(indent,t)lethboxt=Hboxtlethvbox?(indent=0)t=Hvbox(indent,t)lethovbox?(indent=0)t=Hovbox(indent,t)letverbatimx=Verbatimxletverbatimffmt=Printf.ksprintfverbatimfmtletcharx=Charxletcustom_break~fits~breaks=Break(fits,breaks)letbreak~nspaces~shift=custom_break~fits:("",nspaces,"")~breaks:("",shift,"")letspace=break~nspaces:1~shift:0letcut=break~nspaces:0~shift:0letnewline=Newlinelettexts=Textslettextf(fmt:('a,'tag)format_string)=Printf.ksprintftextfmtlettagtagt=Tag(tag,t)letparagraphs=hovbox(texts)letparagraphf(fmt:('a,'tag)format_string)=Printf.ksprintfparagraphfmtletenumeratel~f=vbox(concat~sep:cut(List.mapl~f:(funx->box~indent:2(seq(verbatim"- ")(fx)))))letchainl~f=vbox(concat~sep:cut(List.mapil~f:(funix->box~indent:3(seq(verbatim(ifi=0then" "else"-> "))(fx)))))moduleO=structlet(++)=seqendletcompare=letcompare_both(typeab)(f:a->a->int)(g:b->b->int)(a,b)(c,d)=letr=facinifr<>0thenrelsegbdin(* Due to 4.08 lower bound, we need to define this here. *)letreccompare_listab~cmp:f:int=match(a,b)with|[],[]->0|[],_::_->-1|_::_,[]->1|x::a,y::b->(match(fxy:int)with|0->compare_listab~cmp:f|ne->ne)infuncompare_tag->letreccomparexy=match(x,y)with|Nop,Nop->0|Nop,_->-1|_,Nop->1|Seq(a,b),Seq(c,d)->compare_bothcomparecompare(a,b)(c,d)|Seq_,_->-1|_,Seq_->1|Concat(a,b),Concat(c,d)->compare_bothcompare(compare_list~cmp:compare)(a,b)(c,d)|Concat_,_->-1|_,Concat_->1|Box(a,b),Box(c,d)->compare_bothInt.comparecompare(a,b)(c,d)|Box_,_->-1|_,Box_->1|Vbox(a,b),Vbox(c,d)->compare_bothInt.comparecompare(a,b)(c,d)|Vbox_,_->-1|_,Vbox_->1|Hboxa,Hboxb->compareab|Hbox_,_->-1|_,Hbox_->1|Hvbox(a,b),Hvbox(c,d)->compare_bothInt.comparecompare(a,b)(c,d)|Hvbox_,_->-1|_,Hvbox_->1|Hovbox(a,b),Hovbox(c,d)->compare_bothInt.comparecompare(a,b)(c,d)|Hovbox_,_->-1|_,Hovbox_->1|Verbatima,Verbatimb->String.compareab|Verbatim_,_->-1|_,Verbatim_->1|Chara,Charb->Char.compareab|Char_,_->-1|_,Char_->1|Break(a,b),Break(c,d)->letcompare(x,y,z)(a,b,c)=compare_bothString.compare(compare_bothInt.compareString.compare)(x,(y,z))(a,(b,c))incompare_bothcomparecompare(a,b)(c,d)|Break_,_->-1|_,Break_->1|Newline,Newline->0|Newline,_->-1|_,Newline->1|Texta,Textb->String.compareab|Text_,_->-1|_,Text_->1|Tag(a,b),Tag(c,d)->compare_bothcompare_tagcompare(a,b)(c,d)incompare