12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970open!ImportmoduleList=Base.ListmoduleString=Base.Stringleteprintmessage=Printf.eprintf"%s\n%!"messageleteprint_ssexp=eprint(Sexp.to_string_humsexp)leteprintsmessageasexp_of_a=eprint_s([%sexp_of:string*a](message,a))leteprintfformat=Printf.ksprintfeprintformatletfailwiths=Error.failwithsmoduleMake()=structletcheck_invariant=reftrueletshow_messages=reftrueletdebuginvariant~module_namenametsargsexp_of_argsexp_of_resultf=if!show_messagestheneprints(String.concat~sep:""[module_name;".";name])argsexp_of_arg;if!check_invariantthen(tryList.iterts~f:invariantwith|exn->failwiths~here:[%here]"invariant pre-condition failed"(name,exn)[%sexp_of:string*exn]);letresult_or_exn=Result.try_withfinif!check_invariantthen(tryList.iterts~f:invariantwith|exn->failwiths~here:[%here]"invariant post-condition failed"(name,exn)[%sexp_of:string*exn]);if!show_messagestheneprints(String.concat~sep:""[module_name;".";name;"-result"])result_or_exn[%sexp_of:(result,exn)Result.t];Result.ok_exnresult_or_exn;;endletshould_print_backtrace=reffalseletam_internalheremessage=(* In this function we use [Printf.eprintf] rather than [Debug.eprintf], because the
former doesn't flush, while the latter does. We'd rather flush once at the end,
rather than three times. *)Printf.eprintf"%s:\n"(Source_code_position.to_stringhere);if!should_print_backtracethenPrintf.eprintf"%s\n"(Backtrace.get()|>[%sexp_of:Backtrace.t]|>Sexp.to_string_hum);(matchmessagewith|None->()|Somemessage->Printf.eprintf"%s\n"message);Printf.eprintf"%!";;letamhere=am_internalhereNoneletamfherefmt=Printf.ksprintf(funstring->am_internalhere(Somestring))fmtletamsheremessageasexp_of_a=am_internalhere(Some((message,a)|>[%sexp_of:string*a]|>Sexp.to_string_hum));;