Standard library for ppx rewriters
Module type
Class type
Library ppxlib
module Located : sig ... end
val pdir_int : loc:Astlib.Location.t -> string -> char option -> Astlib.Ast_500.Parsetree.directive_argument
val include_infos : loc:Astlib.Location.t -> 'a -> 'a Astlib.Ast_500.Parsetree.include_infos
val location : start:Lexing.position -> end_:Lexing.position -> ghost:bool -> Astlib.Location.t
val position : fname:string -> lnum:int -> bol:int -> cnum:int -> Lexing.position
val value_description : loc:Astlib.Location.t -> name:string Astlib.Location.loc -> type_:Astlib.Ast_500.Parsetree.core_type -> prim:string list -> Astlib.Ast_500.Parsetree.value_description
module Latest : sig ... end

This module contains updated versions of node constructors that were kept stable when the node changed. For every function in this module, there's an equally-named function outside this module. The function outside this module will stay stable, whereas the function inside this module will adapt potential upcoming new compiler features. Only use a function in this module, if the equally-named one outside this module is missing a feature you need.

val estring : loc:Location.t -> string -> Astlib.Ast_500.Parsetree.expression
val efloat : loc:Location.t -> string -> Astlib.Ast_500.Parsetree.expression
val eint32 : loc:Location.t -> int32 -> Astlib.Ast_500.Parsetree.expression
val eint64 : loc:Location.t -> int64 -> Astlib.Ast_500.Parsetree.expression
val enativeint : loc:Location.t -> nativeint -> Astlib.Ast_500.Parsetree.expression
val pchar : loc:Location.t -> char -> Astlib.Ast_500.Parsetree.pattern
val pstring : loc:Location.t -> string -> Astlib.Ast_500.Parsetree.pattern
val pfloat : loc:Location.t -> string -> Astlib.Ast_500.Parsetree.pattern
val pint32 : loc:Location.t -> int32 -> Astlib.Ast_500.Parsetree.pattern
val pint64 : loc:Location.t -> int64 -> Astlib.Ast_500.Parsetree.pattern
val pnativeint : loc:Location.t -> nativeint -> Astlib.Ast_500.Parsetree.pattern
val pbool : loc:Location.t -> bool -> Astlib.Ast_500.Parsetree.pattern

evar id produces a Pexp_ident _ expression, it parses its input so you can pass any dot-separated identifier, for instance: evar ~loc "Foo.bar".

val pvar : loc:Location.t -> string -> Astlib.Ast_500.Parsetree.pattern

pstr_value_list ~loc rf vbs = pstr_value ~loc rf vbs if vbs <> [], [] otherwise.

val unapplied_type_constr_conv : loc:Location.t -> Longident.t Loc.t -> f:( string -> string ) -> Astlib.Ast_500.Parsetree.expression

unapplied_type_constr_conv is the standard way to map identifiers to conversion fonctions, for preprocessor that creates values that follow the structure of types. More precisely, path_conv path (sprintf "sexp_of_%s") is:

  • sexp_of_t if path is "t"
  • A.B.sexp_of_foo if path is "A.B.foo"
  • A.B.sexp_of_f__foo (module A1) (module A2) if path is "A.B.F(A1)(A2).foo" type_constr_conv also applies it to a list of expression, which both prevents the compiler from allocating useless closures, and almost always what is needed, since type constructors are always applied.
val type_constr_conv : loc:Location.t -> Longident.t Loc.t -> f:( string -> string ) -> Astlib.Ast_500.Parsetree.expression list -> Astlib.Ast_500.Parsetree.expression

Tries to simplify fun v1 v2 .. -> f v1 v2 .. into f. Only works when f is a path, not an arbitrary expression as that would change the meaning of the code. This can be used either for cleaning up the generated code, or to reduce allocation if f is a local variable (the compiler won't optimize the allocation of the closure).

Eta-reduction can change the types/behavior in some corner cases that are unlikely to show up in generated code:

  • if f has optional arguments, eta-expanding f can drop them
  • because labels commute, it can change the type of an expression: $ let f ~x y = x + y let f2 = fun x -> add x;; val f : x:int -> int -> int = <fun> val f2 : int -> x:int -> int = <fun> In fact, if f does side effects before receiving all its arguments, and if the eta-expansion is partially applied, eta-reducing could change behavior.

eta_reduce_if_possible_and_nonrec is meant for the case where the resulting expression is going to be bound in a potentially recursive let-binding, where we have to keep the eta-expansion when rec_flag is Recursive to avoid a compile error.