Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file main.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199openPpxlib(*
* - [%impl_record n] becomes becomes a function which builds record representations with 1 up to [n] fields.
* - [%impl_variant n] becomes a function which builds variant representations with 1 up to [n] cases.
*)moduletypeS=sigvalimpl_record:int->expressionvalimpl_variant:int->expressionendlet(>>|)xf=List.mapfxlet(>>=)xf=List.mapfx|>List.flattenmoduleLocated(A:Ast_builder.S):S=structopenAletevni=evar(n^string_of_inti)letpvni=pvar(n^string_of_inti)letplist:patternlist->pattern=funps->List.fold_right(funhdtl->[%pat?[%phd]::[%ptl]])ps[%pat?[]]letelist:expressionlist->expression=funes->List.fold_right(funhdtl->[%expr[%ehd]::[%etl]])es[%expr[]]letefun~(params:patternlist):expression->expression=List.fold_right(funparambody->[%exprfun[%pparam]->[%ebody]])paramsleterror_case~msg:case=case~lhs:ppat_any~guard:None~rhs:[%exprfailwith[%eestringmsg]](** Generates the code for the [%impl_record n] extension point. *)letimpl_recordn=letgenerate_caseindices=letlhs=plist(indices>>|funi->[%pat?[%ppv"n"i],AT[%ppv"t"i]])inletwrap_params=efun~params:(indices>>|pv"v")inletrhs=letapply_fieldsbody=indices>>|(funibody->[%expr[%ebody]|+T.field[%eev"n"i](t_to_repr[%eev"t"i])(new_dyn_record_getterrecord_name[%eev"n"i][%eev"t"i])])|>List.fold_left(|>)bodyinletvalues=indices>>|funi->[%expr[%eev"n"i],wrap[%eev"t"i][%eev"v"i]]in[%expr[%eapply_fields[%exprT.recordrecord_name[%ewrap_params[%exprnew_dyn_recordrecord_name[%eelistvalues]]]]]|>T.sealr]incase~lhs~guard:None~rhsinletcases=List.initnsucc>>|(funl->List.initlsucc)>>|generate_caseinleterror_case=error_case~msg:(Format.sprintf"The given TRecord has a number of fields outside of [|1; %d|]"n)in[%exprfunrecord_namefs->[%epexp_match[%exprfs](cases@[error_case])]]letgenerate_caseindices=letpattern:pattern=plist(indices>>|fun(i,typ)->matchtypwith|`Case0->[%pat?[%ppv"n"i],ACTCase0]|`Case1->[%pat?[%ppv"n"i],ACT(Case1[%ppv"t"i])])inletwrap_params:expression->expression=indices>>|(fun(i,_)->pv"c"i)|>List.fold_right(funparambody->[%exprfun[%pparam]->[%ebody]])inletinits:caselist=letguardi=Some[%exprr=[%eev"n"i]]inindices>>|function|i,`Case0->case~lhs:[%pat?_,r,_]~guard:(guardi)~rhs:(ev"c"i)|i,`Case1->case~lhs:[%pat?_,r,v]~guard:(guardi)~rhs:[%expr[%eev"c"i](unwrap[%eev"t"i]v)]inletcases(body:expression):expression=letcase=function|i,`Case0->fune->[%expr[%ee]|~T.case0[%eev"n"i](variant_name,[%eev"n"i],VUnit())]|i,`Case1->fune->[%expr[%ee]|~T.case1[%eev"n"i](t_to_repr[%eev"t"i])(funv->(variant_name,[%eev"n"i],wrap[%eev"t"i]v))]inindices>>|case|>List.fold_left(|>)bodyinletrhs=letdestructor=[case~lhs:[%pat?vn,_,_]~guard:(Some[%exprnot(variant_name=vn)])~rhs:[%exprvariant_errorvn];]@inits@[case~lhs:[%pat?_,unmatched_case_name,_]~guard:None~rhs:[%exprcase_errorunmatched_case_name];]in[%expr[%ecases[%exprT.variantvariant_name[%ewrap_params(pexp_functiondestructor)]]]|>T.sealv]incase~lhs:pattern~guard:None~rhs(** Generates the code for the [%impl_variant n] extension point. *)letimpl_variantn=leterror_case=error_case~msg:(Format.sprintf"The given TVariant has a number of fields outside of [|1; %d|]."n)in(* Generate the i-th cartesian power l^i. *)letreccartl=function|0->[[]]|i->cartl(i-1)>>=funp->l>>|fune->e::pinletcases=List.initnsucc>>=cart[`Case0;`Case1]>>|List.mapi(funit->(succi,t))>>|generate_casein[%exprfunvariant_namecs->letvariant_error=Fmt.failwith"Trying to access the wrong variant: wanted %s, got %s"variant_nameinletcase_error=Fmt.failwith"Trying to use an unknown case name: %s"in[%epexp_match[%exprcs](cases@[error_case])]]endlet()=letextensionfname=Extension.declarenameExtension.Context.ExpressionAst_pattern.(pstr(pstr_eval(eint__)nil^::nil))(fun~loc~path:_->let(moduleA)=Ast_builder.makelocinf(moduleLocated(A):S))|>Context_free.Rule.extensioninDriver.register_transformation~rules:[extension(fun(moduleL)->L.impl_record)"impl_record";extension(fun(moduleL)->L.impl_variant)"impl_variant";]"alcotest.test"