Pastakhov has uploaded a new change for review. https://gerrit.wikimedia.org/r/58657
Change subject: add ternary operator (version 0.0.9)
......................................................................
add ternary operator (version 0.0.9)
example:
echo true?'true':'false'; // 'true'
Change-Id: Ic7b4b5092628ee2446f6ab6f75d4080a28c2bcc5
---
M Foxway.php
M includes/Interpreter.php
M includes/Runtime.php
M tests/phpunit/includes/InterpreterTest.php
4 files changed, 157 insertions(+), 8 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Foxway
refs/changes/57/58657/1
diff --git a/Foxway.php b/Foxway.php
index cd71152..4ece886 100644
--- a/Foxway.php
+++ b/Foxway.php
@@ -15,7 +15,7 @@
die( 'This file is an extension to MediaWiki and thus not a valid entry
point.' );
}
-define( 'Foxway_VERSION' , '0.0.8' );
+define( 'Foxway_VERSION' , '0.0.9' );
// Register this extension on Special:Version
$wgExtensionCredits['parserhook'][] = array(
diff --git a/includes/Interpreter.php b/includes/Interpreter.php
index dab7d7d..ca27337 100644
--- a/includes/Interpreter.php
+++ b/includes/Interpreter.php
@@ -38,6 +38,8 @@
T_IS_NOT_EQUAL, // !=
T_IS_IDENTICAL, // ===
T_IS_NOT_IDENTICAL, // !==
+ '?',
+ ':',
);
public static function run($source, $is_debug = false) {
@@ -52,10 +54,12 @@
$incrementVariable = false;
$variableName = null;
$variableValue = null;
+ $skipTernaryBlocks = 0;
$line = 1;
$runtime = new Runtime();
- foreach ($tokens as $token) {
+ reset($tokens);
+ while ( list(, $token) = each($tokens) ) {
if ( is_string($token) ) {
$id = $token;
} else {
@@ -64,7 +68,7 @@
if( $expected && in_array($id, self::$skipTokenIds) ===
false && in_array($id, $expected) === false) {
$id_str = is_string($id) ? "' $id '" :
token_name($id);
- $return .= '<br><span class="error">' .
wfMessage( 'foxway-php-syntax-error-unexpected', $id_str, $line )->escaped() .
'</span>';
+ $return .= '<br><span class="error" title="' .
__LINE__ . '">' . wfMessage( 'foxway-php-syntax-error-unexpected', $id_str,
$line )->escaped() . '</span>';
break;
}
@@ -128,6 +132,98 @@
case T_IS_IDENTICAL: // ===
case T_IS_NOT_IDENTICAL: // !==
$runtime->addOperator( $id );
+ break;
+ case '?':
+ if( $runtime->getMathResult($debug) ) {
+ $skipTernaryBlocks++;
+ } else {
+ $tmp_skip = 0;
+ $skipedTokens = 0;
+ $tmp_token = current($tokens);
+ do {
+ \MWDebug::log(
var_export($tmp_token, true) );
+ switch ($tmp_token) {
+ case '?':
+
$tmp_skip++;
+ break;
+ case ':':
+ if(
$tmp_skip > 0 ) {
+
$tmp_skip--;
+ } else {
+
break 2;
+ }
+ break;
+ case
T_WHITESPACE:
+ case T_COMMENT:
+ case
T_DOC_COMMENT:
+ break;
// just ignore
+ case ',':
+ case ';':
+ case T_IF:
+ if (
is_string($tmp_token) ) {
+
$tmp_id = $tmp_token;
+
$tmp_line = $line;
+ } else {
+
list($tmp_id, $tmp_text, $tmp_line) = $tmp_token;
+ }
+ $return
.= $return .= '<br><span class="error" title="' . __LINE__ . '">' . wfMessage(
'foxway-php-syntax-error-unexpected', is_string($tmp_id) ? "' $tmp_id '" :
token_name($tmp_id), $tmp_line )->escaped() . '</span>';
+ break 4;
+ default :
+
$skipedTokens++;
+ break;
+ }
+ } while( $tmp_token =
next($tokens) );
+ if($is_debug) {
+ $debug[] = '<span
style="color:#969696" title="Skiped tokens: '.$skipedTokens.'"> ? ... </span>';
+ }
+ continue 2;
+ }
+ break;
+ case ':':
+ if( $skipTernaryBlocks > 0 ) {
+ $skipTernaryBlocks--;
+ $skipedTokens = 0;
+ $tmp_token = current($tokens);
+ do {
+ \MWDebug::log(
var_export($tmp_token, true) );
+ switch ($tmp_token) {
+ case '?':
+
$skipTernaryBlocks++;
+ break;
+ case ':':
+
$skipTernaryBlocks--;
+ break;
+ case ',':
+ case ';':
+ if(
$skipedTokens > 0 ) {
+
if($is_debug) {
+
$debug[] = '<span style="color:#969696" title="Skiped tokens:
'.$skipedTokens.'"> : ... </span>';
+
}
+
//prev($tokens);
+
continue 4;
+ }
+ //
break is not necessary here
+ case T_IF:
+ if (
is_string($tmp_token) ) {
+
$tmp_id = $tmp_token;
+
$tmp_line = $line;
+ } else {
+
list($tmp_id, $tmp_text, $tmp_line) = $tmp_token;
+ }
+ $return
.= $return .= '<br><span class="error" title="' . __LINE__ . '">' . wfMessage(
'foxway-php-syntax-error-unexpected', is_string($tmp_id) ? "' $tmp_id '" :
token_name($tmp_id), $tmp_line )->escaped() . '</span>';
+ break 4;
+ case
T_WHITESPACE:
+ case T_COMMENT:
+ case
T_DOC_COMMENT:
+ break;
// just ignore
+ default :
+
$skipedTokens++;
+ break;
+ }
+ } while( $tmp_token =
next($tokens) );
+ $return .= $return .=
'<br><span class="error" title="' . __LINE__ . '">' . wfMessage(
'foxway-php-syntax-error-unexpected', '$end', $line )->escaped() . '</span>';
+ break 2;
+ }
break;
case T_INC: // ++
case T_DEC: // --
@@ -249,7 +345,7 @@
} elseif( strcasecmp($text, 'false') ==
0 ) {
$runtime->addParam( false );
} else {
- $return .= '<br><span
class="error">' . wfMessage( 'foxway-php-syntax-error-unexpected', "'$text'",
$line )->escaped() . '</span>';
+ $return .= '<br><span
class="error" title="' . __LINE__ . '">' . wfMessage(
'foxway-php-syntax-error-unexpected', "'$text'", $line )->escaped() . '</span>';
break 2;
}
break;
@@ -257,6 +353,8 @@
if( $id != T_VARIABLE && $id != T_INC && $id != T_DEC )
{
$incrementVariable = false;
}
+
+ /***************** EXPECT
*************************************/
switch ($id) {
case ';':
@@ -320,6 +418,8 @@
case T_IS_NOT_EQUAL: // !=
case T_IS_IDENTICAL: // ===
case T_IS_NOT_IDENTICAL: // !==
+ case '?':
+ case ':':
$expected = array(
T_CONSTANT_ENCAPSED_STRING, //
"foo" or 'bar'
T_ENCAPSED_AND_WHITESPACE, // "
$a"
@@ -347,7 +447,7 @@
$expectCurlyClose = true;
$expected = array( T_VARIABLE );
} else {
- $return .= '<br><span
class="error">' . wfMessage( 'foxway-php-syntax-error-unexpected', '\' { \'',
$line )->escaped() . '</span>';
+ $return .= '<br><span
class="error" title="' . __LINE__ . '">' . wfMessage(
'foxway-php-syntax-error-unexpected', '\' { \'', $line )->escaped() . '</span>';
break 2;
}
break;
@@ -364,7 +464,7 @@
'"',
);
} else {
- $return .= '<br><span
class="error">' . wfMessage( 'foxway-php-syntax-error-unexpected', '\' } \'',
$line )->escaped() . '</span>';
+ $return .= '<br><span
class="error" title="' . __LINE__ . '">' . wfMessage(
'foxway-php-syntax-error-unexpected', '\' } \'', $line )->escaped() . '</span>';
break 2;
}
break;
diff --git a/includes/Runtime.php b/includes/Runtime.php
index 3ac793a..50785bc 100644
--- a/includes/Runtime.php
+++ b/includes/Runtime.php
@@ -39,7 +39,6 @@
array('|'),
array('&&'),
array('||'),
- array('?', ':'),
);
private function getOperatorPrecedence( $operator ) {
@@ -138,7 +137,7 @@
}
}
- private function doMath( $precedence = 12 ) { //12 =
count($operatorsPrecedence)-1
+ private function doMath( $precedence = 11 ) { //11 =
count($operatorsPrecedence)-1
if( isset($this->mathMemory[0]) ) {
while( $mathZerroMemory =
array_pop($this->mathMemory[0]) ) {
$this->doOperation($mathZerroMemory);
@@ -241,6 +240,13 @@
//\MWDebug::log( "function doOperation('$operator', '$param') @
'$this->lastParam'");
}
+ public function getMathResult( &$debug ) {
+ $this->doMath();
+ $return = $this->lastParam;
+ $this->lastParam = null;
+ return $return;
+ }
+
public function getCommandResult( &$debug ) {
// \MWDebug::log('function getCommandResult()');
$this->doMath();
diff --git a/tests/phpunit/includes/InterpreterTest.php
b/tests/phpunit/includes/InterpreterTest.php
index 4ff2c6a..76d9ef8 100644
--- a/tests/phpunit/includes/InterpreterTest.php
+++ b/tests/phpunit/includes/InterpreterTest.php
@@ -552,4 +552,47 @@
);
}
+ public function testRun_echo_ternary_1() {
+ $this->assertEquals(
+ Interpreter::run('echo true?"true":"false";'),
+ 'true'
+ );
+ }
+ public function testRun_echo_ternary_2() {
+ $this->assertEquals(
+ Interpreter::run('echo false?"true":"false";'),
+ 'false'
+ );
+ }
+ public function testRun_echo_ternary_3() {
+ $this->assertEquals(
+ Interpreter::run('echo
true?"true":false?"t":"f";'),
+ 't'
+ );
+ }
+ public function testRun_echo_ternary_4() {
+ $this->assertEquals(
+ Interpreter::run('echo
true?true?"true":false:false?"t":"f";'),
+ 't'
+ );
+ }
+ public function testRun_echo_ternary_5() {
+ $this->assertEquals(
+ Interpreter::run('echo
true?true?false:false:false?"t":"f";'),
+ 'f'
+ );
+ }
+ public function testRun_echo_ternary_6() {
+ $this->assertEquals(
+ Interpreter::run('echo
true?true?"true":false:"false";'),
+ 'true'
+ );
+ }
+ public function testRun_echo_ternary_7() {
+ $this->assertEquals(
+ Interpreter::run('echo
false?true?false:false:"false";'),
+ 'false'
+ );
+ }
+
}
--
To view, visit https://gerrit.wikimedia.org/r/58657
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic7b4b5092628ee2446f6ab6f75d4080a28c2bcc5
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Foxway
Gerrit-Branch: master
Gerrit-Owner: Pastakhov <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
