123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173moduleState=structtype'at=|Partialof'apartial|Lazyof'atLazy.t|Doneofint*'a|Failofint*stringlist*stringand'apartial={committed:int;continue:Bigstringaf.t->off:int->len:int->More.t->'at}endtype'awith_state=Input.t->int->More.t->'atype'afailure=(stringlist->string->'aState.t)with_statetype('a,'r)success=('a->'rState.t)with_statetype'at={run:'r.('rfailure->('a,'r)success->'rState.t)with_state}letfail_kinputpos_marksmsg=State.Fail(pos-Input.client_committed_bytesinput,marks,msg)letsucceed_kinputpos_v=State.Done(pos-Input.client_committed_bytesinput,v)letrecto_exported_state=function|State.Partial{committed;continue}->Exported_state.Partial{committed;continue=funbs~off~lenmore->to_exported_state(continuebs~off~lenmore)}|State.Done(i,x)->Exported_state.Done(i,x)|State.Fail(i,sl,s)->Exported_state.Fail(i,sl,s)|State.Lazyx->to_exported_state(Lazy.forcex)letparsep=letinput=Input.createBigstringaf.empty~committed_bytes:0~off:0~len:0into_exported_state(p.runinput0Incompletefail_ksucceed_k)letparse_bigstringpinput=letinput=Input.createinput~committed_bytes:0~off:0~len:(Bigstringaf.lengthinput)inExported_state.state_to_result(to_exported_state(p.runinput0Completefail_ksucceed_k))moduleMonad=structletreturnv={run=funinputposmore_failsucc->succinputposmorev}letfailmsg={run=funinputposmorefail_succ->failinputposmore[]msg}let(>>=)pf={run=funinputposmorefailsucc->letsucc'input'pos'more'v=(fv).runinput'pos'more'failsuccinp.runinputposmorefailsucc'}let(>>|)pf={run=funinputposmorefailsucc->letsucc'input'pos'more'v=succinput'pos'more'(fv)inp.runinputposmorefailsucc'}let(<$>)fm=m>>|flet(<*>)fm=(* f >>= fun f -> m >>| f *){run=funinputposmorefailsucc->letsucc0input0pos0more0f=letsucc1input1pos1more1m=succinput1pos1more1(fm)inm.runinput0pos0more0failsucc1inf.runinputposmorefailsucc0}letliftfm=f<$>mletlift2fm1m2={run=funinputposmorefailsucc->letsucc1input1pos1more1m1=letsucc2input2pos2more2m2=succinput2pos2more2(fm1m2)inm2.runinput1pos1more1failsucc2inm1.runinputposmorefailsucc1}letlift3fm1m2m3={run=funinputposmorefailsucc->letsucc1input1pos1more1m1=letsucc2input2pos2more2m2=letsucc3input3pos3more3m3=succinput3pos3more3(fm1m2m3)inm3.runinput2pos2more2failsucc3inm2.runinput1pos1more1failsucc2inm1.runinputposmorefailsucc1}letlift4fm1m2m3m4={run=funinputposmorefailsucc->letsucc1input1pos1more1m1=letsucc2input2pos2more2m2=letsucc3input3pos3more3m3=letsucc4input4pos4more4m4=succinput4pos4more4(fm1m2m3m4)inm4.runinput3pos3more3failsucc4inm3.runinput2pos2more2failsucc3inm2.runinput1pos1more1failsucc2inm1.runinputposmorefailsucc1}let(*>)ab=(* a >>= fun _ -> b *){run=funinputposmorefailsucc->letsucc'input'pos'more'_=b.runinput'pos'more'failsuccina.runinputposmorefailsucc'}let(<*)ab=(* a >>= fun x -> b >>| fun _ -> x *){run=funinputposmorefailsucc->letsucc0input0pos0more0x=letsucc1input1pos1more1_=succinput1pos1more1xinb.runinput0pos0more0failsucc1ina.runinputposmorefailsucc0}endmoduleChoice=structlet(<?>)pmark={run=funinputposmorefailsucc->letfail'input'pos'more'marksmsg=failinput'pos'more'(mark::marks)msginp.runinputposmorefail'succ}let(<|>)pq={run=funinputposmorefailsucc->letfail'input'pos'more'marksmsg=(* The only two constructors that introduce new failure continuations are
* [<?>] and [<|>]. If the initial input position is less than the length
* of the committed input, then calling the failure continuation will
* have the effect of unwinding all choices and collecting marks along
* the way. *)ifpos<Input.parser_committed_bytesinput'thenfailinput'pos'moremarksmsgelseq.runinput'posmore'failsuccinp.runinputposmorefail'succ}endmoduleMonad_use_for_debugging=structletreturn=Monad.returnletfail=Monad.faillet(>>=)=Monad.(>>=)let(>>|)mf=m>>=funx->return(fx)let(<$>)fm=m>>|flet(<*>)fm=f>>=funf->m>>|fletlift=(>>|)letlift2fm1m2=f<$>m1<*>m2letlift3fm1m2m3=f<$>m1<*>m2<*>m3letlift4fm1m2m3m4=f<$>m1<*>m2<*>m3<*>m4let(*>)ab=a>>=fun_->blet(<*)ab=a>>=funx->b>>|fun_->xend