package ppx_optcomp
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=287ccb33f8c50c9cc5ad264b773c93f8b32c646dc98e94472cb1ef3d27e1de06
md5=2e86bd2e41407cb16dcd1a546e43e531
Description
Part of the Jane Street's PPX rewriters collection.
Published: 15 Dec 2017
README
ppx_optcomp - Optional compilation for OCaml
ppx_optcomp stands for Optional Compilation. It is a tool used to handle optional compilations of pieces of code depending of the word size, the version of the compiler, ...
ppx_optcomp can be used a a standalone pre-processor, but is also integrated in the ppx_driver.
The syntax is quite similar to cpp:
#if ocaml_version < (4, 02, 0)
let x = 1
#else
let y = 2
#endif
Note that ppx_optcomp does not support macros like cpp, we only use it for optional compilations.
Syntax
ppx_optcomp runs after the OCaml lexer and before the OCaml parser. This means that parts of the file that are dropped by ppx_optcomp needs to be lexically correct but not grammatically correct.
ppx_optcomp will interpret all lines that start with a #
. #
has to be the first character, if there are spaces before ppx_optcomp will not try to interpret the line and will pass it as-is to the OCaml parser. The syntax is:
#identifier directive-argument
The argument is everything up to the end of the line. You can use \
at the end of lines to span the argument over multiple line. Optcomp will also automatically fetch arguments past the end of line if a set of parentheses is not properly closed.
So for instance one can write:
#if ocaml_version < ( 4
, 02
, 0
)
Note that since ppx_optcomp runs after the lexer it won't interpret lines starting with #
if they are inside another token. So for instance these won't work:
#
-directive inside a string:let x = " #if foo "
#
-directive inside a comment:(* #if foo *)
Directives
Defining variables
#let
pattern=
expression#define
identifier expression
We also allow: #define
identifier. This will define identifier to ()
.
You can also undefine a variable using #undef
identifier.
Conditionals
The following directives are available for conditional compilations:
#if
expression#elif
expression#else
#endif
In all cases expression must be an expression that evaluates to a boolean value. Ppx_optcomp will fail if it is not the case.
For people used to cpp, we also allow these:
#ifdef
identifier#ifndef
identifier#elifdef
identifier#elifndef
identifier
Which will test if a variable is defined. Note that ppx_optcomp will only accept to test if a variable is defined if it has seen it before, in one of #let
, #define
or #undef
. This allows ppx_opcompt to check for typos.
We do however allow this special case:
#ifndef VAR
#define VAR
Warnings and errors
#warning
expression will cause the pre-processor to print a message on stderr.
#error
expression will cause the pre-processor to fail with the following error message.
Note that in both cases expression can be an arbitrary expression.
Imports
Ppx_optcomp allows one to import another file using:
#import
filename
where filename is a string constant. Filenames to import are resolved as follow:
if filename is relative, i.e. doesn't start with
/
, it is considered as relative to the directory of the file being parsedif filename is absolute, i.e. starts with
/
, it is used as it
To keep things simple ppx_optcomp only allows for #
-directives in imported files. The intended use is having this at the beginning of a file:
#import "config.mlh"
Expressions and patterns
ppx_optcomp supports a subset of OCaml expressions and patterns:
literals: integers, characters and strings
tuples
true
andfalse
let-bindings
pattern matching
And it provides the following functions:
comparison operators:
=
,<
, ...boolean operators:
||
,&&
,not
, ...arithmetic operators:
+
,-
,*
,/
min
andmax
fst
andsnd
conversion functions:
to_int
,to_string
,to_char
,to_bool
show
: pretty-print a value
It also provides defined
which is a special function to test if a variable is defined. But the same remark as for #ifdef
applies to defined
.
Dev Dependencies
None
Used by (11)
-
caqti-dynload
< "0.10.2"
-
conduit
>= "0.12.0" & < "1.0.0"
-
eliom
>= "10.1.0"
-
grace
>= "0.2.0"
-
kqueue
>= "0.2.0"
-
pgocaml_ppx
>= "4.2"
- poll
-
ppx_bap
< "v0.14.0"
-
ppx_driver
>= "v0.10.0" & < "v0.11.0"
-
vscoq-language-server
>= "2.1.0+coq8.19"
- yices2_bindings
Conflicts
None