* improved the filter system to allow object methods to be used as filters
* changed the Array and String loaders to actually make use of the cache mechanism
* included the default filter function definitions in the extension class files directly (Core, Escaper)
+ * added the // operator (like the floor() PHP function)
* added the .. operator (as a syntactic sugar for the range filter when the step is 1)
* added the in operator (as a syntactic sugar for the in filter)
- * added the following filters in the Core extension: in, range, floor
+ * added the following filters in the Core extension: in, range
* added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes)
* enhanced some error messages to provide better feedback in case of parsing errors
public function parseDivExpression()
{
$lineno = $this->parser->getCurrentToken()->getLine();
- $left = $this->parseModExpression();
+ $left = $this->parseFloorDivExpression();
while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '/'))
{
$this->parser->getStream()->next();
return $left;
}
+ public function parseFloorDivExpression()
+ {
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $left = $this->parseModExpression();
+ while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '//'))
+ {
+ $this->parser->getStream()->next();
+ $right = $this->parseModExpression();
+ $left = new Twig_Node_Expression_Binary_FloorDiv($left, $right, $lineno);
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ }
+
+ return $left;
+ }
+
public function parseModExpression()
{
$lineno = $this->parser->getCurrentToken()->getLine();
// numbers
'even' => new Twig_Filter_Function('twig_is_even_filter'),
'odd' => new Twig_Filter_Function('twig_is_odd_filter'),
- 'floor' => new Twig_Filter_Function('twig_floor_filter'),
// encoding
'urlencode' => new Twig_Filter_Function('twig_urlencode_filter', array('is_escaper' => true)),
return $value % 2 == 1;
}
-function twig_floor_filter($value, $div)
-{
- return floor($value / $div);
-}
-
function twig_length_filter($thing)
{
return is_string($thing) ? strlen($thing) : count($thing);
const REGEX_NAME = '/[A-Za-z_][A-Za-z0-9_]*/A';
const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?/A';
const REGEX_STRING = '/(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')/Asm';
- const REGEX_OPERATOR = '/<=? | >=? | [!=]= | \.\. | [(){}.,%*\/+~|-] | \[ | \] | \? | \:/Ax';
+ const REGEX_OPERATOR = '/<=? | >=? | [!=]= | \/\/ | \.\. | [(){}.,%*\/+~|-] | \[ | \] | \? | \:/Ax';
public function __construct(Twig_Environment $env = null, array $options = array())
{
--- /dev/null
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
+{
+ public function compile($compiler)
+ {
+ $compiler
+ ->raw('floor(')
+ ->subcompile($this->left)
+ ->raw(' / ')
+ ->subcompile($this->right)
+ ->raw(')')
+ ;
+ }
+
+ public function operator($compiler)
+ {
+ return;
+ }
+}
{{ foo ~ "bar" }}
{{ "foo" ~ bar }}
{{ foo ~ bar }}
+{{ 20 // 7 }}
--DATA--
return array('foo' => 'bar', 'bar' => 'foo')
--EXPECT--
barbar
foofoo
barfoo
+2