function ctools_math_expr::evaluate

Evaluate the expression.

Parameters

string $expr: The expression to evaluate.

Return value

string|bool The result of the expression, or FALSE if an error occurred, or TRUE if an user-defined function was created.

1 call to ctools_math_expr::evaluate()
ctools_math_expr::e in includes/math-expr.inc
Backwards compatible wrapper for evaluate().

File

includes/math-expr.inc, line 302

Class

ctools_math_expr
ctools_math_expr Class.

Code

public function evaluate($expr) {
    $this->last_error = NULL;
    $expr = trim($expr);
    // Strip possible semicolons at the end.
    if (substr($expr, -1, 1) == ';') {
        $expr = (string) substr($expr, 0, -1);
    }
    // Is it a variable assignment?
    if (preg_match('/^\\s*([a-z]\\w*)\\s*=\\s*(.+)$/', $expr, $matches)) {
        // Make sure we're not assigning to a constant.
        if (in_array($matches[1], $this->constvars)) {
            return $this->trigger("cannot assign to constant '{$matches[1]}'");
        }
        // Get the result and make sure it's good:
        if (($tmp = $this->pfx($this->nfx($matches[2]))) === FALSE) {
            return FALSE;
        }
        // If so, stick it in the variable array...
        $this->vars[$matches[1]] = $tmp;
        // ...and return the resulting value:
        return $this->vars[$matches[1]];
    }
    elseif (preg_match('/^\\s*([a-z]\\w*)\\s*\\(\\s*([a-z]\\w*(?:\\s*,\\s*[a-z]\\w*)*)\\s*\\)\\s*=\\s*(.+)$/', $expr, $matches)) {
        // Get the function name.
        $fnn = $matches[1];
        // Make sure it isn't built in:
        if (isset($this->funcs[$matches[1]])) {
            return $this->trigger("cannot redefine built-in function '{$matches[1]}()'");
        }
        // Get the arguments.
        $args = explode(",", preg_replace("/\\s+/", "", $matches[2]));
        // See if it can be converted to postfix.
        $stack = $this->nfx($matches[3]);
        if ($stack === FALSE) {
            return FALSE;
        }
        // Freeze the state of the non-argument variables.
        for ($i = 0; $i < count($stack); $i++) {
            $token = (string) $stack[$i];
            if (preg_match('/^[a-z]\\w*$/', $token) and !in_array($token, $args)) {
                if (array_key_exists($token, $this->vars)) {
                    $stack[$i] = $this->vars[$token];
                }
                else {
                    return $this->trigger("undefined variable '{$token}' in function definition");
                }
            }
        }
        $this->userfuncs[$fnn] = array(
            'args' => $args,
            'func' => $stack,
        );
        return TRUE;
    }
    else {
        // Straight up evaluation.
        return trim($this->pfx($this->nfx($expr)), '"');
    }
}