phrep

Artifact [2008bd7b4e]
Login

Artifact 2008bd7b4e8651b68dfe4a5c3c68681a261fb33d:

Wiki page [expressions] by mario 2015-03-19 15:55:21.
D 2015-03-19T15:55:21.248
L expressions
N text/x-markdown
P 156397bff1364e3b3707d7633cf7c103805b71d3
U mario
W 2253
Phrep includes a simple expression evaluator for `#if` and `#elif`
directives.  It allows for most common operations:

  * Arithmetic

        #if 7 / 2 - 5 + 2.5

  * Comparison

        #if 12 > 3

  * Constant substitution and tests

        #if CONST > 2.0.0-beta

  * Regex comparisons (case-insensitive)

        #if !(VER =~ beta)

  * Alternatives of course

        #if X>0 || Y && Z<0

  * Constant checks via `defined()` function

        #if defined(WHATEVER)

    Works basically just like `#ifdef`. There's also a `pragma(..)` function
    to look up current processing options.

  * And allows to use a few elected PHP functions:

        #if is_int(strpos(abc, b))

    Simple file checks even:

        #if file_exists("lib/scope.php")

    One can also use strpos, stripos, strstr, stristr, is_int, is_float, is_numeric, 
    max, min, function_exists, and class_exists.

  * Invalid expressions:

        #if (1 + - / 0)

    Will obviously fail. In the default mode, this will simply
    skip the condition as falsy (with a warning). In the
    <kbd>-W</kbd> or `#pragma(fail=1)` mode, it'll however
    abort further preprocessing.


The expression evaluation is mostly careless with types.

  * It mostly expands both literal `CONST_NAMES` as well as string-quoted
    `"CONST_NAMES"` eagerly.

  * Even numbers may be quoted `"1" + "2" == "3"`. (Which suits the most
    common use cases though.)

  * And it does all comparisions under the presumption they could be version
    numbers. For example `1.2 > 2.3` is a version comparison, as is
    `"PKG_VERSION" >= 2.0.0`. (Relying on PHPs [version_compare](http://php.net/version_compare)
    internally. Though could switch to plain float fallbacks later..)

  * Only function names and operators must be noted literally (`defined`,
    not `"defined"` as string).

It's somewhat of an gimmick anyway.  You don't commonly need a lot of
conditions to control a build/preprocessing run (`#ifdef` often suffices).

The `MacroExpression` handler is mainly there for some crude compatibility
with CPP and preprocess.py.  Converting expressions into PHP evaluable code
would just have been more work.  Probably.

Z e9f8e6e3b3a9e3673ecf8e1e16ff8700