value = $value; } /** * Returns the value of this expression. * * @param Context $context symbol table */ public function value($context) { return $this->value; } } /** * SymbolExpression represents a symbol (template variable). */ class SymbolExpression implements Expression { protected $name; /** * Initializes a new Expression instance. * * @param string $name symbol name */ public function __construct($name) { $this->name = $name; } /** * Returns the name of this symbol. */ public function name() { return $this->name; } /** * Returns the value of this expression. * * @param Context $context symbol table */ public function value($context) { return $context->lookup($this->name); } } /** * UnaryExpression represents a unary operator. */ abstract class UnaryExpression implements Expression { protected $expr; /** * Initializes a new Expression instance. * * @param Expression $expr expression object */ public function __construct(Expression $expr) { $this->expr = $expr; } } /** * MinusExpression represents the unary minus operator ('-'). */ class MinusExpression extends UnaryExpression { /** * Returns the value of this expression. * * @param Context $context symbol table */ public function value($context) { return -$this->expr->value($context); } } /** * NotExpression represents the logical negation operator ('!'). */ class NotExpression extends UnaryExpression { /** * Returns the value of this expression. * * @param Context $context symbol table */ public function value($context) { return !$this->expr->value($context); } } /** * RawExpression represents the "raw" filter function. */ class RawExpression extends UnaryExpression { /** * Returns the value of this expression. * * @param Context $context symbol table */ public function value($context) { return $this->expr->value($context); } } /** * BinaryExpression represents a binary operator. */ abstract class BinaryExpression implements Expression { protected $left, $right; protected $operator; /** * Initializes a new Expression instance. * * @param Expression $left left operand * @param Expression $right right operand * @param mixed $operator operator token */ public function __construct(Expression $left, Expression $right, $operator) { $this->left = $left; $this->right = $right; $this->operator = $operator; } } /** * ArithExpression represents an arithmetic operator. */ class ArithExpression extends BinaryExpression { /** * Returns the value of this expression. * * @param Context $context symbol table */ public function value($context) { $left = $this->left->value($context); $right = $this->right->value($context); switch ($this->operator) { case '+': return $left + $right; case '-': return $left - $right; case '*': return $left * $right; case '/': return $left / $right; case '%': return $left % $right; case '~': return $left . $right; } } } /** * IndexExpression represents the array index operator. */ class IndexExpression extends BinaryExpression { /** * Returns the value of this expression. * * @param Context $context symbol table */ public function value($context) { $left = $this->left->value($context); $right = $this->right->value($context); return $left[$right]; } } /** * BooleanExpression represents a boolean operator. */ class BooleanExpression extends BinaryExpression { /** * Returns the value of this expression. * * @param Context $context symbol table */ public function value($context) { $left = $this->left->value($context); $right = $this->right->value($context); switch ($this->operator) { case T_IS_EQUAL : return $left == $right; case T_IS_NOT_EQUAL : return $left != $right; case '<' : return $left < $right; case T_IS_SMALLER_OR_EQUAL: return $left <= $right; case '>' : return $left > $right; case T_IS_GREATER_OR_EQUAL: return $left >= $right; case T_BOOLEAN_AND : return $left && $right; case T_BOOLEAN_OR : return $left || $right; } } } /** * ConditionExpression represents the conditional operator ('?:'). */ class ConditionExpression implements Expression { protected $condition; protected $left, $right; /** * Initializes a new Expression instance. * * @param Expression $condition expression * @param Expression $left left alternative * @param Expression $right right alternative */ public function __construct($condition, $left, $right) { $this->condition = $condition; $this->left = $left; $this->right = $right; } /** * Returns the value of this expression. * * @param Context $context symbol table */ public function value($context) { return $this->condition->value($context) ? $this->left->value($context) : $this->right->value($context); } } /** * FunctionExpression represents a function call. */ class FunctionExpression implements Expression { protected $name; protected $arguments; /** * Initializes a new Expression instance. * * @param Expression $name function name * @param array $arguments function arguments */ public function __construct(Expression $name, $arguments) { $this->name = $name; $this->arguments = $arguments; } /** * Returns the value of this expression. * * @param Context $context symbol table */ public function value($context) { $callable = $this->name->value($context); $arguments = array(); foreach ($this->arguments as $expr) { $arguments[] = $expr->value($context); } if ($callable instanceof \Closure) { return call_user_func_array($callable, $arguments); } return NULL; } }