jenkins-bot has submitted this change and it was merged.

Change subject: add operator T_FOREACH
......................................................................


add operator T_FOREACH

* show exception foxway as string
* fix double variables '$bar' in $code for source 'echo "$foo[$bar]";'
* fix double while without braces

Time: 498 ms, Memory: 24.75Mb
OK (492 tests, 498 assertions)

Change-Id: Id917d91f56f0daef19fa0ee716feba284c35620c
---
M Foxway.body.php
M includes/Compiler.php
M includes/ExceptionFoxway.php
M includes/Runtime.php
M tests/phpunit/includes/RuntimeTest.php
5 files changed, 198 insertions(+), 25 deletions(-)

Approvals:
  Pastakhov: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/Foxway.body.php b/Foxway.body.php
index bfcfcb5..4ffbcff 100644
--- a/Foxway.body.php
+++ b/Foxway.body.php
@@ -51,6 +51,8 @@
                                        array( 'Parser'=>&$parser, 
'PPFrame'=>&$frame )
                                        );
                        $return = implode($result);
+               } catch (\Foxway\ExceptionFoxway $exc) {
+                       $return = (string) $exc;
                } catch (Exception $exc) {
                        $return = $exc->getTraceAsString();
                }
@@ -85,7 +87,10 @@
                                        self::getScope($frame),
                                        array( 'Parser'=>&$parser, 
'PPFrame'=>&$frame )
                                        );
-               } catch (Exception $exc) {
+               } catch ( \Foxway\ExceptionFoxway $exc ) {
+                       \Foxway\Runtime::$time += microtime(true) - 
self::$startTime;
+                       return (string) $exc;
+               } catch ( Exception $exc ) {
                        \Foxway\Runtime::$time += microtime(true) - 
self::$startTime;
                        return $exc->getTraceAsString();
                }
diff --git a/includes/Compiler.php b/includes/Compiler.php
index 14fa2cf..8c9cbce 100644
--- a/includes/Compiler.php
+++ b/includes/Compiler.php
@@ -28,6 +28,7 @@
 define( 'FOXWAY_ALLOW_ONLY_VARIABLES', 1 << 22 );
 define( 'FOXWAY_ALLOW_SKIP_PARAMS', 1 << 23 ); // used in operator T_LIST
 define( 'FOXWAY_DOUBLE_ARROW_WAS_USED', 1 << 24 );
+define( 'FOXWAY_EXPECT_OPERATOR_AS', 1 << 25 ); // for operator T_FOREACH
 
 define( 'FOXWAY_CLEAR_FLAG_FOR_SHIFT_BEFORE_PARENTHESES', 
FOXWAY_EXPECT_PARENTHESES_WITH_LIST_PARAMS );
 //define( 'FOXWAY_CLEAR_FLAG_FOR_SHIFT_AFTER_PARENTHESES', 
FOXWAY_EXPECT_PARENTHESES_WITH_LIST_PARAMS );
@@ -287,6 +288,7 @@
                                        }else{ // right operator was not used
                                                $lastValue = &$tmp;
                                        }
+                                       $values = array(); // there is 
variables of array index. Example '$bar' for : echo "$foo[$bar]";
                                        unset($tmp);
                                        $stackEncapsed = false;
                                        break;
@@ -462,14 +464,21 @@
                                case T_XOR_EQUAL:               // ^=
                                case T_SL_EQUAL:                // <<=
                                case T_SR_EQUAL:                // >>=
+                                       if ( $parentFlags & 
FOXWAY_ALLOW_ONLY_VARIABLES ) { throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); }
+                                       // break is not necessary here
                                case T_DOUBLE_ARROW:    // =>
