Pastakhov has submitted this change and it was merged. Change subject: Add support number and math operators + - * / (version 0.0.2) ......................................................................
Add support number and math operators + - * / (version 0.0.2) sample: echo 10 + 5 * 5; // 35 Change-Id: I2b4caf4bb01b52ded5f3c1c70152604dff469206 --- M Foxway.php M includes/Interpreter.php M includes/Runtime.php M tests/phpunit/includes/InterpreterTest.php 4 files changed, 139 insertions(+), 30 deletions(-) Approvals: Pastakhov: Verified; Looks good to me, approved diff --git a/Foxway.php b/Foxway.php index ed7ad34..f07851a 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.1' ); +define( 'Foxway_VERSION' , '0.0.2' ); // Register this extension on Special:Version $wgExtensionCredits['parserhook'][] = array( diff --git a/includes/Interpreter.php b/includes/Interpreter.php index 97fbdcf..bf592c0 100644 --- a/includes/Interpreter.php +++ b/includes/Interpreter.php @@ -43,6 +43,8 @@ break; } + //\MWDebug::log( var_export($token,true) ); + switch ($id) { case T_COMMENT: case T_DOC_COMMENT: @@ -62,8 +64,10 @@ } if( $expectQuotesClose ) { $expectQuotesClose = false; + $expected = array('.', ';'); } else { $expectQuotesClose = true; + $expected = array(T_ENCAPSED_AND_WHITESPACE, T_CURLY_OPEN, T_VARIABLE, '"'); } break; case ';': @@ -76,27 +80,37 @@ $expected = array( T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE, + T_LNUMBER, + T_DNUMBER, T_VARIABLE, T_CURLY_OPEN, '"', - ';', + //';', ); break; case '.': + case '+': + case '-': + case '*': + case '/': $expected = array( T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE, + T_LNUMBER, + T_DNUMBER, T_VARIABLE, T_CURLY_OPEN, '"', - ';', + //';', ); - $runtime->addOperator('.'); + $runtime->addOperator( $id ); break; case ',': $expected = array( T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE, + T_LNUMBER, + T_DNUMBER, T_VARIABLE, T_CURLY_OPEN, '"', @@ -109,6 +123,8 @@ $expected = array( T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE, + //T_LNUMBER, + //T_DNUMBER, T_VARIABLE, T_CURLY_OPEN, '"', @@ -129,8 +145,6 @@ //@todo: /*$expected = array( T_START_HEREDOC, - T_DNUMBER, - T_LNUMBER, T_STRING_CAST, T_INT_CAST, T_FUNCTION, @@ -139,6 +153,8 @@ $expected = array( T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE, + T_LNUMBER, + T_DNUMBER, T_VARIABLE, T_CURLY_OPEN, '"', @@ -152,13 +168,18 @@ $is_apostrophe = substr($text, 0, 1) == '\'' ? true : false; $string = substr($text, 1, -1); $runtime->addParam( self::process_slashes($string, $is_apostrophe) ); - $expected = array( - ';', - '.', - ); + $expected = array( ';', '.', '+', '-', '*', '/' ); if($expectListParams){ $expected[] = ','; } + break; + case T_LNUMBER: + case T_DNUMBER: + if($is_debug) { + $debug[] = '<span style="color:#FF00FF" title="'. token_name($id) . '">' . htmlspecialchars($text) . '</span>'; + } + $runtime->addParam( $text ); + $expected = array(';', '.', '+', '-', '*', '/'); break; case T_ENCAPSED_AND_WHITESPACE: if($is_debug) { @@ -174,12 +195,13 @@ if( $expectCurlyClose ) { $expected = array( '}' ); } else { - $expected = array( ';', T_ENCAPSED_AND_WHITESPACE ); + $expected = array( ';', '.', '+', '-', '*', '/', T_ENCAPSED_AND_WHITESPACE ); } if( $expectListParams ) { $expected[] = ','; } if( $expectQuotesClose ) { + $expected[] = T_VARIABLE; //echo "$s$s"; $expected[] = '"'; } if($is_debug) { diff --git a/includes/Runtime.php b/includes/Runtime.php index d06671e..caca417 100644 --- a/includes/Runtime.php +++ b/includes/Runtime.php @@ -15,15 +15,14 @@ private $lastParam = null; private $listParams = array(); private $lastOperator = false; - private $lastVariable = false; - private $listVariables = array(); - private $lastVariableOperator = false; + private $variableOperator = false; + private $mathMemory = false; private $stack = array(); private static $variables = array(); private function pushStack() { - $this->stack[] = array($this->lastCommand, $this->lastDebug, $this->lastParam, $this->listParams, $this->lastOperator, $this->lastVariable, $this->listVariables, $this->lastVariableOperator); + $this->stack[] = array($this->lastCommand, $this->lastDebug, $this->lastParam, $this->listParams, $this->lastOperator, $this->variableOperator, $this->mathMemory); } public function popStack() { @@ -33,11 +32,10 @@ $this->lastParam = null; $this->listParams = array(); $this->lastOperator = false; - $this->lastVariable = false; - $this->listVariables = array(); - $this->lastVariableOperator = false; + $this->variableOperator = false; + $this->mathMemory = false; } else { - list($this->lastCommand, $this->lastDebug, $this->lastParam, $this->listParams, $this->lastOperator, $this->lastVariable, $this->listVariables, $this->lastVariableOperator) = array_pop($this->stack); + list($this->lastCommand, $this->lastDebug, $this->lastParam, $this->listParams, $this->lastOperator, $this->variableOperator, $this->mathMemory) = array_pop($this->stack); } } @@ -53,7 +51,21 @@ if( $this->lastOperator ) { switch ( $this->lastOperator ) { case '.': - $this->lastParam = $this->lastParam . $param; + $this->lastParam .= $param; + $this->lastOperator = false; + break; + case '*': + $this->lastParam *= $param; + $this->lastOperator = false; + break; + case '/': + $this->lastParam /= $param; + $this->lastOperator = false; + break; + case '+': + case '-': + $this->mathMemory = array($this->lastParam, $this->lastOperator); + $this->lastParam = $param; $this->lastOperator = false; break; default: @@ -70,10 +82,26 @@ } public function addOperator( $operator ) { + if( $this->mathMemory && ($operator=='+'||$operator=='-') ){ + if( $this->mathMemory[1] == '+' ) { + $this->lastParam = $this->mathMemory[0] + $this->lastParam; + } else { // $this->mathMemory[1] == '-' + $this->lastParam = $this->mathMemory[0] - $this->lastParam; + } + $this->mathMemory = false; + } $this->lastOperator = $operator; } public function getCommandResult( &$debug ) { + if( $this->mathMemory ) { + if( $this->mathMemory[1] == '+' ) { + $this->lastParam = $this->mathMemory[0] + $this->lastParam; + } else { // $this->mathMemory[1] == '-' + $this->lastParam = $this->mathMemory[0] - $this->lastParam; + } + $this->mathMemory = false; + } $this->listParams[] = $this->lastParam; $return = null; @@ -87,7 +115,7 @@ default: $lastCommand = $this->lastCommand; if( substr($lastCommand, 0, 1) == '$' ) { - switch ($this->lastVariableOperator) { + switch ($this->variableOperator) { case '=': if( $this->lastDebug !== false ) { $debug[$this->lastDebug] = '<span style="color:#6D3206" title="'.token_name(T_VARIABLE).' set '.htmlspecialchars( var_export($this->lastParam, true) ).'">' . $lastCommand . '</span>'; @@ -96,7 +124,7 @@ break; default: // TODO exception - $return = 'Error! Unknown operator "' . htmlspecialchars($this->lastVariableOperator) . '" in ' . __METHOD__; + $return = 'Error! Unknown operator "' . htmlspecialchars($this->variableOperator) . '" in ' . __METHOD__; \MWDebug::log($return); break; } @@ -116,7 +144,7 @@ } public function setVariableOperator( $operator ) { - $this->lastVariableOperator = $operator; + $this->variableOperator = $operator; } public function getVariable( $name ) { diff --git a/tests/phpunit/includes/InterpreterTest.php b/tests/phpunit/includes/InterpreterTest.php index 27cf316..5d0bd1c 100644 --- a/tests/phpunit/includes/InterpreterTest.php +++ b/tests/phpunit/includes/InterpreterTest.php @@ -7,33 +7,56 @@ */ class InterpreterTest extends \PHPUnit_Framework_TestCase { - public function testRun_echo() { + public function testRun_echo_apostrophe() { $this->assertEquals( Interpreter::run('echo "Hello!";'), 'Hello!' ); + } + + public function testRun_echo_quotes() { $this->assertEquals( Interpreter::run("echo 'Hello!';"), 'Hello!' ); + } + + public function testRun_echo_union() { $this->assertEquals( Interpreter::run('echo "String" . "Union";'), 'StringUnion' ); $this->assertEquals( + Interpreter::run('echo \'This \' . \'string \' . \'was \' . \'made \' . \'with concatenation.\' . "\n";'), + "This string was made with concatenation.\n" + ); + } + + public function testRun_echo_parameters() { + $this->assertEquals( Interpreter::run('echo "Parameter1","Parameter2" , "Parameter3";'), 'Parameter1Parameter2Parameter3' ); - /*$this->assertEquals( + $this->assertEquals( + Interpreter::run('echo \'This \', \'string \', \'was \', \'made \', \'with multiple parameters.\';'), + 'This string was made with multiple parameters.' + ); + } + + public function testRun_echo_multiline() { + $this->assertEquals( Interpreter::run('echo "This spans multiple lines. The newlines will be output as well";'), "This spans\nmultiple lines. The newlines will be\noutput as well" - );*/ + ); $this->assertEquals( Interpreter::run('echo "Again: This spans\nmultiple lines. The newlines will be\noutput as well.";'), "Again: This spans\nmultiple lines. The newlines will be\noutput as well." ); + } + + public function testRun_echo_variables() { $this->assertEquals( Interpreter::run(' $foo = "foobar"; @@ -62,17 +85,53 @@ 'foobarbarbaz' ); $this->assertEquals( - Interpreter::run('echo \'This \', \'string \', \'was \', \'made \', \'with multiple parameters.\';'), - 'This string was made with multiple parameters.' + Interpreter::run('echo "$foo$bar";'), + 'foobarbarbaz' ); $this->assertEquals( - Interpreter::run('echo \'This \' . \'string \' . \'was \' . \'made \' . \'with concatenation.\' . "\n";'), - "This string was made with concatenation.\n" + Interpreter::run('echo "s{$foo}l{$bar}e";'), + 'sfoobarlbarbaze' ); + $this->assertEquals( + Interpreter::run('echo "s{$foo}l$bar";'), + 'sfoobarlbarbaz' + ); + $this->assertEquals( + Interpreter::run('echo "start" . $foo . "end";'), + 'startfoobarend' + ); + } + + public function testRun_echo_escaping() { $this->assertEquals( Interpreter::run('echo \'s\\\\\\\'e\';'), // echo 's\\\'e'; 's\\\'e' // s\'e ); + $this->assertEquals( + Interpreter::run('echo "s\\\\\\"e";'), // echo "s\\\"e"; + 's\\"e' // s\"e + ); } + public function testRun_echo_digit() { + $this->assertEquals( + Interpreter::run('echo 5;'), + '5' + ); + } + + public function testRun_echo_math() { + $this->assertEquals( + Interpreter::run('echo 5 + 5 * 10;'), + '55' + ); + $this->assertEquals( + Interpreter::run('echo 5 + 5 / 10 + 50/100;'), + '6' + ); + $this->assertEquals( + Interpreter::run('echo 10 * 10 + "20" * \'20\' - 30 * 30 + 40 / 9;'), + '-395.55555555556' + ); + } } -- To view, visit https://gerrit.wikimedia.org/r/56893 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2b4caf4bb01b52ded5f3c1c70152604dff469206 Gerrit-PatchSet: 2 Gerrit-Project: mediawiki/extensions/Foxway Gerrit-Branch: master Gerrit-Owner: Pastakhov <pastak...@yandex.ru> Gerrit-Reviewer: Pastakhov <pastak...@yandex.ru> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits