GitXplorerGitXplorer
j

ppx_optcomp_old

public
1 stars
1 forks
0 issues

Commits

List of commits on branch master.
Unverified
5cda72176fabc275a9f6538e9731fd98c3a3651b

v0.11.117.03+59

ttrefis committed 7 years ago
Unverified
0adb062d7aec17805fe243139743b15a51aa7bd6

v0.11.117.00+101

ttrefis committed 7 years ago
Unverified
fd915241eefbaef22a56643a006875c837a839a3

v0.11.116.17+187

ttrefis committed 7 years ago
Unverified
4ebf1d8f692612b72e639b6e760491e263dfc76e

v0.10.116.15+15

ttrefis committed 7 years ago
Unverified
d2807f64d318d3b4983dae2a3d63927ed82989ba

update dep on migrate-parsetree to new version

ttrefis committed 7 years ago
Unverified
4f0b6749095cc07e9d2bcc60b09520bda20b168f

v0.10.116.14+12

ttrefis committed 7 years ago

README

The README file for this repository.

ppx_optcomp_old - Optional compilation for OCaml (deprecated)

WARNING ppx_optcomp_old is the old ppx_optcomp. It is a text preprocessor rather than a pure ppx rewriter like the new ppx_optcomp. ppx_optcomp_old is deprecated and its use is strongly discouraged. In order to upgrade to the new syntax, write this in your jbuild file:

(library
 (...
  (preprocess (pps (... ppx_optcomp_old -upgrade-optcomp-syntax)))))

then run jbuilder build --auto-promote. This will override the source files by ones using the new syntax. The resulting files might need to be tweaked as sometimes the upgrade produce invalid files.

Old README

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 parsed
  • if 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 and false
  • let-bindings
  • pattern matching

And it provides the following functions:

  • comparison operators: =, <, ...
  • boolean operators: ||, &&, not, ...
  • arithmetic operators: +, -, *, /
  • min and max
  • fst and snd
  • 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.