Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ppx_metaquot.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288(* This file is part of the ppx_tools package. It is released *)(* under the terms of the MIT license (see LICENSE file). *)(* Copyright 2013 Alain Frisch and LexiFi *)(* A -ppx rewriter to be used to write Parsetree-generating code
(including other -ppx rewriters) using concrete syntax.
We support the following extensions in expression position:
[%expr ...] maps to code which creates the expression represented by ...
[%pat? ...] maps to code which creates the pattern represented by ...
[%str ...] maps to code which creates the structure represented by ...
[%stri ...] maps to code which creates the structure item represented by ...
[%sig: ...] maps to code which creates the signature represented by ...
[%sigi: ...] maps to code which creates the signature item represented by ...
[%type: ...] maps to code which creates the core type represented by ...
Quoted code can refer to expressions representing AST fragments,
using the following extensions:
[%e ...] where ... is an expression of type Parsetree.expression
[%t ...] where ... is an expression of type Parsetree.core_type
[%p ...] where ... is an expression of type Parsetree.pattern
[%%s ...] where ... is an expression of type Parsetree.structure
or Parsetree.signature depending on the context.
All locations generated by the meta quotation are by default set
to [Ast_helper.default_loc]. This can be overriden by providing a custom
expression which will be inserted whereever a location is required
in the generated AST. This expression can be specified globally
(for the current structure) as a structure item attribute:
;;[@@metaloc ...]
or locally for the scope of an expression:
e [@metaloc ...]
Support is also provided to use concrete syntax in pattern
position. The location and attribute fields are currently ignored
by patterns generated from meta quotations.
We support the following extensions in pattern position:
[%expr ...] maps to code which creates the expression represented by ...
[%pat? ...] maps to code which creates the pattern represented by ...
[%str ...] maps to code which creates the structure represented by ...
[%type: ...] maps to code which creates the core type represented by ...
Quoted code can refer to expressions representing AST fragments,
using the following extensions:
[%e? ...] where ... is a pattern of type Parsetree.expression
[%t? ...] where ... is a pattern of type Parsetree.core_type
[%p? ...] where ... is a pattern of type Parsetree.pattern
*)moduleMain:sigvalmain:unit->unitend=structopenAsttypesopenParsetreeopenAst_helperopenAst_convenienceletprefixtys=letopenLongidentinmatchparsetywith|Ldot(m,_)->String.concat"."(Longident.flattenm)^"."^s|_->sletappend?loc?attrsee'=letfn=Location.mknoloc(Longident.(Ldot(Lident"List","append")))inExp.apply?loc?attrs(Exp.identfn)[Nolabel,e;Nolabel,e']classexp_builder=objectmethodrecordtyx=record(List.map(fun(l,e)->prefixtyl,e)x)methodconstrty(c,args)=constr(prefixtyc)argsmethodlistl=listlmethodtuplel=tuplelmethodinti=intimethodstrings=strsmethodcharc=charcmethodint32x=Exp.constant(Const.int32x)methodint64x=Exp.constant(Const.int64x)methodnativeintx=Exp.constant(Const.nativeintx)endclasspat_builder=objectmethodrecordtyx=precord~closed:Closed(List.map(fun(l,e)->prefixtyl,e)x)methodconstrty(c,args)=pconstr(prefixtyc)argsmethodlistl=plistlmethodtuplel=ptuplelmethodinti=pintimethodstrings=pstrsmethodcharc=pcharcmethodint32x=Pat.constant(Const.int32x)methodint64x=Pat.constant(Const.int64x)methodnativeintx=Pat.constant(Const.nativeintx)endletget_exploc=function|PStr[{pstr_desc=Pstr_eval(e,_);_}]->e|_->letreport=Location.error~loc"Expression expected."inLocation.print_reportFormat.err_formatterreport;exit2letget_typloc=function|PTypt->t|_->letreport=Location.error~loc"Type expected."inLocation.print_reportFormat.err_formatterreport;exit2letget_patloc=function|PPat(t,None)->t|_->letreport=Location.error~loc"Pattern expected."inLocation.print_reportFormat.err_formatterreport;exit2letexp_lifterlocmap=letmap=map.Ast_mapper.exprmapinobjectinherit[_]Ast_lifter.lifterassuperinheritexp_builder(* Special support for location in the generated AST *)method!lift_Location_t_=loc(* Support for antiquotations *)method!lift_Parsetree_expression=function|{pexp_desc=Pexp_extension({txt="e";loc},e);_}->map(get_exploce)|x->super#lift_Parsetree_expressionxmethod!lift_Parsetree_pattern=function|{ppat_desc=Ppat_extension({txt="p";loc},e);_}->map(get_exploce)|x->super#lift_Parsetree_patternxmethod!lift_Parsetree_structurestr=List.fold_right(function|{pstr_desc=Pstr_extension(({txt="s";loc},e),_);_}->append(get_exploce)|x->cons(super#lift_Parsetree_structure_itemx))str(nil())method!lift_Parsetree_signaturesign=List.fold_right(function|{psig_desc=Psig_extension(({txt="s";loc},e),_);_}->append(get_exploce)|x->cons(super#lift_Parsetree_signature_itemx))sign(nil())method!lift_Parsetree_core_type=function|{ptyp_desc=Ptyp_extension({txt="t";loc},e);_}->map(get_exploce)|x->super#lift_Parsetree_core_typexendletpat_liftermap=letmap=map.Ast_mapper.patmapinobjectinherit[_]Ast_lifter.lifterassuperinheritpat_builderasbuilder(* Special support for location and attributes in the generated AST *)method!lift_Location_t_=Pat.any()method!lift_Parsetree_attributes_=Pat.any()method!recordnfields=letfields=List.map(fun(name,pat)->matchnamewith|"pexp_loc_stack"|"ppat_loc_stack"|"ptyp_loc_stack"->name,Pat.any()|_->name,pat)fieldsinbuilder#recordnfields(* Support for antiquotations *)method!lift_Parsetree_expression=function|{pexp_desc=Pexp_extension({txt="e";loc},e);_}->map(get_patloce)|x->super#lift_Parsetree_expressionxmethod!lift_Parsetree_pattern=function|{ppat_desc=Ppat_extension({txt="p";loc},e);_}->map(get_patloce)|x->super#lift_Parsetree_patternxmethod!lift_Parsetree_core_type=function|{ptyp_desc=Ptyp_extension({txt="t";loc},e);_}->map(get_patloce)|x->super#lift_Parsetree_core_typexendletloc=ref(app(evar"Stdlib.!")[evar"Ast_helper.default_loc"])lethandle_attr=function|{attr_name={txt="metaloc";loc=l};attr_payload=e;_}->loc:=get_exple|_->()letwith_loc?(attrs=[])f=letold_loc=!locinList.iterhandle_attrattrs;letr=f()inloc:=old_loc;rletexpander_args=letopenAst_mapperinletsuper=default_mapperinletexprthise=with_loc~attrs:e.pexp_attributes(fun()->matche.pexp_descwith|Pexp_extension({txt="expr";loc=l},e)->(exp_lifter!locthis)#lift_Parsetree_expression(get_exple)|Pexp_extension({txt="pat";loc=l},e)->(exp_lifter!locthis)#lift_Parsetree_pattern(get_patle)|Pexp_extension({txt="str";_},PStre)->(exp_lifter!locthis)#lift_Parsetree_structuree|Pexp_extension({txt="stri";_},PStr[e])->(exp_lifter!locthis)#lift_Parsetree_structure_iteme|Pexp_extension({txt="sig";_},PSige)->(exp_lifter!locthis)#lift_Parsetree_signaturee|Pexp_extension({txt="sigi";_},PSig[e])->(exp_lifter!locthis)#lift_Parsetree_signature_iteme|Pexp_extension({txt="type";loc=l},e)->(exp_lifter!locthis)#lift_Parsetree_core_type(get_typle)|_->super.exprthise)andpatthisp=with_loc~attrs:p.ppat_attributes(fun()->matchp.ppat_descwith|Ppat_extension({txt="expr";loc=l},e)->(pat_lifterthis)#lift_Parsetree_expression(get_exple)|Ppat_extension({txt="pat";loc=l},e)->(pat_lifterthis)#lift_Parsetree_pattern(get_patle)|Ppat_extension({txt="str";_},PStre)->(pat_lifterthis)#lift_Parsetree_structuree|Ppat_extension({txt="stri";_},PStr[e])->(pat_lifterthis)#lift_Parsetree_structure_iteme|Ppat_extension({txt="sig";_},PSige)->(pat_lifterthis)#lift_Parsetree_signaturee|Ppat_extension({txt="sigi";_},PSig[e])->(pat_lifterthis)#lift_Parsetree_signature_iteme|Ppat_extension({txt="type";loc=l},e)->(pat_lifterthis)#lift_Parsetree_core_type(get_typle)|_->super.patthisp)andstructurethisl=with_loc(fun()->super.structurethisl)andstructure_itemthisx=beginmatchx.pstr_descwith|Pstr_attributex->handle_attrx|_->()end;super.structure_itemthisxandsignaturethisl=with_loc(fun()->super.signaturethisl)andsignature_itemthisx=beginmatchx.psig_descwith|Psig_attributex->handle_attrx|_->()end;super.signature_itemthisxin{superwithexpr;pat;structure;structure_item;signature;signature_item}letmain()=Ast_mapper.run_mainexpanderend