Pastakhov has uploaded a new change for review.
https://gerrit.wikimedia.org/r/62217
Change subject: Refactoring (version 0.2.0)
......................................................................
Refactoring (version 0.2.0)
Patch Set 1: Refactoring and add class Variable
Change-Id: I7a479b05548e9a9f096f3d1375fb6feaafab8c2d
---
M Foxway.php
M includes/Debug.php
M includes/Interpreter.php
M includes/Runtime.php
M includes/RuntimeDebug.php
A includes/Variable.php
M tests/phpunit/includes/InterpreterTest.php
7 files changed, 331 insertions(+), 293 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Foxway
refs/changes/17/62217/1
diff --git a/Foxway.php b/Foxway.php
index 3e60e4b..5dec562 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.1.0' );
+define( 'Foxway_VERSION' , '0.2.0' );
// Register this extension on Special:Version
$wgExtensionCredits['parserhook'][] = array(
@@ -57,6 +57,7 @@
$wgAutoloadClasses['Foxway\\Interpreter'] = $dir .
'/includes/Interpreter.php';
$wgAutoloadClasses['Foxway\\Runtime'] = $dir .
'/includes/Runtime.php';
$wgAutoloadClasses['Foxway\\RuntimeDebug'] = $dir .
'/includes/RuntimeDebug.php';
+$wgAutoloadClasses['Foxway\\Variable'] = $dir .
'/includes/Variable.php';
// Resources
$wgResourceModules['ext.Foxway.Debug'] = array(
diff --git a/includes/Debug.php b/includes/Debug.php
index 33dea04..bea0441 100644
--- a/includes/Debug.php
+++ b/includes/Debug.php
@@ -38,12 +38,14 @@
}
private static function getHTMLbyToken( $token ) {
- if ( is_string($token) ) {
+ if ( is_array($token) ) {
+ list($id, $t) = $token;
+ $text = strtr( $t, array('&'=>'&', '<'=>'<') );
+ $tokenName = token_name($id);
+ } else {
$id = $token;
$text = strtr( $id, array('&'=>'&', '<'=>'<') );
- } else {
- list($id, $text) = $token;
- $text = strtr( $text, array('&'=>'&', '<'=>'<')
);
+ $tokenName = false;
}
$class = false;
@@ -76,6 +78,7 @@
case T_IF:
case T_ELSE:
case T_ELSEIF:
+ case T_ARRAY:
$class = 'foxway_construct';
break;
case T_VARIABLE:
@@ -95,11 +98,15 @@
return '';
}
+ $attribs = array();
if( $class !== false ) {
- return \Html::rawElement( 'span',
array('class'=>$class, 'title'=>token_name($id)), $text );
+ $attribs['class'] = $class;
}
- if( is_array($token) ) {
- return \Html::rawElement( 'span',
array('title'=>token_name($id)), $text );
+ if( $tokenName ) {
+ $attribs['title'] = $tokenName;
+ }
+ if( count($attribs) > 0 ) {
+ return \Html::rawElement( 'span', $attribs, $text );
}
return $text;
}
diff --git a/includes/Interpreter.php b/includes/Interpreter.php
index 19b70a2..0aaf205 100644
--- a/includes/Interpreter.php
+++ b/includes/Interpreter.php
@@ -224,12 +224,13 @@
$runtime->addParam( (float)$text );
break;
case T_ENCAPSED_AND_WHITESPACE: // " $a"
+ $runtime->addParam(
self::process_slashes($text, false) );
if( $expectQuotesClose ) {
$runtime->addOperator('.');
}
- $runtime->addParam(
self::process_slashes($text, false) );
break;
case T_VARIABLE:
+ $runtime->addVariableAsParam( $text );
if( $expected && in_array(T_VARIABLE,
$expected) ) {
if( $expectCurlyClose ) {
$expected = array( '}'
);
@@ -286,7 +287,6 @@
',',
);
}
- $runtime->addParam( "\0$text" );
break;
case T_STRING:
if( strcasecmp($text, 'true') == 0 ) {
@@ -325,7 +325,7 @@
switch ($command) {
case T_ECHO:
$commandsEmbedded--;
- $return[] = $result;
+ $return =
array_merge($return, $result);
break;
case T_IF:
$commandsEmbedded--;
@@ -405,7 +405,6 @@
case '"':
if( $expectQuotesClose === false ) {
$runtime->addOperator('"(');
- $runtime->addParam('');
$expectQuotesClose = true;
$expected =
array(T_ENCAPSED_AND_WHITESPACE, T_CURLY_OPEN, T_VARIABLE, '"');
break;
diff --git a/includes/Runtime.php b/includes/Runtime.php
index 01786df..bc148db 100644
--- a/includes/Runtime.php
+++ b/includes/Runtime.php
@@ -46,6 +46,11 @@
array(T_LOGICAL_OR), // or
array(','),
);
+ private $countPrecedences;
+
+ public function __construct() {
+ $this->countPrecedences = count(self::$operatorsPrecedence)-1;
+ }
public function getOperators() {
static $operators = array();
@@ -91,10 +96,12 @@
}
public function addCommand( $name ) {
- if( $this->lastCommand ) {
- $this->pushStack();
- }
+ $this->pushStack();
$this->lastCommand = $name;
+ }
+
+ public function addVariableAsParam( $name ) {
+ $this->addParam( new Variable($name, self::$variables) );
}
public function addParam( $param ) {
@@ -104,7 +111,6 @@
$this->lastOperator = false;
}
$this->lastParam = $param;
- $this->doMath(0);
}
protected function parenthesesOpen() {
@@ -118,6 +124,10 @@
protected function parenthesesClose() {
$this->doMath();
+ if( count($this->listParams) ) {
+ $this->listParams[] = $this->lastParam;
+ $this->lastParam = $this->listParams;
+ }
$this->popStack();
if( !is_null($this->lastCommand) && $this->lastCommand !=
T_ECHO ) {
return $this->lastCommand;
@@ -125,26 +135,59 @@
}
public function addOperator( $operator ) {
+ if( $this->lastParam instanceof Variable ) {
+ $lastParam = &$this->lastParam->getReference();
+ }else{
+ $lastParam = &$this->lastParam;
+ }
+
switch ($operator) {
+ case ',':
+ $this->doMath();
+ $this->listParams[] = $this->lastParam
instanceof Variable ? $this->lastParam->getReference() : $this->lastParam;
+ $this->lastParam = null;
+ break;
+ case '?':
+ $this->doMath(
$this->getOperatorPrecedence('?') );
+ return $this->lastParam instanceof Variable ?
$this->lastParam->getReference() : $this->lastParam;
+ break;
case '"(':
case '(':
$this->parenthesesOpen();
break;
case '")':
+ $this->lastOperator = false;
+ // break is not necessary here
case ')':
$this->parenthesesClose();
- if( $this->lastCommand && $this->lastCommand !=
T_ECHO ) {
- if( substr($this->lastParam, 0, 2) ==
"\0$" ) {
- $variableLastParam =
substr($this->lastParam, 2);
- if(
!isset(self::$variables[$variableLastParam]) ) {
- //TODO
- return array(
$this->lastCommand, null);
- } else {
- return array(
$this->lastCommand, self::$variables[$variableLastParam]);
+ if( $this->lastCommand == T_IF ) {
+ return array( T_IF, $this->lastParam
instanceof Variable ? $this->lastParam->getReference() : $this->lastParam );
+ }elseif($this->lastCommand ) {
+ $this->doCommand();
+ }
+ break;
+ case '[':
+ $this->addCommand($this->lastParam);
+ break;
+ case ']':
+ $this->doMath();
+ if( substr($this->lastCommand, 0, 2) == "\0$" )
{
+ $variable = substr($this->lastCommand,
2);
+ \MWDebug::log('$variable = ' .
var_export($variable,true));
+ \MWDebug::log('variables = ' .
var_export(self::$variables,true));
+ if( isset(self::$variables[$variable])
) {
+ $value =
&self::$variables[$variable];
+ if( !is_array($value) || isset(
$value[$this->lastParam]) ) {
+ $this->lastParam =
$value[$this->lastParam];
+ $this->popStack();
+
\MWDebug::log('$this->lastParam = ' . var_export($this->lastParam,true));
+ break;
}
}
- return array( $this->lastCommand,
$this->lastParam);
}
+ $this->lastParam = null;
+ $this->popStack();
+ \MWDebug::log('$this->lastParam = ' .
var_export($this->lastParam,true));
break;
default:
$precedence = $this->getOperatorPrecedence(
$operator );
@@ -160,45 +203,15 @@
case T_STRING_CAST:
case T_ARRAY_CAST:
case T_BOOL_CAST:
+ case T_INC:
+ case T_DEC:
if(
!isset($this->mathMemory[0]) ) {
$this->mathMemory[0] = array();
}
$this->mathMemory[0][]
= $operator;
- break;
- case T_INC: // TODO
- if( $this->lastOperator
|| is_null($this->lastParam) ) {
- if(
!isset($this->mathMemory[0]) ) {
-
$this->mathMemory[0] = array();
- }
-
$this->mathMemory[0][] = $operator;
- } else {
-
$variableLastParam = false;
- if(
substr($this->lastParam, 0, 2) == "\0$" ) {
-
$variableLastParam = substr($this->lastParam, 2);
- if(
!isset(self::$variables[$variableLastParam]) ) {
-
self::$variables[$variableLastParam] = null;
- }
-
$this->lastParam = self::$variables[$variableLastParam];
-
self::$variables[$variableLastParam]++;
- }
- }
- break;
- case T_DEC: // TODO
- if( $this->lastOperator
|| is_null($this->lastParam) ) {
- if(
!isset($this->mathMemory[0]) ) {
-
$this->mathMemory[0] = array();
- }
-
$this->mathMemory[0][] = $operator;
- } else {
-
$variableLastParam = false;
- if(
substr($this->lastParam, 0, 2) == "\0$" ) {
-
$variableLastParam = substr($this->lastParam, 2);
- if(
!isset(self::$variables[$variableLastParam]) ) {
-
self::$variables[$variableLastParam] = null;
- }
-
$this->lastParam = self::$variables[$variableLastParam];
-
self::$variables[$variableLastParam]--;
- }
+ if( $this->lastParam
instanceof Variable && !$this->lastOperator ) {
+
$this->lastOperator = $operator;
+
$this->doMath(0);
}
break;
default:
@@ -212,24 +225,18 @@
}
break;
}
- if( substr($this->lastParam, 0, 2) == "\0$" ) {
- $variableLastParam = substr($this->lastParam, 2);
- if( !isset(self::$variables[$variableLastParam]) ) {
- //TODO
- return null;
- } else {
- return self::$variables[$variableLastParam];
- }
- }
- return $this->lastParam;
}
- protected function doMath( $precedence = 17 ) { //17 =
count($operatorsPrecedence)-1
+ protected function doMath( $precedence = false ) {
+
if( isset($this->mathMemory[0]) ) {
while( $mathZerroMemory =
array_pop($this->mathMemory[0]) ) {
$this->doOperation($mathZerroMemory);
}
unset($this->mathMemory[0]);
+ }
+ if($precedence === false){
+ $precedence = $this->countPrecedences;
}
for($n = 1; $n <= $precedence; $n++) {
if( isset($this->mathMemory[$n]) ) {
@@ -240,163 +247,142 @@
}
protected function doOperation($operator, $param = null) {
- $variableParam = false;
- if( substr($param, 0, 2) == "\0$" ) {
- $variableParam = substr($param, 2);
- if( !isset(self::$variables[$variableParam]) ) {
- self::$variables[$variableParam] = null;
- // TODO show warning
- }
- $param = self::$variables[$variableParam];
+ if( $param instanceof Variable ) {
+ $param = &$param->getReference();
}
-
- $variableLastParam = false;
- if( substr($this->lastParam, 0, 2) == "\0$" ) {
- $variableLastParam = substr($this->lastParam, 2);
- if( !isset(self::$variables[$variableLastParam]) ) {
- self::$variables[$variableLastParam] = null;
- // TODO show warning
- }
- $this->lastParam = self::$variables[$variableLastParam];
+ if( $this->lastParam instanceof Variable ) {
+ $lastParam = &$this->lastParam->getReference();
+ }else{
+ $lastParam = &$this->lastParam;
}
switch ($operator) {
case '=':
- self::$variables[$variableParam] =
$this->lastParam;
+ $this->lastParam = $param = $lastParam;
break;
case T_CONCAT_EQUAL:// .=
- self::$variables[$variableParam] .=
$this->lastParam;
- $this->lastParam =
self::$variables[$variableParam];
+ $this->lastParam = $param .= $lastParam;
break;
case T_PLUS_EQUAL:// +=
- self::$variables[$variableParam] +=
$this->lastParam;
- $this->lastParam =
self::$variables[$variableParam];
+ $this->lastParam = $param += $lastParam;
break;
case T_MINUS_EQUAL:// -=
- self::$variables[$variableParam] -=
$this->lastParam;
- $this->lastParam =
self::$variables[$variableParam];
+ $this->lastParam = $param -= $lastParam;
break;
case T_MUL_EQUAL: // *=
- self::$variables[$variableParam] *=
$this->lastParam;
- $this->lastParam =
self::$variables[$variableParam];
+ $this->lastParam = $param *= $lastParam;
break;
case T_DIV_EQUAL: // /=
- self::$variables[$variableParam] /=
$this->lastParam;
- $this->lastParam =
self::$variables[$variableParam];
+ $this->lastParam = $param /= $lastParam;
break;
case T_MOD_EQUAL: // %=
- self::$variables[$variableParam] %=
$this->lastParam;
- $this->lastParam =
self::$variables[$variableParam];
+ $this->lastParam = $param %= $lastParam;
break;
case T_AND_EQUAL:// &=
- self::$variables[$variableParam] &=
$this->lastParam;
- $this->lastParam =
self::$variables[$variableParam];
+ $this->lastParam = $param &= $lastParam;
break;
case T_OR_EQUAL:// |=
- self::$variables[$variableParam] |=
$this->lastParam;
- $this->lastParam =
self::$variables[$variableParam];
+ $this->lastParam = $param |= $lastParam;
break;
case T_XOR_EQUAL:// ^=
- self::$variables[$variableParam] ^=
$this->lastParam;
- $this->lastParam =
self::$variables[$variableParam];
+ $this->lastParam = $param ^= $lastParam;
break;
case T_SL_EQUAL:// <<=
- self::$variables[$variableParam] <<=
$this->lastParam;
- $this->lastParam =
self::$variables[$variableParam];
+ $this->lastParam = $param <<= $lastParam;
break;
case T_SR_EQUAL:// >>=
- self::$variables[$variableParam] >>=
$this->lastParam;
- $this->lastParam =
self::$variables[$variableParam];
+ $this->lastParam = $param >>= $lastParam;
break;
- case T_INC: // ++$variable
- $this->lastParam =
++self::$variables[$variableLastParam];
- break;
- case T_DEC: // --$variable
- $this->lastParam =
--self::$variables[$variableLastParam];
- break;
- case ',':
- $this->listParams[] = $param;
- break;
- case '.':
- $this->lastParam = $param . $this->lastParam;
- break;
- case '+':
- $this->lastParam += $param;
- break;
- case '-':
- if( is_null($param) ) { // Negation
- $this->lastParam = -$this->lastParam;
- } else { // Subtraction
- $this->lastParam = $param -
$this->lastParam;
+ case T_INC: // ++
+ if( $this->lastOperator) {
+ $this->lastOperator = false;
+ $this->lastParam = $lastParam++;
+ } else {
+ $this->lastParam = ++$lastParam;
}
break;
+ case T_DEC: // --
+ if( $this->lastOperator) {
+ $this->lastOperator = false;
+ $this->lastParam = $lastParam--;
+ } else {
+ $this->lastParam = --$lastParam;
+ }
+ break;
+ case '.':
+ $this->lastParam = $param . $lastParam;
+ break;
+ case '+':
+ $this->lastParam = $param + $lastParam;
+ break;
+ case '-':
+ $this->lastParam = $param - $lastParam;
+ break;
case '*':
- $this->lastParam *= $param;
+ $this->lastParam = $param * $lastParam;
break;
case '/':
- $this->lastParam = $param / $this->lastParam;
+ $this->lastParam = $param / $lastParam;
break;
case '%':
- $this->lastParam = $param % $this->lastParam;
+ $this->lastParam = $param % $lastParam;
break;
case '&':
- $this->lastParam &= $param;
+ $this->lastParam = $param & $lastParam;
break;
case '|':
- $this->lastParam = $param | $this->lastParam;
+ $this->lastParam = $param | $lastParam;
break;
case '^':
- $this->lastParam = $param ^ $this->lastParam;
+ $this->lastParam = $param ^ $lastParam;
break;
case T_SL: // <<
- $this->lastParam = $param << $this->lastParam;
+ $this->lastParam = $param << $lastParam;
break;
case T_SR: // >>
- $this->lastParam = $param >> $this->lastParam;
+ $this->lastParam = $param >> $lastParam;
break;
case '~':
- $this->lastParam = ~$this->lastParam;
+ $this->lastParam = ~$lastParam;
break;
case T_INT_CAST:
- $this->lastParam = (integer) $this->lastParam;
+ $this->lastParam = (integer) $lastParam;
break;
case T_DOUBLE_CAST:
- $this->lastParam = (float) $this->lastParam;
+ $this->lastParam = (float) $lastParam;
break;
case T_STRING_CAST:
- $this->lastParam = (string) $this->lastParam;
+ $this->lastParam = (string) $lastParam;
break;
case T_ARRAY_CAST:
- $this->lastParam = (array) $this->lastParam;
+ $this->lastParam = (array) $lastParam;
break;
case T_BOOL_CAST:
- $this->lastParam = (bool) $this->lastParam;
+ $this->lastParam = (bool) $lastParam;
break;
case '<':
- $this->lastParam = $param < $this->lastParam;
+ $this->lastParam = $param < $lastParam;
break;
case '>':
- $this->lastParam = $param > $this->lastParam;
+ $this->lastParam = $param > $lastParam;
break;
case T_IS_SMALLER_OR_EQUAL: // <=
- $this->lastParam = $param <= $this->lastParam;
+ $this->lastParam = $param <= $lastParam;
break;
case T_IS_GREATER_OR_EQUAL: // >=
- $this->lastParam = $param >= $this->lastParam;
+ $this->lastParam = $param >= $lastParam;
break;
case T_IS_EQUAL: // ==
- $this->lastParam = $param == $this->lastParam;
+ $this->lastParam = $param == $lastParam;
break;
case T_IS_NOT_EQUAL: // !=
- $this->lastParam = $param != $this->lastParam;
+ $this->lastParam = $param != $lastParam;
break;
case T_IS_IDENTICAL: // ===
- $this->lastParam = $param === $this->lastParam;
+ $this->lastParam = $param === $lastParam;
break;
case T_IS_NOT_IDENTICAL: // !==
- $this->lastParam = $param !== $this->lastParam;
- break;
- case '?':
+ $this->lastParam = $param !== $lastParam;
break;
default:
\MWDebug::log( __METHOD__ . " unknown operator
'$operator'" );
@@ -406,14 +392,13 @@
// Remember the child class RuntimeDebug
public function getCommandResult( ) {
- $this->doMath();
- $this->doOperation(',', $this->lastParam);
+ $this->addOperator(',');
$return = null;
// Remember the child class RuntimeDebug
switch ($this->lastCommand) {
case T_ECHO:
- $return = array( $this->lastCommand,
implode('', $this->listParams) );
+ $return = array( $this->lastCommand,
$this->listParams );
break;
case false:
break; // exsample: $foo = 'foobar';
@@ -423,8 +408,19 @@
\MWDebug::log($return);
}
$this->popStack();
- $this->lastParam = null;
+ //$this->lastParam = null;
return $return;
}
-}
+ private function doCommand() {
+ switch ($this->lastCommand) {
+ case T_ARRAY:
+ \MWDebug::log( var_export($this->lastParam,
true));
+ $this->lastCommand = false;
+ break;
+ default:
+ break;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/includes/RuntimeDebug.php b/includes/RuntimeDebug.php
index 957c041..6e9ee33 100644
--- a/includes/RuntimeDebug.php
+++ b/includes/RuntimeDebug.php
@@ -11,6 +11,24 @@
class RuntimeDebug extends Runtime {
private $debug = array();
+ private $listParamsDebug = array();
+ private $savedListParams;
+ private $stackDebug = array();
+
+ protected function pushStack() {
+ parent::pushStack();
+ $this->stackDebug[] = $this->listParamsDebug;
+ }
+
+ protected function popStack() {
+ parent::popStack();
+ $this->savedListParams = $this->listParamsDebug;
+ if( count($this->stackDebug) == 0 ) {
+ $this->listParamsDebug = array();
+ } else {
+ $this->listParamsDebug = array_pop($this->stackDebug);
+ }
+ }
public function getDebug() {
$return = implode('<br>', $this->debug);
@@ -19,106 +37,46 @@
}
protected function doOperation($operator, $param = null) {
- if( $operator == ',' || $operator == '?' ) {
- return parent::doOperation($operator, $param);
- }
-
- if( substr($param, 0, 2) == "\0$" ) {
- $variableParam = substr($param, 2);
- $undefined = '';
- if( !isset(self::$variables[$variableParam]) ) {
- $undefined = \Html::element('span',
array('class'=>'foxway_undefined'), "Undefined ");
- $thisparam = null;
- }else{
- $thisparam = self::$variables[$variableParam];
- }
- $thisparam = $undefined . \Html::element('span',
array('class'=>'foxway_variable'), "\$$variableParam") .
- '(' . self::getHTMLForValue($thisparam)
. ')';
- } else {
- $thisparam = self::getHTMLForValue($param);
- }
-
- if( substr($this->lastParam, 0, 2) == "\0$" ) {
- $variableLastParam = substr($this->lastParam, 2);
- $undefined = '';
- if( !isset(self::$variables[$variableLastParam]) ) {
- $undefined = \Html::element('span',
array('class'=>'foxway_undefined'), "Undefined ");
- $lastParam = null;
- } else {
- $lastParam =
self::$variables[$variableLastParam];
- }
- $lastParam = $undefined . \Html::element('span',
array('class'=>'foxway_variable'), "\$$variableLastParam") .
- '(' . self::getHTMLForValue($lastParam)
. ')';
- } else {
- $lastParam = self::getHTMLForValue($this->lastParam);
- }
-
if( $operator == '=' ){
- $return = \Html::element('span',
array('class'=>'foxway_variable'), "\$$variableParam") .
' <b>=></b> = ';
+ $return = \Html::element('span',
array('class'=>'foxway_variable'), $param->name) .
+ ' <b>=></b> = ';
} else {
- if( $variableParam || $variableLastParam ) {
- $return = ($variableParam ?
\Html::element('span', array('class'=>'foxway_variable'), "\$$variableParam") :
self::getHTMLForValue($thisparam)) .
-
self::getHTMLForOperator($operator) .
- ($variableLastParam ?
\Html::element('span', array('class'=>'foxway_variable'),
"\$$variableLastParam") : self::getHTMLForValue($lastParam)) .
- " <b>=></b> ";
- }
- $return = $thisparam .
self::getHTMLForOperator($operator) . $lastParam . ' <b>=></b> ';
+ $return = self::getHTMLForValue($param) .
+ self::getHTMLForOperator($operator) .
+ self::getHTMLForValue($this->lastParam)
.
+ ' <b>=></b> ';
}
parent::doOperation($operator, $param);
- $this->debug[] = $return .
self::getHTMLForValue($this->lastParam);
+ $this->debug[] = $return . self::getHTMLForValue(
$this->lastParam /*instanceof Variable ? $this->lastParam->value :
$this->lastParam*/ );
}
public function addOperator($operator) {
+ if( $operator == ',' ) {
+ $this->doMath();
+ $this->listParamsDebug[] =
self::getHTMLForValue($this->lastParam);
+ }
+/*
if( ($operator == T_INC || $operator == T_DEC) &&
(!$this->lastOperator && !is_null($this->lastParam)) ) {
- $variableLastParam = substr($this->lastParam, 2);
- $variable = '';
- $value = null;
- if( !isset(self::$variables[$variableLastParam]) ) {
- $variable = \Html::element('span',
array('class'=>'foxway_undefined'), 'Undefined ');
- }else{
- $value = self::$variables[$variableLastParam];
- }
- $this->debug[] = $variable . \Html::element('span',
array('class'=>'foxway_variable'), "\$$variableLastParam") .
- '(' . self::getHTMLForValue($value) .
')' .
+ $lastParam = $this->lastParam;
+ $value = $lastParam->value;
+ $this->debug[] = self::getHTMLForValue($value) .
($operator == T_INC ? '++' : '--') .
' <b>=></b> ' .
'(' . self::getHTMLForValue($operator
== T_INC ? $value+1 : $value-1) . ') ' . self::getHTMLForValue($value);
- }
+ }*/
$return = parent::addOperator($operator);
+ $value = $this->lastParam;
if( $operator == '?' ) {
-
- if( substr($this->lastParam, 0, 2) == "\0$" ) {
- $variableLastParam = substr($this->lastParam,
2);
- $variable = '';
- if(
!isset(self::$variables[$variableLastParam]) ) {
- $variable = \Html::element('span',
array('class'=>'foxway_undefined'), 'Undefined ');
- }
- $variable .= \Html::element('span',
array('class'=>'foxway_variable'), "\$$variableLastParam");
- $variable .= '(' .
self::getHTMLForValue($return) . ')';
- }else{
- $variable = self::getHTMLForValue($return);
- }
- $this->debug[] = $variable .
" ? <b>=></b> " . self::getHTMLForValue($return?true:false);
+ $this->debug[] = self::getHTMLForValue($value) .
" ? <b>=></b> " . self::getHTMLForValue($return?true:false);
}elseif( $operator == ')' && is_array($return) ) {
list($command, $result) = $return;
switch ($command) {
case T_IF:
- if( substr($this->lastParam, 0, 2) ==
"\0$" ) {
- $variableLastParam =
substr($this->lastParam, 2);
- $variable = '';
- if(
!isset(self::$variables[$variableLastParam]) ) {
- $variable =
\Html::element('span', array('class'=>'foxway_undefined'), 'Undefined ');
- }
- $variable .=
\Html::element('span', array('class'=>'foxway_variable'),
"\$$variableLastParam");
- $variable .= '(' .
self::getHTMLForValue($result) . ')';
- }else{
- $variable =
self::getHTMLForValue($result);
- }
- $t = self::getHTMLForCommand($command)
. "( " . $variable . " ) <b>=></b> ";
+ $t = self::getHTMLForCommand($command)
. "( " . self::getHTMLForValue($value) . " ) <b>=></b> ";
if( $result ) {
$t .=
self::getHTMLForValue(true);
} else {
@@ -127,69 +85,63 @@
$this->debug[] = $t;
break;
default:
- $this->debug[] =
self::getHTMLForCommand($command) . "( " . self::getHTMLForValue($result) . "
)";
+ $this->debug[] =
self::getHTMLForCommand($command) . "( " . self::getHTMLForValue($value) . " )";
break;
}
}
return $return;
}
- // This is a modified copy of the parent
public function getCommandResult( ) {
- $this->doMath();
- $this->doOperation(',', $this->lastParam);
- $return = null;
+ $lastCommand = $this->lastCommand;
+ $return = parent::getCommandResult();
- // Remember the child class RuntimeDebug
- switch ($this->lastCommand) {
+ switch ($lastCommand) {
case T_ECHO:
- $return = array( $this->lastCommand,
implode('', $this->listParams) );
- $this->debug[] =
self::getHTMLForCommand($this->lastCommand) . ' ' .
$this->getHTMLForListParams() . ';';
- $this->debug[] = $return[1];
+ $this->debug[] =
self::getHTMLForCommand($lastCommand) . ' ' . implode(', ',
$this->savedListParams) . ';';
+ $this->debug[] = implode('', $return[1]);
break;
- case false:
- break; // exsample: $foo = 'foobar';
- default:
- // TODO
- $return = 'Error! Unknown command "' .
htmlspecialchars($this->lastCommand) . '" in ' . __METHOD__;
- $this->debug[] = $return;
- \MWDebug::log($return);
+ default :
+ $this->debug[] = is_array($return) ? $return[1]
: $return ;
}
- $this->popStack();
- $this->lastParam = null;
+
+
return $return;
}
- private function getHTMLForListParams() {
- $return = array();
- foreach ($this->listParams as $value) {
- $return[] = self::getHTMLForValue($value);
- }
- return implode(', ', $return);
- }
-
private static function getHTMLForValue($param) {
+ $value = $param instanceof Variable ? $param->value : $param;
$class = false;
- if( $param === true ) {
+ if( $value === true ) {
$class = 'foxway_construct';
- $param = 'true';
- }elseif( $param === false ) {
+ $value = 'true';
+ }elseif( $value === false ) {
$class = 'foxway_construct';
- $param = 'false';
- }elseif( $param === null ) {
+ $value = 'false';
+ }elseif( $value === null ) {
$class = 'foxway_construct';
- $param = 'null';
- }elseif( is_string($param) ) {
+ $value = 'null';
+ }elseif( is_string($value) ) {
$class = 'foxway_string';
- $param = "'$param'";
- }elseif( is_numeric($param) ) {
+ $value = "'$value'";
+ }elseif( is_numeric($value) ) {
$class = 'foxway_number';
+ } elseif( is_array($value) ) {
+ if( count($value) <= 3 ) {
+ return var_export($value, true);
+ }
+ }
+ if( $class ) {
+ $value = \Html::element('span', array('class'=>$class),
$value);
+ } else {
+ $value = strtr( $value, array('&'=>'&',
'<'=>'<') );
}
- if( $class ) {
- return \Html::element('span', array('class'=>$class),
$param);
+ if( $param instanceof Variable ) {
+ return ($param->isDefined ? '' : \Html::element(
'span', array('class'=>'foxway_undefined'), "Undefined " )) .
+ \Html::element( 'span',
array('class'=>'foxway_variable'), $param->name ) . "($value)";
}
- return strtr( $param, array('&'=>'&', '<'=>'<') );
+ return $value;
}
private static function getHTMLForCommand($command) {
diff --git a/includes/Variable.php b/includes/Variable.php
new file mode 100644
index 0000000..3c2170e
--- /dev/null
+++ b/includes/Variable.php
@@ -0,0 +1,46 @@
+<?php
+namespace Foxway;
+/**
+ * Variable class for Runtime of Foxway extension.
+ *
+ * @file Variable.php
+ * @ingroup Foxway
+ * @author Pavel Astakhov <[email protected]>
+ * @licence GNU General Public Licence 2.0 or later
+ * @property-read string $name Name of variable
+ * @property-read mixed $value Value of variable
+ * @property-read boolean $isDefined Returns true if variable is defined
+ */
+class Variable {
+ private $name;
+ private $variablesArray;
+
+ public function __construct( $name, &$variablesArray ) {
+ $this->name = $name;
+ $this->variablesArray = &$variablesArray;
+ }
+
+ public function &getReference() {
+ $name = $this->name;
+ if( !isset($this->variablesArray[$name]) ) {
+ $this->variablesArray[$name] = null;
+ }
+ return $this->variablesArray[$name];
+ }
+
+ public function __get($name) {
+ switch ($name) {
+ case 'name':
+ return $this->name;
+ break;
+ case 'value':
+ if( isset($this->variablesArray[$this->name]) )
{
+ return
$this->variablesArray[$this->name];
+ }
+ break;
+ case 'isDefined':
+ return
isset($this->variablesArray[$this->name]);
+ break;
+ }
+ }
+}
diff --git a/tests/phpunit/includes/InterpreterTest.php
b/tests/phpunit/includes/InterpreterTest.php
index 0e135df..caf4268 100644
--- a/tests/phpunit/includes/InterpreterTest.php
+++ b/tests/phpunit/includes/InterpreterTest.php
@@ -37,13 +37,13 @@
public function testRun_echo_parameters_1() {
$this->assertEquals(
Interpreter::run('echo
"Parameter1","Parameter2" , "Parameter3";'),
- array('Parameter1Parameter2Parameter3')
+ array('Parameter1', 'Parameter2', 'Parameter3')
);
}
public function testRun_echo_parameters_2() {
$this->assertEquals(
Interpreter::run('echo \'This \', \'string \',
\'was \', \'made \', \'with multiple parameters.\';'),
- array('This string was made with multiple
parameters.')
+ array('This ', 'string ', 'was ', 'made ',
'with multiple parameters.')
);
}
@@ -98,7 +98,7 @@
public function testRun_echo_variables_6() {
$this->assertEquals(
Interpreter::run('echo $foo,$bar;'),
- array('foobarbarbaz')
+ array('foobar', 'barbaz')
);
}
public function testRun_echo_variables_7() {
@@ -128,7 +128,7 @@
public function testRun_echo_variables_11() {
$this->assertEquals(
Interpreter::run('echo "This ", \'string \',
"was $foo ", \'with multiple parameters.\';'),
- array('This string was foobar with multiple
parameters.')
+ array('This ', 'string ', 'was foobar ', 'with
multiple parameters.')
);
}
@@ -155,7 +155,7 @@
public function testRun_echo_math_1() {
$this->assertEquals(
Interpreter::run('echo \'5 + 5 * 10 = \', 5 + 5
* 10;'),
- array('5 + 5 * 10 = 55')
+ array('5 + 5 * 10 = ', '55')
);
}
public function testRun_echo_math_2() {
@@ -192,7 +192,7 @@
public function testRun_echo_math_params() {
$this->assertEquals(
Interpreter::run('echo \'10 + 5 * 5 = \', 10 +
5 * 5, "\n\n";'),
- array("10 + 5 * 5 = 35\n\n")
+ array('10 + 5 * 5 = ', '35', "\n\n")
);
}
@@ -202,15 +202,15 @@
$foo = 100;
$bar = \'5\';
echo "\$foo * \$bar = $foo * $bar = ", $foo * $bar, "\n\n";'),
- array("\$foo * \$bar = 100 * 5 = 500\n\n")
+ array('$foo * $bar = 100 * 5 = ', '500', "\n\n")
);
$this->assertEquals(
Interpreter::run('echo "\$foo / \$bar = $foo /
$bar = ", $foo / $bar, "\n\n";'),
- array("\$foo / \$bar = 100 / 5 = 20\n\n")
+ array('$foo / $bar = 100 / 5 = ', '20', "\n\n")
);
$this->assertEquals(
Interpreter::run('echo "-\$foo / -\$bar =
{-$foo} / {-$bar} = ", -$foo / -$bar, "\n\n";'),
- array("-\$foo / -\$bar = {-100} / {-5} =
20\n\n")
+ array('-$foo / -$bar = {-100} / {-5} = ', '20',
"\n\n")
);
}
@@ -345,7 +345,7 @@
public function testRun_echo_math_Increment_1() {
$this->assertEquals(
Interpreter::run('$a = 10; echo $a++, $a,
++$a;'),
- array('101112')
+ array('10', '11', '12')
);
}
public function testRun_echo_math_Increment_2() {
@@ -361,13 +361,13 @@
$a++;
++$a;
echo "$a, ", $a++ + -5, ", " . ++$a, ", $a.";'),
- array('12, 7, 14, 14.')
+ array('12, ', '7', ', 14', ', 14.')
);
}
public function testRun_echo_math_Decrement_1() {
$this->assertEquals(
Interpreter::run('$a = 10; echo $a--, $a,
--$a;'),
- array('1098')
+ array('10', '9', '8')
);
}
public function testRun_echo_math_Decrement_2() {
@@ -377,7 +377,7 @@
$a--;
--$a;
echo "$a, ", $a-- + -5, ", " . --$a, ", $a.";'),
- array('8, 3, 6, 6.')
+ array('8, ', '3', ', 6', ', 6.')
);
}
@@ -424,13 +424,13 @@
public function testRun_echo_parentheses_7() {
$this->assertEquals(
Interpreter::run('echo("hello "), $foo;'),
- array('hello foo')
+ array('hello ', 'foo')
);
}
public function testRun_echo_parentheses_8() {
$this->assertEquals(
Interpreter::run('echo ($foo), (" is "),
$foo;'),
- array('foo is foo')
+ array('foo', ' is ', 'foo')
);
}
@@ -827,4 +827,41 @@
);
}
+ public function testRun_echo_assignment_1() {
+ $this->assertEquals(
+ Interpreter::run('echo $foo = 1;'),
+ array('1')
+ );
+ }
+ public function testRun_echo_assignment_2() {
+ $this->assertEquals(
+ Interpreter::run('echo $foo = 1 + 2;'),
+ array('3')
+ );
+ }
+ public function testRun_echo_assignment_3() {
+ $this->assertEquals(
+ Interpreter::run('$foo=1; echo $foo += 2;'),
+ array('3')
+ );
+ }
+ public function testRun_echo_assignment_4() {
+ $this->assertEquals(
+ Interpreter::run('$foo=1; echo $foo += 2 + 3;'),
+ array('6')
+ );
+ }/*
+ public function testRun_echo_assignment_5() {
+ $this->assertEquals(
+ Interpreter::run('echo $bar = $foo = 1, $foo,
$bar;'),
+ array('1', '1', '1')
+ );
+ }*/
+ public function testRun_echo_assignment_6() {
+ $this->assertEquals(
+ Interpreter::run('$foo=1; $bar=2; $foo+=$bar;
echo $foo,$bar;'),
+ array('3', '2')
+ );
+ }
+
}
--
To view, visit https://gerrit.wikimedia.org/r/62217
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7a479b05548e9a9f096f3d1375fb6feaafab8c2d
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