-                                       if ( !$needOperator || 
!isset($lastValue) || $rightOperators || $parentFlags & 
FOXWAY_ALLOW_ONLY_VARIABLES ) { throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); }
+                                       if ( !$needOperator || 
!isset($lastValue) || $rightOperators ) { throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); }
                                        $needOperator = false;
 
                                        array_unshift( $needParams, 
array(FOXWAY_STACK_COMMAND=>$id, 
FOXWAY_STACK_RESULT=>&$lastValue[FOXWAY_STACK_RESULT], 
FOXWAY_STACK_PARAM=>&$lastValue, FOXWAY_STACK_TOKEN_LINE=>$tokenLine) );
                                        if ( $id == T_DOUBLE_ARROW ) {
-                                               if( $parentFlags & 
FOXWAY_ALLOW_DOUBLE_ARROW == 0 ) { throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); }
+                                               if ( $parentFlags & 
FOXWAY_ALLOW_DOUBLE_ARROW == 0 ) { throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); }
                                                $parentFlags = ( $parentFlags & 
~FOXWAY_ALLOW_DOUBLE_ARROW ) | FOXWAY_DOUBLE_ARROW_WAS_USED; // Mark double 
arrow was used
+                                               if ( $parentFlags & 
FOXWAY_ALLOW_ONLY_VARIABLES  ) { // T_DOUBLE_ARROW for operator T_FOREACH
+                                                       array_shift( 
$needParams );
+                                                       unset( $lastValue );
+                                                       break; // **** EXIT ****
+                                               }
                                        } elseif ( $id == '=' ) {
                                                if ( 
$lastValue[FOXWAY_STACK_COMMAND] == T_VARIABLE ) {
                                                        array_pop( $values ); 
// remove T_VARIABLE from $values
@@ -521,7 +530,19 @@
                                        if( !isset($operator) ) { $needOperator 
= true; } // Example: $foo[]
                                        // break is not necessary here
                                case ')':
-                                       if( !$needOperator && !isset($operator) 
&& $parentFlags & FOXWAY_THIS_IS_FUNCTION ) { $needOperator = true; }
+                                       if ( !$needOperator && 
!isset($operator) && $parentFlags & FOXWAY_THIS_IS_FUNCTION ) { $needOperator = 
true; } // @todo ALLOW_VOID_PARAMS
+                                       if ( $parentFlags & 
FOXWAY_EXPECT_PARENTHES_CLOSE && $parentFlags & FOXWAY_THIS_IS_FUNCTION && 
$needParams[0][FOXWAY_STACK_COMMAND] == T_FOREACH ) {
+                                               if ( $parentFlags & 
FOXWAY_DOUBLE_ARROW_WAS_USED ) { // T_DOUBLE_ARROW Example: while ( $foo as 
$key=>$value )
+                                                       
$needParams[0][FOXWAY_STACK_DO_TRUE][0][FOXWAY_STACK_PARAM_2] = array( 
$values[0][FOXWAY_STACK_PARAM], $lastValue[FOXWAY_STACK_PARAM] );
+                                               } else { // T_VARIABLE. 
Example: while ( $foo as $value )
+                                                       
$needParams[0][FOXWAY_STACK_DO_TRUE][0][FOXWAY_STACK_PARAM_2] = 
$lastValue[FOXWAY_STACK_PARAM];
+                                               }
+                                               $values = array();
+                                               unset( $lastValue );
+                                               $parentFlags = 
array_pop($parentheses);
+                                               $needOperator = false;
+                                               break; // **** EXIT ****
+                                       }
                                        // break is not necessary here
                                case ',':
                                        if ( !$needOperator && 
!isset($lastValue) && $parentFlags & FOXWAY_ALLOW_SKIP_PARAMS ) {
@@ -554,13 +575,13 @@
                                                        unset( 
$incompleteOperators[$parentLevel], $math[$parentLevel] );
                                                }
                                        }elseif( isset($lastValue) ) { // 
Operator does not exists, but there is value. Operator and value not exists 
for: array() or array(1,)
-                                               if( isset($lastValue) ) {
+                                               //if( isset($lastValue) ) {
                                                        $operator = &$lastValue;
                                                        unset($lastValue);
-                                               }else{ // Value does not exist. 
Examples: echo () OR echo , OR echo ;
+                                               //}else{ // Value does not 
exist. Examples: echo () OR echo , OR echo ;
                                                        // @todo ternary 
without middle
-                                                       throw new 
ExceptionFoxway($id, FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine);
-                                               }
+                                               //      throw new 
ExceptionFoxway($id, FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine);
+                                               //}
                                        }
 
                                        if( $parentFlags & 
FOXWAY_EXPECT_TERNARY_END ) { // Examples: echo 1?2:3,
@@ -602,7 +623,7 @@
                                                        $lastValue = 
&$needParams[0];
                                                        
array_shift($needParams);
                                                        
$lastValue[FOXWAY_STACK_ARRAY_INDEX][] = &$operator[FOXWAY_STACK_RESULT]; // 
$lastValue must be T_VARIABLE only
-                                                       $stack[] = &$lastValue;
+                                                       $values[] = &$lastValue;
                                                        unset($operator);
                                                        if( $parentFlags & 
FOXWAY_NEED_RESTORE_OPERATOR ) {
                                                                $operator = 
array_pop( $memOperators );
@@ -612,22 +633,23 @@
                                                        list( $tmp, $math ) = 
array_pop($memory); // restore $stack, $math
                                                        $s = 
self::mergeStackAndMath($tmp, $math);
                                                        if( $s ) {
-                                                               $stack = 
array_merge( $s, $stack );
+                                                               $stack = 
array_merge( $stack, $s );
                                                        }
                                                        break 2;
                                                case ')':
                                                        $parentLevel--;
                                                        if( $parentFlags & 
FOXWAY_EXPECT_PARENTHES_CLOSE == 0 ) { throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); }
-                                                       if( $parentFlags & 
FOXWAY_THIS_IS_FUNCTION ) {
-                                                               if( 
isset($operator) ) {
-                                                                       if( 
$parentFlags & FOXWAY_EXPECT_LIST_PARAMS ) {
+                                                       if ( $parentFlags & 
FOXWAY_THIS_IS_FUNCTION ) {
+                                                               if ( 
isset($operator) ) {
+                                                                       //if( 
$parentFlags & FOXWAY_EXPECT_LIST_PARAMS ) {
                                                                                
$needParams[0][FOXWAY_STACK_PARAM][] = &$operator;
-                                                                               
if( $parentFlags & FOXWAY_EXPECT_VARIABLE_REFERENCE && 
$operator[FOXWAY_STACK_COMMAND] == T_VARIABLE ) {
-                                                                               
        array_pop( $stack ); // @todo refactoring
-                                                                               
}
-                                                                       }else{
-                                                                               
throw new ExceptionFoxway($id, FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine);
-                                                                       }
+                                                                               
if ( $parentFlags & FOXWAY_EXPECT_VARIABLE_REFERENCE && 
$operator[FOXWAY_STACK_COMMAND] == T_VARIABLE ) { // @todo refactoring
+                                                                               
        $stack = array(); // @todo refactoring
+                                                                               
        //array_pop( $stack ); // @todo refactoring
+                                                                               
} // @todo refactoring
+                                                                       //}else{
+                                                                       //      
throw new ExceptionFoxway($id, FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine);
+                                                                       //}
                                                                        
unset($operator);
                                                                }
                                                                $operator = 
&$needParams[0]; // restore result of function as value, this will be set as 
$lastValue
@@ -635,7 +657,7 @@
                                                                        
$stack[] = &$operator; // add function to stack
                                                                }
                                                                
array_shift($needParams);
-                                                               list( $s, $math 
) = array_pop($memory); // restore $stack, $math
+                                                               list( $s, $math 
) = array_pop($memory); // restore $stack, $math @todo NEED_RESTORE_STACK
                                                                if( $s ) {
                                                                        $stack 
= array_merge( $s, $stack );
                                                                }
@@ -744,7 +766,7 @@
                                                                                
break; /********** EXIT **********/
                                                                        }else{ 
// if(1) echo 2;
                                                                                
$link = &$needParams[0];
-                                                                               
if( $link[FOXWAY_STACK_COMMAND] == T_WHILE ) { // T_WHILE
+                                                                               
if( $link[FOXWAY_STACK_COMMAND] != T_IF ) { // T_WHILE, T_FOREACH
                                                                                
        $stack[] = array( FOXWAY_STACK_COMMAND=>T_CONTINUE, 
FOXWAY_STACK_RESULT=>1 ); // Add operator T_CONTINUE to the end of the cycle
                                                                                
        $link[FOXWAY_STACK_DO_TRUE] = array_merge( $link[FOXWAY_STACK_DO_TRUE], 
$stack );
                                                                                
        $stack = array( &$link );
@@ -805,7 +827,7 @@
                                        if( $parentFlags & 
FOXWAY_EXPECT_START_COMMAND == 0 ) { throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); }
 
                                        // for compatible with functions that 
use flag FOXWAY_EXPECT_LIST_PARAMS
-                                       $memory[] = array(array(), array());
+                                       $memory[] = array( array(), array() ); 
// @todo NEED_RESTORE_STACK
                                        /*ksort($math);
                                        array_unshift( $memory, array($stack, 
$math) );
                                        $stack = array();
@@ -963,7 +985,7 @@
                                        array_pop($parentheses);
                                        $parentFlags = array_pop($parentheses);
                                        if( 
!isset($link[FOXWAY_STACK_DO_FALSE]) ) { // operator 'else' not used
-                                               if( $link[FOXWAY_STACK_COMMAND] 
== T_WHILE ) {
+                                               if( $link[FOXWAY_STACK_COMMAND] 
!= T_IF ) { // T_WHILE, T_FOREACH
                                                        
$link[FOXWAY_STACK_DO_TRUE][] = array( FOXWAY_STACK_COMMAND=>T_CONTINUE, 
FOXWAY_STACK_RESULT=>1 );  // Add operator T_CONTINUE to the end of the cycle
                                                        $tmp = array( &$link );
                                                        $ifOperators = array();
@@ -980,8 +1002,9 @@
                                                                        break; 
/********** EXIT **********/
                                                                }else{ // 
Exsample: if(1) if(2) { echo 3; }
                                                                        $link = 
&$needParams[0];
-                                                                       if( 
$link[FOXWAY_STACK_COMMAND] == T_WHILE ) { // T_WHILE
+                                                                       if( 
$link[FOXWAY_STACK_COMMAND] != T_IF ) { // T_WHILE, T_FOREACH
                                                                                
$link[FOXWAY_STACK_DO_TRUE] = array_merge( $link[FOXWAY_STACK_DO_TRUE], $tmp );
+                                                                               
$link[FOXWAY_STACK_DO_TRUE][] = array( FOXWAY_STACK_COMMAND=>T_CONTINUE, 
FOXWAY_STACK_RESULT=>1 );  // Add operator T_CONTINUE to the end of the cycle
                                                                                
$tmp = array( &$link );
                                                                        }else{ 
// T_IF
                                                                                
$link[FOXWAY_STACK_DO_TRUE] = $tmp;
@@ -1110,6 +1133,30 @@
 
                                        self::getNextToken( $tokens, $index, 
$countTokens, $tokenLine, array('(') );
                                        break;
+                               case T_FOREACH:
+                                       if ( $parentFlags & 
FOXWAY_EXPECT_START_COMMAND == 0 || $stack || isset($operator) || $values ) {
+                                               throw new ExceptionFoxway( $id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine );
+                                       }
+
+                                       array_unshift( $needParams, 
array(FOXWAY_STACK_COMMAND=>$id, FOXWAY_STACK_DO_TRUE=>array(), 
FOXWAY_STACK_TOKEN_LINE=>$tokenLine) );
+                                       $parentheses[] = $parentFlags;
+                                       $parentheses[] = 
FOXWAY_EXPECT_START_COMMAND | FOXWAY_EXPECT_SEMICOLON | 
FOXWAY_EXPECT_DO_TRUE_STACK;
+                                       $parentFlags = 
FOXWAY_ALLOW_ONLY_VARIABLES|FOXWAY_EXPECT_OPERATOR_AS;
+
+                                       self::getNextToken( $tokens, $index, 
$countTokens, $tokenLine, array('(') );
+                                       break;
+                               case T_AS:
+                                       if ( !$needOperator || !($parentFlags & 
FOXWAY_EXPECT_OPERATOR_AS) || !isset($lastValue) || 
$lastValue[FOXWAY_STACK_COMMAND] != T_VARIABLE ) {
+                                               throw new ExceptionFoxway( $id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine );
+                                       }
+                                       $needOperator = false;
+                                       $parentFlags = 
FOXWAY_ALLOW_ONLY_VARIABLES|FOXWAY_EXPECT_VARIABLE_REFERENCE|FOXWAY_EXPECT_PARENTHES_CLOSE|FOXWAY_THIS_IS_FUNCTION|FOXWAY_ALLOW_DOUBLE_ARROW;
+
+                                       $needParams[0][FOXWAY_STACK_PARAM] = 
$lastValue[FOXWAY_STACK_PARAM]; // for reset array
+                                       $needParams[0][FOXWAY_STACK_DO_TRUE][0] 
= array( FOXWAY_STACK_COMMAND=>$id, 
FOXWAY_STACK_PARAM=>$lastValue[FOXWAY_STACK_PARAM], 
FOXWAY_STACK_TOKEN_LINE=>$tokenLine);
+                                       unset( $lastValue );
+                                       $values = array();
+                                       break;
                                default :
                                        throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine);
                                        break;
diff --git a/includes/ExceptionFoxway.php b/includes/ExceptionFoxway.php
index 1960613..980a733 100644
--- a/includes/ExceptionFoxway.php
+++ b/includes/ExceptionFoxway.php
@@ -17,6 +17,11 @@
 define( 'FOXWAY_PHP_NOTICE_UNINIT_STRING_OFFSET', 113 ); // PHP Notice:  
Uninitialized string offset: $1
 define( 'FOXWAY_PHP_NOTICE_UNDEFINED_CONSTANT', 114 ); // PHP Notice:  Use of 
undefined constant $1 - assumed '$1'
 define( 'FOXWAY_PHP_FATAL_CANNOT_UNSET_STRING_OFFSETS', 115 ); // PHP Fatal 
error:  Cannot unset string offsets
+define( 'FOXWAY_PHP_WARNING_INVALID_ARGUMENT_FOR_FOREACH', 116 ); // PHP 
Warning:  Invalid argument supplied for foreach()
+// PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried 
to allocate 73 bytes)
+// PHP Fatal error:  Maximum execution time of 30 seconds exceeded
+// PHP Warning:  Variable passed to each() is not an array or object
+
 
 /**
  * Error Exception class of Foxway extension.
@@ -44,6 +49,9 @@
                $place = $this->place;
 
                switch ( $this->code ) {
+                       case FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED:
+                               $message = 'HP Parse error:  syntax error, 
unexpected ' . ( is_string($params) ? $params : token_name($params) );
+                               break;
                        case FOXWAY_PHP_WARNING_DIVISION_BY_ZERO:
                                $message = "PHP Warning:  Division by zero";
                                break;
@@ -69,9 +77,13 @@
                                $message = "PHP Notice:  Use of undefined 
constant $params - assumed '$params'";
                                break;
                        case FOXWAY_PHP_FATAL_CANNOT_UNSET_STRING_OFFSETS:
-                               $message = "PHP Fatal error:  Cannot unset 
string offsets";
+                               $message = 'PHP Fatal error:  Cannot unset 
string offsets';
+                               break;
+                       case FOXWAY_PHP_WARNING_INVALID_ARGUMENT_FOR_FOREACH:
+                               $message = 'PHP Warning:  Invalid argument 
supplied for foreach()';
                                break;
                        default:
+                               $message = "PHP Fatal error:  Undefined error, 
code {$this->code}";
                                break;
                }
                //return "$message in $place on line $line\n";
diff --git a/includes/Runtime.php b/includes/Runtime.php
index 9d8c9ae..36f99ca 100644
--- a/includes/Runtime.php
+++ b/includes/Runtime.php
@@ -255,6 +255,19 @@
                                                        }
                                                }
                                                break;
+                                       case T_FOREACH:
+                                               $vn = 
$value[FOXWAY_STACK_PARAM]; // Variable name
+                                               if ( !array_key_exists($vn, 
$thisVariables) ) {
+                                                       $return[] = (string) 
new ExceptionFoxway( $vn, FOXWAY_PHP_NOTICE_UNDEFINED_VARIABLE, 
$value[FOXWAY_STACK_TOKEN_LINE], $place );
+                                                       $return[] = (string) 
new ExceptionFoxway( null, FOXWAY_PHP_WARNING_INVALID_ARGUMENT_FOR_FOREACH, 
$value[FOXWAY_STACK_TOKEN_LINE], $place );
+                                                       break; // **** EXIT ****
+                                               }
+                                               if ( !is_array($thisVariables[ 
$value[FOXWAY_STACK_PARAM] ]) ) {
+                                                       $return[] = (string) 
new ExceptionFoxway( null, FOXWAY_PHP_WARNING_INVALID_ARGUMENT_FOR_FOREACH, 
$value[FOXWAY_STACK_TOKEN_LINE], $place );
+                                                       break; // **** EXIT ****
+                                               }
+                                               reset( $thisVariables[ 
$value[FOXWAY_STACK_PARAM] ] );
+                                               // break is not necessary here
                                        case T_WHILE: // PHP code "while($foo) 
{ ... }" doing as T_WHILE { T_DO($foo) ... }. If $foo == false, T_DO doing as 
T_BREAK
                                                $memory[] = array( null, $code, 
$i, $c, $loopsOwner );
                                                $code = 
$value[FOXWAY_STACK_DO_TRUE];
@@ -267,6 +280,17 @@
                                                        continue; // this is 
"while(true)", just go next
                                                }// while(false) doing as 
T_BREAK;
                                                break 2; // go to one level down
+                                       case T_AS:
+                                               if ( 
is_string($value[FOXWAY_STACK_PARAM_2]) ) { // T_VARIABLE. Example: while ( 
$foo as $value )
+                                                       if ( 
!list(,$thisVariables[ $value[FOXWAY_STACK_PARAM_2] ]) = each($thisVariables[ 
$value[FOXWAY_STACK_PARAM] ]) ) {
+                                                               break 2; // go 
to one level down
+                                                       }
+                                               } else { // T_DOUBLE_ARROW 
Example: while ( $foo as $key=>$value )
+                                                       if ( 
!list($thisVariables[ $value[FOXWAY_STACK_PARAM_2][0] ], $thisVariables[ 
$value[FOXWAY_STACK_PARAM_2][1] ]) = each($thisVariables[ 
$value[FOXWAY_STACK_PARAM] ]) ) {
+                                                               break 2; // go 
to one level down
+                                                       }
+                                               }
+                                               break;
                                        case T_BREAK:
                                                $break = 
$value[FOXWAY_STACK_RESULT];
                                                if( $loopsOwner == T_WHILE ) {
diff --git a/tests/phpunit/includes/RuntimeTest.php 
b/tests/phpunit/includes/RuntimeTest.php
index 43a1ebb..b0d98e8 100644
--- a/tests/phpunit/includes/RuntimeTest.php
+++ b/tests/phpunit/includes/RuntimeTest.php
@@ -1768,6 +1768,24 @@
                                '|1|(1)|2|(1)(2)|3|(1)(2)(3)'
                                );
        }
+       public function testRun_while_while_2() {
+               $this->assertEquals(
+                               Runtime::runSource('$i=1; $y=2; while($i++<4 && 
$y--) { while($y<5) { echo $y++; } }'),
+                               array(1, 2, 3, 4, 4, 4)
+                               );
+       }
+       public function testRun_while_while_3() {
+               $this->assertEquals(
+                               Runtime::runSource('$i=1; $y=2; while($i++<4 && 
$y--) while($y<5) { echo $y++; }'),
+                               array(1, 2, 3, 4, 4, 4)
+                               );
+       }
+       public function testRun_while_while_4() {
+               $this->assertEquals(
+                               Runtime::runSource('$i=1; $y=2; while($i++<4 && 
$y--) while($y<5) echo $y++;'),
+                               array(1, 2, 3, 4, 4, 4)
+                               );
+       }
        public function testRun_while_while_continue_1() {
                $this->assertEquals(
                                implode( Runtime::runSource('$i=1; while( $i<=3 
){ echo "|$i|"; $y=0; while( $y<3 ){ $y++; if( $y==2) continue; echo "($y)";  } 
$i++; }') ),
@@ -3034,4 +3052,71 @@
                                );
        }
 
+       public function testRun_foreach_1() {
+               $this->assertEquals(
+                               Runtime::runSource('$arr = array("one", "two", 
"three"); foreach ($arr as $value) echo "* Value: $value\n";'),
+                               array("* Value: one\n", "* Value: two\n", "* 
Value: three\n")
+                               );
+       }
+       public function testRun_foreach_2() {
+               $this->assertEquals(
+                               Runtime::runSource('foreach ($arr as $value) { 
echo "* Value: $value\n"; }'),
+                               array("* Value: one\n", "* Value: two\n", "* 
Value: three\n")
+                               );
+       }
+       public function testRun_foreach_3() {
+               $this->assertEquals(
+                               Runtime::runSource('$arr = array("one", "two", 
"three"); foreach ($arr as $value) echo "* Value: $value\n"; echo "end";'),
+                               array("* Value: one\n", "* Value: two\n", "* 
Value: three\n", 'end')
+                               );
+       }
+       public function testRun_foreach_4() {
+               $this->assertEquals(
+                               Runtime::runSource('foreach ($arr as $value) { 
echo "* Value: $value\n"; } echo "end";'),
+                               array("* Value: one\n", "* Value: two\n", "* 
Value: three\n", 'end')
+                               );
+       }
+       public function testRun_foreach_5() {
+               $this->assertEquals(
+                               Runtime::runSource('foreach ($arr as $key => 
$value) { echo $key, $value; }'),
+                               array(0, 'one', 1, 'two', 2, 'three')
+                               );
+       }
+       public function testRun_foreach_6() {
+               $this->assertEquals(
+                               Runtime::runSource('foreach ($arr as $key => 
$value) echo "* Key: $key; Value: $value\n"; echo "end";'),
+                               array("* Key: 0; Value: one\n", "* Key: 1; 
Value: two\n", "* Key: 2; Value: three\n", 'end')
+                               );
+       }
+       public function testRun_foreach_7() {
+               $this->assertEquals(
+                               Runtime::runSource('foreach ($arr as $key => 
$value) { echo "* Key: $key; Value: $value\n"; } echo "end";'),
+                               array("* Key: 0; Value: one\n", "* Key: 1; 
Value: two\n", "* Key: 2; Value: three\n", 'end')
+                               );
+       }
+       public function testRun_foreach_8() {
+               $this->assertEquals(
+                               Runtime::runSource('$a = array("one" => 1,"two" 
=> 2,"three" => 3,"seventeen" => 17); foreach ($a as $k => $v) {echo "\$a[$k] 
=> $v.";}'),
+                               array('$a[one] => 1.', '$a[two] => 2.', 
'$a[three] => 3.', '$a[seventeen] => 17.')
+                               );
+       }
+       public function testRun_foreach_9() {
+               $this->assertEquals(
+                               Runtime::runSource('$a=array(); $a[0][0]="a"; 
$a[0][1]="b"; $a[1][0]="y"; $a[1][1]="z"; foreach ($a as $v1) { foreach ($v1 as 
$v2) { echo $v2; } }'),
+                               array('a', 'b', 'y', 'z')
+                               );
+       }
+       public function testRun_foreach_10() {
+               $this->assertEquals(
+                               Runtime::runSource('foreach ($a as $v1) foreach 
($v1 as $v2) { echo $v2; }'),
+                               array('a', 'b', 'y', 'z')
+                               );
+       }
+       public function testRun_foreach_11() {
+               $this->assertEquals(
+                               Runtime::runSource('foreach ($a as $v1) foreach 
($v1 as $v2) echo $v2;'),
+                               array('a', 'b', 'y', 'z')
+                               );
+       }
+
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/94874
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Id917d91f56f0daef19fa0ee716feba284c35620c
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/Foxway
Gerrit-Branch: develop
Gerrit-Owner: Pastakhov <pastak...@yandex.ru>
Gerrit-Reviewer: Pastakhov <pastak...@yandex.ru>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to