Pastakhov has uploaded a new change for review.
https://gerrit.wikimedia.org/r/191858
Change subject: new Runtime (v 5.0.0)
......................................................................
new Runtime (v 5.0.0)
Change-Id: Idbfcca925f6668a6d1ec9810e6f8c1df75c31c58
---
M PhpTags.php
M includes/Compiler.php
M includes/PhpTagsException.php
M includes/Runtime.php
4 files changed, 1,334 insertions(+), 714 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/PhpTags
refs/changes/58/191858/1
diff --git a/PhpTags.php b/PhpTags.php
index 916b474..700ccfe 100644
--- a/PhpTags.php
+++ b/PhpTags.php
@@ -15,13 +15,13 @@
die( 'This file is an extension to MediaWiki and thus not a valid entry
point.' );
}
-const PHPTAGS_MAJOR_VERSION = 4;
-const PHPTAGS_MINOR_VERSION = 2;
+const PHPTAGS_MAJOR_VERSION = 5;
+const PHPTAGS_MINOR_VERSION = 0;
const PHPTAGS_RELEASE_VERSION = 0;
define( 'PHPTAGS_VERSION', PHPTAGS_MAJOR_VERSION . '.' . PHPTAGS_MINOR_VERSION
. '.' . PHPTAGS_RELEASE_VERSION );
const PHPTAGS_HOOK_RELEASE = 6;
-const PHPTAGS_RUNTIME_RELEASE = 3;
+const PHPTAGS_RUNTIME_RELEASE = 4;
const PHPTAGS_JSONLOADER_RELEASE = 1;
// Register this extension on Special:Version
diff --git a/includes/Compiler.php b/includes/Compiler.php
index 4d74bf7..47d7fd4 100644
--- a/includes/Compiler.php
+++ b/includes/Compiler.php
@@ -17,6 +17,9 @@
*/
class Compiler {
+ //
+= -= *=
/= .= %=
&= |= ^=
<<= >>=
+ protected static $assignmentOperators = array( '=', T_PLUS_EQUAL,
T_MINUS_EQUAL, T_MUL_EQUAL, T_DIV_EQUAL, T_CONCAT_EQUAL, T_MOD_EQUAL,
T_AND_EQUAL, T_OR_EQUAL, T_XOR_EQUAL, T_SL_EQUAL, T_SR_EQUAL );
+
/**
* Operator Precedence
* @see http://www.php.net/manual/en/language.operators.precedence.php
@@ -41,8 +44,7 @@
array( T_BOOLEAN_AND ), // &&
array( T_BOOLEAN_OR ), // ||
array( '?', ':' ),
- // += -=
*= /= .=
%= &=
|= ^= <<= >>=
- array( '=', T_PLUS_EQUAL, T_MINUS_EQUAL, T_MUL_EQUAL,
T_DIV_EQUAL, T_CONCAT_EQUAL, T_MOD_EQUAL, T_AND_EQUAL, T_OR_EQUAL, T_XOR_EQUAL,
T_SL_EQUAL, T_SR_EQUAL ),
+ null, // self::$assignmentOperators
array( T_LOGICAL_AND ), // and
array( T_LOGICAL_XOR ), // xor
array( T_LOGICAL_OR ), // or
@@ -55,20 +57,23 @@
* @var array
*/
protected static $runtimeOperators = array(
- '~' => '~',
- '!' => '!',
- '*' => '*',
- '/' => '/',
- '%' => '%',
- '+' => '+',
- '-' => '-',
- '.' => '.',
- '<' => '<',
- '>' => '>',
- '&' => '&',
- '^' => '^',
- '|' => '|',
- '=' => '=',
+ '~' => PHPTAGS_T_NOT,
+ '!' => PHPTAGS_T_IS_NOT,
+ '*' => PHPTAGS_T_MUL,
+ '/' => PHPTAGS_T_DIV,
+ '%' => PHPTAGS_T_MOD,
+ '+' => PHPTAGS_T_PLUS,
+ '-' => PHPTAGS_T_MINUS,
+ '.' => PHPTAGS_T_CONCAT,
+ '<' => PHPTAGS_T_IS_SMALLER,
+ '>' => PHPTAGS_T_IS_GREATER,
+ '&' => PHPTAGS_T_AND,
+ '^' => PHPTAGS_T_XOR,
+ '|' => PHPTAGS_T_OR,
+ '=' => PHPTAGS_T_EQUAL,
+ '"' => PHPTAGS_T_QUOTE,
+ '@' => PHPTAGS_T_IGNORE_ERROR,
+ '?' => PHPTAGS_T_TERNARY,
T_LOGICAL_OR => PHPTAGS_T_LOGICAL_OR,
T_BOOLEAN_OR => PHPTAGS_T_LOGICAL_OR,
T_LOGICAL_XOR => PHPTAGS_T_LOGICAL_XOR,
@@ -107,6 +112,8 @@
T_ISSET => PHPTAGS_T_ISSET,
T_EMPTY => PHPTAGS_T_EMPTY,
T_NEW => PHPTAGS_T_NEW,
+ T_GLOBAL => PHPTAGS_T_GLOBAL,
+ T_STATIC => PHPTAGS_T_STATIC,
);
/**
@@ -129,6 +136,7 @@
function __construct() {
if ( !self::$precedencesMatrix ) {
+ self::$operatorsPrecedence[13] =
self::$assignmentOperators;
foreach ( self::$operatorsPrecedence as $key => &$value
) {
self::$precedencesMatrix += array_fill_keys(
$value, $key );
}
@@ -214,6 +222,8 @@
return $this->stepForeachConstruct(
$throwEndTag ); // return true
case T_FOR:
return $this->stepForConstruct( $throwEndTag );
// return true
+// case T_SWITCH:
+// return $this->stepSwitchConstruct( $throwEndTag
); // return true
case T_CONTINUE:
case T_BREAK:
$this->stepUP( true );
@@ -245,7 +255,7 @@
// PHP Parse error: syntax
error, unexpected $id,
throw new PhpTagsException(
PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id ),
$this->tokenLine, $this->place );
}
- if ( $value[PHPTAGS_STACK_COMMAND] !=
PHPTAGS_T_VARIABLE ) { // Example global $foo=5;
+ if ( $value[PHPTAGS_STACK_COMMAND] !==
PHPTAGS_T_VARIABLE ) { // Example global $foo=5;
throw new PhpTagsException(
PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array(
$value[PHPTAGS_STACK_COMMAND], 'T_VARIABLE' ), $this->tokenLine, $this->place );
}
if (
isset($value[PHPTAGS_STACK_ARRAY_INDEX]) ) {
@@ -288,7 +298,7 @@
PHPTAGS_STACK_TOKEN_LINE => $this->tokenLine,
PHPTAGS_STACK_DEBUG =>
$text );
$this->stack_push_memory();
- } elseif (
$value[PHPTAGS_STACK_COMMAND] === '=' ) {
+ } elseif (
$value[PHPTAGS_STACK_COMMAND] === PHPTAGS_T_EQUAL ) {
if (
isset($value[PHPTAGS_STACK_PARAM][PHPTAGS_STACK_ARRAY_INDEX]) ) {
throw new
PhpTagsException( PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( '[',
"','", "';'" ), $this->tokenLine, $this->place );
}
@@ -537,7 +547,7 @@
$i++;
}
}
- $result = array( PHPTAGS_STACK_COMMAND=>'"',
PHPTAGS_STACK_PARAM=>&$strings, PHPTAGS_STACK_RESULT=>null,
PHPTAGS_STACK_TOKEN_LINE=>$this->tokenLine, PHPTAGS_STACK_DEBUG=>$text );
+ $result = array(
PHPTAGS_STACK_COMMAND=>PHPTAGS_T_QUOTE, PHPTAGS_STACK_PARAM=>&$strings,
PHPTAGS_STACK_RESULT=>null, PHPTAGS_STACK_TOKEN_LINE=>$this->tokenLine,
PHPTAGS_STACK_DEBUG=>$text );
break;
case T_VARIABLE:
$cannotRead = false;
@@ -572,7 +582,7 @@
$id = $this->id;
$text = $this->text;
- if ( in_array($id,
self::$operatorsPrecedence[13]) ) { // It is assignment operator
+ if ( in_array($id, self::$assignmentOperators)
) { // It is assignment operator
$this->stepUP();
$val =& $this->getNextValue( '=' );
if ( $val == false ) { // Example:
$foo=;
@@ -751,7 +761,7 @@
throw new PhpTagsException(
PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id, "'('" ),
$this->tokenLine, $this->place );
}
$param = array();
- $i = 0;
+ $i = -1;
do {
$this->stepUP();
if ( $this->id === T_LIST ) { // T_LIST
inside T_LIST. Example: list( $foo, list
@@ -760,13 +770,13 @@
$value =& $this->getNextValue();
if ( $value === false ) { //
Example: list($foo, ,
$value = null;
- } elseif (
$value[PHPTAGS_STACK_COMMAND] != PHPTAGS_T_VARIABLE &&
$value[PHPTAGS_STACK_COMMAND] != PHPTAGS_T_LIST ) { // Example: unset( $foo+1 );
+ } elseif (
$value[PHPTAGS_STACK_COMMAND] !== PHPTAGS_T_VARIABLE &&
$value[PHPTAGS_STACK_COMMAND] !== PHPTAGS_T_LIST ) { // Example: unset( $foo+1
);
throw new
PhpTagsException( PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array(
$value[PHPTAGS_STACK_COMMAND], 'T_VARIABLE' ), $this->tokenLine, $this->place );
}
}
$tmp = array(
PHPTAGS_STACK_COMMAND=>null, PHPTAGS_STACK_RESULT=>&$value );
- $param[$i] = null;
- $this->addValueIntoStack( $tmp, $param,
$i++ );
+ $param[++$i] = null;
+ $this->addValueIntoStack( $tmp, $param,
$i );
unset( $value, $tmp );
} while ( $this->id === ',' );
if ( $this->id != ')' ) {
@@ -776,6 +786,8 @@
$result = array(
PHPTAGS_STACK_COMMAND => PHPTAGS_T_LIST,
PHPTAGS_STACK_PARAM => &$param,
+ PHPTAGS_STACK_PARAM_2 => null,
+ PHPTAGS_STACK_RESULT => null,
PHPTAGS_STACK_TOKEN_LINE =>
$this->tokenLine,
PHPTAGS_STACK_DEBUG => $text,
);
@@ -791,16 +803,8 @@
// PHP Parse error: syntax
error, unexpected $id
throw new PhpTagsException(
PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id ),
$this->tokenLine, $this->place );
}
- $return = array(
- PHPTAGS_STACK_COMMAND => '=',
- PHPTAGS_STACK_PARAM => $result,
- PHPTAGS_STACK_PARAM_2 => null,
- PHPTAGS_STACK_RESULT => null,
- PHPTAGS_STACK_TOKEN_LINE =>
$this->tokenLine,
- PHPTAGS_STACK_DEBUG => '=',
- );
- $this->addValueIntoStack( $val,
$return, PHPTAGS_STACK_PARAM_2 );
- return $return; // *********** EXIT
***********
+ $this->addValueIntoStack( $val,
$result, PHPTAGS_STACK_PARAM_2 );
+ return $result; // *********** EXIT
***********
}
break;
case T_PRINT:
@@ -839,7 +843,7 @@
// PHP Parse error: syntax
error, unexpected $id,
throw new PhpTagsException(
PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id ),
$this->tokenLine, $this->place );
}
- if ( $value[PHPTAGS_STACK_COMMAND] !=
PHPTAGS_T_VARIABLE ) { // Example: unset( $foo+1 );
+ if ( $value[PHPTAGS_STACK_COMMAND] !==
PHPTAGS_T_VARIABLE ) { // Example: unset( $foo+1 );
throw new PhpTagsException(
PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array(
$value[PHPTAGS_STACK_COMMAND], 'T_VARIABLE' ), $this->tokenLine, $this->place );
}
$param[] =& $value;
@@ -894,7 +898,7 @@
case '@': // Error Control Operator
$this->stepUP();
if ( $this->ignoreErrors === false ) {
- $this->stack[] = array(
PHPTAGS_STACK_COMMAND => '@', PHPTAGS_STACK_PARAM => true );
+ $this->stack[] = array(
PHPTAGS_STACK_COMMAND => PHPTAGS_T_IGNORE_ERROR, PHPTAGS_STACK_PARAM => true );
$this->ignoreErrors = true;
}
$result =& $this->stepValue( $owner );
@@ -965,7 +969,7 @@
case '?':
// Make the operator without the second value
$ternary = array(
- PHPTAGS_STACK_COMMAND => '?',
+ PHPTAGS_STACK_COMMAND =>
PHPTAGS_T_TERNARY,
PHPTAGS_STACK_PARAM => null,
PHPTAGS_STACK_PARAM_2 => null,
PHPTAGS_STACK_RESULT => null,
@@ -1096,7 +1100,7 @@
PHPTAGS_STACK_DO_FALSE => false,
);
$result = array(
- PHPTAGS_STACK_COMMAND => '?',
+ PHPTAGS_STACK_COMMAND =>
PHPTAGS_T_TERNARY,
PHPTAGS_STACK_PARAM => null,
PHPTAGS_STACK_PARAM_2 => $param2,
PHPTAGS_STACK_RESULT => null,
@@ -1152,7 +1156,7 @@
PHPTAGS_STACK_DO_FALSE => $stack_false,
);
$result = array(
- PHPTAGS_STACK_COMMAND => '?',
+ PHPTAGS_STACK_COMMAND =>
PHPTAGS_T_TERNARY,
PHPTAGS_STACK_PARAM => null,
PHPTAGS_STACK_PARAM_2 => $param2,
PHPTAGS_STACK_RESULT => null,
@@ -1466,8 +1470,12 @@
if ( $this->id === $end ) {
break;
}
- throw new PhpTagsException(
PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id, "',' or ';'"
), $this->tokenLine, $this->place );
+ throw new PhpTagsException(
PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id, ',', ';' ),
$this->tokenLine, $this->place );
}
+ }
+
+ private function stepSwitchConstruct( $throwEndTag ) {
+
}
private function stepForeachConstruct( $throwEndTag = true ) {
@@ -1486,7 +1494,7 @@
// PHP Parse error: syntax error, unexpected $id
throw new PhpTagsException(
PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id ),
$this->tokenLine, $this->place );
}
- if ( $arrayExpression[PHPTAGS_STACK_COMMAND] !=
PHPTAGS_T_VARIABLE && $arrayExpression[PHPTAGS_STACK_COMMAND] !=
PHPTAGS_T_ARRAY ) {
+ if ( $arrayExpression[PHPTAGS_STACK_COMMAND] !==
PHPTAGS_T_VARIABLE && $arrayExpression[PHPTAGS_STACK_COMMAND] !==
PHPTAGS_T_ARRAY ) {
// PHP Parse error: syntax error, unexpected $id,
expecting T_VARIABLE
throw new PhpTagsException(
PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array(
$arrayExpression[PHPTAGS_STACK_COMMAND], 'T_VARIABLE', 'T_ARRAY' ),
$this->tokenLine, $this->place );
}
@@ -1634,7 +1642,7 @@
$runtimeReturn = Runtime::run( array($command,
$tmp), array('PhpTags\\Compiler') );
if ( $runtimeReturn instanceof PhpTagsException
) {
if ( $this->ignoreErrors === null ) {
- $this->stack[] = array(
PHPTAGS_STACK_COMMAND => '@', PHPTAGS_STACK_PARAM => false );
+ $this->stack[] = array(
PHPTAGS_STACK_COMMAND => PHPTAGS_T_IGNORE_ERROR, PHPTAGS_STACK_PARAM => false );
$this->ignoreErrors = false;
}
return false;
@@ -1650,7 +1658,7 @@
}
if ( $this->ignoreErrors === null ) {
- $this->stack[] = array( PHPTAGS_STACK_COMMAND => '@',
PHPTAGS_STACK_PARAM => false );
+ $this->stack[] = array( PHPTAGS_STACK_COMMAND =>
PHPTAGS_T_IGNORE_ERROR, PHPTAGS_STACK_PARAM => false );
$this->ignoreErrors = false;
}
return false;
diff --git a/includes/PhpTagsException.php b/includes/PhpTagsException.php
index f8b9cd4..5a8e803 100644
--- a/includes/PhpTagsException.php
+++ b/includes/PhpTagsException.php
@@ -162,6 +162,9 @@
case self::FATAL_CALLED_MANY_EXPENSIVE_FUNCTION:
$message = "Too many expensive function calls,
last is $arguments";
break;
+ case self::FATAL_WRONG_BREAK_LEVELS:
+ $message = "Cannot break/continue $arguments
levels";
+ break;
case self::NOTICE_GET_PROPERTY_OF_NON_OBJECT:
$message = 'Trying to get property of
non-object';
break;
@@ -266,6 +269,7 @@
const FATAL_CALL_FUNCTION_ON_NON_OBJECT = 4019; // PHP Fatal error:
Call to a member function doo() on a non-object
const FATAL_ACCESS_TO_UNDECLARED_STATIC_PROPERTY = 4020; // PHP Fatal
error: Access to undeclared static property: F::$rsrr
const FATAL_UNEXPECTED_OBJECT_TYPE = 4021; // Fatal error: Unexpected
object type stdClass. in
+ const FATAL_WRONG_BREAK_LEVELS = 4022; // PHP Fatal error: Cannot
break/continue 4 levels
const FATAL_DENIED_FOR_NAMESPACE = 4500;
const FATAL_CALLFUNCTION_INVALID_HOOK = 4501;
diff --git a/includes/Runtime.php b/includes/Runtime.php
index 2b997af..a1c500c 100644
--- a/includes/Runtime.php
+++ b/includes/Runtime.php
@@ -1,19 +1,33 @@
<?php
namespace PhpTags;
-define( 'PHPTAGS_STACK_RESULT', 'r' );
-define( 'PHPTAGS_STACK_COMMAND', 'c' );
-define( 'PHPTAGS_STACK_PARAM', 'p' );
-define( 'PHPTAGS_STACK_PARAM_2', 's' );
-define( 'PHPTAGS_STACK_PARAM_3', 'o' );
-define( 'PHPTAGS_STACK_INC_AFTER', 'i' );
-define( 'PHPTAGS_STACK_TOKEN_LINE', 'l' );
-define( 'PHPTAGS_STACK_DO_TRUE', 't' );
-define( 'PHPTAGS_STACK_DO_FALSE', 'f' );
-define( 'PHPTAGS_STACK_ARRAY_INDEX', 'a' );
-define( 'PHPTAGS_STACK_DEBUG', '#' );
-define( 'PHPTAGS_STACK_AIM', '*' );
-define( 'PHPTAGS_STACK_HOOK_TYPE', 'h' );
+//const PHPTAGS_STACK_RESULT = 'r';
+//const PHPTAGS_STACK_COMMAND = 'c';
+//const PHPTAGS_STACK_PARAM = 'p';
+//const PHPTAGS_STACK_PARAM_2 = 's';
+//const PHPTAGS_STACK_PARAM_3 = 'o';
+//const PHPTAGS_STACK_INC_AFTER = 'i';
+//const PHPTAGS_STACK_TOKEN_LINE = 'l';
+//const PHPTAGS_STACK_DO_TRUE = 't';
+//const PHPTAGS_STACK_DO_FALSE = 'f';
+//const PHPTAGS_STACK_ARRAY_INDEX = 'a';
+//const PHPTAGS_STACK_DEBUG = '#';
+//const PHPTAGS_STACK_AIM = '*';
+//const PHPTAGS_STACK_HOOK_TYPE = 'h';
+
+const PHPTAGS_STACK_COMMAND = 0;
+const PHPTAGS_STACK_RESULT = 1;
+const PHPTAGS_STACK_PARAM = 2;
+const PHPTAGS_STACK_PARAM_2 = 3;
+const PHPTAGS_STACK_PARAM_3 = 4;
+const PHPTAGS_STACK_INC_AFTER = 5;
+const PHPTAGS_STACK_TOKEN_LINE = 6;
+const PHPTAGS_STACK_DO_TRUE = 7;
+const PHPTAGS_STACK_DO_FALSE = 8;
+const PHPTAGS_STACK_ARRAY_INDEX = 9;
+const PHPTAGS_STACK_DEBUG = 10;
+const PHPTAGS_STACK_AIM = 11;
+const PHPTAGS_STACK_HOOK_TYPE = 12;
define( 'PHPTAGS_HOOK_GET_CONSTANT', '_' );
define( 'PHPTAGS_HOOK_FUNCTION', 'f' );
@@ -28,56 +42,223 @@
define( 'PHPTAGS_OBJECT_DEFINITION', 0 );
define( 'PHPTAGS_METHOD_CONSTRUCTOR', 1 );
-define( 'PHPTAGS_T_LOGICAL_OR', 263 );
-define( 'PHPTAGS_T_LOGICAL_XOR', 264 );
-define( 'PHPTAGS_T_LOGICAL_AND', 265 );
-define( 'PHPTAGS_T_PRINT', 266 );
-define( 'PHPTAGS_T_SR_EQUAL', 268 );
-define( 'PHPTAGS_T_SL_EQUAL', 269 );
-define( 'PHPTAGS_T_XOR_EQUAL', 270 );
-define( 'PHPTAGS_T_OR_EQUAL', 271 );
-define( 'PHPTAGS_T_AND_EQUAL', 272 );
-define( 'PHPTAGS_T_MOD_EQUAL', 273 );
-define( 'PHPTAGS_T_CONCAT_EQUAL', 274 );
-define( 'PHPTAGS_T_DIV_EQUAL', 275 );
-define( 'PHPTAGS_T_MUL_EQUAL', 276 );
-define( 'PHPTAGS_T_MINUS_EQUAL', 277 );
-define( 'PHPTAGS_T_PLUS_EQUAL', 278 );
-define( 'PHPTAGS_T_IS_NOT_IDENTICAL', 281 );
-define( 'PHPTAGS_T_IS_IDENTICAL', 282 );
-define( 'PHPTAGS_T_IS_NOT_EQUAL', 283 );
-define( 'PHPTAGS_T_IS_EQUAL', 284 );
-define( 'PHPTAGS_T_IS_GREATER_OR_EQUAL', 285 );
-define( 'PHPTAGS_T_IS_SMALLER_OR_EQUAL', 286 );
-define( 'PHPTAGS_T_SR', 287 );
-define( 'PHPTAGS_T_SL', 288 );
-define( 'PHPTAGS_T_UNSET_CAST', 290 );
-define( 'PHPTAGS_T_BOOL_CAST', 291 );
-define( 'PHPTAGS_T_ARRAY_CAST', 293 );
-define( 'PHPTAGS_T_STRING_CAST', 294 );
-define( 'PHPTAGS_T_DOUBLE_CAST', 295 );
-define( 'PHPTAGS_T_INT_CAST', 296 );
-define( 'PHPTAGS_T_DEC', 297 );
-define( 'PHPTAGS_T_INC', 298 );
-define( 'PHPTAGS_T_NEW', 300 );
-define( 'PHPTAGS_T_IF', 302 );
-define( 'PHPTAGS_T_HOOK', 308 );
-define( 'PHPTAGS_T_HOOK_CHECK_PARAM', 309 );
-define( 'PHPTAGS_T_VARIABLE', 310 );
-define( 'PHPTAGS_T_WHILE', 319 );
-define( 'PHPTAGS_T_FOREACH', 323 );
-define( 'PHPTAGS_T_AS', 327 );
-define( 'PHPTAGS_T_BREAK', 332 );
-define( 'PHPTAGS_T_CONTINUE', 333 );
-define( 'PHPTAGS_T_RETURN', 337 );
-define( 'PHPTAGS_T_GLOBAL', 344 );
-define( 'PHPTAGS_T_STATIC', 350 );
-define( 'PHPTAGS_T_UNSET', 352 );
-define( 'PHPTAGS_T_ISSET', 353 );
-define( 'PHPTAGS_T_EMPTY', 354 );
-define( 'PHPTAGS_T_LIST', 363 );
-define( 'PHPTAGS_T_ARRAY', 364 );
-define( 'PHPTAGS_T_COPY', 500 );
+/**
+ * operator: "
+ */
+const PHPTAGS_T_QUOTE = 0; // "
+/**
+ * operator: .
+ */
+const PHPTAGS_T_CONCAT = 1;
+/**
+ * operator: +
+ */
+const PHPTAGS_T_PLUS = 2;
+/**
+ * operator: -
+ */
+const PHPTAGS_T_MINUS = 3;
+/**
+ * operator: *
+ */
+const PHPTAGS_T_MUL = 4;
+/**
+ * operator: /
+ */
+const PHPTAGS_T_DIV = 5;
+/**
+ * operator: ==
+ */
+const PHPTAGS_T_IS_EQUAL = 6;
+/**
+ * get value from variable
+ */
+const PHPTAGS_T_VARIABLE = 7;
+/**
+ * operator: if
+ */
+const PHPTAGS_T_IF = 8;
+/**
+ * operator: =
+ */
+const PHPTAGS_T_EQUAL = 9;
+/**
+ * operator: .=
+ */
+const PHPTAGS_T_CONCAT_EQUAL = 10;
+/**
+ * operator: /=
+ */
+const PHPTAGS_T_DIV_EQUAL = 11;
+/**
+ * operator: *=
+ */
+const PHPTAGS_T_MUL_EQUAL = 12;
+/**
+ * operator: -=
+ */
+const PHPTAGS_T_MINUS_EQUAL = 13;
+/**
+ * operator: +=
+ */
+const PHPTAGS_T_PLUS_EQUAL = 14;
+/**
+ * operator: !==
+ */
+const PHPTAGS_T_IS_NOT_IDENTICAL = 15;
+/**
+ * operator: ===
+ */
+const PHPTAGS_T_IS_IDENTICAL = 16;
+/**
+ * operator: !=
+ */
+const PHPTAGS_T_IS_NOT_EQUAL = 17;
+/**
+ * operator: ^=
+ */
+const PHPTAGS_T_XOR_EQUAL = 18;
+/**
+ * operator: >=
+ */
+const PHPTAGS_T_IS_GREATER_OR_EQUAL = 19;
+/**
+ * operator: <=
+ */
+const PHPTAGS_T_IS_SMALLER_OR_EQUAL = 20;
+/**
+ * operator: >>
+ */
+const PHPTAGS_T_SR = 21;
+/**
+ * operator: <<
+ */
+const PHPTAGS_T_SL = 22;
+/**
+ * operator: (unset)
+ */
+const PHPTAGS_T_UNSET_CAST = 23;
+/**
+ * operator: (bool)
+ */
+const PHPTAGS_T_BOOL_CAST = 24;
+/**
+ * operator: (array)
+ */
+const PHPTAGS_T_ARRAY_CAST = 25;
+/**
+ * operator: (string)
+ */
+const PHPTAGS_T_STRING_CAST = 26;
+/**
+ * operator: (double)
+ */
+const PHPTAGS_T_DOUBLE_CAST = 27;
+/**
+ * operator: (int)
+ */
+const PHPTAGS_T_INT_CAST = 28;
+/**
+ * operator: --
+ */
+const PHPTAGS_T_DEC = 29;
+/**
+ * operator: ++
+ */
+const PHPTAGS_T_INC = 30;
+/**
+ * operator: new
+ */
+const PHPTAGS_T_NEW = 31;
+/**
+ * operator: &=
+ */
+const PHPTAGS_T_AND_EQUAL = 32;
+/**
+ * call phptags hook
+ */
+const PHPTAGS_T_HOOK = 33;
+/**
+ * check passed param to phptags hook
+ */
+const PHPTAGS_T_HOOK_CHECK_PARAM = 34;
+/**
+ * it copies value from variable to destination
+ */
+const PHPTAGS_T_COPY = 35;
+const PHPTAGS_T_WHILE = 36;
+const PHPTAGS_T_FOREACH = 37;
+const PHPTAGS_T_AS = 38;
+const PHPTAGS_T_BREAK = 39;
+const PHPTAGS_T_CONTINUE = 40;
+const PHPTAGS_T_RETURN = 41;
+const PHPTAGS_T_GLOBAL = 42;
+const PHPTAGS_T_STATIC = 43;
+const PHPTAGS_T_UNSET = 44;
+const PHPTAGS_T_ISSET = 45;
+const PHPTAGS_T_EMPTY = 46;
+const PHPTAGS_T_LIST = 47;
+const PHPTAGS_T_ARRAY = 48;
+const PHPTAGS_T_OR_EQUAL = 49;
+/**
+ * operators: echo, print
+ */
+const PHPTAGS_T_PRINT = 50;
+/**
+ * operator: ||
+ */
+const PHPTAGS_T_LOGICAL_OR = 51;
+/**
+ * operator: @
+ */
+const PHPTAGS_T_IGNORE_ERROR = 52; // @
+/**
+ * ternary operator: ?
+ */
+const PHPTAGS_T_TERNARY = 53; // ?
+/**
+ * operator: |
+ */
+const PHPTAGS_T_OR = 54; // |
+/**
+ * operator: ^
+ */
+const PHPTAGS_T_XOR = 55;
+/**
+ * operator: &
+ */
+const PHPTAGS_T_AND = 56;
+/**
+ * operator: >
+ */
+const PHPTAGS_T_IS_GREATER = 57;
+/**
+ * operator: <
+ */
+const PHPTAGS_T_IS_SMALLER = 58;
+/**
+ * operator: xor
+ */
+const PHPTAGS_T_LOGICAL_XOR = 59;
+const PHPTAGS_T_MOD_EQUAL = 60;
+/**
+ * operator: and
+ */
+const PHPTAGS_T_LOGICAL_AND = 61;
+/**
+ * operator: %
+ */
+const PHPTAGS_T_MOD = 62;
+const PHPTAGS_T_SL_EQUAL = 63;
+const PHPTAGS_T_SR_EQUAL = 64;
+/**
+ * operator: !
+ */
+const PHPTAGS_T_IS_NOT = 65;
+/**
+ * operator: ~
+ */
+const PHPTAGS_T_NOT = 66;
/**
* The runtime class of the extension PhpTags.
@@ -106,10 +287,80 @@
private static $variables = array();
private static $staticVariables = array();
private static $globalVariables = array();
- private static $exceptions = array();
+ private static $ignoreErrors = false;
private static $scope;
private static $parserDisabled = false;
private static $errorCategoryAdded = false;
+
+ private static $operators = array(
+ PHPTAGS_T_QUOTE => 'doQuote',
+ PHPTAGS_T_CONCAT => 'doConcat',
+ PHPTAGS_T_PLUS => 'doPlus',
+ PHPTAGS_T_MINUS => 'doMinus',
+ PHPTAGS_T_MUL => 'doMul',
+ PHPTAGS_T_DIV => 'doDiv',
+ PHPTAGS_T_MOD => 'doMod',
+ PHPTAGS_T_AND => 'doAnd',
+ PHPTAGS_T_OR => 'doOr',
+ PHPTAGS_T_XOR => 'doXor',
+ PHPTAGS_T_SL => 'doShiftLeft',
+ PHPTAGS_T_SR => 'doShiftRight',
+ PHPTAGS_T_LOGICAL_AND => 'doLogicalAnd',
+ PHPTAGS_T_LOGICAL_XOR => 'doLogicalXor',
+ PHPTAGS_T_LOGICAL_OR => 'doLogicalOr',
+ PHPTAGS_T_IS_SMALLER => 'doIsSmaller',
+ PHPTAGS_T_IS_GREATER => 'doIsGreater',
+ PHPTAGS_T_IS_SMALLER_OR_EQUAL => 'doIsSmallerOrEqual',
+ PHPTAGS_T_IS_GREATER_OR_EQUAL => 'doIsGreaterOrEqual',
+ PHPTAGS_T_IS_EQUAL => 'doIsEqual',
+ PHPTAGS_T_IS_NOT_EQUAL => 'doIsNotEqual',
+ PHPTAGS_T_IS_IDENTICAL => 'doIsIdentical',
+ PHPTAGS_T_IS_NOT_IDENTICAL => 'doIsNotIdentical',
+ PHPTAGS_T_PRINT => 'doPrint',
+ PHPTAGS_T_NOT => 'doNot',
+ PHPTAGS_T_IS_NOT => 'doIsNot',
+ PHPTAGS_T_INT_CAST => 'doIntCast',
+ PHPTAGS_T_DOUBLE_CAST => 'doDoubleCast',
+ PHPTAGS_T_STRING_CAST => 'doStringCast',
+ PHPTAGS_T_ARRAY_CAST => 'doArrayCast',
+ PHPTAGS_T_BOOL_CAST => 'doBoolCast',
+ PHPTAGS_T_UNSET_CAST => 'doUnsetCast',
+ PHPTAGS_T_VARIABLE => 'doVariable',
+ PHPTAGS_T_TERNARY => 'doTernary',
+ PHPTAGS_T_IF => 'doIf',
+ PHPTAGS_T_FOREACH => 'doForeach',
+ PHPTAGS_T_WHILE => 'doWhile',
+ PHPTAGS_T_AS => 'doAs',
+ PHPTAGS_T_BREAK => 'doBreak',
+ PHPTAGS_T_CONTINUE => 'doContinue',
+ PHPTAGS_T_ARRAY => 'doArray',
+ PHPTAGS_T_STATIC => 'doStatic',
+ PHPTAGS_T_GLOBAL => 'doGlobal',
+ PHPTAGS_T_HOOK_CHECK_PARAM => 'doCheckingParam',
+ PHPTAGS_T_HOOK => 'doCallingHook',
+ PHPTAGS_T_NEW => 'doNewObject',
+ PHPTAGS_T_UNSET => 'doUnset',
+ PHPTAGS_T_ISSET => 'doIsSet',
+ PHPTAGS_T_EMPTY => 'doIsEmpty',
+ PHPTAGS_T_RETURN => 'doReturn',
+ PHPTAGS_T_COPY => 'doCopy',
+ PHPTAGS_T_IGNORE_ERROR => 'doIgnoreErrors',
+ PHPTAGS_T_LIST => 'doList',
+ PHPTAGS_T_INC => 'doIncrease',
+ PHPTAGS_T_DEC => 'doDecrease',
+ PHPTAGS_T_EQUAL => 'doSetVal',
+ PHPTAGS_T_CONCAT_EQUAL => 'doSetConcatVal',
+ PHPTAGS_T_PLUS_EQUAL => 'doSetPlusVal',
+ PHPTAGS_T_MINUS_EQUAL => 'doSetMinusVal',
+ PHPTAGS_T_MUL_EQUAL => 'doSetMulVal',
+ PHPTAGS_T_DIV_EQUAL => 'doSetDivVal',
+ PHPTAGS_T_MOD_EQUAL => 'doSetModVal',
+ PHPTAGS_T_AND_EQUAL => 'doSetAndVal',
+ PHPTAGS_T_OR_EQUAL => 'doSetOrVal',
+ PHPTAGS_T_XOR_EQUAL => 'doSetXorVal',
+ PHPTAGS_T_SL_EQUAL => 'doSetShiftLeftVal',
+ PHPTAGS_T_SR_EQUAL => 'doSetShiftRightVal',
+ );
public static function reset() {
global $wgPhpTagsMaxLoops;
@@ -126,629 +377,984 @@
return self::run( Compiler::compile($code), $args, $scope );
}
+ /**
+ * The output cache
+ * @var array
+ */
+ private static $return;
+ private static $running;
+ private static $runIndex;
+ private static $c;
+ private static $loopsOwner;
+ private static $memory;
+ private static $place;
+ private static $thisVariables;
+
+ private static function pushDown( $newCode, $newLoopsOwner, &$refReturn
) {
+ self::$memory[] = array( &$refReturn, self::$running,
self::$runIndex, self::$c, self::$loopsOwner );
+ self::$running = $newCode;
+ self::$runIndex = -1;
+ self::$c = count( $newCode );
+ self::$loopsOwner = $newLoopsOwner;
+ }
+
+ private static function popUp() {
+ list( self::$running[self::$runIndex][PHPTAGS_STACK_RESULT],
self::$running, self::$runIndex, self::$c, self::$loopsOwner ) = array_pop(
self::$memory );
+ }
+
+ /**
+ * PHPTAGS_T_QUOTE
+ * @param array $value
+ */
+ private static function doQuote ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = implode(
$value[PHPTAGS_STACK_PARAM] );
+ }
+
+ /**
+ * PHPTAGS_T_CONCAT
+ * @param array $value
+ */
+ private static function doConcat ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] .
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_PLUS
+ * @param array $value
+ */
+ private static function doPlus ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] +
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_MINUS
+ * @param array $value
+ */
+ private static function doMinus ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] -
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_MUL
+ * @param array $value
+ */
+ private static function doMul ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] *
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_DIV
+ * @param array $value
+ */
+ private static function doDiv ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] /
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_MOD
+ * @param array $value
+ */
+ private static function doMod ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] %
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_AND
+ * @param array $value
+ */
+ private static function doAnd ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] &
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_OR
+ * @param array $value
+ */
+ private static function doOr ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] |
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_XOR
+ * @param array $value
+ */
+ private static function doXor ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] ^
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_SL
+ * @param array $value
+ */
+ private static function doShiftLeft ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] <<
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_SR
+ * @param array $value
+ */
+ private static function doShiftRight ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] >>
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_LOGICAL_AND
+ * @param array $value
+ */
+ private static function doLogicalAnd ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] &&
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_LOGICAL_XOR
+ * @param array $value
+ */
+ private static function doLogicalXor ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] xor
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_LOGICAL_OR
+ * @param array $value
+ */
+ private static function doLogicalOr ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] ||
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_IS_SMALLER
+ * @param array $value
+ */
+ private static function doIsSmaller ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] <
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_IS_GREATER
+ * @param array $value
+ */
+ private static function doIsGreater ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] >
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_IS_SMALLER_OR_EQUAL
+ * @param array $value
+ */
+ private static function doIsSmallerOrEqual ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] <=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_IS_GREATER_OR_EQUAL
+ * @param array $value
+ */
+ private static function doIsGreaterOrEqual ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] >=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_IS_EQUAL
+ * @param array $value
+ */
+ private static function doIsEqual ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] ==
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_IS_NOT_EQUAL
+ * @param array $value
+ */
+ private static function doIsNotEqual ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] !=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_IS_IDENTICAL
+ * @param array $value
+ */
+ private static function doIsIdentical ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] ===
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_IS_NOT_IDENTICAL
+ * @param array $value
+ */
+ private static function doIsNotIdentical ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] !==
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_PRINT outputs the value
+ * @param array $value
+ */
+ private static function doPrint ( $value ) {
+ if( $value[PHPTAGS_STACK_PARAM] instanceof GenericObject ) {
+ self::$return[] =
$value[PHPTAGS_STACK_PARAM]->toString();
+ } else {
+ self::$return[] = $value[PHPTAGS_STACK_PARAM];
+ }
+ }
+
+ /**
+ * PHPTAGS_T_NOT
+ * @param array $value
+ */
+ private static function doNot ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = ~$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_IS_NOT
+ * @param array $value
+ */
+ private static function doIsNot ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = !$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_INT_CAST
+ * @param array $value
+ */
+ private static function doIntCast ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] =
(int)$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_DOUBLE_CAST
+ * @param array $value
+ */
+ private static function doDoubleCast ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] =
(double)$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_STRING_CAST
+ * @param array $value
+ */
+ private static function doStringCast ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] =
(string)$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_ARRAY_CAST
+ * @param array $value
+ */
+ private static function doArrayCast ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] =
(array)$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_BOOL_CAST
+ * @param array $value
+ */
+ private static function doBoolCast ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] =
(bool)$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_UNSET_CAST
+ * @param array $value
+ */
+ private static function doUnsetCast ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] =
(unset)$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_VARIABLE
+ * @param array $value
+ */
+ private static function doVariable ( $value ) {
+ $aim = $value[PHPTAGS_STACK_AIM];
+ if ( isset(self::$thisVariables[ $value[PHPTAGS_STACK_PARAM] ])
|| array_key_exists($value[PHPTAGS_STACK_PARAM], self::$thisVariables) ) {
+ $value[PHPTAGS_STACK_PARAM_2][$aim] =&
self::$thisVariables[ $value[PHPTAGS_STACK_PARAM] ];
+ if ( isset($value[PHPTAGS_STACK_ARRAY_INDEX]) ) { //
Example: $foo[1]
+ foreach ( $value[PHPTAGS_STACK_ARRAY_INDEX] as
$v ) {
+ if ( is_array(
$value[PHPTAGS_STACK_PARAM_2][$aim] ) ) {
+ if (
isset($value[PHPTAGS_STACK_PARAM_2][$aim][$v]) || array_key_exists($v,
$value[PHPTAGS_STACK_PARAM_2][$aim]) ) {
+
$value[PHPTAGS_STACK_PARAM_2][$aim] =& $value[PHPTAGS_STACK_PARAM_2][$aim][$v];
+ } else {
+ // PHP Notice:
Undefined offset: $1
+ self::pushException(
new PhpTagsException( PhpTagsException::NOTICE_UNDEFINED_INDEX, $v ) );
+ unset(
$value[PHPTAGS_STACK_PARAM_2][$aim] );
+
$value[PHPTAGS_STACK_PARAM_2][$aim] = null;
+ }
+ } else {
+ if ( isset(
$value[PHPTAGS_STACK_PARAM_2][$aim][$v]) ) {
+ unset(
$value[PHPTAGS_STACK_PARAM_2][$aim] );
+
$value[PHPTAGS_STACK_PARAM_2][$aim] = $value[PHPTAGS_STACK_PARAM_2][$aim][$v];
+ } else {
+ // PHP Notice:
Uninitialized string offset: $1
+ self::pushException(
new PhpTagsException( PhpTagsException::NOTICE_UNINIT_STRING_OFFSET, (int)$v )
);
+ unset(
$value[PHPTAGS_STACK_PARAM_2][$aim] );
+
$value[PHPTAGS_STACK_PARAM_2][$aim] = null;
+ }
+ }
+ }
+ }
+ } else {
+ unset( $value[PHPTAGS_STACK_PARAM_2][$aim] );
+ $value[PHPTAGS_STACK_PARAM_2][$aim] = null;
+ Runtime::pushException( new PhpTagsException(
PhpTagsException::NOTICE_UNDEFINED_VARIABLE, $value[PHPTAGS_STACK_PARAM] ) );
+ }
+ }
+
+ /**
+ * PHPTAGS_T_TERNARY
+ * @param array $value
+ */
+ private static function doTernary ( $value ) {
+ if( $value[PHPTAGS_STACK_PARAM] ) { // true ?
+ if(
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_DO_TRUE] ) { // true ? 1+2 :
+ self::pushDown(
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_DO_TRUE], '?',
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_PARAM] );
+ }else{ // true ? 1 :
+ $value[PHPTAGS_STACK_RESULT] =
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_PARAM];
+ }
+ }else{ // false ?
+ if(
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_DO_FALSE] ) { // false ? ... : 1+2
+ self::pushDown(
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_DO_FALSE], '?',
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_PARAM_2] );
+ }else{ // false ? ... : 1
+ $value[PHPTAGS_STACK_RESULT] =
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_PARAM_2];
+ }
+ }
+ }
+
+ /**
+ * PHPTAGS_T_IF
+ * @param array $value
+ */
+ private static function doIf ( $value ) {
+ $return = null;
+ if( $value[PHPTAGS_STACK_PARAM] ) { // Example: if( true )
+ if( $value[PHPTAGS_STACK_DO_TRUE] ) { // Stack not
empty: if(true);
+ self::pushDown( $value[PHPTAGS_STACK_DO_TRUE],
T_IF, $return );
+ }
+ }else{ // Example: if( false )
+ if( isset($value[PHPTAGS_STACK_DO_FALSE]) ) { // Stack
not empty: if(false) ; else ;
+ self::pushDown( $value[PHPTAGS_STACK_DO_FALSE],
T_IF, $return );
+ }
+ }
+ }
+
+ /**
+ * PHPTAGS_T_FOREACH
+ * @param array $value
+ */
+ private static function doForeach ( $value ) {
+ if ( !is_array($value[PHPTAGS_STACK_PARAM]) ) {
+ self::pushException( new PhpTagsException(
PhpTagsException::WARNING_INVALID_ARGUMENT_FOR_FOREACH, null ) );
+ return;
+ }
+ reset( $value[PHPTAGS_STACK_PARAM] );
+ $null = null;
+ self::pushDown( $value[PHPTAGS_STACK_DO_TRUE], T_WHILE, $null );
+ }
+
+ /**
+ * PHPTAGS_T_WHILE
+ * @param array $value
+ */
+ private static function doWhile ( $value ) {
+ $null = null;
+ self::pushDown( $value[PHPTAGS_STACK_DO_TRUE], T_WHILE, $null );
+ }
+
+ /**
+ * PHPTAGS_T_AS
+ * @param array $value
+ */
+ private static function doAs ( $value ) {
+ if ( !is_array($value[PHPTAGS_STACK_RESULT]) ) {
+ Runtime::pushException( new PhpTagsException(
PhpTagsException::WARNING_INVALID_ARGUMENT_FOR_FOREACH, null ) );
+ return;
+ }
+ if ( isset($value[PHPTAGS_STACK_PARAM_2]) ) { // T_DOUBLE_ARROW
Example: while ( $foo as $key=>$value )
+ if ( !list(self::$thisVariables[
$value[PHPTAGS_STACK_PARAM] ], self::$thisVariables[
$value[PHPTAGS_STACK_PARAM_2] ]) = each($value[PHPTAGS_STACK_RESULT]) ) {
+ self::popUp();
+ }
+ } else { // Example: while ( $foo as $value )
+ if ( !list(,self::$thisVariables[
$value[PHPTAGS_STACK_PARAM] ]) = each($value[PHPTAGS_STACK_RESULT]) ) {
+ self::popUp();
+ }
+ }
+ }
+
+ /**
+ * PHPTAGS_T_BREAK
+ * @param array $value
+ */
+ private static function doBreak ( $value ) {
+ $loopsOwner =& self::$loopsOwner;
+ $memory =& self::$memory;
+ $originalBreak = $break = $value[PHPTAGS_STACK_RESULT];
+
+ for ( ; ; ) {
+ if ( $loopsOwner === T_WHILE ) {
+ --$break;
+ }
+ self::popUp();
+ if ( $break === 0 ) {
+ return;
+ } elseif ( count( $memory ) === 0 ) {
+ if ( $break > 1 ) {
+ throw new PhpTagsException(
PhpTagsException::FATAL_WRONG_BREAK_LEVELS, $originalBreak );
+ }
+ return;
+ }
+ }
+ }
+
+ /**
+ * PHPTAGS_T_CONTINUE
+ * @param array $value
+ */
+ private static function doContinue ( $value ) {
+ if( self::$loopsLimit-- <= 0 ) {
+ throw new PhpTagsException(
PhpTagsException::FATAL_LOOPS_LIMIT_REACHED, null,
$value[PHPTAGS_STACK_TOKEN_LINE], $place );
+ }
+ $loopsOwner =& self::$loopsOwner;
+ $memory =& self::$memory;
+ $originalBreak = $break = $value[PHPTAGS_STACK_RESULT] - 1;
+
+ for ( ; ; ) {
+ if ( $loopsOwner === T_WHILE ) {
+ if ( $break > 0 ) {
+ --$break;
+ } else {
+ break;
+ }
+ }
+ self::popUp();
+ if ( count( $memory ) === 0 && $break > 0 ) {
+ throw new PhpTagsException(
PhpTagsException::FATAL_WRONG_BREAK_LEVELS, $originalBreak );
+ }
+ }
+ self::$runIndex = -1;
+ }
+
+ /**
+ * PHPTAGS_T_ARRAY inits new array
+ * @param array $value
+ */
+ private static function doArray ( $value ) {
+ $newArray = $value[PHPTAGS_STACK_PARAM][0];
+ $i = 1;
+ foreach ( $value[PHPTAGS_STACK_PARAM_2] as $t ) {
+ list ( $k, $v ) = $t;
+ $newArray[$k] = $v;
+ if ( isset($value[PHPTAGS_STACK_PARAM][$i]) ) {
+ foreach ( $value[PHPTAGS_STACK_PARAM][$i] as $n
) {
+ $newArray[] = $n;
+ }
+ }
+ ++$i;
+ }
+ $value[PHPTAGS_STACK_RESULT] = $newArray;
+ }
+
+ /**
+ * PHPTAGS_T_STATIC inits static variables
+ * @param array $value
+ */
+ private static function doStatic ( $value ) {
+ $name = $value[PHPTAGS_STACK_PARAM]; // variable name
+ if( !isset(self::$staticVariables[self::$place]) ||
!array_key_exists($name, self::$staticVariables[self::$place]) ) {
+ self::$staticVariables[self::$place][$name] =
$value[PHPTAGS_STACK_RESULT];
+ if ( $value[PHPTAGS_STACK_DO_TRUE] ) {
+ $null = null;
+ self::pushDown( $value[PHPTAGS_STACK_DO_TRUE],
T_STATIC, $null );
+ }
+ }
+ self::$thisVariables[$name] =&
self::$staticVariables[self::$place][$name];
+ }
+
+ /**
+ * PHPTAGS_T_GLOBAL inits global variables
+ * @param array $value
+ */
+ private static function doGlobal ( $value ) {
+ $gVars =& self::$globalVariables;
+ foreach( $value[PHPTAGS_STACK_PARAM] as $name ) { // variable
names
+ if( !array_key_exists($name, $gVars) ) {
+ $gVars[$name] = null;
+ }
+ self::$thisVariables[$name] =& $gVars[$name];
+ }
+ }
+
+ /**
+ * PHPTAGS_T_HOOK_CHECK_PARAM checks param for hooks
+ * @param array $value
+ */
+ private static function doCheckingParam ( $value ) {
+ $i = $value[PHPTAGS_STACK_AIM];
+ $reference_info = Hooks::getReferenceInfo(
+ $i, // ordinal number of the argument, zero is
first
+ $value[PHPTAGS_STACK_HOOK_TYPE],
+ $value[PHPTAGS_STACK_PARAM], // name of
function or method
+ $value[PHPTAGS_STACK_PARAM_3] === false ? false
: $value[PHPTAGS_STACK_PARAM_3][PHPTAGS_STACK_PARAM_3] // $object or false
+ );
+
+ if ( $value[PHPTAGS_STACK_PARAM_2] === true && $reference_info
=== false ) {
+ // Param is variable and it needs to clone
+ $t = $value[PHPTAGS_STACK_RESULT][$i];
+ unset( $value[PHPTAGS_STACK_RESULT][$i] );
+ $value[PHPTAGS_STACK_RESULT][$i] = $t;
+ } elseif ( $value[PHPTAGS_STACK_PARAM_2] === false &&
$reference_info === true ) {
+ // Param is not variable and it's need reference
+ throw new PhpTagsException(
PhpTagsException::FATAL_VALUE_PASSED_BY_REFERENCE, null,
$value[PHPTAGS_STACK_TOKEN_LINE], $place );
+ }
+ }
+
+ /**
+ * PHPTAGS_T_HOOK calls hook
+ * @param array $value
+ */
+ private static function doCallingHook ( $value ) {
+ $result = Hooks::callHook(
+ $value[PHPTAGS_STACK_HOOK_TYPE],
+ $value[PHPTAGS_STACK_PARAM_2], // arguments
+ $value[PHPTAGS_STACK_PARAM], // name of
function or method
+ $value[PHPTAGS_STACK_PARAM_3] // $object or
false
+ );
+
+ if ( $result instanceof outPrint ) {
+ $value[PHPTAGS_STACK_RESULT] = $result->returnValue;
+ self::$return[] = $result;
+ } else {
+ $value[PHPTAGS_STACK_RESULT] = $result;
+ }
+ if ( is_object($value[PHPTAGS_STACK_RESULT]) &&
!($value[PHPTAGS_STACK_RESULT] instanceof iRawOutput ||
$value[PHPTAGS_STACK_RESULT] instanceof GenericObject) ) {
+ // @todo
+ $value[PHPTAGS_STACK_RESULT] = null;
+ Runtime::pushException( new PhpTagsException(
PhpTagsException::WARNING_RETURNED_INVALID_VALUE, $value[PHPTAGS_STACK_PARAM] )
);
+ }
+ }
+
+ /**
+ * PHPTAGS_T_NEW creates new object
+ * @param array $value
+ */
+ private static function doNewObject ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = Hooks::createObject(
$value[PHPTAGS_STACK_PARAM_2], $value[PHPTAGS_STACK_PARAM_3] );
+ }
+
+ /**
+ * PHPTAGS_T_UNSET unsets variables
+ * @param array $value
+ */
+ private static function doUnset ( $value ) {
+ $thisVariables =& self::$thisVariables;
+ foreach ( $value[PHPTAGS_STACK_PARAM] as $val ) {
+ $name = $val[PHPTAGS_STACK_PARAM]; // Variable Name
+ if ( isset($thisVariables[$name]) ||
array_key_exists($name, $thisVariables) ) { // defined variable
+ if ( isset($val[PHPTAGS_STACK_ARRAY_INDEX]) ) {
// There is array index. Example: unset($foo[0])
+ $ref =& $thisVariables[$name];
+ $tmp = array_pop(
$val[PHPTAGS_STACK_ARRAY_INDEX] );
+ foreach (
$val[PHPTAGS_STACK_ARRAY_INDEX] as $v ) {
+ if ( is_string($ref) ) {
+ throw new
PhpTagsException( PhpTagsException::FATAL_CANNOT_UNSET_STRING_OFFSETS, null,
$value[PHPTAGS_STACK_TOKEN_LINE], $place );
+ } elseif ( !isset($ref[$v]) ) {
// undefined array index not for string
+ continue 2;
+ }
+ $ref =& $ref[$v];
+ }
+ if ( is_array($ref) ) {
+ unset( $ref[$tmp] );
+ } else {
+ throw new PhpTagsException(
PhpTagsException::FATAL_CANNOT_UNSET_STRING_OFFSETS, null,
$value[PHPTAGS_STACK_TOKEN_LINE], $place );
+ }
+ }else{ // There is no array index. Example:
unset($foo)
+ unset( $thisVariables[$name] );
+ }
+ } elseif ( isset($val[PHPTAGS_STACK_ARRAY_INDEX]) ) {
// undefined variable with array index. Example: unset($foo[1])
+ self::pushException( new PhpTagsException(
PHPTAGS_NOTICE_UNDEFINED_VARIABLE, $name ) );
+ }
+ }
+ }
+
+ /**
+ * PHPTAGS_T_ISSET returns TRUE when variables are set
+ * @param array $value
+ */
+ private static function doIsSet ( $value ) {
+ $thisVariables =& self::$thisVariables;
+ foreach($value[PHPTAGS_STACK_PARAM] as $val) {
+ if( !isset($thisVariables[ $val[PHPTAGS_STACK_PARAM] ])
) { // undefined variable or variable is null
+ $value[PHPTAGS_STACK_RESULT] = false;
+ return;
+ } // true, variable is defined
+ if( isset($val[PHPTAGS_STACK_ARRAY_INDEX]) ) { //
Example: isset($foo[1])
+ $ref =& $thisVariables[
$val[PHPTAGS_STACK_PARAM] ];
+ $tmp = array_pop(
$val[PHPTAGS_STACK_ARRAY_INDEX] );
+ foreach( $val[PHPTAGS_STACK_ARRAY_INDEX] as $v
) {
+ if( !isset($ref[$v]) ) { // undefined
array index
+ $value[PHPTAGS_STACK_RESULT] =
false;
+ return;
+ }
+ $ref =& $ref[$v];
+ }
+ // @todo ->>>>>>>>>>>> |
************************************************************* | <<<<< it only
for compatible with PHP 5.4 if used PHP 5.3 @see
http://www.php.net/manual/en/function.isset.php Example #2 isset() on String
Offsets
+ if( !isset($ref[$tmp]) || (is_string($ref) &&
is_string($tmp ) && $tmp != (string)(int)$tmp ) ) {
+ $value[PHPTAGS_STACK_RESULT] = false;
+ return;
+ }
+ } // true, variable is defined and have no array index
+ }
+ $value[PHPTAGS_STACK_RESULT] = true;
+ }
+
+ /**
+ * PHPTAGS_T_EMPTY returns TRUE when variables are empty
+ * @param array $value
+ */
+ private static function doIsEmpty ( $value ) {
+ $thisVariables =& self::$thisVariables;
+ foreach($value[PHPTAGS_STACK_PARAM] as $val) {
+ if( !array_key_exists($val[PHPTAGS_STACK_PARAM],
$thisVariables) ) { // undefined variable
+ continue;
+ }
+ $ref =& $thisVariables[ $val[PHPTAGS_STACK_PARAM] ];
+ if( isset($val[PHPTAGS_STACK_ARRAY_INDEX]) ) { //
Example: empty($foo[1])
+ $tmp = array_pop(
$val[PHPTAGS_STACK_ARRAY_INDEX] );
+ foreach( $val[PHPTAGS_STACK_ARRAY_INDEX] as $v
) {
+ if( !isset($ref[$v]) ) { // undefined
array index
+ continue 2;
+ }
+ $ref = &$ref[$v];
+ }
+ // @todo ->>>>>>>>>>>> |
************************************************************* | <<<<< it only
for compatible with PHP 5.4 if used PHP 5.3 @see
http://www.php.net/manual/en/function.empty.php Example #2 empty() on String
Offsets
+ if( !empty($ref[$tmp]) && (is_array($ref) ||
!is_string( $tmp ) || $tmp == (string)(int)$tmp ) ) {
+ $value[PHPTAGS_STACK_RESULT] = false;
+ return;
+ }
+ }elseif( !empty($ref) ) { // there is no array index
and empty() returns false (PHP 5.5.0 supports expressions)
+ $value[PHPTAGS_STACK_RESULT] = false;
+ return;
+ }
+ }
+ $value[PHPTAGS_STACK_RESULT] = true;
+ }
+
+ /**
+ * PHPTAGS_T_RETURN is designed for compiler only!
+ * @param array $value
+ */
+ private static function doReturn ( $value ) {
+ self::$return = self::$return ? new PhpTagsException() :
$value[PHPTAGS_STACK_PARAM];
+ }
+
+ /**
+ * PHPTAGS_T_COPY copies value from variable to destination
+ * @param array $value
+ */
+ private static function doCopy ( $value ) {
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM];
+ }
+
+ /**
+ * PHPTAGS_T_IGNORE_ERROR
+ * @param array $value
+ */
+ private static function doIgnoreErrors ( $value ) {
+ self::$ignoreErrors = $value[PHPTAGS_STACK_PARAM];
+ }
+
+ /**
+ * PHPTAGS_T_LIST
+ * @param array $value
+ */
+ private static function doList ( $value ) {
+ self::fillList( $value[PHPTAGS_STACK_PARAM_2],
$value[PHPTAGS_STACK_PARAM], self::$thisVariables );
+ $value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_INC
+ * @param array $value
+ */
+ private static function doIncrease ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ if ( $value[PHPTAGS_STACK_PARAM_2] ) { // $foo++
+ $value[PHPTAGS_STACK_RESULT] = $ref++;
+ }else{ // ++$foo
+ $value[PHPTAGS_STACK_RESULT] = ++$ref;
+ }
+ }
+
+ /**
+ * PHPTAGS_T_DEC
+ * @param array $value
+ */
+ private static function doDecrease ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ if ( $value[PHPTAGS_STACK_PARAM_2] ) { // $foo--
+ $value[PHPTAGS_STACK_RESULT] = $ref--;
+ }else{ // --$foo
+ $value[PHPTAGS_STACK_RESULT] = --$ref;
+ }
+ }
+
+ /**
+ * PHPTAGS_T_EQUAL
+ * @param array $value
+ */
+ private static function doSetVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref =
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_CONCAT_EQUAL
+ * @param array $value
+ */
+ private static function doSetConcatVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref .=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_PLUS_EQUAL
+ * @param array $value
+ */
+ private static function doSetPlusVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref +=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_MINUS_EQUAL
+ * @param array $value
+ */
+ private static function doSetMinusVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref -=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_MUL_EQUAL
+ * @param array $value
+ */
+ private static function doSetMulVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref *=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_DIV_EQUAL
+ * @param array $value
+ */
+ private static function doSetDivVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref /=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_MOD_EQUAL
+ * @param array $value
+ */
+ private static function doSetModVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref %=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_AND_EQUAL
+ * @param array $value
+ */
+ private static function doSetAndVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref &=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_OR_EQUAL
+ * @param array $value
+ */
+ private static function doSetOrVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref |=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_XOR_EQUAL
+ * @param array $value
+ */
+ private static function doSetXorVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref ^=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_SL_EQUAL
+ * @param array $value
+ */
+ private static function doSetShiftLeftVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref <<=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ /**
+ * PHPTAGS_T_SR_EQUAL
+ * @param array $value
+ */
+ private static function doSetShiftRightVal ( $value ) {
+ $ref =& self::getVariableRef( $value );
+ $value[PHPTAGS_STACK_RESULT] = $ref <<=
$value[PHPTAGS_STACK_PARAM_2];
+ }
+
+ private static function & getVariableRef( $value ) {
+ $thisVariables =& self::$thisVariables;
+ $variable = $value[PHPTAGS_STACK_PARAM];
+ $variableName = $variable[PHPTAGS_STACK_PARAM];
+ if( !(isset($thisVariables[$variableName]) ||
array_key_exists($variableName, $thisVariables)) ) { // Use undefined variable
+ if( isset($value[PHPTAGS_STACK_ARRAY_INDEX]) ) { //
Example: $foo[1]++
+ $thisVariables[$variableName] = array();
+ }else{
+ $thisVariables[$variableName] = null;
+ }
+ if( $value[PHPTAGS_STACK_COMMAND] !== PHPTAGS_T_EQUAL )
{
+ Runtime::pushException( new PhpTagsException(
PhpTagsException::NOTICE_UNDEFINED_VARIABLE, $variableName ) );
+ }
+ }
+ $ref =& $thisVariables[$variableName];
+ if ( isset($variable[PHPTAGS_STACK_ARRAY_INDEX]) ) { //
Example: $foo[1]++
+ foreach ( $variable[PHPTAGS_STACK_ARRAY_INDEX] as $v ) {
+ if ( $v === INF ) { // Example: $foo[]
+ $t = null;
+ $ref[] = &$t;
+ $ref = &$t;
+ unset( $t );
+ } else {
+ if ( $ref === null ) {
+ if(
$value[PHPTAGS_STACK_COMMAND] !== PHPTAGS_T_EQUAL ) {
+ // PHP Notice:
Undefined offset: $1
+ Runtime::pushException(
new PhpTagsException( PhpTagsException::NOTICE_UNDEFINED_OFFSET,
$v[PHPTAGS_STACK_RESULT] ) );
+ }
+ $ref[$v] = null;
+ $ref =& $ref[$v];
+ } elseif ( is_array($ref) ) {
+ if ( !( isset($ref[$v]) ||
array_key_exists($v, $ref) ) ) {
+ $ref[$v] = null;
+ if(
$value[PHPTAGS_STACK_COMMAND] !== PHPTAGS_T_EQUAL ) {
+ // PHP Notice:
Undefined offset: $1
+
Runtime::pushException( new PhpTagsException(
PhpTagsException::NOTICE_UNDEFINED_INDEX, $v ) );
+ }
+ }
+ $ref =& $ref[$v];
+ } elseif ( is_string($ref) ) {
+ // PHP Fatal error: Cannot use
string offset as an array
+ throw new PhpTagsException(
PhpTagsException::NOTICE_UNDEFINED_OFFSET, $v,
$value[PHPTAGS_STACK_TOKEN_LINE], $place );
+ } else {
+ Runtime::pushException( new
PhpTagsException( PhpTagsException::FATAL_STRING_OFFSET_AS_ARRAY, $v ) );
+ break 2;
+ // PHP Warning: Cannot use a
scalar value as an array
+ }
+ }
+ }
+ }
+ return $ref;
+ }
+
public static function run( $code, array $args, $scope = '' ) {
set_error_handler( '\\PhpTags\\ErrorHandler::onError' );
try {
- if( !isset(self::$variables[$scope]) ) {
+ self::$scope = $scope;
+ self::$running = $code;
+ self::$memory = array();
+ self::$return = array();
+ self::$loopsOwner = null;
+ self::$place = isset($args[0]) ? $args[0] : ''; // Page
name for static variables and error messages
+ self::$c = count( $code );
+ if( false === isset(self::$variables[$scope]) ) {
self::$variables[$scope] = array();
}
- self::$scope = $scope;
- $thisVariables =& self::$variables[$scope];
- $thisVariables['argv'] = $args;
- $thisVariables['argc'] = count($args);
- $thisVariables['GLOBALS'] = &self::$globalVariables;
- $exceptions =& self::$exceptions;
- $memory=array();
- $return = array();
- $break = 0; // used for T_BREAK
- $continue = false; // used for T_CONTINUE
- $loopsOwner = null;
- $place = isset($args[0]) ? $args[0] : ''; // Page name
for static variables and error messages
+ self::$thisVariables =& self::$variables[$scope];
+ self::$thisVariables['argv'] = $args;
+ self::$thisVariables['argc'] = count($args);
+ self::$thisVariables['GLOBALS'] =&
self::$globalVariables;
- $c = count( $code );
- $codeIndex=-1;
+ $runCode =& self::$running;
+ $runIndex =& self::$runIndex;
+ $loopsOwner =& self::$loopsOwner;
+ $memory =& self::$memory;
+ $c =& self::$c;
+ $operators = self::$operators;
+ $runIndex = -1;
do {
- if ( $break ) {
- if ( $loopsOwner == T_WHILE ) {
- $break--;
- continue;
- }
- break;
- } elseif ( $continue ) {
- if ( $loopsOwner == T_WHILE ) {
- $codeIndex = -1;
- $continue = false;
- } else {
- continue;
- }
+ for ( ++$runIndex; $runIndex < $c; ++$runIndex
) {
+ $value =& $runCode[$runIndex];
+ $call = $operators[
$value[PHPTAGS_STACK_COMMAND] ];
+ self::$call( $value );
}
- $codeIndex++;
- for ( ; $codeIndex < $c; $codeIndex++ ) {
- $value =& $code[$codeIndex];
- switch ( $value[PHPTAGS_STACK_COMMAND]
) {
- case '"': // Example: echo
"abc$foo";
-
$value[PHPTAGS_STACK_RESULT] = implode( $value[PHPTAGS_STACK_PARAM] );
- break;
- case '.':
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] .
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case '+':
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] +
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case '-':
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] -
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case '*':
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] *
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case '/':
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] /
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case '%':
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] %
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case '&':
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] &
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case '|':
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] |
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case '^':
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] ^
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_SL:
// <<
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] <<
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_SR:
// >>
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] >>
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_LOGICAL_AND:
// and
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] &&
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_LOGICAL_XOR:
// xor
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] xor
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_LOGICAL_OR:
// or
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] ||
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case '<':
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] <
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case '>':
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] >
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_IS_SMALLER_OR_EQUAL: // <=
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] <=
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_IS_GREATER_OR_EQUAL: // >=
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] >=
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_IS_EQUAL:
// ==
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] ==
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_IS_NOT_EQUAL:
// !=
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] !=
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_IS_IDENTICAL:
// ===
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] ===
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_IS_NOT_IDENTICAL: // !==
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM] !==
$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_PRINT:
- if(
$value[PHPTAGS_STACK_PARAM] instanceof GenericObject ) {
- $return[] =
$value[PHPTAGS_STACK_PARAM]->toString();
- } else {
- $return[] =
$value[PHPTAGS_STACK_PARAM];
- }
- break;
- case '~':
-
$value[PHPTAGS_STACK_RESULT] = ~$value[PHPTAGS_STACK_PARAM_2];
- break;
- case '!':
-
$value[PHPTAGS_STACK_RESULT] = !$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_INT_CAST:
// (int)
-
$value[PHPTAGS_STACK_RESULT] = (int)$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_DOUBLE_CAST:
// (double)
-
$value[PHPTAGS_STACK_RESULT] = (double)$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_STRING_CAST:
// (string)
-
$value[PHPTAGS_STACK_RESULT] = (string)$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_ARRAY_CAST:
// (array)
-
$value[PHPTAGS_STACK_RESULT] = (array)$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_BOOL_CAST:
// (bool)
-
$value[PHPTAGS_STACK_RESULT] = (bool)$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_UNSET_CAST:
// (unset)
-
$value[PHPTAGS_STACK_RESULT] = (unset)$value[PHPTAGS_STACK_PARAM_2];
- break;
- case PHPTAGS_T_VARIABLE:
- $aim =
$value[PHPTAGS_STACK_AIM];
- if (
isset($thisVariables[ $value[PHPTAGS_STACK_PARAM] ]) ||
array_key_exists($value[PHPTAGS_STACK_PARAM], $thisVariables) ) {
-
$value[PHPTAGS_STACK_PARAM_2][$aim] =& $thisVariables[
$value[PHPTAGS_STACK_PARAM] ];
- if (
isset($value[PHPTAGS_STACK_ARRAY_INDEX]) ) { // Example: $foo[1]
- foreach
( $value[PHPTAGS_STACK_ARRAY_INDEX] as $v ) {
-
if ( is_array( $value[PHPTAGS_STACK_PARAM_2][$aim] ) ) {
-
if ( isset($value[PHPTAGS_STACK_PARAM_2][$aim][$v]) ||
array_key_exists($v, $value[PHPTAGS_STACK_PARAM_2][$aim]) ) {
-
$value[PHPTAGS_STACK_PARAM_2][$aim] =&
$value[PHPTAGS_STACK_PARAM_2][$aim][$v];
-
} else {
-
// PHP Notice: Undefined offset: $1
-
self::pushException( new PhpTagsException(
PhpTagsException::NOTICE_UNDEFINED_INDEX, $v ) );
-
unset( $value[PHPTAGS_STACK_PARAM_2][$aim] );
-
$value[PHPTAGS_STACK_PARAM_2][$aim] = null;
-
}
-
} else {
-
if ( isset( $value[PHPTAGS_STACK_PARAM_2][$aim][$v]) ) {
-
unset( $value[PHPTAGS_STACK_PARAM_2][$aim] );
-
$value[PHPTAGS_STACK_PARAM_2][$aim] =
$value[PHPTAGS_STACK_PARAM_2][$aim][$v];
-
} else {
-
// PHP Notice: Uninitialized string offset: $1
-
self::pushException( new PhpTagsException(
PhpTagsException::NOTICE_UNINIT_STRING_OFFSET, (int)$v ) );
-
unset( $value[PHPTAGS_STACK_PARAM_2][$aim] );
-
$value[PHPTAGS_STACK_PARAM_2][$aim] = null;
-
}
-
}
- }
- }
- } else {
- unset(
$value[PHPTAGS_STACK_PARAM_2][$aim] );
-
$value[PHPTAGS_STACK_PARAM_2][$aim] = null;
-
self::pushException( new PhpTagsException(
PhpTagsException::NOTICE_UNDEFINED_VARIABLE, $value[PHPTAGS_STACK_PARAM] ) );
- }
- break;
- case '?':
- if(
$value[PHPTAGS_STACK_PARAM] ) { // true ?
- if(
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_DO_TRUE] ) { // true ? 1+2 :
-
$memory[] = array( &$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_PARAM], $code,
$codeIndex, $c, $loopsOwner );
- $code =
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_DO_TRUE];
-
$codeIndex = -1;
- $c =
count($code);
-
$loopsOwner = '?';
- }else{ // true
? 1 :
-
$value[PHPTAGS_STACK_RESULT] =
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_PARAM];
- }
- }else{ // false ?
- if(
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_DO_FALSE] ) { // false ? ... : 1+2
-
$memory[] = array( &$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_PARAM_2],
$code, $codeIndex, $c, $loopsOwner );
- $code =
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_DO_FALSE];
-
$codeIndex = -1;
- $c =
count($code);
-
$loopsOwner = '?';
- }else{ // false
? ... : 1
-
$value[PHPTAGS_STACK_RESULT] =
$value[PHPTAGS_STACK_PARAM_2][PHPTAGS_STACK_PARAM_2];
- }
- }
- break;
- case PHPTAGS_T_IF:
- if(
$value[PHPTAGS_STACK_PARAM] ) { // Example: if( true )
- if(
$value[PHPTAGS_STACK_DO_TRUE] ) { // Stack not empty: if(true);
-
$memory[] = array( null, $code, $codeIndex, $c, $loopsOwner );
- $code =
$value[PHPTAGS_STACK_DO_TRUE];
-
$codeIndex = -1;
- $c =
count($code);
-
$loopsOwner = T_IF;
- }
- }else{ // Example: if(
false )
- if(
isset($value[PHPTAGS_STACK_DO_FALSE]) ) { // Stack not empty: if(false) ; else ;
-
$memory[] = array( null, $code, $codeIndex, $c, $loopsOwner );
- $code =
$value[PHPTAGS_STACK_DO_FALSE];
-
$codeIndex = -1;
- $c =
count($code);
-
$loopsOwner = T_IF;
- }
- }
- break;
- case PHPTAGS_T_FOREACH:
- if (
!is_array($value[PHPTAGS_STACK_PARAM]) ) {
-
self::pushException( new PhpTagsException(
PhpTagsException::WARNING_INVALID_ARGUMENT_FOR_FOREACH, null ) );
- break; // ****
EXIT ****
- }
- reset(
$value[PHPTAGS_STACK_PARAM] );
- // break is not
necessary here
- case PHPTAGS_T_WHILE: // PHP
code "while($foo) { ... }" doing as T_WHILE { T_DO($foo) ... }. If $foo ==
false, T_DO doing as T_BREAK
- $memory[] = array(
null, $code, $codeIndex, $c, $loopsOwner );
- $code =
$value[PHPTAGS_STACK_DO_TRUE];
- $codeIndex = -1;
- $c = count($code);
- $loopsOwner = T_WHILE;
- break;
- case PHPTAGS_T_AS:
- if (
!is_array($value[PHPTAGS_STACK_RESULT]) ) {
-
self::pushException( new PhpTagsException(
PhpTagsException::WARNING_INVALID_ARGUMENT_FOR_FOREACH, null ) );
- break; // ****
EXIT ****
- }
- if (
isset($value[PHPTAGS_STACK_PARAM_2]) ) { // T_DOUBLE_ARROW Example: while (
$foo as $key=>$value )
- if (
!list($thisVariables[ $value[PHPTAGS_STACK_PARAM] ], $thisVariables[
$value[PHPTAGS_STACK_PARAM_2] ]) = each($value[PHPTAGS_STACK_RESULT]) ) {
- break
2; // go to one level down
- }
- } else { // Example:
while ( $foo as $value )
- if (
!list(,$thisVariables[ $value[PHPTAGS_STACK_PARAM] ]) =
each($value[PHPTAGS_STACK_RESULT]) ) {
- break
2; // go to one level down
- }
- }
- break;
- case PHPTAGS_T_BREAK:
- $break =
$value[PHPTAGS_STACK_RESULT];
- if( $loopsOwner ==
T_WHILE ) {
- $break--;
- }
- break 2; // go to one
level down
- case PHPTAGS_T_CONTINUE:
- if( self::$loopsLimit--
<= 0 ) {
- throw new
PhpTagsException( PhpTagsException::FATAL_LOOPS_LIMIT_REACHED, null,
$value[PHPTAGS_STACK_TOKEN_LINE], $place );
- }
- $break =
$value[PHPTAGS_STACK_RESULT]-1;
- if( $loopsOwner ==
T_WHILE && $break == 0 ) { // Example: while(true) continue;
- $codeIndex = -1;
- break;
- }
- $continue = true;
- break 2; // go to one
level down
- case PHPTAGS_T_ARRAY:
// array
- $tmp =
$value[PHPTAGS_STACK_PARAM][0];
- $i = 1;
- foreach (
$value[PHPTAGS_STACK_PARAM_2] as $t ) {
- list ( $k, $v )
= $t;
- $tmp[$k] = $v;
- if (
isset($value[PHPTAGS_STACK_PARAM][$i]) ) {
- foreach
( $value[PHPTAGS_STACK_PARAM][$i] as $n ) {
-
$tmp[] = $n;
- }
- }
- $i++;
- }
-
$value[PHPTAGS_STACK_RESULT] = $tmp;
- break;
- case PHPTAGS_T_STATIC:
- $vn =
$value[PHPTAGS_STACK_PARAM]; // variable name
- if(
!isset(self::$staticVariables[$place]) || !array_key_exists($vn,
self::$staticVariables[$place]) ) {
-
self::$staticVariables[$place][$vn] = &$value[PHPTAGS_STACK_RESULT];
- if(
$value[PHPTAGS_STACK_DO_TRUE] ) {
-
//self::$staticVariables[$p][$vn] = null;
-
$memory[] = array( null, $code, $codeIndex, $c, $loopsOwner );
- $code =
$value[PHPTAGS_STACK_DO_TRUE];
-
$codeIndex = -1;
- $c =
count($code);
-
$loopsOwner = T_STATIC;
- }
- }
- $thisVariables[$vn] =
&self::$staticVariables[$place][$vn];
- break;
- case PHPTAGS_T_GLOBAL:
- foreach(
$value[PHPTAGS_STACK_PARAM] as $vn ) { // variable names
- if(
!array_key_exists($vn, self::$globalVariables) ) {
-
self::$globalVariables[$vn] = null;
- }
-
$thisVariables[$vn] = &self::$globalVariables[$vn];
- }
- break;
- case PHPTAGS_T_HOOK_CHECK_PARAM:
- $i =
$value[PHPTAGS_STACK_AIM];
- $reference_info =
Hooks::getReferenceInfo(
- $i, //
ordinal number of the argument, zero is first
-
$value[PHPTAGS_STACK_HOOK_TYPE],
-
$value[PHPTAGS_STACK_PARAM], // name of function or method
-
$value[PHPTAGS_STACK_PARAM_3] === false ? false :
$value[PHPTAGS_STACK_PARAM_3][PHPTAGS_STACK_PARAM_3] // $object or false
- );
-
- if (
$value[PHPTAGS_STACK_PARAM_2] === true && $reference_info === false ) {
- // Param is
variable and it needs to clone
- $t =
$value[PHPTAGS_STACK_RESULT][$i];
- unset(
$value[PHPTAGS_STACK_RESULT][$i] );
-
$value[PHPTAGS_STACK_RESULT][$i] = $t;
- } elseif (
$value[PHPTAGS_STACK_PARAM_2] === false && $reference_info === true ) {
- // Param is not
variable and it's need reference
- throw new
PhpTagsException( PhpTagsException::FATAL_VALUE_PASSED_BY_REFERENCE, null,
$value[PHPTAGS_STACK_TOKEN_LINE], $place );
- }
- break;
- case PHPTAGS_T_HOOK:
- $result =
Hooks::callHook(
-
$value[PHPTAGS_STACK_HOOK_TYPE],
-
$value[PHPTAGS_STACK_PARAM_2], // arguments
-
$value[PHPTAGS_STACK_PARAM], // name of function or method
-
$value[PHPTAGS_STACK_PARAM_3] // $object or false
- );
-
- if ( $result instanceof
outPrint ) {
-
$value[PHPTAGS_STACK_RESULT] = $result->returnValue;
- $return[] =
$result;
- } else {
-
$value[PHPTAGS_STACK_RESULT] = $result;
- }
- if (
is_object($value[PHPTAGS_STACK_RESULT]) && !($value[PHPTAGS_STACK_RESULT]
instanceof iRawOutput || $value[PHPTAGS_STACK_RESULT] instanceof GenericObject)
) {
- // @todo
-
$value[PHPTAGS_STACK_RESULT] = null;
-
self::pushException( new PhpTagsException(
PhpTagsException::WARNING_RETURNED_INVALID_VALUE, $value[PHPTAGS_STACK_PARAM] )
);
- }
- break;
- case PHPTAGS_T_NEW:
-
$value[PHPTAGS_STACK_RESULT] = Hooks::createObject(
$value[PHPTAGS_STACK_PARAM_2], $value[PHPTAGS_STACK_PARAM_3] );
- break;
- case PHPTAGS_T_UNSET:
- foreach (
$value[PHPTAGS_STACK_PARAM] as $val ) {
- $vn =
$val[PHPTAGS_STACK_PARAM]; // Variable Name
- if (
isset($thisVariables[$vn]) || array_key_exists($vn, $thisVariables) ) { //
defined variable
- if (
isset($val[PHPTAGS_STACK_ARRAY_INDEX]) ) { // There is array index. Example:
unset($foo[0])
-
$ref = &$thisVariables[$vn];
-
$tmp = array_pop( $val[PHPTAGS_STACK_ARRAY_INDEX] );
-
foreach ( $val[PHPTAGS_STACK_ARRAY_INDEX] as $v ) {
-
if ( is_string($ref) ) {
-
throw new PhpTagsException(
PhpTagsException::FATAL_CANNOT_UNSET_STRING_OFFSETS, null,
$value[PHPTAGS_STACK_TOKEN_LINE], $place );
-
} elseif ( !isset($ref[$v]) ) { // undefined array index not for string
-
continue 2;
-
}
-
$ref = &$ref[$v];
-
}
-
if ( is_array($ref) ) {
-
unset( $ref[$tmp] );
-
} else {
-
throw new PhpTagsException(
PhpTagsException::FATAL_CANNOT_UNSET_STRING_OFFSETS, null,
$value[PHPTAGS_STACK_TOKEN_LINE], $place );
-
}
- }else{
// There is no array index. Example: unset($foo)
-
unset( $thisVariables[$vn] );
- }
- } elseif (
isset($val[PHPTAGS_STACK_ARRAY_INDEX]) ) { // undefined variable with array
index. Example: unset($foo[1])
-
self::pushException( new PhpTagsException( PHPTAGS_NOTICE_UNDEFINED_VARIABLE,
$vn ) );
- }
- }
- break;
- case PHPTAGS_T_ISSET:
-
foreach($value[PHPTAGS_STACK_PARAM] as $val) {
- if(
!isset($thisVariables[ $val[PHPTAGS_STACK_PARAM] ]) ) { // undefined variable
or variable is null
-
$value[PHPTAGS_STACK_RESULT] = false;
- break 2;
- } // true,
variable is defined
- if(
isset($val[PHPTAGS_STACK_ARRAY_INDEX]) ) { // Example: isset($foo[1])
- $ref =
&$thisVariables[ $val[PHPTAGS_STACK_PARAM] ];
- $tmp =
array_pop( $val[PHPTAGS_STACK_ARRAY_INDEX] );
-
foreach( $val[PHPTAGS_STACK_ARRAY_INDEX] as $v ) {
-
if( !isset($ref[$v]) ) { // undefined array index
-
$value[PHPTAGS_STACK_RESULT] = false;
-
break 3;
-
}
-
$ref = &$ref[$v];
- }
- //
@todo ->>>>>>>>>>>> |
************************************************************* | <<<<< it only
for compatible with PHP 5.4 if used PHP 5.3 @see
http://www.php.net/manual/en/function.isset.php Example #2 isset() on String
Offsets
- if(
!isset($ref[$tmp]) || (is_string($ref) && is_string($tmp ) && $tmp !=
(string)(int)$tmp ) ) {
-
$value[PHPTAGS_STACK_RESULT] = false;
-
break 2;
- }
- } // true,
variable is defined and have no array index
- }
-
$value[PHPTAGS_STACK_RESULT] = true;
- break;
- case PHPTAGS_T_EMPTY:
-
foreach($value[PHPTAGS_STACK_PARAM] as $val) {
- if(
!array_key_exists($val[PHPTAGS_STACK_PARAM], $thisVariables) ) { // undefined
variable
-
continue;
- }
- $ref =
&$thisVariables[ $val[PHPTAGS_STACK_PARAM] ];
- if(
isset($val[PHPTAGS_STACK_ARRAY_INDEX]) ) { // Example: empty($foo[1])
- $tmp =
array_pop( $val[PHPTAGS_STACK_ARRAY_INDEX] );
-
foreach( $val[PHPTAGS_STACK_ARRAY_INDEX] as $v ) {
-
if( !isset($ref[$v]) ) { // undefined array index
-
continue 2;
-
}
-
$ref = &$ref[$v];
- }
- //
@todo ->>>>>>>>>>>> |
************************************************************* | <<<<< it only
for compatible with PHP 5.4 if used PHP 5.3 @see
http://www.php.net/manual/en/function.empty.php Example #2 empty() on String
Offsets
- if(
!empty($ref[$tmp]) && (is_array($ref) || !is_string( $tmp ) || $tmp ==
(string)(int)$tmp ) ) {
-
$value[PHPTAGS_STACK_RESULT] = false;
-
break 2;
- }
- }elseif(
!empty($ref) ) { // there is no array index and empty() returns false (PHP
5.5.0 supports expressions)
-
$value[PHPTAGS_STACK_RESULT] = false;
- break 2;
- }
- }
-
$value[PHPTAGS_STACK_RESULT] = true;
- break;
- case PHPTAGS_T_RETURN:
- if ( $return ) {
- return new
PhpTagsException();
- }
- return
$value[PHPTAGS_STACK_PARAM];
- case PHPTAGS_T_COPY:
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM];
- break;
- case '@':
- if (
$value[PHPTAGS_STACK_PARAM] === true ) {
- $exceptions =
false;
- } else {
- $exceptions =
array();
- }
- break;
- default: // ++, --, =, +=, -=,
*=, etc...
- $variable =
&$value[PHPTAGS_STACK_PARAM];
- $variableName =
$variable[PHPTAGS_STACK_PARAM];
- if (
$variable[PHPTAGS_STACK_COMMAND] == PHPTAGS_T_LIST ) { // this is T_LIST.
Example: list($foo, $bar) = $array;
- self::fillList(
$value[PHPTAGS_STACK_PARAM_2], $variable, $thisVariables );
-
$value[PHPTAGS_STACK_RESULT] = $value[PHPTAGS_STACK_PARAM_2];
- unset(
$variable );
- break; /****
EXIT ****/
- }
- if(
!(isset($thisVariables[$variableName]) || array_key_exists($variableName,
$thisVariables)) ) { // Use undefined variable
- if(
isset($value[PHPTAGS_STACK_ARRAY_INDEX]) ) { // Example: $foo[1]++
-
$thisVariables[$variableName] = array();
- }else{
-
$thisVariables[$variableName] = null;
- }
- if(
$value[PHPTAGS_STACK_COMMAND] != '=' ) {
-
self::pushException( new PhpTagsException(
PhpTagsException::NOTICE_UNDEFINED_VARIABLE, $variableName ) );
- }
- }
- $ref =
&$thisVariables[$variableName];
- if (
isset($variable[PHPTAGS_STACK_ARRAY_INDEX]) ) { // Example: $foo[1]++
- foreach (
$variable[PHPTAGS_STACK_ARRAY_INDEX] as $v ) {
- if ( $v
=== INF ) { // Example: $foo[]
-
$t = null;
-
$ref[] = &$t;
-
$ref = &$t;
-
unset( $t );
- } else {
-
if ( $ref === null ) {
-
if( $value[PHPTAGS_STACK_COMMAND] != '=' ) {
-
// PHP Notice: Undefined offset: $1
-
self::pushException( new PhpTagsException(
PhpTagsException::NOTICE_UNDEFINED_OFFSET, $v[PHPTAGS_STACK_RESULT] ) );
-
}
-
$ref[$v] = null;
-
$ref = &$ref[$v];
-
} elseif ( is_array($ref) ) {
-
if ( !( isset($ref[$v]) || array_key_exists($v, $ref) ) ) {
-
$ref[$v] = null;
-
if( $value[PHPTAGS_STACK_COMMAND] != '=' ) {
-
// PHP Notice: Undefined offset: $1
-
self::pushException( new PhpTagsException(
PhpTagsException::NOTICE_UNDEFINED_INDEX, $v ) );
-
}
-
}
-
$ref = &$ref[$v];
-
} elseif ( is_string($ref) ) {
-
// PHP Fatal error: Cannot use string offset as an array
-
throw new PhpTagsException( PhpTagsException::NOTICE_UNDEFINED_OFFSET,
$v, $value[PHPTAGS_STACK_TOKEN_LINE], $place );
-
} else {
-
self::pushException( new PhpTagsException(
PhpTagsException::FATAL_STRING_OFFSET_AS_ARRAY, $v ) );
-
unset( $variable );
-
break 2;
-
// PHP Warning: Cannot use a scalar value as an array
-
}
- }
- }
- }
- switch (
$value[PHPTAGS_STACK_COMMAND] ) {
- case
PHPTAGS_T_INC:
- if (
$value[PHPTAGS_STACK_PARAM_2] ) { // $foo++
-
$value[PHPTAGS_STACK_RESULT] = $ref++;
- }else{
// ++$foo
-
$value[PHPTAGS_STACK_RESULT] = ++$ref;
- }
- break;
- case
PHPTAGS_T_DEC:
- if (
$value[PHPTAGS_STACK_PARAM_2] ) { // $foo--
-
$value[PHPTAGS_STACK_RESULT] = $ref--;
- }else{
// --$foo
-
$value[PHPTAGS_STACK_RESULT] = --$ref;
- }
- break;
- case '=':
-
$value[PHPTAGS_STACK_RESULT] = $ref = $value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_CONCAT_EQUAL: // .=
-
$value[PHPTAGS_STACK_RESULT] = $ref .= $value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_PLUS_EQUAL: // +=
-
$value[PHPTAGS_STACK_RESULT] = $ref += $value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_MINUS_EQUAL: // -=
-
$value[PHPTAGS_STACK_RESULT] = $ref -= $value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_MUL_EQUAL: // *=
-
$value[PHPTAGS_STACK_RESULT] = $ref *= $value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_DIV_EQUAL: // /=
-
$value[PHPTAGS_STACK_RESULT] = $ref /= $value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_MOD_EQUAL: // %=
-
$value[PHPTAGS_STACK_RESULT] = $ref %= $value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_AND_EQUAL: // &=
-
$value[PHPTAGS_STACK_RESULT] = $ref &= $value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_OR_EQUAL: // |=
-
$value[PHPTAGS_STACK_RESULT] = $ref |= $value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_XOR_EQUAL: // ^=
-
$value[PHPTAGS_STACK_RESULT] = $ref ^= $value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_SL_EQUAL: // <<=
-
$value[PHPTAGS_STACK_RESULT] = $ref <<= $value[PHPTAGS_STACK_PARAM_2];
- break;
- case
PHPTAGS_T_SR_EQUAL: // >>=
-
$value[PHPTAGS_STACK_RESULT] = $ref >>= $value[PHPTAGS_STACK_PARAM_2];
- break;
- }
- break;
- }
- if ( $exceptions ) {
- foreach ( $exceptions as $exc )
{
- $exc->tokenLine =
$value[PHPTAGS_STACK_TOKEN_LINE];
- $exc->place = $place;
- $return[] = (string)
$exc;
- }
- $exceptions = array();
- self::addRuntimeErrorCategory();
- }
- }
- } while( list($code[$codeIndex][PHPTAGS_STACK_RESULT],
$code, $codeIndex, $c, $loopsOwner) = array_pop($memory) );
+ } while(
list($runCode[$runIndex][PHPTAGS_STACK_RESULT], $runCode, $runIndex, $c,
$loopsOwner) = array_pop($memory) );
} catch ( PhpTagsException $e ) {
- $e->tokenLine = $value[PHPTAGS_STACK_TOKEN_LINE];
- $e->place = $place;
- if ( $exceptions ) {
- foreach ( $exceptions as $exc ) {
- $exc->tokenLine =
$value[PHPTAGS_STACK_TOKEN_LINE];
- $exc->place = $place;
- $return[] = (string) $exc;
- }
+ if ( self::$ignoreErrors ) {
+ self::$ignoreErrors = false;
+ } else {
+ $e->tokenLine =
$value[PHPTAGS_STACK_TOKEN_LINE];
+ $e->place = self::$place;
+ self::addRuntimeErrorCategory();
+ self::$return[] = (string) $e;
}
- $exceptions = array();
- self::addRuntimeErrorCategory();
- $return[] = (string) $e;
$value[PHPTAGS_STACK_RESULT] = null;
} catch ( \Exception $e ) {
- $exceptions = array();
self::addRuntimeErrorCategory();
restore_error_handler();
throw $e;
}
restore_error_handler();
- return $return;
+ return self::$return;
}
- private static function fillList( &$values, &$param, &$thisVariables ) {
+ static function fillList( &$values, &$parametrs, &$thisVariables ) {
$return = array();
- foreach ( $param[PHPTAGS_STACK_PARAM] as $key => $val ) {
- if( $val !== null ) { // skip emty params. Example:
list(, $bar) = $array;
- if( $val[PHPTAGS_STACK_COMMAND] ==
PHPTAGS_T_LIST ) { // T_LIST inside other T_LIST. Example: list($a, list($b,
$c)) = array(1, array(2, 3));
- if ( is_array($values) &&
isset($values[$key]) ) {
- $return[$key] =
self::fillList($values[$key], $val, $thisVariables);
- } else {
- static $a=array();
- $return[$key] =
self::fillList($a, $val, $thisVariables);
- }
- continue;
- }
- $ref = &$thisVariables[
$val[PHPTAGS_STACK_PARAM] ];
- if ( isset($val[PHPTAGS_STACK_ARRAY_INDEX]) ) {
// Example: list($foo[0], $foo[1]) = $array;
- foreach (
$val[PHPTAGS_STACK_ARRAY_INDEX] as $v ) {
- if ( $v === INF ) { //
Example: $foo[]
- $t = null;
- $ref[] = &$t;
- $ref = &$t;
- unset( $t );
- } else {
- if ( !isset($ref[$v]) )
{
- $ref[$v] = null;
- }
- $ref = &$ref[$v];
- }
- }
- }
- if ( is_array($values) ) {
- if ( isset($values[$key]) ) {
- $ref = $values[$key];
- } else {
- $ref = null;
- // @todo E_NOTICE
- }
- } else { // list() work with array only
- $ref = null;
- }
- $return[$key] = $ref;
+
+ for ( $pkey = count( $parametrs ) - 1; $pkey >= 0; --$pkey ) {
+ $param = $parametrs[$pkey];
+ if ( $param === null ) { // skip emty params. Example:
list(, $bar) = $array;
+ continue;
}
+ if( $param[PHPTAGS_STACK_COMMAND] == PHPTAGS_T_LIST ) {
// T_LIST inside other T_LIST. Example: list($a, list($b, $c)) = array(1,
array(2, 3));
+ if ( is_array($values) && isset($values[$pkey])
) {
+ $return[$pkey] =
self::fillList($values[$pkey], $param[PHPTAGS_STACK_PARAM], $thisVariables);
+ } else {
+ static $emptyArray=array();
+ $return[$pkey] =
self::fillList($emptyArray, $param[PHPTAGS_STACK_PARAM], $thisVariables);
+ }
+ continue;
+ }
+ // $param is variable
+ $ref = &$thisVariables[ $param[PHPTAGS_STACK_PARAM] ];
+ if ( isset($param[PHPTAGS_STACK_ARRAY_INDEX]) ) { //
Example: list($foo[0], $foo[1]) = $array;
+ foreach ( $param[PHPTAGS_STACK_ARRAY_INDEX] as
$v ) {
+ if ( $v === INF ) { // Example: $foo[]
+ $t = null;
+ $ref[] = &$t;
+ $ref = &$t;
+ unset( $t );
+ } else {
+ if ( !isset($ref[$v]) ) {
+ $ref[$v] = null;
+ }
+ $ref = &$ref[$v];
+ }
+ }
+ }
+ if ( is_array($values) ) {
+ if ( isset($values[$pkey]) ||
array_key_exists($pkey, $values) ) {
+ $ref = $values[$pkey];
+ } else {
+ $ref = null;
+ Runtime::pushException( new
PhpTagsException( PhpTagsException::NOTICE_UNDEFINED_OFFSET, $pkey ) );
+ }
+ } else { // list() work with array only
+ $ref = null;
+ }
+ $return[$pkey] = $ref;
}
}
@@ -793,13 +1399,15 @@
}
public static function pushException( PhpTagsException $exc ) {
- if ( self::$exceptions !== false ) {
- self::$exceptions[] = $exc;
+ if ( self::$ignoreErrors === false ) {
+ $exc->tokenLine =
self::$running[self::$runIndex][PHPTAGS_STACK_TOKEN_LINE];
+ $exc->place = self::$place;
+ self::$return[] = (string) $exc;
}
}
public static function getExceptions() {
- return self::$exceptions;
+ return false;
}
public static function getVariables() {
--
To view, visit https://gerrit.wikimedia.org/r/191858
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Idbfcca925f6668a6d1ec9810e6f8c1df75c31c58
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/PhpTags
Gerrit-Branch: master
Gerrit-Owner: Pastakhov <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits