module Delimited_overloading:(submodule of`sig`

..`end`

`Pa_do`

) Syntax extension module to enable easy `X1.X2...Xk.(expr)`

are automatically
transformed, substituting constants, operators, and functions in
`expr`

and possibly optimizing the resulting expression. For
example, you can write `Float.(1 + x / 3)`

and it will be just as
if you wrote `1.0 +. x /. 3.0`

.
This library comes with overloadings of arithmetic and comparison
operators for all standard OCaml numeric types, namely `Int`

,
`Float`

, `Complex`

, `Int32`

, `Int64`

, `Nativeint`

, `Num`

,
`Big_int`

, and `Ratio`

(the latter three are in `Pa_do_nums`

since they require to load `nums.cma`

for compile time checks).
Where applicable the functions `lsl`

, `lsr`

, `land`

, `lor`

,
`succ`

, `pred`

, `floor`

, `max`

, `min`

, `abs`

, `truncate`

,... are
also overloaded.

There are two ways of using this syntax extension to define your own overloadings.

**1. Creating a camlp4 syntax module**

Here you create a file, say my_syntax.ml, and use the API below to define your overloadings. This is the recommended and more powerful way.

**2. Using the concrete syntax**

From time to time, you'll find that you need a quick way to
overload operators for a module you just defined. In this case,
you can the concrete syntax which allows simple overloading to be
defined. Given a module longident `X`

(i.e. `X`

has the form
`X1.X2...Xk`

for some modules `X1`

, `X2`

,..., `Xk`

), you can use

```
OVERLOAD X (op1 -> f1; op2 -> f2; ...)
```

to mean that `op1`

should be replaced by `X.f1`

, etc. Note that,
if unqualified, the functions `f1`

, `f2`

,... will be automatically
qualified by the module `X`

. They are untouched if they are
prefixed by a module (hence the complete module path must then be
provided). For example, if you set ```
OVERLOAD X((+) -> add; succ ->
succ)
```

, then the expression `X.(x + succ y)`

will be transformed
into `A.add x (X.succ y)`

. The shortcut `OVERLOAD X (f)`

means
`OVERLOAD X (f -> f)`

. You can overload literal values using
```
OVERLOAD_INT X(f) (* the argument of f is an int *)
OVERLOAD_FLOAT X(f) (* the argument of f is a float *)
OVERLOAD_INT32 X(f) (* the argument of f is an int32 *)
OVERLOAD_INT64 X(f) (* the argument of f is an int64 *)
OVERLOAD_NATIVEINT X(f) (* the argument of f is a nativeint *)
OVERLOAD_STRING X(f) (* the argument of f is a string *)
OVERLOAD_POLY_VAR X(f) (* the argument of f is a string *)
```

which will replace any constant `x`

with `f x`

. The meaning of
common constructions can also be changed:
```
OVERLOAD_ARRAY_GET X(f) (* [a.(i)] is transformed into [X.f a i] *)
OVERLOAD_ARRAY_SET X(f) (* [a.(i) <- x] is transformed into [X.f a i x] *)
OVERLOAD_BIGARRAY_GET X(f) (* [a.{i1,...,iN})] is transformed into
[X.f a [| i1;...; iN |]] *)
OVERLOAD_BIGARRAY_SET X(f) (* [a.{i1,...,iN} <- x] is transformed into
[X.f a [| i1;...; iN |] x] *)
OVERLOAD_STRING_GET X(f) (* [a.[i]] is transformed into [X.f a i] *)
OVERLOAD_STRING_SET X(f) (* [a.[i] <- x] is transformed into [X.f a i x] *)
OVERLOAD_ASSIGN_REF X(f) (* [a := x] is transformed into [X.f a x] *)
OVERLOAD_RECORD_FIELD X(field1; ...; fieldN) (* qualifies the fields *)
```

As a convenience, you can use `OVERLOAD_ARITHMETIC X`

to overload
the usual arithmetic operators (see
`Delimited_overloading.std_arithmetic`

) and ```
OVERLOAD_COMPARISON
X(cmp)
```

to interpret comparison operators using the compare
function `cmp`

(see `Delimited_overloading.comparison`

for more
details). As it is a common case, you can use the shortcut
`OVERLOAD_COMPARISON X`

for `OVERLOAD_COMPARISON X(compare)`

.
You can add to `X`

the overloadings defined in another module
longident, say `Y`

, by doing `OVERLOAD X inherit Y`

. The
functions of `Y`

will be re-qualified by the module `X`

(i.e. `Y.f`

will become `X.f`

). To avoid that requalification,
use `OVERLOAD X = Y`

(further overloads added to `X`

will also be
qualified by the same module used to qualify the overloadings of
`Y`

). This latter form is for example useful to use a shorter
name for a given overloading. Finally, you can use

```
OVERLOAD_OPENIN X
```

(resp. `OVERLOAD_OPENIN X(false)`

) to enable (resp. disable) the
opening of the module `M`

in `e`

for an expression like `M.(e)`

.
In all the above directives `X`

can have the special value
`DEFAULT`

. Setting overloadings for `DEFAULT`

will apply these
overloadings to all modules for which no specific overloadings
have been set.

*Remark:* Saving constant expressions to avoid evaluating them
more than once (see `Delimited_overloading.int`

) is not enabled
for the concrete syntax. This is because the module to be
overloaded is usually defined in the same source file and
therefore will not be known by the bindings put at the beginning
of the source file.

**Author(s):** Dany Maslowski, Julie De Pril, Christophe Troestler

`type `

t

Type representing an immutable "set of overloadings".

type`module_longident =`

`Macro.Module_longident.t`

Type representing a module longident, i.e. a "sequence" of
modules like

`A.B.C`

.type`reloc_expr =`

`module_longident ->`

Camlp4.PreCast.Syntax.Ast.Loc.t -> Camlp4.PreCast.Syntax.Ast.expr

A relocatable expression, i.e. an expression parametrized by a
module name and a location.

The purpose is as follows. Suppose we want to overload `"+"`

with `add`

. `add`

must be qualified with the module to which it
belongs. However we do not know yet what that module will be
because we want to use this overloading with several modules.
The same goes for the location: for correct error reporting, the
location of the subtituted expression must be the location of
`"+"`

wich is currently unknown. Thus the right way to declare
the overloading of `+`

is using ```
fun m _loc -> qualify_lid add m
_loc
```

, where `qualify_lid`

is explained below.

`exception Invalid_identifier of ``string`

`Invalid_identifier m`

is raised to indicate that the
string `m`

is not a valid identifier (lowercase or operator).`val empty : ``t`

Empty set of overloadings.

`val concat : ``t -> t -> t`

`concat t1 t2`

"concatenates" the overloadings in `t1`

and `t2`

.
If a constant, string, identifier,... has been overloaded in
`t1`

and in `t2`

, then the overloading of `t2`

is the one
present in the result of `concat`

.`val qualify_lid : ``string -> reloc_expr`

`qualify_lid lid m _loc`

returns the expression of the operator
or function name `lid`

qualified with the module longident `m`

.
See `reloc_expr`

for a use case of this function.`val int : ``t ->`

?cache:bool ->

(int -> reloc_expr) -> t

`int t f`

return the same "set of overloadings" that `t`

with the new
function `f`

that specifies how integer constants are overloaded for `t`

.`cache`

: if `true`

(the default), for any literal `i`

, binds
the expression transforming `i`

at the beginning of the source
file so it is only evaluated once. The overloaded module must
therefore be know at for the whole source (this is generally the
case for a library) and it is advised to use fully qualified names.`val float : ``t ->`

?cache:bool ->

(float -> reloc_expr) -> t

`float t f`

return the same "set of overloadings" that `t`

with the new
function `f`

that specifies how float constants are overloaded for `t`

.`cache`

: see `Delimited_overloading.int`

.`val nativeint : ``t ->`

?cache:bool ->

(nativeint -> reloc_expr) -> t

`nativeint t f`

return the "set of overloadings" `t`

augmented with the
new function `f`

that specifies how nativeint constants are overloaded
for `t`

.`cache`

: see `Delimited_overloading.int`

.`val int32 : ``t ->`

?cache:bool ->

(int32 -> reloc_expr) -> t

`int32 t f`

return the "set of overloadings" `t`

augmented with the new
function `f`

that specifies how int32 constants are overloaded for `t`

.`cache`

: see `Delimited_overloading.int`

.`val int64 : ``t ->`

?cache:bool ->

(int64 -> reloc_expr) -> t

`int64 t f`

return the "set of overloadings" `t`

augmented with the new
function `f`

that specifies how int64 constants are overloaded for `t`

.`cache`

: see `Delimited_overloading.int`

.`val string : ``t ->`

?cache:bool ->

check:(string -> 'a) ->

?to_type:(string -> string) ->

(string -> reloc_expr) -> t

`string t f`

return the "set of overloadings" `t`

augmented with the new
function `f`

that specifies how string constants are overloaded for `t`

.`cache`

: see `Delimited_overloading.int`

.`check`

: a function that checks that the string represent a
valid value. If it does not, it is expected that `check`

raise
an exception (which one is unimportant).`to_type`

: Allows to customize the error message in case
`check`

fails. `to_type`

receive the module name and is
expected to return a string characterizing the type of the
expected value. Default: identity.`val poly_var : ``t ->`

?cache:bool ->

check:(string -> 'a) ->

?to_type:(string -> string) ->

(string -> reloc_expr) -> t

`poly_var t f`

return the "set of overloadings" `t`

augmented with the new
function `f`

that specifies how the `t`

. The string argument of `f`

is the name of the
polymorphic variant (for example `abc`

is the name of ``abc`

).`cache`

: see `Delimited_overloading.int`

.`val list : ``t ->`

(Camlp4.PreCast.Syntax.Ast.expr list -> reloc_expr) ->

t

`list t f`

return the "set of overloadings" `t`

augmented with the new
function `f`

that specifies how list constants are overloaded for `t`

.`val array : ``t ->`

(Camlp4.PreCast.Syntax.Ast.expr list -> reloc_expr) ->

t

`array t f`

return the "set of overloadings" `t`

augmented with the new
function `f`

that specifies how array constants are overloaded for `t`

.
Note that `Ast.exSem_of_list`

may be useful to group the expressions into
a single one.`val array_get : ``t ->`

(Camlp4.PreCast.Syntax.Ast.expr ->

Camlp4.PreCast.Syntax.Ast.expr -> reloc_expr) ->

t

`array_get t f`

return the "set of overloadings" `t`

augmented with the
new function `f`

that specifies how the construction `a.(i)`

is overloaded
for `t`

. Expressions like `a.(i)`

, where `a`

and `i`

are expressions,
will be transformed into `f a i _loc`

where `_loc`

is the location of
`a.(i)`

.`val array_set : ``t ->`

(Camlp4.PreCast.Syntax.Ast.expr ->

Camlp4.PreCast.Syntax.Ast.expr ->

Camlp4.PreCast.Syntax.Ast.expr -> reloc_expr) ->

t

`array_set t f`

return the "set of overloadings" `t`

augmented with the
new function `f`

that specifies how the construction `a.(i) <- x`

is
overloaded for `t`

. Expressions like `a.(i) <- x`

, where `a`

, `i`

, and
`x`

are expressions, will be transformed into `f a i x _loc`

where `_loc`

is the location of `a.(i) <- x`

.`val string_get : ``t ->`

(Camlp4.PreCast.Syntax.Ast.expr ->

Camlp4.PreCast.Syntax.Ast.expr -> reloc_expr) ->

t

Same as

`array_get`

but for `a.[i]`

.`val string_set : ``t ->`

(Camlp4.PreCast.Syntax.Ast.expr ->

Camlp4.PreCast.Syntax.Ast.expr ->

Camlp4.PreCast.Syntax.Ast.expr -> reloc_expr) ->

t

Same as

`array_set`

but for `a.[i] <- x`

.`val bigarray_get : ``t ->`

(Camlp4.PreCast.Syntax.Ast.expr ->

Camlp4.PreCast.Syntax.Ast.expr list -> reloc_expr) ->

t

Same as

`array_get`

but for `a.{i1,...,iK}`

.`val bigarray_set : ``t ->`

(Camlp4.PreCast.Syntax.Ast.expr ->

Camlp4.PreCast.Syntax.Ast.expr list ->

Camlp4.PreCast.Syntax.Ast.expr -> reloc_expr) ->

t

Same as

`array_set`

but for `a.{i1,...,iK} <- x`

.`val assign : ``t ->`

(Camlp4.PreCast.Syntax.Ast.expr ->

Camlp4.PreCast.Syntax.Ast.expr -> reloc_expr) ->

t

`assign t f`

return the "set of overloadings" `t`

augmented with the new
function `f`

that specifies how the assignment is overloaded for `t`

.
More precisely, expressions `a <- x`

will be replaced by `f a x _loc`

where `_loc`

is the location of `a <- x`

.`val assign_ref : ``t ->`

(Camlp4.PreCast.Syntax.Ast.expr ->

Camlp4.PreCast.Syntax.Ast.expr -> reloc_expr) ->

t

`assign t f`

return the "set of overloadings" `t`

augmented with the new
function `f`

that specifies how the reference assignment is overloaded
for `t`

. More precisely, expressions `a := x`

will be replaced by
`f a x _loc`

where `_loc`

is the location of `a := x`

.`val lid : ``t ->`

?cache:bool ->

string -> reloc_expr -> t

`lid t op e`

return the set of overloadings `t`

augmented with
the transformation of the identifier `op`

in the relocatable
expression `e`

.`cache`

: if `false`

, camlp4 will just replace `op`

with the
expression `a`

. If `true`

, camlp4 will be bind the expression
`e`

to an identifier and use that identifier for all occurrences
of `e`

(this is interesting if `e`

is a complicated function for
example). Default: `true`

as a very small benefit can be seen
on `Int32`

and `Int64`

benchmarks.`val lid_subst : ``t -> (string * string) list -> t`

`lid_subst t ov`

return the set of overloadings `t`

augmented
with the transformations of the identifier `op`

in the
identifier `op'`

for all `(op, op')`

in the list `ov`

. The
identifiers `op'`

will be qualified by the module to which the
result is linked. In other words, if you set ```
let t' =
lid_subst t ["+", "add"]
```

and `t'`

is linked with the module
longident `M`

, then `M.(a + b)`

will be transformed into ```
M.add
a b
```

.`val std_arithmetic : ``t -> t`

`std_arithmetic t`

is just a shortcut for ```
lid_subst t
[("+","add"); ("-","sub"); ("~-", "neg"); ("*","mul");
("/","div")]
```

. Note that the unary negation, `~-`

, is
overloaded as well.`val comparison : ``?cache:bool ->`

?cmp:string -> t -> t

`comparison ?cmp t`

return the set of overloadings `t`

augmented
with the transformations for comparison operators `=`

, `<>`

,
`<`

, `>`

, `<=`

, and `>=`

using the function name `cmp`

to
overload them. In other words, the expression `M.(a = b)`

will
be substituted by `M.cmp a b = 0`

(where the last equality is
the standard one on integers), `M.(a < b)`

will be transformed
into `M.cmp a b < 0`

, etc.
Associated `min`

and `max`

functions are also defined.

`cache`

: whether to cache the comparison functions built
from `cmp`

. It is generally a good idea to do so
(e.g. speed-wise).`cmp`

: the name of the comparison function to use. It will
be automatically qualified by the module to which the result is
linked. Default: `compare`

.`val lid_remove : ``t -> string list -> t`

`lid_remove t l`

return the set of overloadings `t`

with all
overloadings for a lowercase identifier or an operator in the
list `l`

removed.`type `

transf

Represents a "stack" of expression transformation functions.

type`transf_fun =`

`transf ->`

Camlp4.PreCast.Syntax.Ast.expr -> Camlp4.PreCast.Syntax.Ast.expr

`val transf_module : ``transf -> module_longident`

`val transf_qualify : ``transf ->`

string -> Camlp4.PreCast.Syntax.Ast.Loc.t -> Camlp4.PreCast.Syntax.Ast.expr

`transf_qualify tr lid _loc`

qualify `lid`

by the module
longident used to apply the overloadings. This is a shortcut
for `qualify_lid lid (transf_module tr) _loc`

.`val self : ``transf -> Camlp4.PreCast.Syntax.Ast.map`

`self tr`

returns the complete transformation object (closed
complete when using `apply`

) allowing to apply it to
sub-formulas. For example, to recurse on a subexpression `e`

,
use `(self tr)#expr e`

.`val super : ``transf_fun`

When adding a new transformation,

`super tr`

is the previous
transformation that the new one may override.`val expr : ``t ->`

transf_fun -> t

`expr t f`

returns a new set of overloadings which executes
the transformation `f`

first. The location of `f tr e m`

should
be the same as `e`

; use the function `Ast.loc_of_expr`

to
retrieve the location from `e`

. A typical function `f`

is as
follows:
```
let f tr e =
let _loc = Ast.loc_of_expr e in
match e with
| ... e ... -> ... (self tr)#expr e ... (* recurse on expression [e] *)
| ...
| _ -> super tr e
```

Note that the recusion on sub-expressions of `e`

will apply `f`

to these subexpressions too.
The fact that `self tr`

is a transversal on the AST allows to
apply it to various kind of subformulas (e.g. for a recursive
binding, use `(self tr)#rec_binding`

).`val expr_fold : ``t ->`

(self:('a -> transf -> Camlp4.PreCast.Syntax.Ast.map) ->

super:('a -> transf_fun) ->

'a -> transf_fun) ->

'a -> t

`expr_fold f a0`

is the same as `Delimited_overloading.expr`

except that it allows to carry down information while parsing
the AST. More precisely, the first time ```
f ~self ~super a tr e
m
```

is called, `a = a0`

and, when you recurse down the AST with
`self a tr`

or `super a tr`

, you state that the new value `a`

must be used for subsequent calls of `f`

on the subtree. The
preceding `self`

and `super`

may also be used in cases one wants
to recurse without changing the value of `a`

.`val before : ``t -> (unit -> unit) -> t`

`before t f`

add `f`

to the list of functions to execute before
performing an overloading. The functions given last are executed
first. This is executed once for each construction `M.(e)`

where
`M`

is the module name to which `t`

is bound. Recall that
an overloading may occur inside another one.`val after : ``t ->`

(Camlp4.PreCast.Syntax.Ast.expr -> Camlp4.PreCast.Syntax.Ast.expr) ->

t

`after t f`

perform the transformation `f e`

after the overloading
have been preformed -- i.e. `e`

is the final expression without
overloaded expression. The functions given last are executed
last. This is useful for example to prefix the expression with
some declarations.`val openin : ``?remove:bool -> t -> t`

Set (default) or disable (with

`~remove:true`

) the opening of
the module `M`

for the expression `e`

when using `M.(e)`

.
Since version 0.8.13, modules are by default opened to be
compatible with OCaml 3.12 notation `M.(e)`

.`val apply : ``t ->`

module_longident ->

Camlp4.PreCast.Syntax.Ast.expr -> Camlp4.PreCast.Syntax.Ast.expr

`apply t m e`

apply the overloadings in `t`

to the expression
`e`

. The overloadings will be resolved for sub-expressions `e'`

of `e`

appearing in `e`

as `M.(e')`

where `M`

is the module name
contained in `m`

.`val associate : ``t -> ?qualify:string -> string -> unit`

`associate_t t m`

links the "set of overloadings" `t`

to the
module longident `m`

. For example ```
let t = std_arithmetic empty
in associate t "I"
```

implies that `I.(x + y * z)`

will be
transformed into `I.add x (I.mul y z)`

.`Invalid_module_longident`

if `m`

does not have the form of
a module longident.`qualify`

: allows to specify a module different from `m`

for
the qualidifcation of the relocatable expressions in the
overloading `t`

(this is interesting if several overloadings are
defined for a given library).module Default:`sig`

..`end`

Default overloadings (initially not set).

module Suspend:`sig`

..`end`

Suspension of overloading for certain modules.

`val new_lid : ``unit -> string`

`new_lid()`

returns the name of a new lowercase identifier.`val is_immediate : ``Camlp4.PreCast.Syntax.Ast.expr -> bool`

`is_immediate e`

says whether the expression `e`

is "immediate",
such as a literal number or string, a variable name, a variable
name with type annotation, the dereference of a name,... (assuming
expression is a standard OCaml one). It is an interesting
information in order to decide whether the expression needs to be
bound to a variable to avoid to evaluate it several times.`val add_to_beginning_of_file : ``Camlp4.PreCast.Syntax.Ast.str_item -> unit`

`add_to_beginning_of_file decl`

add `decl`

(a structure item) to
the beginning of the parsed file.`val overloaded : ``string`

The function name that serves to protect already overloaded
expressions. May be removed at any time.

`val suspended : ``string`

For internal purposes only

`val module_square_brackets : ``(module_longident ->`

Camlp4.PreCast.Syntax.Ast.Loc.t ->

Camlp4.PreCast.Syntax.Ast.expr -> Camlp4.PreCast.Syntax.Ast.expr)

Pervasives.ref

Function to be performed on

`M.[ e ]`

.`val module_curly_brackets : ``(module_longident ->`

Camlp4.PreCast.Syntax.Ast.Loc.t ->

Camlp4.PreCast.Syntax.Ast.expr -> Camlp4.PreCast.Syntax.Ast.expr)

Pervasives.ref

Function to be performed on

`M.{ e }`

.