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