You are here

class SassScriptOperation in Sassy 7.3

Same name and namespace in other branches
  1. 7 phamlp/sass/script/SassScriptOperation.php \SassScriptOperation

SassScriptOperation class. The operation to perform. @package PHamlP @subpackage Sass.script

Hierarchy

Expanded class hierarchy of SassScriptOperation

File

phpsass/script/SassScriptOperation.php, line 18

View source
class SassScriptOperation {
  const MATCH = '/^(\\(|\\)|\\+|-|\\*|\\/|%|<=|>=|<|>|==|!=|=|#{|}|,|and\\b|or\\b|xor\\b|not\\b)/';

  /**
   * @var array map symbols to tokens.
   * A token is function, associativity, precedence, number of operands
   */
  public static $operators = array(
    '*' => array(
      'times',
      'l',
      8,
      2,
    ),
    '/' => array(
      'div',
      'l',
      8,
      2,
    ),
    '%' => array(
      'modulo',
      'l',
      8,
      2,
    ),
    '+' => array(
      'plus',
      'l',
      7,
      2,
    ),
    '-' => array(
      'minus',
      'l',
      7,
      2,
    ),
    '<<' => array(
      'shiftl',
      'l',
      6,
      2,
    ),
    '>>' => array(
      'shiftr',
      'l',
      6,
      2,
    ),
    '<=' => array(
      'lte',
      'l',
      5,
      2,
    ),
    '>=' => array(
      'gte',
      'l',
      5,
      2,
    ),
    '<' => array(
      'lt',
      'l',
      5,
      2,
    ),
    '>' => array(
      'gt',
      'l',
      5,
      2,
    ),
    '==' => array(
      'eq',
      'l',
      4,
      2,
    ),
    '!=' => array(
      'neq',
      'l',
      4,
      2,
    ),
    'and' => array(
      'and',
      'l',
      3,
      2,
    ),
    'or' => array(
      'or',
      'l',
      3,
      2,
    ),
    'xor' => array(
      'xor',
      'l',
      3,
      2,
    ),
    'not' => array(
      'not',
      'l',
      3,
      1,
    ),
    '=' => array(
      'assign',
      'l',
      2,
      2,
    ),
    ')' => array(
      'rparen',
      'l',
      1,
    ),
    '(' => array(
      'lparen',
      'l',
      0,
    ),
    ',' => array(
      'comma',
      'l',
      0,
      2,
    ),
    '#{' => array(
      'begin_interpolation',
    ),
    '}' => array(
      'end_interpolation',
    ),
  );

  /**
   * @var array operators with meaning in uquoted strings;
   * selectors, property names and values
   */
  public static $inStrOperators = array(
    ',',
    '#{',
  );

  /**
   * @var array default operator token.
   */
  public static $defaultOperator = array(
    'concat',
    'l',
    0,
    2,
  );

  /**
   * @var string operator for this operation
   */
  private $operator;

  /**
   * @var string associativity of the operator; left or right
   */
  private $associativity;

  /**
   * @var integer precedence of the operator
   */
  private $precedence;

  /**
   * @var integer number of operands required by the operator
   */
  private $operandCount;

  /**
   * SassScriptOperation constructor
   *
   * @param mixed string: operator symbol; array: operator token
   * @return SassScriptOperation
   */
  public function __construct($operation) {
    if (is_string($operation)) {
      $operation = self::$operators[$operation];
    }
    $this->operator = $operation[0];
    if (isset($operation[1])) {
      $this->associativity = $operation[1];
      $this->precedence = $operation[2];
      $this->operandCount = isset($operation[3]) ? $operation[3] : null;
    }
  }

  /**
   * Getter function for properties
   * @param string name of property
   * @return mixed value of the property
   * @throws SassScriptOperationException if the property does not exist
   */
  public function __get($name) {
    if (property_exists($this, $name)) {
      return $this->{$name};
    }
    else {
      throw new SassScriptOperationException('Unknown property: ' . $name, SassScriptParser::$context->node);
    }
  }

  /**
   * Performs this operation.
   * @param array operands for the operation. The operands are SassLiterals
   * @return SassLiteral the result of the operation
   * @throws SassScriptOperationException if the oprand count is incorrect or
   * the operation is undefined
   */
  public function perform($operands) {
    if (count($operands) !== $this->operandCount) {
      throw new SassScriptOperationException('Incorrect operand count for ' . get_class($operands[0]) . '; expected ' . $this->operandCount . ', received ' . count($operands), SassScriptParser::$context->node);
    }
    if (count($operands) > 1 && is_null($operands[1])) {
      $operation = 'op_unary_' . $this->operator;
    }
    else {
      $operation = 'op_' . $this->operator;
      if ($this->associativity == 'l') {
        $operands = array_reverse($operands);
      }
    }
    if (method_exists($operands[0], $operation)) {
      $op = clone $operands[0];
      return $op
        ->{$operation}(!empty($operands[1]) ? $operands[1] : null);
    }
    throw new SassScriptOperationException('Undefined operation "' . $operation . '" for ' . get_class($operands[0]), SassScriptParser::$context->node);
  }

  /**
   * Returns a value indicating if a token of this type can be matched at
   * the start of the subject string.
   * @param string the subject string
   * @return mixed match at the start of the string or false if no match
   */
  public static function isa($subject) {
    return preg_match(self::MATCH, $subject, $matches) ? trim($matches[0]) : false;
  }

  /**
   * Converts the operation back into it's SASS representation
   */
  public function __toString() {
    foreach (SassScriptOperation::$operators as $char => $operator) {
      if ($operator[0] == trim($this->operator)) {
        return $char;
      }
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
SassScriptOperation::$associativity private property
SassScriptOperation::$defaultOperator public static property
SassScriptOperation::$inStrOperators public static property selectors, property names and values
SassScriptOperation::$operandCount private property
SassScriptOperation::$operator private property
SassScriptOperation::$operators public static property A token is function, associativity, precedence, number of operands
SassScriptOperation::$precedence private property
SassScriptOperation::isa public static function Returns a value indicating if a token of this type can be matched at the start of the subject string.
SassScriptOperation::MATCH constant
SassScriptOperation::perform public function Performs this operation.
SassScriptOperation::__construct public function SassScriptOperation constructor
SassScriptOperation::__get public function Getter function for properties
SassScriptOperation::__toString public function Converts the operation back into it's SASS representation