Pastakhov has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/90290


Change subject: add operator while
......................................................................

add operator while

Time: 238 ms, Memory: 21.00Mb
OK (258 tests, 260 assertions)

Change-Id: If93ace77f6145b42289207e6091cf6a3617b32aa
---
M includes/Compiler.php
M includes/Runtime.php
M tests/phpunit/includes/RuntimeTest.php
3 files changed, 74 insertions(+), 16 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Foxway 
refs/changes/90/90290/1

diff --git a/includes/Compiler.php b/includes/Compiler.php
index 979cc5a..370ecd7 100644
--- a/includes/Compiler.php
+++ b/includes/Compiler.php
@@ -583,15 +583,18 @@
                                                        // Restore flags
                                                        $parentFlags = 
array_pop($parentheses);
                                                        if( $parentFlags & 
FOXWAY_EXPECT_RESULT_FROM_PARENTHESES ) {
-                                                               
$needParams[0][FOXWAY_STACK_PARAM] = &$lastValue[FOXWAY_STACK_RESULT]; // Save 
result of parentheses, exsample: if(true)
                                                                $parentFlags = 
array_pop($parentheses);
-                                                               if( 
$parentFlags & FOXWAY_EXPECT_DO_TRUE_STACK ) {
+                                                               if( 
$needParams[0][FOXWAY_STACK_COMMAND] == T_WHILE ) {
+                                                                       
$stack[] = array( FOXWAY_STACK_COMMAND=>T_DO, 
FOXWAY_STACK_PARAM=>&$lastValue[FOXWAY_STACK_RESULT], 
FOXWAY_STACK_TOKEN_LINE=>$tokenLine ); // Save result of parentheses, Example: 
while(true)
+                                                                       
$needParams[0][FOXWAY_STACK_DO_TRUE] = $stack;
+                                                                       $stack 
= array();
+                                                               }elseif( 
$parentFlags & FOXWAY_EXPECT_DO_TRUE_STACK ) {
                                                                        
$memory[] = $stack;
                                                                        $stack 
= array();
+                                                                       
$needParams[0][FOXWAY_STACK_PARAM] = &$lastValue[FOXWAY_STACK_RESULT]; // Save 
result of parentheses, exsample: if(true)
                                                                }
                                                                $needOperator = 
false;
                                                        }
-                                                       //$parentFlags &= 
~FOXWAY_EXPECT_VALUE_FOR_RIGHT_OPERATOR;
                                                        break 2;
                                                case ',':
                                                        if( $parentFlags & 
FOXWAY_ALLOW_DOUBLE_ARROW ) {
@@ -631,7 +634,12 @@
                                                                                
$lastValue[FOXWAY_STACK_DO_TRUE] = array_merge( 
$lastValue[FOXWAY_STACK_DO_TRUE], $stack );
                                                                                
break; /********** EXIT **********/
                                                                        }else{ 
// if(1) echo 2;
-                                                                               
$lastValue[FOXWAY_STACK_DO_TRUE] = $stack;
+                                                                               
if( $lastValue[FOXWAY_STACK_COMMAND] == T_WHILE ) {
+                                                                               
        $stack[] = array( FOXWAY_STACK_COMMAND=>T_CONTINUE, 
FOXWAY_STACK_PARAM=>1 ); // Add operator T_CONTINUE to the end of the cycle
+                                                                               
        $lastValue[FOXWAY_STACK_DO_TRUE] = array_merge( 
$lastValue[FOXWAY_STACK_DO_TRUE], $stack );
+                                                                               
}else{
+                                                                               
        $lastValue[FOXWAY_STACK_DO_TRUE] = $stack;
+                                                                               
}
                                                                                
$stack = array_shift($memory); // Restore stack and ...
                                                                                
$stack[] = &$lastValue; // ... add operator
                                                                                
array_shift($needParams);
@@ -699,14 +707,16 @@
                                        $parentFlags = FOXWAY_EXPECT_SEMICOLON 
| FOXWAY_EXPECT_LIST_PARAMS;
                                        break;
                                case T_IF:                      // if
-                                       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_RESULT=>null, FOXWAY_STACK_PARAM=>null, 
FOXWAY_STACK_TOKEN_LINE=>$tokenLine ) );
-                                       //$parentheses[] = $parentFlags;
                                        if( $parentFlags & 
FOXWAY_EXPECT_DO_TRUE_STACK ) { // Example: if(1) if
                                                $parentFlags |= 
FOXWAY_KEEP_EXPECT_ELSE;
                                        }
-                                       $parentheses[] = $parentFlags | 
FOXWAY_EXPECT_ELSE;
+                                       $parentFlags |= FOXWAY_EXPECT_ELSE;
+                                       // break is not necessary here
+                               case T_WHILE:           // while
+                                       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_RESULT=>null, FOXWAY_STACK_PARAM=>null, 
FOXWAY_STACK_TOKEN_LINE=>$tokenLine ) );
+                                       $parentheses[] = $parentFlags;
                                        $parentheses[] = 
FOXWAY_EXPECT_START_COMMAND | FOXWAY_EXPECT_SEMICOLON | 
FOXWAY_EXPECT_DO_TRUE_STACK;
                                        $parentheses[] = 
FOXWAY_EXPECT_RESULT_FROM_PARENTHESES;
                                        $parentFlags = 
