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 <[email protected]>
Gerrit-Reviewer: Pastakhov <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits