You are here

public function ctools_math_expr::evaluate in Chaos Tool Suite (ctools) 7

Same name and namespace in other branches
  1. 6 includes/math-expr.inc \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 = 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 = $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)), '"');
  }
}