Pastakhov has uploaded a new change for review.

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


Change subject: Add 'else' operator for 'if' with blocks
......................................................................

Add 'else' operator for 'if' with blocks

Change-Id: Ie93952efdd89e6f2f2dd54bb296cad721f54bad3
---
M includes/Compiler.php
M includes/Runtime.php
M tests/phpunit/includes/RuntimeTest.php
3 files changed, 103 insertions(+), 33 deletions(-)


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

diff --git a/includes/Compiler.php b/includes/Compiler.php
index 4728b05..1006e0e 100644
--- a/includes/Compiler.php
+++ b/includes/Compiler.php
@@ -30,6 +30,7 @@
 define( 'FOXWAY_EXPECT_DO_TRUE_STACK', 1 << 11 );
 define( 'FOXWAY_EXPECT_DO_FALSE_STACK', 1 << 12 );
 define( 'FOXWAY_EXPECT_CURLY_CLOSE', 1 << 13 );
+define( 'FOXWAY_EXPECT_ELSE', 1 << 14 );
 
 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 );
@@ -547,32 +548,39 @@
                                                        $parentFlags = 
array_pop($parentheses);
                                                }
 
-                                               if( $parentFlags & 
FOXWAY_EXPECT_DO_TRUE_STACK ) { // Exsample: if(1) echo 2;
+                                               while(true) {
                                                        krsort( $stack );
                                                        foreach ($stack as 
&$value) {
                                                                ksort( $value );
                                                                $value = 
call_user_func_array( 'array_merge', $value );
                                                        }
                                                        $s = 
call_user_func_array( 'array_merge', $stack );
-                                                       if( $parentFlags & 
FOXWAY_EXPECT_CURLY_CLOSE ) { // if(1) { echo 2; }
-                                                               
$needParams[0][FOXWAY_STACK_DO_TRUE] = array_merge( 
$needParams[0][FOXWAY_STACK_DO_TRUE], $s );
-                                                               $stack = 
array();
-                                                               
unset($operator);
-                                                               $operator = 
false;
-                                                               break;
-                                                       }else{ // if(1) echo 2;
-                                                               
$needParams[0][FOXWAY_STACK_DO_TRUE] = $s;
-                                                               $stack = 
array_merge( array(array(array(array_shift($needParams)))), 
array_shift($memory) ); // Restore stack and add operator
-                                                               $parentFlags = 
array_pop($parentheses);
+                                                       if( $parentFlags & 
FOXWAY_EXPECT_DO_TRUE_STACK ) { // Exsample: if(1) echo 2;
+                                                               $lastValue = 
&$needParams[0]; // Save link for operator 'else'
+                                                               if( 
$parentFlags & FOXWAY_EXPECT_CURLY_CLOSE ) { // if(1) { echo 2; }
+                                                                       
$lastValue[FOXWAY_STACK_DO_TRUE] = array_merge( 
$lastValue[FOXWAY_STACK_DO_TRUE], $s );
+                                                                       break; 
/********** EXIT **********/
+                                                               }else{ // if(1) 
echo 2;
+                                                                       
$lastValue[FOXWAY_STACK_DO_TRUE] = $s;
+                                                                       $stack 
= array_merge( array(array(array(&$lastValue))), array_shift($memory) ); // 
Restore stack and add operator
+                                                                       
array_shift($needParams);
+                                                                       
$parentFlags = array_pop($parentheses);
+                                                               }
+                                                       } elseif ( $parentFlags 
& FOXWAY_EXPECT_DO_FALSE_STACK ) { // Exsample: if(1) echo 2; else echo 3;
+                                                               $lastValue = 
&$needParams[0];
+                                                               if( 
$parentFlags & FOXWAY_EXPECT_CURLY_CLOSE ) { // if(1) { echo 2; } else { echo 
3; }
+                                                                       
$lastValue[FOXWAY_STACK_DO_FALSE] = array_merge( 
$lastValue[FOXWAY_STACK_DO_FALSE], $s );
+                                                                       break; 
/********** EXIT **********/
+                                                               }else{ // if(1) 
echo 2; else echo 3;
+                                                                       
$lastValue[FOXWAY_STACK_DO_FALSE] = $s;
+                                                                       
array_shift($needParams);
+                                                                       
$parentFlags = array_pop($parentheses);
+                                                               }
+                                                       } else { // Example: 
echo 1;
+                                                               $bytecode[] = 
$s;
+                                                               break; 
/********** EXIT **********/
                                                        }
                                                }
-
-                                               krsort( $stack );
-                                               foreach ($stack as &$value) {
-                                                       ksort( $value );
-                                                       $value = 
call_user_func_array( 'array_merge', $value );
-                                               }
-                                               $bytecode[] = 
call_user_func_array( 'array_merge', $stack );
                                                $stack = array();
                                                $parentLevel = 0;
                                        }