FOXWAY_EXPECT_PARENTHES_CLOSE;
@@ -867,12 +877,14 @@
                                        break;
                                case '{':
                                        if( $parentFlags & 
FOXWAY_EXPECT_START_COMMAND == 0 || $stack || isset($operator) || $values ) { 
throw new ExceptionFoxway($id, FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); 
}
-                                       if( $parentFlags & 
FOXWAY_EXPECT_DO_TRUE_STACK ) {
-                                               
$needParams[0][FOXWAY_STACK_DO_TRUE] = array();
-                                       }elseif( $parentFlags & 
FOXWAY_EXPECT_DO_FALSE_STACK ) {
-                                               
$needParams[0][FOXWAY_STACK_DO_FALSE] = array();
-                                       }else{
-                                               throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine);
+                                               if( 
$needParams[0][FOXWAY_STACK_COMMAND] == T_IF ) {
+                                               if( $parentFlags & 
FOXWAY_EXPECT_DO_TRUE_STACK ) {
+                                                       
$needParams[0][FOXWAY_STACK_DO_TRUE] = array();
+                                               }elseif( $parentFlags & 
FOXWAY_EXPECT_DO_FALSE_STACK ) {
+                                                       
$needParams[0][FOXWAY_STACK_DO_FALSE] = array();
+                                               }else{
+                                                       throw new 
ExceptionFoxway($id, FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine);
+                                               }
                                        }
                                        // break is not necessary here
                                case T_CURLY_OPEN: // Example: echo "hello {
@@ -891,6 +903,9 @@
                                        if( $parentFlags & 
FOXWAY_EXPECT_START_COMMAND == 0 || $stack || isset($operator) || $values ) { 
throw new ExceptionFoxway($id, FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); 
}
 
                                        $lastValue = &$needParams[0];
+                                       if( $lastValue[FOXWAY_STACK_COMMAND] == 
T_WHILE ) { // Add operator T_CONTINUE to the end of the cycle
+                                               
$lastValue[FOXWAY_STACK_DO_TRUE][] = array( FOXWAY_STACK_COMMAND=>T_CONTINUE, 
FOXWAY_STACK_PARAM=>1 );
+                                       }
                                        array_shift($needParams);
                                        array_pop($parentheses);
                                        $parentFlags = array_pop($parentheses);
diff --git a/includes/Runtime.php b/includes/Runtime.php
index 207688a..10e290a 100644
--- a/includes/Runtime.php
+++ b/includes/Runtime.php
@@ -607,6 +607,8 @@
                $thisVariables['GLOBALS'] = &self::$globalVariables;
                $memory=array();
                $return = array();
+               $break = 0; // used for T_BREAK
+               $continue = false; // used for T_CONTINUE
 
                $c=count($code);
                $i=-1;
@@ -694,7 +696,9 @@
                                                $value[FOXWAY_STACK_RESULT] = 
$value[FOXWAY_STACK_PARAM] !== $value[FOXWAY_STACK_PARAM_2];
                                                break;
                                        case T_ECHO:
-                                               $return = array_merge($return, 
$value[FOXWAY_STACK_PARAM]); //$return += $value[FOXWAY_STACK_PARAM];
+                                               foreach( 
$value[FOXWAY_STACK_PARAM] as $v ) {
+                                                       $return[] = $v;
+                                               }
                                                break;
                                        case '~':
                                                $value[FOXWAY_STACK_RESULT] = 
~$value[FOXWAY_STACK_PARAM_2];
@@ -758,6 +762,32 @@
                                                        }
                                                }
                                                break;
+                                       case T_WHILE: // PHP code "while($foo) 
{ ... }" doing as T_WHILE { T_DO($foo) ... }. If $foo == false, T_DO doing as 
T_BREAK
+                                               if( $break ) { // was used 
T_BREAK
+                                                       if( --$break ) { // 
T_BREAK is 2 or more
+                                                               break 2; // go 
to one level down
+                                                       }
+                                                       break; // T_BREAK is 1, 
just go to next operator (T_WHILE will be skiped)
+                                               } // T_BREAK is not used
+                                               $memory[] = array( null, $code, 
$i, $c );
+                                               $code = 
$value[FOXWAY_STACK_DO_TRUE];
+                                               $i = -1;
+                                               $c = count($code);
+                                               break;
+                                       case T_DO:
+                                               if( $value[FOXWAY_STACK_PARAM] 
) {
+                                                       continue; // this is 
"while(true)", just go next
+                                               }// while(false) doing as 
T_BREAK;
+                                               $break = 1;
+                                               break 2; // go to one level down
+                                       case T_BREAK:
+                                               // @todo T_BREAK is 2 or more
+                                               $break = 1;
+                                               break 2; // go to one level down
+                                       case T_CONTINUE:
+                                               // @todo T_CONTINUE is 2 or more
+                                               $i = -1;
+                                               break;
                                        case T_ARRAY:                   // array
                                                $value[FOXWAY_STACK_RESULT] = 
array(); // init array
                                                foreach 
($value[FOXWAY_STACK_PARAM] as $v) {
diff --git a/tests/phpunit/includes/RuntimeTest.php 
b/tests/phpunit/includes/RuntimeTest.php
index 4d0a9ea..2a802fd 100644
--- a/tests/phpunit/includes/RuntimeTest.php
+++ b/tests/phpunit/includes/RuntimeTest.php
@@ -1618,4 +1618,17 @@
                                );
        }
 
+       public function testRun_while_1() {
+               $this->assertEquals(
+                               Runtime::runSource('$i=1; while( $i <= 3 ) { 
echo $i++; }'),
+                               array('1', '2', '3')
+                               );
+       }
+       public function testRun_while_2() {
+               $this->assertEquals(
+                               Runtime::runSource('$i=1; while( $i <= 3 ) echo 
$i++;'),
+                               array('1', '2', '3')
+                               );
+       }
+
 }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: If93ace77f6145b42289207e6091cf6a3617b32aa
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Foxway
Gerrit-Branch: develop
Gerrit-Owner: Pastakhov <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to