12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788open!CoreopenPpxlibopenAst_builder.Defaultletppx_name="demo"letfiles=String.Table.create()letread_filefilename=matchHashtbl.findfilesfilenamewith|Somefile_contents->file_contents|None->letfile_contents=In_channel.read_allfilenameinHashtbl.add_exnfiles~key:filename~data:file_contents;file_contents;;letcreate_demo_string~loc_start~loc_end=(* We start the substring a little further into the string so that we can
strip off the leading "[%demo" of the expression. *)letstart_index=loc_start.pos_cnum+String.lengthppx_name+2in(* We end the substring one character earlier to strip off the trailing "]"
from the ppx. *)letend_index=loc_end.pos_cnum-1inletfile_contents=read_fileloc_start.pos_fnameinlet()=letsanity_check_substring=String.subfile_contents~pos:loc_start.pos_cnum~len:(String.lengthppx_name+2)inifnot(String.equalsanity_check_substring"[%demo")thenfailwith"ppx_demo requires that extension node be of the form [%demo ...]"inletsubstring_length=end_index-start_indexinletpad_length=start_index-loc_start.pos_bolinletbuffer=Buffer.create(substring_length+pad_length)infor_=0topad_length-1doBuffer.add_charbuffer' 'done;Buffer.add_substringbufferfile_contents~pos:start_index~len:substring_length;Buffer.contentsbuffer|>Dedent.string;;letexpand_expr~loc:{loc_start;loc_end;_}~path:_expr=letstring=create_demo_string~loc_start~loc_endinletloc={loc_start;loc_end;loc_ghost=true}inpexp_tuple~loc[expr;estring~locstring];;letexpand_str~loc:{loc_start;loc_end;_}~path:_(structure:structure)=letstring=create_demo_string~loc_start~loc_endinletloc={loc_start;loc_end;loc_ghost=true}in(* let ppx_demo_string = (* demo string of structure *) *)letdemo=pstr_value~locNonrecursive[value_binding~loc~pat:(ppat_var~loc{txt="ppx_demo_string";loc})~expr:(estring~locstring)]in(* {[
struct
(* original structure *)
let ppx_demo_string = (* demo string of structure *)
end
]}
*)pmod_structure~loc(structure@[demo]);;let()=Driver.register_transformationppx_name~extensions:[Extension.declareppx_nameExtension.Context.expressionAst_pattern.(single_expr_payload__)expand_expr;Extension.declareppx_nameExtension.Context.module_exprAst_pattern.(pstr__)expand_str];;