@@ -613,16 +621,19 @@
                                        $parentFlags = FOXWAY_EXPECT_SEMICOLON 
| FOXWAY_EXPECT_LIST_PARAMS;
                                        break;
                                case T_IF:                      // if
-                                       if( $parentFlags & 
FOXWAY_EXPECT_START_COMMAND == 0 ) { throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); }
-
-                                       //array_unshift($memory, $stack);
-                                       //$stack = array();
-                                       // stack must be empty array
+                                       if( $parentFlags & 
FOXWAY_EXPECT_START_COMMAND == 0 || $stack || $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[] = $parentFlags | 
FOXWAY_EXPECT_ELSE;
                                        $parentheses[] = 
FOXWAY_EXPECT_START_COMMAND | FOXWAY_EXPECT_SEMICOLON | 
FOXWAY_EXPECT_DO_TRUE_STACK;
                                        $parentFlags = 
FOXWAY_EXPECT_RESULT_FROM_PARENTHESES;
+                                       break;
+                               case T_ELSE:
+                                       if( $parentFlags & FOXWAY_EXPECT_ELSE 
== 0 || $stack || $operator || $values ) { throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); }
+
+                                       array_unshift( $needParams, &$lastValue 
); // $lastValue is link to operator 'if'
+                                       $parentheses[] = $parentFlags & 
~FOXWAY_EXPECT_ELSE;
+                                       $parentFlags = 
FOXWAY_EXPECT_START_COMMAND | FOXWAY_EXPECT_SEMICOLON | 
FOXWAY_EXPECT_DO_FALSE_STACK;
                                        break;
                                case '~':
                                case '!':
@@ -669,16 +680,19 @@
                                        // Example: if(1) { echo "hello"; }
                                        if( $parentFlags & 
FOXWAY_EXPECT_START_COMMAND == 0 || $stack || $operator || $values ) { throw 
new ExceptionFoxway($id, FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine); }
 
-                                       $s = array_merge( 
array(array(array(array_shift($needParams)))), array_shift($memory) ); // 
Restore stack and add operator
-                                       krsort( $s );
-                                       foreach ($s as &$value) {
-                                               ksort( $value );
-                                               $value = call_user_func_array( 
'array_merge', $value );
-                                       }
-                                       $bytecode[] = call_user_func_array( 
'array_merge', $s );
-                                       $parentLevel = 0;
+                                       array_shift($needParams);
                                        array_pop($parentheses);
                                        $parentFlags = array_pop($parentheses);
+                                       if( 
!isset($lastValue[FOXWAY_STACK_DO_FALSE]) ) { // operator 'else' not used
+                                               $s = array_merge( 
array(array(array(&$lastValue))), array_shift($memory) ); // Restore stack and 
add operator
+                                               krsort( $s );
+                                               foreach ($s as &$value) {
+                                                       ksort( $value );
+                                                       $value = 
call_user_func_array( 'array_merge', $value );
+                                               }
+                                               $bytecode[] = 
call_user_func_array( 'array_merge', $s );
+                                               $parentLevel = 0;
+                                       }
                                        break;
                                default :
                                        //throw new ExceptionFoxway($id, 
