<?php /* SVN FILE: $Id: SassLiteral.php 118 2010-09-21 09:45:11Z chris.l.yates@gmail.com $ */ /**
* SassLiteral class file. * @author Chris Yates <chris.l.yates@gmail.com> * @copyright Copyright (c) 2010 PBM Web Development * @license http://phamlp.googlecode.com/files/license.txt * @package PHamlP * @subpackage Sass.script.literals */
require_once('SassLiteralExceptions.php');
/**
* SassLiteral class. * Base class for all Sass literals. * Sass data types are extended from this class and these override the operation * methods to provide the appropriate semantics. * @package PHamlP * @subpackage Sass.script.literals */
abstract class SassLiteral {
/** * @var array maps class names to data types */ static private $typeOf = array( 'SassBoolean' => 'bool', 'SassColour' => 'color', 'SassNumber' => 'number', 'SassString' => 'string' ); /** * @var mixed value of the literal type */ protected $value; /** * class constructor * @param string value of the literal type * @return SassLiteral */ public function __construct($value = null, $context) { $this->value = $value; $this->context = $context; } /** * Getter. * @param string name of property to get * @return mixed return value of getter function */ public function __get($name) { $getter = 'get' . ucfirst($name); if (method_exists($this, $getter)) { return $this->$getter(); } else { throw new SassLiteralException('No getter function for {what}', array('{what}'=>$name), array(), SassScriptParser::$context->node); } } public function __toString() { return $this->toString(); } /** * Returns the boolean representation of the value of this * @return boolean the boolean representation of the value of this */ public function toBoolean() { return (boolean)$this->value; } /** * Returns the type of this * @return string the type of this */ protected function getTypeOf() { return self::$typeOf[get_class($this)]; } /** * Returns the value of this * @return mixed the value of this */ protected function getValue() { throw new SassLiteralException('Child classes must override this method', array(), SassScriptParser::$context->node); } /** * Adds a child object to this. * @param sassLiteral the child object */ public function addChild($sassLiteral) { $this->children[] = $sassLiteral; } /** * SassScript '+' operation. * @param sassLiteral value to add * @return sassString the string values of this and other with no seperation */ public function op_plus($other) { return new SassString($this->toString().$other->toString()); } /** * SassScript '-' operation. * @param SassLiteral value to subtract * @return sassString the string values of this and other seperated by '-' */ public function op_minus($other) { return new SassString($this->toString().'-'.$other->toString()); } /** * SassScript '*' operation. * @param SassLiteral value to multiply by * @return sassString the string values of this and other seperated by '*' */ public function op_times($other) { return new SassString($this->toString().'*'.$other->toString()); } /** * SassScript '/' operation. * @param SassLiteral value to divide by * @return sassString the string values of this and other seperated by '/' */ public function op_div($other) { return new SassString($this->toString().'/'.$other->toString()); } /** * SassScript '%' operation. * @param SassLiteral value to take the modulus of * @return SassLiteral result * @throws Exception if modulo not supported for the data type */ public function op_modulo($other) { throw new SassLiteralException('{class} does not support {operation}.', array('{class}'=>get_class($this), '{operation}'=>Phamlp::t('sass', 'Modulus')), SassScriptParser::$context->node); } /** * Bitwise AND the value of other and this value * @param string value to bitwise AND with * @return string result * @throws Exception if bitwise AND not supported for the data type */ public function op_bw_and($other) { throw new SassLiteralException('{class} does not support {operation}.', array('{class}'=>get_class($this), '{operation}'=>Phamlp::t('sass', 'Bitwise AND')), SassScriptParser::$context->node); } /** * Bitwise OR the value of other and this value * @param SassNumber value to bitwise OR with * @return string result * @throws Exception if bitwise OR not supported for the data type */ public function op_bw_or($other) { throw new SassLiteralException('{class} does not support {operation}.', array('{class}'=>get_class($this), '{operation}'=>Phamlp::t('sass', 'Bitwise OR')), SassScriptParser::$context->node); } /** * Bitwise XOR the value of other and the value of this * @param SassNumber value to bitwise XOR with * @return string result * @throws Exception if bitwise XOR not supported for the data type */ public function op_bw_xor($other) { throw new SassLiteralException('{class} does not support {operation}.', array('{class}'=>get_class($this), '{operation}'=>Phamlp::t('sass', 'Bitwise XOR')), SassScriptParser::$context->node); } /** * Bitwise NOT the value of other and the value of this * @param SassNumber value to bitwise NOT with * @return string result * @throws Exception if bitwise NOT not supported for the data type */ public function op_bw_not() { throw new SassLiteralException('{class} does not support {operation}.', array('{class}'=>get_class($this), '{operation}'=>Phamlp::t('sass', 'Bitwise NOT')), SassScriptParser::$context->node); } /** * Shifts the value of this left by the number of bits given in value * @param SassNumber amount to shift left by * @return string result * @throws Exception if bitwise Shift Left not supported for the data type */ public function op_shiftl($other) { throw new SassLiteralException('{class} does not support {operation}.', array('{class}'=>get_class($this), '{operation}'=>Phamlp::t('sass', 'Bitwise Shift Left')), SassScriptParser::$context->node); } /** * Shifts the value of this right by the number of bits given in value * @param SassNumber amount to shift right by * @return string result * @throws Exception if bitwise Shift Right not supported for the data type */ public function op_shiftr($other) { throw new SassLiteralException('{class} does not support {operation}.', array('{class}'=>get_class($this), '{operation}'=>Phamlp::t('sass', 'Bitwise Shift Right')), SassScriptParser::$context->node); } /** * The SassScript and operation. * @param sassLiteral the value to and with this * @return SassLiteral other if this is boolean true, this if false */ public function op_and($other) { return ($this->toBoolean() ? $other : $this); } /** * The SassScript or operation. * @param sassLiteral the value to or with this * @return SassLiteral this if this is boolean true, other if false */ public function op_or($other) { return ($this->toBoolean() ? $this : $other); } /** * The SassScript xor operation. * @param sassLiteral the value to xor with this * @return SassBoolean SassBoolean object with the value true if this or * other, but not both, are true, false if not */ public function op_xor($other) { return new SassBoolean($this->toBoolean() xor $other->toBoolean()); } /** * The SassScript not operation. * @return SassBoolean SassBoolean object with the value true if the * boolean of this is false or false if it is true */ public function op_not() { return new SassBoolean(!$this->toBoolean()); } /** * The SassScript > operation. * @param sassLiteral the value to compare to this * @return SassBoolean SassBoolean object with the value true if the values * of this is greater than the value of other, false if it is not */ public function op_gt($other) { return new SassBoolean($this->value > $other->value); } /** * The SassScript >= operation. * @param sassLiteral the value to compare to this * @return SassBoolean SassBoolean object with the value true if the values * of this is greater than or equal to the value of other, false if it is not */ public function op_gte($other) { return new SassBoolean($this->value >= $other->value); } /** * The SassScript < operation. * @param sassLiteral the value to compare to this * @return SassBoolean SassBoolean object with the value true if the values * of this is less than the value of other, false if it is not */ public function op_lt($other) { return new SassBoolean($this->value < $other->value); } /** * The SassScript <= operation. * @param sassLiteral the value to compare to this * @return SassBoolean SassBoolean object with the value true if the values * of this is less than or equal to the value of other, false if it is not */ public function op_lte($other) { return new SassBoolean($this->value <= $other->value); } /** * The SassScript == operation. * @param sassLiteral the value to compare to this * @return SassBoolean SassBoolean object with the value true if this and * other are equal, false if they are not */ public function op_eq($other) { return new SassBoolean($this == $other); } /** * The SassScript != operation. * @param sassLiteral the value to compare to this * @return SassBoolean SassBoolean object with the value true if this and * other are not equal, false if they are */ public function op_neq($other) { return new SassBoolean(!$this->op_eq($other)->toBoolean()); } /** * The SassScript default operation (e.g. $a $b, "foo" "bar"). * @param sassLiteral the value to concatenate with a space to this * @return sassString the string values of this and other seperated by " " */ public function op_concat($other) { return new SassString($this->toString().' '.$other->toString()); } /** * SassScript ',' operation. * @param sassLiteral the value to concatenate with a comma to this * @return sassString the string values of this and other seperated by "," */ public function op_comma($other) { return new SassString($this->toString().', '.$other->toString()); } /** * Asserts that the literal is the expected type * @param SassLiteral the literal to test * @param string expected type * @throws SassScriptFunctionException if value is not the expected type */ public static function assertType($literal, $type) { if (!$literal instanceof $type) { throw new SassScriptFunctionException('{what} must be a {type}', array('{what}'=>($literal instanceof SassLiteral ? $literal->typeOf : 'literal'), '{type}'=>$type), SassScriptParser::$context->node); } } /** * Asserts that the value of a literal is within the expected range * @param SassLiteral the literal to test * @param float the minimum value * @param float the maximum value * @param string the units. * @throws SassScriptFunctionException if value is not the expected type */ public static function assertInRange($literal, $min, $max, $units = '') { if ($literal->value < $min || $literal->value > $max) { throw new SassScriptFunctionException('{what} must be {inRange}', array('{what}'=>$literal->typeOf, '{inRange}'=>Phamlp::t('sass', 'between {min} and {max} inclusive', array('{min}'=>$min.$units, '{max}'=>$max.$units))), SassScriptParser::$context->node); } } /** * Returns a string representation of the value. * @return string string representation of the value. */ abstract public function toString(); /** * 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 */ abstract public static function isa($subject);
}