12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273openPpxlib(* [eseq] function is somewhat similar to [elist] but constructs a sequence.
It is not provided by the Ast_builder. *)letreceseq~loc=function|[]->[%exprfun()->Seq.Nil]|x::xs->[%exprfun()->Seq.Cons([%ex],[%eeseq~locxs])][@@tail_mod_cons]letextend_seq=Extension.V2.declare"seq"Extension.Context.expressionAst_pattern.(pstr@@alt_option(pstr_eval(esequence__)nil^::nil)nil)(fun~loc~path:_xs->eseq~loc@@matchxswithNone->[]|Somexs->xs)leteinf~locab=letmkgenbody=[%exprletrecinfxs()=Seq.Cons(x,inf(x+s)s)in[%ebody]]inmatchawith|None->mkgen[%exprletx=[%eb]ininfx(succx-x)]|Somea->mkgen[%exprletx=[%ea]andy=[%eb]ininfx(y-x)]letextend_inf=Extension.V2.declare"seq.inf"Extension.Context.expressionAst_pattern.(pstr@@alt_option(pstr_eval(pexp_tuple(__^::__^::nil))nil^::nil)(pstr_eval__nil^::nil))(fun~loc~path:_->einf~loc)letefin~locabc=letmkgenbody=[%exprletrecfinxsy()=letn=x+sinifcomparexy=comparenxthenSeq.NilelseSeq.Cons(x,finnsy)in[%ebody]]inmatchawith|None->mkgen[%exprletx=[%eb]andy=[%ec]inifcomparexy=0thenSeq.returnxelsefinx(ifcomparexy<0thensuccx-xelsex-succx)y]|Somea->mkgen[%exprletx=[%ea]andv=[%eb]andy=[%ec]inifcomparexy=0thenSeq.returnxelseifcomparexv=0thenSeq.emptyelsefinx(v-x)y]letextend_fin=Extension.V2.declare"seq.fin"Extension.Context.expressionAst_pattern.(pstr@@alt_option(pstr_eval(pexp_tuple(__^::__^::__^::nil))nil^::nil)(pstr_eval(pexp_tuple(__^::__^::nil))nil^::nil))(fun~loc~path:_->efin~loc)letrules=List.mapContext_free.Rule.extension[extend_seq;extend_inf;extend_fin;]let_=Driver.register_transformation~rules"ppx_seq"