FOXWAY_PHP_SYNTAX_ERROR_UNEXPECTED, $tokenLine);
diff --git a/includes/Runtime.php b/includes/Runtime.php
index 75f8ecd..0bcf76f 100644
--- a/includes/Runtime.php
+++ b/includes/Runtime.php
@@ -787,13 +787,20 @@
                                                }
                                                break;
                                        case T_IF:
-                                               if( $value[FOXWAY_STACK_PARAM] 
) { // if( true )
+                                               if( $value[FOXWAY_STACK_PARAM] 
) { // Example: if( true )
                                                        if( 
$value[FOXWAY_STACK_DO_TRUE] ) { // Stack not empty: if(true);
                                                                $memory[] = 
array( null, $code, $i, $c );
                                                                $code = 
$value[FOXWAY_STACK_DO_TRUE];
                                                                $i = -1;
                                                                $c = 
count($code);
                                                        }
+                                               }else{ // Example: if( false )
+                                                       if( 
isset($value[FOXWAY_STACK_DO_FALSE]) ) { // Stack not empty: if(false) ; else ;
+                                                               $memory[] = 
array( null, $code, $i, $c );
+                                                               $code = 
$value[FOXWAY_STACK_DO_FALSE];
+                                                               $i = -1;
+                                                               $c = 
count($code);
+                                                       }
                                                }
                                                break;
                                }
diff --git a/tests/phpunit/includes/RuntimeTest.php 
b/tests/phpunit/includes/RuntimeTest.php
index c736414..5d9fef0 100644
--- a/tests/phpunit/includes/RuntimeTest.php
+++ b/tests/phpunit/includes/RuntimeTest.php
@@ -1059,4 +1059,53 @@
                                array()
                                );
        }
+       public function testRun_echo_if_else_simple_1() {
+               $this->assertEquals(
+                               Runtime::runSource('if ( true ) echo "true"; 
else echo "false";'),
+                               array('true')
+                               );
+       }
+       public function testRun_echo_if_else_simple_2() {
+               $this->assertEquals(
+                               Runtime::runSource('if ( false ) echo "true"; 
else echo "false";'),
+                               array('false')
+                               );
+       }
+       public function testRun_echo_if_else_simple_3() {
+               $this->assertEquals(
+                               Runtime::runSource('if ( true ) echo "true"; 
else echo "false"; echo " always!";'),
+                               array('true', ' always!')
+                               );
+       }
+       public function testRun_echo_if_else_simple_4() {
+               $this->assertEquals(
+                               Runtime::runSource('if ( false ) echo "true"; 
else echo "false"; echo " always!";'),
+                               array('false', ' always!')
+                               );
+       }
+       public function testRun_echo_if_else_block_1() {
+               $this->assertEquals(
+                               Runtime::runSource('if ( true ) { echo "true1"; 
echo "true2";} else { echo "false1"; echo "false2"; }'),
+                               array('true1', 'true2')
+                               );
+       }
+       public function testRun_echo_if_else_block_2() {
+               $this->assertEquals(
+                               Runtime::runSource('if ( false ) { echo 
"true1"; echo "true2";} else { echo "false1"; echo "false2"; }'),
+                               array('false1', 'false2')
+                               );
+       }
+       public function testRun_echo_if_else_block_3() {
+               $this->assertEquals(
+                               Runtime::runSource('if ( true ) { echo "true1"; 
echo "true2";} else { echo "false1"; echo "false2"; } echo " always!";'),
+                               array('true1', 'true2', ' always!')
+                               );
+       }
+       public function testRun_echo_if_else_block_4() {
+               $this->assertEquals(
+                               Runtime::runSource('if ( false ) { echo 
"true1"; echo "true2";} else { echo "false1"; echo "false2"; } echo " 
always!";'),
+                               array('false1', 'false2', ' always!')
+                               );
+       }
+
 }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie93952efdd89e6f2f2dd54bb296cad721f54bad3
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