jenkins-bot has submitted this change and it was merged.
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(-)
Approvals:
Pastakhov: Looks good to me, approved
jenkins-bot: Verified
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: merged
Gerrit-Change-Id: If93ace77f6145b42289207e6091cf6a3617b32aa
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Foxway
Gerrit-Branch: develop
Gerrit-Owner: Pastakhov <[email protected]>
Gerrit-Reviewer: Pastakhov <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits