summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2013-11-03 01:58:39 +0100
committerBob Weinand <bobwei9@hotmail.com>2013-11-03 01:58:39 +0100
commitad967e1329ce25e80f485f77be1478f3676b9a37 (patch)
tree1b93787b779604d64bab54713e4d5b99c3bcc7c7
parent82cd3779f4644a903b6dbbc966e72ebc54c9d694 (diff)
downloadphp-git-ad967e1329ce25e80f485f77be1478f3676b9a37.tar.gz
Added a few more operators
-rw-r--r--Zend/tests/constant_expressions.phpt46
-rw-r--r--Zend/zend_compile.h4
-rw-r--r--Zend/zend_language_parser.y37
-rw-r--r--Zend/zend_operators.c40
-rw-r--r--Zend/zend_operators.h2
5 files changed, 115 insertions, 14 deletions
diff --git a/Zend/tests/constant_expressions.phpt b/Zend/tests/constant_expressions.phpt
index 441b9a6f2a..7dea0d83f7 100644
--- a/Zend/tests/constant_expressions.phpt
+++ b/Zend/tests/constant_expressions.phpt
@@ -14,12 +14,26 @@ This is a test string
ENDOFSTRING;
const T_9 = ~-1;
const T_10 = (-1?:1) + (0?2:3);
+const T_11 = 1 && 0;
+const T_12 = 1 and 1;
+const T_13 = 0 || 0;
+const T_14 = 1 or 0;
+const T_15 = 1 xor 1;
+const T_16 = 1 xor 0;
+const T_17 = 1 < 0;
+const T_18 = 0 <= 0;
+const T_19 = 1 > 0;
+const T_20 = 1 >= 0;
+const T_21 = 1 === 1;
+const T_22 = 1 !== 1;
+const T_23 = 0 != "0";
+const T_24 = 1 == "1";
// Test order of operations
-const T_11 = 1 + 2 * 3;
+const T_25 = 1 + 2 * 3;
// Test for memory leaks
-const T_12 = "1" + 2 + "3";
+const T_26 = "1" + 2 + "3";
var_dump(T_1);
var_dump(T_2);
@@ -33,6 +47,20 @@ var_dump(T_9);
var_dump(T_10);
var_dump(T_11);
var_dump(T_12);
+var_dump(T_13);
+var_dump(T_14);
+var_dump(T_15);
+var_dump(T_16);
+var_dump(T_17);
+var_dump(T_18);
+var_dump(T_19);
+var_dump(T_20);
+var_dump(T_21);
+var_dump(T_22);
+var_dump(T_23);
+var_dump(T_24);
+var_dump(T_25);
+var_dump(T_26);
?>
--EXPECT--
int(2)
@@ -45,5 +73,19 @@ int(8)
string(21) "This is a test string"
int(0)
int(2)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(true)
int(7)
int(6)
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index bbc6e47383..b80a7cb84f 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -722,6 +722,10 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC);
#define ZEND_OP_DATA 137
+/* Pseudo-opcodes for internal object overloading */
+#define ZEND_BOOL_AND -1
+#define ZEND_BOOL_OR -2
+
/* END: OPCODES */
/* class fetches */
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index af00f2ef4a..65e3e0ce3c 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -970,23 +970,36 @@ static_scalar_value:
static_operation:
static_scalar_value '+' static_scalar_value { zend_ast_add_binary(&$$.u.constant, add_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
- | static_scalar_value '-' static_scalar_value { zend_ast_add_binary(&$$.u.constant, sub_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value '-' static_scalar_value { zend_ast_add_binary(&$$.u.constant, sub_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
| static_scalar_value '*' static_scalar_value { zend_ast_add_binary(&$$.u.constant, mul_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
- | static_scalar_value '/' static_scalar_value { zend_ast_add_binary(&$$.u.constant, div_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
- | static_scalar_value '%' static_scalar_value { zend_ast_add_binary(&$$.u.constant, mod_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
- | '!' static_scalar_value { zend_ast_add_unary(&$$.u.constant, boolean_not_function, &$2.u.constant TSRMLS_CC); }
- | '~' static_scalar_value { zend_ast_add_unary(&$$.u.constant, bitwise_not_function, &$2.u.constant TSRMLS_CC); }
- | static_scalar_value '|' static_scalar_value { zend_ast_add_binary(&$$.u.constant, bitwise_or_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
- | static_scalar_value '&' static_scalar_value { zend_ast_add_binary(&$$.u.constant, bitwise_and_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
- | static_scalar_value '^' static_scalar_value { zend_ast_add_binary(&$$.u.constant, bitwise_xor_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
- | static_scalar_value T_SL static_scalar_value { zend_ast_add_binary(&$$.u.constant, shift_left_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
- | static_scalar_value T_SR static_scalar_value { zend_ast_add_binary(&$$.u.constant, shift_right_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
- | static_scalar_value '.' static_scalar_value { zend_ast_add_binary(&$$.u.constant, concat_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value '/' static_scalar_value { zend_ast_add_binary(&$$.u.constant, div_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value '%' static_scalar_value { zend_ast_add_binary(&$$.u.constant, mod_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | '!' static_scalar_value { zend_ast_add_unary(&$$.u.constant, boolean_not_function, &$2.u.constant TSRMLS_CC); }
+ | '~' static_scalar_value { zend_ast_add_unary(&$$.u.constant, bitwise_not_function, &$2.u.constant TSRMLS_CC); }
+ | static_scalar_value '|' static_scalar_value { zend_ast_add_binary(&$$.u.constant, bitwise_or_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value '&' static_scalar_value { zend_ast_add_binary(&$$.u.constant, bitwise_and_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value '^' static_scalar_value { zend_ast_add_binary(&$$.u.constant, bitwise_xor_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_SL static_scalar_value { zend_ast_add_binary(&$$.u.constant, shift_left_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_SR static_scalar_value { zend_ast_add_binary(&$$.u.constant, shift_right_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value '.' static_scalar_value { zend_ast_add_binary(&$$.u.constant, concat_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_LOGICAL_XOR static_scalar_value { zend_ast_add_binary(&$$.u.constant, boolean_xor_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_LOGICAL_AND static_scalar_value { zend_ast_add_binary(&$$.u.constant, boolean_and_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_LOGICAL_OR static_scalar_value { zend_ast_add_binary(&$$.u.constant, boolean_or_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_BOOLEAN_AND static_scalar_value { zend_ast_add_binary(&$$.u.constant, boolean_and_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_BOOLEAN_OR static_scalar_value { zend_ast_add_binary(&$$.u.constant, boolean_or_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_IS_IDENTICAL static_scalar_value { zend_ast_add_binary(&$$.u.constant, is_identical_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_IS_NOT_IDENTICAL static_scalar_value { zend_ast_add_binary(&$$.u.constant, is_not_identical_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_IS_EQUAL static_scalar_value { zend_ast_add_binary(&$$.u.constant, is_equal_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_IS_NOT_EQUAL static_scalar_value { zend_ast_add_binary(&$$.u.constant, is_not_equal_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value '<' static_scalar_value { zend_ast_add_binary(&$$.u.constant, is_smaller_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value '>' static_scalar_value { zend_ast_add_binary(&$$.u.constant, is_smaller_function, &$3.u.constant, &$1.u.constant TSRMLS_CC); }
+ | static_scalar_value T_IS_SMALLER_OR_EQUAL static_scalar_value { zend_ast_add_binary(&$$.u.constant, is_smaller_or_equal_function, &$1.u.constant, &$3.u.constant TSRMLS_CC); }
+ | static_scalar_value T_IS_GREATER_OR_EQUAL static_scalar_value { zend_ast_add_binary(&$$.u.constant, is_smaller_or_equal_function, &$3.u.constant, &$1.u.constant TSRMLS_CC); }
| static_scalar_value '?' ':' static_scalar_value { zend_ast_add_ternary(&$$.u.constant, ternary_function, &$1.u.constant, NULL, &$4.u.constant TSRMLS_CC); }
| static_scalar_value '?' static_scalar_value ':' static_scalar_value { zend_ast_add_ternary(&$$.u.constant, ternary_function, &$1.u.constant, &$3.u.constant, &$5.u.constant TSRMLS_CC); }
| '+' static_scalar_value { ZVAL_LONG(&$1.u.constant, 0); zend_ast_add_binary(&$$.u.constant, add_function, &$1.u.constant, &$2.u.constant TSRMLS_CC); }
| '-' static_scalar_value { ZVAL_LONG(&$1.u.constant, 0); zend_ast_add_binary(&$$.u.constant, sub_function, &$1.u.constant, &$2.u.constant TSRMLS_CC); }
- | '(' static_scalar_value ')' { $$ = $2; }
+ | '(' static_scalar_value ')' { $$ = $2; }
;
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 53a84de155..8c083542f0 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -1082,6 +1082,46 @@ ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
}
/* }}} */
+ZEND_API int boolean_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
+{
+ zval op1_copy, op2_copy;
+ long op1_lval;
+
+ if (Z_TYPE_P(op1) != IS_BOOL || Z_TYPE_P(op2) != IS_BOOL) {
+ ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BOOL_AND);
+
+ zendi_convert_to_boolean(op1, op1_copy, result);
+ op1_lval = Z_LVAL_P(op1);
+ zendi_convert_to_boolean(op2, op2_copy, result);
+ } else {
+ op1_lval = Z_LVAL_P(op1);
+ }
+
+ ZVAL_BOOL(result, op1_lval & Z_LVAL_P(op2));
+ return SUCCESS;
+}
+/* }}} */
+
+ZEND_API int boolean_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
+{
+ zval op1_copy, op2_copy;
+ long op1_lval;
+
+ if (Z_TYPE_P(op1) != IS_BOOL || Z_TYPE_P(op2) != IS_BOOL) {
+ ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BOOL_OR);
+
+ zendi_convert_to_boolean(op1, op1_copy, result);
+ op1_lval = Z_LVAL_P(op1);
+ zendi_convert_to_boolean(op2, op2_copy, result);
+ } else {
+ op1_lval = Z_LVAL_P(op1);
+ }
+
+ ZVAL_BOOL(result, op1_lval | Z_LVAL_P(op2));
+ return SUCCESS;
+}
+/* }}} */
+
ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
{
zval op1_copy;
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index 79ede57320..3f0fc2ef6a 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -50,6 +50,8 @@ ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
+ZEND_API int boolean_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
+ZEND_API int boolean_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC);
ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC);
ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);