123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107openBaseopenPpxlibopenPpxlib.Ast_builder.Defaultletwrap_with_subscope~loc~nameexpr=(* Wraps a function body with subscope creation. Only supports functions.
Transforms:
{v
let%subscope my_function arg1 arg2 = body
v}
into:
{v
let my_function arg1 arg2 =
let scope = Hardcaml.Scope.sub_scope scope "my_function" in
body
v}
The [scope] variable is captured from the surrounding context using normal OCaml
scoping rules. If a function has a [scope] parameter, that parameter shadows the
outer scope and is used. If no [scope] exists, OCaml's type checker will error. *)matchPpxlib_jane.Shim.Pexp_function.of_parsetreeexpr.pexp_desc~locwith|Some(params,constraint_,body)->letsubscope_binding=value_binding~loc~pat:(ppat_var~loc(Located.mk~loc"scope"))~expr:[%exprHardcaml.Scope.sub_scopescope[%eestring~locname]]inletwrap_bodybody_expr=pexp_let~locNonrecursive[subscope_binding]body_exprinletwrapped_body:Ppxlib_jane.Shim.Pexp_function.function_body=matchbodywith|Pfunction_bodybody_expr->Pfunction_body(wrap_bodybody_expr)|Pfunction_cases(cases,cases_loc,attrs)->(* Transform into: let scope = ... in function | ... *)letfunction_expr={exprwithpexp_desc=Ppxlib_jane.Shim.Pexp_function.to_parsetree~params:[]~constraint_:Ppxlib_jane.Shim.Pexp_function.Function_constraint.none~body:(Pfunction_cases(cases,cases_loc,attrs))}inPfunction_body(wrap_bodyfunction_expr)in{exprwithpexp_desc=Ppxlib_jane.Shim.Pexp_function.to_parsetree~params~constraint_~body:wrapped_body}|None->Location.raise_errorf~loc"[let%%subscope] only supports function definitions";;lethardcaml_subscope_structure()=letpattern=(* Matches a structure item containing a let binding *)Ast_pattern.(pstr(pstr_valuenonrecursive__^::nil))inExtension.declare_inline"subscope"Structure_itempattern(fun~loc~path:_bindings->letbindings=List.mapbindings~f:(fun({pvb_pat;pvb_expr;_}asvb)->letbinding_name=matchpvb_pat.ppat_descwith|Ppat_var{txt;_}->txt|_->Location.raise_errorf~loc:pvb_pat.ppat_loc"[let%%subscope] requires a function name binding"in{vbwithpvb_expr=wrap_with_subscope~loc~name:binding_namepvb_expr})in[pstr_value~locNonrecursivebindings]);;lethardcaml_subscope_expression()=letpattern=(* Matches let bindings in expressions: let x = e1 in e2 *)Ast_pattern.(single_expr_payload(pexp_letnonrecursive____))inExtension.declare"subscope"Expressionpattern(fun~loc~path:_bindingsbody->letbindings=List.mapbindings~f:(fun({pvb_pat;pvb_expr;_}asvb)->letbinding_name=matchpvb_pat.ppat_descwith|Ppat_var{txt;_}->txt|_->Location.raise_errorf~loc:pvb_pat.ppat_loc"[let%%subscope] requires a function name binding"in{vbwithpvb_expr=wrap_with_subscope~loc~name:binding_namepvb_expr})inpexp_let~locNonrecursivebindingsbody);;letregister()=Driver.register_transformation"hardcaml_subscope"~rules:[Context_free.Rule.extension(hardcaml_subscope_structure());Context_free.Rule.extension(hardcaml_subscope_expression())];;