diff --git a/.gitignore b/.gitignore index 999b52e3..10184eb4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /.commit-template +*.swp diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..594e5103 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: php + +php: + - 7.3 + +script: + - REPORT_EXIT_STATUS=1 php ~/.phpenv/versions/$(phpenv version-name)/lib/php/build/run-tests.php -P -c ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini -q -x --show-diff diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0b60901b..d4979574 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,24 @@ ## Contributing to the Specification for PHP We'd love your help in improving, correcting, adding to the specification. -Please [file an issue](https://bugs.php.net/) or [submit a pull request](https://wiki.php.net/vcs/gitworkflow) -at the [spec git repo](https://github.com/php/php-langspec). +Please [file an issue](https://github.com/php/php-langspec/issues) +or [submit a pull request](https://github.com/php/php-langspec/pulls). + +## Generated content + +The grammar listings and table of contents of the specification are automatically +generated. If you want to change the grammar, you need to modify the respective +` -#Specification for PHP +# Specification for PHP Facebook has dedicated all copyright to this specification to the public domain worldwide under the CC0 Public Domain Dedication located at . This specification @@ -9,7 +9,7 @@ is distributed without any warranty. (Initially written in 2014 by Facebook, Inc., July 2014) -**Table of Contents** +**Table of Contents** - [Introduction](01-introduction.md#introduction) - [Conformance](02-conformance.md#conformance) - [Terms and Definitions](03-terms-and-definitions.md#terms-and-definitions) @@ -86,7 +86,6 @@ is distributed without any warranty. - [Names](09-lexical-structure.md#names) - [Keywords](09-lexical-structure.md#keywords) - [Literals](09-lexical-structure.md#literals) - - [General](09-lexical-structure.md#general-2) - [Integer Literals](09-lexical-structure.md#integer-literals) - [Floating-Point Literals](09-lexical-structure.md#floating-point-literals) - [String Literals](09-lexical-structure.md#string-literals) @@ -99,38 +98,37 @@ is distributed without any warranty. - [General](10-expressions.md#general) - [Primary Expressions](10-expressions.md#primary-expressions) - [General](10-expressions.md#general-1) + - [Simple Variable](10-expressions.md#simple-variable) + - [Dereferencable expression](10-expressions.md#dereferencable-expression) + - [Variables](10-expressions.md#variables) + - [Constant Access Expression](10-expressions.md#constant-access-expression) + - [Literals](10-expressions.md#literals) - [Intrinsics](10-expressions.md#intrinsics) - [General](10-expressions.md#general-2) - - [array](10-expressions.md#array) - - [echo](10-expressions.md#echo) - [empty](10-expressions.md#empty) - [eval](10-expressions.md#eval) - [exit/die](10-expressions.md#exitdie) - [isset](10-expressions.md#isset) - - [list](10-expressions.md#list) - - [print](10-expressions.md#print) - - [unset](10-expressions.md#unset) - - [Anonymous Function-Creation](10-expressions.md#anonymous-function-creation) - - [Postfix Operators](10-expressions.md#postfix-operators) - - [General](10-expressions.md#general-3) - - [The `clone` Operator](10-expressions.md#the-clone-operator) + - [Anonymous Function Creation](10-expressions.md#anonymous-function-creation) - [The `new` Operator](10-expressions.md#the-new-operator) - [Array Creation Operator](10-expressions.md#array-creation-operator) - [Subscript Operator](10-expressions.md#subscript-operator) - [Function Call Operator](10-expressions.md#function-call-operator) - - [Member-Selection Operator](10-expressions.md#member-selection-operator) + - [Member Access Operator](10-expressions.md#member-access-operator) + - [Member Call Operator](10-expressions.md#member-call-operator) - [Postfix Increment and Decrement Operators](10-expressions.md#postfix-increment-and-decrement-operators) + - [Prefix Increment and Decrement Operators](10-expressions.md#prefix-increment-and-decrement-operators) + - [Shell Command Operator](10-expressions.md#shell-command-operator) - [Scope-Resolution Operator](10-expressions.md#scope-resolution-operator) - - [Exponentiation Operator](10-expressions.md#exponentiation-operator) + - [The `clone` Operator](10-expressions.md#the-clone-operator) + - [Exponentiation Operator](10-expressions.md#exponentiation-operator) - [Unary Operators](10-expressions.md#unary-operators) - - [General](10-expressions.md#general-4) - - [Prefix Increment and Decrement Operators](10-expressions.md#prefix-increment-and-decrement-operators) + - [General](10-expressions.md#general-3) - [Unary Arithmetic Operators](10-expressions.md#unary-arithmetic-operators) - [Error Control Operator](10-expressions.md#error-control-operator) - - [Shell Command Operator](10-expressions.md#shell-command-operator) - [Cast Operator](10-expressions.md#cast-operator) - - [Variable-Name Creation Operator](10-expressions.md#variable-name-creation-operator) - [`instanceof` Operator](10-expressions.md#instanceof-operator) + - [Logical NOT Operator](10-expressions.md#logical-not-operator) - [Multiplicative Operators](10-expressions.md#multiplicative-operators) - [Additive Operators](10-expressions.md#additive-operators) - [Bitwise Shift Operators](10-expressions.md#bitwise-shift-operators) @@ -141,18 +139,21 @@ is distributed without any warranty. - [Bitwise Inclusive OR Operator](10-expressions.md#bitwise-inclusive-or-operator) - [Logical AND Operator (form 1)](10-expressions.md#logical-and-operator-form-1) - [Logical Inclusive OR Operator (form 1)](10-expressions.md#logical-inclusive-or-operator-form-1) + - [Coalesce Operator](10-expressions.md#coalesce-operator) - [Conditional Operator](10-expressions.md#conditional-operator) - [Assignment Operators](10-expressions.md#assignment-operators) - - [General](10-expressions.md#general-5) + - [General](10-expressions.md#general-4) - [Simple Assignment](10-expressions.md#simple-assignment) + - [list intrinsic](10-expressions.md#list-intrinsic) - [byRef Assignment](10-expressions.md#byref-assignment) - [Compound Assignment](10-expressions.md#compound-assignment) + - [`yield` Operator](10-expressions.md#yield-operator) + - [Print expression](10-expressions.md#print-expression) - [Logical AND Operator (form 2)](10-expressions.md#logical-and-operator-form-2) - [Logical Exclusive OR Operator](10-expressions.md#logical-exclusive-or-operator) - [Logical Inclusive OR Operator (form 2)](10-expressions.md#logical-inclusive-or-operator-form-2) - - [`yield` Operator](10-expressions.md#yield-operator) - [Script Inclusion Operators](10-expressions.md#script-inclusion-operators) - - [General](10-expressions.md#general-6) + - [General](10-expressions.md#general-5) - [The `include` Operator](10-expressions.md#the-include-operator) - [The `include_once` Operator](10-expressions.md#the-include_once-operator) - [The `require` Operator](10-expressions.md#the-require-operator) @@ -182,6 +183,8 @@ is distributed without any warranty. - [The `throw` Statement](11-statements.md#the-throw-statement) - [The `try` Statement](11-statements.md#the-try-statement) - [The `declare` Statement](11-statements.md#the-declare-statement) + - [The `echo` Statement](11-statements.md#the-echo-statement) + - [The `unset` Statement](11-statements.md#the-unset-statement) - [Arrays](12-arrays.md#arrays) - [General](12-arrays.md#general) - [Array Creation and Initialization](12-arrays.md#array-creation-and-initialization) @@ -190,6 +193,8 @@ is distributed without any warranty. - [General](13-functions.md#general) - [Function Calls](13-functions.md#function-calls) - [Function Definitions](13-functions.md#function-definitions) + - [Return typing](13-functions.md#return-typing) + - [Type check modes](13-functions.md#type-check-modes) - [Variable Functions](13-functions.md#variable-functions) - [Anonymous Functions](13-functions.md#anonymous-functions) - [Classes](14-classes.md#classes) @@ -224,6 +229,13 @@ is distributed without any warranty. - [Class `Generator`](14-classes.md#class-generator) - [Class `__PHP_Incomplete_Class`](14-classes.md#class-__php_incomplete_class) - [Class `stdClass`](14-classes.md#class-stdclass) + - [Predefined Error Classes](14-classes.md#predefined-error-classes) + - [Class `Error`](14-classes.md#class-error) + - [Class `ArithmeticError`](14-classes.md#class-arithmeticerror) + - [Class `AssertionError`](14-classes.md#class-assertionerror) + - [Class `DivisionByZeroError`](14-classes.md#class-divisionbyzeroerror) + - [Class `ParseError`](14-classes.md#class-parseerror) + - [Class `TypeError`](14-classes.md#class-typeerror) - [Interfaces](15-interfaces.md#interfaces) - [General](15-interfaces.md#general) - [Interface Declarations](15-interfaces.md#interface-declarations) @@ -234,12 +246,13 @@ is distributed without any warranty. - [Interface `ArrayAccess`](15-interfaces.md#interface-arrayaccess) - [Interface `Iterator`](15-interfaces.md#interface-iterator) - [Interface `IteratorAggregate`](15-interfaces.md#interface-iteratoraggregate) + - [Interface `Throwable`](15-interfaces.md#interface-throwable) - [Interface `Traversable`](15-interfaces.md#interface-traversable) - [Interface `Serializable`](15-interfaces.md#interface--serializable) - [Traits](16-traits.md#traits) - [General](16-traits.md#general) - [Trait Declarations](16-traits.md#trait-declarations) - - [Trait Members](16-traits.md#trait-members) + - [Trait Uses](16-traits.md#trait-uses) - [Exception Handling](17-exception-handling.md#exception-handling) - [General](17-exception-handling.md#general) - [Class `Exception`](17-exception-handling.md#class-exception) @@ -253,49 +266,11 @@ is distributed without any warranty. - [Grammar](19-grammar.md#grammar) - [General](19-grammar.md#general) - [Lexical Grammar](19-grammar.md#lexical-grammar) - - [General](19-grammar.md#general-1) - - [Comments](19-grammar.md#comments) - - [White Space](19-grammar.md#white-space) - - [Tokens](19-grammar.md#tokens) - - [General](19-grammar.md#general-2) - - [Names](19-grammar.md#names) - - [Keywords](19-grammar.md#keywords) - - [Literals](19-grammar.md#literals) - - [General](19-grammar.md#general-3) - - [Integer Literals](19-grammar.md#integer-literals) - - [Floating-Point Literals](19-grammar.md#floating-point-literals) - - [String Literals](19-grammar.md#string-literals) - - [Operators and Punctuators](19-grammar.md#operators-and-punctuators) - [Syntactic Grammar](19-grammar.md#syntactic-grammar) - - [Program Structure](19-grammar.md#program-structure) + - [Basic Concepts](19-grammar.md#basic-concepts) - [Variables](19-grammar.md#variables) - [Expressions](19-grammar.md#expressions) - - [Primary Expressions](19-grammar.md#primary-expressions) - - [Postfix Operators](19-grammar.md#postfix-operators) - - [Unary Operators](19-grammar.md#unary-operators) - - [instanceof Operator](19-grammar.md#instanceof-operator) - - [Multiplicative Operators](19-grammar.md#multiplicative-operators) - - [Additive Operators](19-grammar.md#additive-operators) - - [Bitwise Shift Operators](19-grammar.md#bitwise-shift-operators) - - [Relational Operators](19-grammar.md#relational-operators) - - [Equality Operators](19-grammar.md#equality-operators) - - [Bitwise Logical Operators](19-grammar.md#bitwise-logical-operators) - - [Logical Operators (form 1)](19-grammar.md#logical-operators-form-1) - - [Conditional Operator](19-grammar.md#conditional-operator) - - [Assignment Operators](19-grammar.md#assignment-operators) - - [Logical Operators (form 2)](19-grammar.md#logical-operators-form-2) - - [yield Operator](19-grammar.md#yield-operator) - - [Script Inclusion Operators](19-grammar.md#script-inclusion-operators) - - [Constant Expressions](19-grammar.md#constant-expressions) - [Statements](19-grammar.md#statements) - - [General](19-grammar.md#general-4) - - [Compound Statements](19-grammar.md#compound-statements) - - [Labeled Statements](19-grammar.md#labeled-statements) - - [Expression Statements](19-grammar.md#expression-statements) - - [Iteration Statements](19-grammar.md#iteration-statements) - - [Jump Statements](19-grammar.md#jump-statements) - - [The try Statement](19-grammar.md#the-try-statement) - - [The declare Statement](19-grammar.md#the-declare-statement) - [Functions](19-grammar.md#functions) - [Classes](19-grammar.md#classes) - [Interfaces](19-grammar.md#interfaces) diff --git a/spec/01-introduction.md b/spec/01-introduction.md index c2c29b44..84953ebb 100644 --- a/spec/01-introduction.md +++ b/spec/01-introduction.md @@ -1,4 +1,4 @@ -#Introduction +# Introduction This specification is intended to provide a complete and concise definition of the syntax and semantics of the PHP language, suitable for use by the following: @@ -10,4 +10,3 @@ use by the following: For now, the runtime library has been excluded, as that is documented at [www.php.net](http://www.php.net). However, the document can contain references to the library functions, usually in the form of links to http://www.php.net. - diff --git a/spec/02-conformance.md b/spec/02-conformance.md index e86a0eae..4ab126bb 100644 --- a/spec/02-conformance.md +++ b/spec/02-conformance.md @@ -1,4 +1,4 @@ -#Conformance +# Conformance In this specification, "must" is to be interpreted as a requirement on an implementation or on a program; conversely, "must not" is to be interpreted as a prohibition. @@ -15,7 +15,7 @@ The word "may" indicates "permission", and is never used to mean A *strictly conforming program* must use only those features of the language described in this specification. In particular, it must not -produce output or exhibit behavior dependent on any unspecified, +produce output or exhibit behavior dependent on any unspecified, undefined, or implementation-defined behavior. A *conforming implementation* must accept any strictly conforming @@ -52,4 +52,3 @@ to exist in future revisions. Usually, they are old approaches that have been superseded by new ones, and use of the old approach is discouraged. (Examples of this include the use of braces ({ }) for subscripting, and the use of old-style constructor names). - diff --git a/spec/03-terms-and-definitions.md b/spec/03-terms-and-definitions.md index 46656a5c..ae87eb6b 100644 --- a/spec/03-terms-and-definitions.md +++ b/spec/03-terms-and-definitions.md @@ -1,68 +1,66 @@ -#Terms and Definitions +# Terms and Definitions For the purposes of this document, the following terms and definitions apply:
-
argument
-
a value passed to a function, that is intended to map to a - corresponding parameter.
+
argument
+
a value passed to a function, that is intended to map to a + corresponding parameter.
-
behavior
-
external appearance or action.
+
behavior
+
external appearance or action.
-
behavior, implementation-defined
-
behavior specific to an implementation, where that implementation - must document that behavior.
+
behavior, implementation-defined
+
behavior specific to an implementation, where that implementation + must document that behavior.
-
behavior, undefined
-
behavior which is not guaranteed to produce any specific result. - Usually follows an erroneous program construct or data.
+
behavior, undefined
+
behavior which is not guaranteed to produce any specific result. + Usually follows an erroneous program construct or data.
-
behavior, unspecified
-
behavior for which this specification provides no requirements.
+
behavior, unspecified
+
behavior for which this specification provides no requirements.
-
constraint
-
restriction, either syntactic or semantic, on how language elements - can be used.
+
constraint
+
restriction, either syntactic or semantic, on how language elements + can be used.
-
error, fatal
-
a condition in which the engine cannot continue executing the script - and must terminate.
+
error, fatal
+
a condition in which the engine cannot continue executing the script + and must terminate.
-
error, fatal, catchable
-
a fatal error that can be caught by a user-defined handler.
+
error, fatal, catchable
+
a fatal error that can be caught by a user-defined handler.
-
error, non-fatal
-
an error that is not a fatal error and allows for the engine to - continue execution.
+
error, non-fatal
+
an error that is not a fatal error and allows for the engine to + continue execution.
-
lvalue
-
an expression that designates a location that can store a value.
+
lvalue
+
an expression that designates a location that can store a value.
-
lvalue, modifiable
-
an lvalue whose value can be changed.
+
lvalue, modifiable
+
an lvalue whose value can be changed.
-
lvalue, non-modifiable
-
an lvalue whose value cannot be changed.
+
lvalue, non-modifiable
+
an lvalue whose value cannot be changed.
-
notice
-
an informational message informing user of the code that may not work as intended.
+
notice
+
an informational message informing user of the code that may not work as intended.
-
parameter
-
a variable declared in the parameter list of a function that is - intended to map to a corresponding argument in a call to that - function.
+
parameter
+
a variable declared in the parameter list of a function that is + intended to map to a corresponding argument in a call to that + function.
-
PHP Run-Time Engine
-
the software that executes a PHP program. Referred to as the - Engine throughout this specification.
+
PHP Run-Time Engine
+
the software that executes a PHP program. Referred to as the + Engine throughout this specification.
-
value
-
a primitive unit of data operated by the Engine having a type - and potentially other content depending on the type.
+
value
+
a primitive unit of data operated by the Engine having a type + and potentially other content depending on the type.
Other terms are defined throughout this specification, as needed, with the first usage being typeset *like this*. - - diff --git a/spec/04-basic-concepts.md b/spec/04-basic-concepts.md index fd75894a..6f99d468 100644 --- a/spec/04-basic-concepts.md +++ b/spec/04-basic-concepts.md @@ -1,30 +1,50 @@ -#Basic Concepts -##Program Structure +# Basic Concepts +## Program Structure A PHP *program* consists of one or more source files, known formally as *scripts*. + +
-script:
- script-section
- script   script-section
-
-script-section:
-   textopt start-tag statement-listopt end-tagopt textopt
-
-start-tag:
-  <?php
-  <?=
-  
-end-tag:
-  ?>
-  
-text:
-  arbitrary text not containing any of start-tag sequences
+script:
+   script-section
+   script   script-section
+
+script-section:
+   textopt   start-tag   statement-listopt   end-tagopt   textopt
+
+start-tag:
+   <?php
+   <?=
+
+end-tag:
+   ?>
+
+text:
+   arbitrary text not containing any of   start-tag   sequences
 
All of the sections in a script are treated as though they belonged to one continuous section, except that any intervening text is treated as -though it were a string literal given to the [intrinsic `echo`](10-expressions.md#echo). +though it were a string literal given to the +[`echo` statement](11-statements.md#the-echo-statement). A script can import another script via a [script inclusion operator](10-expressions.md#script-inclusion-operators). @@ -32,16 +52,10 @@ A script can import another script via a [script inclusion operator](10-expressi The top level of a script is simply referred to as the *top level*. -If `` and `` -- `<%` and `%>` +If ` +``` [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *]] | | V V [VStore int 1] [VStore int 3] - +``` In this picture the VSlot in the upper left corner represents the variable `$a`, and it points to a VStore that represents `$a`'s current -value, which is a object. This VStore contains a handle pointing to an -HStore which represents the contents of an object of type Point with two +value, which is a object. This VStore contains a handle pointing to an +HStore which represents the contents of an object of type Point with two instance properties `$x` and `$y`. The HStore contains two VSlots representing instance properties `$x` and `$y`, and each of these VSlots points to a distinct VStore which contains an integer value. @@ -243,23 +258,23 @@ of which (except `unset`) use the & punctuator: - [byRef value in a foreach statement](11-statements.md#the-foreach-statement). - [byRef initializer for an array element](10-expressions.md#array-creation-operator). - [byRef variable-use list in an anonymous function](10-expressions.md#anonymous-function-creation). -- [unset](10-expressions.md#unset). +- [unset](11-statements.md#the-unset-statement). -###Reclamation and Automatic Memory Management +### Reclamation and Automatic Memory Management The Engine is required to manage the lifetimes of VStores and HStores -using some form of automatic memory management. +using some form of automatic memory management. In particular, when a VStore or HStore is created, memory is allocated for it. Later, if a VStore or HStore becomes unreachable through any existing VSlot, they become eligible for reclamation to release the memory they occupy. The engine may reclaim a VStore or HStore at any time -between when it becomes eligible for reclamation and the end of the script execution. +between when it becomes eligible for reclamation and the end of the script execution. -Before reclaiming an HStore that represents an [object](05-types.md#object-types), +Before reclaiming an HStore that represents an [object](05-types.md#objects), the Engine should invoke the object's [destructor](14-classes.md#constructors) if one is defined. The Engine must reclaim each VSlot when the [storage duration](#storage-duration) of its -corresponding variable ends, when the variable is explicitly [unset](10-expressions.md#unset) by the +corresponding variable ends, when the variable is explicitly [unset](11-statements.md#the-unset-statement) by the programmer, or when the script exits, whichever comes first. In the case where a VSlot is contained within an HStore, the engine must immediately reclaim the VSlot when it is explicitly unset by the programmer, when the containing HStore is reclaimed, @@ -284,8 +299,8 @@ a VSlot, this indicates that the VSlot has been reclaimed or, in the case of a VSlot contained with an HStore, that the containing HStore has been reclaimed or is eligible for reclamation. -###Assignment -####General +### Assignment +#### General This section and those immediately following it describe the abstract model's implementation of *value assignment* and *byRef assignment*. Value assignment of non-array types to local variables is described @@ -298,7 +313,7 @@ Value assignment and byRef assignment are core to the PHP language, and many other operations in this specification are described in terms of value assignment and byRef assignment. -####Value Assignment of Scalar Types to a Local Variable +#### Value Assignment of Scalar Types to a Local Variable Value assignment is the primary means by which the programmer can create local variables. If a local variable that appears on the left-hand side of value assignment does not exist, the engine will bring a new local @@ -313,11 +328,12 @@ $a = 123; $b = false; ``` -
+
+```
 [VSlot $a *]-->[VStore int 123]
 
 [VSlot $b *]-->[VStore bool false]
-
+``` Variable `$a` comes into existence and is represented by a newly created VSlot pointing to a newly created VStore. Then the integer value 123 is @@ -327,11 +343,11 @@ to the VStore. Next consider the value assignment `$b = $a`: -
+```
 [VSlot $a *]-->[VStore int 123]
 
 [VSlot $b *]-->[VStore int 123]
-
+``` The integer value 123 is read from `$a`'s VStore and is written into `$b`'s VStore, overwriting its previous contents. As we can see, the two @@ -359,23 +375,23 @@ not change the content of another. For example, the php.net implementation's model, which in some cases will set two variable slots to point to the same zval when performing value assignment, produces the same observable behavior as the abstract -model presented here. +model presented here. To illustrate the semantics of value assignment further, consider `++$b`: -
+```
 [VSlot $a *]-->[VStore int 123]
 
 [VSlot $b *]-->[VStore int 124 (123 was overwritten)]
-
+``` Now consider `$a = 99`: -
+```
 [VSlot $a *]-->[VStore int 99 (123 was overwritten)]
 
 [VSlot $b *]-->[VStore int 124]
-
+``` In both of these examples, one variable's value is changed without affecting the other variable's value. While the above examples only @@ -383,7 +399,7 @@ demonstrate value assignment for integer and Boolean values, the same mechanics apply for all scalar types. Note that as string values are scalar values, the model assumes the whole string -representation, including string characters and its length, is contained within the VStore. +representation, including string characters and its length, is contained within the VStore. This means that the model assumes whole string data is copied when the string is assigned. ```PHP @@ -392,28 +408,28 @@ $a = 'gg'; $b = $a; ``` -
+```
 [VSlot $a *]-->[VStore string 'gg']
 
 [VSlot $b *]-->[VStore string 'gg']
-
+``` `$a`'s string value and `$b`'s string values are distinct from each other, and mutating `$a`'s string will not affect `$b`. Consider `++$b`, for example: -
+```
 [VSlot $a *]-->[VStore string 'gg']
 
 [VSlot $b *]-->[VStore string 'gh']
-
+``` -***Implementation Notes:*** +***Implementation Notes:*** The conforming implementation may use an actual representation where string characters are stored outside the structure representing the VStore and are not copied immediately on assignment, for performance reasons. Applications in PHP are often written to assume that value assignment of strings -is a rather inexpensive operation. +is a rather inexpensive operation. Thus, it is common for an implementation to use a deferred copy mechanism to reduce the cost of value assignment for strings. Deferred copy mechanisms work by not copying a string during value assignment and @@ -425,13 +441,13 @@ defer copying a string's contents for value assignment so long as it has no observable effect on behavior from any testable viewpoint (excluding performance and resource consumption). -####Value Assignment of Objects to a Local Variable +#### Value Assignment of Objects to a Local Variable To demonstrate value assignment of objects to local variables, consider the case in which we have a Point class that supports a two-dimensional Cartesian system. An instance of Point contains two instance properties, `$x` and `$y`, that store the x- and y-coordinates, respectively. A -[constructor call](14-classes.md#constructors) of the form `Point(x, y)` +[constructor call](14-classes.md#constructors) of the form `Point(x, y)` used with operator [`new`](10-expressions.md#the-new-operator) creates a new point at the given location, and a method call of the form `move(newX, newY)` moves a `Point` to the new location. @@ -439,12 +455,12 @@ of the form `move(newX, newY)` moves a `Point` to the new location. With the `Point` class, let us consider the value assignment `$a = new Point(1, 3)`: -
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *]]
                                                            |            |
                                                            V            V
                                                       [VStore int 1]  [VStore int 3]
-
+``` Variable `$a` is given its own VSlot, which points to a VStore that contains a handle pointing to an HStore allocated by [`new`](10-expressions.md#the-new-operator) and @@ -452,12 +468,12 @@ that is initialized by `Point`'s constructor. Now consider the value assignment `$b = $a`: -
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *]]
                                      ^                     |            |
                                      |                     V            V
 [VSlot $b *]-->[VStore object *]-----+             [VStore int 1] [VStore int 3]
-
+``` `$b`'s VStore contains a handle that points to the same object as does `$a`'s VStore's handle. Note that the Point object itself was not copied, @@ -466,20 +482,20 @@ and note that `$a`'s and `$b`'s VSlots point to distinct VStores. Let's modify the value of the Point whose handle is stored in `$b` using `$b->move(4, 6)`: -
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *]]
                                      ^                     |            |
                                      |                     V            V
 [VSlot $b *]-->[VStore object *]-----+            [VStore int 4] [VStore int 6]
                                        (1 was overwritten) (3 was overwritten)
-
+``` As we can see, changing `$b`'s Point changes `$a`'s as well. Now, let's make `$a` point to a different object using `$a = new Point(2, 1)`: -
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *]]
                                                            |            |
 [VSlot $b *]-->[VStore object *]-----+                     V            V
@@ -489,24 +505,25 @@ Now, let's make `$a` point to a different object using `$a = new Point(2,
                                                            |            |
                                                            V            V
                                                    [VStore int 4] [VStore int 6]
-
+``` Before `$a` can take on the handle of the new `Point`, its handle to the old `Point` must be removed, which leaves the handles of `$a` and `$b` pointing to different Points. We can remove all these handles using `$a = NULL` and `$b = NULL`: -
+
+```
 [VSlot $a *]-->[VStore null]    [HStore Point [VSlot $x *] [VSlot $y *] (dead)]
                                                         |            |
-[VSlot $b *]-->[VStore null]    [VStore int 2 (dead)]<--+            V
+[VSlot $b *]-->[VStore null]    [VStore int 2 (dead)]<--+            V
                                                           [VStore int 1 (dead)]
 
                                 [HStore Point [VSlot $x *] [VSlot $y *] (dead)]
                                                         |            |
-                                [VStore int 4 (dead)]<--+            V
+                                [VStore int 4 (dead)]<--+            V
                                                         [VStore int 6 (dead)]
-
+``` By assigning null to `$a`, we remove the only handle to `Point(2,1)` which makes that object eligible for destruction. A similar thing happens with `$b`, @@ -518,28 +535,29 @@ though they can have an arbitrarily large number of instance properties of arbitrary type. Likewise, the same mechanics apply to value assignment of all resource types. -####ByRef Assignment for Scalar Types with Local Variables +#### ByRef Assignment for Scalar Types with Local Variables Let's begin with the same value [assignment](10-expressions.md#simple-assignment) as in the previous section, `$a = 123` and `$b = false`: -
+```
 [VSlot $a *]-->[VStore int 123]
 
 [VSlot $b *]-->[VStore bool false]
-
+``` Now consider the [byRef assignment](10-expressions.md#byref-assignment) `$b =& $a`, which has byRef semantics: -
+
+```
 [VSlot $a *]-->[VStore int 123]
                  ^
                  |
 [VSlot $b *]-----+     [VStore bool false (dead)]
-
+``` In this example, byRef assignment changes `$b`'s VSlot point to the same VStore that `$a`'s VSlot points to. The old VStore that `$b`'s VSlot used -to point to is now unreachable. +to point to is now unreachable. When multiple variables' VSlots point to the same VStore, the variables are said to be *aliases* of each other or they are said to @@ -547,16 +565,17 @@ have an *alias relationship*. In the example above, after the byRef assignment executes the variables `$a` and `$b` will be aliases of each other. -Note that even though in the assignment `$b =& $a` the variable `$b` is on the left and `$a` is on the right, +Note that even though in the assignment `$b =& $a` the variable `$b` is on the left and `$a` is on the right, after becoming aliases they are absolutely symmetrical and equal in their relation to the VStore. When we change the value of `$b` using `++$b` the result is: -
+
+```
 [VSlot $a *]-->[VStore int 124 (123 was overwritten)]
                  ^
                  |
 [VSlot $b *]-----+
-
+``` `$b`'s value, which is stored in the VStore that `$b`'s VSlot points, is changed to 124. And as that VStore is also aliased by `$a`'s VSlot, the @@ -564,22 +583,24 @@ value of `$a` is also 124. Indeed, any variable's VSlot that is aliased to that VStore will have the value 124. Now consider the value assignment `$a = 99`: -
+
+```
 [VSlot $a *]-->[VStore int 99 (124 was overwritten)]
                  ^
                  |
 [VSlot $b *]-----+
-
+``` The alias relationship between `$a` and `$b` can be broken explicitly by using `unset` on variable `$a` or variable `$b`. For example, consider `unset($a)`: -
+
+```
 [VSlot $a (dead)]      [VStore int 99]
                          ^
                          |
 [VSlot $b *]-------------+
-
+``` Unsetting `$a` causes variable `$a` to be destroyed and its link to the VStore to be removed, leaving `$b`'s VSlot as the only @@ -587,25 +608,27 @@ pointer remaining to the VStore. Other operations can also break an alias relationship between two or more variables. For example, `$a = 123` and `$b =& $a`, and `$c = 'hi'`: -
+
+```
 [VSlot $a *]-->[VStore int 123]
                  ^
                  |
 [VSlot $b *]-----+
 
 [VSlot $c *]-->[VStore string 'hi']
-
+``` After the byRef assignment, `$a` and `$b` now have an alias relationship. Next, let's observe what happens for `$b =& $c`: -
+
+```
 [VSlot $a *]-->[VStore int 123]
 
 [VSlot $b *]-----+
                  |
                  V
 [VSlot $c *]-->[VStore string 'hi']
-
+``` As we can see, the byRef assignment above breaks the alias relationship between `$a` and `$b`, and now `$b` and `$c` are aliases of each other. When @@ -621,14 +644,15 @@ $b =& $a; $c =& $b; $a = 123; ``` -
+
+```
 [VSlot $a *]-->[VStore int 123]
                  ^   ^
                  |   |
 [VSlot $b *]-----+   |
                      |
 [VSlot $c *]---------+
-
+``` Like value assignment, byRef assignment provides a means for the programmer to create variables. If the local variables that appear on @@ -640,45 +664,50 @@ Note that literals, constants, and other expressions that don't designate a modifiable lvalue cannot be used on the left- or right-hand side of byRef assignment. -####ByRef Assignment of Non-Scalar Types with Local Variables +#### ByRef Assignment of Non-Scalar Types with Local Variables ByRef assignment of non-scalar types works using the same mechanism as byRef assignment for scalar types. Nevertheless, it is worthwhile to describe a few examples to clarify the semantics of byRef assignment. -Recall the [example using the `Point` class](#value-assignment-of-object-and-resource-types-to-a-local-variable): +Recall the [example using the `Point` class](#value-assignment-of-objects-to-a-local-variable): `$a = new Point(1, 3);` -
+
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *]]
                                                            |            |
                                                            V            V
                                                   [VStore int 1]  [VStore int 3]
-
+``` Now consider the [byRef assignment](10-expressions.md#byref-assignment) `$b =& $a`, which has byRef semantics: -
+
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *][VSlot $y *]]
                  ^                                         |           |
                  |                                         V           V
 [VSlot $b *]-----+                                  [VStore int 1] [VStore int 3]
-
+``` + `$a` and `$b` now aliases of each other. Note that byRef assignment produces a different result than `$b = $a` where `$a` and `$b` would point to distinct VStores pointing to the same HStore. Let's modify the value of the `Point` aliased by `$a` using `$a->move(4, 6)`: -
+
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *] VSlot $y *]]
                  ^                                         |           |
                  |                                         V           V
 [VSlot $b *]-----+                              [VStore int 4] [VStore int 6]
                                         (1 was overwritten) (3 was overwritten)
-
+``` Now, let's change `$a` itself using the value assignment `$a = new Point(2, 1)`: -
+
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *][VSlot $y *]]
                  ^                                         |           |
                  |                                         V           V
@@ -688,7 +717,7 @@ Point(2, 1)`:
                                                        |              |
                                                        V              V
                                      [VStore int 4 (dead)] [VStore int 6 (dead)]
-
+``` As we can see, `$b` continues to have an alias relationship with `$a`. Here's what's involved in that assignment: `$a` and `$b`'s VStore's handle @@ -697,33 +726,35 @@ pointing to `Point(4,6)` is removed, `Point(2,1)` is created, and `$a` and `Point`. As there are now no VStores pointing to `Point(4,6)`, it can be destroyed. We can remove these aliases using `unset($a, $b)`: -
+
+```
 [VSlot $a (dead)]       [HStore Point [VSlot $x *] [VSlot $y *] (dead)]
                                                 |            |
                                                 V            V
 [VSlot $b (dead)]             [VStore int 2 (dead)]  [VStore int 1 (dead)]
-
+``` Once all the aliases to the VStores are gone, the VStores can be destroyed, in which case, there are no more pointers to the HStore, and it can be destoyed too. -####Value Assignment of Array Types to Local Variables +#### Value Assignment of Array Types to Local Variables The semantics of value assignment of array types is different from value -assignment of other types. Recall the `Point` class from [the examples](#value-assignment-of-object-and-resource-types-to-a-local-variable), and consider the following [value assignments](10-expressions.md#simple-assignment) and their abstract implementation: +assignment of other types. Recall the `Point` class from [the examples](#value-assignment-of-objects-to-a-local-variable), and consider the following [value assignments](10-expressions.md#simple-assignment) and their abstract implementation: `$a = array(10, 'B' => new Point(1, 3));` -
+
+```
 [VSlot $a *]-->[VStore array *]-->[HStore Array [VSlot 0 *] [VSlot 'B' *]]
                                                          |             |
                                                          V             V
                                                [VStore int 10]   [VStore Obj *]
                                                                              |
-                                [HStore Point [VSlot $x *] [VSlot $y *]]<----+
+                                [HStore Point [VSlot $x *] [VSlot $y *]]<----+
                                                         |            |
                                                         V            V
                                             [VStore int 1]  [VStore int 3]
-
+``` In the example above, `$a`'s VStore is initialized to contain a handle to an HStore for an array containing two elements, where one element is an @@ -740,7 +771,8 @@ describes [deferred copying](#deferred-array-copying). To describe the semantics of eager copying, let's begin by considering the value assignment `$b = $a`: -
+
+```
 [VSlot $a *]-->[VStore array *]-->[HStore Array [VSlot 0 *] [VSlot 'B' *]]
                                                          |             |
 [VSlot $b *]-->[VStore array *]                          V             V
@@ -750,11 +782,11 @@ the value assignment `$b = $a`:
                        |             |                                          |
              +---------+   +---------+                                          |
              V             V                                                    |
-[VStore int 10] [VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *]]<---+
+[VStore int 10] [VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *]]<---+
                                                             |            |
                                                             V            V
                                                  [VStore int 1]  [VStore int 3]
-
+``` The value assignment `$b = $a` made a copy of `$a`'s array. Note how `$b`'s VSlot points to a different VStore than `$a`'s VSlot, and `$b`'s @@ -794,10 +826,11 @@ $b = $a; Eager copying can produce two possible outcomes depending on the implementation. Here is the first possible outcome: -
+
+```
 [VSlot $a *]---->[VStore array *]---->[HStore Array [VSlot 0 *]]
                                                              |
-[VSlot $x *]-------------------------+   [VStore array *]<---+
+[VSlot $x *]-------------------------+   [VStore array *]<---+
                                      |                 |
 [VSlot $b *]-->[VStore array *]      |                 V
                              |       |  [HStore Array [VSlot 0 *][VSlot 1 *]]
@@ -812,13 +845,14 @@ implementation. Here is the first possible outcome:
                                                         |
                                                         V
                                                      [VStore string 'hi']
-
+``` Here is the second possible outcome: -
+
+```
 [VSlot $a *]---->[VStore array *]---->[HStore Array [VSlot 0 *]]
                                                              |
-[VSlot $x *]-------------------------+  [VStore array *]<----+
+[VSlot $x *]-------------------------+  [VStore array *]<----+
                                      |                |
 [VSlot $b *]-->[VStore array *]      |                V
                              |       |  [HStore Array [VSlot 0 *] [VSlot 1 *]]
@@ -831,9 +865,9 @@ Here is the second possible outcome:
                                    V
                     [HStore Array [VSlot 0 *] [VSlot 1 *]]
                                            |           |
-                                           V           V 
+                                           V           V
                                   [VStore int 123]  [VStore string 'hi']
-
+``` In both possible outcomes, value assignment with eager copying makes a copy of `$a`'s array, copying the array's single element using @@ -857,7 +891,7 @@ arrays even though they can have an arbitrarily large number of elements. As to how an HStore accommodates all of them, is unspecified and unimportant to the abstract model. -####Deferred Array Copying +#### Deferred Array Copying As mentioned in the [previous section](#value-assignment-of-array-types-to-local-variables), an implementation may choose to use a deferred copy mechanism instead of eagerly making a copy for value assignment of arrays. An implementation may use any deferred @@ -901,10 +935,11 @@ $x = 123; $a = array(array(&$x, 'hi')); $b = $a; ``` -
+
+```
 [VSlot $a *]--->[VStore array *]--->[HStore Array [VSlot 0 *]]
                                       ^                    |
-                                      | [VStore array *]<--+
+                                      | [VStore array *]<--+
 [VSlot $b *]--->[VStore Arr-D *]------+               |
                                                       V
                                         [HStore Array [VSlot 0 *] [VSlot 1 *]]
@@ -913,7 +948,7 @@ $b = $a;
 [VSlot $x *]------------------------------------------>[VStore int 123]    |
                                                                            V
                                                                [VStore string 'hi']
-
+``` As we can see, both `$a`'s VStore (the source VStore) and `$b`'s VStore (the destination VStore) point to the same array HStore. Note the @@ -962,10 +997,11 @@ Continuing with the previous example, consider the array-mutating operation `$b[1]++`. Depending on the implementation, this can produce one of three possible outcomes. Here is the one of the possible outcomes: -
+
+```
 [VSlot $a *]---->[VStore array *]---->[HStore Array [VSlot 0 *]]
                                                              |
-[VSlot $b *]-->[VStore array *]            [VStore Arr *]<---+
+[VSlot $b *]-->[VStore array *]            [VStore Arr *]<---+
                              |                         |
       +----------------------+              +----------+
       V                                     V
@@ -977,7 +1013,7 @@ outcomes:
                        [VStore Arr-D *]------+             |   [VStore string 'hi']
                                                            |
  [VSlot $x *]----------------------------------------------+
-
+``` As we can see in the outcome shown above, `$b`'s VStore was array-separated and now `$a`'s VStore and `$b`'s VStore point to distinct @@ -996,10 +1032,11 @@ array-separated. However, an implementation can choose to array-separate shown below demonstrate what can possibly happen if the implementation choose to array-separate `$b[0]`'s VStore as well. Here is the second possible outcome: -
+
+```
 [VSlot $a *]---->[VStore array *]---->[HStore Array [VSlot 0 *]]
                                                              |
-[VSlot $b *]-->[VStore array *]          [VStore array *]<---+
+[VSlot $b *]-->[VStore array *]          [VStore array *]<---+
                              |                         |
                              V                         V
   [HStore Array [VSlot 0 *] [VSlot 1 *]]  [HStore Array [VSlot 0 *] [VSlot 1 *]]
@@ -1013,14 +1050,15 @@ possible outcome:
                                     |                   V   |
                                     | [VStore string 'hi']  |
                                     V                       |
- [VSlot $x *]--------------------->[VStore int 123]<--------+
-
+ [VSlot $x *]--------------------->[VStore int 123]<--------+ +``` Here is the third possible outcome: -
+
+```
 [VSlot $a *]---->[VStore array *-]---->[HStore Array [VSlot 0 *]]
-                                                            |
-[VSlot $b *]-->[VStore array *]           [VStore array *]<---+
+                                                              |
+[VSlot $b *]-->[VStore array *]           [VStore array *]<---+
                              |                          |
                              V                          V
  [HStore Array [VSlot 0 *] [VSlot 1 *]]  [HStore Array [VSlot 0 *] [VSlot 1 *]]
@@ -1030,12 +1068,12 @@ Here is the third possible outcome:
        V                                                     |              V
    [VStore Arr-D *]-->[HStore Array [VSlot 0 *] [VSlot 1 *]] | [VStore string 'hi']
                                              |           |   |
-                     [VStore int 123]<-------+           |   |
+                     [VStore int 123]<-------+           |   |
                                                          V   |
                                        [VStore string 'hi']  |
                                                              |
- [VSlot $x *]--------------------->[VStore int 123]<---------+
-
+ [VSlot $x *]--------------------->[VStore int 123]<---------+ +``` The second and third possible outcomes show what can possibly happen if the implementation chooses to array-separate `$b[0]`'s VStore. In the @@ -1079,11 +1117,11 @@ difference, php.net's implementation produces behavior that is compatible with the abstract model's definition of deferred array copy mechanisms. -####General Value Assignment +#### General Value Assignment The sections above thus far have described the mechanics of value assignment to a local variable. The assignment to a modifiable lvalue that is not a variable, such as array element or object property, works like the local variable assignment, except that the VSlot which represented -a variable is replaced by a VSlot that represents the target lvalue. +a variable is replaced by a VSlot that represents the target lvalue. If necessary, such VSlot is created. For example, assuming `Point` definition as in previous sections and further assuming all @@ -1095,13 +1133,14 @@ $b = 123; $a->x = $b; ``` Will result in: -
+
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *]]
                                                            |            |
                                                            V            V
                                                   [VStore int 123] [VStore int 3]
 [VSlot $b *]-->[VStore int 123]
-
+``` If needed, new VSlots are created as part of the containing VStore, for example: ```PHP @@ -1110,13 +1149,14 @@ $b = 123; $a->z = $b; ``` Will result in: -
+
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *] [VSlot $z *]]
                                                            |            |            |
                                                            V            V            V
                                                   [VStore int 1] [VStore int 3] [VStore int 123]
 [VSlot $b *]-->[VStore int 123]
-
+``` The same holds for array elements: ```PHP @@ -1126,21 +1166,23 @@ $a[1] = $b; $a[2] = 'World!'; ``` Will result in: -
+
+```
 [VSlot $a *]-->[VStore array *]-->[HStore Array [VSlot 0 *]  [VSlot 1 *]  [VSlot 2 *]]
                                                          |            |            |
                                                          V            V            V
                                     [VStore string 'hello'] [VStore string 'php'] [VStore string 'World!']
 [VSlot $b *]-->[VStore string 'php']
-
+``` + Where the third VSlot with index 2 was created by the assignment. Note that any array element and instance property, including a designation of non-existing ones, is considered a modifiable lvalue, and the VSlot will be created by the engine and added to the appropriate HStore automatically. Static class properties are considered modifiable lvalues too, -though new ones would not be created automatically. +though new ones would not be created automatically. -####General ByRef Assignment +#### General ByRef Assignment The sections above thus far have described the mechanics of byref assignment with local variables. The byRef assignment to a modifiable lvalue that is not a variable, such as array element or object property, works like the local variable assignment, @@ -1156,24 +1198,25 @@ $a->z =& $b; ``` Will result in: -
+
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *] [VSlot $z *]]
                                                            |            |            |
                                                            V            V            |
                                                   [VStore int 1] [VStore int 3]      |
-[VSlot $b *]---------------->[VStore int 123]<---------------------------------------+
-
+[VSlot $b *]---------------->[VStore int 123]<---------------------------------------+ +``` -###Argument Passing -Argument passing is defined in terms of [simple assignment](#assignment) or [byRef assignment](#byref-assignment-for-scalar-types-with-local-variables), depending on how the parameter is declared. +### Argument Passing +Argument passing is defined in terms of [simple assignment](#assignment) or [byRef assignment](#byref-assignment-for-scalar-types-with-local-variables), depending on how the parameter is declared. That is, passing an argument to a function having a corresponding parameter is like assigning that argument to that parameter. The function call situations involving missing arguments or undefined variable arguments are discussed in section describing [the function call operator](10-expressions.md#function-call-operator). -###Value Returning -Returning a value from a function is defined in terms of [simple assignment](#assignment) or [byRef assignment](#byref-assignment-for-scalar-types-with-local-variables), depending on how the function is declared. +### Value Returning +Returning a value from a function is defined in terms of [simple assignment](#assignment) or [byRef assignment](#byref-assignment-for-scalar-types-with-local-variables), depending on how the function is declared. That is, returning a value from a function to its caller is like assigning that value to the user of the caller's return value. The function-return situations involving a missing return value @@ -1199,46 +1242,48 @@ counter(); ``` This example prints `1 2 4 `, since the first assignment does not produce -byRef semantics even though the function return is declared byRef. +byRef semantics even though the function return is declared byRef. If the function is not declared to return byRef, its return never produces byRef semantics, regardles of how it is assigned. Passing function's return to another function is considered the same as assigning the value to the corresponding function's parameter, with byRef parameters -treated as byRef assignments. +treated as byRef assignments. -###Cloning objects +### Cloning objects When an object instance is allocated, operator [`new`](10-expressions.md#the-new-operator) returns a handle -that points to that object. As described [above](#value-assignment-of-object-and-resource-types-to-a-local-variable), -value assignment of a handle to an object does not copy the object HStore itself. Instead, it creates a copy of the handle. +that points to that object. As described [above](#value-assignment-of-objects-to-a-local-variable), +value assignment of a handle to an object does not copy the object HStore itself. Instead, it creates a copy of the handle. The copying of the HStore itself is performed via [operator `clone`](10-expressions.md#the-clone-operator). To demonstrate how the `clone` operator works, consider the case in which an instance of class `Widget` contains two instance properties: `$p1` has the integer value 10, and `$p2` is a handle to an array of elements of some type(s) or to an instance of some other type. -
+
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Widget [VSlot $p1 *][VSlot $p2 *]]
                                                              |            |
                                                              V            V
                                                [VStore int 10] [VStore object *]
                                                                               |
-                                                        [HStore ...]<---------+
-
+ [HStore ...]<---------+ +``` Let us consider the result of `$b = clone $a`: -
+
+```
 [VSlot $a *]-->[VStore object *]-->[HStore Widget [VSlot $p1 *][VSlot $p2 *]]
                                                              |            |
 [VSlot $b *]-->[VStore object *]                             V            V
                              |                  [VStore int 10] [VStore object *]
      +-----------------------+                                                 |
      V                                                                         |
-   [HStore Widget [VSlot $p1 *] [VSlot $p2 *]]              +--->[HStore ...]<-+
+   [HStore Widget [VSlot $p1 *] [VSlot $p2 *]]              +--->[HStore ...]<-+
                              |             |                |
                              V             V                |
                  [VStore int 10] [VStore object *]----------+
-
+``` The clone operator will create another object HStore of the same class as the original and copy `$a`'s object's instance properties using @@ -1249,9 +1294,9 @@ objects held in `$a`'s instance properties; hence the object copying performed by the clone operator is often referred to as a *shallow copy*. If a *deep copy* of an object is desired, the programmer must achieve this manually by using the [method `__clone`](14-classes.md#method-__clone) which -is called after the initial shallow copy has been performed. +is called after the initial shallow copy has been performed. -##Scope +## Scope The same name can designate different things at different places in a program. For each different thing that a name designates, that name is @@ -1259,11 +1304,11 @@ visible only within a part of the program called that name's *scope*. There are a number of scope types that exist in PHP: -- Variable scope - the scope which defined what unqualified variables (like `$foo`) are referring to. - Variables defined in one variable scope are not visible in another variable scope. +- Variable scope - the scope which defined what unqualified variables (like `$foo`) are referring to. + Variables defined in one variable scope are not visible in another variable scope. - Class scope - the scope that defines visibility of the methods and properties, and resolution of keywords like `self`, `parent`, etc. Class scope encompasses [the body of that class](14-classes.md#class-declarations) and any classes derived - from it. + from it. - Namespace scope - the scope that defines what unqualified and not-fully-qualified class and function names (e.g. `foo()` or `new Bar()`) refer to. Namespace scoping rules are defined in the [Namespaces chapter](18-namespaces.md#namespaces). @@ -1275,22 +1320,22 @@ For variable scopes, the following scopes can be distinguished: initialization through to the end of that [function's body](13-functions.md#function-definitions). [Start-up scripts](#program-start-up) have the global variable scope. -[Included](10-expressions.md#script-inclusion-operators) scripts have the variable scope matching the scope in +[Included](10-expressions.md#script-inclusion-operators) scripts have the variable scope matching the scope in the place where the inclusion operator was executed. -A variable declared or first initialized inside a function, has function scope; -otherwise, the variable has the same variable scope as the enclosing script. +A variable declared or first initialized inside a function, has function scope; +otherwise, the variable has the same variable scope as the enclosing script. [Global variables](07-variables.md#global-variables) can be brought into the current scope by using `global` keyword. -[Superglobals](07-variables.md#general) exist in the global variable scope, however they can be also accessed in any scope; +[Superglobals](07-variables.md#general) exist in the global variable scope, however they can be also accessed in any scope; they never need explicit declaration. Each function has its own function scope. An [anonymous function](13-functions.md#anonymous-functions) has its own scope separate from that of any function inside which that anonymous function is defined. -The variable scope of a parameter is the body of the function in which the parameter is declared. +The variable scope of a parameter is the body of the function in which the parameter is declared. -The scope of a []*named-label*](11-statements.md#labeled-statements) is the body of the function in +The scope of a [*named-label*](11-statements.md#labeled-statements) is the body of the function in which the label is defined. The class scope of a [class member m](14-classes.md#class-members) that is declared in, or inherited by, a @@ -1300,10 +1345,10 @@ The class scope of an [interface member m](14-classes.md#class-members) that is an interface type I is the body of I. When a [trait](16-traits.md#general) is used by a class or an interface, the [trait's -members](16-traits.md#trait-members) take on the class scope of a member of that class or +members](16-traits.md#trait-declarations) take on the class scope of a member of that class or interface. -##Storage Duration +## Storage Duration The lifetime of a variable is the time during program execution that storage for that variable is guaranteed to exist. This lifetime is @@ -1326,14 +1371,14 @@ following kinds of variables have static storage duration: [constants](07-variab and class and interface [constants](07-variables.md#class-and-interface-constants). A variable having *allocated storage duration* comes into being based on -program logic by use of the [new operator](10-expressions.md#the-new-operator) or a factory function. +program logic by use of the [new operator](10-expressions.md#the-new-operator) or a factory function. Ordinarily, once such storage is no longer needed, it is reclaimed automatically by the Engine via its garbage-collection process and the use of [destructors](14-classes.md#destructors). The following kinds of variables have allocated storage duration: [array elements](07-variables.md#array-elements) and [instance properties](07-variables.md#instance-properties). Although all three storage durations have default ends-of-life, their -lives can be shortened by calling the intrinsic [`unset`](10-expressions.md#unset), +lives can be shortened by using the [`unset` statement](11-statements.md#the-unset-statement), which destroys any given set of variables. The following example demonstrates the three storage durations: diff --git a/spec/05-types.md b/spec/05-types.md index 6374f87c..703da4f8 100644 --- a/spec/05-types.md +++ b/spec/05-types.md @@ -1,6 +1,6 @@ -#Types +# Types -##General +## General The meaning of a value is determined by its *type*. PHP's types are categorized as *scalar types* and *composite types*. The scalar types @@ -26,9 +26,9 @@ The same variable can contain values of different types at different times. Useful library functions for interrogating and using type information include [`gettype`](http://www.php.net/gettype), [`is_type`](http://www.php.net/is_type), [`settype`](http://www.php.net/settype), and [`var_dump`](http://www.php.net/var_dump). -##Scalar Types +## Scalar Types -###General +### General The integer and floating-point types are collectively known as *arithmetic types*. The library function [`is_numeric`](http://www.php.net/is_numeric) indicates if @@ -43,7 +43,7 @@ convertible to scalar types (this is currently available only to internal classe Such object types together with scalar types are called *scalar-compatible types*. Note that the same object type may be scalar-compatible for one operation but not for another. -###The Boolean Type +### The Boolean Type The Boolean type is `bool`, for which the name `boolean` is a synonym. This type is capable of storing two distinct values, which correspond to the @@ -53,7 +53,7 @@ The internal representation of this type and its values is unspecified. The library function [`is_bool`](http://www.php.net/is_bool) indicates if a given value has type `bool`. -###The Integer Type +### The Integer Type There is one integer type, `int`, for which the name `integer` is a synonym. This type is binary, signed, and uses twos-complement representation for @@ -71,13 +71,13 @@ cannot be represented as an integer. Examples include the following: In such cases, the computation is done as though the types of the values were `float` with the result having that type. -The constants [`PHP_INT_SIZE` and `PHP_INT_MAX`](06-constants.md#core-predefined-constants) define certain +The constants [`PHP_INT_SIZE`, `PHP_INT_MIN` and `PHP_INT_MAX`](06-constants.md#core-predefined-constants) define certain characteristics about type `int`. The library function [`is_int`](http://www.php.net/is_int) indicates if a given value has type `int`. -###The Floating-Point Type +### The Floating-Point Type There is one floating-point type, `float`, for which the names `double` and `real` are synonyms. The `float` type must support at least the range and @@ -90,12 +90,12 @@ indicates if a given floating-point value is infinite. The library function [`is_nan`](http://www.php.net/is_nan) indicates if a given floating-point value is a `NaN`. -###The String Type +### The String Type A string is a set of contiguous bytes that represents a sequence of zero or more characters. -Conceptually, a string can be considered as an [array](#array-types) of +Conceptually, a string can be considered as an [array](#the-array-type) of bytesβ€”the *elements*β€”whose keys are the `int` values starting at zero. The type of each element is `string`. However, a string is *not* considered a collection, so it cannot be iterated over. @@ -113,30 +113,69 @@ library functions assume the strings they receive as arguments are UTF-8 encoded, often without explicitly mentioning that fact. A *numeric string* is a string whose content exactly matches the pattern -defined using integer format by the production [*integer-literal*](09-lexical-structure.md#integer-literals) -or using floating-point format by the production -[*floating-literal*](09-lexical-structure.md#floating-point-literals), where leading whitespace is permitted. +defined by the *str-numeric* production below. A *leading-numeric string* is a string whose initial characters follow the requirements of a numeric string, and whose trailing characters are non-numeric. A *non-numeric string* is a string that is not a numeric string. + + +
+str-numeric::
+   str-whitespaceopt   signopt   str-number
+
+str-whitespace::
+   str-whitespaceopt   str-whitespace-char
+
+str-whitespace-char::
+   new-line
+   Space character (0x20)
+   Horizontal-tab character (0x09)
+   Vertical-tab character (0x0B)
+   Form-feed character (0x0C)
+
+str-number::
+   digit-sequence
+   floating-literal
+
+ +Note that *digit-sequence* is interpreted as having base-10 (so `"0377"` is treated as 377 decimal with a redundant +leading zero, rather than as octal 377). + Only one mutation operation may be performed on a string, offset assignment, which involves the simple assignment [operator =](10-expressions.md#simple-assignment). The library function [`is_string`](http://www.php.net/is_string) indicates if a given value has type string. -###The Null Type +### The Null Type The null type has only one possible value, [`NULL`](06-constants.md#core-predefined-constants). The representation of this type and its value is unspecified. The library function [`is_null`](http://www.php.net/is_null) indicates if a given value is `NULL`. -##Composite Types +## Composite Types -###The Array Type +### The Array Type An array is a data structure that contains a collection of zero or more elements whose values are accessed through keys that are of type `int` or @@ -145,17 +184,17 @@ elements whose values are accessed through keys that are of type `int` or The library function [`is_array`](http://www.php.net/is_array) indicates if a given value is an array. -###Objects +### Objects An *object* is an instance of a [class](14-classes.md#classes). Each distinct -[]*class-declaration*](14-classes.md#class-declarations) defines a new class type, and each class +[*class-declaration*](14-classes.md#class-declarations) defines a new class type, and each class type is an object type. The representation of object types is unspecified. The library function [`is_object`](http://www.php.net/is_object) indicates if a given value is an object, and the library function [`get_class`](http://php.net/manual/function.get-class.php) indicates the name of an object's class. -###Resources +### Resources A [*resource*](http://php.net/manual/language.types.resource.php) is a descriptor to some sort of external entity. Examples include @@ -170,6 +209,3 @@ Each distinct resource has a unique identity of some unspecified form. The library function [`is_resource`](http://www.php.net/is_resource) indicates if a given value is a resource, and the library function [`get_resource_type`](http://php.net/manual/function.get-resource-type.php) indicates the type of a resource. - - - diff --git a/spec/06-constants.md b/spec/06-constants.md index 2d23c18a..8b23a2af 100644 --- a/spec/06-constants.md +++ b/spec/06-constants.md @@ -1,6 +1,6 @@ -#Constants +# Constants -##General +## General A *constant* is a [named](09-lexical-structure.md#names) value. Once defined, the value of the constant can not be changed. @@ -12,14 +12,10 @@ Specifically: - The name of a c-constant must comply with the lexical grammar for a name while that for a d-constant can contain any source character. -- The name of a c-constant is case-sensitive while that for a - d-constant can be case-sensitive or case-insensitive based on the - value of the third argument passed to `define`. - If `define` is able to define the given name, it returns `TRUE`; otherwise, it returns `FALSE`. -- `define` cannot create array constants. -The constants can only hold a value of a [scalar type](05-types.md#scalar-types), an array or a [resource](05-types.md#resource-types). +The constants can only hold a value of a [scalar type](05-types.md#scalar-types), an array or a [resource](05-types.md#resources). The library function [`defined`](http://www.php.net/defined) reports if a given name (specified as a string) is defined as a constant. The library function [`constant`](http://www.php.net/constant) @@ -31,18 +27,18 @@ string. ```PHP const MAX_HEIGHT = 10.5; // define two (case-sensitive) c-constants const UPPER_LIMIT = MAX_HEIGHT; -define('COEFFICIENT_1', 2.345, TRUE); // define a case-insensitive d-constant +define('COEFFICIENT_1', 2.345, TRUE); // define a case-insensitive d-constant (deprecated) define('FAILURE', FALSE, FALSE); // define a case-sensitive d-constant ``` -##Context-Dependent Constants +## Context-Dependent Constants The following constantsβ€”sometimes referred to as *magic constants*β€”are automatically available to all scripts; their values are not fixed and they are case-insensitive: - Constant Name | Description - ----------------- | --------- - `__CLASS__` | `string`; The name of the current class. From within a trait method, the name of the class in which that trait is used. If the current namespace is other than the default, the namespace name and `\` are prepended, in that order. If used outside all classes, the value is the empty string. + Constant Name | Description + ----------------- | --------- + `__CLASS__` | `string`; The name of the current class. From within a trait method, the name of the class in which that trait is used. If the current namespace is other than the default, the namespace name and `\` are prepended, in that order. If used outside all classes, the value is the empty string. `__COMPILER_HALT_OFFSET__` | `int`; When the [`__halt_compiler();`](04-basic-concepts.md#__halt_compiler) construct is used, this constant contains the byte offset in the source file immediately following the `__halt_compiler();` token in this file. `__DIR__` | `string`; The directory name of the script. A directory separator is only appended for the root directory. `__FILE__` | `string`; The full name of the script. @@ -54,12 +50,12 @@ automatically available to all scripts; their values are not fixed and they are Constant names beginning with __ are reserved for future use by the Engine. -##Core Predefined Constants +## Core Predefined Constants The following constants are automatically available to all scripts; they are case-sensitive with the exception of `NULL`, `TRUE` and `FALSE`: Constant Name | Description -------------- | ----------- +------------- | ----------- `DEFAULT_INCLUDE_PATH` | `string`; the [`fopen`](http://www.php.net/fopen) library function include path is used if it is not overridden by the `php.ini` setting `include_path`. `E_ALL` | `int`; All errors and warnings, as supported. `E_COMPILE_ERROR` | `int`; Fatal compile-time errors. This is like an `E_ERROR`, except that `E_COMPILE_ERROR` is generated by the scripting engine. @@ -77,7 +73,6 @@ Constant Name | Description `E_USER_NOTICE` | `int`; User-generated warning message. This is like an `E_NOTICE`, except that `E_USER_NOTICE` is generated in PHP code by using the library function [`trigger_error`](http://www.php.net/trigger_error). `E_USER_WARNING` | `int`; User-generated warning message. This is like an `E_WARNING`, except that `E_USER_WARNING` is generated in PHP code by using the library function [`trigger_error`](http://www.php.net/trigger_error). `E_WARNING` | `int`; Run-time warnings (non-fatal errors). Execution of the script is not halted. -`E_USER_DEPRECATED` | `int`; User-generated warning message. This is like an `E_DEPRECATED`, except that `E_USER_DEPRECATED` is generated in PHP code by using the library function [`trigger_error`](http://www.php.net/trigger_error). `FALSE` | `bool`; the case-insensitive Boolean value `FALSE`. `INF` | `float`; Infinity `M_1_PI` | `float`; 1/pi @@ -107,13 +102,19 @@ Constant Name | Description `PHP_EOL` | `string`; the end-of-line terminator for this platform. `PHP_EXTENSION_DIR` | `string`; The directory to be searched by the library function [`dl`](http://www.pph.net/dl) when looking for runtime extensions. `PHP_EXTRA_VERSION` | `string`; the current PHP extra version. -`PHP_INT_MAX` | `int`; the largest representable value for an integer. +`PHP_INT_MAX` | `int`; the maximum representable value for an integer. +`PHP_INT_MIN` | `int`; the minimum representable value for an integer. `PHP_INT_SIZE` | `int`; the number of bytes used to represent an integer. +`PHP_FLOAT_DIG` | `int`; the number of decimal digits that can be rounded into a float and back without precision loss. +`PHP_FLOAT_EPSILON` | `float`; the smallest representable positive number `x`, so that `x + 1.0 != 1.0`. +`PHP_FLOAT_MIN` | `float`; the smallest representable normalized floating point number larger than zero. +`PHP_FLOAT_MAX` | `float`; the largest representable floating point number. `PHP_MAJOR_VERSION` | `int`; the current PHP major version `PHP_MANDIR` | `string`; the installation location of the manual pages. `PHP_MAXPATHLEN` | `int`; the maximum length of a fully qualified filename supported by this build. `PHP_MINOR_VERSION` | `int`; the current PHP minor version. `PHP_OS` | `string`; the current operating system. +`PHP_OS_FAMILY` | `string`; the operating system family PHP was built for. Either of 'Windows', 'BSD', 'Darwin', 'Solaris', 'Linux' or 'Unknown'. `PHP_PREFIX` | `string`; the value to which "--prefix" was set when configured. `PHP_RELEASE_VERSION` | `int`; the current PHP release version. `PHP_ROUND_HALF_DOWN` | `int`; Round halves down. @@ -134,10 +135,7 @@ Constant Name | Description The members of the `E_*` family have values that are powers of 2, so they can be combined meaningfully using bitwise operators. -##User-Defined Constants +## User-Defined Constants A constant may be defined inside or outside of functions, inside a [class](14-classes.md#constants), or inside an [interface](15-interfaces.md#constants). - - - diff --git a/spec/07-variables.md b/spec/07-variables.md index dfa901d9..b280fda8 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -1,9 +1,10 @@ -#Variables +# Variables -##General +## General A *variable* is a named area of data storage that contains a PHP value. A variable is represented by a [VSlot](04-basic-concepts.md#general). A variable is created by [assigning a value](04-basic-concepts.md#assignment) to it. -A variable is destroyed by *unsetting* it, either by an explicit call to the intrinsic [`unset`](10-expressions.md#unset), or by the Engine. The intrinsic [`isset`](10-expressions.md#isset) tests if a given variable exists and is not set to `NULL`. A variable that somehow becomes defined, but is not initialized starts out with the value `NULL`. +A variable is destroyed by *unsetting* it, either by an explicit call to the [`unset` statement](11-statements.md#the-unset-statement), or by the Engine. The intrinsic [`isset`](10-expressions.md#isset) tests if a given variable exists and is not set to `NULL`. +If a variable, which is not defined so far, is used in an expression, then different strategies are applied which determine whether the variable is defined implicitly or a substitution value is used instead and whether a notice is emitted or not. The strategies depend on the kind of the variable as well as on the context where the undefined variable is being used. The strategies are elaborated in the sub-sections of the different [kinds of variables](#kinds-of-variables) below. Variables have [names](09-lexical-structure.md#names). Distinct variables may have the same name provided they are in different [scopes](04-basic-concepts.md#scope). @@ -27,9 +28,9 @@ The following kinds of variable may exist in a script: - [Static class property](#static-properties). - [Class and interface constant](#class-and-interface-constants). -##Kinds of Variables +## Kinds of Variables -###Constants +### Constants **Syntax** @@ -44,9 +45,17 @@ top level of a script. See [constants](06-constants.md#general) and [class constants](14-classes.md#constants). -A constant defined outside of a class or interface is a [superglobal](#general). A constant has static [storage duration](04-basic-concepts.md#storage-duration) +A constant defined outside of a class or interface is a [superglobal](#general). A constant has static [storage duration](04-basic-concepts.md#storage-duration) and is a non-modifiable lvalue. +**Undefined Constants** + +Undefined constants are not defined implicitly -- forward usages of constants are also classified as undefined constants here. A distinction between class/interface constants and top level constants is made. + +For top level constants: For unqualified usages, the name of the undefined constant (as string) is used as substitution value. Moreover, a warning is emitted stating that the corresponding constant was undefined. For qualified usages, an exception of type [`Error`](14-classes.md#class-error) is thrown. + +For class/interface constants: An exception of type [`Error`](14-classes.md#class-error) is thrown, stating that the corresponding constant was undefined. + **Examples** ```PHP @@ -54,9 +63,33 @@ const MAX_HEIGHT = 10.5; // define two c-constants const UPPER_LIMIT = MAX_HEIGHT; define('COEFFICIENT_1', 2.345); // define two d-constants define('FAILURE', TRUE); + +// Examples of undefined constants +echo NON_EXISTING_CONSTANT; // uses 'NON_EXISTING_CONSTANT' as substitution + // value and emits a warning stating that the + // constant was undefined. + +echo NON_EXISTING_CONSTANT; // same here, the constant is still undefined + // and 'NON_EXISTING_CONSTANT' is used as + // substitution value and a warning is emitted + // again. + +echo MAX_LENGTH; // same here due to a forward usage + // (MAX_LENGTH is defined further below). + // 'MAX_LENGTH' is used as substitution + // value and a warning is emitted. + +echo \NON_EXISTING_CONSTANT; // qualified use of undefined constant. Throws + // an exception of type Error. + +const MAX_LENGTH = 7.5; + +echo Exception::MESSAGE; // undefined class constant. Throws an exception + // of type Error. + ``` -###Local Variables +### Local Variables **Syntax** @@ -102,52 +135,166 @@ Unlike the [function static equivalent](#function-statics), function `f` outputs See the recursive function example in [storage duration section](04-basic-concepts.md#storage-duration). -###Array Elements + +**Undefined Local Variables** + +A distinction is made based on the context where an undefined local variable is used. + +*byVal Context* + +PHP does not implicitly define an undefined local variable and uses `NULL` as substitution value instead. Furthermore, a notice is emitted, stating that the corresponding variable was undefined, unless the variable is used + +1. as the single expression in a statement. +2. as argument of [isset](10-expressions.md#isset). +3. as argument of [empty](10-expressions.md#empty). +4. as the left hand side of the [coalesce operator `??`](10-expressions.md#coalesce-operator). + +Since undefined local variables are not defined implicitly, they stay undefined. In general, a VSlot is not created for undefined variables used in a byValue context. + +*byRef Context* + +If the undefined variable is used in a byRef context then PHP defines the variable implicitly. Hence, a VSlot is created for it and `NULL` is stored in it. A notice is *not* emitted in such a case. + +*Examples of Undefined Variables* + +Following some examples which outlines the behaviour with undefined local variables. + +```PHP +// The following 4 cases outline the exceptions of undefined variables +// used in byValue context where no notice is emitted. +$a; +isset($a); +empty($a); +$a ?? 'default Value'; + +$a = 1; // a VSlot for $a was created and 1 was assigned. + +$b = $c; // a VSlot for $b was created and the value of $c was assigned to + // it. But because $c in turn was undefined, NULL was used as + // substitution value instead. In addition, a notice was + // emitted stating that $c was undefined. + +$d = $c; // a VSlot for $d was created and the value of $c was assigned to + // it. But since $c is still undefined, NULL was used as + // substitution value instead and another notice was emitted + // stating $c was undefined. + +$d + $e; // $e was undefined and `NULL` was used as substitution value + // instead. In addition, a notice was emitted stating that + // $e was undefined. + +$f = &$g; // a VSlot for $f was created which points to the VSlot of $g. + // $g in turn was undefined but was defined implicitly because the + // assignment was byRef. Thus a VSlot for $g was created and `NULL` + // was assigned to it. A notice was *not* emitted. + +$h = $g; // a VSlot for $h was created and the value of $g (which is NULL) + // was assigned to it. + +function foo($x){} + +foo($i); // $i was undefined and NULL was used as substitution value + // instead. In addition, a notice was emitted stating that $i + // was undefined. + +$j = $i; // a VSlot for $j was created and the value of $i was assigned to + // it. But because $i in turn was still undefined, NULL was used + // as substitution value instead. Another notice was emitted + // stating that $i was undefined. + +function bar(&$x){} + +bar($k); // $k was undefined but implicitly defined because it was passed to + // the function bar byRef. Thus a VSlot for $k was created and + // NULL was assigned to it. A notice was *not* emitted. + +$l = $k; // a VSlot for $l was created and the value of $k (which is NULL) + // was assigned to it. + +``` + +### Array Elements **Syntax** -[Arrays](12-arrays.md#arrays) are created via the [array-creation operator](10-expressions.md#array-creation-operator) or -the intrinsic [`array`](10-expressions.md#array). At the same time, one or more elements +[Arrays](12-arrays.md#arrays) are created using the [array-creation operator](10-expressions.md#array-creation-operator). At the same time, one or more elements may be created for that array. New elements are inserted into an existing array via the [simple-assignment operator](10-expressions.md#simple-assignment) in conjunction with the subscript [operator `[]`](10-expressions.md#subscript-operator). Elements can be -removed by calling the [`unset` intrinsic](10-expressions.md#unset). +removed by calling the [`unset` statement](11-statements.md#the-unset-statement). **Semantics** The [scope](04-basic-concepts.md#scope) of an array element is the same as the scope of that array's name. An array element has allocated [storage duration](04-basic-concepts.md#storage-duration). +**Undefined Array Elements** + +Similar to [undefined local variables](#undefined-local-variables), a distinction is made based on the context where an undefined array element is used. + +*byValue Context* + +If one tries to access an undefined array element, then `NULL` is used as substitution value and a notice is emitted, stating that an undefined offset was used. The undefined offset is not created implicitly and a subsequent access results in another notice. + +*byRef Context* + +PHP defines implicitly an undefined array element when it is accessed byRef, a VSlot for the corresponding undefined offset is created and `NULL` is assigned to it. A notice is *not* emitted in this case. + **Examples** ```PHP $colors = ["red", "white", "blue"]; // create array with 3 elements $colors[] = "green"; // insert a new element + +echo $colors[100]; // element with offset 100 is undefined and NULL is + // used as substitution value. Moreover, a notice is + // emitted stating that an undefined offset was used. + +echo $colors[100]; // element with offset 100 is still undefined and NULL + // is used as substitution value instead. Another + // notice is emitted. + +$b = &$colors[100]; // a VSlot for $b is created which points to the array + // element with the offset 100. An array element with + // offset 100 was undefined but implicitly defined + // because the assignment is byRef. Thus a VSlot for + // the array element with offset 100 is created and + // NULL is assigned to it. A notice is *not* emitted. ``` -###Function Statics +### Function Statics **Syntax** + +
-  function-static-declaration:
-    static static-variable-name-list  ;
-
-  static-variable-name-list:
-    static-variable-declaration
-	static-variable-name-list  ,  static-variable-declaration 
-
-  static-variable-declaration:
-	variable-name function-static-initializeropt 
-	
-  function-static-initializer:
-    = constant-expression
-
+function-static-declaration: + static static-variable-name-list ; -**Defined elsewhere** +static-variable-name-list: + static-variable-declaration + static-variable-name-list , static-variable-declaration -* [*variable-name*](09-lexical-structure.md#names) -* [*constant-expression*](10-expressions.md#constant-expressions) +static-variable-declaration: + variable-name function-static-initializeropt + +function-static-initializer: + = constant-expression + **Constraints** @@ -163,9 +310,13 @@ A function static has function [scope](04-basic-concepts.md#scope) and static [s The value of a function static is retained across calls to its parent function. Each time the function containing a function static declaration is called, that execution is dealing with an [alias](04-basic-concepts.md#general) -to that static variable. If that alias is passed to the [`unset` intrinsic](10-expressions.md#unset), +to that static variable. If that alias is passed to the [`unset` statement](11-statements.md#the-unset-statement), only that alias is destroyed. The next time that function is called, a new alias is created. +**Undefined Function Statics** + +Function statics are explicitly defined and thus cannot be undefined. + **Examples** ```PHP @@ -183,26 +334,49 @@ Unlike the [local variable equivalent](#local-variables), function `f` outputs " = 1`", "`$fs = 2`", and "`$fs = 3`", as `$fs` retains its value across calls. -###Global Variables + +Be also aware that declaring a function static can hide a local variable and/or a global variable with the same name. The value of the local or global variable is not taken over as initial value of the function static. Subsequent modifications of the variable only modify the function static and do not affect the local nor the global variable. An example: -**Syntax** +```PHP +function f(){ + $fs = 10; // assign 10 to the local variable $fs + static $fs; // define a function static with name $fs + echo "\$fs = $fs\n"; // $fs = + $fs = 5; // assign 5 to the function static $fs (local variable is not modified) + echo "\$fs = $fs\n"; // $fs = 5 + global $fs; // define a global variable with name $fs + echo "\$fs = $fs\n"; // $fs = + $fs = 3; // assign 3 to the global variable $fs (function static and local variable is not modified + echo "\$fs = $fs\n"; // $fs = 3 + static $fs; + ++$fs; // increment function static $fs + echo "\$fs = $fs\n"; // $fs = 6 +} +f(); +echo "\$fs = $fs\n"; // $fs = 3 +``` -
-  global-declaration:
-    global variable-name-list ;
+### Global Variables
 
-  variable-name-list:
-    expression
-    variable-name-list  ,  expression
-
+**Syntax** -**Defined elsewhere** + -**Constraints** +
+global-declaration:
+   global   variable-name-list   ;
 
-Each *expression* must designate a variable name.
+variable-name-list:
+   simple-variable
+   variable-name-list   ,   simple-variable
+
**Semantics** @@ -228,10 +402,14 @@ A global variable has global [scope](04-basic-concepts.md#scope) and static When a global value is imported into a function, each time the function is called, that execution is dealing with an [alias](04-basic-concepts.md#general) to that -global variable. If that alias is passed to the [`unset` intrinsic](10-expressions.md#unset), +global variable. If that alias is passed to the [`unset` statement](11-statements.md#the-unset-statement), only that alias is destroyed. The next time that function is called, a new alias is created with the current value of the global variable. +**Undefined Global Variables** + +The same rules as for [undefined local variables](#undefined-local-variables) apply. + **Examples** ```PHP @@ -265,33 +443,35 @@ function f() } ``` -###Instance Properties +Be also aware that declaring a variable global can hide a local variable and/or a function static with the same name. See [static variables section](#hidingNotice) for an example. + +### Instance Properties These are described in [class instance properties section](14-classes.md#properties). They have class [scope](04-basic-concepts.md#scope) of the defining class and -allocated [storage duration](04-basic-concepts.md#storage-duration). +allocated [storage duration](04-basic-concepts.md#storage-duration). Access to the instance properties is governed by [visibility rules](14-classes.md#general). -###Static Properties +### Static Properties These are described in [class static properties section](14-classes.md#properties). -They have class [scope](04-basic-concepts.md#scope) of the defining class +They have class [scope](04-basic-concepts.md#scope) of the defining class and static [storage duration](04-basic-concepts.md#storage-duration). Access to the static properties is governed by [visibility rules](14-classes.md#general). -###Class and Interface Constants +### Class and Interface Constants These are described in [class constants section](14-classes.md#constants) and [interface constants section](15-interfaces.md#constants). They have class [scope](04-basic-concepts.md#scope) of the defining class or interface and static [storage duration](04-basic-concepts.md#storage-duration). -##Predefined Variables +## Predefined Variables The following global variables are available to all scripts: Variable Name | Description ------------- | ----------- -`$argc` | `int`; The number of command-line arguments passed to the script. This is at least 1. (See `$argv` below). This may not be available in non-command-line builds of the Engine. -`$argv` | `array`; An array of `$argc` elements containing the command-line arguments passed to the script as strings. Each element has an `int` key with the keys being numbered sequentially starting at zero through `$argc-1`. `$argv[0]` is the name of the script. It is implementation-defined as to how white space on command lines is handled, whether letter casing is preserved, which characters constitute quotes, or how `$argv[0]`'s string is formatted. As to how command-line arguments are defined, is unspecified. This may not be available in non-command-line builds of the Engine. +`$argc` | `int`; The number of command-line arguments passed to the script. This is at least 1. (See `$argv` below). This may not be available in non-command-line builds of the Engine. +`$argv` | `array`; An array of `$argc` elements containing the command-line arguments passed to the script as strings. Each element has an `int` key with the keys being numbered sequentially starting at zero through `$argc-1`. `$argv[0]` is the name of the script. It is implementation-defined as to how white space on command lines is handled, whether letter casing is preserved, which characters constitute quotes, or how `$argv[0]`'s string is formatted. As to how command-line arguments are defined, is unspecified. This may not be available in non-command-line builds of the Engine. `$_COOKIE` | `array`; The variables passed to the current script via HTTP Cookies. `$_ENV` | `array`; An array in which the environment variable names are element keys, and the environment variable value strings are element values. As to how an environment variable is defined, is unspecified. `$_FILES` | `array`; The items uploaded to the current script via the HTTP POST method. @@ -300,6 +480,6 @@ Variable Name | Description `$_POST` | `array`; The variables passed to the current script via the HTTP POST method. `$_REQUEST` | `array`; By default contains the contents of `$_COOKIE`, `$_GET`, and `$_POST`. The exact contents may depend on the Engine settings. `$_SERVER` | `array`; Server and execution environment information, such as headers, paths, and script locations. The entries in this array are taken from the Engine environment, e.g. the webserver. -`$_SESSION` | `array`; The session variables available to the current script. This global is defined only if a [session](http://php.net/manual/en/book.session.php) is active. +`$_SESSION` | `array`; The session variables available to the current script. This global is defined only if a [session](http://php.net/manual/en/book.session.php) is active. All `$_*` variables above are superglobals. The exact set of the variables available may depend on the implementation, the Engine build and the environment. diff --git a/spec/08-conversions.md b/spec/08-conversions.md index 29cbf356..069676d6 100644 --- a/spec/08-conversions.md +++ b/spec/08-conversions.md @@ -1,10 +1,10 @@ -#Conversions +# Conversions -##General +## General Explicit type conversion is performed using the [cast operator](10-expressions.md#cast-operator). If an operation or language construct expects operand of one type and a value of another type is given, -implict (automatic) conversion will be performed. Same will happen with most internal functions, though some +implicit (automatic) conversion will be performed. Same will happen with most internal functions, though some functions may do different things depending on argument type and thus would not perform the conversion. If an expression is converted to its own type, the type and value of the @@ -12,9 +12,9 @@ result are the same as the type and value of the expression. Conversions to `resource` and `null` types can not be performed. -##Converting to Boolean Type +## Converting to Boolean Type -The [result type] (http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting) is [`bool`](05-types.md#the-boolean-type). +The [result type](http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting) is [`bool`](05-types.md#the-boolean-type). If the source type is `int` or `float`, then if the source value tests equal to 0, the result value is `FALSE`; otherwise, the result value is `TRUE`. @@ -34,7 +34,7 @@ If the source is a resource, the result value is `TRUE`. The library function [`boolval`](http://www.php.net/boolval) allows values to be converted to `bool`. -##Converting to Integer Type +## Converting to Integer Type The [result type](http://www.php.net/manual/en/language.types.integer.php#language.types.integer.casting) is [`int`](05-types.md#the-integer-type). @@ -42,7 +42,7 @@ If the source type is `bool`, then if the source value is `FALSE`, the result value is 0; otherwise, the result value is 1. If the source type is `float`, for the values `INF`, `-INF`, and `NAN`, the -result value is implementation-defined. For all other values, if the +result value is zero. For all other values, if the precision can be preserved (that is, the float is within the range of an integer), the fractional part is rounded towards zero. If the precision cannot be preserved, the following conversion algorithm is used, where *X* is @@ -84,7 +84,7 @@ If the source is a resource, the result is the resource's unique ID. The library function [`intval`](http://php.net/manual/function.intval.php) allows values to be converted to `int`. -##Converting to Floating-Point Type +## Converting to Floating-Point Type The [result type](http://www.php.net/manual/en/language.types.float.php#language.types.float.casting) is [`float`](05-types.md#the-floating-point-type). @@ -110,7 +110,7 @@ For sources of all other types, the conversion result is obtained by first The library function [`floatval`](http://www.php.net/floatval) allows values to be converted to float. -##Converting to String Type +## Converting to String Type The [result type](http://www.php.net/manual/en/language.types.string.php#language.types.string.casting) is [`string`](05-types.md#the-string-type). @@ -136,7 +136,7 @@ implementation-defined string. The library function [`strval`](http://www.php.net/strval) allows values to be converted to string. -##Converting to Array Type +## Converting to Array Type The [result type](http://www.php.net/manual/en/language.types.array.php#language.types.array.casting) is [`array`](05-types.md#the-array-type). @@ -167,7 +167,7 @@ where *name* is that of the property. The value for each key is that from the corresponding property, or `NULL` if the property was not initialized. -##Converting to Object Type +## Converting to Object Type The [result type](http://www.php.net/manual/en/language.types.object.php#language.types.object.casting) is [`object`](05-types.md#objects). diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index f0c26712..537c9936 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -1,20 +1,19 @@ -#Lexical Structure +# Lexical Structure -##Scripts +## Scripts A [script](04-basic-concepts.md#program-structure) is an ordered sequence of characters. Typically, a script has a one-to-one correspondence with a file in a file system, but this correspondence is not required. +PHP scripts are parsed as a series of 8-bit bytes, rather than code points from Unicode or any other character repertoire. +Within this specification, bytes are represented by their ASCII interpretations where these are printable characters. Conceptually speaking, a script is translated using the following steps: -1. Transformation, which converts a script from a particular character - repertoire and encoding scheme into a sequence of 8-bit characters. - -2. Lexical analysis, which translates a stream of input characters into +1. Lexical analysis, which translates a stream of input characters into a stream of tokens. -3. Syntactic analysis, which translates the stream of tokens into +2. Syntactic analysis, which translates the stream of tokens into executable code. Conforming implementations must accept scripts encoded with the UTF-8 @@ -22,7 +21,7 @@ encoding form (as defined by the Unicode standard), and transform them into a sequence of characters. Implementations can choose to accept and transform additional character encoding schemes. -##Grammars +## Grammars This specification shows the syntax of the PHP programming language using two grammars. The *lexical grammar* defines how source @@ -43,13 +42,19 @@ successive indented line contains a possible expansion of the non-terminal given as a sequence of non-terminal or terminal symbols. For example, the production: + +
-  single-line-comment::
-    // input-charactersopt
-    #  input-charactersopt
+single-line-comment-example::
+   //   input-charactersopt
+   #   input-charactersopt
 
-defines the lexical grammar production *single-line-comment* as being +defines the lexical grammar production *single-line-comment-example* as being the terminals `//` or `#`, followed by an optional *input-characters*. Each expansion is listed on a separate line. @@ -57,37 +62,50 @@ Although alternatives are usually listed on separate lines, when there is a large number, the shorthand phrase β€œone of” may precede a list of expansions given on a single line. For example, + +
-  hexadecimal-digit:: one of
-    0   1   2   3   4   5   6   7   8   9
-    a   b   c   d   e   f
-    A   B   C   D   E   F
+hexadecimal-digit-example:: one of
+   0   1   2   3   4   5   6   7   8   9
+   a   b   c   d   e   f
+   A   B   C   D   E   F
 
-##Lexical analysis +## Lexical analysis -###General +### General The production *input-file* is the root of the lexical structure for a script. Each script must conform to this production. **Syntax** -
-  input-file::
-    input-element
-    input-file   input-element
-  input-element::
-    comment
-    white-space
-    token
-
+ -* [*comment*](#comments) -* [*white-space*](#white-space) -* [*token*](#tokens) +
+input-file::
+   input-element
+   input-file   input-element
+
+input-element::
+   comment
+   white-space
+   token
+
**Semantics** @@ -102,43 +120,68 @@ Lexical processing always results in the creation of the longest possible lexical element. (For example, `$a+++++$b` must be parsed as `$a++ ++ +$b`, which syntactically is invalid). -###Comments +### Comments Two forms of comments are supported: *delimited comments* and *single-line comments*. **Syntax** + +
-  comment::
-    single-line-comment
-    delimited-comment
-    
-  single-line-comment::
-    //   input-charactersopt
-    #    input-charactersopt
-
-  input-characters::
-    input-character
-    input-characters   input-character
-
-  input-character::
-    Any source character except new-line
-    
-  new-line::
-    Carriage-return character (U+000D)
-    Line-feed character (U+000A)
-    Carriage-return character (U+000D) followed by line-feed character (U+000A)
-
-  delimited-comment::
-    /*   No characters or any source character sequence except */   */
+comment::
+   single-line-comment
+   delimited-comment
+
+single-line-comment::
+   //   input-charactersopt
+   #   input-charactersopt
+
+input-characters::
+   input-character
+   input-characters   input-character
+
+input-character::
+   Any source character except   new-line
+
+new-line::
+   Carriage-return character (0x0D)
+   Line-feed character (0x0A)
+   Carriage-return character (0x0D) followed by line-feed character (0x0A)
+
+delimited-comment::
+   /*   No characters or any source character sequence except */   */
 
**Semantics** -Except within a string literal or a comment, the characters /\* start a -delimited comment, which ends with the characters \*/. Except within a -string literal or a comment, the characters // or \# start a single-line +Except within a string literal or a comment, the characters `/*` start a +delimited comment, which ends with the characters `*/`. Except within a +string literal or a comment, the characters `//` or `#` start a single-line comment, which ends with a new line. That new line is not part of the comment. However, if the single-line comment is the last source element in an embedded script, the trailing new line can be omitted. (Note: this @@ -154,99 +197,141 @@ space](#white-space) can occur. (For example; During tokenizing, an implementation can treat a delimited comment as though it was white space. -###White Space +### White Space White space consists of an arbitrary combination of one or more -new-line, space, horizontal tab, vertical tab, and form-feed characters. +new-line, space and horizontal tab characters. **Syntax** -
-  white-space::
-    white-space-character
-    white-space   white-space-character
-
-  white-space-character::
-    new-line
-    Space character (U+0020)
-    Horizontal-tab character (U+0009)
-
+ -* [*new-line*](#comments) +
+white-space::
+   white-space-character
+   white-space   white-space-character
+
+white-space-character::
+   new-line
+   Space character (0x20)
+   Horizontal-tab character (0x09)
+
**Semantics** The space and horizontal tab characters are considered *horizontal white-space characters*. -###Tokens +### Tokens -####General +#### General There are several kinds of source *tokens*: **Syntax** + +
-  token::
-    variable-name
-    name
-    keyword
-    literal
-    operator-or-punctuator
+token::
+   variable-name
+   name
+   keyword
+   integer-literal
+   floating-literal
+   string-literal
+   operator-or-punctuator
 
-**Defined elsewhere** +#### Names -* [*variable-name*](#names) -* [*name*](#names) -* [*keyword*](#keywords) -* [*literal*](#general-2) -* [*operator-or-punctuator*](#operators-and-punctuators) +**Syntax** -####Names + + +
+variable-name::
+   $   name
+
+namespace-name::
+   name
+   namespace-name   \   name
+
+namespace-name-as-a-prefix::
+   \
+   \opt   namespace-name   \
+   namespace   \
+   namespace   \   namespace-name   \
+
+qualified-name::
+   namespace-name-as-a-prefixopt   name
+
+name::
+   name-nondigit
+   name   name-nondigit
+   name   digit
+
+name-nondigit::
+   nondigit
+   one of the characters 0x80–0xff
+
+nondigit:: one of
+   _
+   a   b   c   d   e   f   g   h   i   j   k   l   m
+   n   o   p   q   r   s   t   u   v   w   x   y   z
+   A   B   C   D   E   F   G   H   I   J   K   L   M
+   N   O   P   Q   R   S   T   U   V   W   X   Y   Z
+
**Semantics** @@ -258,21 +343,27 @@ Names are used to identify the following: [constants](06-constants.md#general), and names in [heredoc](#heredoc-string-literals) and [nowdoc comments](#nowdoc-string-literals). A *name* begins with an underscore (_), *name-nondigit*, or extended -name character in the range U+007f–-U+00ff. Subsequent characters can +name character in the range 0x80–-0xff. Subsequent characters can also include *digits*. A *variable name* is a name with a leading dollar ($). Unless stated otherwise ([functions](13-functions.md#function-definitions), [classes](14-classes.md#class-declarations), [methods](14-classes.md#methods), [interfaces](15-interfaces.md#interface-declarations), [traits](16-traits.md#trait-declarations), -[namespaces](18-namespaces.md#defining-namespaces), names are case-sensitive, and every character in a name is significant. +[namespaces](18-namespaces.md#defining-namespaces)), names are case-sensitive, and every character in a name is significant. Names beginning with two underscores (__) are reserved by the PHP language and should not be defined by the user code. +The following names cannot be used as the names of classes, interfaces, or traits: `bool`, `FALSE`, `float`, `int`, `NULL`, `string`, `TRUE`, `iterable`, and `void`. + +The following names are reserved for future use and should not be used as the names of classes, interfaces, or traits: `mixed`, `numeric`, `object`, and `resource`. + +With the exception of `class`, all [keywords](#keywords) can be used as names for the members of a class, interface, or trait. However, `class` can be used as the name of a property or method. + Variable names and function names (when used in a function-call context) need not be defined as source tokens; they can also be created at -runtime using the [variable name-creation operator](10-expressions.md#variable-name-creation-operator). (For -example, given `$a = "Total"; $b = 3; $c = $b + 5;`, `${$a.$b.$c} = TRUE;` +runtime using [simple variable expressions](10-expressions.md#simple-variable). (For +example, given `$a = "Total"; $b = 3; $c = $b + 5;`, `${$a.$b.$c} = TRUE;` is equivalent to `$Total38 = TRUE;`, and `${$a.$b.$c}()` is equivalent to `Total38()`). @@ -290,99 +381,145 @@ interface ICollection { /*...*/ } An implementation is discouraged from placing arbitrary restrictions on name lengths. -####Keywords +#### Keywords A *keyword* is a name-like sequence of characters that is reserved, and cannot be used as a name. **Syntax** + +
-  keyword:: one of
-    abstract   and   as   break   callable   case   catch   class   clone   
-    const   continue   declare   default   do   echo   else   elseif   
-    enddeclare   endfor   endforeach   endif   endswitch   endwhile
-    extends   final   finally   for   foreach   function   global
-    goto   if   implements   include   include_once   instanceof
-    insteadof   interface   list   namespace   new   or   print   private
-    protected   public   require   require_once   return static   switch
-    throw   trait   try   use   var   while   xor   yield
+keyword:: one of
+   abstract   and   array   as   break   callable   case   catch   class   clone
+   const   continue   declare   default   die   do   echo   else   elseif   empty
+   enddeclare   endfor   endforeach   endif   endswitch   endwhile   eval   exit
+   extends   final   finally   for   foreach   function   global
+   goto   if   implements   include   include_once   instanceof
+   insteadof   interface   isset   list   namespace   new   or   print   private
+   protected   public   require   require_once   return   static   switch
+   throw   trait   try   unset   use   var   while   xor   yield   yield from
 
**Semantics** Keywords are not case-sensitive. -####Literals +Note carefully that `yield from` is a single token that contains whitespace. However, [comments](#comments) are not permitted in that whitespace. + +Also, all [*magic constants*](06-constants.md#context-dependent-constants) are also treated as keywords. -#####General +#### Literals The source code representation of a value is called a *literal*. +##### Integer Literals + **Syntax** -
-  literal::
-    integer-literal
-    floating-literal
-    string-literal
-
+
-  integer-literal::
-    decimal-literal
-    octal-literal
-    hexadecimal-literal
-    binary-literal
-
-    decimal-literal::
-      nonzero-digit
-      decimal-literal   digit
-
-    octal-literal::
-      0
-      octal-literal   octal-digit
-
-    hexadecimal-literal::
-      hexadecimal-prefix   hexadecimal-digit
-      hexadecimal-literal   hexadecimal-digit
-
-    hexadecimal-prefix:: one of
-      0x  0X
-
-    binary-literal::
-      binary-prefix   binary-digit
-      binary-literal   binary-digit
-
-    binary-prefix:: one of
-      0b  0B
-
-    digit:: one of
-      0  1  2  3  4  5  6  7  8  9
-
-    nonzero-digit:: one of
-      1  2  3  4  5  6  7  8  9
-      
-    octal-digit:: one of
-      0  1  2  3  4  5  6  7
-
-    hexadecimal-digit:: one of
-      0  1  2  3  4  5  6  7  8  9
-      a  b  c  d  e  f
-      A  B  C  D  E  F
-
-    binary-digit:: one of
-        0  1
+integer-literal::
+   decimal-literal
+   octal-literal
+   hexadecimal-literal
+   binary-literal
+
+decimal-literal::
+   nonzero-digit
+   decimal-literal   digit
+
+octal-literal::
+   0
+   octal-literal   octal-digit
+
+hexadecimal-literal::
+   hexadecimal-prefix   hexadecimal-digit
+   hexadecimal-literal   hexadecimal-digit
+
+hexadecimal-prefix:: one of
+   0x   0X
+
+binary-literal::
+   binary-prefix   binary-digit
+   binary-literal   binary-digit
+
+binary-prefix:: one of
+   0b   0B
+
+digit:: one of
+   0   1   2   3   4   5   6   7   8   9
+
+nonzero-digit:: one of
+   1   2   3   4   5   6   7   8   9
+
+octal-digit:: one of
+   0   1   2   3   4   5   6   7
+
+hexadecimal-digit:: one of
+   0   1   2   3   4   5   6   7   8   9
+   a   b   c   d   e   f
+   A   B   C   D   E   F
+
+binary-digit:: one of
+   0   1
 
**Semantics** @@ -428,34 +565,51 @@ On an implementation using 32-bit int representation 0x80000000 -> 2147483648 (too big for int, so is a float) ``` -#####Floating-Point Literals +##### Floating-Point Literals **Syntax** -
-  floating-literal::
-    fractional-literal   exponent-partopt
-    digit-sequence   exponent-part
+
+
+
+floating-literal::
+   fractional-literal   exponent-partopt
+   digit-sequence   exponent-part
+
+fractional-literal::
+   digit-sequenceopt   .   digit-sequence
+   digit-sequence   .
 
-**Defined elsewhere**
+exponent-part::
+   e   signopt   digit-sequence
+   E   signopt   digit-sequence
 
-* [*digit*](#integer-literals)
+sign:: one of
+   +   -
+
+digit-sequence::
+   digit
+   digit-sequence   digit
+
**Constraints** @@ -466,7 +620,7 @@ The value of a floating-point literal must be representable by its type. The type of a *floating-literal* is `float`. The constants [`INF`](06-constants.md#core-predefined-constants) and -[`NAN`](06-constants.md#core-predefined-constants) provide access to the +[`NAN`](06-constants.md#core-predefined-constants) provide access to the floating-point values for infinity and Not-a-Number, respectively. A floating point literal is always a constant expression. @@ -477,25 +631,26 @@ A floating point literal is always a constant expression. $values = array(1.23, 3e12, 543.678E-23); ``` -#####String Literals +##### String Literals **Syntax** + +
-  string-literal::
-    single-quoted-string-literal
-    double-quoted-string-literal
-    heredoc-string-literal
-    nowdoc-string-literal
+string-literal::
+   single-quoted-string-literal
+   double-quoted-string-literal
+   heredoc-string-literal
+   nowdoc-string-literal
 
-**Defined elsewhere** - -* [*single-quoted-string-literal*](#single-quoted-string-literals) -* [*double-quoted-string-literal*](#double-quoted-string-literals) -* [*heredoc-string-literal*](#heredoc-string-literals) -* [*nowdoc-string-literal*](#nowdoc-string-literals) - **Semantics** A string literal is a sequence of zero or more characters delimited in @@ -503,36 +658,58 @@ some fashion. The delimiters are not part of the literal's content. The type of a string literal is `string`. -######Single-Quoted String Literals +###### Single-Quoted String Literals **Syntax** + +
-  single-quoted-string-literal::
-    bopt  ' sq-char-sequenceopt  '
+single-quoted-string-literal::
+   b-prefixopt   '   sq-char-sequenceopt   '
+
+sq-char-sequence::
+   sq-char
+   sq-char-sequence   sq-char
 
-  sq-char-sequence::
-    sq-char
-    sq-char-sequence   sq-char
+sq-char::
+   sq-escape-sequence
+   \opt   any member of the source character set except single-quote (') or backslash (\)
 
-  sq-char::
-    sq-escape-sequence
-    \opt   any member of the source character set except single-quote (') or backslash (\)
+sq-escape-sequence:: one of
+   \'   \\
 
-  sq-escape-sequence:: one of
-    \'  \\
+b-prefix:: one of
+   b   B
 
**Semantics** A single-quoted string literal is a string literal delimited by -single-quotes (`'`, U+0027). The literal can contain any source character except +single-quotes (`'`, 0x27). The literal can contain any source character except single-quote (`'`) and backslash (`\\`), which can only be represented by their corresponding escape sequence. -The optional `b` prefix is reserved for future use in dealing with +The optional *b-prefix* is reserved for future use in dealing with so-called *binary strings*. For now, a *single-quoted-string-literal* -with a `b` prefix is equivalent to one without. +with a *b-prefix* is equivalent to one without. A single-quoted string literal is always a constant expression. @@ -544,123 +721,194 @@ A single-quoted string literal is always a constant expression. 'Can embed a single quote (\') and a backslash (\\) like this' ``` -######Double-Quoted String Literals +###### Double-Quoted String Literals **Syntax** -
-  double-quoted-string-literal::
-    bopt  " dq-char-sequenceopt  "
-
-  dq-char-sequence::
-    dq-char
-    dq-char-sequence   dq-char
-
-  dq-char::
-    dq-escape-sequence
-    any member of the source character set except double-quote (") or backslash (\)
-    \  any member of the source character set except "\$efnrtvxX or octal-digit
-
-  dq-escape-sequence::
-    dq-simple-escape-sequence
-    dq-octal-escape-sequence
-    dq-hexadecimal-escape-sequence
-
-  dq-simple-escape-sequence:: one of
-    \"   \\   \$   \e   \f   \n   \r   \t   \v
-
-  dq-octal-escape-sequence::
-    \   octal-digit
-    \   octal-digit   octal-digit
-    \   octal-digit   octal-digit   octal-digit
-
-  dq-hexadecimal-escape-sequence::
-    \x  hexadecimal-digit   hexadecimal-digitopt
-    \X  hexadecimal-digit   hexadecimal-digitopt
-
+ + +
+double-quoted-string-literal::
+   b-prefixopt   "   dq-char-sequenceopt   "
+
+dq-char-sequence::
+   dq-char
+   dq-char-sequence   dq-char
+
+dq-char::
+   dq-escape-sequence
+   any member of the source character set except double-quote (") or backslash (\)
+   \   any member of the source character set except "\$efnrtvxX or   octal-digit
+
+dq-escape-sequence::
+   dq-simple-escape-sequence
+   dq-octal-escape-sequence
+   dq-hexadecimal-escape-sequence
+   dq-unicode-escape-sequence
+
+dq-simple-escape-sequence:: one of
+   \"   \\   \$   \e   \f   \n   \r   \t   \v
+
+dq-octal-escape-sequence::
+   \   octal-digit
+   \   octal-digit   octal-digit
+   \   octal-digit   octal-digit   octal-digit
+
+dq-hexadecimal-escape-sequence::
+   \x   hexadecimal-digit   hexadecimal-digitopt
+   \X   hexadecimal-digit   hexadecimal-digitopt
+
+dq-unicode-escape-sequence::
+   \u{   codepoint-digits   }
+
+codepoint-digits::
+   hexadecimal-digit
+   hexadecimal-digit   codepoint-digits
+
**Semantics** A double-quoted string literal is a string literal delimited by -double-quotes (`"`, U+0022). The literal can contain any source character except +double-quotes (`"`, 0x22). The literal can contain any source character except double-quote (`"`) and backslash (`\\`), which can only be represented by their corresponding escape sequence. Certain other (and sometimes non-printable) characters can also be expressed as escape sequences. -The optional `b` prefix is reserved for future use in dealing with +The optional *b-prefix* is reserved for future use in dealing with so-called *binary strings*. For now, a *double-quoted-string-literal* -with a `b` prefix is equivalent to one without. +with a *b-prefix* is equivalent to one without. An escape sequence represents a single-character encoding, as described in the table below: Escape sequence | Character name | Unicode character --------------- | --------------| ------ -\$ | Dollar sign | U+0024 -\" | Double quote | U+0022 -\\ | Backslash | U+005C -\e | Escape | U+001B -\f | Form feed | U+000C -\n | New line | U+000A -\r | Carriage Return | U+000D -\t | Horizontal Tab | U+0009 -\v | Vertical Tab | U+000B +\$ | Dollar sign | 0x24 +\" | Double quote | 0x22 +\\ | Backslash | 0x5C +\e | Escape | 0x1B +\f | Form feed | 0x0C +\n | New line | 0x0A +\r | Carriage Return | 0x0D +\t | Horizontal Tab | 0x09 +\v | Vertical Tab | 0x0B \ooo | 1–3-digit octal digit value ooo \xhh or \Xhh | 1–2-digit hexadecimal digit value hh +\u{xxxxxx} | UTF-8 encoding of Unicode codepoint U+xxxxxx | U+xxxxxx Within a double-quoted string literal, except when recognized as the start of an escape sequence, a backslash (\\) is retained verbatim. Within a double-quoted string literal a dollar ($) character not escaped by a backslash (\\) is handled using a variable substitution rules -described below. +described below. + +The `\u{xxxxxx}` escape sequence produces the UTF-8 encoding of the Unicode +codepoint with the hexadecimal number specified within the curly braces. +Implementations MUST NOT allow Unicode codepoints beyond U+10FFFF as this is +outside the range UTF-8 can encode (see +[RFC 3629](http://tools.ietf.org/html/rfc3629#section-3)). If a codepoint +larger than U+10FFFF is specified, implementations MUST error. +Implementations MUST pass through `\u` verbatim and not interpret it as an +escape sequence if it is not followed by an opening `{`, but if it is, +implementations MUST produce an error if there is no terminating `}` or the +contents are not a valid codepoint. Implementations MUST support leading zeroes, +but MUST NOT support leading or trailing whitespace for the codepoint between +the opening and terminating braces. Implementations MUST allow Unicode +codepoints that are not Unicode scalar values, such as high and low surrogates. + +A Unicode escape sequence cannot be created by variable substitution. For example, given `$v = "41"`, +`"\u{$v}"` results in `"\u41"`, a string of length 4, while `"\u{0$v}"` and `"\u{{$v}}"` contain +ill-formed Unicode escape sequences. **Variable substitution** The variable substitution accepts the following syntax: + +
-    string-variable::
-        variable-name   offset-or-propertyopt
-        ${   expression   }  
-
-    offset-or-property::
-        offset-in-string
-        property-in-string
-
-    offset-in-string::
-        [   name   ]
-        [   variable-name   ]
-        [   integer-literal   ]
-        
-    property-in-string::
-        ->   name
-        
-
+string-variable:: + variable-name offset-or-propertyopt + ${ expression } + +offset-or-property:: + offset-in-string + property-in-string -**Defined elsewhere** +offset-in-string:: + [ name ] + [ variable-name ] + [ integer-literal ] -* [*variable-name*](#names) -* [*name*](#names) -* [*integer-literal*](#integer-literals) -* [*expression*](10-expressions.md#general-6) +property-in-string:: + -> name +
-*expression* works the same way as in [variable name creation operator](10-expressions.md#variable-name-creation-operator). +*expression* works the same way as in [simple variable expressions](10-expressions.md#simple-variable). After the variable defined by the syntax above is evaluated, its value is converted to string according to the rules of [string conversion](08-conversions.md#converting-to-string-type) -and is substituted into the string in place of the variable substitution expression. +and is substituted into the string in place of the variable substitution expression. Subscript or property access defined by *offset-in-string* and *property-in-string* is resolved according to the rules of the [subscript operator](10-expressions.md#subscript-operator) -and [member selection operator](10-expressions.md#member-selection-operator) respectively. -The exception is that *name* inside *offset-in-string* is interpreted as a string literal even if it is not -quoted. +and [member access operator](10-expressions.md#member-access-operator) respectively. +The exception is that *name* inside *offset-in-string* is interpreted as a string literal even if it is not +quoted. If the character sequence following the `$` does not parse as *name* and does not start with `{`, the `$` character is instead interpreted verbatim and no variable substitution is performed. @@ -673,9 +921,9 @@ begin a variable name. If this is not the case, braces are treated verbatim. If the opening brace (`{`) is escaped it is not interpreted as a start of the embedded expression and instead is interpreted verbatim. -The value of the expression is converted to string according to the rules of +The value of the expression is converted to string according to the rules of [string conversion](08-conversions.md#converting-to-string-type) and is substituted into the string -in place of the substitution expression. +in place of the substitution expression. A double-quoted string literal is a constant expression if it does not contain any variable substitution. @@ -698,45 +946,75 @@ $myC = new C(); echo "\$myC->p1 = >$myC->p1<\n"; // β†’ $myC->p1 = >2< ``` -######Heredoc String Literals +###### Heredoc String Literals **Syntax** -
-  heredoc-string-literal::
-    <<<  hd-start-identifier   new-line   hd-char-sequenceopt  new-line hd-end-identifier  ;opt   new-line
+
 
-**Defined elsewhere**
+
+heredoc-string-literal::
+   b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
 
-* [*name*](#names)
-* [*new-line*](#comments)
-* [*dq-octal-escape-sequence*](#double-quoted-string-literals)
-* [*dq-hexadecimal-escape-sequence*](#double-quoted-string-literals)
+hd-start-identifier::
+   name
+   "   name   "
+
+hd-end-identifier::
+   name
+
+hd-body::
+   hd-char-sequenceopt   new-line
+
+hd-char-sequence::
+   hd-char
+   hd-char-sequence   hd-char
+
+hd-char::
+   hd-escape-sequence
+   any member of the source character set except backslash (\)
+   \ any member of the source character set except \$efnrtvxX or   octal-digit
+
+hd-escape-sequence::
+   hd-simple-escape-sequence
+   dq-octal-escape-sequence
+   dq-hexadecimal-escape-sequence
+   dq-unicode-escape-sequence
+
+hd-simple-escape-sequence:: one of
+   \\   \$   \e   \f   \n   \r   \t   \v
+
**Constraints** @@ -761,6 +1039,8 @@ A heredoc literal supports variable substitution as defined for A heredoc string literal is a constant expression if it does not contain any variable substitution. +The optional *b-prefix* has no effect. + **Examples** ```PHP @@ -774,25 +1054,25 @@ echo ">$s<"; // Some more text< ``` -######Nowdoc String Literals +###### Nowdoc String Literals **Syntax** + +
-  nowdoc-string-literal::
-    <<<  '  name  '  new-line  hd-char-sequenceopt   new-line name  ;opt   new-line
+nowdoc-string-literal::
+   b-prefixopt   <<<   '   name   '   new-line   hd-bodyopt   name   ;opt   new-line
 
-**Defined elsewhere** - -* [*hd-char-sequence*](#heredoc-string-literals) -* [*new-line*](#comments) - **Constraints** The start and end identifier names must be the same. No white space is permitted between the start identifier name and its -enclosing single quotes (`'`). See also [heredoc string literal](#heredoc-string-literals). +enclosing single quotes (`'`). See also [heredoc string literal](#heredoc-string-literals). **Semantics** @@ -804,6 +1084,8 @@ not subject to variable substitution (like the single-quoted string). A nowdoc string literal is a constant expression. +The optional *b-prefix* has no effect. + **Examples** ```PHP @@ -817,16 +1099,24 @@ echo ">$s<\n\n"; // Some more text< ``` -####Operators and Punctuators +#### Operators and Punctuators **Syntax** + +
-  operator-or-punctuator:: one of
-    [   ]    (   )   {    }   .   ->   ++   --   **   *   +   -   ~   !
-    $   /   %   <<    >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
-    &   &&   ||   ?   :   ; =   **=   *=   /=   %=   +=   -=   .=   <<=
-    >>=   &=   ^=   |=   =&   ,
+operator-or-punctuator:: one of
+   [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
+   $   /   %   <<   >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
+   &   &&   ||   ?   :   ;   =   **=   *=   /=   %=   +=   -=   .=   <<=
+   >>=   &=   ^=   |=   ,   ??   <=>   ...   \
 
**Semantics** diff --git a/spec/10-expressions.md b/spec/10-expressions.md index fae970cd..a3289600 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -1,6 +1,6 @@ -#Expressions +# Expressions -##General +## General An *expression* involves one or more terms and zero or more operators. @@ -30,18 +30,18 @@ computations and side effects previously promised are complete, and no computations or side effects of future operations have yet begun. There is a sequence point at the end of each full expression. The [logical and](#logical-and-operator-form-1), [logical or](#logical-inclusive-or-operator-form-1), -[conditional](#logical-inclusive-or-operator-form-1), and [function call](#function-call-operator) +[conditional](#logical-inclusive-or-operator-form-1), [coalesce](#coalesce-operator) and [function call](#function-call-operator) operators each contain a sequence point. (For example, in the following series of expression statements, `$a = 10; ++$a; $b = $a;`, there is sequence point at the end of each full expression, so the -assignment to $a is completed before `$a` is incremented, and the +assignment to `$a` is completed before `$a` is incremented, and the increment is completed before the assignment to `$b`). When an expression contains multiple operators, the *precedence* of those operators controls the order in which those operators are applied. (For example, the expression `$a - $b / $c` is evaluated as -`$a - ($b / $c)` because the / operator has higher precedence than the -binary - operator). The precedence of an operator is determined by the +`$a - ($b / $c)` because the `/` operator has higher precedence than the +binary `-` operator). The precedence of an operator is determined by the definition of its associated grammar production. If an operand occurs between two operators having the same precedence, @@ -74,7 +74,7 @@ called, is unspecified). An expression that contains no side effects and whose resulting value is not used need not be evaluated. For example, the expression statements -`6;, $i + 6;`, and `$i/$j`; are well formed, but they contain no side +`6;`, `$i + 6;`, and `$i/$j`; are well formed, but they contain no side effects and their results are not used. A side effect need not be executed if it can be determined that no other @@ -83,166 +83,274 @@ of `return $a++;` and `return ++$a;`, it is obvious what value must be returned in each case, but if `$a` is a variable local to the enclosing function, `$a` need not actually be incremented. -##Primary Expressions +## Primary Expressions -###General +### General **Syntax** + +
-  primary-expression:
-    variable-name
-    qualified-name
-    literal
-    constant-expression
-    intrinsic
-    anonymous-function-creation-expression
-    (  expression  )
-    $this
+primary-expression:
+   variable
+   class-constant-access-expression
+   constant-access-expression
+   literal
+   array-creation-expression
+   intrinsic
+   anonymous-function-creation-expression
+   object-creation-expression
+   postfix-increment-expression
+   postfix-decrement-expression
+   prefix-increment-expression
+   prefix-decrement-expression
+   byref-assignment-expression
+   shell-command-expression
+   (   expression   )
 
-**Defined elsewhere** - -* [*variable-name*](09-lexical-structure.md#names) -* [*qualified-name*](09-lexical-structure.md#names) -* [*literal*](09-lexical-structure.md#general-2) -* [*constant-expression*](#constant-expressions) -* [*intrinsic*](#general-2) -* [*anonymous-function-creation-expression*](#anonymous-function-creation) -* [*expression*](#script-inclusion-operators) - **Semantics** The type and value of parenthesized expression are identical to those of the un-parenthesized expression. -The variable `$this` is predefined inside any non-static instance method (including -constructor) when that method is called from within an object -context. The value of `$this` is the calling object or the object being constructed. +### Simple Variable -###Intrinsics +**Syntax** -####General + -**Syntax**
-  intrinsic:
-    intrisic-construct
-    intrisic-operator
-
-  intrisic-construct:
-    echo-intrinsic
-    list-intrinsic
-    unset-intrinsic
-
-  intrinsic-operator:
-    array-intrinsic
-    empty-intrinsic
-    eval-intrinsic
-    exit-intrinsic
-    isset-intrinsic
-    print-intrinsic
+simple-variable:
+   variable-name
+   $   simple-variable
+   $   {   expression   }
 
-**Defined elsewhere** +**Constraints** -* [*array-intrinsic*](#array) -* [*echo-intrinsic*](#echo) -* [*empty-intrinsic*](#empty) -* [*eval-intrinsic*](#eval) -* [*exit-intrinsic*](#exitdie) -* [*isset-intrinsic*](#isset) -* [*list-intrinsic*](#list) -* [*print-intrinsic*](#print) -* [*unset-intrinsic*](#unset) +The *simple-variable* or *expression* in the last two variants +must designate a scalar value or object convertible to string. **Semantics** -The names in this series of sections have special meaning and are -called *intrinsics*, but they are not keywords; nor are they functions, they -are language constructs that are interpreted by the Engine. +A *simple-variable* expression designates a variable with the name determined by either +the *variable-name* or the string representation of the result of the *simple-variable* or +*expression*, depending on which case is applicable. In the latter two cases the variable +name may contain characters that are not allowed in a lexical +[variable-name](09-lexical-structure.md#names). -*intrinsic-operator* can be used as part of an expression, in any place -other values or expressions could be used. +The behavior of a *simple-variable* in different contexts and for different types of +variables is as specified in the [variables](07-variables.md) section. -*intrisic-construct* can be used only as stand-alone [statement](11-statements.md#statements). +The variable `$this` is predefined inside any non-static instance method (including +constructor) when that method is called from within an object +context. The value of `$this` is the calling object or the object being constructed. -####array +**Examples** + +```PHP +$color = "red"; +$$color = 123; // equivalent to $red = 123 +// ----------------------------------------- +$x = 'ab'; $ab = 'fg'; $fg = 'xy'; +$$ $ $x = 'Hello'; // equivalent to $xy = Hello +// ----------------------------------------- +$v1 = 3; +$$v1 = 22; // equivalent to ${3} = 22, variable name is "3" +$v2 = 9.543; +$$v2 = TRUE; // equivalent to ${9.543} = TRUE +$v3 = NULL; +$$v3 = "abc"; // equivalent to ${NULL} = "abc", here we create a variable with empty name +// ----------------------------------------- +function f1 () { return 2.5; } +${1 + f1()} = 1000; // equivalent to ${3.5} = 1000 +``` + +### Dereferencable expression **Syntax** + +
-  array-intrinsic:
-    array ( array-initializeropt  )
+dereferencable-expression:
+   variable
+   (   expression   )
+   array-creation-expression
+   string-literal
+
+callable-expression:
+   callable-variable
+   (   expression   )
+   array-creation-expression
+   string-literal
 
-**Defined elsewhere** +**Constraints** -* [*array-initializer*](#array-creation-operator) +The *string-literal* must not use variable interpolation and must not be a heredoc +or nowdoc string literal. **Semantics** -This intrinsic creates and initializes an array. It is equivalent to the -array-creation operator [`[]`](#array-creation-operator). +A *dereferencable-expression* can be used as the left hand side of dereferencing operators, such +as `[]`, `->` and `::`. A *callable-expression* can be used as the left hand side of the [function +call operator](#function-call-operator). -####echo +### Variables **Syntax** -
-  echo-intrinsic:
-    echo  expression
-    echo  expression-list-two-or-more
+
+
+
+callable-variable:
+   simple-variable
+   subscript-expression
+   member-call-expression
+   scoped-call-expression
+   function-call-expression
+
+variable:
+   callable-variable
+   scoped-property-access-expression
+   member-access-expression
 
-**Defined elsewhere** +**Semantics** -* [*expression*](#general-6) +A *variable* is an expression that can *in principle* be used as an lvalue. However, the +individual possible expressions may further restrict whether they can behave as lvalues. +An expression that is not a *variable* can never act as an lvalue. -**Constraints** +### Constant Access Expression -*expression* value must be [convertable to a string](08-conversions.md#converting-to-string-type). -In particular, it should not be an array and if it is an object, it must implement -a [`__toString` method](14-classes.md#method-__tostring). + + +
+constant-access-expression:
+   qualified-name
+
**Semantics** -After converting each of its *expression*s' values to strings, if -necessary, `echo` concatenates them in order given, and writes the -resulting string to [`STDOUT`](06-constants.md#core-predefined-constants). Unlike [`print`](#print), it does -not produce a result. +A *constant-access-expression* evaluates to the value of the [constant](06-constants.md) +with name *qualified-name*. -See also: [double quioted strings](09-lexical-structure.md#double-quoted-string-literals) and -[heredoc documents](09-lexical-structure.md#heredoc-string-literals), [conversion to string](08-conversions.md#converting-to-string-type). +### Literals -**Examples** +**Syntax** -```PHP -$v1 = TRUE; -$v2 = 123; -echo '>>' . $v1 . '|' . $v2 . "<<\n"; // outputs ">>1|123<<" -echo '>>' , $v1 , '|' , $v2 , "<<\n"; // outputs ">>1|123<<" -echo ('>>' . $v1 . '|' . $v2 . "<<\n"); // outputs ">>1|123<<" -$v3 = "qqq{$v2}zzz"; -echo "$v3\n"; -``` + + +
+literal:
+   integer-literal
+   floating-literal
+   string-literal
+
+ +**Semantics** -####empty +A literal evaluates to its value, as specified in the lexical specification for +[literals](09-lexical-structure.md#literals). + +### Intrinsics + +#### General **Syntax** +
-  empty-intrinsic:
-    empty ( expression  )
+intrinsic:
+   empty-intrinsic
+   eval-intrinsic
+   exit-intrinsic
+   isset-intrinsic
 
-**Defined elsewhere** +**Semantics** + +The names in this series of sections have special meaning and are +called *intrinsics*, but they are not keywords; nor are they functions, they +are language constructs that are interpreted by the Engine. -* [*expression*](#general-6) +#### empty + +**Syntax** + + + +
+empty-intrinsic:
+   empty   (   expression   )
+
**Semantics** @@ -270,23 +378,24 @@ $v = [10, 20]; empty($v); // results in FALSE ``` -####eval +#### eval **Syntax** + +
-  eval-intrinsic:
-    eval (  expression  )
+eval-intrinsic:
+   eval   (   expression   )
 
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** *expression* must designate a string, or be [convertable to a string](08-conversions.md#converting-to-string-type). -The contents of the string must be valid PHP source code. +The contents of the string must be valid PHP source code. If the source code is ill formed, an exception of type `ParseError` is thrown. The PHP source code in the string must not be delimited by opening and closing [PHP tags](04-basic-concepts.md#program-structure). However, the source code @@ -312,22 +421,26 @@ $str = "Hello"; eval("echo \$str . \"\\n\";"); // β†’ echo $str . "\n"; β†’ prints Hello ``` -####exit/die +#### exit/die **Syntax** + +
-  exit-intrinsic:
-    exit  expressionopt
-    exit  (  expressionopt  )
-    die   expressionopt
-    die   (   expressionopt )
+exit-intrinsic:
+   exit
+   exit   (   expressionopt   )
+   die
+   die   (   expressionopt   )
 
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** When *expression* designates an integer, its value must be in the range @@ -360,31 +473,32 @@ exit (1); exit; ``` -####isset +#### isset **Syntax** -
-  isset-intrinsic:
-    isset  (  expression-list-one-or-more  )
-
-  expression-list-one-or-more:
-    expression
-    expression-list-one-or-more  ,  expression
-
- -**Defined elsewhere** + -**Constraints** +
+isset-intrinsic:
+   isset   (   variable-list   ,opt   )
 
-Each *expression* must designate a variable.
+variable-list:
+   variable
+   variable-list   ,   variable
+
**Semantics** This intrinsic returns `TRUE` if all the variables designated by -*expression*s are set and their values are not `NULL`. Otherwise, it +*variables*s are set and their values are not `NULL`. Otherwise, it returns `FALSE`. If this intrinsic is used with an expression that designate a [dynamic @@ -405,195 +519,34 @@ $v1 = TRUE; $v2 = 12.3; $v3 = NULL; isset($v1, $v2, $v3); // results in FALSE ``` -####list - -**Syntax** - -
-  list-intrinsic:
-    list  (  list-expression-listopt  )
-
-  list-expression-list:
-    list-or-variable
-    ,
-    list-expression-list  ,  list-or-variableopt
-
-  list-or-variable:
-    list-intrinsic
-    expression
-
- -**Defined elsewhere** - -* [*expression*](#general-6) - -**Constraints** - -*list-intrinsic* must be used as the left-hand operand in a -[*simple-assignment-expression*](#simple-assignment) of which the right-hand -operand must be an expression that designates an array (called the *source -array*). - -Each *expression* in *expression-list-one-or-more* must designate a -variable (called the *target variable*). - -**Semantics** - -This intrinsic assigns zero or more elements of the source array to the -target variables. On success, it returns a copy of the source array. If -the source array is actually the value `NULL`, this is considered a failure, -and the return value from `list` is undefined. - -All elements in the source array having keys of type `string` are ignored. -The element having an `int` key of 0 is assigned to the first target -variable, the element having an `int` key of 1 is assigned to the second -target variable, and so on, until all target variables have been -assigned. Any other array elements are ignored. If there are -fewer source array elements having int keys than there are target -variables, the unassigned target variables are set to `NULL` and -a non-fatal error is produced. - -Any target variable may be a list, in which case, the corresponding -element is expected to be an array. - -If the source array elements and the target variables overlap in any -way, the behavior is unspecified. - -**Examples** - -```PHP -list($min, $max, $avg) = array(0, 100, 67); - // $min is 0, $max is 100, $avg is 67 -list($min, $max, $avg) = array(2 => 67, 1 => 100, 0 => 0); - // same as example above -list($min, , $avg) = array(0, 100, 67); - // $min is 0, $avg is 67 -list($min, $max, $avg) = array(0, 2 => 100, 4 => 67); - // $min is 0, $max is NULL, $avg is 100 -list($min, list($max, $avg)) = [0, [1 => 67, 99, 0 => 100], 33]; - // $min is 0, $max is 100, $avg is 67 -``` - -####print +### Anonymous Function Creation **Syntax** -
-  print-intrinsic:
-    print  expression
-    print  (  expression  )
-
+
-  unset-intrinsic:
-    unset  (  expression-list-one-or-more  )
-
- -**Defined elsewhere** - -* [*expression-list-one-or-more*](#isset) - -**Constraints** - -Each *expression* must designate a variable. - -**Semantics** +anonymous-function-creation-expression: + staticopt function &opt ( parameter-declaration-listopt ) anonymous-function-use-clauseopt return-typeopt compound-statement -This intrinsic [unsets](07-variables.md#general) the variables designated by each -*expression* in *expression-list-one-or-more*. No value is returned. An -attempt to unset a non-existent variable (such as a non-existent element -in an array) is ignored. - -When called from inside a function, this intrinsic behaves, as follows: - -- For a variable declared `global` in that function, `unset` removes the - alias to that variable from the scope of the current call to that - function. The global variable remains set. - (To unset the global variable, use unset on the corresponding - [`$GLOBALS`](07-variables.md#predefined-variables) array entry. -- For a variable passed byRef to that function, `unset` removes the - alias to that variable from the scope of the current call to that - function. Once the function returns, the passed-in argument variable - is still set. -- For a variable declared static in that function, `unset` removes the - alias to that variable from the scope of the current call to that - function. In subsequent calls to that function, the static variable - is still set and retains its value from call to call. - -Any visible instance property may be unset, in which case, the property -is removed from that instance. - -If this intrinsic is used with an expression that designates a [dynamic -property](14-classes.md#dynamic-members), then if the class of that property has an [`__unset` -method](14-classes.md#method-__unset), that method is called. - -**Examples** +anonymous-function-use-clause: + use ( use-variable-name-list ) -```PHP -unset($v); -unset($v1, $v2, $v3); -unset($x->m); // if m is a dynamic property, $x->__unset("m") is called -``` - -###Anonymous Function Creation - -**Syntax** - -
-  anonymous-function-creation-expression:
-  staticopt function  &opt (  parameter-declaration-listopt  )  anonymous-function-use-clauseopt
-      compound-statement
-
-  anonymous-function-use-clause:
-    use  (  use-variable-name-list  )
-
-  use-variable-name-list:
-    &opt   variable-name
-    use-variable-name-list  ,  &opt  variable-name
+use-variable-name-list:
+   &opt   variable-name
+   use-variable-name-list   ,   &opt   variable-name
 
-**Defined elsewhere** - -* [*parameter-declaration-list*](13-functions.md#function-definitions) -* [*compound-statement*](11-statements.md#compound-statements) -* [*variable-name*](09-lexical-structure.md#names) - **Semantics** This operator returns an object of type [`Closure`](14-classes.md#class-closure), or a derived @@ -616,7 +569,7 @@ An anonymous function defined inside an instance or static method has its [*scope*](14-classes.md#class-closure) set to the class it was defined in. Otherwise, an anonymous function is [*unscoped*](14-classes.md#class-closure). -An anonymous function defined inside an instance method is is [*bound*](14-classes.md#class-closure) +An anonymous function defined inside an instance method is [*bound*](14-classes.md#class-closure) to the object on which that method is called, while an an anonymous function defined inside a static method, or prefixed with the optional `static` modifier is [*static*](14-classes.md#class-closure), and otherwise @@ -637,7 +590,7 @@ class C public function compute(array $values) { $count = 0; - $callback1 = function () use (&$count) // has C as its scope + $callback1 = function () use (&$count) // has C as its scope { ++$count; //... @@ -653,125 +606,59 @@ class C } ``` -##Postfix Operators - -###General - -**Syntax** - -
-  postfix-expression:
-    primary-expression
-    clone-expression
-    object-creation-expression
-    array-creation-expression
-    subscript-expression
-    function-call-expression
-    member-selection-expression
-    postfix-increment-expression
-    postfix-decrement-expression
-    scope-resolution-expression
-    exponentiation-expression
-
- -**Defined elsewhere** - -* [*primary-expression*](#general-1) -* [*clone-expression*](#the-clone-operator) -* [*object-creation-expression*](#the-new-operator) -* [*array-creation-expression*](#array-creation-operator) -* [*subscript-expression*](#subscript-operator) -* [*function-call-expression*](#function-call-operator) -* [*member-selection-expression*](#member-selection-operator) -* [*postfix-increment-expression*](#postfix-increment-and-decrement-operators) -* [*postfix-decrement-expression*](#postfix-increment-and-decrement-operators) -* [*scope-resolution-expression*](#scope-resolution-operator) -* [*exponentiation-expression*](#exponentiation-operator) - -**Semantics** - -These operators associate left-to-right. - -###The `clone` Operator +### The `new` Operator **Syntax** -
-  clone-expression:
-    clone  expression
-
- -**Defined elsewhere** - -* [*expression*](#general-6) - -**Constraints** - -*expression* must designate an object. - -**Semantics** - -The `clone` operator creates a new object that is a shallow copy of the object designated by *expression*. -Then, if the class type of *expression* has a method called [`__clone`](14-classes.md#method-__clone), it is called to perform a deep copy. -The result is the new object. - -**Examples** - -Consider a class `Employee`, from which is derived a class `Manager`. Let us -assume that both classes contain properties that are objects. `clone` is -used to make a copy of a `Manager` object, and behind the scenes, the -`Manager` object uses clone to copy the properties for the base class, -`Employee`. - -```PHP -class Employee -{ - //... - public function __clone() - { - // make a deep copy of Employee object - } -} -class Manager extends Employee -{ - //... - public function __clone() - { - $v = parent::__clone(); - // make a deep copy of Manager object - - } -} -$obj1 = new Manager("Smith", 23); -$obj2 = clone $obj1; // creates a new Manager that is a deep copy -``` - -###The `new` Operator - -**Syntax** +
-  object-creation-expression:
-    new  class-type-designator  (  argument-expression-listopt  )
-    new  class-type-designator
-
-  class-type-designator:
-    qualified-name
-    expression
+object-creation-expression:
+   new   class-type-designator   (   argument-expression-listopt   )
+   new   class-type-designator   (   argument-expression-list   ,opt   )
+   new   class-type-designator
+   new   class   (   argument-expression-listopt   )   class-base-clauseopt   class-interface-clauseopt   {   class-member-declarationsopt   }
+   new   class   class-base-clauseopt   class-interface-clauseopt   {   class-member-declarationsopt   }
+
+class-type-designator:
+   qualified-name
+   new-variable
+
+new-variable:
+   simple-variable
+   new-variable   [   expressionopt   ]
+   new-variable   {   expression   }
+   new-variable   ->   member-name
+   qualified-name   ::   simple-variable
+   relative-scope   ::   simple-variable
+   new-variable   ::   simple-variable
 
-**Defined elsewhere** - -* [*argument-expression-list*](#function-call-operator) -* [*qualified-name*](09-lexical-structure.md#names) -* [*expression*](#general-6) - **Constraints** *qualified-name* must name a class. -*expression* must be a value of type `string` (but not be a string -literal) that contains the name of a class, or an object. +*new-variable* must be a value of type `string` that contains the name of a class, or an object. *class-type-designator* must not designate an [abstract class](14-classes.md#general). @@ -780,12 +667,13 @@ as many as the number of non-optional parameters defined for the class's [constr **Semantics** -The `new` operator creates an object that is an instance of -the class specified by *class-type-designator*. +The `new` *class-type-designator* forms create an object of the class type specified by *class-type-designator*. The `new class` forms create an object of an *anonymous class type*, a type that has an unspecified name. In all other respects, however, an anonymous class has the same capabilities as a named class type. -If the *class-type-designator* is an expression resulting in a string value, +If the *class-type-designator* is a *new-variable* resulting in a string value, that string is used as the class name. If the expression results in an object, -the class of the object is used as the class for the new object. +the class of the object is used as the class for the new object. The *new-variable* +has the same semantics as a *variable*, but the grammar is restricted to exclude +calls. The *qualified-name* is resolved according to the rules described in [scope resolution operator](#scope-resolution-operator), including @@ -800,8 +688,10 @@ passing it the optional *argument-expression-list*. If the class has no constructor, the constructor that class inherits (if any) is used. The class can also specify no constructor definition, in this case the constructor call is omitted. -The result of an *object-creation-expression* is an object -of the type specified by *class-type-designator*. +The result of a named-type *object-creation-expression* is an object of the type specified by *class-type-designator*. The result of an anonymous class *object-creation-expression* is an object of unspecified type. However, this type will subtype all types +provided by *class-base-clause* and *class-interface-clause* and the *class-members* definition should follow the same inheritance and implementation rules as the regular [class declaration](14-classes.md#class-declarations) does. + +Each distinct source code expression of the form `new class` results in the class type that is different from that of all other anonymous class types. However, multiple evaluations of the same source code expression of the form `new class` result in instances of the same class type. Because a constructor call is a function call, the relevant parts of [function call operator](#function-call-operator) section also apply. @@ -821,42 +711,63 @@ $p1 = new Point; // create Point(0, 0) $p1 = new Point(12); // create Point(12, 0) $cName = 'Point'; $p1 = new $cName(-1, 1); // create Point(-1, 1) +// ----------------------------------------- +$v2 = new class (100) extends C1 implements I1, I2 { + public function __construct($p) { + echo "Inside class " . __CLASS__ . " constructor with parameter $p\n"; + } +}; ``` -###Array Creation Operator - -An array is created and initialized by one of two equivalent ways: via -the array-creation operator `[]`, as described below, or the intrinsic -[`array`](#array). +### Array Creation Operator **Syntax** -
-  array-creation-expression:
-    array  (  array-initializeropt  )
-    [ array-initializeropt ]
+
+
+
+array-creation-expression:
+   array   (   array-initializeropt   )
+   [   array-initializeropt   ]
 
-**Defined elsewhere**
+array-initializer:
+   array-initializer-list   ,opt
 
-* [*expression*](#general-6)
+array-initializer-list:
+   array-element-initializer
+   array-element-initializer   ,   array-initializer-list
+
+array-element-initializer:
+   &opt   element-value
+   element-key   =>   &opt   element-value
+
+element-key:
+   expression
+
+element-value:
+   expression
+
**Constraints** @@ -921,29 +832,30 @@ foreach($v as $e) { /* ... */ } // iterates over keys 2, 0, 1, -1 for ($i = -1; $i <= 2; ++$i) { echo $v[$i]; } // retrieves via keys -1, 0, 1, 2 ``` -###Subscript Operator +### Subscript Operator **Syntax** + +
-  subscript-expression:
-    postfix-expression  [  expressionopt  ]
-    postfix-expression  {  expression  }   [Deprecated form]
+subscript-expression:
+   dereferencable-expression   [   expressionopt   ]
+   dereferencable-expression   {   expression   }   <b>[Deprecated form]</b>
 
-**Defined elsewhere** - -* [*postfix-expression*](#general-3) -* [*expression*](#general-6) - **Constraints** -If *postfix-expression* designates a string, *expression* must not +If *dereferencable-expression* designates a string, *expression* must not designate a string. *expression* can be omitted only if *subscript-expression* is used in a -modifiable-lvalue context and *postfix-expression* does not designate a string. -Exception from this is when *postfix-expression* is an empty string - then it is +modifiable-lvalue context and *dereferencable-expression* does not designate a string. +Exception from this is when *dereferencable-expression* is an empty string - then it is converted to an empty array. If *subscript-expression* is used in a non-lvalue context, the element @@ -962,23 +874,22 @@ or `bool` values, or strings whose contents match exactly the pattern of [*decimal-literal*](09-lexical-structure.md#integer-literals), are [converted to integer](08-conversions.md#converting-to-integer-type), and key values of all other types are [converted to string](08-conversions.md#converting-to-string-type). -If both *postfix-expression* and *expression* designate strings, +If both *dereferencable-expression* and *expression* designate strings, *expression* is treated as if it specified the `int` key zero instead and a non-fatal error is produces. A *subscript-expression* designates a modifiable lvalue if and only if -*postfix-expression* designates a modifiable lvalue. +*dereferencable-expression* designates a modifiable lvalue. -**postfix-expression designates an array** +**dereferencable-expression designates an array** If *expression* is present, if the designated element exists, the type and value of the result is the type and value of that element; otherwise, the result is `NULL`. If *expression* is omitted, a new element is inserted. Its key has type -`int` and is one more than the highest, previously assigned, non-negative -`int` key for this array. If this is the first element with a non-negative -`int` key, key `0` is used. +`int` and is one more than the highest, previously assigned `int` key for +this array. If this is the first element with an `int` key, key `0` is used. If the largest previously assigned `int` key is the largest integer value that can be represented, the new element is not added. The result is the added new element, or `NULL` if the element was not added. @@ -994,24 +905,25 @@ The result is the added new element, or `NULL` if the element was not added. [postfix- or prefix-increment or decrement operator](#postfix-increment-and-decrement-operators), the value of the new element is considered to be `NULL`. -**postfix-expression designates a string** +**dereferencable-expression designates a string** The *expression* is converted to `int` and the result is the character of the -string at the position equal to that integer. If the integer is negative or refers +string at the position corresponding to that integer. If the integer is negative, +the position is counted backwards from the end of the string. If the position refers to a non-existing offset, the result is an empty string. If the operator is used as the left-hand side of a [*simple-assignment-expression*](#simple-assignment), -the value being assigned is converted to string and the character in the specified offset will be -replaced by the first character of the string. If the assigned string is empty, the `'\0'` character is used. -If the string before the assignment had no such offset, the string is extended to include the offset -with `'\0'` characters. + +- If the assigned string is empty, or in case of non-existing negative offset (absolute value larger than string length), a warning is raised and no assignment is performed. +- If the offset is larger than the current string length, the string is extended to a length equal to the offset value, using space (0x20) padding characters. +- The value being assigned is converted to string and the character in the specified offset is replaced by the first character of the string. The subscript operator can not be used on a string value in a byRef context or as the operand of the [postfix- or prefix-increment or decrement operators](#postfix-increment-and-decrement-operators) or on the left side of [*compound-assignment-expression*](#compound-assignment), doing so will result in a fatal error. -**postfix-expression designates an object of a type that implements `ArrayAccess`** +**dereferencable-expression designates an object of a type that implements `ArrayAccess`** If *expression* is present, @@ -1074,6 +986,7 @@ $v["red"] = TRUE; // insert a new element with string key "red" function f() { return [1000, 2000, 3000]; } f()[2]; // designates element with value 3000 "red"[1.9]; // designates "e" +"red"[-2]; // designates "e" "red"[0][0][0]; // designates "r" // ----------------------------------------- class MyVector implements ArrayAccess { /* ... */ } @@ -1083,39 +996,54 @@ $vect1[] = "xxx"; // calls Vector::offsetSet(NULL, "xxx") $x = $vect1[1]; // calls Vector::offsetGet(1) ``` -###Function Call Operator +### Function Call Operator **Syntax** -
-  function-call-expression:
-    qualified-name  (  argument-expression-listopt  )
-    postfix-expression  (  argument-expression-listopt  )
+
 
+
+function-call-expression:
+   qualified-name   (   argument-expression-listopt   )
+   qualified-name   (   argument-expression-list   ,   )
+   callable-expression   (   argument-expression-listopt   )
+   callable-expression   (   argument-expression-list   ,   )
+
+argument-expression-list:
+   argument-expression
+   argument-expression-list   ,   argument-expression
+
+argument-expression:
+   variadic-unpacking
+   expression
+
+variadic-unpacking:
+   ...   expression
 
-**Defined elsewhere** - -* [*postfix-expression*](#general-3) -* [*assignment-expression*](#general-5) - **Constraints** -*postfix-expression* must designate a function, either by being its -*name*, by being a value of type string (but not a string literal) that -contains the function's name, or by being an object of a type that implements -[`__invoke`](14-classes.md#method-__invoke) method (including [`Closure`](14-classes.md#class-closure) objects). +*callable-expression* must designate a function, by being a value of type string +that contains the function's name, or by being an object of a type that implements +[`__invoke`](14-classes.md#method-__invoke) method (including +[`Closure`](14-classes.md#class-closure) objects). The number of arguments present in a function call must be at least as many as the number of non-optional parameters defined for that function. @@ -1135,18 +1063,12 @@ An expression of the form *function-call-expression* is a *function call*. The expression designates the *called function*, and *argument-expression-list* specifies the arguments to be passed to that function. An argument can be any value. In a function call, -*postfix-expression* is evaluated first, followed by each -*assignment-expression* in the order left-to-right. There is -a [sequence point](#general) after each argument is evaluated and right before the function is called. +*callable-expression* is evaluated first, followed by each +*expression* in the order left-to-right. There is +a [sequence point](#general) after each argument is evaluated and right before the function is called. For details of the result of a function call see [`return` statement](11-statements.md#the-return-statement). The value of a function call is a modifiable lvalue only if the function returns a modifiable value byRef. -When *postfix-expression* designates an instance method or constructor, -the instance used in that designation is used as the value of `$this` in -the invoked method or constructor. However, if no instance was used in -that designation (for example, in the call `C::instance_method()`) the -invoked instance has no `$this` defined. - When a function is called, the value of each argument passed to it is assigned to the corresponding parameter in that function's definition, if such a parameter exists. The assignment of argument values to @@ -1168,7 +1090,7 @@ defined, with an initial value of `NULL`. Direct and indirect recursive function calls are permitted. -If *postfix-expression* is a string, this is +If *callable-expression* is a string, this is a [variable function call](13-functions.md#variable-functions). If *variadic-unpacking* operation is used, the operand is considered to be a parameter list. @@ -1213,32 +1135,34 @@ $anon = function () { ... }; // store a Closure in $anon $anon(); // call the anonymous function encapsulated by that object ``` -###Member-Selection Operator +### Member Access Operator **Syntax** -
-  member-selection-expression:
-    postfix-expression  ->  member-selection-designator
+
 
-**Defined elsewhere**
+
+member-access-expression:
+   dereferencable-expression   ->   member-name
 
-* [*postfix-expression*](#general-3)
-* [*name*](09-lexical-structure.md#names)
-* [*expression*](#general-6)
+member-name:
+   name
+   simple-variable
+   {   expression   }
+
**Constraints** -*postfix-expression* must designate an object or be `NULL`, `FALSE`, or an -empty string. - -*name* must designate an instance property, or an instance or static -method of *postfix-expression*'s class type. +The *dereferencable-expression* must designate an object or be `NULL`, `FALSE`, +or an empty string. *expression* must be a value of type `string` (but not a string literal) that contains the name of an instance property (**without** the @@ -1247,25 +1171,24 @@ type. **Semantics** -A *member-selection-expression* designates an instance property or an -instance or static method of the object designated by -*postfix-expression*. For a property, the value is that of the property, -and is a modifiable lvalue if *postfix-expression* is a modifiable -lvalue. +A *member-access-expression* designates an instance property of the object +designated by *dereferencable-expression* with the name given by the string +representation of *member-name*. The value is that of the property, and is a +modifiable lvalue if *dereferencable-expression* is a modifiable lvalue. -When the `->` operator is used in a modifiable lvalue context and *name* -or *expression* designate a property that is not visible, the property -is treated as a [dynamic property](14-classes.md#dynamic-members). If *postfix-expression*'s class +When the `->` operator is used in a modifiable lvalue context and *member-name* +designate a property that is not visible, the property is treated as a +[dynamic property](14-classes.md#dynamic-members). If *dereferencable-expression*'s class type defines a [`__set` method](14-classes.md#method-__set), it is called to store the property's value. When the `->` operator is used in a non-lvalue context -and *name* or *expression* designate a property that is not visible, the -property is treated as a dynamic property. If *postfix-expression*'s -class type defines a [`__get` method](14-classes.md#method-__get), it is called to retrieve -the property's value. - -If *postfix-expression* is `NULL`, `FALSE`, or an empty string, an expression -of the form `$p->x = 10` causes an instance of [`stdClass`](14-classes.md#class-stdclass) to be -created with a dynamic property x having a value of 10. `$p` is then made +and *member-name* designate a property that is not visible, the property +is treated as a dynamic property. If *dereferencable-expression*'s +class type defines a [`__get` method](14-classes.md#method-__get), +it is called to retrieve the property's value. + +If *dereferencable-expression* is `NULL`, `FALSE`, or an empty string, an expression +of the form `$p->x = 10` causes an instance of [`stdClass`](14-classes.md#class-stdclass) +to be created with a dynamic property `x` having a value of 10. `$p` is then made to refer to this instance. **Examples** @@ -1283,9 +1206,10 @@ class Point public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; - } // get private properties $x and $y - public function __set($name, $value) { ... } - public function __get($name) { ... } + } + // get private properties $x and $y + public function __set($name, $value) { ... } + public function __get($name) { ... } } $p1 = new Point; $p1->move(3, 9); // calls public instance method move by name @@ -1295,21 +1219,67 @@ $p1->color = "red"; // turned into $p1->__set("color", "red"); $c = $p1->color; // turned into $c = $p1->__get("color"); ``` -###Postfix Increment and Decrement Operators +### Member Call Operator **Syntax** -
-  postfix-increment-expression:
-    unary-expression  ++
+
 
-  postfix-decrement-expression:
-    unary-expression  --
+
+member-call-expression:
+   dereferencable-expression   ->   member-name   (   argument-expression-listopt   )
+   dereferencable-expression   ->   member-name   (   argument-expression-list   ,   )
 
-**Defined elsewhere** +**Constraints** + +The *dereferencable-expression* must designate an object. + +Additionally the general [function call constraints](#function-call-operator) +apply. + +**Semantics** + +A *member-call-expression* calls an instance or static method of the +object designated by *dereferencable-expression*, with the method +name given by the string representation of *member-name* and the +arguments given by *argument-expression-list*. The value of +*dereferencable-expression* is used as the value of `$this` in the +invoked method. + +The general [function call semantics](#function-call-operator) apply. + +If the called method does not exist or is not visible from the current +scope an exception is thrown, unless a [`__call` method](14-classes.md#method-__call) +exists, in which case it will be called instead. + +**Examples** + +See [member access examples](#member-access-operator). + +### Postfix Increment and Decrement Operators -* [*unary-expression*](#general-4) +**Syntax** + + + +
+postfix-increment-expression:
+   variable   ++
+
+postfix-decrement-expression:
+   variable   --
+
**Constraints** @@ -1329,36 +1299,212 @@ $i = 10; $j = $i-- + 100; // old value of $i (10) is added to 100 $a = array(100, 200); $v = $a[1]++; // old value of $ia[1] (200) is assigned ``` -###Scope-Resolution Operator +### Prefix Increment and Decrement Operators + +**Syntax** + + + +
+prefix-increment-expression:
+   ++   variable
+
+prefix-decrement-expression:
+   --   variable
+
+ +**Constraints** + +The operand of the prefix `++` or `--` operator must be a modifiable lvalue +that has scalar-compatible type. + +**Semantics** + +*Arithmetic Operands* + +For a prefix `++` operator used with an arithmetic operand, the [side +effect](#general) of the operator is to increment the value of the operand by 1. +The result is the value of the operand after it +has been incremented. If an `int` operand's value is the largest +representable for that type, the operand is incremented as if it were `float`. + +For a prefix `--` operator used with an arithmetic operand, the side +effect of the operator is to decrement the value of the operand by 1. +The result is the value of the operand after it has been +decremented. If an `int` operand's value is the smallest representable for +that type, the operand is decremented as if it were `float`. + +For a prefix `++` or `--` operator used with an operand having the value +`INF`, `-INF`, or `NAN`, there is no side effect, and the result is the +operand's value. + +*Boolean Operands* + +For a prefix `++` or `--` operator used with a Boolean-valued operand, there +is no side effect, and the result is the operand's value. + +*NULL-valued Operands* + +For a prefix -- operator used with a `NULL`-valued operand, there is no +side effect, and the result is the operand's value. For a prefix `++` +operator used with a `NULL`-valued operand, the side effect is that the +operand's type is changed to int, the operand's value is set to zero, +and that value is incremented by 1. The result is the value of the +operand after it has been incremented. + +*String Operands* + +For a prefix `--` operator used with an operand whose value is an empty +string, the side effect is that the operand's type is changed to `int`, +the operand's value is set to zero, and that value is decremented by 1. +The result is the value of the operand after it has been incremented. + +For a prefix `++` operator used with an operand whose value is an empty +string, the side effect is that the operand's value is changed to the +string "1". The type of the operand is unchanged. The result is the new +value of the operand. + +For a prefix `--` or `++` operator used with a numeric string, the numeric +string is treated as the corresponding `int` or `float` value. + +For a prefix `--` operator used with a non-numeric string-valued operand, +there is no side effect, and the result is the operand's value. + +For a non-numeric string-valued operand that contains only alphanumeric +characters, for a prefix `++` operator, the operand is considered to be a +representation of a base-36 number (i.e., with digits 0–9 followed by A–Z or a–z) in +which letter case is ignored for value purposes. The right-most digit is +incremented by 1. For the digits 0–8, that means going to 1–9. For the +letters "A"–"Y" (or "a"–"y"), that means going to "B"–"Z" (or "b"–"z"). +For the digit 9, the digit becomes 0, and the carry is added to the next +left-most digit, and so on. For the digit "Z" (or "z"), the resulting +string has an extra digit "A" (or "a") appended. For example, when +incrementing, "a" -> "b", "Z" -> "AA", "AA" -> "AB", "F29" -> "F30", "FZ9" -> "GA0", and "ZZ9" -> "AAA0". A digit position containing a number wraps +modulo-10, while a digit position containing a letter wraps modulo-26. + +For a non-numeric string-valued operand that contains any +non-alphanumeric characters, for a prefix `++` operator, all characters up +to and including the right-most non-alphanumeric character is passed +through to the resulting string, unchanged. Characters to the right of +that right-most non-alphanumeric character are treated like a +non-numeric string-valued operand that contains only alphanumeric +characters, except that the resulting string will not be extended. +Instead, a digit position containing a number wraps modulo-10, while a +digit position containing a letter wraps modulo-26. + +*Object Operands* + +If the operand has an object type supporting the operation, +then the object semantics defines the result. Otherwise, the operation has +no effect and the result is the operand. + +**Examples** + +```PHP +$i = 10; $j = --$i + 100; // new value of $i (9) is added to 100 +$a = array(100, 200); $v = ++$a[1]; // new value of $a[1] (201) is assigned +$a = "^^Z"; ++$a; // $a is now "^^A" +$a = "^^Z^^"; ++$a; // $a is now "^^Z^^" +``` + +### Shell Command Operator **Syntax** + +
-  scope-resolution-expression:
-    scope-resolution-qualifier  ::  member-selection-designator
-    scope-resolution-qualifier  ::  class
-
-  scope-resolution-qualifier:
-    relative-scope
-    qualified-name
-    expression
-
-  relative-scope:
-    self
-    parent
-    static
+shell-command-expression:
+   `   dq-char-sequenceopt   `
 
-**Defined elsewhere** +where \` is the GRAVE ACCENT character 0x60, commonly referred to as a +*backtick*. + +**Semantics** + +This operator passes *dq-char-sequence* to the command shell for +execution, as though it was being passed to the library function +[`shell_exec`](http://www.php.net/shell_exec). If the output from execution of that command is +written to [`STDOUT`](06-constants.md#core-predefined-constants), that output is the result of this operator +as a string. If the output is redirected away from `STDOUT`, or +*dq-char-sequence* is empty or contains only white space, the result of +the operator is `NULL`. + +If [`shell_exec`](http://php.net/manual/function.shell-exec.php) is disabled, this operator is disabled. + +**Examples** + +```PHP +$result = `ls`; // result is the output of command ls +$result = `ls >dirlist.txt`; // result is NULL +$d = "dir"; $f = "*.*"; +$result = `$d {$f}`; // result is the output of command dir *.* +``` + +### Scope-Resolution Operator + +**Syntax** -* [*member-selection-designator*](#member-selection-operator) + + +
+scoped-property-access-expression:
+   scope-resolution-qualifier   ::   simple-variable
+
+scoped-call-expression:
+   scope-resolution-qualifier   ::   member-name   (   argument-expression-listopt   )
+   scope-resolution-qualifier   ::   member-name   (   argument-expression-list   ,   )
+
+class-constant-access-expression:
+   scope-resolution-qualifier   ::   name
+
+scope-resolution-qualifier:
+   relative-scope
+   qualified-name
+   dereferencable-expression
+
+relative-scope:
+   self
+   parent
+   static
+
**Constraints** *qualified-name* must be the name of a class or interface type. -*expression* must be a value of type string (but not a string literal) -that contains the name of a class or interface type. +*dereferencable-expression* must be a value of type string, which contains the name +of a class or interface type, or an object. **Semantics** @@ -1366,23 +1512,24 @@ From inside or outside a class or interface, operator `::` allows the selection of a constant. From inside or outside a class, this operator allows the selection of a static property, static method, or instance method. From within a class, it also allows the selection of an -overridden property or method. For a property, the value is that of the -property, and is a modifiable lvalue if *member-selection-designator* is -a modifiable lvalue. +overridden property or method. + +If the *scoped-property-access-expression* form is used, this operator +is accessing a static property given by *simple-variable* and can be +used as an lvalue. -If *member-selection-designator* is a [*name*](09-lexical-structure.md#names), this operator is accessing -a class constant. This form can not be used as an lvalue. +If the *class-constant-access-expression* form is used, this operator is +is accessing a class constant given by *name*. This form can not be used +as an lvalue. -If the operator is used as a *postfix-expression* for *function-call-expression* -then the operator is accessing the method - which, outside of the object context, +If the *scoped-call-expression* form is used, the operator is calling the +method given by *member-anem*, which, outside of the object context, is treated as static method call. Inside of the object context when `$this` is defined and the called method is not `static` and -the called class is the same of a parent of the class of `$this`, then the method is +the called class is the same as a parent of the class of `$this`, then the method call is non-static with the same `$this`. Otherwise it is a static method call. -Otherwise, the operator is accessing a static property. - *relative-scope* designates the class with relation to the current class scope. From within a class, `self` refers to the same class, `parent` refers to the class the current class extends from. From within a method, `static` refers @@ -1446,19 +1593,82 @@ class Point } ``` -###Exponentiation Operator +## The `clone` Operator + +**Syntax** + + + +
+clone-expression:
+   primary-expression
+   clone   primary-expression
+
+ +**Constraints** + +*primary-expression* must designate an object. + +**Semantics** + +The `clone` operator creates a new object that is a shallow copy of the object designated +by *primary-expression*. +Then, if the class type of *primary-expression* has a method called +[`__clone`](14-classes.md#method-__clone), it is called to perform a deep copy. +The result is the new object. + +**Examples** + +Consider a class `Employee`, from which is derived a class `Manager`. Let us +assume that both classes contain properties that are objects. `clone` is +used to make a copy of a `Manager` object, and behind the scenes, the +`Manager` object uses clone to copy the properties for the base class, +`Employee`. + +```PHP +class Employee +{ + //... + public function __clone() + { + // make a deep copy of Employee object + } +} +class Manager extends Employee +{ + //... + public function __clone() + { + $v = parent::__clone(); + // make a deep copy of Manager object + + } +} +$obj1 = new Manager("Smith", 23); +$obj2 = clone $obj1; // creates a new Manager that is a deep copy +``` + + +## Exponentiation Operator **Syntax** + +
-  exponentiation-expression:
-    expression  **  expression
+exponentiation-expression:
+   clone-expression
+   clone-expression   **   exponentiation-expression
 
-**Defined elsewhere** - -* [*expression*](#general-6) - **Semantics** The `**` operator produces the result of raising the value of the @@ -1467,10 +1677,12 @@ left-hand operand to the power of the right-hand one. If either of the operands have an object type supporting `**` operation, then the object semantics defines the result. The left operand is checked first. -If either or both operands have non-numeric types, their values are converted to type `int` -or `float`, as appropriate. If both operands have non-negative integer -values and the result can be represented as an `int`, the result has type -`int`; otherwise, the result has type `float`. +If either or both operands have non-numeric types, their values are converted +to type `int` or `float`, as appropriate. If both operands have non-negative +integer values and the result can be represented as an `int`, the result has +type `int`; otherwise, the result has type `float`. If either or both operands +were leading-numeric or non-numeric strings, a non-fatal error must be produced +for each. **Examples** @@ -1480,165 +1692,53 @@ values and the result can be represented as an `int`, the result has type "2.0"**"3"; // float with value 8.0 ``` -##Unary Operators +## Unary Operators -###General +### General **Syntax** -
-  unary-expression:
-    postfix-expression
-    prefix-increment-expression
-    prefix-decrement-expression
-    unary-op-expression
-    error-control-expression
-    shell-command-expression
-    cast-expression
-    variable-name-creation-expression
-
- -**Defined elsewhere** - -* [*postfix-expression*](#general-3) -* [*prefix-increment-expression*](#prefix-increment-and-decrement-operators) -* [*prefix-decrement-expression*](#prefix-increment-and-decrement-operators) -* [*unary-op-expression*](#unary-arithmetic-operators) -* [*error-control-expression*](#error-control-operator) -* [*shell-command-expression*](#shell-command-operator) -* [*cast-expression*](#cast-operator) -* [*variable-name-creation-expression*](#variable-name-creation-operator) - -**Semantics** - -These operators associate right-to-left. - -###Prefix Increment and Decrement Operators - -**Syntax** +
-  prefix-increment-expression:
-    ++ unary-expression
-
-  prefix-decrement-expression:
-    -- unary-expression
+unary-expression:
+   exponentiation-expression
+   unary-op-expression
+   error-control-expression
+   cast-expression
 
-**Defined elsewhere** - -* [*unary-expression*](#general-4) - -**Constraints** - -The operand of the prefix `++` or `--` operator must be a modifiable lvalue -that has scalar-compatible type. - **Semantics** -*Arithmetic Operands* - -For a prefix `++` operator used with an arithmetic operand, the [side -effect](#general) of the operator is to increment the value of the operand by 1. -The result is the value of the operand after it -has been incremented. If an `int` operand's value is the largest -representable for that type, the operand is incremented as if it were `float`. - -For a prefix `--` operator used with an arithmetic operand, the side -effect of the operator is to decrement the value of the operand by 1. -The result is the value of the operand after it has been -decremented. If an `int` operand's value is the smallest representable for -that type, the operand is decremented as if it were `float`. - -For a prefix `++` or `--` operator used with an operand having the value -`INF`, `-INF`, or `NAN`, there is no side effect, and the result is the -operand's value. - -*Boolean Operands* - -For a prefix `++` or `--` operator used with a Boolean-valued operand, there -is no side effect, and the result is the operand's value. - -*NULL-valued Operands* - -For a prefix -- operator used with a `NULL`-valued operand, there is no -side effect, and the result is the operand's value. For a prefix `++` -operator used with a `NULL`-valued operand, the side effect is that the -operand's type is changed to int, the operand's value is set to zero, -and that value is incremented by 1. The result is the value of the -operand after it has been incremented. - -*String Operands* - -For a prefix `--` operator used with an operand whose value is an empty -string, the side effect is that the operand's type is changed to `int`, -the operand's value is set to zero, and that value is decremented by 1. -The result is the value of the operand after it has been incremented. - -For a prefix `++` operator used with an operand whose value is an empty -string, the side effect is that the operand's value is changed to the -string "1". The type of the operand is unchanged. The result is the new -value of the operand. - -For a prefix `--` or `++` operator used with a numeric string, the numeric -string is treated as the corresponding `int` or `float` value. - -For a prefix `--` operator used with a non-numeric string-valued operand, -there is no side effect, and the result is the operand's value. - -For a non-numeric string-valued operand that contains only alphanumeric -characters, for a prefix `++` operator, the operand is considered to be a -representation of a base-36 number (i.e., with digits 0–9 followed by A–Z or a–z) in -which letter case is ignored for value purposes. The right-most digit is -incremented by 1. For the digits 0–8, that means going to 1–9. For the -letters "A"–"Y" (or "a"–"y"), that means going to "B"–"Z" (or "b"–"z"). -For the digit 9, the digit becomes 0, and the carry is added to the next -left-most digit, and so on. For the digit "Z" (or "z"), the resulting -string has an extra digit "A" (or "a") appended. For example, when -incrementing, "a" -> "b", "Z" -> "AA", "AA" -> "AB", "F29" -> "F30", "FZ9" -> "GA0", and "ZZ9" -> "AAA0". A digit position containing a number wraps -modulo-10, while a digit position containing a letter wraps modulo-26. - -For a non-numeric string-valued operand that contains any -non-alphanumeric characters, for a prefix `++` operator, all characters up -to and including the right-most non-alphanumeric character is passed -through to the resulting string, unchanged. Characters to the right of -that right-most non-alphanumeric character are treated like a -non-numeric string-valued operand that contains only alphanumeric -characters, except that the resulting string will not be extended. -Instead, a digit position containing a number wraps modulo-10, while a -digit position containing a letter wraps modulo-26. - -*Object Operands* +These operators associate right-to-left. -If the operand has an object type supporting the operation, -then the object semantics defines the result. Otherwise, the operation has -no effect and the result is the operand. -**Examples** +### Unary Arithmetic Operators -```PHP -$i = 10; $j = --$i + 100; // new value of $i (9) is added to 100 -$a = array(100, 200); $v = ++$a[1]; // new value of $a[1] (201) is assigned -$a = "^^Z"; ++$a; // $a is now "^^A" -$a = "^^Z^^"; ++$a; // $a is now "^^Z^^" -``` +**Syntax** -###Unary Arithmetic Operators +
-  unary-op-expression:
-    unary-operator cast-expression
+unary-op-expression:
+   unary-operator   unary-expression
 
-  unary-operator: one of
-    +  -  !  ~
+unary-operator: one of
+   +   -   ~
 
-**Defined elsewhere** - -* [*cast-expression*](#cast-operator) - **Constraints** The operand of the unary `+` and unary `-` must have scalar-compatible type. @@ -1648,10 +1748,6 @@ an object supporting `~`. **Semantics** -For a unary `!` operator the type of the result is `bool`. -The value of the operand is [converted to type `bool`](08-conversions.md#converting-to-boolean-type) -and if it is `TRUE` then the of the operator result is `FALSE`, and the result is `TRUE` otherwise. - *Arithmetic Operands* For a unary `+` operator used with an arithmetic operand, the type and @@ -1691,7 +1787,8 @@ leading-numeric string, the string is first converted to an `int` or `float`, as appropriate, after which it is handled as an arithmetic operand. The trailing non-numeric characters in leading-numeric strings are ignored. With a non-numeric string, the result has type `int` and -value 0. +value 0. If the string was leading-numeric or non-numeric, a non-fatal error +MUST be produced. For a unary `~` operator used with a string, the result is the string with each byte being bitwise complement of the corresponding byte of the source string. @@ -1707,29 +1804,28 @@ and for `+` and `-` the object is [converted to `int`](08-conversions.md#convert ```PHP $v = +10; if ($v1 > -5) // ... -$t = TRUE; -if (!$t) // ... $v = ~0b1010101; $s = "\x86\x97"; $s = ~$s; // $s is "yh" ``` -###Error Control Operator +### Error Control Operator **Syntax** + +
-  error-control-expression:
-    @   expression
+error-control-expression:
+   @   unary-expression
 
-**Defined elsewhere** - -* [*expression*](#general-6) - **Semantics** Operator `@` suppresses the reporting of any error messages generated by the evaluation of -*expression*. +*unary-expression*. If a custom error-handler has been established using the library function [`set_error_handler`](http://php.net/manual/function.set-error-handler.php), that handler is @@ -1769,60 +1865,31 @@ if ($curER === 0) error_reporting($origER); $x = $tmp; ``` -###Shell Command Operator +### Cast Operator **Syntax** -
-  shell-command-expression:
-    `  dq-char-sequenceopt  `
-
- -where \` is the GRAVE ACCENT character U+0060, commonly referred to as a -*backtick*. - -**Defined elsewhere** - -* [*dq-char-sequence*](09-lexical-structure.md#double-quoted-string-literals) - -**Semantics** - -This operator passes *dq-char-sequence* to the command shell for -execution, as though it was being passed to the library function -[`shell_exec`](http://www.php.net/shell_exec). If the output from execution of that command is -written to [`STDOUT`](06-constants.md#core-predefined-constants), that output is the result of this operator -as a string. If the output is redirected away from `STDOUT`, or -*dq-char-sequence* is empty or contains only white space, the result of -the operator is `NULL`. - -If [`shell_exec`](http://php.net/manual/function.shell-exec.php) is disabled, this operator is disabled. - -**Examples** - -```PHP -$result = `ls`; // result is the output of command ls -$result = `ls >dirlist.txt`; // result is NULL -$d = "dir"; $f = "*.*"; -$result = `$d {$f}`; // result is the output of command dir *.* -``` - -###Cast Operator +
-  cast-expression:
-    unary-expression
-    (  cast-type  ) expression
+cast-expression:
+   (   cast-type   )   unary-expression
 
-  cast-type: one of
-    array  binary  bool  boolean  double  int  integer  float  object
-    real  string  unset
+cast-type: one of
+   array   binary   bool   boolean   double   int   integer   float   object
+   real   string   unset
 
-**Defined elsewhere** +**Constaints** -* [*unary-expression*](#general-4) +A *cast-type* of `unset` is no longer supported and results in a compile-time error. **Semantics** @@ -1850,9 +1917,6 @@ A *cast-type* of `object` results in a [conversion to type `object`](08-conversi A *cast-type* of `string` results in a [conversion to type `string`](08-conversions.md#converting-to-string-type). -A *cast-type* of `unset` always results in a value of `NULL`. (This use of -`unset` should not be confused with the [`unset` intrinsic](#unset). - **Examples** ```PHP @@ -1861,111 +1925,40 @@ A *cast-type* of `unset` always results in a value of `NULL`. (This use of (int)(float)"123.87E3" // results in the int 123870 ``` -###Variable-Name Creation Operator +## `instanceof` Operator **Syntax** -
-  variable-name-creation-expression:
-    $   expression
-    $  {  expression  }
-
- -**Defined elsewhere** - -* [*expression*](#general-6) - -**Constraints** - -In the non-brace form, *expression* must be a -*variable-name-creation-expression* or a *variable-name* that designates -a scalar value or an object convertible to string. - -In the brace form, *expression* must be a -*variable-name-creation-expression* or an expression that designates a -scalar value or an object convertible to string. - -**Semantics** - -The result of this operator is a variable name spelled using the string -representation of the value of *expression* even though such a name -might not be permitted as a [variable-name](09-lexical-structure.md#names) source code token. - -The operator will consume the following *variable-name-creation-expression* and *variable-name* tokens, and -also tokens representing [subscript operator](#subscript-operator). - -I.e., in example `$$o->pr` the expression is treated as `${$o}->pr`, i.e. it is parsed as -"take the value of $o, consider it a variable name, and assuming the variable with this name -is an object take the property 'pr' of it". -However, in the expression ``$$a[0]` the tokens `$a[0]` would be treated as the variable name, not just `$a`. - -**Examples** - -```PHP -$color = "red"; -$$color = 123; // equivalent to $red = 123 -// ----------------------------------------- -$x = 'ab'; $ab = 'fg'; $fg = 'xy'; -$$ $ $x = 'Hello'; // equivalent to $xy = Hello -// ----------------------------------------- -$v1 = 3; -$$v1 = 22; // equivalent to ${3} = 22, variable name is "3" -$v2 = 9.543; -$$v2 = TRUE; // equivalent to ${9.543} = TRUE -$v3 = NULL; -$$v3 = "abc"; // equivalent to ${NULL} = "abc", here we create a variable with empty name -// ----------------------------------------- -function f1 () { return 2.5; } -${1 + f1()} = 1000; // equivalent to ${3.5} = 1000 -// ----------------------------------------- -$v = array(10, 20); $a = 'v'; -$$a[0] = 5; // [] has higher precedence than $, $v is now 5 -$v = array(10, 20); $a = 'v'; -${$a[0]} = 5; // equivalent to above, $v is 5 -$v = array(10, 20); $a = 'v'; -${$a}[0] = 5; // $ gets first shot at $a, $v is [5, 20] -``` +
-  instanceof-expression:
-    unary-expression
-    instanceof-subject  instanceof   instanceof-type-designator
+instanceof-expression:
+   unary-expression
+   instanceof-subject   instanceof   class-type-designator
 
-  instanceof-subject:
-    expression
-
-  instanceof-type-designator:
-    qualified-name
-    expression
+instanceof-subject:
+   instanceof-expression
 
-**Defined elsewhere** - -* [*unary-expression*](#general-4) -* [*expression*](#general-6) -* [*qualified-name*](09-lexical-structure.md#names) - -**Constraints** - -The *expression* in *instanceof-type-designator* and *instanceof-subject* must not be any form of -literal. - **Semantics** Operator `instanceof` returns `TRUE` if the value designated by -*expression* in *instanceof-subject* is an object having the type specified -by *instanceof-type-designator*, is an object whose type is derived from that type, -or is an object whose type implements the interface specified by *instanceof-type-designator*. +*instanceof-subject* is an object having the type specified +by *class-type-designator*, is an object whose type is derived from that type, +or is an object whose type implements the interface specified by *class-type-designator*. Otherwise, it returns `FALSE`. -The type can be specified by *instanceof-type-designator* in one of the three forms: +The type can be specified by *class-type-designator* in one of the three forms: 1. *qualified-name* specifies the type name directly. - 2. When the *expression* form is used, *expression* may have a string value that contains a class or interface name. - 3. Alternatively, *expression* can designate an object, in which case the type of the object is used as the specified type. + 2. When the *new-variable* form is used, *new-variable* may have a string value that contains a class or interface name. + 3. Alternatively, *new-variable* can designate an object, in which case the type of the object is used as the specified type. Note that an interface can not be specified with this form. Note that `instanceof` will not invoke autoloader if the name of the type given does not @@ -1995,21 +1988,51 @@ $e2 = new E1; var_dump($e2 instanceof $e1); // TRUE ``` -##Multiplicative Operators +## Logical NOT Operator -**Syntax** +
-  multiplicative-expression:
-    instanceof-expression
-    multiplicative-expression  *  instanceof-expression
-    multiplicative-expression  /  instanceof-expression
-    multiplicative-expression  %  instanceof-expression
+logical-NOT-expression:
+   instanceof-expression
+   !   instanceof-expression
 
-**Defined elsewhere** +**Semantics** + +The value of the operand is [converted to type `bool`](08-conversions.md#converting-to-boolean-type) +and if it is `TRUE` then the result of the operator is `FALSE`. The result is `TRUE` otherwise. + +**Examples** + +```PHP +$t = TRUE; +if (!$t) // ... +``` + +## Multiplicative Operators -* [*instanceof-expression*](#instanceof-operator) +**Syntax** + + + +
+multiplicative-expression:
+   logical-NOT-expression
+   multiplicative-expression   *   logical-NOT-expression
+   multiplicative-expression   /   logical-NOT-expression
+   multiplicative-expression   %   logical-NOT-expression
+
**Constraints** @@ -2020,30 +2043,33 @@ The right-hand operand of operator `/` and operator `%` must not be zero. If either of the operands is an object supporting the operation, the result is defined by that object's semantics, with the left operand checked first. -The binary `*` operator produces the product of its operands. If either -or both operands have non-numeric types, their values are converted to -type `int` or `float`, as appropriate. Then if either operand has type -`float`, the other is converted to that type, and the result has type -`float`. Otherwise, both operands have type `int`, in which case, if the -resulting value can be represented in type `int` that is the result type. -Otherwise, the result would have type `float`. +The binary `*` operator produces the product of its operands. If either or both +operands have non-numeric types, their values are converted to type `int` or +`float`, as appropriate. If either or both operands were leading-numeric or +non-numeric strings, a non-fatal error MUST be produced for each. Then if +either operand has type `float`, the other is converted to that type, and the +result has type `float`. Otherwise, both operands have type `int`, in which +case, if the resulting value can be represented in type `int` that is the +result type. Otherwise, the result would have type `float`. -Division by zero results in a non-fatal error and the result value is `FALSE`. -The values +/- infinity and NaN cannot be generated via this operator; -instead, use the predefined constants `INF` and `NAN`. +Division by zero results in a non-fatal error. If the value of the numerator is positive, the result value is `INF`. If the value of the numerator is negative, the result value is `-INF`. If the value of the numerator is zero, the result value is `NAN`. The binary `/` operator produces the quotient from dividing the left-hand -operand by the right-hand one. If either or both operands have -non-numeric types, their values are converted to type `int` or `float`, as -appropriate. Then if either operand has type `float`, the other is -converted to that type, and the result has type `float`. Otherwise, both -operands have type `int`, in which case, if the mathematical value of the -computation can be preserved using type `int`, that is the result type; -otherwise, the type of the result is `float`. +operand by the right-hand one. If either or both operands have non-numeric +types, their values are converted to type `int` or `float`, as appropriate. If +either or both operands were leading-numeric or non-numeric strings, a +non-fatal error must be produced for each. Then if either operand has type +`float`, the other is converted to that type, and the result has type `float`. +Otherwise, both operands have type `int`, in which case, if the mathematical +value of the computation can be preserved using type `int`, that is the result +type; otherwise, the type of the result is `float`. The binary `%` operator produces the remainder from dividing the left-hand -operand by the right-hand one. If the type of both operands is not `int`, -their values are converted to that type. The result has type `int`. +operand by the right-hand one. If the type of both operands is not `int`, their +values are converted to that type. If either or both operands were +leading-numeric or non-numeric strings, a non-fatal error MUST be produced for +each. The result has type `int`. If the right-hand operand has value zero, an +exception of type `DivisionByZeroError` is thrown. These operators associate left-to-right. @@ -2063,22 +2089,26 @@ These operators associate left-to-right. 100 / "a"; // results in a diagnostic followed by bool with value false (a is converted to 0) ``` -##Additive Operators +## Additive Operators **Syntax** + +
-  additive-expression:
-    multiplicative-expression
-    additive-expression  +  multiplicative-expression
-    additive-expression  -  multiplicative-expression
-    additive-expression  .  multiplicative-expression
+additive-expression:
+   multiplicative-expression
+   additive-expression   +   multiplicative-expression
+   additive-expression   -   multiplicative-expression
+   additive-expression   .   multiplicative-expression
 
-**Defined elsewhere** - -* [*multiplicative-expression*](#multiplicative-operators) - **Constraints** If either operand of `+` has array type, the other operand must also have array @@ -2092,15 +2122,15 @@ If either of the operands is an object supporting the operation, the result is defined by that object's semantics, with the left operand checked first. For non-array operands, the binary `+` operator produces the sum of those -operands, while the binary `-` operator produces the difference of its -operands when subtracting the right-hand operand from the left-hand one. -If either or both operands have non-array, non-numeric types, their -values are converted to type `int` or `float`, as appropriate. Then if -either operand has type `float`, the other is converted to that type, and -the result has type `float`. Otherwise, both operands have type `int`, in -which case, if the resulting value can be represented in type `int` that -is the result type. -Otherwise, the result would have type `float`. +operands, while the binary `-` operator produces the difference of its operands +when subtracting the right-hand operand from the left-hand one. If either or +both operands have non-array, non-numeric types, their values are converted to +type `int` or `float`, as appropriate. If either or both operands were +leading-numeric or non-numeric strings, a non-fatal error MUST be produced for +each. Then if either operand has type `float`, the other is converted to that +type, and the result has type `float`. Otherwise, both operands have type +`int`, in which case, if the resulting value can be represented in type `int` +that is the result type. Otherwise, the result would have type `float`. If both operands have array type, the binary `+` operator produces a new array that is the union of the two operands. The result is a copy of the @@ -2137,21 +2167,24 @@ TRUE . NULL; // string with value "1" 10 + 5 . 12 . 100 - 50; // int with value 1512050; ((((10 + 5).12).100)-50) ``` -##Bitwise Shift Operators +## Bitwise Shift Operators **Syntax** + +
-  shift-expression:
-    additive-expression
-    shift-expression  <<  additive-expression
-    shift-expression  >>  additive-expression
+shift-expression:
+   additive-expression
+   shift-expression   <<   additive-expression
+   shift-expression   >>   additive-expression
 
-**Defined elsewhere** - -* [*additive-expression*](#additive-operators) - **Constraints** Each of the operands must have scalar-compatible type. @@ -2168,53 +2201,78 @@ zero bits are shifted on from the right end. Given the expression `e2` positions. Bits shifted off the right end are discarded, and the sign bit is propagated from the left end. -If either operand does not have type `int`, its value is first converted -to that type. +If either operand does not have type `int`, its value is first converted to +that type. If either or both operands were leading-numeric or non-numeric +strings, a non-fatal error MUST be produced for each. The type of the result is `int`, and the value of the result is that after the shifting is complete. The values of `e1` and `e2` are unchanged. -If the shift count is negative, the actual shift applied is `n - -(-shift count % n)`, where `n` is the number of bits per `int`. If the -shift count is greater than the number of bits in an `int`, the actual -shift applied is shift count `% n`. +Left shifts where the shift count is greater than the bit width of the integer +type (e.g. 32 or 64) must always result in 0, even if there is no native +processor support for this. + +Right shifts where the shift count is greater than the bit width of the integer +type (e.g. 32 or 64) must always result in 0 when `e1` is positive and -1 when +`e1` is negative, even if there is no native processor support for this. + +If the shift count is negative, an exception of type `ArithmeticError` is thrown. These operators associate left-to-right. **Examples** ```PHP -1000 >> 2 // 3E8 is shifted right 2 places --1000 << 2 // FFFFFC18 is shifted left 5 places -123 >> 128 // adjusted shift count = 0 -123 << 33 // For a 32-bit int, adjusted shift count = 1; otherwise, 33 +1000 >> 2 // 0x3E8 is shifted right 2 places +-1000 << 2 // 0xFFFFFC18 is shifted left 5 places +123 >> 128 // Shift count larger than bit width => result 0 +123 << 33 // For 32-bit integers the result is zero, otherwise + // it is 0x7B shifted left 33 places ``` -##Relational Operators +## Relational Operators **Syntax** + +
-  relational-expression:
-    shift-expression
-    relational-expression  <   shift-expression
-    relational-expression  >   shift-expression
-    relational-expression  <=  shift-expression
-    relational-expression  >=  shift-expression
+relational-expression:
+   shift-expression
+   relational-expression   <   shift-expression
+   relational-expression   >   shift-expression
+   relational-expression   <=   shift-expression
+   relational-expression   >=   shift-expression
+   relational-expression   <=>   shift-expression
 
-**Defined elsewhere** - -* [*shift-expression*](#bitwise-shift-operators) - **Semantics** +Operator `<=>` represents comparison operator between two expressions, with the +result being an integer less than `0` if the expression on the left is less than the expression on the right +(i.e. if `$a < $b` would return `TRUE`), as defined below by the semantics of the operator `<`, +integer `0` if those expressions are equal (as defined by the semantics of the `==` operator) +and integer greater than `0` otherwise. + Operator `<` represents *less-than*, operator `>` represents *greater-than*, operator `<=` represents *less-than-or-equal-to*, and operator `>=` represents *greater-than-or-equal-to*. The type of the result is `bool`. +Note that *greater-than* semantics is implemented as the reverse of *less-than*, i.e. +`$a > $b` is the same as `$b < $a`. This may lead to confusing results if the operands +are not well-ordered - such as comparing two objects not having comparison semantics, or +comparing arrays. + The following table shows the result for comparison of different types, with the left operand displayed vertically and the right displayed horizontally. The conversions are performed according to [type conversion rules](08-conversions.md). @@ -2240,7 +2298,7 @@ The conversions are performed according to [type conversion rules](08-conversion 1. If either operand has type `bool`, the other operand is converted to that type. The result is the logical comparison of the two operands after conversion, where `FALSE` is defined to be less than `TRUE`. -2. If one of the operands has arithmetic type, is a resource, or a numeric string, +2. If one of the operands has arithmetic type, is a resource, or a numeric string, which can be represented as `int` or `float` without loss of precision, the operands are converted to the corresponding arithmetic type, with `float` taking precedence over `int`, and resources converting to `int`. @@ -2302,26 +2360,36 @@ FALSE < "abc" // result has value TRUE [100] < [10,20,30] // result has value TRUE (LHS array is shorter) [10,20] >= ["red"=>0,"green"=>0] // result has value FALSE, (key 10 does not exists in RHS) ["red"=>0,"green"=>0] >= ["green"=>0,"red"=>0] // result has value TRUE (order is irrelevant) +// ------------------------------------ +function order_func($a, $b) { + return ($a->$x <=> $b->x) ?: ($a->y <=> $b->y) ?: ($a->z <=> $b->z); +} ``` -##Equality Operators +## Equality Operators **Syntax** + +
-  equality-expression:
-    relational-expression
-    equality-expression  ==  relational-expression
-    equality-expression  !=  relational-expression
-    equality-expression  <>  relational-expression
-    equality-expression  ===  relational-expression
-    equality-expression  !==  relational-expression
+equality-expression:
+   relational-expression
+   equality-expression   ==   relational-expression
+   equality-expression   !=   relational-expression
+   equality-expression   <>   relational-expression
+   equality-expression   ===   relational-expression
+   equality-expression   !==   relational-expression
 
-**Defined elsewhere** - -* [*relational-expression*](#relational-operators) - **Semantics** Operator `==` represents *value equality*, operators `!=` and `<>` are @@ -2366,16 +2434,18 @@ TRUE !== 100 // result has value TRUE **Syntax** + +
-  bitwise-AND-expression:
-    equality-expression
-    bit-wise-AND-expression  &  equality-expression
+bitwise-AND-expression:
+   equality-expression
+   bitwise-AND-expression   &   equality-expression
 
-**Defined elsewhere** - -* [*equality-expression*](#equality-operators) - **Constraints** Each of the operands must have scalar-compatible type. @@ -2385,8 +2455,9 @@ Each of the operands must have scalar-compatible type. If either of the operands is an object supporting the operation, the result is defined by that object's semantics, with the left operand checked first. -If either operand does not have type `int`, its value is first converted -to that type. +If either operand does not have type `int`, its value is first converted to +that type. If either or both operands were leading-numeric or non-numeric +strings, a non-fatal error MUST be produced for each. The result of this operator is the bitwise-AND of the two operands, and the type of that result is `int`. @@ -2406,20 +2477,22 @@ $lLetter = 0x73; // letter 's' $uLetter = $lLetter & ~0x20; // clear the 6th bit to make letter 'S' ``` -##Bitwise Exclusive OR Operator +## Bitwise Exclusive OR Operator **Syntax** + +
-  bitwise-exc-OR-expression:
-    bitwise-AND-expression
-    bitwise-exc-OR-expression  ^  bitwise-AND-expression
+bitwise-exc-OR-expression:
+   bitwise-AND-expression
+   bitwise-exc-OR-expression   ^   bitwise-AND-expression
 
-**Defined elsewhere** - -* [*bitwise-AND-expression*](#bitwise-and-operator) - **Constraints** Each of the operands must have scalar-compatible type. @@ -2429,8 +2502,9 @@ Each of the operands must have scalar-compatible type. If either of the operands is an object supporting the operation, the result is defined by that object's semantics, with the left operand checked first. -If either operand does not have type `int`, its value is first converted -to that type. +If either operand does not have type `int`, its value is first converted to +that type. If either or both operands were leading-numeric or non-numeric +strings, a non-fatal error MUST be produced for each. The result of this operator is the bitwise exclusive-OR of the two operands, and the type of that result is `int`. @@ -2452,20 +2526,22 @@ $v2 = $v1 ^ $v2; $v1 = $v1 ^ $v2; // $v1 is now -987, and $v2 is now 1234 ``` -##Bitwise Inclusive OR Operator +## Bitwise Inclusive OR Operator **Syntax** + +
-  bitwise-inc-OR-expression:
-    bitwise-exc-OR-expression
-    bitwise-inc-OR-expression  |  bitwise-exc-OR-expression
+bitwise-inc-OR-expression:
+   bitwise-exc-OR-expression
+   bitwise-inc-OR-expression   |   bitwise-exc-OR-expression
 
-**Defined elsewhere** - -* [*bitwise-exc-OR-expression*](#bitwise-exclusive-or-operator) - **Constraints** Each of the operands must have scalar-compatible type. @@ -2475,8 +2551,9 @@ Each of the operands must have scalar-compatible type. If either of the operands is an object supporting the operation, the result is defined by that object's semantics, with the left operand checked first. -If either operand does not have type `int`, its value is first converted -to that type. +If either operand does not have type `int`, its value is first converted to +that type. If either or both operands were leading-numeric or non-numeric +strings, a non-fatal error MUST be produced for each. The result of this operator is the bitwise inclusive-OR of the two operands, and the type of that result is `int`. @@ -2496,76 +2573,131 @@ $uLetter = 0x41; // letter 'A' $lLetter = $upCaseLetter | 0x20; // set the 6th bit to make letter 'a' ``` -##Logical AND Operator (form 1) +## Logical AND Operator (form 1) **Syntax** + +
-  logical-AND-expression-1:
-    bitwise-incl-OR-expression
-    logical-AND-expression-1  &&  bitwise-inc-OR-expression
+logical-AND-expression-1:
+   bitwise-inc-OR-expression
+   logical-AND-expression-1   &&   bitwise-inc-OR-expression
 
-**Defined elsewhere** +**Semantics** + +Given the expression `e1 && e2`, `e1` is evaluated first. If `e1` [converts to `bool`](08-conversions.md#converting-to-boolean-type) as `FALSE`, `e2` is not evaluated, and the result has type `bool`, value `FALSE`. Otherwise, `e2` is evaluated. If `e2` converts to `bool` as `FALSE`, the result has type `bool`, value `FALSE`; otherwise, it has type `bool`, value `TRUE`. There is a sequence point after the evaluation of `e1`. + +This operator associates left-to-right. + +Except for the difference in precedence, operator `&&` has exactly the +same semantics as operator [`and`](#logical-and-operator-form-2). + +**Examples** + +```PHP +if ($month > 1 && $month <= 12) ... +``` + +## Logical Inclusive OR Operator (form 1) + +**Syntax** + + -* [*bitwise-incl-OR-expression*](#bitwise-inclusive-or-operator) +
+logical-inc-OR-expression-1:
+   logical-AND-expression-1
+   logical-inc-OR-expression-1   ||   logical-AND-expression-1
+
**Semantics** -Given the expression `e1 && e2`, `e1` is evaluated first. If `e1` [converts to `bool`](08-conversions.md#converting-to-boolean-type) as `FALSE`, `e2` is not evaluated, and the result has type `bool`, value `FALSE`. Otherwise, `e2` is evaluated. If `e2` converts to `bool` as `FALSE`, the result has type `bool`, value `FALSE`; otherwise, it has type `bool`, value `TRUE`. There is a sequence point after the evaluation of `e1`. +Given the expression `e1 || e2`, `e1` is evaluated first. If `e1` [converts to `bool`](08-conversions.md#converting-to-boolean-type) as `TRUE`, `e2` is not evaluated, and the result has type `bool`, value `TRUE`. Otherwise, `e2` is evaluated. If `e2` converts to `bool` as `TRUE`, the result has type `bool`, value `TRUE`; otherwise, it has type `bool`, value `FALSE`. There is a sequence point after the evaluation of `e1`. This operator associates left-to-right. -Except for the difference in precedence, operator `&&` has exactly the -same semantics as operator [`and`](#logical-and-operator-form-2). - **Examples** ```PHP -if ($month > 1 && $month <= 12) ... +if ($month < 1 || $month > 12) ... ``` -##Logical Inclusive OR Operator (form 1) +## Coalesce Operator **Syntax** + +
-  logical-inc-OR-expression-1:
-    logical-AND-expression-1
-    logical-inc-OR-expression-1  ||  logical-AND-expression-1
+coalesce-expression:
+   logical-inc-OR-expression-1
+   logical-inc-OR-expression-1   ??   coalesce-expression
 
-**Defined elsewhere** - -* [*logical-exc-OR-expression*](#bitwise-exclusive-or-operator) - **Semantics** -Given the expression `e1 || e2`, `e1` is evaluated first. If `e1` [converts to `bool`](08-conversions.md#converting-to-boolean-type) as `TRUE`, `e2` is not evaluated, and the result has type `bool`, value `TRUE`. Otherwise, `e2` is evaluated. If `e2` converts to `bool` as `TRUE`, the result has type `bool`, value `TRUE`; otherwise, it has type `bool`, value `FALSE`. There is a sequence point after the evaluation of `e1`. +Given the expression `e1 ?? e2`, if `e1` is set and not `NULL` (i.e. TRUE for +[isset](#isset)), then the result is `e1`. Otherwise, then and only then is `e2` +evaluated, and the result becomes the result of the whole +expression. There is a sequence point after the evaluation of `e1`. -This operator associates left-to-right. +Note that the semantics of `??` is similar to `isset` so that uninitialized variables will +not produce warnings when used in `e1`. + +This operator associates right-to-left. **Examples** ```PHP -if ($month < 1 || $month > 12) ... +$arr = ["foo" => "bar", "qux" => NULL]; +$obj = (object)$arr; + +$a = $arr["foo"] ?? "bang"; // "bar" as $arr["foo"] is set and not NULL +$a = $arr["qux"] ?? "bang"; // "bang" as $arr["qux"] is NULL +$a = $arr["bing"] ?? "bang"; // "bang" as $arr["bing"] is not set + +$a = $obj->foo ?? "bang"; // "bar" as $obj->foo is set and not NULL +$a = $obj->qux ?? "bang"; // "bang" as $obj->qux is NULL +$a = $obj->bing ?? "bang"; // "bang" as $obj->bing is not set + +$a = NULL ?? $arr["bing"] ?? 2; // 2 as NULL is NULL, and $arr["bing"] is not set + +function foo() { + echo "executed!", PHP_EOL; +} +var_dump(true ?? foo()); // outputs bool(true), "executed!" does not appear as it short-circuits ``` -##Conditional Operator +## Conditional Operator **Syntax** + +
-  conditional-expression:
-    logical-inc-OR-expression-1
-    logical-inc-OR-expression-1  ?  expressionopt  :  conditional-expression
+conditional-expression:
+   coalesce-expression
+   conditional-expression   ?   expressionopt   :   coalesce-expression
 
-**Defined elsewhere** - -* [*logical-OR-expression*](#logical-inclusive-or-operator-form-1) -* [*expression*](#general-6) - **Semantics** Given the expression `e1 ? e2 : e3`, `e1` is evaluated first and [converted to `bool`](08-conversions.md#converting-to-boolean-type) if it has another type. If the result is `TRUE`, then and only then is `e2` evaluated, and the result and its type become the result and type of @@ -2597,27 +2729,27 @@ function factorial($int) } ``` -##Assignment Operators -###General +## Assignment Operators + +### General **Syntax** + +
-  assignment-expression:
-    conditional-expression
-    simple-assignment-expression
-    byref-assignment-expression
-    compound-assignment-expression
+assignment-expression:
+   conditional-expression
+   simple-assignment-expression
+   compound-assignment-expression
 
-**Defined elsewhere** - -* [*conditional-expression*](#conditional-operator) -* [*simple-assignment-expression*](#simple-assignment) -* [*byref-assignment-expression*](#byref-assignment) -* [*compound-assignment-expression*](#compound-assignment) - **Constraints** The left-hand operand of an assignment operator must be a modifiable @@ -2627,20 +2759,22 @@ lvalue. These operators associate right-to-left. -###Simple Assignment +### Simple Assignment **Syntax** + +
-  simple-assignment-expression:
-    unary-expression  =  assignment-expression
+simple-assignment-expression:
+   variable   =   assignment-expression
+   list-intrinsic   =   assignment-expression
 
-**Defined elsewhere** - -* [*unary-expression*](#general-4) -* [*assignment-expression*](#general-5) - **Constraints** If the location designated by the left-hand operand is a string element, @@ -2651,7 +2785,7 @@ must have type `string`. If *assignment-expression* designates an expression having value type, see [assignment for scalar types](04-basic-concepts.md#byref-assignment-for-scalar-types-with-local-variables) -If *assignment-expression* designates an expression having handle type, see [assignment for object and resource types](04-basic-concepts.md#value-assignment-of-object-and-resource-types-to-a-local-variable). +If *assignment-expression* designates an expression having handle type, see [assignment for object and resource types](04-basic-concepts.md#value-assignment-of-objects-to-a-local-variable). If *assignment-expression* designates an expression having array type, see [assignment of array types](04-basic-concepts.md#value-assignment-of-array-types-to-local-variables). @@ -2670,9 +2804,9 @@ character from the right-hand operand is stored at the designated location; all other characters in the right-hand operand string are ignored. If the designated location is beyond the end of the destination string, that string is extended to the new length with -spaces (U+0020) added as padding beyond the old end and before the newly +spaces (0x20) added as padding beyond the old end and before the newly added character. If the right-hand operand is an empty string, the null -character \\0 (U+0000) is stored. +character \\0 (0x00) is stored. **Examples** @@ -2695,27 +2829,170 @@ class C { ... } $a = new C; // make $a point to the allocated object ``` -###byRef Assignment +#### list intrinsic **Syntax** + +
-  byref-assignment-expression:
-    unary-expression  =  &  assignment-expression
-
+list-intrinsic: + list ( list-expression-list ) + +list-expression-list: + unkeyed-list-expression-list + keyed-list-expression-list ,opt -**Defined elsewhere** +unkeyed-list-expression-list: + list-or-variable + , + unkeyed-list-expression-list , list-or-variableopt -* [*unary-expression*](#general-4) -* [*assignment-expression*](#general-5) +keyed-list-expression-list: + expression => list-or-variable + keyed-list-expression-list , expression => list-or-variable + +list-or-variable: + list-intrinsic + &opt variable +
**Constraints** -*unary-expression* must designate a variable. +*list-intrinsic* must be used as the left-hand operand in a +[*simple-assignment-expression*](#simple-assignment) of which the right-hand +operand must be an expression that designates an array or object implementing +the `ArrayAccess` interface (called the *source array*). + +Each *variable* in *list-or-variable* must designate a writable variable (called +the *target variable*). + +At least one of the elements of the *list-expression-list* must be non-empty. + +**Semantics** + +This intrinsic assigns one or more elements of the source array to the +target variables. Target variables may be assigned by reference. +On success, it will return a copy of the source array. If the +source array is not an array or object implementing `ArrayAccess` no +assignments are performed and the return value is `NULL`. + +For *unkeyed-list-expression-list*, all elements in the source array having +keys of type `string` are ignored. +The element having an `int` key of 0 is assigned to the first target +variable, the element having an `int` key of 1 is assigned to the second +target variable, and so on, until all target variables have been +assigned. Any other array elements are ignored. If there are +fewer source array elements having int keys than there are target +variables, the unassigned target variables are set to `NULL` and +a non-fatal error is produced. + +For *keyed-list-expression-list*, each key-variable pair is handled in turn, +with the key and variable being separated by the `=>` symbol. +The element having the first key, with the key having been converted using the +same rules as the [subscript operator](10-expressions.md#subscript-operator), +is assigned to the frst target variable. This process is repeated for the +second `=>` pair, if any, and so on. Any other array elements are ignored. +If there is no array element with a given key, the unassigned target variable +is set to `NULL` and a non-fatal error is produced. + +The assignments must occur in this order. + +Any target variable may be a list, in which case, the corresponding +element is expected to be an array. + +If the source array elements and the target variables overlap in any +way, the behavior is unspecified. + +**Examples** + +```PHP +list($min, $max, $avg) = array(0, 100, 67); + // $min is 0, $max is 100, $avg is 67 +list($min, $max, $avg) = array(2 => 67, 1 => 100, 0 => 0); + // same as example above +list($min, , $avg) = array(0, 100, 67); + // $min is 0, $avg is 67 +list($min, $max, $avg) = array(0, 2 => 100, 4 => 67); + // $min is 0, $max is NULL, $avg is 100 +list($min, list($max, $avg)) = [0, [1 => 67, 99, 0 => 100], 33]; + // $min is 0, $max is 100, $avg is 67 + +list($arr[1], $arr[0]) = [0, 1]; + // $arr is [1 => 0, 0 => 1], in this order +list($arr2[], $arr2[]) = [0, 1]; + // $arr2 is [0, 1] + +$a = [1, 2]; +list(&$one, $two) = $a; + // $a[0] is 1, $a[1] is 2 +$one++; + // $a[0] is 2, $a[1] is 2 + +list("one" => $one, "two" => $two) = ["one" => 1, "two" => 2]; + // $one is 1, $two is 2 +list( + "one" => $one, + "two" => $two, +) = [ + "one" => 1, + "two" => 2, +]; + // $one is 1, $two is 2 + +$a = ['one' => 1, 'two' => 2]; +list('one' => &$one, 'two' => $two) = $a; + // $a['one'] is 1, $a['two'] is 2 +$one++; + // $a['one'] is 2, $a['two'] is 2 + +list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = [ + ["x" => 1, "y" => 2], + ["x" => 3, "y" => 4] +]; + // $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4 +list(0 => list($x1, $x2), 1 => list($x2, $y2)) = [[1, 2], [3, 4]]; + // $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4 +``` + +### byRef Assignment + +**Syntax** -*assignment-expression* must be an lvalue, a call to a function that -returns a value byRef, or a *new-expression* (see comment below -regarding this). + + +
+byref-assignment-expression:
+   variable   =   &   variable
+
+ +**Constraints** + +The right-hand-side *variable* must be an lvalue or a call to a function +that returns a value byRef. **Semantics** @@ -2740,22 +3017,25 @@ function &g2() { $t = "xxx"; return $t; } // return byRef $b =& g2(); // make $b an alias to "xxx" ``` -##Compound Assignment +## Compound Assignment **Syntax** -
-  compound-assignment-expression:
-    unary-expression   compound-assignment-operator   assignment-expression
+
 
-**Defined elsewhere**
+
+compound-assignment-expression:
+   variable   compound-assignment-operator   assignment-expression
 
-* [*unary-expression*](#general-4)
-* [*assignment-expression*](#general-5)
+compound-assignment-operator: one of
+   **=   *=   /=   %=   +=   -=   .=   <<=   >>=   &=   ^=   |=
+
**Constraints** @@ -2778,91 +3058,32 @@ $i = 1; $a[$i++] += 50; // $a[1] = 250, $i β†’ 2 ``` -##Logical AND Operator (form 2) - -**Syntax** - -
-  logical-AND-expression-2:
-    assignment-expression
-    logical-AND-expression-2  and  assignment-expression
-
- -**Defined elsewhere** - -* [*assignment-expression*](#general-5) - -**Semantics** - -Except for the difference in precedence, operator and has exactly the -same semantics as [operator `&&`](#logical-and-operator-form-1). - -##Logical Exclusive OR Operator - -**Syntax** - -
-  logical-exc-OR-expression:
-    logical-AND-expression-2
-    logical-exc-OR-expression  xor  logical-AND-expression-2
-
- -**Defined elsewhere** - -* [*logical-AND-expression*](#logical-and-operator-form-2) - -**Semantics** - -If either operand does not have type `bool`, its value is first converted -to that type. - -Given the expression `e1 xor e2`, `e1` is evaluated first, then `e2`. If -either `e1` or `e2` [converted to `bool`](08-conversions.md#converting-to-boolean-type) as `TRUE`, but not both, the result has type `bool`, value -`TRUE`. Otherwise, the result has type `bool`, value `FALSE`. There is a -sequence point after the evaluation of `e1`. - -This operator associates left-to-right. - -**Examples** - -```PHP -f($i++) xor g($i) // the sequence point makes this well-defined -``` - -##Logical Inclusive OR Operator (form 2) +## `yield` Operator **Syntax** -
-  logical-inc-OR-expression-2:
-    logical-exc-OR-expression
-    logical-inc-OR-expression-2  or  logical-exc-OR-expression
-
- -**Defined elsewhere** - -* [*logical-exc-OR-expression*](#logical-exclusive-or-operator) - -**Semantics** - -Except for the difference in precedence, operator and has exactly the -same semantics as [operator `||`](#logical-inclusive-or-operator-form-1). - -## `yield` Operator +
-  yield-expression:
-    logical-inc-OR-expression-2
-    yield  array-element-initializer
+yield-from-expression:
+   yield from   assignment-expression
+
+yield-expression:
+   yield-from-expression
+   yield
+   yield   yield-expression
+   yield   yield-from-expression   =>   yield-expression
 
-**Defined elsewhere** - -* [*logical-inc-OR-expression*](#logical-inclusive-or-operator-form-2) -* [*array-element-initializer*](#array-creation-operator) - **Semantics** Any function containing a *yield-expression* is a *generator function*. @@ -2880,26 +3101,31 @@ The `yield` operator produces the result `NULL` unless the method [`Generator->send`](14-classes.md#class-generator) was called to provide a result value. This operator has the side effect of generating the next value in the collection. -Before being used, an *element-key* must have, or be converted to, type -`int` or `string`. Keys with `float` or `bool` values, or numeric strings, are -[converted to `int`](08-conversions.md#converting-to-integer-type). Values of all other key types are [converted to -`string`](08-conversions.md#converting-to-string-type). - -If *element-key* is omitted from an *array-element-initializer*, an +If the key is omitted from an a *yield-expression*, an element key of type `int` is associated with the corresponding -*element-value*. The key associated is one more than the previously +value. The key associated is one more than the previously assigned int key for this collection. However, if this is the first -element in this collection with an `int` key, key zero is used. If -*element-key* is provided, it is associated with the corresponding -*element-value*. The resulting key/value pair is made available by -`yield`. +element in this collection with an `int` key, zero is used. -If *array-element-initializer* is omitted, default int-key assignment is -used and each value is `NULL`. +If the value is also omitted, `NULL` will be used instead. If the generator function definition declares that it returns byRef, each value in a key/value pair is yielded byRef. +The following applies only to the `yield from` form: + +A generator function (referred to as a *delegating generator*) can delegate to another generator function (referred to as a *subgenerator*), a Traversable object, or an array, each of which is designated by *expression*. + +Each value yielded by *assignment-expression* is passed directly to the delegating generator's caller. + +Each value sent to the delegating generator's `send` method is passed to the subgenerator's `send` method. If *assignment-expression* is not a generator function, any sent values are ignored. + +Exceptions thrown by *assignment-expression* are propagated up to the delegating generator. + +Upon traversable completion, `NULL` is returned to the delegating generator if the traversable is not a generator. If the traversable is a generator, its return value is sent to the delegating generator as the value of the `yield from` *expression*. + +An exception of type `Error` is thrown if *assignment-expression* evaluates to a generator that previously terminated with an uncaught exception, or it evaluates to something that is neither Traversable nor an array. + **Examples** ```PHP @@ -2931,30 +3157,177 @@ function series($start, $end, $keyPrefix = "") } } foreach (series(1, 5, "X") as $key => $val) { /* process each key/val pair */ } +// ----------------------------------------- +function gen() +{ + yield 1; + yield from gen2(); + yield 4; +} +function gen2() +{ + yield 2; + yield 3; +} +foreach (gen() as $val) +{ + echo $val . "\n"; // Produces the values 1, 2, 3, and 4 +} +// ----------------------------------------- +function g() { + yield 1; + yield from [2, 3]; + yield 4; +} +$g = g(); +foreach ($g as $yielded) { + echo $yielded . "\n"; // Produces the values 1, 2, 3, and 4 +} +``` + +## Print expression + +**Syntax** + + + +
+print-expression:
+   yield-expression
+   print   print-expression
+
+ +**Constraints** + +*print-expression* value must be [convertable to a string](08-conversions.md#converting-to-string-type). +In particular, it should not be an array and if it is an object, it must implement +a [`__toString` method](14-classes.md#method-__tostring). + +**Semantics** + +After converting *print-expression*'s value into a string, if necessary, +`print` writes the resulting string to [`STDOUT`](06-constants.md#core-predefined-constants). +Unlike [`echo`](11-statements.md#the-echo-statement), `print` can be used in any context +allowing an expression. It always returns the value 1. + +See also: [double quoted strings](09-lexical-structure.md#double-quoted-string-literals) and +[heredoc documents](09-lexical-structure.md#heredoc-string-literals), [conversion to string](08-conversions.md#converting-to-string-type). + +**Examples** + +```PHP +$v1 = TRUE; +$v2 = 123; +print '>>' . $v1 . '|' . $v2 . "<<\n"; // outputs ">>1|123<<" +print ('>>' . $v1 . '|' . $v2 . "<<\n"); // outputs ">>1|123<<" +$v3 = "qqq{$v2}zzz"; +print "$v3\n"; // outputs "qqq123zzz" +$a > $b ? print "..." : print "..."; ``` -##Script Inclusion Operators +## Logical AND Operator (form 2) + +**Syntax** + + + +
+logical-AND-expression-2:
+   print-expression
+   logical-AND-expression-2   and   yield-expression
+
+ +**Semantics** + +Except for the difference in precedence, operator and has exactly the +same semantics as [operator `&&`](#logical-and-operator-form-1). + +## Logical Exclusive OR Operator + +**Syntax** + + + +
+logical-exc-OR-expression:
+   logical-AND-expression-2
+   logical-exc-OR-expression   xor   logical-AND-expression-2
+
+ +**Semantics** + +If either operand does not have type `bool`, its value is first converted +to that type. + +Given the expression `e1 xor e2`, `e1` is evaluated first, then `e2`. If +either `e1` or `e2` [converted to `bool`](08-conversions.md#converting-to-boolean-type) as `TRUE`, but not both, the result has type `bool`, value +`TRUE`. Otherwise, the result has type `bool`, value `FALSE`. There is a +sequence point after the evaluation of `e1`. + +This operator associates left-to-right. + +**Examples** + +```PHP +f($i++) xor g($i) // the sequence point makes this well-defined +``` -###General +## Logical Inclusive OR Operator (form 2) **Syntax** + +
-  expression:
-    yield-expression
-    include-expression
-    include-once-expression
-    require-expression
-    require-once-expression
+logical-inc-OR-expression-2:
+   logical-exc-OR-expression
+   logical-inc-OR-expression-2   or   logical-exc-OR-expression
 
-**Defined elsewhere** +**Semantics** + +Except for the difference in precedence, operator and has exactly the +same semantics as [operator `||`](#logical-inclusive-or-operator-form-1). + +## Script Inclusion Operators + +### General -* [*yield-expression*](#yield-operator) -* [*include-expression*](#the-include-operator) -* [*include-once-expression*](#the-include_once-operator) -* [*require-expression*](#the-require-operator) -* [*require-once-expression*](#the-require_once-operator) +**Syntax** + + + +
+expression:
+   logical-inc-OR-expression-2
+   include-expression
+   include-once-expression
+   require-expression
+   require-once-expression
+
**Semantics** @@ -3077,7 +3450,7 @@ class Bar{ include 'include.php'; } } -echo X; // emits a notice: Use of undefined constant X ... +echo X; // emits a warning: Use of undefined constant X ... echo \foo\X; // same as above since the inclusion did not happen yet $bar = new Bar(); $bar->bar(); @@ -3109,23 +3482,23 @@ echo $x; // hello ```` -###The `include` Operator +### The `include` Operator **Syntax** + +
-  include-expression:
-    include  (  expression  )
-    include  expression
+include-expression:
+   include   expression
 
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** -*expresssion* must be convertable to a string, which designates +*expression* must be convertable to a string, which designates a filename. **Semantics** @@ -3161,20 +3534,20 @@ $inc = include('limits.php'); If ((include 'Positions.php') == 1) ... ``` -###The `include_once` Operator +### The `include_once` Operator **Syntax** + +
-  include-once-expression:
-    include_once  (  expression  )
-    include_once  expression
+include-once-expression:
+   include_once   expression
 
-**Defined elsewhere** - -* [*expression*](#general-6) - **Semantics** This operator is identical to operator [`include`](#the-include-operator) except that in @@ -3209,40 +3582,40 @@ $p1 = new Point(10, 20); $c1 = new Circle(9, 7, 2.4); ``` -###The `require` Operator +### The `require` Operator **Syntax** + +
-  require-expression:
-    require  (  expression  )
-    require  expression
+require-expression:
+   require   expression
 
-**Defined elsewhere** - -* [*expression*](#general-6) - **Semantics** This operator is identical to operator [`include`](#the-include-operator) except that in the case of `require`, failure to find/open the designated include file produces a fatal error. -###The `require_once` Operator +### The `require_once` Operator **Syntax** + +
-  require-once-expression:
-    require_once  (  expression  )
-    require_once  expression
+require-once-expression:
+   require_once   expression
 
-**Defined elsewhere** - -* [*expression*](#general-6) - **Semantics** This operator is identical to operator [`require`](#the-require-operator) except that in @@ -3256,31 +3629,34 @@ happens. The files are identified by the full pathname, so different forms of the filename (such as full and relative path) still are considered the same file. -##Constant Expressions +## Constant Expressions **Syntax** + +
-  constant-expression:
-    array-creation-expression
-    expression
+constant-expression:
+   expression
 
-**Defined elsewhere** - -* [*array-creation-expression*](#array-creation-operator) -* [*expression*](#general-6) - **Constraints** -All of the *element-key* and *element-value* elements in -[*array-creation-expression*](#array-creation-operator) must be literals. +The *expression* may only use the following syntactic elements: -*expression* must have a scalar type, and be a literal or the name of a [c-constant](06-constants.md#general). +* [Literals](#literals). String literals must not use interpolation. +* [Array creation expressions](#array-creation-operator). +* Unary operators `+`, `-`, `~`, `!`. +* Binary operators `+`, `-`, `*`, `/`, `%`, `.`, `**`, `^`, `|`, `&`, + `<`, `>`, `<=`, `>=`, `<=>`, `==`, `!=`, `===`, `!==`, `&&`, `||`, `??`. +* [Conditional expressions](#conditional-operator). +* [Subscript expressions](#subscript-operator). +* [Constant access expressions](#constant-access-expression). +* [Class constant access expressions](#scope-resolution-operator). **Semantics** -A *constant-expression* is the value of a c-constant. A *constant-expression* -is required in several contexts, such as in initializer values in a -[*const-declaration*](14-classes.md#constants) and default initial values in a [function -definition](13-functions.md#function-definitions). +A *constant-expression* evaluates to the value of the constituent *expression*. diff --git a/spec/11-statements.md b/spec/11-statements.md index d0eadd7f..61af9cc8 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -1,66 +1,76 @@ -#Statements +# Statements -##General +## General **Syntax** -
+
 
-  statement:
-    compound-statement
-    labeled-statement
-    expression-statement
-    selection-statement
-    iteration-statement
-    jump-statement
-    try-statement
-    declare-statement
-    const-declaration
-    function-definition
-    class-declaration
-    interface-declaration
-    trait-declaration
-    namespace-definition
-    namespace-use-declaration
-    global-declaration
-    function-static-declaration
+
+statement:
+   compound-statement
+   named-label-statement
+   expression-statement
+   selection-statement
+   iteration-statement
+   jump-statement
+   try-statement
+   declare-statement
+   echo-statement
+   unset-statement
+   const-declaration
+   function-definition
+   class-declaration
+   interface-declaration
+   trait-declaration
+   namespace-definition
+   namespace-use-declaration
+   global-declaration
+   function-static-declaration
 
-**Defined elsewhere** - -* [*compound-statement*](#compound-statements) -* [*labeled-statement*](#labeled-statements) -* [*expression-statement*](#expression-statements) -* [*selection-statement*](#general-1) -* [*iteration-statement*](#general-2) -* [*jump-statement*](#general-3) -* [*declare-statement*](#the-declare-statement) -* [*const-declaration*](14-classes.md#constants) -* [*function-definition*](13-functions.md#function-definitions) -* [*class-declaration*](14-classes.md#class-declarations) -* [*interface-declaration*](15-interfaces.md#interface-declarations) -* [*trait-declaration*](16-traits.md#trait-declarations) -* [*namespace-definition*](18-namespaces.md#defining-namespaces) -* [*namespace-use-declaration*](18-namespaces.md#namespace-use-declarations) -* [*global-declaration*](07-variables.md#global-variables) -* [*function-static-declaration*](07-variables.md#function-statics) - -##Compound Statements +## Compound Statements **Syntax** -
-  compound-statement:
-    {   statement-listopt  }
+
 
-**Defined elsewhere**
+
+compound-statement:
+   {   statement-listopt   }
 
-* [*statement*](#general)
+statement-list:
+   statement
+   statement-list   statement
+
**Semantics** @@ -86,63 +96,43 @@ while (condition) } ``` -##Labeled Statements +## Labeled Statements **Syntax** -
-  labeled-statement:
-    named-label-statement
-    case-statement
-    default-statement
-
-  named-label-statement:
-    name  :  statement
-
-  case-statement:
-    case   expression   case-default-label-terminator   statement
+
 
-  default-statement:
-    default  case-default-label-terminator   statement
-
-  case-default-label-terminator:
-    :
-    ;
+
+named-label-statement:
+   name   :
 
-**Defined elsewhere** - -* [*name*](09-lexical-structure.md#names) -* [*statement*](#general) -* [*expression*](10-expressions.md#general-6) - **Constraints** -A named label can be used as the target of a [`goto` statement](#the-goto-statement). - Named labels must be unique within a function. -A case and default labeled statements must only occur inside a [`switch` statement](#the-switch-statement). - **Semantics** -Any statement may be preceded by a token sequence that declares a name -as a label name. The presence of a label does not alter the flow of -execution. +A named label can be used as the target of a [`goto` statement](#the-goto-statement). +The presence of a label does not by itself alter the flow of execution. -##Expression Statements +## Expression Statements **Syntax** + +
-   expression-statement:
-     expressionopt  ;
+expression-statement:
+   expressionopt   ;
 
-**Defined elsewhere** - -* [*expression*](10-expressions.md#general-6) - **Semantics** If present, *expression* is evaluated for its side effects, if any, and @@ -181,63 +171,84 @@ done: } ``` -##Selection Statements +## Selection Statements -###General +### General **Syntax** + +
-  selection-statement:
-    if-statement
-    switch-statement
+selection-statement:
+   if-statement
+   switch-statement
 
-**Defined elsewhere** - -* [*if-statement*](#the-if-statement) -* [*switch-statement*](#the-switch-statement) - **Semantics** Based on the value of a controlling expression, a selection statement selects among a set of statements. -###The `if` Statement +### The `if` Statement **Syntax** -
-  if-statement:
-    if   (   expression   )   statement   elseif-clauses-1opt   else-clause-1opt
-    if   (   expression   )   :   statement-list   elseif-clauses-2opt   else-clause-2opt   endif   ;
+
+
+
+if-statement:
+   if   (   expression   )   statement   elseif-clauses-1opt   else-clause-1opt
+   if   (   expression   )   :   statement-list   elseif-clauses-2opt   else-clause-2opt   endif   ;
 
-**Defined elsewhere**
+elseif-clauses-1:
+   elseif-clause-1
+   elseif-clauses-1   elseif-clause-1
 
-* [*expression*](10-expressions.md#general-6)
-* [*statement*](#general)
-* [*statement-list*](#compound-statements)
+elseif-clause-1:
+   elseif   (   expression   )   statement
+
+else-clause-1:
+   else   statement
+
+elseif-clauses-2:
+   elseif-clause-2
+   elseif-clauses-2   elseif-clause-2
+
+elseif-clause-2:
+   elseif   (   expression   )   :   statement-list
+
+else-clause-2:
+   else   :   statement-list
+
**Semantics** @@ -296,27 +307,49 @@ else // this else does go with the outer if ... ``` -###The `switch` Statement +### The `switch` Statement **Syntax** + +
-  switch-statement:
-    switch  (  expression  )  { case-statementsopt }
-    switch  (  expression  )  :   case-statementsopt  endswitch;
+switch-statement:
+   switch   (   expression   )   {   case-statementsopt   }
+   switch   (   expression   )   :   case-statementsopt   endswitch   ;
 
-  case-statements:
-    case-statement statement-listopt case-statementsopt
-    default-statement statement-listopt case-statementsopt
-
+case-statements: + case-statement case-statementsopt + default-statement case-statementsopt -**Defined elsewhere** +case-statement: + case expression case-default-label-terminator statement-listopt -* [*expression*](10-expressions.md#general-6) -* [*case-statement*](#labeled-statements) -* [*default-statement*](#labeled-statements) -* [*compound-statement*](#compound-statements) -* [*statement-list*](#compound-statements) +default-statement: + default case-default-label-terminator statement-listopt + +case-default-label-terminator: + : + ; +
**Constraints** @@ -400,43 +433,44 @@ case $v < $a: // non-constant expression } ``` -##Iteration Statements +## Iteration Statements -###General +### General **Syntax** + +
-  iteration-statement:
-    while-statement
-    do-statement
-    for-statement
-    foreach-statement
+iteration-statement:
+   while-statement
+   do-statement
+   for-statement
+   foreach-statement
 
-**Defined elsewhere** - -* [*while-statement*](#the-while-statement) -* [*do-statement*](#the-do-statement) -* [*for-statement*](#the-for-statement) -* [*foreach-statement*](#the-foreach-statement) - -##The `while` Statement +## The `while` Statement **Syntax** + +
-  while-statement:
-    while  (  expression  )  statement
-    while  (  expression  )  :   statement-list  endwhile ;
+while-statement:
+   while   (   expression   )   statement
+   while   (   expression   )   :   statement-list   endwhile   ;
 
-**Defined elsewhere** - -* [*expression*](10-expressions.md#general-6) -* [*statement*](#general) -* [*statement-list*](#compound-statements) - **Semantics** The two forms of the `while` statement are equivalent; they simply provide @@ -469,22 +503,22 @@ while (TRUE) } ``` -##The `do` Statement +## The `do` Statement **Syntax** + +
-  do-statement:
-    do  statement  while  (  expression  )  ;
+do-statement:
+   do   statement   while   (   expression   )   ;
 
(Note: There is no alternate syntax). -**Defined elsewhere** - -* [*statement*](#general) -* [*expression*](10-expressions.md#general-6) - **Constraints** The controlling expression *expression* must have type `bool` or be @@ -513,39 +547,52 @@ do while ($i <= 10); ``` -##The `for` Statement +## The `for` Statement **Syntax** + +
-  for-statement:
-    for   (   for-initializeropt   ;   for-controlopt   ;   for-end-of-loopopt   )   statement
-    for   (   for-initializeropt   ;   for-controlopt   ;   for-end-of-loopopt   )   :   statement-list   endfor   ;
+for-statement:
+   for   (   for-initializeropt   ;   for-controlopt   ;   for-end-of-loopopt   )   statement
+   for   (   for-initializeropt   ;   for-controlopt   ;   for-end-of-loopopt   )   :   statement-list   endfor   ;
 
-  for-initializer:
-    for-expression-group
+for-initializer:
+   for-expression-group
 
-  for-control:
-    for-expression-group
+for-control:
+   for-expression-group
 
-  for-end-of-loop:
-    for-expression-group
+for-end-of-loop:
+   for-expression-group
 
-  for-expression-group:
-    expression
-    for-expression-group   ,   expression
+for-expression-group:
+   expression
+   for-expression-group   ,   expression
 
Note: Unlike C/C++, PHP does not support a comma operator, per se. However, the syntax for the `for` statement has been extended from that of C/C++ to achieve the same results in this context. -**Defined elsewhere** - -* [*statement*](#general) -* [*statement-list*](#compound-statements) -* [*expression*](10-expressions.md#general-6) - **Semantics** The two forms of the `for` statement are equivalent; they simply provide @@ -605,32 +652,41 @@ for ($a = 100, $i = 1; ++$i, $i <= 10; ++$i, $a -= 10) } ``` -##The `foreach` Statement +## The `foreach` Statement **Syntax** -
-  foreach-statement:
-    foreach  (  foreach-collection-name  as  foreach-keyopt  foreach-value  )   statement
-    foreach  (  foreach-collection-name  as  foreach-keyopt  foreach-value  )  :  statement-list  endforeach  ;
+
+
+
+foreach-statement:
+   foreach   (   foreach-collection-name   as   foreach-keyopt   foreach-value   )   statement
+   foreach   (   foreach-collection-name   as   foreach-keyopt   foreach-value   )   :   statement-list   endforeach   ;
 
-**Defined elsewhere**
+foreach-collection-name:
+   expression
 
-* [*statement*](#general)
-* [*statement-list*](#compound-statements)
-* [*list-intrinsic*](10-expressions.md#list)
-* [*expression*](10-expressions.md#general-6)
+foreach-key:
+   expression   =>
+
+foreach-value:
+   &opt   expression
+   list-intrinsic
+
**Constraints** @@ -688,42 +744,44 @@ foreach ($colors as &$color) // note the & } ``` -##Jump Statements +## Jump Statements -###General +### General **Syntax** + +
-  jump-statement:
-    goto-statement
-    continue-statement
-    break-statement
-    return-statement
-    throw-statement
+jump-statement:
+   goto-statement
+   continue-statement
+   break-statement
+   return-statement
+   throw-statement
 
-**Defined elsewhere** - -* [*goto-statement*](#the-goto-statement) -* [*continue-statement*](#the-continue-statement) -* [*break-statement*](#the-break-statement) -* [*return-statement*](#the-return-statement) -* [*throw-statement*](#the-throw-statement) - -###The `goto` Statement +### The `goto` Statement **Syntax** + +
-  goto-statement:
-    goto  name  ;
+goto-statement:
+   goto   name   ;
 
-**Defined elsewhere** - -* [*name*](09-lexical-structure.md#names) - **Constraints** The name in a `goto` statement must be that of a [named label](#labeled-statements) located @@ -763,21 +821,27 @@ done: } ``` -###The `continue` Statement +### The `continue` Statement **Syntax** -
-  continue-statement:
-    continue   breakout-levelopt  ;
+
 
-**Defined elsewhere**
+
+continue-statement:
+   continue   breakout-levelopt   ;
 
-* [*integer-literal*](09-lexical-structure.md#integer-literals)
+breakout-level:
+   integer-literal
+   (   breakout-level   )
+
**Constraints** @@ -796,9 +860,11 @@ number `1` and containing statements having levels increasing by 1. A `continue` statement terminates the execution of one or more enclosing [iteration](#iteration-statements) or [`switch`](#the-switch-statement) statements, up to the specified level. If the statement at the *breakout-level* is an iteration statement, -the next iteration (if any) of the next innermost enclosing iteration or switch statement is started. +the next iteration (if any) of the iteration statement is started. If that statement is a `for` statement and it has a *for-end-of-loop*, its -end-of-loop expression group for the current iteration is evaluated first. If +end-of-loop expression group for the current iteration is evaluated first. If it +is a `switch` statement, a warning is emitted and the behavior is the same as a +[`break` statement](#the-break-statement) at the same *breakout-level*. If *breakout-level* is omitted, a level of 1 is assumed. A `continue` statement may break out of a construct that is fully @@ -815,19 +881,20 @@ for ($i = 1; $i <= 5; ++$i) } ``` -###The `break` Statement +### The `break` Statement **Syntax** + +
-  break-statement:
-    break  breakout-levelopt  ;
+break-statement:
+   break   breakout-levelopt   ;
 
-**Defined elsewhere** - -* [*breakout-level*](#the-continue-statement) - **Constraints** The breakout level must be greater than zero, and it must not exceed the level of @@ -880,24 +947,20 @@ for ($i = 10; $i <= 40; $i +=10) } ``` -###The `return` Statement +### The `return` Statement **Syntax** + +
-  return-statement:
-    return  expressionopt  ;
+return-statement:
+   return   expressionopt   ;
 
-**Defined elsewhere** - -* [*expression*](10-expressions.md#general-6) - -**Constraints** - -The *expression* in a *return-statement* in a [generator function](10-expressions.md#yield-operator) -must be the literal `NULL` or be omitted. - **Semantics** A `return` statement from within a function terminates the execution of @@ -908,6 +971,10 @@ by value or byRef. If *expression* is omitted the value `NULL` is used. If execution flows into the closing brace (`}`) of a function, `return NULL;` is implied. +Explicit `return` statements with *expression* given are not permitted within a +function with a `void` [return type](13-functions.md#return-typing) and cause +a fatal error. + A function may have any number of `return` statements, whose returned values may have different types. @@ -926,7 +993,8 @@ If an uncaught exception exists when a finally-block is executed, if that finally-block executes a `return` statement, the uncaught exception is discarded. -A `return` statement may occur in a script outside any function. In an [included file](10-expressions.md#general-6), +A `return` statement may occur in a script outside any function. In an +[included file](10-expressions.md#script-inclusion-operators), such statement terminates processing of that script file and returns control to the including file. If *expression* is present, that is the value returned; otherwise, the value `NULL` is returned. If @@ -938,9 +1006,13 @@ implied. Likewise, if *expression* is omitted at the top level. (See also Returning from a constructor or destructor behaves just like returning from a function. -A `return` statement inside a generator function causes the generator to +A `return` statement inside a [generator function](10-expressions.md#yield-operator) causes the generator to terminate. +A generator function can contain a statement of the form `return` *expression* `;`. The value this returns +can be fetched using the method `Generator::getReturn`, which can only be called once the generator +has finishing yielding values. The value cannot be returned byRef. + Return statements can also be used in the body of anonymous functions. `return` also terminates the execution of source code given to the intrinsic @@ -989,19 +1061,20 @@ the cases of `return $a++;` and `return ++$a;`, it is obvious what value must be returned in each case, but if `$a` is a variable local to the enclosing function, `$a` need not actually be incremented. -###The `throw` Statement +### The `throw` Statement **Syntax** + +
-  throw-statement:
-    throw  expression  ;
+throw-statement:
+   throw   expression   ;
 
-**Defined elsewhere** - -* [*expression*](10-expressions.md#general-6) - **Constraints** The type of *expression* must be [Exception](17-exception-handling.md#class-exception) or a subclass of that @@ -1029,38 +1102,56 @@ class MyException extends Exception { ... } throw new MyException; ``` -##The `try` Statement +## The `try` Statement **Syntax** -
-  try-statement:
-    try  compound-statement   catch-clauses
-    try  compound-statement   finally-clause
-    try  compound-statement   catch-clauses   finally-clause
+
+
+
+try-statement:
+   try   compound-statement   catch-clauses
+   try   compound-statement   finally-clause
+   try   compound-statement   catch-clauses   finally-clause
 
-**Defined elsewhere**
+catch-clauses:
+   catch-clause
+   catch-clauses   catch-clause
 
-* [*compound-statement*](#compound-statements)
-* [*variable-name*](09-lexical-structure.md#names)
-* [*qualified-name*](09-lexical-structure.md#names)
+catch-clause:
+   catch   (   catch-name-list   variable-name   )   compound-statement
+
+catch-name-list:
+   qualified-name
+   catch-name-list   |   qualified-name
+
+finally-clause:
+   finally   compound-statement
+
**Constraints** -In a *catch-clause*, *parameter-declaration-list* must contain only one -parameter, and its type must be [`Exception`](17-exception-handling.md#class-exception) or a type derived from -that class, and that parameter must not be passed byRef. +Each *qualified-name* inside a *catch-name-list* must name a type derivated from +[`Exception`](17-exception-handling.md#class-exception). **Semantics** @@ -1081,9 +1172,10 @@ try-block that encloses the call to the current function. This process continues until a catch-block is found that can handle the current exception. -The matching is done by considering the class specified by *qualified-name* -and comparing it to the type of the exception. If the exception is an -[instance of](10-expressions.md#instanceof-operator) this class then the clause matches. +The matching is done by considering the classes specified by *qualified-name* +in *catch-name-list* and comparing it to the type of the exception. If the +exception is an [instance of](10-expressions.md#instanceof-operator) one of +the specified classes then the clause matches. If a matching catch-block is located, the Engine prepares to transfer control to the first statement of that catch-block. However, before @@ -1130,28 +1222,34 @@ catch (DeviceException $dve) { ... } finally { ... } ``` -##The `declare` Statement +## The `declare` Statement **Syntax** -
-  declare-statement:
-    declare  (  declare-directive  )  statement
-    declare  (  declare-directive  )  :  statement-list  enddeclare  ;
-    declare  (  declare-directive  )  ;
+
 
+
+declare-statement:
+   declare   (   declare-directive   )   statement
+   declare   (   declare-directive   )   :   statement-list   enddeclare   ;
+   declare   (   declare-directive   )   ;
+
+declare-directive:
+   ticks   =   literal
+   encoding   =   literal
+   strict_types   =   literal
 
-**Defined elsewhere** - -* [*statement*](#general) -* [*statement-list*](#compound-statements) -* [*literal*](09-lexical-structure.md#literals) - **Constraints** The literal for *ticks* must designate a value that is, or can be converted, to an @@ -1164,6 +1262,10 @@ encoding](http://en.wikipedia.org/wiki/Character_encoding). Except for white space, a *declare-statement* in a script that specifies *character-encoding* must be the first thing in that script. +The literal for *strict_types* should be either `0` or `1`. Only the statement-less +form can be used for *strict_types* declare. The *strict_types* declare should be the first statement +in the script, excepting other declare statements. + **Semantics** The first two forms of the `declare` statement are equivalent; they simply @@ -1172,7 +1274,9 @@ provide alternate styles. The `declare` statement sets an *execution directive* for its *statement* body, or for the `;`-form, for the remainder of the script or until the statement is overridden by another *declare-statement*, whichever comes -first. As the parser is executing, certain statements are considered +first. + +*ticks*: as the parser is executing, certain statements are considered *tickable*. For every *tick-count* ticks, an event occurs, which can be serviced by the function previously registered by the library function [`register_tick_function`](http://php.net/manual/function.register-tick-function.php). @@ -1180,12 +1284,17 @@ Tick event monitoring can be disabled by calling the library function [`unregister_tick_function`](http://php.net/manual/function.unregister-tick-function.php). This facility allows a profiling mechanism to be developed. -Character encoding can be specified on a script-by-script basis using +*encoding*: character encoding can be specified on a script-by-script basis using the encoding directive. The joint ISO and IEC standard [ISO/IEC 8859 standard series](http://en.wikipedia.org/wiki/ISO/IEC_8859) specifies a number of 8-bit-[character encodings](http://en.wikipedia.org/wiki/Character_encoding) whose names can be used with this directive. +This directive applies only to the file it appears in, and does not affect the included files. + +*strict_types*: if set to `1`, scalar type checking for function calls will be +checked using [strict mode](13-functions.md#type-check-modes). If set to `0`, the coercive mode (default) is used. +This directive applies only to the file it appears in, and does not affect the included files. **Examples** @@ -1194,3 +1303,106 @@ declare(ticks = 1) { ... } declare(encoding = 'ISO-8859-1'); // Latin-1 Western European declare(encoding = 'ISO-8859-5'); // Latin/Cyrillic ``` + +## The `echo` Statement + +**Syntax** + + + +
+echo-statement:
+   echo   expression-list   ;
+
+expression-list:
+   expression
+   expression-list   ,   expression
+
+ +**Constraints** + +The *expression* value must be +[convertable to a string](08-conversions.md#converting-to-string-type). +In particular, it should not be an array and if it is an object, it must implement +a [`__toString` method](14-classes.md#method-__tostring). + +**Semantics** + +After converting each of its *expression*s' values to strings, if +necessary, `echo` concatenates them in order given, and writes the +resulting string to [`STDOUT`](06-constants.md#core-predefined-constants). Unlike [`print`](10-expressions.md#print-expression), it does +not produce a result. + +See also: [double quoted strings](09-lexical-structure.md#double-quoted-string-literals) and +[heredoc documents](09-lexical-structure.md#heredoc-string-literals), [conversion to string](08-conversions.md#converting-to-string-type). + +**Examples** + +```PHP +$v1 = TRUE; +$v2 = 123; +echo '>>' . $v1 . '|' . $v2 . "<<\n"; // outputs ">>1|123<<" +echo '>>' , $v1 , '|' , $v2 , "<<\n"; // outputs ">>1|123<<" +echo ('>>' . $v1 . '|' . $v2 . "<<\n"); // outputs ">>1|123<<" +$v3 = "qqq{$v2}zzz"; +echo "$v3\n"; +``` + +## The `unset` Statement + +**Syntax** + + + +
+unset-statement:
+   unset   (   variable-list   ,opt   )   ;
+
+ +**Semantics** + +This statement [unsets](07-variables.md#general) the variables designated by each +*variable* in *variable-list*. No value is returned. An +attempt to unset a non-existent variable (such as a non-existent element +in an array) is ignored. + +When called from inside a function, this statement behaves, as follows: + +- For a variable declared `global` in that function, `unset` removes the + alias to that variable from the scope of the current call to that + function. The global variable remains set. + (To unset the global variable, use unset on the corresponding + [`$GLOBALS`](07-variables.md#predefined-variables) array entry. +- For a variable passed byRef to that function, `unset` removes the + alias to that variable from the scope of the current call to that + function. Once the function returns, the passed-in argument variable + is still set. +- For a variable declared static in that function, `unset` removes the + alias to that variable from the scope of the current call to that + function. In subsequent calls to that function, the static variable + is still set and retains its value from call to call. + +Any visible instance property may be unset, in which case, the property +is removed from that instance. + +If this statement is used with an expression that designates a [dynamic +property](14-classes.md#dynamic-members), then if the class of that property has an [`__unset` +method](14-classes.md#method-__unset), that method is called. + +**Examples** + +```PHP +unset($v); +unset($v1, $v2, $v3); +unset($x->m); // if m is a dynamic property, $x->__unset("m") is called +``` diff --git a/spec/12-arrays.md b/spec/12-arrays.md index ee7d16e8..2021c48c 100644 --- a/spec/12-arrays.md +++ b/spec/12-arrays.md @@ -1,6 +1,6 @@ -#Arrays +# Arrays -##General +## General An [*array*](http://php.net/manual/language.types.array.php) is a data structure that contains a collection of zero or more *elements*. An array element can have any type (which allows for arrays of arrays) @@ -14,7 +14,7 @@ elements in the map is the order in which the elements were *inserted* into the array. An element is said to *exist* once it has been inserted into the array with a corresponding key. An array is *extended* by initializing a previously non-existent element using a new key. Elements -can be *removed* from an array via the intrinsic [`unset`](10-expressions.md#unset). +can be *removed* from an array via the [`unset` statement](11-statements.md#the-unset-statement). The [`foreach` statement](11-statements.md#the-foreach-statement) can be used to iterate over the collection of elements in an array in order. This statement also provides a way to access the key and value @@ -27,18 +27,16 @@ is the first element inserted into the array. Numerous [library functions](http://php.net/manual/en/ref.array.php) are available to create and/or manipulate arrays. -Note: Arrays in PHP are different from arrays in several other languages. +Note: Arrays in PHP are different from arrays in several other languages. Specifically, in PHP, array elements need not have the same type, the subscript index need not be an integer, and there is no concept of consecutive elements of the array occupying physically adjacent memory locations). -##Array Creation and Initialization +## Array Creation and Initialization -An array is created and initialized by one of two equivalent ways: via -the array-creation operator [`[]`](10-expressions.md#array-creation-operator) or the [intrinsic `array`](10-expressions.md#array). +An array is created and initialized using the +[array-creation operator](10-expressions.md#array-creation-operator): -##Element Access and Insertion +## Element Access and Insertion The value (and possibly the type) of an existing element is changed, and new elements are inserted, using the subscript operator [`[]`](10-expressions.md#subscript-operator). - - diff --git a/spec/13-functions.md b/spec/13-functions.md index b689c4d6..75c48d93 100644 --- a/spec/13-functions.md +++ b/spec/13-functions.md @@ -1,6 +1,6 @@ -#Functions +# Functions -##General +## General When a function is called, information may be passed to it by the caller via an *argument list*, which contains one or more *argument @@ -17,7 +17,7 @@ case of an *outer function*, and an *inner function* defined within it. Until the outer function is called at least once, its inner function does not exist. Even if the outer function is called, if its runtime logic bypasses the definition of the inner function, that inner function still -does not exist. The conditionally defined function comes into existance when +does not exist. The conditionally defined function comes into existence when the execution flow reaches the point where the function is defined. Any function containing [`yield`](10-expressions.md#yield-operator) is a *generator function*. @@ -39,52 +39,111 @@ ucf2(); // now cf2 exists cf2(); // so we can call it ``` -##Function Calls +## Function Calls A function is called via the function-call operator [`()`](10-expressions.md#function-call-operator). -##Function Definitions +## Function Definitions **Syntax** + +
-  function-definition:
-    function-definition-header   compound-statement
+function-definition:
+   function-definition-header   compound-statement
 
-  function-definition-header:
-    function  &opt   name  (  parameter-declaration-listopt  )
+function-definition-header:
+   function   &opt   name   (   parameter-declaration-listopt   )   return-typeopt
 
-  parameter-declaration-list:
-    simple-parameter-declaration-list
-    variadic-declaration-list
+parameter-declaration-list:
+   simple-parameter-declaration-list
+   variadic-declaration-list
 
-  simple-parameter-declaration-list:
-    parameter-declaration
-    parameter-declaration-list  ,  parameter-declaration
+simple-parameter-declaration-list:
+   parameter-declaration
+   parameter-declaration-list   ,   parameter-declaration
 
-  variadic-declaration-list:
-    simple-parameter-declaration-list  ,  variadic-parameter
-    variadic-parameter
+variadic-declaration-list:
+   simple-parameter-declaration-list   ,   variadic-parameter
+   variadic-parameter
 
-  parameter-declaration:
-    type-declarationopt  &opt  variable-name   default-argument-specifieropt
+parameter-declaration:
+   type-declarationopt   &opt   variable-name   default-argument-specifieropt
 
-  variadic-parameter:
-	type-declarationopt  &opt  ...  variable-name
+variadic-parameter:
+   type-declarationopt   &opt   ...   variable-name
 
-  type-declaration:
-    array
-    callable
-    qualified-name
+return-type:
+   :   type-declaration
+   :   void
 
-  default-argument-specifier:
-    =  constant-expression
-
+type-declaration: + ?opt base-type-declaration -**Defined elsewhere** +base-type-declaration: + array + callable + iterable + scalar-type + qualified-name -* [*constant-expression*](10-expressions.md#constant-expressions) -* [*qualified-name*](09-lexical-structure.md#names) +scalar-type: + bool + float + int + string + +default-argument-specifier: + = constant-expression +
**Constraints** @@ -93,6 +152,11 @@ Each parameter name in a *function-definition* must be distinct. A [conditionally defined function](#general) must exist before any calls are made to that function. +The *function-definition* for constructors, destructors, and clone methods must not contain *return-type*. + +For generator functions, if the the return type is specified, it can only be one of: +`Generator`, `Iterator` or `Traversable`. + **Semantics** A *function-definition* defines a function called *name*. Function names @@ -103,7 +167,7 @@ parameter has a name, *variable-name*, and optionally, a *default-argument-specifier*. An `&` in *parameter-declaration* indicates that parameter is passed [byRef](04-basic-concepts.md#assignment) rather than by value. An `&` before *name* indicates that the value returned from this function is to -be returned byRef. Function-value returning is described in [`return` statement description](11-statements.md#the-return-statement). +be returned byRef. Returning values is described in [`return` statement description](11-statements.md#the-return-statement). When the function is called, if there exists a parameter for which there is a corresponding argument, the argument is assigned to the parameter @@ -137,12 +201,12 @@ By default, a parameter will accept an argument of any type. However, by specifying a *type-declaration*, the types of argument accepted can be restricted. By specifying `array`, only an argument of the `array` type is accepted. By specifying `callable`, only an argument designating a -function (see below) is accepted. By specifying *qualified-name*, only an instance -of a class having that type, or being derived from that type, are -accepted, or only an instance of a class that implements that interface -type directly or indirectly is accepted. The check is the same as for [`instanceof` operator](10-expressions.md#instanceof-operator). - -If a parameter has a type declaration, `NULL` is not accepted unless it has a default value that evaluates to `NULL`. +function (see below) is accepted. By specifying `iterable`, only an argument that +is of type `array` or an object implementing the `Traversable` interface is accepted. +By specifying *qualified-name*, only an instance of a class having that type, +or being derived from that type, are accepted, or only an instance of a class that +implements that interface type directly or indirectly is accepted. The check is the +same as for [`instanceof` operator](10-expressions.md#instanceof-operator). `callable` pseudo-type accepts the following: * A string value containing the name of a function defined at the moment of the call. @@ -156,14 +220,95 @@ that can be called on an object designated by the first element, from the contex The library function [`is_callable`](http://php.net/is_callable) reports whether the contents of a variable can be called as a function. -##Variable Functions +Parameters typed with *scalar-type* are accepted if they pass the type check for this [scalar type](05-types.md#scalar-types), +as [described below](#type-check-modes). Once the checks have been passed, the parameter types are always of the scalar type +specified (or `NULL` if `NULL` is allowed). + +If a parameter has a type declaration, `NULL` is not accepted unless the +type is nullable. A type is nullable if it is prefixed with `?` or if the +parameter has a default value that evaluates to `NULL`. + +The default value for a typed parameter must be of the type specified, or `NULL`, +and conversion is not be performed for defaults, regardless of the mode. + +## Return typing + +If the function is defined with *return-type* declaration, the value returned by the function should +be compatible with the defined type, using the same rules as for parameter type checks. `NULL` values +are not allowed for typed returns. If the value of the [`return` statement](11-statements.md#the-return-statement) +does not pass the type check, a fatal error is produced. + +The `void` type is a special type that can only be used as a return type, and +not in other contexts. It has no effect at runtime, see the [`return` statement](11-statements.md#the-return-statement). + +## Type check modes + +The type checking can be performed in two modes, strict and coercive (default). +The difference between modes exists only for scalar typed parameters (`int`, `float`, `string` and `bool`). + +For coercive mode, if the value passed is of the same type as the parameter, it is accepted. +If not, the [conversion](08-conversions.md#general) is attempted. If the conversion succeeds, +the converted value is the value assigned to the parameter. If the conversion fails, a fatal error +is produced. + +For strict mode, the parameter must be exactly of the type that is declared (e.g., string `"1"` is not +accepted as a value for parameter typed as `int`). The only exception is that `int` values will be accepted +for `float` typed parameter and [converted to `float`](08-conversions.md#converting-to-floating-point-type). +Note that the strict mode applies not only to user-defined but also to internal functions, +please consult [the manual](http://php.net/manual/) for appropriate parameter types. If the types do not match, +an exception of type `TypeError` is thrown. + +Note that if the parameter is passed byRef, and conversion happened, +then the value will be re-assigned with the newly converted value. + +The mode is set by the [`declare` statement](11-statements.md#the-declare-statement). + +Note that the type check mode is for the function call controleed by the caller, not the callee. +While the check is performed in the function being called, the caller defines whether the check is strict. +Same function can be called with both strict and coercive mode checks from different contexts. + +The check for the return type is always defined by the script that the function was defined in. + +**Examples** + +```PHP +// coercive mode by default +function accept_int(int $a) { return $a+1; } +accept_int(1); // ok +accept_int("123"); // ok +accept_int("123.34"); // ok +accept_int("123.34 and some"); // ok + notice +accept_int("not 123"); // fatal error! +accept_int(null); // fatal error + +function accept_int_or_not(int $a = null) { return $a+1; } +accept_int_or_not(null); // ok + +function convert_int(int &$a) { return $a+1; } +$a = "12"; +convert_int($a); +var_dump($a); // $a is now int + +// Now in strict mode +declare(strict_types=1); +function accept_int(int $a) { return $a+1; } +function accept_float(float $a) { return $a+1; } +accept_int(1); // ok +accept_float(1); // ok +accept_int(1.5); // fatal error +accept_int("123"); // fatal error +echo substr("123", "1"); // fatal error + +``` + +## Variable Functions If a variable name is followed by the function-call operator [`()`](10-expressions.md#function-call-operator), and the value of that variable designates the function currently defined and visible (see description above), that function will be executed. If the variable does not designate a function or this function can not be called, a fatal error is produced. -##Anonymous Functions +## Anonymous Functions An *anonymous function*, also known as a *closure*, is a function defined with no name. As such, it must be defined in the context of an @@ -172,4 +317,4 @@ that is saved in a variable for later execution. An anonymous function is defined via the [anonymous function creation operator](10-expressions.md#anonymous-function-creation). For both [`__FUNCTION__` and `__METHOD__`](06-constants.md#context-dependent-constants), an anonymous -function's name is reported as `{closure}`. \ No newline at end of file +function's name is reported as `{closure}`. diff --git a/spec/14-classes.md b/spec/14-classes.md index 252355ae..6a8639d2 100644 --- a/spec/14-classes.md +++ b/spec/14-classes.md @@ -1,24 +1,24 @@ -#Classes +# Classes -##General +## General A class is a type that may contain zero or more explicitly declared *members*, which can be any combination of [*class constants*](#constants); data members, called [*properties*](#properties); and function members, called [*methods*](#methods). The ability to add properties to an -instance at runtime is described in [dynamic members section](#dynamic-members). +instance at runtime is described in [dynamic members section](#dynamic-members). An object (often called an *instance*) of a class type is created (i.e., *instantiated*) via the [new operator](10-expressions.md#the-new-operator). PHP supports [inheritance](#class-declarations), a means by which a *derived class* can -*extend* and specialize a single *base class* (also called *parent*). -Classes in PHP are **not** all derived from a common ancestor. +*extend* and specialize a single *base class* (also called *parent*). +Classes in PHP are **not** all derived from a common ancestor. An [*abstract* class](#class-declarations) is a base type intended for derivation, but which cannot be instantiated directly. A *concrete* class is a class that is not abstract. A [*final* class](#class-declarations) is one from which other classes cannot be derived. -A class may [*implement*](#class-declarations) one or more [*interfaces*](15-interfaces.md#general), +A class may [*implement*](#class-declarations) one or more [*interfaces*](15-interfaces.md#general), each of which defines a contract. Interfaces may have method and constants, but not properties. A class can *use* one or more [traits](16-traits.md#general), which allows a class to @@ -52,30 +52,53 @@ When an instance is allocated, `new` returns a handle that points to that object. As such, assignment of a handle does not copy the object itself. (See [cloning objects](04-basic-concepts.md#cloning-objects) for a discussion of shallow and deep copying). -##Class Declarations +While PHP supports *anonymous class types*, such a type cannot be declared using [*class-declaration*](#class-declarations). Instead, it must be specified at the time of instantiation; that is, as part of an [*object-creation-expression*](10-expressions.md#the-new-operator). + +## Class Declarations **Syntax** -
-  class-declaration:
-    class-modifieropt  class  name   class-base-clauseopt  class-interface-clauseopt   {   trait-use-clausesopt   class-member-declarationsopt }
+
+
+
+class-declaration:
+   class-modifiersopt   class   name   class-base-clauseopt   class-interface-clauseopt   {   class-member-declarationsopt   }
 
-* [*class-member-declarations*](#class-members)
-* [*trait-use-clauses*](16-traits.md#trait-declarations)
+class-modifiers:
+   class-modifier
+   class-modifiers   class-modifier
+
+class-modifier:
+   abstract
+   final
+   readonly
+
+class-base-clause:
+   extends   qualified-name
+
+class-interface-clause:
+   implements   qualified-name
+   class-interface-clause   ,   qualified-name
+
**Constraints** @@ -101,7 +124,8 @@ For each interface method, the corresponding implementing method must be *compat - If the interface method is variadic, the implementing method must also be variadic (see also below). - The number of required (i.e. having no defaults) arguments of the implementing methods can not be more than the number of required arguments of the interface method (adding non-optional arguments is not allowed). - The overall number of arguments for the implementing method should be at least the number of the arguments of the interface method (removing arguments is not allowed). -- Each argument of the implementing method must be compatible with corresponding argument of the prototype method. +- Each argument of the implementing method must be compatible with corresponding argument of the prototype method. +- If the interface method defines the return type, the implementing method must have the same return type. Compatible arguments are defined as follows: - Parameter names do not matter. @@ -135,22 +159,20 @@ inherits all the members from the base class. The optional *class-interface-clause* specifies the one or more interfaces that are implemented by the class being defined. -A class can use one or more traits via a [*trait-use-clauses*](16-traits.md#general). - **Examples** ```PHP -abstract class Vehicle +abstract class Vehicle { public abstract function getMaxSpeed(); ... } -abstract class Aircraft extends Vehicle +abstract class Aircraft extends Vehicle { public abstract function getMaxAltitude(); ... } -class PassengerJet extends Aircraft +class PassengerJet extends Aircraft { public function getMaxSpeed() { @@ -166,7 +188,7 @@ $pj = new PassengerJet(...); echo "\$pj's maximum speed: " . $pj->getMaxSpeed() . "\n"; echo "\$pj's maximum altitude: " . $pj->getMaxAltitude() . "\n"; // ----------------------------------------- -final class MathLibrary +final class MathLibrary { private function MathLibrary() {} // disallows instantiation public static function sin() { ... } @@ -174,12 +196,12 @@ final class MathLibrary } $v = MathLibrary::sin(2.34); // ----------------------------------------- -interface MyCollection +interface MyCollection { function put($item); function get(); } -class MyList implements MyCollection +class MyList implements MyCollection { public function put($item) { @@ -193,30 +215,37 @@ class MyList implements MyCollection } ``` -##Class Members +## Class Members **Syntax** -
-  class-member-declarations:
-    class-member-declaration
-    class-member-declarations   class-member-declaration
-
-   class-member-declaration:
-     const-declaration
-     property-declaration
-     method-declaration
-     constructor-declaration
-     destructor-declaration
-
+ -* [*const-declaration*](#constants) -* [*property-declaration*](#properties) -* [*method-declaration*](#methods) -* [*constructor-declaration*](#constructors) -* [*destructor-declaration*](#destructors) +
+class-member-declarations:
+   class-member-declaration
+   class-member-declarations   class-member-declaration
+
+class-member-declaration:
+   class-const-declaration
+   property-declaration
+   method-declaration
+   constructor-declaration
+   destructor-declaration
+   trait-use-clause
+
**Semantics** @@ -230,28 +259,32 @@ A class may contain the following members: - [Properties](#properties) – the variables of the class. - [Methods](#methods) – the computations and actions that can be performed by the class. - + Some methods have special semantics, such as: - + - [Constructor](#constructors) – the actions required to initialize an instance of the class. - [Destructor](#destructors) – the actions to be performed when an instance of the class is no longer needed. - [Special (or *magic*) methods](#methods-with-special-semantics) +Members can be imported from one or more traits via [*trait-use-clauses*](16-traits.md#general). + The class can also have [dynamic members](#dynamic-members) which are not part of the class definition. Methods and properties can either be *static* or *instance* members. A static member is declared using `static`. An instance member is one that is not static. The name of a static or instance member can never be used on its own; it must always be used as the right-hand operand of the -[scope resolution operator](10-expressions.md#scope-resolution-operator) or the [member selection operator](10-expressions.md#member-selection-operator). +[scope resolution operator](10-expressions.md#scope-resolution-operator) +or the [member access operator](10-expressions.md#member-access-operator). Each instance of a class contains its own, unique set of instance properties of that class. An instance member is accessed via the -[`->` operator](10-expressions.md#member-selection-operator). In contrast, a static property designates -exactly one VSlot for its class, which does not belong to any instance, -per se. A static property exists whether or not any instances of that -class exist. A static member is accessed via the [`::` operator](10-expressions.md#scope-resolution-operator). +[`->` operator](10-expressions.md#member-access-operator). In contrast, +a static property designates exactly one VSlot for its class, which does +not belong to any instance, per se. A static property exists whether or +not any instances of that class exist. A static member is accessed via +the [`::` operator](10-expressions.md#scope-resolution-operator). When any instance method operates on a given instance of a class, within that method that object can be accessed via [`$this`](10-expressions.md#general-1). As a @@ -260,7 +293,7 @@ static method does not operate on a specific instance, it has no `$this`. **Examples** ```PHP -class Point +class Point { private static $pointCount = 0; // static property @@ -294,19 +327,19 @@ $cName = 'Point'; echo "Point count = " . $cName::getPointCount() . "\n"; ``` -##Dynamic Members +## Dynamic Members Initially, the instance only has properties that are -declared explicitly in its class's definition. However, properties can be +declared explicitly in its class's definition. However, properties can be added to and removed from the instance at runtime. Static properties of a class can not be changed at runtime, attempt to access non-existing static -property results in a fatal error. +property results in a fatal error. Runtime-created properties always have public visibility. The class can also define special methods for *dynamic members* - methods and properties. This facility uses the same syntax to access the members as the regular members, but instead of accessing actual properties and -methods the engine will use special methods to simulate the access. +methods the engine will use special methods to simulate the access. In the case of dynamic properties, if a class makes provision to do so by defining a series of special methods, it can @@ -338,20 +371,20 @@ the instance method [`__get`](#method-__get), which treats that name as designating a dynamic property of the instance being operated on, and gets its value. In the case of the call to the intrinsic [`isset`](10-expressions.md#isset), this generates a call to the instance method [`__isset`](#method-__isset), -while a call to the intrinsic [`unset`](10-expressions.md#unset) generates a +while a use of the [`unset` statement](11-statements.md#the-unset-statement) generates a call to the instance method [`__unset`](#method-__unset). By defining these four special methods, the implementer of a class can control how dynamic -properties are handled. +properties are handled. The Engine will call the methods only if they are defined, if they are not defined, no error is produced and default behavior is used. In the case of a dynamic method, if a call to an undefined instance method is performed -and the instance has [`__call`](#method-__call) method, then this method is called. -Otherwise, as per default, a fatal error is produced. +and the instance has [`__call`](#method-__call) method, then this method is called. +Otherwise, as per default, a fatal error is produced. If a static call to an undefined class method is performed, and the class defines a -[`__callStatic`](#method-__callstatic) method, this method is called. -Otherwise, as per default, a fatal error is produced. +[`__callStatic`](#method-__callstatic) method, this method is called. +Otherwise, as per default, a fatal error is produced. In both cases, the return value of the call is the return value of the method called. Consider the following code fragment, in which class Widget has neither @@ -376,35 +409,56 @@ and the call to `sMethod` is treated as if it were Widget::__callStatic('sMethod', array(NULL, 1.234)) ``` -##Constants +## Constants **Syntax** + +
-  const-declaration:
-    const  name  =  constant-expression   ;
-
+const-declaration: + const const-elements ; + +class-const-declaration: + visibility-modifieropt const const-elements ; -**Defined elsewhere** +const-elements: + const-element + const-elements , const-element -* [*name*](09-lexical-structure.md#names) -* [*constant-expression*](10-expressions.md#constant-expressions) +const-element: + name = constant-expression +
**Constraints:** -A *const-declaration* must only appear at the top level of a script, be -a *class constant* (inside a [*class-definition*](#class-members) or be an -[*interface constant*](15-interfaces.md#interface-members). +A *const-declaration* must only appear at the top level of a script, and +must not redefine an existing [c-constant](06-constants.md#general). -A *const-declaration* must not redefine an existing [c-constant](06-constants.md#general). +A *class-const-declaration* must be inside a [*class-declaration*](#class-members) or +[*interface-declaration*](15-interfaces.md#interface-members). -A class constant must not have visibility specifier or `static` specifier. +A class constant must not have a `static` specifier. **Semantics:** A *const-declaration* defines a c-constant. -All class constants have public visibility. +If *visibility-modifier* for a class constant is omitted, `public` is assumed. +The *visibility-modifier* applies to all constants defined in the *const-elements* list. All constants are implicitly `static`. @@ -417,61 +471,94 @@ const LOWER = MIN_VAL; class Automobile { const DEFAULT_COLOR = "white"; + public DEFAULT_BRAND = 'benz'; + protected WHEEL_NUM = 4; + private PRIVATE_CONST = 'const'; ... } $col = Automobile::DEFAULT_COLOR; ``` -##Properties +## Properties **Syntax** + +
-  property-declaration:
-    property-modifier   variable-name   property-initializeropt  ;
+property-declaration:
+   property-modifier   property-elements   ;
 
-  property-modifier:
-    var
-    visibility-modifier   static-modifieropt
-    static-modifier   visibility-modifieropt
+property-modifier:
+   var
+   visibility-modifier   static-modifieropt
+   static-modifier   visibility-modifieropt
 
-  visibility-modifier:
-    public
-    protected
-    private
+visibility-modifier:
+   public
+   protected
+   private
 
-  static-modifier:
-    static
+static-modifier:
+   static
 
-  property-initializer:
-    =  constant-expression
-
+property-elements: + property-element + property-elements property-element -**Defined elsewhere** +property-element: + variable-name property-initializeropt ; -* [*variable-name*](09-lexical-structure.md#names) -* [*constant-expression*](10-expressions.md#constant-expressions) +property-initializer: + = constant-expression +
**Semantics** -A *property-declaration* defines an instance or static property. +A *property-declaration* defines one or more instance or static properties. If [*visibility-modifier*](#general) is omitted, `public` is assumed. The `var` modifier -implies public visibility. The `static` modifier defines the member as [static member](#class-members). +implies public visibility. The `static` modifier defines the member as a [static member](#class-members). The *property-initializer* for instance properties is applied prior to the class's [constructor](#constructors) being called. -An instance property that is visible may be [`unset`](10-expressions.md#unset), in which +An instance property that is visible may be [`unset`](11-statements.md#the-unset-statement), in which case, the property is actually removed from that instance. **Examples** ```PHP -class Point +class Point { private static $pointCount = 0; // static property with initializer - + private $x; // instance property private $y; // instance property ... @@ -479,31 +566,39 @@ class Point } ``` -##Methods +## Methods **Syntax** -
-  method-declaration:
-    method-modifiersopt   function-definition
-    method-modifiers   function-definition-header  ;
-
-  method-modifiers:
-    method-modifier
-    method-modifiers   method-modifier
-
-  method-modifier:
-    visibility-modifier
-    static-modifier
-	class-modifier
-
+ -* [*visibility-modifier*](#properties) -* [*static-modifier*](#properties) -* [*function-definition*](13-functions.md#function-definitions) -* [*function-definition-header*](13-functions.md#function-definitions) +
+method-declaration:
+   method-modifiersopt   function-definition
+   method-modifiers   function-definition-header   ;
+
+method-modifiers:
+   method-modifier
+   method-modifiers   method-modifier
+
+method-modifier:
+   visibility-modifier
+   static-modifier
+   class-modifier
+
**Constraints** @@ -537,33 +632,26 @@ If *visibility-modifier* is omitted, `public` is assumed. See [class members](#class-members) for examples of instance and static methods. See [class declarations](#class-declarations) for examples of abstract methods and their subsequent definitions. -##Constructors +## Constructors **Syntax** -
-  constructor-declaration:
-    method-modifiers  function &opt   __construct  (  parameter-declaration-listopt  )  compound-statement
-    method-modifiers  function &opt    name  (  parameter-declaration-listopt  )  compound-statement     [Deprecated form]
+
 
+
+constructor-declaration:
+   method-modifiers   function   &opt   __construct   (   parameter-declaration-listopt   )   compound-statement
 
-**Defined elsewhere** - -* [*method-modifiers*](#methods) -* [*parameter-declaration-list*](13-functions.md#function-definitions) -* [*compound-statement*](11-statements.md#compound-statements) -* [*name*](09-lexical-structure.md#names) - **Constraints** An overriding constructor in a derived class must have the same or a less-restricted [visibility](#general) than the one in the base class. -*method-modifiers* can not contain `static`. - -*name* must be the same as that in the [*class-declaration*](#class-declarations) that -contains this *constructor-declaration*. +*method-modifiers* can not contain `static`. **Semantics** @@ -597,20 +685,10 @@ than once. A call to a base-class constructor searches for the nearest constructor in the class hierarchy. Not every level of the hierarchy needs to have a constructor. -Prior to the addition of the `__construct` form of constructor, a -class's constructor was called the same as its class name. For example, -class `Point`'s constructor was called `Point`. Although this old-style form -is supported, its use is deprecated. In any event, both -`parent::__construct(...)` and `parent::name(...)` (where `name` is the name -of the parent class type) will find an old- or a new-style constructor -in the base class, if one exists. If both forms exist, the new-style one -is used. The same is true of an *object-creation-expression* when -searching for a base-class constructor. - **Examples** ```PHP -class Point +class Point { private static $pointCount = 0; private $x; @@ -629,7 +707,7 @@ class Point ... } // ----------------------------------------- -class MyRangeException extends Exception +class MyRangeException extends Exception { public function __construct($message, ...) { @@ -640,23 +718,23 @@ class MyRangeException extends Exception } ``` -##Destructors +## Destructors **Syntax** + +
-  destructor-declaration:
-    method-modifiers  function  &opt  __destruct  ( ) compound-statement
+destructor-declaration:
+   method-modifiers   function   &opt   __destruct   (   )   compound-statement
 
-**Defined elsewhere** - -* [*method-modifiers*](#methods) -* [*compound-statement*](11-statements.md#compound-statements) - **Constraints** -*method-modifiers* can not contain `static`. +*method-modifiers* can not contain `static`. **Semantics** @@ -684,7 +762,7 @@ inhibits destructor calls from derived classes. See [constructors section](#constructors) for an example of a constructor and destructor. -##Inheritance +## Inheritance When a class `extends` another class it can *override* members of the parent class by declaring a member with the same name. Only properties and methods can be overridden. @@ -692,23 +770,23 @@ member with the same name. Only properties and methods can be overridden. Visibility of the overridden member can not be made more restrictive, only more permissive (from `private` to `protected` to `public`). When a private member is overridden, the methods of the defining class still have access to the original private -member, however non-static public and protected members are shared across the inheritance chain. +member, however non-static public and protected members are shared across the inheritance chain. When a method is overridden, the signature of the overriding method should be [compatible](#class-declarations) with the signature of the original method, by the same rule as if the original method belonged to the interface -and the overriding method belonged to an implementation. +and the overriding method belonged to an implementation. If an implemented method is overridden with an incompatible method, a non-fatal error is issued, however the override is still accepted by the engine. The use of incompatible overrides is not recommended. -##Methods with Special Semantics +## Methods with Special Semantics -###General +### General If a class contains a definition for a method having one of the following names, that method must have the prescribed visibility, signature, and semantics: -Method Name | Description +Method Name | Description ------------|------------- [`__call`](#method-__call) | Calls a dynamic method in the context of an instance method call. [`__callStatic`](#method-__callstatic) | Calls a dynamic method in the context of a static method call. @@ -727,25 +805,20 @@ Method Name | Description [`__wakeup`](#method-__wakeup) | Executed after [unserialization](#serialization) of an instance of this class. In general, method names beginning with `__` are reserved for special methods. The code should not define methods with names -beginning with `__` unless it is one of the special methods described here. +beginning with `__` unless it is one of the special methods described here. Note that while syntax definitions below use the [non-abstract syntax](#methods) in the method definition, the special methods, like any methods, can be declared `abstract`. In this case the definition does not actually define a special method but defines that an overriding concrete class must declare one. Nevertheless, the constraints on special methods must still be followed in such definitions. -###Method `__call` +### Method `__call` **Syntax**
-  method-modifiers function  __call  (  $name  ,  $arguments  )  compound-statement
+  method-modifiers function  __call  (  $name  ,  $arguments  )  return-typeopt  compound-statement
 
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The method can not be static and must have public visibility. @@ -759,8 +832,9 @@ designated by `$name` using the arguments specified by the elements of the array designated by `$arguments`. It can return any value deemed appropriate. -Typically, `__call` is called implicitly, when the [`->` operator](10-expressions.md#member-selection-operator) -is used to call an instance method that is not visible. +Typically, `__call` is called implicitly, when the +[`->` operator](10-expressions.md#member-call-operator) +is used to call an instance method that is not visible. While `__call` can be called explicitly, the two scenarios do not necessarily produce the same result. Consider the expression `p->m(...)`, @@ -772,7 +846,7 @@ method, ignoring the fact that a visible method having the same name might exist. If `m` is not the name of a visible method, the two expressions are equivalent; that is; when handling `p->m(...)`, if no visible method by that name is found, a dynamic method is assumed, and -`__call` is called. +`__call` is called. While the [*name*](09-lexical-structure.md#names) source token has a prescribed syntax, there are no restrictions on the content of the dynamic method name designated by @@ -794,19 +868,14 @@ $obj = new Widget; $obj->iMethod(10, TRUE, "abc"); // $obj->__call('iMethod', array(...)) ``` -###Method `__callStatic` +### Method `__callStatic` **Syntax**
-  method-modifiers  function  __callStatic  (  $name  ,  $arguments  )   compound-statement
+  method-modifiers  function  __callStatic  (  $name  ,  $arguments  )  return-typeopt  compound-statement
 
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must contain `static` and must define public visibility. @@ -821,7 +890,7 @@ the array designated by `$arguments`. It can return any value deemed appropriate. Typically, `__callStatic` is called implicitly, when the [`::` operator](10-expressions.md#scope-resolution-operator) -is used to call a static method that is not visible. +is used to call a static method that is not visible. While `__callStatic` can be called explicitly, the two scenarios do not necessarily produce the same result. Consider the expression `C::m(...)`, @@ -833,7 +902,7 @@ dynamic method, ignoring the fact that a static visible method having the same name might exist. If m is not the name of a visible method, the two expressions are equivalent; that is; when handling `C::m(...)`, if no visible method by that name is found, a dynamic method is assumed, and -`__callStatic` is called. +`__callStatic` is called. While the [*name*](09-lexical-structure.md#names) source token has a prescribed syntax, there are no restrictions on the spelling of the dynamic method name designated by @@ -855,7 +924,7 @@ class Widget Widget::sMethod(NULL, 1.234); // Widget::__callStatic('sMethod', array(...)) ``` -###Method `__clone` +### Method `__clone` **Syntax** @@ -863,11 +932,6 @@ Widget::sMethod(NULL, 1.234); // Widget::__callStatic('sMethod', array(...)) method-modifiers function __clone ( ) compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -910,7 +974,7 @@ instance having [dynamic properties](#dynamic-members). class Employee { ... - public function __clone() + public function __clone() { // do what it takes here to make a copy of Employee object properties } @@ -918,7 +982,7 @@ class Employee class Manager extends Employee { ... - public function __clone() + public function __clone() { parent::__clone(); // request cloning of the Employee properties @@ -927,15 +991,15 @@ class Manager extends Employee ... } // ----------------------------------------- -class Point +class Point { private static $pointCount = 0; - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { ... ++self::$pointCount; } - public function __clone() + public function __clone() { ++self::$pointCount; // emulate the constructor } @@ -945,7 +1009,7 @@ $p1 = new Point; // created using the constructor $p2 = clone $p1; // created by cloning ``` -###Method `__debugInfo` +### Method `__debugInfo` **Syntax** @@ -953,11 +1017,6 @@ $p2 = clone $p1; // created by cloning method-modifiers function __debugInfo ( ) compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -982,7 +1041,7 @@ class File { public function open($filename, $mode = 'r'){ $this->fp = fopen($filename, $mode); - } + } } $f = new File; @@ -999,19 +1058,14 @@ object(File)#1 { */ ``` -###Method `__get` +### Method `__get` **Syntax**
-  method-modifiers function  &opt  __get  (  $name  )   compound-statement
+  method-modifiers function  &opt  __get  (  $name  )  return-typeopt  compound-statement
 
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1021,7 +1075,8 @@ The *method-modifiers* must not contain `static` and must define public visibili This instance method gets the value of the [dynamic property](#dynamic-members) designated by `$name`. It is up to the implementor to define the return value. -Typically, `__get` is called implicitly, when the [`->` operator](10-expressions.md#member-selection-operator) +Typically, `__get` is called implicitly, when the +[`->` operator](10-expressions.md#member-access-operator) is used in a non-lvalue context and the named property is not visible. While `__get` can be called explicitly, the two scenarios do not @@ -1048,7 +1103,7 @@ and the modifications are reflected in the dynamic property), `__get` should ret **Examples** ```PHP -class Point +class Point { private $dynamicProperties = array(); private $x; @@ -1095,20 +1150,14 @@ While the [*name*](09-lexical-structure.md#names) source token has a prescribed restrictions on the spelling of the dynamic property name designated by `$name`. Any source character is allowed here. -###Method `__invoke` +### Method `__invoke` **Syntax**
-  method-modifiers  function  __invoke  ( parameter-declaration-listopt  )  compound-statement
+  method-modifiers  function  __invoke  ( parameter-declaration-listopt  )  return-typeopt  compound-statement
 
-**Defined elsewhere** - -* [*parameter-declaration-list*](13-functions.md#function-definitions) -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1140,19 +1189,14 @@ is_callable($c) // returns TRUE $r = $c(123); // becomes $r = $c->__invoke(123); ``` -###Method `__isset` +### Method `__isset` **Syntax**
-  method-modifiers  function  __isset  (  $name  )  compound-statement
+  method-modifiers  function  __isset  (  $name  )  return-typeopt  compound-statement
 
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1161,11 +1205,11 @@ The *method-modifiers* must not contain `static` and must define public visibili If the [dynamic property](#dynamic-members) designated by `$name` exists, this instance method returns `TRUE`; otherwise, `FALSE` is returned. The speficis of -how existance of the dynamic property is determined is left to the implementor of the method. +how existence of the dynamic property is determined is left to the implementor of the method. Typically, `__isset` is called implicitly, when the intrinsic [`isset`](10-expressions.md#isset) or intrinsic [`empty`](10-expressions.md#empty) is called with an argument that designates -a property that is not visible. +a property that is not visible. While `__isset` can be called explicitly, the two scenarios do not necessarily produce the same result. Consider the @@ -1185,7 +1229,7 @@ restrictions on the spelling of the dynamic property name designated by **Examples** ```PHP -class Point +class Point { private $dynamicProperties = array(); private $x; @@ -1202,19 +1246,14 @@ class Point See the Implementation Notes for [`__get`](#method-__get). -###Method `__set` +### Method `__set` **Syntax**
-  method-modifiers  function  __set  (  $name  ,  $value  )  compound-statement
+  method-modifiers  function  __set  (  $name  ,  $value  )  return-typeopt  compound-statement
 
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1224,9 +1263,10 @@ The *method-modifiers* must not contain `static` and must define public visibili This instance method sets the value of the [dynamic property](#dynamic-members) designated by `$name` to `$value`. No value is expected to be returned. -Typically, `__set` is called implicitly, when the [`->` operator](10-expressions.md#member-selection-operator) +Typically, `__set` is called implicitly, when the +[`->` operator](10-expressions.md#member-access-operator) is used in a modifiable lvalue context and the named property is not -visible. +visible. While `__set` can be called explicitly, the two scenarios do not necessarily produce the same result. Consider the expression @@ -1238,7 +1278,7 @@ property, ignoring the fact that a visible property having the same name might exist. If `m` is not the name of a visible property, the two expressions are equivalent; that is; when handling `p->m`, if no visible property by that name is found, a dynamic property is assumed, and -`__set` is called. +`__set` is called. While the [*name*](09-lexical-structure.md#names) source token has a prescribed syntax, there are no restrictions on the spelling of the dynamic property name designated by @@ -1247,7 +1287,7 @@ restrictions on the spelling of the dynamic property name designated by **Examples** ```PHP -class Point +class Point { private $dynamicProperties = array(); private $x; @@ -1273,19 +1313,14 @@ $p->thing = new X; // set dynamic property "thing" to instance with destructor See the Implementation Notes for [`__get`](#method-__get). -###Method `__set_state` +### Method `__set_state` **Syntax**
-  method-modifiers  function  __set_state  ( array  $properties  )  compound-statement
+  method-modifiers  function  __set_state  ( array  $properties  )  return-typeopt  compound-statement
 
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must contain `static` and must define public visibility. @@ -1312,8 +1347,8 @@ will produce a fatal error. To allow the string to be used with `eval`, the meth class type, initialize its instance properties using the key/value pairs in `$properties`, and it must return that new object. -When extending the class with `__set_state` method, one should override -the method, otherwise a call to it will look for such a method in the base class hierarchy, +When extending the class with `__set_state` method, one should override +the method, otherwise a call to it will look for such a method in the base class hierarchy, and that method will return an instance of the associated base class, not of the class on which it was invoked. Usage of `static` allows [late static binding](10-expressions.md#scope-resolution-operator) to produce the instance of an appropriate class. @@ -1327,7 +1362,7 @@ below. **Examples** ```PHP -class Point +class Point { private $x; private $y; @@ -1349,7 +1384,7 @@ The string produced looks something like the following: "Point::__set_state(array( 'x' => 3, 'y' => 5, -))" +))" eval('$z = ' . $v . ";"); // execute the string putting the result in $z echo "Point \$z is $z\n"; // Point $z is (3,5) // ----------------------------------------- @@ -1394,19 +1429,14 @@ eval('$z = ' . $v . ";"); var_dump($z); ``` -###Method `__sleep` +### Method `__sleep` **Syntax**
-  method-modifiers  function  __sleep  ( ) compound-statement
+  method-modifiers  function  __sleep  ( )  return-typeopt  compound-statement
 
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1416,7 +1446,7 @@ The *method-modifiers* must not contain `static` and must define public visibili The instance methods `__sleep` and [`__wakeup`](#method-__wakeup) support [serialization](#serialization). -If a class has a `__sleep` method, the library function [`serialize`](http://www.php.net/serialize) +If a class has a `__sleep` method, the library function [`serialize`](http://www.php.net/serialize) calls that method to find out which visible instance properties it should serialize. (In the absence of a `__sleep` or `serialize` method, all instance properties are serialized, including ones defined in runtime). @@ -1433,7 +1463,7 @@ else might be needed before serialization occurs. The alternative to using `__sleep` and `__wakeup` is implementing the [Serializable interface](15-interfaces.md#interface--serializable). -Note that if a class defining `__sleep` and `__wakeup` is extended, and the +Note that if a class defining `__sleep` and `__wakeup` is extended, and the derived class does not override the methods, the serialization and unserialization will be performed as if those were instances of the base class, e.g. additional properties may not be serialized or restored. @@ -1450,23 +1480,23 @@ other transient properties, such as those that contain temporary results or run-time caches). ```PHP -class Point +class Point { private static $nextId = 1; private $x; private $y; private $id; - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; $this->id = self::$nextId++; // assign the next available id } - public function __sleep() + public function __sleep() { return array('y', 'x'); // serialize only $y and $x, in that order } - public function __wakeup() + public function __wakeup() { $this->id = self::$nextId++; // assign a new id } @@ -1477,19 +1507,14 @@ $s = serialize($p); // serialize Point(-1,0) $v = unserialize($s); // unserialize Point(-1,0) ``` -###Method `__toString` +### Method `__toString` **Syntax**
-  method-modifiers  function  __toString  ( )  compound-statement
+  method-modifiers  function  __toString  ( )  return-typeopt  compound-statement
 
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1501,7 +1526,7 @@ This function must not throw any exceptions. **Semantics** This instance method is intended to create a string representation of -the instance on which it is called. +the instance on which it is called. `__toString` is called by a number of language and library facilities, including `echo`, when an object-to-string conversion is needed. @@ -1513,16 +1538,16 @@ instance having [dynamic properties](#dynamic-members). **Examples** ```PHP -class Point +class Point { private $x; private $y; - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; } - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; } @@ -1531,9 +1556,9 @@ class Point $p1 = new Point(20, 30); echo $p1 . "\n"; // implicit call to __toString() returns "(20,30)" // ----------------------------------------- -class MyRangeException extends Exception +class MyRangeException extends Exception { - public function __toString() + public function __toString() { return parent::__toString() . string-representation-of-MyRangeException @@ -1542,19 +1567,14 @@ class MyRangeException extends Exception } ``` -###Method `__unset` +### Method `__unset` **Syntax**
-  method-modifiers  function  __unset  (  $name  )  compound-statement
+  method-modifiers  function  __unset  (  $name  )  return-typeopt  compound-statement
 
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1565,9 +1585,9 @@ If the [dynamic property](#dynamic-members) designated by `$name` exists, it is removed by this instance method; otherwise, the call has no effect. No value is expected to be returned. -Typically, `__unset` is called implicitly, when the intrinsic [`unset`](10-expressions.md#unset) +Typically, `__unset` is called implicitly, when the [`unset` statement](11-statements.md#the-unset-statement) is called with an argument that designates a property that -is not visible. +is not visible. While `__unset` can be called explicitly, the two scenarios do not necessarily produce the same result. Consider the @@ -1587,7 +1607,7 @@ restrictions on the spelling of the dynamic property name designated by **Examples** ```PHP -class Point +class Point { private $dynamicProperties = array(); private $x; @@ -1604,19 +1624,14 @@ class Point See the Implementation Notes for [`__get`](#method-__get). -###Method `__wakeup` +### Method `__wakeup` **Syntax**
-  method-modifiers  function  __wakeup  ( )  compound-statement
+  method-modifiers  function  __wakeup  ( )  return-typeopt  compound-statement
 
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1647,19 +1662,19 @@ by `__wakeup` when that `Point` is unserialized. This means that See [`__sleep`](#method-__sleep). -##Serialization +## Serialization In PHP, variables can be converted into some external form suitable for use in file storage or inter-program communication. The process of converting to this form is known as *serialization* while that of converting back again is known as *unserialization*. These facilities are provided by the library functions [`serialize`](http://www.php.net/serialize) -and [`serialize`](http://www.php.net/serialize), respectively. +and [`unserialize`](http://www.php.net/unserialize), respectively. In the case of variables that are objects, on their own, these two functions serialize and unserialize all the instance properties, which may be sufficient for some applications. However, if the programmer -wants to customize these processes, they can do so in one of two mutually exclusive ways. +wants to customize these processes, they can do so in one of two mutually exclusive ways. The first approach is to define methods called `__sleep` and `__wakeup`, and have them get control before serialization and after serialization, respectively. For information on this approach, @@ -1686,17 +1701,17 @@ class Point implements Serializable // note the interface private $x; private $y; private $id; // transient property; not serialized - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; $this->id = self::$nextId++; } - public function __toString() + public function __toString() { return 'ID:' . $this->id . '(' . $this->x . ',' . $this->y . ')'; } - public function serialize() + public function serialize() { return serialize(array('y' => $this->y, 'x' => $this->x)); } @@ -1754,18 +1769,18 @@ class ColoredPoint extends Point implements Serializable private $color; // an instance property - public function __construct($x = 0, $y = 0, $color = RED) + public function __construct($x = 0, $y = 0, $color = RED) { parent::__construct($x, $y); $this->color = $color; } - public function __toString() + public function __toString() { return parent::__toString() . $this->color; } - public function serialize() + public function serialize() { return serialize(array( 'color' => $this->color, @@ -1801,16 +1816,20 @@ $s = serialize($cp); $v = unserialize($s); ``` -##Predefined Classes +Function `unserialize` takes an optional second argument, which specifies an array of trusted class names as strings. Objects found in the data stream whose type name is not in this trusted name list are converted to objects of type [`__PHP_Incomplete_Class`](#class-__php_incomplete_class). + +Any attempt to serialize an object having an anonymous class type results in an instance of type `Exception` being thrown. + +## Predefined Classes ### Class `Closure` The predefined class [`Closure`](http://php.net/manual/class.closure.php) is used for representing an [anonymous function](13-functions.md#anonymous-functions). It -cannot be instantiated except by the Engine, as described below. +cannot be instantiated except by the Engine, as described below. Closure objects are immutable and must not permit the creation or modification of properties. -Closures can be *bound*, *unbound* or *static*. If a closure is said to be +Closures can be *bound*, *unbound* or *static*. If a closure is said to be bound, then it has an object that `$this` will be bound to when called. If a closure is unbound, then it has no object `$this` will be bound to. If a closure is static, then it cannot be bound. @@ -1828,6 +1847,7 @@ class Closure { public static bind(Closure $closure, $newthis [, $newscope = "static" ]); public bindTo($newthis [, $newscope = "static" ]); + public call($newthis [, ...$parameters ]); } ``` @@ -1837,7 +1857,8 @@ The class members are defined below: Name | Purpose -----|-------- `bind` | Duplicates closure `$closure` with a specific bound object `$newthis` and class scope `$newscope`. If `$newthis` is `NULL` then the closure is to be unbound if no scope is specified, or static if a scope is specified. `$newscope` is the scope the closure is to be given (either a string containing the name of a class, or an object whose class will be used), or `"static"` to keep the current one. Returns a new `Closure` object or `FALSE` on failure. This function must not violate the invariant that closures must either be both scoped and bound or static, or otherwise both unscoped and unbound. This function must prevent binding an object to the new closure if the `$closure` is static, however the new closure may have a different scope. -`bindTo` | Duplicates the closure designated by the current instance with a new-bound object and class scope. This method is an instance version of bind. +`bindTo` | Duplicates the closure designated by the current instance with a new-bound object and class scope. This method is an instance version of bind. +`call` | Calls the closure (the current instance) with `$this` bound to `$newthis`, the class scope of the class of `$newthis`, and the parameters specified by `$parameters`. This function must fail if `$newthis` is NULL, or if the closure is static. When the [anonymous function creation operator](10-expressions.md#anonymous-function-creation) is evaluated, the result is an object of type `Closure` (or some unspecified class @@ -1911,7 +1932,7 @@ case, the `Closure` object is empty. Closure objects can not be serialized or unserialized. -###Class `Generator` +### Class `Generator` This class supports the [`yield` operator](10-expressions.md#yield-operator). This class cannot be instantiated directly. It is defined, as follows: @@ -1920,6 +1941,7 @@ instantiated directly. It is defined, as follows: class Generator implements Iterator { public function current(); + public function getReturn(); public function key(); public function next(); public function rewind(); @@ -1934,6 +1956,7 @@ The class members are defined below: Name | Purpose ---- | ------- `current` | An implementation of the instance method [`Iterator::current`](15-interfaces.md#interface-iterator). +`getReturn` | Returns the final expression from a generator, which was produced by a `return` statement rather than a `yield`. This function can only be called meaningfully once the generator has finishing yielding values; otherwise, an instance of `Exception` is thrown. `key` | An implementation of the instance method [`Iterator::key`](15-interfaces.md#interface-iterator). `next` | An implementation of the instance method [`Iterator::next`](15-interfaces.md#interface-iterator). `rewind` | An implementation of the instance method [`Iterator::rewind`](15-interfaces.md#interface-iterator). @@ -1943,16 +1966,18 @@ Name | Purpose Generator objects can not be serialized or unserialized. -###Class `__PHP_Incomplete_Class` +### Class `__PHP_Incomplete_Class` There are certain circumstances in which a program can generate an instance of this class, which on its own contains no members. One involves an attempt to [unserialize](#serialization) a string that -encodes an instance of a class for which there is no definition. +encodes an instance of a class for which there is no definition or +if an object’s type is declared untrusted by `unserialize`’s filter argument. + Consider the following code: ```PHP -class Point +class Point { private $x; private $y; @@ -1982,14 +2007,100 @@ __PHP_Incomplete_Class } ``` -Object of this class can be serialized, however, any attemt to call its method or access its property +Object of this class can be serialized, however, any attempt to call its method or access its property for any other operation except serialization will result in a fatal error. -###Class `stdClass` +### Class `stdClass` This class contains no members. It can be instantiated and used as a base class. An instance of this type is automatically created when a -non-object is [converted to an object](08-conversions.md#converting-to-object-type), or the [member selection -operator](10-expressions.md#member-selection-operator) is applied to `NULL`, `FALSE`, or an empty string. +non-object is [converted to an object](08-conversions.md#converting-to-object-type), +or the [member selection operator](10-expressions.md#member-access-operator) +is applied to `NULL`, `FALSE`, or an empty string. +### Predefined Error Classes + +PHP has a number of predefined classes that are used for error reporting. All these classes extend the base Error class. + +#### Class `Error` + +This class is the base class for all internal PHP error exceptions. It is defined, as follows: + +```PHP +class Error implements Throwable +{ + protected $message = ''; + protected $code = 0; + protected $file; + protected $line; + + public function __construct($message = "", $code = 0, + Throwable $previous = NULL); + + final private function __clone(); +} +``` + +For information about the base interface, see [Throwable](15-interfaces.md#interface-throwable). +Note that the methods from Throwable are implemented as `final` in the Error class, which means +the extending class can not override them. + +#### Class `ArithmeticError` + +An instance of this class is thrown when an error occurs during certain mathematical operations. It is defined, as follows: + +```PHP +class ArithmeticError extends Error +{ +} +``` + +#### Class `AssertionError` + +An instance of this class is thrown when an assertion made via the intrinsic `assert` fails. The class type is defined, as follows: + +```PHP +class AssertionError extends Error +{ +} +``` + +#### Class `DivisionByZeroError` + +An instance of this class is thrown when an attempt is made to divide a number by zero, e.g. when using the remainder operators ([`%`](10-expressions.md#multiplicative-operators) and [`%=`](10-expressions.md#compound-assignment)). +Note that this happens only for integer operations, regular float division (`/`) produces a non-fatal error instead. +The class type is defined, as follows: + +```PHP +class DivisionByZeroError extends Error +{ +} +``` + +#### Class `ParseError` + +An instance of this class is thrown when an error occurs while parsing PHP code (such as when calling the intrinsic [`eval`](10-expressions.md#eval)). It is defined, as follows: + +```PHP +class ParseError extends Error +{ +} +``` + +#### Class `TypeError` + +An instance of this class is thrown when any of the following occurs: + + * The type of an argument being passed to a function does not match its corresponding parameter’s declared type. + * The type of the value being returned from a function does not match the function’s declared return type. + * In [strict mode](13-functions.md#type-check-modes), an invalid number of arguments are passed to a library function. + +The class is defined, as follows: + +```PHP +class TypeError extends Error +{ +} +``` +See also class [`Exception`](17-exception-handling.md#class-exception). diff --git a/spec/15-interfaces.md b/spec/15-interfaces.md index 16888734..9e0775a9 100644 --- a/spec/15-interfaces.md +++ b/spec/15-interfaces.md @@ -1,6 +1,6 @@ -#Interfaces +# Interfaces -##General +## General A class can implement a set of capabilities β€” herein called a *contract* β€” through what is called an interface. An *interface* is a set @@ -14,23 +14,27 @@ requiring those classes to share a common base class. An interface can extend one or more other interfaces, in which case, it inherits all members from its *base interface(s)*. -##Interface Declarations +## Interface Declarations **Syntax** -
-  interface-declaration:
-    interface   name   interface-base-clauseopt {  interface-member-declarationsopt  }
+
 
-**Defined elsewhere**
+
+interface-declaration:
+   interface   name   interface-base-clauseopt   {   interface-member-declarationsopt   }
 
-* [*name*](09-lexical-structure.md#names)
-* [*interface-member-declarations*](#interface-members)
+interface-base-clause:
+   extends   qualified-name
+   interface-base-clause   ,   qualified-name
+
**Constraints** @@ -52,19 +56,19 @@ derived interface inherits all the members from the base interfaces. **Examples** ```PHP -interface MyCollection +interface MyCollection { const MAX_NUMBER_ITEMS = 1000; function put($item); function get(); } -class MyList implements MyCollection +class MyList implements MyCollection { public function put($item) { /* implement method */ } public function get() { /* implement method */ } ... } -class MyQueue implements MyCollection +class MyQueue implements MyCollection { public function put($item) { /* implement method */ } public function get() { /* implement method */ } @@ -78,18 +82,28 @@ processCollection(new MyList(...)); processCollection(new MyQueue(...)); ``` -##Interface Members +## Interface Members **Syntax** + +
-  interface-member-declarations:
-    interface-member-declaration
-    interface-member-declarations   interface-member-declaration
+interface-member-declarations:
+   interface-member-declaration
+   interface-member-declarations   interface-member-declaration
 
-  interface-member-declaration:
-    const-declaration
-    method-declaration
+interface-member-declaration:
+   class-const-declaration
+   method-declaration
 
* [*const-declaration*](14-classes.md#constants) @@ -107,7 +121,11 @@ An interface may contain the following members: - [Methods](#methods) – placeholders for the computations and actions that can be performed by implementers of the interface. -##Constants +## Constants + +**Constraints** + +All constants declared in an interface must be implicitly or explicitly public. **Semantics** @@ -118,7 +136,7 @@ nor by an interface that extends it. **Examples** ```PHP -interface MyCollection +interface MyCollection { const MAX_NUMBER_ITEMS = 1000; function put($item); @@ -126,7 +144,7 @@ interface MyCollection } ``` -##Methods +## Methods **Constraints** @@ -140,7 +158,7 @@ An interface method is just like an [abstract method](14-classes.md#methods). **Examples** ```PHP -interface MyCollection +interface MyCollection { const MAX_NUMBER_ITEMS = 1000; function put($item); @@ -148,9 +166,9 @@ interface MyCollection } ``` -##Predefined Interfaces +## Predefined Interfaces -###Interface `ArrayAccess` +### Interface `ArrayAccess` This interface allows an instance of an implementing class to be accessed using array-like notation. This interface is defined, as @@ -175,7 +193,7 @@ Name | Purpose `offsetSet` | This instance method sets the value having key `$offset` to $value. It returns no value. This method is called when an instance of a class that implements this interface is [subscripted](10-expressions.md#subscript-operator) in a modifiable-lvalue context. `offsetUnset` | This instance method unsets the value having key `$offset`. It returns no value. -###Interface `Iterator` +### Interface `Iterator` This interface allows instances of an implementing class to be treated as a collection. This interface is defined, as follows: @@ -202,13 +220,13 @@ Name | Purpose `rewind` | This instance method resets the current position to the first element. It returns no value. From within a `foreach` statement, this method is called once, at the beginning. `valid` | This instance method checks if the current position is valid. It takes no arguments. It returns a bool value of `TRUE` to indicate the current position is valid; `FALSE`, otherwise. This method is called after each call to [`Iterator::rewind()`](http://php.net/manual/iterator.rewind.php) and [`Iterator::next()`](http://php.net/manual/iterator.next.php). -###Interface `IteratorAggregate` +### Interface `IteratorAggregate` This interface allows the creation of an external iterator. This interface is defined, as follows: ```PHP -Interface IteratorAggregate extends Traversable +interface IteratorAggregate extends Traversable { function getIterator(); } @@ -220,20 +238,54 @@ Name | Purpose ---- | ------- `getIterator` | This instance method retrieves an iterator, which implements `Iterator` or `Traversable`. It throws an `Exception` on failure. -###Interface `Traversable` +### Interface `Throwable` + +This type is the base interface for the type of any object that can be thrown via a +[throw statement](11-statements.md#the-throw-statement). A user-written class cannot +implement `Throwable` directly. Instead, it must extend `Error` or `Exception`. + +This type is defined, as follows: + +```PHP +interface Throwable { + function __toString(): string; + function getCode(): int; + function getFile(): string; + function getLine(): int; + function getMessage(): string; + function getPrevious(): Throwable; + function getTrace(): array; + function getTraceAsString(): string; +} +``` +The interface members are defined below: + + +Name | Purpose +---- | ------- +`__toString` | `string`; retrieves a string representation of the exception in some unspecified format +`getCode` | `int`; retrieves the exception code +`getFile` | `string`; retrieves the name of the script where the exception was generated +`getLine` | `int`; retrieves the source line number in the script where the exception was generated +`getMessage` | `string`; retrieves the exception message +`getPrevious` | `Throwable`; retrieves the previous exception, if one exists; otherwise returns `NULL` +`getTrace` | `array`; retrieves the function stack [trace information](17-exception-handling.md#tracing-exceptions) as an array +`getTraceAsString` | `string`; retrieves the function stack trace information formatted as a single string in some unspecified format + +### Interface `Traversable` This interface is intended as the base interface for all traversable classes. This interface is defined, as follows: ```PHP interface Traversable -{ +{ } ``` This interface has no members. -###Interface `Serializable` +### Interface `Serializable` This interface provides support for custom serialization. It is defined, as follows: diff --git a/spec/16-traits.md b/spec/16-traits.md index 90061b7f..511c350d 100644 --- a/spec/16-traits.md +++ b/spec/16-traits.md @@ -1,6 +1,6 @@ -#Traits +# Traits -##General +## General PHP's class model allows [single inheritance](14-classes.md#general) only with contracts being enforced separately via [interfaces](15-interfaces.md#general). A *trait* can provide @@ -38,50 +38,145 @@ each class using that trait has its own instance of that property. Methods in a trait have full access to all members of any class in which that trait is used. -##Trait Declarations +## Trait Declarations **Syntax** + +
-  trait-declaration:
-    trait   name   {   trait-use-clausesopt   trait-member-declarationsopt   }
+trait-declaration:
+   trait   name   {   trait-member-declarationsopt   }
+
+trait-member-declarations:
+   trait-member-declaration
+   trait-member-declarations   trait-member-declaration
+
+trait-member-declaration:
+   property-declaration
+   method-declaration
+   constructor-declaration
+   destructor-declaration
+   trait-use-clauses
+
+ +**Semantics** - trait-use-clauses: - trait-use-clause - trait-use-clauses trait-use-clause +A *trait-declaration* defines a named set of members, which are made +available to any class that uses that trait. - trait-use-clause: - use trait-name-list trait-use-specification +Trait names are case-insensitive. - trait-name-list: - qualified-name - trait-name-list , qualified-name +The members of a trait are those specified by its *trait-member-declaration* +clauses, and members imported from any other traits using *trait-use-clauses*. - trait-use-specification: - ; - { trait-select-and-alias-clausesopt } +A trait may contain the following members: - trait-select-and-alias-clauses: - trait-select-and-alias-clause - trait-select-and-alias-clauses trait-select-and-alias-clause +- [Properties](14-classes.md#properties) – the variables made available to the class in which the + trait is used. +- [Methods](14-classes.md#methods) – the computations and actions that can be performed by the + class in which the trait is used. +- [Constructor](14-classes.md#constructors) – the actions required to initialize an instance of the + class in which the trait is used. +- [Destructor](14-classes.md#destructors) – the actions to be performed when an instance of the + class in which the trait is used is no longer needed. - trait-select-and-alias-clause: - trait-select-insteadof-clause ; - trait-alias-as-clause ; +If a member has no explicit visibility, `public` is assumed. - trait-select-insteadof-clause: - name insteadof name +**Examples** - trait-alias-as-clause: - name as visibility-modifieropt name - name as visibility-modifier nameopt -
+```PHP +trait T +{ + private $prop1 = 1000; + protected static $prop2; + var $prop3; + public function compute( ... ) { ... } + public static function getData( ... ) { ... } +} +``` + +## Trait Uses + +**Syntax** + + + +
+trait-use-clauses:
+   trait-use-clause
+   trait-use-clauses   trait-use-clause
+
+trait-use-clause:
+   use   trait-name-list   trait-use-specification
+
+trait-name-list:
+   qualified-name
+   trait-name-list   ,   qualified-name
+
+trait-use-specification:
+   ;
+   {   trait-select-and-alias-clausesopt   }
 
-**Defined elsewhere**
+trait-select-and-alias-clauses:
+   trait-select-and-alias-clause
+   trait-select-and-alias-clauses   trait-select-and-alias-clause
 
-* [*name*](09-lexical-structure.md#names)
-* [*visibility-modifier*](14-classes.md#properties)
-* [*trait-member-declarations*](#trait-members)
+trait-select-and-alias-clause:
+   trait-select-insteadof-clause   ;
+   trait-alias-as-clause   ;
+
+trait-select-insteadof-clause:
+   qualified-name   ::   name   insteadof   trait-name-list
+
+trait-alias-as-clause:
+   name   as   visibility-modifieropt   name
+   name   as   visibility-modifier   nameopt
+
**Constraints** @@ -101,16 +196,12 @@ unqualified name. **Semantics** -A *trait-declaration* defines a named set of members, which are made -available to any class that uses that trait. - -Trait names are case-insensitive. - -A *trait-declaration* may also use other traits. This is done via one or -more *trait-use-clause* items, each of which contains a comma-separated list -of trait names. A *trait-use-clause* list ends in a semicolon or a -brace-delimited set of *trait-select-insteadof-clause* and -*trait-alias-as-clause* statements. +*trait-use-clauses* can be used as part of *trait-member-declarations* +or *class-member-declarations* to import members of a trait into a +different trait or a class. This is done via one or more *trait-use-clause* +items, each of which contains a comma-separated list of trait names. +A *trait-use-clause* list ends in a semicolon or a brace-delimited set of +*trait-select-insteadof-clause* and *trait-alias-as-clause* statements. A *trait-select-insteadof-clause* allows to avoid name clashes. Specifically, the left-hand *name* designates which name to be used from @@ -124,7 +215,7 @@ assigned a simple alias name. Specifically, the left-hand *name* in *trait-use-clauses* - that is to be aliased, and the right-hand *name* is the alias. -If *trait-alias-as-clause* contains a visibility-modifier, +If *trait-alias-as-clause* contains a visibility-modifier, if a right-hand name is provided, the modifier controls the visibility of the alias, otherwise, it controls the visibility of the left-hand name. @@ -144,60 +235,3 @@ trait T4 } } ``` - -##Trait Members - -**Syntax** - -
-  trait-member-declarations:
-    trait-member-declaration
-    trait-member-declarations   trait-member-declaration
-
-  trait-member-declaration:
-    property-declaration
-    method-declaration
-    constructor-declaration
-    destructor-declaration
-
- -**Defined elsewhere** - -* [*property-declaration*](14-classes.md#properties) -* [*method-declaration*](14-classes.md#methods) -* [*constructor-declaration*](14-classes.md#constructors) -* [*destructor-declaration*](14-classes.md#destructors) - -**Semantics** - -The members of a trait are those specified by its -*trait-member-declaration* clauses, and the members from any other traits it -uses. - -A trait may contain the following members: - -- [Properties](14-classes.md#properties) – the variables made available to the class in which the - trait is used. -- [Methods](14-classes.md#methods) – the computations and actions that can be performed by the - class in which the trait is used. -- [Constructor](14-classes.md#constructors) – the actions required to initialize an instance of the - class in which the trait is used. -- [Destructor](14-classes.md#destructors) – the actions to be performed when an instance of the - class in which the trait is used is no longer needed. - -If a member has no explicit visibility, `public` is assumed. - -**Examples** - -```PHP -trait T -{ - private $prop1 = 1000; - protected static $prop2; - var $prop3; - public function compute( ... ) { ... } - public static function getData( ... ) { ... } -} -``` - - diff --git a/spec/17-exception-handling.md b/spec/17-exception-handling.md index 68be578e..813a582d 100644 --- a/spec/17-exception-handling.md +++ b/spec/17-exception-handling.md @@ -1,6 +1,6 @@ -#Exception Handling +# Exception Handling -##General +## General An *exception* is some unusual condition in that it is outside the ordinary expected behavior. Examples include dealing with situations in @@ -42,41 +42,32 @@ PHP errors also can be translated to exceptions via the class [`ErrorException`](http://php.net/manual/class.errorexception.php) (which is not part of this specification). -##Class `Exception` +## Class `Exception` Class `Exception` is the base class of all exception types. This class is defined, as follows: ```PHP -Class Exception +class Exception implements Throwable { - private $string; - private $trace; - private $previous; - protected $message = 'Unknown exception'; protected $code = 0; protected $file; protected $line; public function __construct($message = "", $code = 0, - Exception $previous = NULL); + Throwable $previous = NULL); final private function __clone(); - - final public function getMessage(); - final public function getCode(); - final public function getFile(); - final public function getLine(); - final public function getTrace(); - final public function getPrevious(); - final public function getTraceAsString(); - public function __toString(); } ``` For information about exception trace-back and nested exceptions, see [tracing exceptions](#tracing-exceptions). +For information about the base interface, see [Throwable](15-interfaces.md#interface-throwable). +Note that the methods from Throwable are implemented as `final` in the Exception class, which means +the extending class can not override them. + The class members are defined below: Name | Purpose @@ -85,21 +76,10 @@ Name | Purpose `$file` | `string`; the name of the script where the exception was generated `$line` | `int`; the source line number in the script where the exception was generated `$message` | `string`; the exception message (as provided by the constructor) -`$previous` | The previous exception in the chain, if this is a nested exception; otherwise, `NULL` -`$string` | Work area for `__toString` -`$trace` | Work area for function-call tracing `__construct` | Takes three (optional) arguments – `string`: the exception message (defaults to ""), `int`: the exception code (defaults to 0), and `Exception`: the previous exception in the chain (defaults to `NULL`) `__clone` | Present to inhibit the cloning of exception objects -`__toString` | `string`; retrieves a string representation of the exception in some unspecified format -`getCode` | `mixed`; retrieves the exception code (as set by the constructor). For an exception of type Exception, the returned value has type int; for subclasses of `Exception`, it may have some other type. -`getFile` | `string`; retrieves the name of the script where the exception was generated -`getLine` | `int`; retrieves the source line number in the script where the exception was generated -`getMessage` | `string`; retrieves the exception message -`getPrevious` | `Exception`; retrieves the previous exception (as set by the constructor), if one exists; otherwise, `NULL` -`getTrace` | `array`; retrieves the function [stack trace information](#tracing-exceptions) as an array -`getTraceAsString` | `string`; retrieves the function stack trace information formatted as a single string in some unspecified format -##Tracing Exceptions +## Tracing Exceptions When an exception is caught, the `get*` functions in class `Exception` provide useful information. If one or more nested function calls were @@ -157,7 +137,7 @@ site have their values recorded in array-argument. See also, library functions [`debug_backtrace`](http://www.php.net/debug_backtrace) and [`debug_print_backtrace`](http://www.php.net/debug_print_backtrace). -##User-Defined Exception Classes +## User-Defined Exception Classes An exception class is defined simply by having it extend class [`Exception`](#class-exception). However, as that class's `__clone` method is declared [`final`](14-classes.md#methods), @@ -168,5 +148,3 @@ parent class' constructor as their first operation to ensure the base-class part of the new object is initialized appropriately. They often also provide an augmented implementation of [`__toString()`](14-classes.md#method-__tostring). - - diff --git a/spec/18-namespaces.md b/spec/18-namespaces.md index b910bc9d..715dff62 100644 --- a/spec/18-namespaces.md +++ b/spec/18-namespaces.md @@ -1,6 +1,6 @@ -#Namespaces +# Namespaces -##General +## General A problem encountered when managing large projects is that of avoiding the use of the same name in the same scope for different purposes. This @@ -32,21 +32,22 @@ The namespaces `PHP`, `php`, and sub-namespaces beginning with those prefixes are reserved for use by PHP. -##Defining Namespaces +## Defining Namespaces **Syntax** + +
-  namespace-definition:
-    namespace  name  ;
-    namespace  nameopt   compound-statement
+namespace-definition:
+   namespace   namespace-name   ;
+   namespace   namespace-nameopt   compound-statement
 
-**Defined elsewhere** - -* [*name*](09-lexical-structure.md#names) -* [*compound-statement*](11-statements.md#compound-statements) - **Constraints** Except for white space and [*declare-statement*](11-statements.md#the-declare-statement), the @@ -114,45 +115,91 @@ namespace NS3\Sub1; } ``` -##Namespace Use Declarations +## Namespace Use Declarations **Syntax** + +
-  namespace-use-declaration:
-    use  namespace-function-or-constopt namespace-use-clauses  ;
+namespace-use-declaration:
+   use   namespace-function-or-constopt   namespace-use-clauses   ;
+   use   namespace-function-or-const   \opt   namespace-name   \   {   namespace-use-group-clauses-1   }   ;
+   use   \opt   namespace-name   \   {   namespace-use-group-clauses-2   }   ;
 
-  namespace-use-clauses:
-    namespace-use-clause
-    namespace-use-clauses  ,  namespace-use-clause
+namespace-use-clauses:
+   namespace-use-clause
+   namespace-use-clauses   ,   namespace-use-clause
 
-  namespace-use-clause:
-    qualified-name   namespace-aliasing-clauseopt
+namespace-use-clause:
+   qualified-name   namespace-aliasing-clauseopt
 
-  namespace-aliasing-clause:
-    as  name
+namespace-aliasing-clause:
+   as   name
 
-  namespace-function-or-const:
-    function
-    const
-
+namespace-function-or-const: + function + const -**Defined elsewhere** +namespace-use-group-clauses-1: + namespace-use-group-clause-1 + namespace-use-group-clauses-1 , namespace-use-group-clause-1 -* [*qualified-name*](09-lexical-structure.md#names) -* [*name*](09-lexical-structure.md#names) +namespace-use-group-clause-1: + namespace-name namespace-aliasing-clauseopt + +namespace-use-group-clauses-2: + namespace-use-group-clause-2 + namespace-use-group-clauses-2 , namespace-use-group-clause-2 + +namespace-use-group-clause-2: + namespace-function-or-constopt namespace-name namespace-aliasing-clauseopt +
**Constraints** A *namespace-use-declaration* must not occur except at the top level or directly in the context of a *namespace-definition*. -If the same *qualified-name* is imported multiple times in the same +If the same *qualified-name*, *name*, or *namespace-name* is imported multiple times in the same scope, each occurrence must have a different alias. **Semantics** -If *namespace-function-or-const* is provided, the import statement creates alias for -a function or constant, otherwise the alias applies for classes, interfaces, or traits. +If *namespace-use-declaration* has a *namespace-function-or-const* with value `function`, the statement imports +one or more functions. If *namespace-use-declaration* has a *namespace-function-or-const* with value `const`, the statement imports one or more constants. Otherwise, *namespace-use-declaration* has no *namespace-function-or-const*. In that case, if *namespace-use-clauses* is present, the names being imported are considered to be classes/interfaces/traits. Otherwise, *namespace-use-group-clauses-2* is present, in which case, the names being imported are considered to be functions, constants, or classes/interfaces/traits based on the respective presence of `function` or `const`, or the absence of *namespace-function-or-const* on each *namespace-name* in subordinate *namespace-use-group-clause-2*s. Note that constant, function and class imports live in different spaces, so the same name can be used as function and class import and apply to the respective cases of class and function use, @@ -162,7 +209,7 @@ A *namespace-use-declaration* *imports* β€” that is, makes available β€” one or more names into a scope, optionally giving them each an alias. Each of those names may designate a namespace, a sub-namespace, a class, an interface, or a trait. If a *namespace-aliasing-clause* is present, its -*name* is the alias for *qualified-name*. Otherwise, the right-most name component +*name* is the alias for *qualified-name*, *name*, or *namespace-name*. Otherwise, the right-most name component in *qualified-name* is the implied alias for *qualified-name*. **Examples** @@ -190,16 +237,25 @@ namespace NS2 use \NS1\C as C2; // C2 is an alias for the class name \NS1\C $c2 = new C2; + // importing a group of classes and interfaces + use \NS\{C11, C12, I10}; + // importing a function use function \My\Full\functionName; // aliasing a function use function \NS1\f as func; + use function \NS\{f1, g1 as myG}; // importing a constant use const \NS1\CON1; + use \NS\{const CON11, const CON12}; + $v = CON1; // imported constant func(); // imported function + + // importing a class, a constant, and a function + use \NS\ { C2 as CX, const CON2 as CZ, function f1 as FZ }; } ``` @@ -233,7 +289,7 @@ namespace a } ``` -##Name Lookup +## Name Lookup When an existing name is used in source code, the Engine must determine how that name is found with respect to namespace lookup. For this diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 0ae5ad35..ae4117b8 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -1,1197 +1,1162 @@ -#Grammar +# Grammar -##General +## General The grammar notation is described in [Grammars section](09-lexical-structure.md#grammars). -##Lexical Grammar - -###General - -
-  input-file::
-    input-element
-    input-file   input-element
-  input-element::
-    comment
-    white-space
-    token
-
- -###Comments +## Lexical Grammar
-  comment::
-    single-line-comment
-    delimited-comment
-
-  single-line-comment::
-    //   input-charactersopt
-    #    input-charactersopt
+input-file::
+   input-element
+   input-file   input-element
+
+input-element::
+   comment
+   white-space
+   token
+
+comment::
+   single-line-comment
+   delimited-comment
+
+single-line-comment::
+   //   input-charactersopt
+   #   input-charactersopt
+
+input-characters::
+   input-character
+   input-characters   input-character
+
+input-character::
+   Any source character except   new-line
+
+new-line::
+   Carriage-return character (0x0D)
+   Line-feed character (0x0A)
+   Carriage-return character (0x0D) followed by line-feed character (0x0A)
+
+delimited-comment::
+   /*   No characters or any source character sequence except */   */
+
+white-space::
+   white-space-character
+   white-space   white-space-character
+
+white-space-character::
+   new-line
+   Space character (0x20)
+   Horizontal-tab character (0x09)
+
+token::
+   variable-name
+   name
+   keyword
+   integer-literal
+   floating-literal
+   string-literal
+   operator-or-punctuator
+
+variable-name::
+   $   name
+
+namespace-name::
+   name
+   namespace-name   \   name
+
+namespace-name-as-a-prefix::
+   \
+   \opt   namespace-name   \
+   namespace   \
+   namespace   \   namespace-name   \
+
+qualified-name::
+   namespace-name-as-a-prefixopt   name
+
+name::
+   name-nondigit
+   name   name-nondigit
+   name   digit
+
+name-nondigit::
+   nondigit
+   one of the characters 0x80–0xff
+
+nondigit:: one of
+   _
+   a   b   c   d   e   f   g   h   i   j   k   l   m
+   n   o   p   q   r   s   t   u   v   w   x   y   z
+   A   B   C   D   E   F   G   H   I   J   K   L   M
+   N   O   P   Q   R   S   T   U   V   W   X   Y   Z
+
+keyword:: one of
+   abstract   and   array   as   break   callable   case   catch   class   clone
+   const   continue   declare   default   die   do   echo   else   elseif   empty
+   enddeclare   endfor   endforeach   endif   endswitch   endwhile   eval   exit
+   extends   final   finally   for   foreach   function   global
+   goto   if   implements   include   include_once   instanceof
+   insteadof   interface   isset   list   namespace   new   or   print   private
+   protected   public   require   require_once   return   static   switch
+   throw   trait   try   unset   use   var   while   xor   yield   yield from
+
+integer-literal::
+   decimal-literal
+   octal-literal
+   hexadecimal-literal
+   binary-literal
+
+decimal-literal::
+   nonzero-digit
+   decimal-literal   digit
+
+octal-literal::
+   0
+   octal-literal   octal-digit
+
+hexadecimal-literal::
+   hexadecimal-prefix   hexadecimal-digit
+   hexadecimal-literal   hexadecimal-digit
+
+hexadecimal-prefix:: one of
+   0x   0X
+
+binary-literal::
+   binary-prefix   binary-digit
+   binary-literal   binary-digit
+
+binary-prefix:: one of
+   0b   0B
+
+digit:: one of
+   0   1   2   3   4   5   6   7   8   9
+
+nonzero-digit:: one of
+   1   2   3   4   5   6   7   8   9
+
+octal-digit:: one of
+   0   1   2   3   4   5   6   7
+
+hexadecimal-digit:: one of
+   0   1   2   3   4   5   6   7   8   9
+   a   b   c   d   e   f
+   A   B   C   D   E   F
+
+binary-digit:: one of
+   0   1
+
+floating-literal::
+   fractional-literal   exponent-partopt
+   digit-sequence   exponent-part
+
+fractional-literal::
+   digit-sequenceopt   .   digit-sequence
+   digit-sequence   .
+
+exponent-part::
+   e   signopt   digit-sequence
+   E   signopt   digit-sequence
 
-  input-characters::
-    input-character
-    input-characters   input-character
+sign:: one of
+   +   -
+
+digit-sequence::
+   digit
+   digit-sequence   digit
+
+string-literal::
+   single-quoted-string-literal
+   double-quoted-string-literal
+   heredoc-string-literal
+   nowdoc-string-literal
+
+single-quoted-string-literal::
+   b-prefixopt   '   sq-char-sequenceopt   '
+
+sq-char-sequence::
+   sq-char
+   sq-char-sequence   sq-char
+
+sq-char::
+   sq-escape-sequence
+   \opt   any member of the source character set except single-quote (') or backslash (\)
+
+sq-escape-sequence:: one of
+   \'   \\
+
+b-prefix:: one of
+   b   B
+
+double-quoted-string-literal::
+   b-prefixopt   "   dq-char-sequenceopt   "
 
-  input-character::
-    Any source character except new-line
+dq-char-sequence::
+   dq-char
+   dq-char-sequence   dq-char
 
-  new-line::
-    Carriage-return character (U+000D)
-    Line-feed character (U+000A)
-    Carriage-return character (U+000D) followed by line-feed character (U+000A)
+dq-char::
+   dq-escape-sequence
+   any member of the source character set except double-quote (") or backslash (\)
+   \   any member of the source character set except "\$efnrtvxX or   octal-digit
 
-  delimited-comment::
-    /*   No characters or any source character sequence except */   */
-
- -###White Space - -
-  white-space::
-    white-space-character
-    white-space   white-space-character
-
-  white-space-character::
-    new-line
-    Space character (U+0020)
-    Horizontal-tab character (U+0009)
-
+dq-escape-sequence:: + dq-simple-escape-sequence + dq-octal-escape-sequence + dq-hexadecimal-escape-sequence + dq-unicode-escape-sequence -###Tokens +dq-simple-escape-sequence:: one of + \" \\ \$ \e \f \n \r \t \v -####General +dq-octal-escape-sequence:: + \ octal-digit + \ octal-digit octal-digit + \ octal-digit octal-digit octal-digit -
-  token::
-    variable-name
-    name
-    keyword
-    literal
-    operator-or-punctuator
-
- -####Names - -
-  variable-name::
-    $   name
-
-  namespace-name::
-    name
-    namespace-name   \   name
-
-  namespace-name-as-a-prefix::
-    \
-    \opt   namespace-name   \
-    namespace   \
-    namespace   \   namespace-name   \
-
-  qualified-name::
-    namespace-name-as-a-prefixopt   name
-
-  name::
-    name-nondigit
-    name   name-nondigit
-    name   digit
-
-  name-nondigit::
-    nondigit
-    one of the characters U+007f–U+00ff
-
-  nondigit:: one of
-    _
-    a   b   c   d   e   f   g   h   i   j   k   l   m
-    n   o   p   q   r   s   t   u   v   w   x   y   z
-    A   B   C   D   E   F   G   H   I   J   K   L   M
-    N   O   P   Q   R   S   T   U   V   W   X   Y   Z
-
- -###Keywords - -
-  keyword:: one of
-    abstract   and   as   break   callable   case   catch   class   clone
-    const   continue   declare   default   do   echo   else   elseif
-    enddeclare   endfor   endforeach   endif   endswitch   endwhile
-    extends   final   finally   for   foreach   function   global
-    goto   if   implements   include   include_once   instanceof
-    insteadof   interface   list   namespace   new   or   print   private
-    protected   public   require   require_once   return static   switch
-    throw   trait   try   use   var   while   xor   yield
-
+dq-hexadecimal-escape-sequence:: + \x hexadecimal-digit hexadecimal-digitopt + \X hexadecimal-digit hexadecimal-digitopt -###Literals +dq-unicode-escape-sequence:: + \u{ codepoint-digits } -####General +codepoint-digits:: + hexadecimal-digit + hexadecimal-digit codepoint-digits -
-  literal::
-    integer-literal
-    floating-literal
-    string-literal
-
+string-variable:: + variable-name offset-or-propertyopt + ${ expression } -####Integer Literals +offset-or-property:: + offset-in-string + property-in-string -
-  integer-literal::
-    decimal-literal
-    octal-literal
-    hexadecimal-literal
-    binary-literal
+offset-in-string::
+   [   name   ]
+   [   variable-name   ]
+   [   integer-literal   ]
 
-    decimal-literal::
-      nonzero-digit
-      decimal-literal   digit
+property-in-string::
+   ->   name
 
-    octal-literal::
-      0
-      octal-literal   octal-digit
+heredoc-string-literal::
+   b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
 
-    hexadecimal-literal::
-      hexadecimal-prefix   hexadecimal-digit
-      hexadecimal-literal   hexadecimal-digit
+hd-start-identifier::
+   name
+   "   name   "
 
-    hexadecimal-prefix:: one of
-      0x  0X
+hd-end-identifier::
+   name
 
-    binary-literal::
-      binary-prefix   binary-digit
-      binary-literal   binary-digit
+hd-body::
+   hd-char-sequenceopt   new-line
 
-    binary-prefix:: one of
-      0b  0B
+hd-char-sequence::
+   hd-char
+   hd-char-sequence   hd-char
 
-    digit:: one of
-      0  1  2  3  4  5  6  7  8  9
+hd-char::
+   hd-escape-sequence
+   any member of the source character set except backslash (\)
+   \ any member of the source character set except \$efnrtvxX or   octal-digit
 
-    nonzero-digit:: one of
-      1  2  3  4  5  6  7  8  9
+hd-escape-sequence::
+   hd-simple-escape-sequence
+   dq-octal-escape-sequence
+   dq-hexadecimal-escape-sequence
+   dq-unicode-escape-sequence
 
-    octal-digit:: one of
-      0  1  2  3  4  5  6  7
+hd-simple-escape-sequence:: one of
+   \\   \$   \e   \f   \n   \r   \t   \v
 
-    hexadecimal-digit:: one of
-      0  1  2  3  4  5  6  7  8  9
-      a  b  c  d  e  f
-      A  B  C  D  E  F
+nowdoc-string-literal::
+   b-prefixopt   <<<   '   name   '   new-line   hd-bodyopt   name   ;opt   new-line
 
-    binary-digit:: one of
-        0  1
+operator-or-punctuator:: one of
+   [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
+   $   /   %   <<   >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
+   &   &&   ||   ?   :   ;   =   **=   *=   /=   %=   +=   -=   .=   <<=
+   >>=   &=   ^=   |=   ,   ??   <=>   ...   \
 
-####Floating-Point Literals - -
-  floating-literal::
-    fractional-literal   exponent-partopt
-    digit-sequence   exponent-part
-
-  fractional-literal::
-    digit-sequenceopt . digit-sequence
-    digit-sequence .
+## Syntactic Grammar
 
-  exponent-part::
-    e  signopt   digit-sequence
-    E  signopt   digit-sequence
-
-  sign:: one of
-    +  -
-
-  digit-sequence::
-    digit
-    digit-sequence   digit
-
- -####String Literals +### Basic Concepts
-  string-literal::
-    single-quoted-string-literal
-    double-quoted-string-literal
-    heredoc-string-literal
-    nowdoc-string-literal
-
-  single-quoted-string-literal::
-    bopt  ' sq-char-sequenceopt  '
-
-  sq-char-sequence::
-    sq-char
-    sq-char-sequence   sq-char
-
-  sq-char::
-    sq-escape-sequence
-    \opt   any member of the source character set except single-quote (') or backslash (\)
-
-  sq-escape-sequence:: one of
-    \'  \\
-
-  double-quoted-string-literal::
-    bopt  " dq-char-sequenceopt  "
-
-  dq-char-sequence::
-    dq-char
-    dq-char-sequence   dq-char
-
-  dq-char::
-    dq-escape-sequence
-    any member of the source character set except double-quote (") or backslash (\)
-    \  any member of the source character set except "\$efnrtvxX or octal-digit
-
-  dq-escape-sequence::
-    dq-simple-escape-sequence
-    dq-octal-escape-sequence
-    dq-hexadecimal-escape-sequence
-
-  dq-simple-escape-sequence:: one of
-    \"   \\   \$   \e   \f   \n   \r   \t   \v
-
-  dq-octal-escape-sequence::
-    \   octal-digit
-    \   octal-digit   octal-digit
-    \   octal-digit   octal-digit   octal-digit
-
-  dq-hexadecimal-escape-sequence::
-    \x  hexadecimal-digit   hexadecimal-digitopt
-    \X  hexadecimal-digit   hexadecimal-digitopt
+script:
+   script-section
+   script   script-section
 
-    string-variable::
-        variable-name   offset-or-propertyopt
-        ${   expression   }
+script-section:
+   textopt   start-tag   statement-listopt   end-tagopt   textopt
 
-    offset-or-property::
-        offset-in-string
-        property-in-string
+start-tag:
+   <?php
+   <?=
 
-    offset-in-string::
-        [   name   ]
-        [   variable-name   ]
-        [   integer-literal   ]
+end-tag:
+   ?>
 
-    property-in-string::
-        ->   name
-
-  heredoc-string-literal::
-    <<<  hd-start-identifier   new-line   hd-char-sequenceopt  new-line hd-end-identifier  ;opt   new-line
-
-  hd-start-identifier::
-    name
-    "   name  "
-
-  hd-end-identifier::
-    name
-
-  hd-char-sequence::
-    hd-char
-    hd-char-sequence   hd-char
-
-  hd-char::
-    hd-escape-sequence
-    any member of the source character set except backslash (\)
-    \  any member of the source character set except \$efnrtvxX or octal-digit
-
-  hd-escape-sequence::
-    hd-simple-escape-sequence
-    dq-octal-escape-sequence
-    dq-hexadecimal-escape-sequence
-
-  hd-simple-escape-sequence:: one of
-    \\   \$   \e   \f   \n   \r   \t   \v
-
-  nowdoc-string-literal::
-    <<<  '  name  '  new-line  hd-char-sequenceopt   new-line name  ;opt   new-line
-
- -###Operators and Punctuators - -
-  operator-or-punctuator:: one of
-    [   ]    (   )   {    }   .   ->   ++   --   **   *   +   -   ~   !
-    $   /   %   <<    >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
-    &   &&   ||   ?   :   ; =   **=   *=   /=   %=   +=   -=   .=   <<=
-    >>=   &=   ^=   |=   =&   ,
-
- -##Syntactic Grammar - -###Program Structure - -
-script:
- script-section
- script   script-section
-
-script-section:
-   textopt start-tag statement-listopt end-tagopt textopt
-
-start-tag:
-  <?php
-  <?=
-
-end-tag:
-  ?>
-
-text:
-  arbitrary text not containing any of start-tag sequences
+text:
+   arbitrary text not containing any of   start-tag   sequences
 
-###Variables +### Variables
-  function-static-declaration:
-    static static-variable-name-list  ;
-
-  static-variable-name-list:
-    static-variable-declaration
-	static-variable-name-list  ,  static-variable-declaration
-
-  static-variable-declaration:
-	variable-name function-static-initializeropt
-
-  function-static-initializer:
-    = constant-expression
-
-  global-declaration:
-    global variable-name-list ;
-
-  variable-name-list:
-    expression
-    variable-name-list  ,  expression
-
- -###Expressions - -####Primary Expressions - -
-  primary-expression:
-    variable-name
-    qualified-name
-    literal
-    constant-expression
-    intrinsic
-    anonymous-function-creation-expression
-    (  expression  )
-    $this
-
-  intrinsic:
-    intrisic-construct
-    intrisic-operator
-
-  intrisic-construct:
-    echo-intrinsic
-    list-intrinsic
-    unset-intrinsic
-
-  intrinsic-operator:
-    array-intrinsic
-    empty-intrinsic
-    eval-intrinsic
-    exit-intrinsic
-    isset-intrinsic
-    print-intrinsic
-
-  array-intrinsic:
-    array ( array-initializeropt  )
-
-  echo-intrinsic:
-    echo  expression
-    echo  expression-list-two-or-more
-
-  expression-list-two-or-more:
-    expression  ,  expression
-    expression-list-two-or-more  ,  expression
-
-  empty-intrinsic:
-    empty ( expression  )
-
-  eval-intrinsic:
-    eval (  expression  )
-
-  exit-intrinsic:
-    exit  expressionopt
-    exit  (  expressionopt  )
-    die   expressionopt
-    die   (   expressionopt )
-
-  isset-intrinsic:
-    isset  (  expression-list-one-or-more  )
-
-  expression-list-one-or-more:
-    expression
-    expression-list-one-or-more  ,  expression
-
-  list-intrinsic:
-    list  (  list-expression-listopt  )
-
-  list-expression-list:
-    list-or-variable
-    ,
-    list-expression-list  ,  list-or-variableopt
-
-  list-or-variable:
-    list-intrinsic
-    expression
-
-  print-intrinsic:
-    print  expression
-    print  (  expression  )
-
-  unset-intrinsic:
-    unset  (  expression-list-one-or-more  )
-
-  anonymous-function-creation-expression:
-  staticopt function  &opt (  parameter-declaration-listopt  )  anonymous-function-use-clauseopt
-      compound-statement
-
-  anonymous-function-use-clause:
-    use  (  use-variable-name-list  )
-
-  use-variable-name-list:
-    &opt   variable-name
-    use-variable-name-list  ,  &opt  variable-name
-
-
- -####Postfix Operators - -
-  postfix-expression:
-    primary-expression
-    clone-expression
-    object-creation-expression
-    array-creation-expression
-    subscript-expression
-    function-call-expression
-    member-selection-expression
-    postfix-increment-expression
-    postfix-decrement-expression
-    scope-resolution-expression
-    exponentiation-expression
-
-  clone-expression:
-    clone  expression
-
-  object-creation-expression:
-    new  class-type-designator  (  argument-expression-listopt  )
-    new  class-type-designator
-
-  class-type-designator:
-    qualified-name
-    expression
-
-  array-creation-expression:
-    array  (  array-initializeropt  )
-    [ array-initializeropt ]
-
-  array-initializer:
-    array-initializer-list  ,opt
-
-  array-initializer-list:
-    array-element-initializer
-    array-element-initializer  ,  array-initializer-list
-
-  array-element-initializer:
-    &opt   element-value
-    element-key  =>  &opt   element-value
-
-  element-key:
-    expression
-
-  element-value
-    expression
-
-  subscript-expression:
-    postfix-expression  [  expressionopt  ]
-    postfix-expression  {  expression  }   [Deprecated form]
-
-  function-call-expression:
-    qualified-name  (  argument-expression-listopt  )
-    postfix-expression  (  argument-expression-listopt  )
-
-  argument-expression-list:
-    argument-expression
-    argument-expression-list  ,  argument-expression
-
-  argument-expression:
-    variadic-unpacking
-    assignment-expression
-
-  variadic-unpacking:
-    ... assignment-expression
-
-  member-selection-expression:
-    postfix-expression  ->  member-selection-designator
-
-  member-selection-designator:
-    name
-    expression
-
-  postfix-increment-expression:
-    unary-expression  ++
-
-  postfix-decrement-expression:
-    unary-expression  --
-
-  scope-resolution-expression:
-    scope-resolution-qualifier  ::  member-selection-designator
-    scope-resolution-qualifier  ::  class
-
-  scope-resolution-qualifier:
-    relative-scope
-    qualified-name
-    expression
-
-  relative-scope:
-    self
-    parent
-    static
-
-  exponentiation-expression:
-    expression  **  expression
-
- -####Unary Operators - -
-  unary-expression:
-    postfix-expression
-    prefix-increment-expression
-    prefix-decrement-expression
-    unary-op-expression
-    error-control-expression
-    shell-command-expression
-    cast-expression
-    variable-name-creation-expression
-
-  prefix-increment-expression:
-    ++ unary-expression
+function-static-declaration:
+   static   static-variable-name-list   ;
 
-  prefix-decrement-expression:
-    -- unary-expression
+static-variable-name-list:
+   static-variable-declaration
+   static-variable-name-list   ,   static-variable-declaration
 
-  unary-op-expression:
-    unary-operator cast-expression
+static-variable-declaration:
+   variable-name   function-static-initializeropt
 
-  unary-operator: one of
-    +  -  !  ~
+function-static-initializer:
+   =   constant-expression
 
-  error-control-expression:
-    @   expression
-
-  shell-command-expression:
-    `  dq-char-sequenceopt  `
-
-  cast-expression:
-    unary-expression
-    (  cast-type  ) expression
-
-  cast-type: one of
-    array  binary  bool  boolean  double  int  integer  float  object
-    real  string  unset
-
-  variable-name-creation-expression:
-    $   expression
-    $  {  expression  }
+global-declaration:
+   global   variable-name-list   ;
 
+variable-name-list:
+   simple-variable
+   variable-name-list   ,   simple-variable
 
-####instanceof Operator +### Expressions
-  instanceof-expression:
-    unary-expression
-    instanceof-subject  instanceof   instanceof-type-designator
+primary-expression:
+   variable
+   class-constant-access-expression
+   constant-access-expression
+   literal
+   array-creation-expression
+   intrinsic
+   anonymous-function-creation-expression
+   object-creation-expression
+   postfix-increment-expression
+   postfix-decrement-expression
+   prefix-increment-expression
+   prefix-decrement-expression
+   byref-assignment-expression
+   shell-command-expression
+   (   expression   )
+
+simple-variable:
+   variable-name
+   $   simple-variable
+   $   {   expression   }
+
+dereferencable-expression:
+   variable
+   (   expression   )
+   array-creation-expression
+   string-literal
+
+callable-expression:
+   callable-variable
+   (   expression   )
+   array-creation-expression
+   string-literal
+
+callable-variable:
+   simple-variable
+   subscript-expression
+   member-call-expression
+   scoped-call-expression
+   function-call-expression
+
+variable:
+   callable-variable
+   scoped-property-access-expression
+   member-access-expression
+
+constant-access-expression:
+   qualified-name
+
+literal:
+   integer-literal
+   floating-literal
+   string-literal
+
+intrinsic:
+   empty-intrinsic
+   eval-intrinsic
+   exit-intrinsic
+   isset-intrinsic
+
+empty-intrinsic:
+   empty   (   expression   )
+
+eval-intrinsic:
+   eval   (   expression   )
+
+exit-intrinsic:
+   exit
+   exit   (   expressionopt   )
+   die
+   die   (   expressionopt   )
+
+isset-intrinsic:
+   isset   (   variable-list   ,opt   )
+
+variable-list:
+   variable
+   variable-list   ,   variable
+
+anonymous-function-creation-expression:
+   staticopt   function   &opt   (   parameter-declaration-listopt   )   anonymous-function-use-clauseopt   return-typeopt   compound-statement
+
+anonymous-function-use-clause:
+   use   (   use-variable-name-list   )
+
+use-variable-name-list:
+   &opt   variable-name
+   use-variable-name-list   ,   &opt   variable-name
+
+object-creation-expression:
+   new   class-type-designator   (   argument-expression-listopt   )
+   new   class-type-designator   (   argument-expression-list   ,opt   )
+   new   class-type-designator
+   new   class   (   argument-expression-listopt   )   class-base-clauseopt   class-interface-clauseopt   {   class-member-declarationsopt   }
+   new   class   class-base-clauseopt   class-interface-clauseopt   {   class-member-declarationsopt   }
+
+class-type-designator:
+   qualified-name
+   new-variable
+
+new-variable:
+   simple-variable
+   new-variable   [   expressionopt   ]
+   new-variable   {   expression   }
+   new-variable   ->   member-name
+   qualified-name   ::   simple-variable
+   relative-scope   ::   simple-variable
+   new-variable   ::   simple-variable
+
+array-creation-expression:
+   array   (   array-initializeropt   )
+   [   array-initializeropt   ]
+
+array-initializer:
+   array-initializer-list   ,opt
+
+array-initializer-list:
+   array-element-initializer
+   array-element-initializer   ,   array-initializer-list
+
+array-element-initializer:
+   &opt   element-value
+   element-key   =>   &opt   element-value
+
+element-key:
+   expression
+
+element-value:
+   expression
+
+subscript-expression:
+   dereferencable-expression   [   expressionopt   ]
+   dereferencable-expression   {   expression   }   <b>[Deprecated form]</b>
 
-  instanceof-subject:
-    expression
+function-call-expression:
+   qualified-name   (   argument-expression-listopt   )
+   qualified-name   (   argument-expression-list   ,   )
+   callable-expression   (   argument-expression-listopt   )
+   callable-expression   (   argument-expression-list   ,   )
 
-  instanceof-type-designator:
-    qualified-name
-    expression
-
+argument-expression-list: + argument-expression + argument-expression-list , argument-expression -####Multiplicative Operators +argument-expression: + variadic-unpacking + expression -
-  multiplicative-expression:
-    instanceof-expression
-    multiplicative-expression  *  instanceof-expression
-    multiplicative-expression  /  instanceof-expression
-    multiplicative-expression  %  instanceof-expression
-
+variadic-unpacking: + ... expression -####Additive Operators +member-access-expression: + dereferencable-expression -> member-name -
-  additive-expression:
-    multiplicative-expression
-    additive-expression  +  multiplicative-expression
-    additive-expression  -  multiplicative-expression
-    additive-expression  .  multiplicative-expression
-
+member-name: + name + simple-variable + { expression } -####Bitwise Shift Operators +member-call-expression: + dereferencable-expression -> member-name ( argument-expression-listopt ) + dereferencable-expression -> member-name ( argument-expression-list , ) + +postfix-increment-expression: + variable ++ + +postfix-decrement-expression: + variable -- + +prefix-increment-expression: + ++ variable + +prefix-decrement-expression: + -- variable + +shell-command-expression: + ` dq-char-sequenceopt ` + +scoped-property-access-expression: + scope-resolution-qualifier :: simple-variable + +scoped-call-expression: + scope-resolution-qualifier :: member-name ( argument-expression-listopt ) + scope-resolution-qualifier :: member-name ( argument-expression-list , ) + +class-constant-access-expression: + scope-resolution-qualifier :: name + +scope-resolution-qualifier: + relative-scope + qualified-name + dereferencable-expression + +relative-scope: + self + parent + static + +clone-expression: + primary-expression + clone primary-expression + +exponentiation-expression: + clone-expression + clone-expression ** exponentiation-expression + +unary-expression: + exponentiation-expression + unary-op-expression + error-control-expression + cast-expression -
-  shift-expression:
-    additive-expression
-    shift-expression  <<  additive-expression
-    shift-expression  >>  additive-expression
-
+unary-op-expression: + unary-operator unary-expression + +unary-operator: one of + + - ~ + +error-control-expression: + @ unary-expression + +cast-expression: + ( cast-type ) unary-expression + +cast-type: one of + array binary bool boolean double int integer float object + real string unset + +instanceof-expression: + unary-expression + instanceof-subject instanceof class-type-designator + +instanceof-subject: + instanceof-expression + +logical-NOT-expression: + instanceof-expression + ! instanceof-expression -####Relational Operators - -
-  relational-expression:
-    shift-expression
-    relational-expression  <   shift-expression
-    relational-expression  >   shift-expression
-    relational-expression  <=  shift-expression
-    relational-expression  >=  shift-expression
-
- -####Equality Operators - -
-  equality-expression:
-    relational-expression
-    equality-expression  ==  relational-expression
-    equality-expression  !=  relational-expression
-    equality-expression  <>  relational-expression
-    equality-expression  ===  relational-expression
-    equality-expression  !==  relational-expression
-
- -####Bitwise Logical Operators - -
-  bitwise-AND-expression:
-    equality-expression
-    bit-wise-AND-expression  &  equality-expression
+multiplicative-expression:
+   logical-NOT-expression
+   multiplicative-expression   *   logical-NOT-expression
+   multiplicative-expression   /   logical-NOT-expression
+   multiplicative-expression   %   logical-NOT-expression
+
+additive-expression:
+   multiplicative-expression
+   additive-expression   +   multiplicative-expression
+   additive-expression   -   multiplicative-expression
+   additive-expression   .   multiplicative-expression
 
-  bitwise-exc-OR-expression:
-    bitwise-AND-expression
-    bitwise-exc-OR-expression  ^  bitwise-AND-expression
+shift-expression:
+   additive-expression
+   shift-expression   <<   additive-expression
+   shift-expression   >>   additive-expression
+
+relational-expression:
+   shift-expression
+   relational-expression   <   shift-expression
+   relational-expression   >   shift-expression
+   relational-expression   <=   shift-expression
+   relational-expression   >=   shift-expression
+   relational-expression   <=>   shift-expression
+
+equality-expression:
+   relational-expression
+   equality-expression   ==   relational-expression
+   equality-expression   !=   relational-expression
+   equality-expression   <>   relational-expression
+   equality-expression   ===   relational-expression
+   equality-expression   !==   relational-expression
+
+bitwise-AND-expression:
+   equality-expression
+   bitwise-AND-expression   &   equality-expression
+
+bitwise-exc-OR-expression:
+   bitwise-AND-expression
+   bitwise-exc-OR-expression   ^   bitwise-AND-expression
+
+bitwise-inc-OR-expression:
+   bitwise-exc-OR-expression
+   bitwise-inc-OR-expression   |   bitwise-exc-OR-expression
+
+logical-AND-expression-1:
+   bitwise-inc-OR-expression
+   logical-AND-expression-1   &&   bitwise-inc-OR-expression
+
+logical-inc-OR-expression-1:
+   logical-AND-expression-1
+   logical-inc-OR-expression-1   ||   logical-AND-expression-1
+
+coalesce-expression:
+   logical-inc-OR-expression-1
+   logical-inc-OR-expression-1   ??   coalesce-expression
+
+conditional-expression:
+   coalesce-expression
+   conditional-expression   ?   expressionopt   :   coalesce-expression
+
+assignment-expression:
+   conditional-expression
+   simple-assignment-expression
+   compound-assignment-expression
+
+simple-assignment-expression:
+   variable   =   assignment-expression
+   list-intrinsic   =   assignment-expression
+
+list-intrinsic:
+   list   (   list-expression-list   )
+
+list-expression-list:
+   unkeyed-list-expression-list
+   keyed-list-expression-list   ,opt
+
+unkeyed-list-expression-list:
+   list-or-variable
+   ,
+   unkeyed-list-expression-list   ,   list-or-variableopt
+
+keyed-list-expression-list:
+   expression   =>   list-or-variable
+   keyed-list-expression-list   ,   expression   =>   list-or-variable
+
+list-or-variable:
+   list-intrinsic
+   &opt   variable
+
+byref-assignment-expression:
+   variable   =   &   variable
+
+compound-assignment-expression:
+   variable   compound-assignment-operator   assignment-expression
+
+compound-assignment-operator: one of
+   **=   *=   /=   %=   +=   -=   .=   <<=   >>=   &=   ^=   |=
+
+yield-from-expression:
+   yield from   assignment-expression
+
+yield-expression:
+   yield-from-expression
+   yield
+   yield   yield-expression
+   yield   yield-from-expression   =>   yield-expression
+
+print-expression:
+   yield-expression
+   print   print-expression
+
+logical-AND-expression-2:
+   print-expression
+   logical-AND-expression-2   and   yield-expression
+
+logical-exc-OR-expression:
+   logical-AND-expression-2
+   logical-exc-OR-expression   xor   logical-AND-expression-2
+
+logical-inc-OR-expression-2:
+   logical-exc-OR-expression
+   logical-inc-OR-expression-2   or   logical-exc-OR-expression
 
-  bitwise-inc-OR-expression:
-    bitwise-exc-OR-expression
-    bitwise-inc-OR-expression  |  bitwise-exc-OR-expression
-
+expression: + logical-inc-OR-expression-2 + include-expression + include-once-expression + require-expression + require-once-expression -####Logical Operators (form 1) +include-expression: + include expression -
-  logical-AND-expression-1:
-    bitwise-incl-OR-expression
-    logical-AND-expression-1  &&  bitwise-inc-OR-expression
+include-once-expression:
+   include_once   expression
 
-  logical-inc-OR-expression-1:
-    logical-AND-expression-1
-    logical-inc-OR-expression-1  ||  logical-AND-expression-1
-
+require-expression: + require expression -####Conditional Operator +require-once-expression: + require_once expression -
-  conditional-expression:
-    logical-inc-OR-expression-1
-    logical-inc-OR-expression-1  ?  expressionopt  :  conditional-expression
+constant-expression:
+   expression
 
-####Assignment Operators +### Statements
-  assignment-expression:
-    conditional-expression
-    simple-assignment-expression
-    byref-assignment-expression
-    compound-assignment-expression
+statement:
+   compound-statement
+   named-label-statement
+   expression-statement
+   selection-statement
+   iteration-statement
+   jump-statement
+   try-statement
+   declare-statement
+   echo-statement
+   unset-statement
+   const-declaration
+   function-definition
+   class-declaration
+   interface-declaration
+   trait-declaration
+   namespace-definition
+   namespace-use-declaration
+   global-declaration
+   function-static-declaration
+
+compound-statement:
+   {   statement-listopt   }
+
+statement-list:
+   statement
+   statement-list   statement
+
+named-label-statement:
+   name   :
+
+expression-statement:
+   expressionopt   ;
+
+selection-statement:
+   if-statement
+   switch-statement
+
+if-statement:
+   if   (   expression   )   statement   elseif-clauses-1opt   else-clause-1opt
+   if   (   expression   )   :   statement-list   elseif-clauses-2opt   else-clause-2opt   endif   ;
+
+elseif-clauses-1:
+   elseif-clause-1
+   elseif-clauses-1   elseif-clause-1
+
+elseif-clause-1:
+   elseif   (   expression   )   statement
+
+else-clause-1:
+   else   statement
+
+elseif-clauses-2:
+   elseif-clause-2
+   elseif-clauses-2   elseif-clause-2
+
+elseif-clause-2:
+   elseif   (   expression   )   :   statement-list
 
-  simple-assignment-expression:
-    unary-expression  =  assignment-expression
+else-clause-2:
+   else   :   statement-list
 
-  byref-assignment-expression:
-    unary-expression  =  &  assignment-expression
+switch-statement:
+   switch   (   expression   )   {   case-statementsopt   }
+   switch   (   expression   )   :   case-statementsopt   endswitch   ;
 
-  compound-assignment-expression:
-    unary-expression   compound-assignment-operator   assignment-expression
+case-statements:
+   case-statement   case-statementsopt
+   default-statement   case-statementsopt
 
-  compound-assignment-operator: one of
-    **=  *=  /=  %=  +=  -=  .=  <<=  >>=  &=  ^=  |=
-
+case-statement: + case expression case-default-label-terminator statement-listopt + +default-statement: + default case-default-label-terminator statement-listopt + +case-default-label-terminator: + : + ; + +iteration-statement: + while-statement + do-statement + for-statement + foreach-statement -####Logical Operators (form 2) +while-statement: + while ( expression ) statement + while ( expression ) : statement-list endwhile ; + +do-statement: + do statement while ( expression ) ; + +for-statement: + for ( for-initializeropt ; for-controlopt ; for-end-of-loopopt ) statement + for ( for-initializeropt ; for-controlopt ; for-end-of-loopopt ) : statement-list endfor ; + +for-initializer: + for-expression-group + +for-control: + for-expression-group -
-  logical-AND-expression-2:
-    assignment-expression
-    logical-AND-expression-2  and  assignment-expression
+for-end-of-loop:
+   for-expression-group
 
-  logical-exc-OR-expression:
-    logical-AND-expression-2
-    logical-exc-OR-expression  xor  logical-AND-expression-2
+for-expression-group:
+   expression
+   for-expression-group   ,   expression
 
-  logical-inc-OR-expression-2:
-    logical-exc-OR-expression
-    logical-inc-OR-expression-2  or  logical-exc-OR-expression
+foreach-statement:
+   foreach   (   foreach-collection-name   as   foreach-keyopt   foreach-value   )   statement
+   foreach   (   foreach-collection-name   as   foreach-keyopt   foreach-value   )   :   statement-list   endforeach   ;
 
-
+foreach-collection-name: + expression +foreach-key: + expression => -####yield Operator +foreach-value: + &opt expression + list-intrinsic -
-  yield-expression:
-    logical-inc-OR-expression-2
-    yield  array-element-initializer
-
+jump-statement: + goto-statement + continue-statement + break-statement + return-statement + throw-statement -####Script Inclusion Operators +goto-statement: + goto name ; -
-  expression:
-    yield-expression
-    include-expression
-    include-once-expression
-    require-expression
-    require-once-expression
-
-  include-expression:
-    include  (  expression  )
-    include  expression
-
-  include-once-expression:
-    include_once  (  expression  )
-    include_once  expression
-
-  require-expression:
-    require  (  expression  )
-    require  expression
-
-  require-once-expression:
-    require_once  (  expression  )
-    require_once  expression
-
+continue-statement: + continue breakout-levelopt ; -####Constant Expressions +breakout-level: + integer-literal + ( breakout-level ) -
-  constant-expression:
-    array-creation-expression
-    expression
-
+break-statement: + break breakout-levelopt ; -###Statements +return-statement: + return expressionopt ; -####General +throw-statement: + throw expression ; -
-
-  statement:
-    compound-statement
-    labeled-statement
-    expression-statement
-    selection-statement
-    iteration-statement
-    jump-statement
-    declare-statement
-    const-declaration
-    function-definition
-    class-declaration
-    interface-declaration
-    trait-declaration
-    namespace-definition
-    namespace-use-declaration
-    global-declaration
-    function-static-declaration
-
+try-statement: + try compound-statement catch-clauses + try compound-statement finally-clause + try compound-statement catch-clauses finally-clause -####Compound Statements +catch-clauses: + catch-clause + catch-clauses catch-clause -
-  compound-statement:
-    {   statement-listopt  }
+catch-clause:
+   catch   (   catch-name-list   variable-name   )   compound-statement
 
-  statement-list:
-    statement
-    statement-list   statement
-
+catch-name-list: + qualified-name + catch-name-list | qualified-name -####Labeled Statements +finally-clause: + finally compound-statement -
-  labeled-statement:
-    named-label-statement
-    case-statement
-    default-statement
+declare-statement:
+   declare   (   declare-directive   )   statement
+   declare   (   declare-directive   )   :   statement-list   enddeclare   ;
+   declare   (   declare-directive   )   ;
 
-  named-label-statement:
-    name  :  statement
+declare-directive:
+   ticks   =   literal
+   encoding   =   literal
+   strict_types   =   literal
 
-  case-statement:
-    case   expression   case-default-label-terminator   statement
+echo-statement:
+   echo   expression-list   ;
 
-  default-statement:
-    default  case-default-label-terminator   statement
+expression-list:
+   expression
+   expression-list   ,   expression
 
-  case-default-label-terminator:
-    :
-    ;
+unset-statement:
+   unset   (   variable-list   ,opt   )   ;
 
-####Expression Statements +### Functions
-   expression-statement:
-     expressionopt  ;
+function-definition:
+   function-definition-header   compound-statement
 
-  selection-statement:
-    if-statement
-    switch-statement
+function-definition-header:
+   function   &opt   name   (   parameter-declaration-listopt   )   return-typeopt
 
-  if-statement:
-    if   (   expression   )   statement   elseif-clauses-1opt   else-clause-1opt
-    if   (   expression   )   :   statement-list   elseif-clauses-2opt   else-clause-2opt   endif   ;
+parameter-declaration-list:
+   simple-parameter-declaration-list
+   variadic-declaration-list
 
-  elseif-clauses-1:
-    elseif-clause-1
-    elseif-clauses-1   elseif-clause-1
+simple-parameter-declaration-list:
+   parameter-declaration
+   parameter-declaration-list   ,   parameter-declaration
 
-  elseif-clause-1:
-    elseif   (   expression   )   statement
+variadic-declaration-list:
+   simple-parameter-declaration-list   ,   variadic-parameter
+   variadic-parameter
 
-  else-clause-1:
-    else   statement
+parameter-declaration:
+   type-declarationopt   &opt   variable-name   default-argument-specifieropt
 
-  elseif-clauses-2:
-    elseif-clause-2
-    elseif-clauses-2   elseif-clause-2
+variadic-parameter:
+   type-declarationopt   &opt   ...   variable-name
 
-  elseif-clause-2:
-    elseif   (   expression   )   :   statement-list
+return-type:
+   :   type-declaration
+   :   void
 
-  else-clause-2:
-    else   :   statement-list
+type-declaration:
+   ?opt   base-type-declaration
 
-  switch-statement:
-    switch  (  expression  )  { case-statementsopt }
-    switch  (  expression  )  :   case-statementsopt  endswitch;
+base-type-declaration:
+   array
+   callable
+   iterable
+   scalar-type
+   qualified-name
 
-  case-statements:
-    case-statement statement-listopt case-statementsopt
-    default-statement statement-listopt case-statementsopt
+scalar-type:
+   bool
+   float
+   int
+   string
 
+default-argument-specifier:
+   =   constant-expression
 
-####Iteration Statements +### Classes
-  iteration-statement:
-    while-statement
-    do-statement
-    for-statement
-    foreach-statement
+class-declaration:
+   class-modifiersopt   class   name   class-base-clauseopt   class-interface-clauseopt   {   class-member-declarationsopt   }
 
-  while-statement:
-    while  (  expression  )  statement
-    while  (  expression  )  :   statement-list  endwhile ;
+class-modifiers:
+   class-modifier
+   class-modifiers   class-modifier
 
-  do-statement:
-    do  statement  while  (  expression  )  ;
+class-modifier:
+   abstract
+   final
+   readonly
 
-  for-statement:
-    for   (   for-initializeropt   ;   for-controlopt   ;   for-end-of-loopopt   )   statement
-    for   (   for-initializeropt   ;   for-controlopt   ;   for-end-of-loopopt   )   :   statement-list   endfor   ;
+class-base-clause:
+   extends   qualified-name
 
-  for-initializer:
-    for-expression-group
+class-interface-clause:
+   implements   qualified-name
+   class-interface-clause   ,   qualified-name
 
-  for-control:
-    for-expression-group
+class-member-declarations:
+   class-member-declaration
+   class-member-declarations   class-member-declaration
 
-  for-end-of-loop:
-    for-expression-group
+class-member-declaration:
+   class-const-declaration
+   property-declaration
+   method-declaration
+   constructor-declaration
+   destructor-declaration
+   trait-use-clause
 
-  for-expression-group:
-    expression
-    for-expression-group   ,   expression
+const-declaration:
+   const   const-elements   ;
 
-  foreach-statement:
-    foreach  (  foreach-collection-name  as  foreach-keyopt  foreach-value  )   statement
-    foreach  (  foreach-collection-name  as  foreach-keyopt  foreach-value  )  :  statement-list  endforeach  ;
+class-const-declaration:
+   visibility-modifieropt   const   const-elements   ;
 
-  foreach-collection-name:
-    expression
+const-elements:
+   const-element
+   const-elements   ,   const-element
 
-  foreach-key:
-    expression  =>
+const-element:
+   name   =   constant-expression
 
-  foreach-value:
-    &opt   expression
-    list-intrinsic
+property-declaration:
+   property-modifier   property-elements   ;
 
-
+property-modifier: + var + visibility-modifier static-modifieropt + static-modifier visibility-modifieropt -####Jump Statements +visibility-modifier: + public + protected + private -
-  jump-statement:
-    goto-statement
-    continue-statement
-    break-statement
-    return-statement
-    throw-statement
+static-modifier:
+   static
 
-  goto-statement:
-    goto  name  ;
+property-elements:
+   property-element
+   property-elements   property-element
 
-  continue-statement:
-    continue   breakout-levelopt  ;
+property-element:
+   variable-name   property-initializeropt   ;
 
-  breakout-level:
-    integer-literal
+property-initializer:
+   =   constant-expression
 
-  break-statement:
-    break  breakout-levelopt  ;
+method-declaration:
+   method-modifiersopt   function-definition
+   method-modifiers   function-definition-header   ;
 
-  return-statement:
-    return  expressionopt  ;
+method-modifiers:
+   method-modifier
+   method-modifiers   method-modifier
 
-  throw-statement:
-    throw  expression  ;
-
- -####The try Statement - -
-  try-statement:
-    try  compound-statement   catch-clauses
-    try  compound-statement   finally-clause
-    try  compound-statement   catch-clauses   finally-clause
-
-  catch-clauses:
-    catch-clause
-    catch-clauses   catch-clause
-
-  catch-clause:
-    catch  (  qualified-name variable-name )  compound-statement
-
-  finally-clause:
-    finally   compound-statement
-
- -####The declare Statement - -
-  declare-statement:
-    declare  (  declare-directive  )  statement
-    declare  (  declare-directive  )  :  statement-list  enddeclare  ;
-    declare  (  declare-directive  )  ;
+method-modifier:
+   visibility-modifier
+   static-modifier
+   class-modifier
 
-  declare-directive:
-    ticks  =  literal
-    encoding  =  literal
+constructor-declaration:
+   method-modifiers   function   &opt   __construct   (   parameter-declaration-listopt   )   compound-statement
 
+destructor-declaration:
+   method-modifiers   function   &opt   __destruct   (   )   compound-statement
 
-###Functions +### Interfaces
-  function-definition:
-    function-definition-header   compound-statement
+interface-declaration:
+   interface   name   interface-base-clauseopt   {   interface-member-declarationsopt   }
 
-  function-definition-header:
-    function  &opt   name  (  parameter-declaration-listopt  )
+interface-base-clause:
+   extends   qualified-name
+   interface-base-clause   ,   qualified-name
 
-  parameter-declaration-list:
-    simple-parameter-declaration-list
-    variadic-declaration-list
+interface-member-declarations:
+   interface-member-declaration
+   interface-member-declarations   interface-member-declaration
 
-  simple-parameter-declaration-list:
-    parameter-declaration
-    parameter-declaration-list  ,  parameter-declaration
-
-  variadic-declaration-list:
-    simple-parameter-declaration-list  ,  variadic-parameter
-    variadic-parameter
-
-  parameter-declaration:
-    type-declarationopt  &opt  variable-name   default-argument-specifieropt
-
-  variadic-parameter:
-	type-declarationopt  &opt  ...  variable-name
-
-  type-declaration:
-    array
-    callable
-    qualified-name
-
-  default-argument-specifier:
-    =  constant-expression
+interface-member-declaration:
+   class-const-declaration
+   method-declaration
 
-###Classes +### Traits
-  class-declaration:
-    class-modifieropt  class  name   class-base-clauseopt  class-interface-clauseopt   {   trait-use-clausesopt   class-member-declarationsopt }
-
-  class-modifier:
-    abstract
-    final
-
-  class-base-clause:
-    extends  qualified-name
-
-  class-interface-clause:
-    implements  qualified-name
-    class-interface-clause  ,  qualified-name
-
-  class-member-declarations:
-    class-member-declaration
-    class-member-declarations   class-member-declaration
-
-   class-member-declaration:
-     const-declaration
-     property-declaration
-     method-declaration
-     constructor-declaration
-     destructor-declaration
+trait-declaration:
+   trait   name   {   trait-member-declarationsopt   }
 
-  const-declaration:
-    const  name  =  constant-expression   ;
+trait-member-declarations:
+   trait-member-declaration
+   trait-member-declarations   trait-member-declaration
 
-  property-declaration:
-    property-modifier   variable-name   property-initializeropt  ;
+trait-member-declaration:
+   property-declaration
+   method-declaration
+   constructor-declaration
+   destructor-declaration
+   trait-use-clauses
 
-  property-modifier:
-    var
-    visibility-modifier   static-modifieropt
-    static-modifier   visibility-modifieropt
+trait-use-clauses:
+   trait-use-clause
+   trait-use-clauses   trait-use-clause
 
-  visibility-modifier:
-    public
-    protected
-    private
+trait-use-clause:
+   use   trait-name-list   trait-use-specification
 
-  static-modifier:
-    static
+trait-name-list:
+   qualified-name
+   trait-name-list   ,   qualified-name
 
-  property-initializer:
-    =  constant-expression
+trait-use-specification:
+   ;
+   {   trait-select-and-alias-clausesopt   }
 
-  method-declaration:
-    method-modifiersopt   function-definition
-    method-modifiers   function-definition-header  ;
+trait-select-and-alias-clauses:
+   trait-select-and-alias-clause
+   trait-select-and-alias-clauses   trait-select-and-alias-clause
 
-  method-modifiers:
-    method-modifier
-    method-modifiers   method-modifier
+trait-select-and-alias-clause:
+   trait-select-insteadof-clause   ;
+   trait-alias-as-clause   ;
 
-  method-modifier:
-    visibility-modifier
-    static-modifier
-	class-modifier
+trait-select-insteadof-clause:
+   qualified-name   ::   name   insteadof   trait-name-list
 
-  constructor-declaration:
-    method-modifiers  function &opt   __construct  (  parameter-declaration-listopt  )  compound-statement
-    method-modifiers  function &opt    name  (  parameter-declaration-listopt  )  compound-statement     [Deprecated form]
-
-  destructor-declaration:
-    method-modifiers  function  &opt  __destruct  ( ) compound-statement
-
-
- -###Interfaces - -
-  interface-declaration:
-    interface   name   interface-base-clauseopt {  interface-member-declarationsopt  }
-
-  interface-base-clause:
-    extends   qualified-name
-    interface-base-clause  ,  qualified-name
-
-  interface-member-declarations:
-    interface-member-declaration
-    interface-member-declarations   interface-member-declaration
-
-  interface-member-declaration:
-    const-declaration
-    method-declaration
+trait-alias-as-clause:
+   name   as   visibility-modifieropt   name
+   name   as   visibility-modifier   nameopt
 
-###Traits +### Namespaces
-  trait-declaration:
-    trait   name   {   trait-use-clausesopt   trait-member-declarationsopt   }
-
-  trait-use-clauses:
-    trait-use-clause
-    trait-use-clauses   trait-use-clause
+namespace-definition:
+   namespace   namespace-name   ;
+   namespace   namespace-nameopt   compound-statement
 
-  trait-use-clause:
-    use   trait-name-list   trait-use-specification
+namespace-use-declaration:
+   use   namespace-function-or-constopt   namespace-use-clauses   ;
+   use   namespace-function-or-const   \opt   namespace-name   \   {   namespace-use-group-clauses-1   }   ;
+   use   \opt   namespace-name   \   {   namespace-use-group-clauses-2   }   ;
 
-  trait-name-list:
-    qualified-name
-    trait-name-list   ,   qualified-name
+namespace-use-clauses:
+   namespace-use-clause
+   namespace-use-clauses   ,   namespace-use-clause
 
-  trait-use-specification:
-    ;
-    {   trait-select-and-alias-clausesopt   }
+namespace-use-clause:
+   qualified-name   namespace-aliasing-clauseopt
 
-  trait-select-and-alias-clauses:
-    trait-select-and-alias-clause
-    trait-select-and-alias-clauses   trait-select-and-alias-clause
-
-  trait-select-and-alias-clause:
-    trait-select-insteadof-clause ;
-    trait-alias-as-clause ;
-
-  trait-select-insteadof-clause:
-    name   insteadof   name
-
-  trait-alias-as-clause:
-    name   as   visibility-modifieropt   name
-    name   as   visibility-modifier   nameopt
-
-  trait-member-declarations:
-    trait-member-declaration
-    trait-member-declarations   trait-member-declaration
-
-  trait-member-declaration:
-    property-declaration
-    method-declaration
-    constructor-declaration
-    destructor-declaration
-
-
- -###Namespaces - -
-  namespace-definition:
-    namespace  name  ;
-    namespace  nameopt   compound-statement
+namespace-aliasing-clause:
+   as   name
 
-  namespace-use-declaration:
-    use  namespace-function-or-constopt namespace-use-clauses  ;
+namespace-function-or-const:
+   function
+   const
 
-  namespace-use-clauses:
-    namespace-use-clause
-    namespace-use-clauses  ,  namespace-use-clause
+namespace-use-group-clauses-1:
+   namespace-use-group-clause-1
+   namespace-use-group-clauses-1   ,   namespace-use-group-clause-1
 
-  namespace-use-clause:
-    qualified-name   namespace-aliasing-clauseopt
+namespace-use-group-clause-1:
+   namespace-name   namespace-aliasing-clauseopt
 
-  namespace-aliasing-clause:
-    as  name
+namespace-use-group-clauses-2:
+   namespace-use-group-clause-2
+   namespace-use-group-clauses-2   ,   namespace-use-group-clause-2
 
-  namespace-function-or-const:
-    function
-    const
+namespace-use-group-clause-2:
+   namespace-function-or-constopt   namespace-name   namespace-aliasing-clauseopt
 
diff --git a/spec/20-bibliography.md b/spec/20-bibliography.md index 80f56e0a..fb03bd87 100644 --- a/spec/20-bibliography.md +++ b/spec/20-bibliography.md @@ -1,4 +1,4 @@ -#Bibliography +# Bibliography The following documents are useful references for implementers and users of this specification: @@ -10,4 +10,3 @@ IEEE Standard for Binary Floating-Point Arithmetic). The Unicode Consortium. *The Unicode Standard, Version 5.0*, [www.Unicode.org](http://www.Unicode.org)). - diff --git a/spec/php-spec-draft.md b/spec/php-spec-draft.md deleted file mode 120000 index a7c2f5e4..00000000 --- a/spec/php-spec-draft.md +++ /dev/null @@ -1 +0,0 @@ -00-specification-for-php.md \ No newline at end of file diff --git a/tests/README.md b/tests/README.md index 0acf1371..f5e7e2ee 100644 --- a/tests/README.md +++ b/tests/README.md @@ -4,11 +4,6 @@ If you pass this suite, you aren't necessarily spec compliant, but it is a helpf ## Usage -To run using the PHP5 test runner, you'll need to convert to PHP5's .phpt format first. The following demonstrates writing the tests out to /tmp/phpt: +To run using the PHP test runner, do something like: - ./make_phpt . /tmp/phpt TEST_PHP_EXECUTABLE=~/php-src/sapi/cli/php ~/php-src/run-tests.php /tmp/phpt - -To use the HHVM test runner: - - ~/hhvm/hphp/test/run . diff --git a/tests/arrays/arrays.phpt b/tests/arrays/arrays.phpt index c164b46b..bbc3a29c 100644 --- a/tests/arrays/arrays.phpt +++ b/tests/arrays/arrays.phpt @@ -108,8 +108,8 @@ foreach($v as $e) // only has 3 elements ([3], [6], and [7]), not 8 ([0]-[7]) } echo "\n"; -echo "\$v[1] is >".$v[1]."<\n"; var_dump($v1[1]); // access non-existant element -echo "\$v[4] is >".$v[4]."<\n"; var_dump($v1[4]); // access non-existant element +echo "\$v[1] is >".$v[1]."<\n"; var_dump($v1[1]); // access non-existent element +echo "\$v[4] is >".$v[4]."<\n"; var_dump($v1[4]); // access non-existent element $v[1] = TRUE; // increases array to 4 elements $v[4] = 99; // increases array to 5 elements @@ -146,11 +146,11 @@ $v = array(FALSE => -4); // FALSE as key becomes key 0 var_dump($v); $v = array("" => -3); var_dump($v); -$v = array(INF => 21); // INF as key becomes key 0/IntMin/0 (imp-def?) +$v = array(INF => 21); // INF as key becomes key 0 var_dump($v); -$v = array(-INF => -1); // -INF as key becomes key 0/IntMin/IntMin (imp-def?) +$v = array(-INF => -1); // -INF as key becomes key 0 var_dump($v); -$v = array(NAN => 123); // NAN as key becomes key of IntMin/IntMin/IntMin (imp-def?) +$v = array(NAN => 123); // NAN as key becomes key of 0 var_dump($v); echo "================= arrays some of whose elements are arrays, and so on =================\n"; @@ -458,15 +458,15 @@ array(1) { int(-3) } array(1) { - [%i]=> + [0]=> int(21) } array(1) { - [%i]=> + [0]=> int(-1) } array(1) { - [%i]=> + [0]=> int(123) } ================= arrays some of whose elements are arrays, and so on ================= diff --git a/tests/basic_concepts/memory_model_and_array_types.phpt b/tests/basic_concepts/memory_model_and_array_types.phpt index 30a53cec..968dd79a 100644 --- a/tests/basic_concepts/memory_model_and_array_types.phpt +++ b/tests/basic_concepts/memory_model_and_array_types.phpt @@ -11,19 +11,19 @@ PHP Spec test generated from ./basic_concepts/memory_model_and_array_types.php error_reporting(-1); -class Point +class Point { private static $pointCount = 0; private $x; private $y; - public static function getPointCount() + public static function getPointCount() { return self::$pointCount; } - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; @@ -32,26 +32,26 @@ class Point echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n"; } - public function move($x, $y) + public function move($x, $y) { $this->x = $x; $this->y = $y; - } + } - public function translate($x, $y) + public function translate($x, $y) { $this->x += $x; $this->y += $y; } - public function __destruct() + public function __destruct() { --self::$pointCount; echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n"; } ///* - public function __clone() + public function __clone() { ++self::$pointCount; @@ -59,10 +59,10 @@ class Point } //*/ - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; - } + } } ///* @@ -489,4 +489,4 @@ after unset($a[1]), $x is 123, $a is array(1) { Inside Point::__destruct, (1,3), point count = 0 -after unset($a), $x is 123, $a is undefined \ No newline at end of file +after unset($a), $x is 123, $a is undefined diff --git a/tests/basic_concepts/memory_model_and_handle_types.phpt b/tests/basic_concepts/memory_model_and_handle_types.phpt index 1ba48832..f4f497f3 100644 --- a/tests/basic_concepts/memory_model_and_handle_types.phpt +++ b/tests/basic_concepts/memory_model_and_handle_types.phpt @@ -11,19 +11,19 @@ PHP Spec test generated from ./basic_concepts/memory_model_and_handle_types.php error_reporting(-1); -class Point +class Point { private static $pointCount = 0; private $x; private $y; - public static function getPointCount() + public static function getPointCount() { return self::$pointCount; } - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; @@ -32,26 +32,26 @@ class Point echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n"; } - public function move($x, $y) + public function move($x, $y) { $this->x = $x; $this->y = $y; - } + } - public function translate($x, $y) + public function translate($x, $y) { $this->x += $x; $this->y += $y; } - public function __destruct() + public function __destruct() { --self::$pointCount; echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n"; } ///* - public function __clone() + public function __clone() { ++self::$pointCount; @@ -59,10 +59,10 @@ class Point } //*/ - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; - } + } } ///* @@ -135,7 +135,7 @@ function f1($b) // pass-by-value creates second alias to first point $b->move(4, 6); // moving $b also moves $a echo "After '\$b->move(4, 6)', \$b is $b\n"; - $b = new Point(5, 7); // removes second alias from first point; + $b = new Point(5, 7); // removes second alias from first point; // then create first alias to second new point echo "After 'new Point(5, 7)', \$b is $b\n"; @@ -163,10 +163,10 @@ function g1(&$b) // make $b alias whatever $a aliases $b->move(4, 6); // moving $b also moves $a echo "After '\$b->move(4, 6)', \$b is $b\n"; - $b = new Point(5, 7); // removes second alias from first point; + $b = new Point(5, 7); // removes second alias from first point; // then create first alias to second new point // changing $b also changes $a as well, so $a's alias - // is also removed, alowing the destructor run + // is also removed, allowing the destructor run echo "After 'new Point(5, 7)', \$b is $b\n"; } // $b goes away, remove its alias from new point @@ -229,7 +229,7 @@ class C public $prop1; public $prop2; - public function __destruct() + public function __destruct() { echo "\nInside " . __METHOD__ . "\n\n"; } diff --git a/tests/basic_concepts/memory_model_and_resources.phpt b/tests/basic_concepts/memory_model_and_resources.phpt index 43b1ad61..d3e1ae66 100644 --- a/tests/basic_concepts/memory_model_and_resources.phpt +++ b/tests/basic_concepts/memory_model_and_resources.phpt @@ -159,4 +159,4 @@ Done ----------------- resource byRef returning ---------------------- After '$b = STDOUT', $b is Resource id #2 After '$a = f2()', $a is Resource id #2 -Done \ No newline at end of file +Done diff --git a/tests/basic_concepts/storage_duration.phpt b/tests/basic_concepts/storage_duration.phpt index 50ada557..d582314c 100644 --- a/tests/basic_concepts/storage_duration.phpt +++ b/tests/basic_concepts/storage_duration.phpt @@ -18,51 +18,51 @@ class Point private $x; private $y; - public static function getPointCount() - { - return self::$pointCount; - } + public static function getPointCount() + { + return self::$pointCount; + } - public function __construct($x = 0, $y = 0) - { - $this->x = $x; - $this->y = $y; - ++self::$pointCount; + public function __construct($x = 0, $y = 0) + { + $this->x = $x; + $this->y = $y; + ++self::$pointCount; echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n"; } - public function move($x, $y) - { - $this->x = $x; - $this->y = $y; - } + public function move($x, $y) + { + $this->x = $x; + $this->y = $y; + } - public function translate($x, $y) - { - $this->x += $x; - $this->y += $y; - } + public function translate($x, $y) + { + $this->x += $x; + $this->y += $y; + } - public function __destruct() - { - --self::$pointCount; + public function __destruct() + { + --self::$pointCount; echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n"; } ///* - public function __clone() - { - ++self::$pointCount; + public function __clone() + { + ++self::$pointCount; echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n"; } //*/ - public function __toString() - { - return '(' . $this->x . ',' . $this->y . ')'; - } + public function __toString() + { + return '(' . $this->x . ',' . $this->y . ')'; + } } echo "---------------- start -------------------\n"; diff --git a/tests/classes/Aircraft.inc b/tests/classes/Aircraft.inc index 5454f2ec..e49fb8bf 100644 --- a/tests/classes/Aircraft.inc +++ b/tests/classes/Aircraft.inc @@ -10,7 +10,7 @@ error_reporting(-1); include_once 'Vehicle.inc'; -abstract class Aircraft extends Vehicle +abstract class Aircraft extends Vehicle { public abstract function getMaxAltitude(); // ... diff --git a/tests/classes/MathLibrary.inc b/tests/classes/MathLibrary.inc index 9df2b866..7d5d4b4d 100644 --- a/tests/classes/MathLibrary.inc +++ b/tests/classes/MathLibrary.inc @@ -8,9 +8,9 @@ error_reporting(-1); -final class MathLibrary +final class MathLibrary { - private function MathLibrary() {} // disallows instantiation + private function __construct() {} // disallows instantiation public static function sin() { /* ... */ } public static function cos() { /* ... */ } diff --git a/tests/classes/MyCollection.inc b/tests/classes/MyCollection.inc index e9208ded..c15f32cc 100644 --- a/tests/classes/MyCollection.inc +++ b/tests/classes/MyCollection.inc @@ -8,7 +8,7 @@ error_reporting(-1); -interface MyCollection +interface MyCollection { function put($item); function get(); diff --git a/tests/classes/PassengerJet.inc b/tests/classes/PassengerJet.inc index 7d7130f9..5d830351 100644 --- a/tests/classes/PassengerJet.inc +++ b/tests/classes/PassengerJet.inc @@ -10,7 +10,7 @@ error_reporting(-1); include_once 'Aircraft.inc'; -class PassengerJet extends Aircraft +class PassengerJet extends Aircraft { public function getMaxSpeed() { diff --git a/tests/classes/Point.inc b/tests/classes/Point.inc index f62c6596..2942d85d 100644 --- a/tests/classes/Point.inc +++ b/tests/classes/Point.inc @@ -8,7 +8,7 @@ error_reporting(-1); -class Point +class Point { private $x; // Cartesian x-coordinate private $y; // Cartesian y-coordinate @@ -19,28 +19,28 @@ class Point public function setY($y) { $this->y = $y; } // public function __construct($x, $y) // see what happens if no default values - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; } - public function move($x, $y) + public function move($x, $y) { $this->x = $x; $this->y = $y; - } + } - public function translate($x, $y) + public function translate($x, $y) { $this->x += $x; $this->y += $y; } - public function __toString() + public function __toString() { // throw new Exception; // throw statement is not permitted return '(' . $this->x . ',' . $this->y . ')'; - } + } } diff --git a/tests/classes/Point2.inc b/tests/classes/Point2.inc index 29e1da60..59ded534 100644 --- a/tests/classes/Point2.inc +++ b/tests/classes/Point2.inc @@ -8,31 +8,31 @@ error_reporting(-1); -class Point2 +class Point2 { private static $pointCount = 0; public $x; // Cartesian x-coordinate public $y; // Cartesian y-coordinate - public static function getPointCount() + public static function getPointCount() { return self::$pointCount; } - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; ++self::$pointCount; } - public function __destruct() + public function __destruct() { --self::$pointCount; } ///* - public function __clone() + public function __clone() { ++self::$pointCount; @@ -43,9 +43,9 @@ class Point2 } //*/ - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; - } + } } diff --git a/tests/classes/Vehicle.inc b/tests/classes/Vehicle.inc index 9250c5a7..db9e69ef 100644 --- a/tests/classes/Vehicle.inc +++ b/tests/classes/Vehicle.inc @@ -8,7 +8,7 @@ error_reporting(-1); -abstract class Vehicle +abstract class Vehicle { public abstract function getMaxSpeed(); diff --git a/tests/classes/__gets_return_type.phpt b/tests/classes/__gets_return_type.phpt index 0f27580e..b69fb715 100644 --- a/tests/classes/__gets_return_type.phpt +++ b/tests/classes/__gets_return_type.phpt @@ -53,4 +53,4 @@ object(C)#2 (1) { [0]=> int(1) } -} \ No newline at end of file +} diff --git a/tests/classes/__php_incomplete_class.phpt b/tests/classes/__php_incomplete_class.phpt index e55c431f..63db08e8 100644 Binary files a/tests/classes/__php_incomplete_class.phpt and b/tests/classes/__php_incomplete_class.phpt differ diff --git a/tests/classes/classes.phpt b/tests/classes/classes.phpt index 3f5c27a4..a32ae5f6 100644 --- a/tests/classes/classes.phpt +++ b/tests/classes/classes.phpt @@ -20,4 +20,4 @@ $c = new C2; var_dump($c); --EXPECT-- object(C2)#1 (0) { -} \ No newline at end of file +} diff --git a/tests/classes/cloning.phpt b/tests/classes/cloning.phpt index 680e790e..ce2256ce 100644 --- a/tests/classes/cloning.phpt +++ b/tests/classes/cloning.phpt @@ -58,7 +58,7 @@ echo "Point count = " . Point2::getPointCount() . "\n"; var_dump($p4 = clone $p1); echo "Point count = " . Point2::getPointCount() . "\n"; -echo "================= use chained cloning in a class heirarchy =================\n"; +echo "================= use chained cloning in a class hierarchy =================\n"; class Employee { @@ -154,7 +154,7 @@ object(Point2)#6 (2) { int(0) } Point count = 4 -================= use chained cloning in a class heirarchy ================= +================= use chained cloning in a class hierarchy ================= object(Manager)#7 (2) { ["level":"Manager":private]=> int(23) @@ -170,4 +170,4 @@ object(Manager)#8 (2) { int(23) ["name":"Employee":private]=> string(5) "Smith" -} \ No newline at end of file +} diff --git a/tests/classes/constructors.phpt b/tests/classes/constructors.phpt index b097ec0b..a1d042ab 100644 --- a/tests/classes/constructors.phpt +++ b/tests/classes/constructors.phpt @@ -73,4 +73,4 @@ In D1 constructor, 1 int(123) In D2 constructor, 1, 2 In D3 constructor, 1, 2, 3 -In D4 constructor \ No newline at end of file +In D4 constructor diff --git a/tests/classes/dynamic_methods.phpt b/tests/classes/dynamic_methods.phpt index 6e1d2f70..002497ec 100644 --- a/tests/classes/dynamic_methods.phpt +++ b/tests/classes/dynamic_methods.phpt @@ -50,7 +50,7 @@ $obj = new Widget; $v = $obj->iDoit(); $obj->__call('iDoit', []); -$v = $obj->iMethod(10, TRUE, "abc"); +$v = $obj->iMethod(10, TRUE, "abc",); var_dump($v); $obj->__call('iMethod', array(10, TRUE, "abc")); $obj->__call('123#$%', []); @@ -58,7 +58,7 @@ $obj->__call('123#$%', []); $v = Widget::sDoit(); Widget::__callStatic('sDoit', []); -$v = Widget::sMethod(NULL, 1.234); +$v = Widget::sMethod(NULL, 1.234,); var_dump($v); Widget::__callStatic('sMethod', array(NULL, 1.234)); Widget::__callStatic('[]{}', []); @@ -110,4 +110,4 @@ array(2) { } Calling static method >[]{}< array(0) { -} \ No newline at end of file +} diff --git a/tests/classes/dynamic_properties.phpt b/tests/classes/dynamic_properties.phpt index 48fe32a5..67483732 100644 --- a/tests/classes/dynamic_properties.phpt +++ b/tests/classes/dynamic_properties.phpt @@ -11,7 +11,7 @@ PHP Spec test generated from ./classes/dynamic_properties.php error_reporting(-1); -class Point +class Point { private $x; private $y; @@ -19,7 +19,7 @@ class Point public $dummy = -100; // for test purposes only - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; @@ -138,7 +138,7 @@ unset($p->dummy); // request to unset a declared accessible is OK var_dump(isset($p->dummy)); var_dump(isset($p->color)); -unset($p->color); // +unset($p->color); // var_dump(isset($p->color)); echo "----------------------\n"; @@ -327,4 +327,4 @@ key p8 has a value of 999 key p9 has a value of 999 key p10 has a value of 999 ---------------------- -X::__destruct \ No newline at end of file +X::__destruct diff --git a/tests/classes/dynamic_properties2.phpt b/tests/classes/dynamic_properties2.phpt index a60b35c2..960b8958 100644 --- a/tests/classes/dynamic_properties2.phpt +++ b/tests/classes/dynamic_properties2.phpt @@ -20,4 +20,4 @@ unset($p->color); // remove the property "color" bool(false) Notice: Undefined property: Point::$color in %s/classes/dynamic_properties2.php on line 9 -NULL \ No newline at end of file +NULL diff --git a/tests/classes/dynamic_properties3.phpt b/tests/classes/dynamic_properties3.phpt index 19b54525..282e65dc 100644 --- a/tests/classes/dynamic_properties3.phpt +++ b/tests/classes/dynamic_properties3.phpt @@ -27,7 +27,7 @@ class C echo "isset\n"; return isset($this->$name); // must not recurse } - + public function __unset($name) { echo "unset\n"; unset($this->$name); // must not recurse @@ -49,4 +49,4 @@ int(123) object(C)#1 (1) { ["prop"]=> int(123) -} \ No newline at end of file +} diff --git a/tests/classes/invoke.phpt b/tests/classes/invoke.phpt index f5d5f37f..36222460 100644 --- a/tests/classes/invoke.phpt +++ b/tests/classes/invoke.phpt @@ -34,4 +34,4 @@ bool(true) Inside C::__invoke with arg 123 string(3) "xxx" Inside C::__invoke with arg Hello -string(3) "xxx" \ No newline at end of file +string(3) "xxx" diff --git a/tests/classes/invoking.phpt b/tests/classes/invoking.phpt index 95d6ac31..20c2e23c 100644 --- a/tests/classes/invoking.phpt +++ b/tests/classes/invoking.phpt @@ -29,4 +29,4 @@ bool(true) Inside C::__invoke with arg 123 string(3) "xxx" Inside C::__invoke with arg Hello -string(3) "xxx" \ No newline at end of file +string(3) "xxx" diff --git a/tests/classes/overloading.phpt b/tests/classes/overloading.phpt index 1a339487..ae02451c 100644 --- a/tests/classes/overloading.phpt +++ b/tests/classes/overloading.phpt @@ -5,7 +5,7 @@ PHP Spec test generated from ./classes/overloading.php error_reporting(-1); -class Point +class Point { private $x; private $y; @@ -13,7 +13,7 @@ class Point public $dummy = -100; // for test purposes only - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; @@ -128,7 +128,7 @@ unset($p->dummy); // request to unset a declared accessible is OK var_dump(isset($p->dummy)); var_dump(isset($p->color)); -unset($p->color); // +unset($p->color); // var_dump(isset($p->color)); echo "----------------------\n"; @@ -215,4 +215,4 @@ Point::__set(thing, xx) Point::__get(thing) object(X)#2 (0) { } -X::__destruct \ No newline at end of file +X::__destruct diff --git a/tests/classes/overloading_2.phpt b/tests/classes/overloading_2.phpt index 46587c02..44a38826 100644 --- a/tests/classes/overloading_2.phpt +++ b/tests/classes/overloading_2.phpt @@ -20,4 +20,4 @@ unset($p->color); // remove the property "color" bool(false) Notice: Undefined property: Point::$color in %s/classes/overloading_2.php on line 9 -NULL \ No newline at end of file +NULL diff --git a/tests/classes/overloading_methods.phpt b/tests/classes/overloading_methods.phpt index eb39e1a1..9f1008f0 100644 --- a/tests/classes/overloading_methods.phpt +++ b/tests/classes/overloading_methods.phpt @@ -105,4 +105,4 @@ array(2) { } Calling static method >[]{}< array(0) { -} \ No newline at end of file +} diff --git a/tests/classes/overloading_play.phpt b/tests/classes/overloading_play.phpt index 417e34aa..6bc2ba66 100644 --- a/tests/classes/overloading_play.phpt +++ b/tests/classes/overloading_play.phpt @@ -78,7 +78,7 @@ var_dump($v); echo "----------------------\n"; -var_dump(isset($obj->hidden)); // test if hidden exists and is accesible, or is dynamic +var_dump(isset($obj->hidden)); // test if hidden exists and is accessible, or is dynamic echo "----------------------\n"; @@ -88,7 +88,7 @@ echo "hidden: $v\n"; echo "----------------------\n"; -var_dump(isset($obj->hidden)); // test if hidden exists and is accesible, or is dynamic +var_dump(isset($obj->hidden)); // test if hidden exists and is accessible, or is dynamic echo "----------------------\n"; diff --git a/tests/classes/overloading_properties.phpt b/tests/classes/overloading_properties.phpt index 20d4e2e7..08fcc073 100644 --- a/tests/classes/overloading_properties.phpt +++ b/tests/classes/overloading_properties.phpt @@ -5,7 +5,7 @@ PHP Spec test generated from ./classes/overloading_properties.php error_reporting(-1); -class Point +class Point { private $x; private $y; @@ -13,7 +13,7 @@ class Point public $dummy = -100; // for test purposes only - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; @@ -132,7 +132,7 @@ unset($p->dummy); // request to unset a declared accessible is OK var_dump(isset($p->dummy)); var_dump(isset($p->color)); -unset($p->color); // +unset($p->color); // var_dump(isset($p->color)); echo "----------------------\n"; @@ -222,4 +222,4 @@ Point::__set(thing, xx) Point::__get(thing) object(X)#2 (0) { } -X::__destruct \ No newline at end of file +X::__destruct diff --git a/tests/classes/overloading_properties2.phpt b/tests/classes/overloading_properties2.phpt index 1ba8e640..32d69702 100644 --- a/tests/classes/overloading_properties2.phpt +++ b/tests/classes/overloading_properties2.phpt @@ -20,4 +20,4 @@ unset($p->color); // remove the property "color" bool(false) Notice: Undefined property: Point::$color in %s/classes/overloading_properties2.php on line 9 -NULL \ No newline at end of file +NULL diff --git a/tests/classes/point2_test1.phpt b/tests/classes/point2_test1.phpt index 7ba9dc02..fc2db3d2 100644 --- a/tests/classes/point2_test1.phpt +++ b/tests/classes/point2_test1.phpt @@ -22,4 +22,4 @@ $cName = 'Point2'; echo "Point count = " . $cName::getPointCount() . "\n"; --EXPECT-- Point count = 3 -Point count = 3 \ No newline at end of file +Point count = 3 diff --git a/tests/classes/property_initializer.phpt b/tests/classes/property_initializer.phpt index 46f02a60..8837354a 100644 --- a/tests/classes/property_initializer.phpt +++ b/tests/classes/property_initializer.phpt @@ -23,10 +23,10 @@ class Point $this->y = $y; } - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; - } + } } $p = new Point; @@ -35,7 +35,7 @@ echo $p . "\n"; $p = new Point(); echo $p . "\n"; -$p = new Point(100); +$p = new Point(100,); echo $p . "\n"; $p = new Point(1000, 2000); @@ -46,7 +46,7 @@ echo "--------------------\n"; function f() { return 10; } -class X +class X { // const Cprop1 = 10 + 12 - 5.6; // invalid // const Cprop2 = f(); // invalid @@ -77,4 +77,4 @@ var_dump(X::$q2); (1000,2000) -------------------- NULL -NULL \ No newline at end of file +NULL diff --git a/tests/classes/serializable.phpt b/tests/classes/serializable.phpt index 12499849..859f24a6 100644 --- a/tests/classes/serializable.phpt +++ b/tests/classes/serializable.phpt @@ -19,7 +19,7 @@ class Point implements Serializable private $y; private $id; - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; @@ -28,18 +28,18 @@ class Point implements Serializable echo "\nInside " . __METHOD__ . ", $this\n\n"; } - public function __toString() + public function __toString() { return 'ID:' . $this->id . '(' . $this->x . ',' . $this->y . ')'; - } + } - public function serialize() + public function serialize() { echo "\nInside " . __METHOD__ . ", $this\n\n"; - + return serialize(array('y' => $this->y, 'x' => $this->x)); } - + public function unserialize($data) { $data = unserialize($data); @@ -73,7 +73,7 @@ class ColoredPoint extends Point implements Serializable private $color; - public function __construct($x = 0, $y = 0, $color = RED) + public function __construct($x = 0, $y = 0, $color = RED) { parent::__construct($x, $y); $this->color = $color; @@ -81,21 +81,21 @@ class ColoredPoint extends Point implements Serializable echo "\nInside " . __METHOD__ . ", $this\n\n"; } - public function __toString() + public function __toString() { return parent::__toString() . $this->color; - } + } - public function serialize() + public function serialize() { echo "\nInside " . __METHOD__ . ", $this\n\n"; - + return serialize(array( 'color' => $this->color, 'baseData' => parent::serialize() )); } - + public function unserialize($data) { $data = unserialize($data); @@ -172,4 +172,4 @@ object(ColoredPoint)#4 (4) { ["id":"Point":private]=> int(4) } ----------------- end ------------------- \ No newline at end of file +---------------- end ------------------- diff --git a/tests/classes/setting_state.phpt b/tests/classes/setting_state.phpt index 3d6537fb..f6262044 100644 --- a/tests/classes/setting_state.phpt +++ b/tests/classes/setting_state.phpt @@ -11,7 +11,7 @@ PHP Spec test generated from ./classes/setting_state.php error_reporting(-1); -class Point +class Point { private static $pointCount = 0; @@ -22,12 +22,12 @@ class Point protected $proti; public $pubi; - public static function getPointCount() + public static function getPointCount() { return self::$pointCount; } - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; @@ -36,26 +36,26 @@ class Point echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n"; } - public function move($x, $y) + public function move($x, $y) { $this->x = $x; $this->y = $y; } - public function translate($x, $y) + public function translate($x, $y) { $this->x += $x; $this->y += $y; } - public function __destruct() + public function __destruct() { --self::$pointCount; echo "\nInside " . __METHOD__ . ", $this, point count = " . self::$pointCount . "\n\n"; } ///* - public function __clone() + public function __clone() { ++self::$pointCount; @@ -63,7 +63,7 @@ class Point } //*/ - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; } diff --git a/tests/classes/sleep_and_wakeup.phpt b/tests/classes/sleep_and_wakeup.phpt index 65ded473..6c1d5dc4 100644 Binary files a/tests/classes/sleep_and_wakeup.phpt and b/tests/classes/sleep_and_wakeup.phpt differ diff --git a/tests/classes/vehicle_test1.phpt b/tests/classes/vehicle_test1.phpt index 4751c89f..2d2cb757 100644 --- a/tests/classes/vehicle_test1.phpt +++ b/tests/classes/vehicle_test1.phpt @@ -21,4 +21,4 @@ echo "\$pj's maximum speed: " . $pj->getMaxSpeed() . "\n"; echo "\$pj's maximum altitude: " . $pj->getMaxAltitude() . "\n"; --EXPECT-- $pj's maximum speed: 550 -$pj's maximum altitude: 30000 \ No newline at end of file +$pj's maximum altitude: 30000 diff --git a/tests/classes/visibility.phpt b/tests/classes/visibility.phpt index 49f5cae3..4b483652 100644 --- a/tests/classes/visibility.phpt +++ b/tests/classes/visibility.phpt @@ -15,10 +15,12 @@ class C { // constants - const CON1 = 123; // implicitly static, and can't say so explicitly -// public const CON2 = 123; // class constants are implicitly public; can't say explicitly -// protected const CON3 = 123; // class constants are implicitly public -// private const CON4 = 123; // class constants are implicitly public + const CON1 = 123; // implicitly static and can't say so explicitly + // implicitly public + + public const CON2 = 123; // explicitly public + protected const CON3 = 123; // protected constant + private const CON4 = 123; // private constant // properties diff --git a/tests/constants/classes.phpt b/tests/constants/classes.phpt index ad69e134..f7b80468 100644 --- a/tests/constants/classes.phpt +++ b/tests/constants/classes.phpt @@ -8,7 +8,7 @@ error_reporting(-1); /* abstract class AC {} -new AC; // Cannot instantiate abstract class AC +new AC; // Cannot instantiate abstract class AC */ interface i1 {} @@ -20,4 +20,4 @@ $c = new C2; var_dump($c); --EXPECT-- object(C2)#1 (0) { -} \ No newline at end of file +} diff --git a/tests/constants/constants.phpt b/tests/constants/constants.phpt index 7ebde661..23f3324b 100644 --- a/tests/constants/constants.phpt +++ b/tests/constants/constants.phpt @@ -11,9 +11,9 @@ PHP Spec test generated from ./constants/constants.php error_reporting(-1); -function trace($name, $value, $b = FALSE) +function trace($name, $value) { - $r = define($name, $value, $b); + $r = define($name, $value); echo "define $name " . ($r ? "succeeded" : "failed"); if (defined($name)) echo "; value is >" . constant($name) . "<\n"; @@ -22,18 +22,18 @@ function trace($name, $value, $b = FALSE) } ///* -// define some constants with simple (single-token) scalar initial values +// define some constants with simple (single-token) scalar initial values trace("STATUS1", TRUE); trace("MIN", 10); -trace("MAX", 20, TRUE); // HHVM Warning: Case insensitive constant names are not supported in HipHop +trace("MAX", 20); trace("MY_PI", 3.1415926); trace("MY_COLOR", "red"); trace("C1", NULL); //*/ ///* -// try to define some constants with multiple-token scalar initial values +// try to define some constants with multiple-token scalar initial values // involving literals only @@ -83,12 +83,12 @@ echo " TRUE's value:" . TRUE . "\n"; // however, this shows the old value, 1 //*/ ///* -// try to define some constants with non-scalar initial values +// try to define some constants with non-scalar initial values -trace("COLORS", [10, 20]); // Constants may only evaluate to scalar values +trace("COLORS", [10, 20]); // Works from PHP 7 onwards class C {} -trace("MY_OBJECT", new C); // Constants may only evaluate to scalar values +trace("MY_OBJECT", new C); // Constants may only evaluate to scalar values or arrays $infile = fopen("Testfile.txt", 'r'); if ($infile == FALSE) @@ -120,8 +120,8 @@ class MyClass ///* // Note: As opposed to defining constants using define(), constants defined using the -// const keyword must be declared at the top-level scope because they are defined at -// compile-time. This means that they cannot be declared inside functions, loops or +// const keyword must be declared at the top-level scope because they are defined at +// compile-time. This means that they cannot be declared inside functions, loops or // if statements. // const CON50; // not permitted; OK @@ -149,7 +149,7 @@ function f($p) // const CON71A = 101; // unexpected 'const' trace("CON71B", 101); // succeeded } -} +} f(10); //*/ @@ -165,14 +165,21 @@ trace("FOR", 100); // succeeded class C3 { - const CON1 = 123; // implicitly static, and can't say so explicitly -// public const CON2 = 123; // all class constants are implicitly public; can't say explicitly -// protected const CON3 = 123; // all class constants are implicitly public -// private const CON4 = 123; // all class constants are implicitly public + + const CON1 = 123; // implicitly static and can't say so explicitly + // implicitly public + + public const CON2 = 123; // explicitly public + protected const CON3 = 123; // protected constant + private const CON4 = 123; // private constant } echo "CON1: " . C3::CON1 . "\n"; // use :: notation, as a const is implicitly static +// public const CON80 = 80; // top level const can not have visibility modifier +// protected const CON81 = 81; // top level const can not have visibility modifier +// private const CON82 = 82; // top level const can not have visibility modifier + //print_r(get_defined_constants()); --EXPECTF-- define STATUS1 succeeded; value is >1< @@ -199,13 +206,15 @@ define #%& succeeded; value is >200< Notice: Constant MY_COLOR already defined in %s/constants/constants.php on line 13 define MY_COLOR failed; value is >red< -define TRUE succeeded; value is >999< - TRUE's value:1 -Warning: Constants may only evaluate to scalar values in %s/constants/constants.php on line 13 -define COLORS failed; not defined +Notice: Constant TRUE already defined in %s/constants/constants.php on line 13 +define TRUE failed; value is >1< + TRUE's value:1 +define COLORS succeeded +Notice: Array to string conversion in %s/constants/constants.php on line 16 +; value is >Array< -Warning: Constants may only evaluate to scalar values in %s/constants/constants.php on line 13 +Warning: Constants may only evaluate to scalar values, arrays or resources in %s/constants/constants.php on line 13 define MY_OBJECT failed; not defined Warning: fopen(Testfile.txt): failed to open stream: No such file or directory in %s/constants/constants.php on line 90 diff --git a/tests/exception_handling/MyRangeException.inc b/tests/exception_handling/MyRangeException.inc index feb0468b..e17c820b 100644 --- a/tests/exception_handling/MyRangeException.inc +++ b/tests/exception_handling/MyRangeException.inc @@ -8,7 +8,7 @@ error_reporting(-1); -class MyRangeException extends Exception +class MyRangeException extends Exception { private $badValue; private $lowerValue; @@ -27,7 +27,7 @@ class MyRangeException extends Exception public function getLowerValue() { return $this->lowerValue; } public function getUpperValue() { return $this->upperValue; } - public function __toString() + public function __toString() { return parent::__toString() . ", badValue: " . $this->badValue diff --git a/tests/exception_handling/exception_class.phpt b/tests/exception_handling/exception_class.phpt index d3559896..95f38ee0 100644 --- a/tests/exception_handling/exception_class.phpt +++ b/tests/exception_handling/exception_class.phpt @@ -145,7 +145,7 @@ fL1(10); --EXPECTF-- L0: In try-block L0: In catch-block -$e = >exception 'Exception' with message 'L0 Message' in %s/exception_handling/exception_class.php:127 +$e = >Exception: L0 Message in %s/exception_handling/exception_class.php:127 Stack trace: #0 {main}< getMessage: >L0 Message< @@ -163,7 +163,7 @@ L0: Beyond try/catch/finally blocks L0: Calling fL1 fL1: In try-block fL1: In catch-block -$e = >exception 'Exception' with message 'fL1 Message' in %s/exception_handling/exception_class.php:55 +$e = >Exception: fL1 Message in %s/exception_handling/exception_class.php:55 Stack trace: #0 %s/exception_handling/exception_class.php(140): fL1(10) #1 {main}< @@ -186,7 +186,7 @@ array(1) { ["args"]=> array(1) { [0]=> - &int(10) + %Sint(10) } } } @@ -203,7 +203,7 @@ fL1: Beyond try/catch/finally blocks fL1: Calling fL2 fL2: In try-block fL2: In catch-block -$e = >exception 'Exception' with message 'fL2 Message' in %s/exception_handling/exception_class.php:81 +$e = >Exception: fL2 Message in %s/exception_handling/exception_class.php:81 Stack trace: #0 %s/exception_handling/exception_class.php(69): fL2(2.3, -4.5) #1 %s/exception_handling/exception_class.php(140): fL1(10) @@ -228,9 +228,9 @@ array(2) { ["args"]=> array(2) { [0]=> - &float(2.3) + %Sfloat(2.3) [1]=> - &float(-4.5) + %Sfloat(-4.5) } } [1]=> @@ -244,7 +244,7 @@ array(2) { ["args"]=> array(1) { [0]=> - &int(10) + %Sint(10) } } } @@ -268,7 +268,7 @@ fL2: Beyond try/catch/finally blocks fL2: Calling fL3 fL3: In try-block fL3: In catch-block -$e = >exception 'Exception' with message 'fL3 Message' in %s/exception_handling/exception_class.php:107 +$e = >Exception: fL3 Message in %s/exception_handling/exception_class.php:107 Stack trace: #0 %s/exception_handling/exception_class.php(95): fL3('xyz', NULL, true) #1 %s/exception_handling/exception_class.php(69): fL2(2.3, -4.5) @@ -295,11 +295,11 @@ array(3) { ["args"]=> array(3) { [0]=> - &string(3) "xyz" + %Sstring(3) "xyz" [1]=> - &NULL + %SNULL [2]=> - &bool(true) + %Sbool(true) } } [1]=> @@ -313,9 +313,9 @@ array(3) { ["args"]=> array(2) { [0]=> - &float(2.3) + %Sfloat(2.3) [1]=> - &float(-4.5) + %Sfloat(-4.5) } } [2]=> @@ -329,7 +329,7 @@ array(3) { ["args"]=> array(1) { [0]=> - &int(10) + %Sint(10) } } } diff --git a/tests/exception_handling/exception_class_experiment_1.phpt b/tests/exception_handling/exception_class_experiment_1.phpt index bd7d7a7c..62ae23a8 100644 --- a/tests/exception_handling/exception_class_experiment_1.phpt +++ b/tests/exception_handling/exception_class_experiment_1.phpt @@ -11,7 +11,7 @@ PHP Spec test generated from ./exception_handling/exception_class_experiment_1.p error_reporting(-1); -// trying to see if the supposed initial value for $message in Exception +// trying to see if the supposed initial value for $message in Exception // ('Unknown exception') is ever used. I can;t get it to appear. // If I construct a Exception, the passed-in or default "" gets used. If I subclass // Exception, whether I define a constructor for that class or not, the base @@ -19,7 +19,7 @@ error_reporting(-1); class MyEx extends Exception { - public function __construct() {} // does nothing; possibly the superclass's + public function __construct() {} // does nothing; possibly the superclass's // constructor isn't called implicitly either } @@ -157,7 +157,7 @@ fL1(10); --EXPECTF-- L0: In try-block L0: In catch-block -$e = >exception 'Exception' with message 'L0 Message' in %s/exception_handling/exception_class_experiment_1.php:139 +$e = >Exception: L0 Message in %s/exception_handling/exception_class_experiment_1.php:139 Stack trace: #0 {main}< getMessage: >L0 Message< @@ -175,7 +175,7 @@ L0: Beyond try/catch/finally blocks L0: Calling fL1 fL1: In try-block fL1: In catch-block -$e = >exception 'MyEx' in %s/exception_handling/exception_class_experiment_1.php:66 +$e = >MyEx in %s/exception_handling/exception_class_experiment_1.php:66 Stack trace: #0 %s/exception_handling/exception_class_experiment_1.php(152): fL1(10) #1 {main}< @@ -198,7 +198,7 @@ array(1) { ["args"]=> array(1) { [0]=> - &int(10) + int(10) } } } @@ -215,7 +215,7 @@ fL1: Beyond try/catch/finally blocks fL1: Calling fL2 fL2: In try-block fL2: In catch-block -$e = >exception 'Exception' with message 'fL2 Message' in %s/exception_handling/exception_class_experiment_1.php:93 +$e = >Exception: fL2 Message in %s/exception_handling/exception_class_experiment_1.php:93 Stack trace: #0 %s/exception_handling/exception_class_experiment_1.php(81): fL2(2.3, -4.5) #1 %s/exception_handling/exception_class_experiment_1.php(152): fL1(10) @@ -240,9 +240,9 @@ array(2) { ["args"]=> array(2) { [0]=> - &float(2.3) + float(2.3) [1]=> - &float(-4.5) + float(-4.5) } } [1]=> @@ -256,7 +256,7 @@ array(2) { ["args"]=> array(1) { [0]=> - &int(10) + int(10) } } } @@ -280,7 +280,7 @@ fL2: Beyond try/catch/finally blocks fL2: Calling fL3 fL3: In try-block fL3: In catch-block -$e = >exception 'Exception' with message 'fL3 Message' in %s/exception_handling/exception_class_experiment_1.php:119 +$e = >Exception: fL3 Message in %s/exception_handling/exception_class_experiment_1.php:119 Stack trace: #0 %s/exception_handling/exception_class_experiment_1.php(107): fL3('xyz', NULL, true) #1 %s/exception_handling/exception_class_experiment_1.php(81): fL2(2.3, -4.5) @@ -307,11 +307,11 @@ array(3) { ["args"]=> array(3) { [0]=> - &string(3) "xyz" + string(3) "xyz" [1]=> - &NULL + NULL [2]=> - &bool(true) + bool(true) } } [1]=> @@ -325,9 +325,9 @@ array(3) { ["args"]=> array(2) { [0]=> - &float(2.3) + float(2.3) [1]=> - &float(-4.5) + float(-4.5) } } [2]=> @@ -341,7 +341,7 @@ array(3) { ["args"]=> array(1) { [0]=> - &int(10) + int(10) } } } diff --git a/tests/exception_handling/exception_class_from_within_a_class.phpt b/tests/exception_handling/exception_class_from_within_a_class.phpt index a2c2b144..0f4df730 100644 --- a/tests/exception_handling/exception_class_from_within_a_class.phpt +++ b/tests/exception_handling/exception_class_from_within_a_class.phpt @@ -151,7 +151,7 @@ $o->fL1(10); --EXPECTF-- L0: In try-block L0: In catch-block -$e = >exception 'Exception' with message 'L0 Message' in %s/exception_handling/exception_class_from_within_a_class.php:131 +$e = >Exception: L0 Message in %s/exception_handling/exception_class_from_within_a_class.php:131 Stack trace: #0 {main}< getMessage: >L0 Message< @@ -169,7 +169,7 @@ L0: Beyond try/catch/finally blocks L0: Calling fL1 fL1: In try-block fL1: In catch-block -$e = >exception 'Exception' with message 'fL1 Message' in %s/exception_handling/exception_class_from_within_a_class.php:57 +$e = >Exception: fL1 Message in %s/exception_handling/exception_class_from_within_a_class.php:57 Stack trace: #0 %s/exception_handling/exception_class_from_within_a_class.php(146): MyClass->fL1(10) #1 {main}< @@ -196,7 +196,7 @@ array(1) { ["args"]=> array(1) { [0]=> - &int(10) + int(10) } } } @@ -215,7 +215,7 @@ fL1: Beyond try/catch/finally blocks fL1: Calling fL2 fL2: In try-block fL2: In catch-block -$e = >exception 'Exception' with message 'fL2 Message' in %s/exception_handling/exception_class_from_within_a_class.php:83 +$e = >Exception: fL2 Message in %s/exception_handling/exception_class_from_within_a_class.php:83 Stack trace: #0 %s/exception_handling/exception_class_from_within_a_class.php(71): MyClass->fL2(2.3, -4.5) #1 %s/exception_handling/exception_class_from_within_a_class.php(146): MyClass->fL1(10) @@ -244,9 +244,9 @@ array(2) { ["args"]=> array(2) { [0]=> - &float(2.3) + float(2.3) [1]=> - &float(-4.5) + float(-4.5) } } [1]=> @@ -264,7 +264,7 @@ array(2) { ["args"]=> array(1) { [0]=> - &int(10) + int(10) } } } @@ -292,7 +292,7 @@ fL2: Beyond try/catch/finally blocks fL2: Calling fL3 fL3: In try-block fL3: In catch-block -$e = >exception 'Exception' with message 'fL3 Message' in %s/exception_handling/exception_class_from_within_a_class.php:109 +$e = >Exception: fL3 Message in %s/exception_handling/exception_class_from_within_a_class.php:109 Stack trace: #0 %s/exception_handling/exception_class_from_within_a_class.php(97): MyClass->fL3('xyz', NULL, true) #1 %s/exception_handling/exception_class_from_within_a_class.php(71): MyClass->fL2(2.3, -4.5) @@ -323,11 +323,11 @@ array(3) { ["args"]=> array(3) { [0]=> - &string(3) "xyz" + string(3) "xyz" [1]=> - &NULL + NULL [2]=> - &bool(true) + bool(true) } } [1]=> @@ -345,9 +345,9 @@ array(3) { ["args"]=> array(2) { [0]=> - &float(2.3) + float(2.3) [1]=> - &float(-4.5) + float(-4.5) } } [2]=> @@ -365,7 +365,7 @@ array(3) { ["args"]=> array(1) { [0]=> - &int(10) + int(10) } } } diff --git a/tests/exception_handling/exception_class_using_conditional_functions.phpt b/tests/exception_handling/exception_class_using_conditional_functions.phpt index bf2acb9b..ef5590d5 100644 --- a/tests/exception_handling/exception_class_using_conditional_functions.phpt +++ b/tests/exception_handling/exception_class_using_conditional_functions.phpt @@ -151,7 +151,7 @@ fL1(10); --EXPECTF-- L0: In try-block L0: In catch-block -$e = >exception 'Exception' with message 'L0 Message' in %s/exception_handling/exception_class_using_conditional_functions.php:133 +$e = >Exception: L0 Message in %s/exception_handling/exception_class_using_conditional_functions.php:133 Stack trace: #0 {main}< getMessage: >L0 Message< @@ -169,7 +169,7 @@ L0: Beyond try/catch/finally blocks L0: Calling fL1 fL1: In try-block fL1: In catch-block -$e = >exception 'Exception' with message 'fL1 Message' in %s/exception_handling/exception_class_using_conditional_functions.php:107 +$e = >Exception: fL1 Message in %s/exception_handling/exception_class_using_conditional_functions.php:107 Stack trace: #0 %s/exception_handling/exception_class_using_conditional_functions.php(146): fL1(10) #1 {main}< @@ -192,7 +192,7 @@ array(1) { ["args"]=> array(1) { [0]=> - &int(10) + int(10) } } } @@ -209,7 +209,7 @@ fL1: Beyond try/catch/finally blocks fL1: Calling fL2 fL2: In try-block fL2: In catch-block -$e = >exception 'Exception' with message 'fL2 Message' in %s/exception_handling/exception_class_using_conditional_functions.php:83 +$e = >Exception: fL2 Message in %s/exception_handling/exception_class_using_conditional_functions.php:83 Stack trace: #0 %s/exception_handling/exception_class_using_conditional_functions.php(123): fL2(2.3, -4.5) #1 %s/exception_handling/exception_class_using_conditional_functions.php(146): fL1(10) @@ -234,9 +234,9 @@ array(2) { ["args"]=> array(2) { [0]=> - &float(2.3) + float(2.3) [1]=> - &float(-4.5) + float(-4.5) } } [1]=> @@ -250,7 +250,7 @@ array(2) { ["args"]=> array(1) { [0]=> - &int(10) + int(10) } } } @@ -274,7 +274,7 @@ fL2: Beyond try/catch/finally blocks fL2: Calling fL3 fL3: In try-block fL3: In catch-block -$e = >exception 'Exception' with message 'fL3 Message' in %s/exception_handling/exception_class_using_conditional_functions.php:65 +$e = >Exception: fL3 Message in %s/exception_handling/exception_class_using_conditional_functions.php:65 Stack trace: #0 %s/exception_handling/exception_class_using_conditional_functions.php(99): fL3('xyz', NULL, true) #1 %s/exception_handling/exception_class_using_conditional_functions.php(123): fL2(2.3, -4.5) @@ -301,11 +301,11 @@ array(3) { ["args"]=> array(3) { [0]=> - &string(3) "xyz" + string(3) "xyz" [1]=> - &NULL + NULL [2]=> - &bool(true) + bool(true) } } [1]=> @@ -319,9 +319,9 @@ array(3) { ["args"]=> array(2) { [0]=> - &float(2.3) + float(2.3) [1]=> - &float(-4.5) + float(-4.5) } } [2]=> @@ -335,7 +335,7 @@ array(3) { ["args"]=> array(1) { [0]=> - &int(10) + int(10) } } } diff --git a/tests/exception_handling/hierarchy_of_exception_classes.phpt b/tests/exception_handling/hierarchy_of_exception_classes.phpt index 58de8ddc..ef1195a5 100644 --- a/tests/exception_handling/hierarchy_of_exception_classes.phpt +++ b/tests/exception_handling/hierarchy_of_exception_classes.phpt @@ -68,4 +68,4 @@ finally } --EXPECT-- In handler for DeviceException -In finally block \ No newline at end of file +In finally block diff --git a/tests/exception_handling/jump_from_catch_or_finally_clause.phpt b/tests/exception_handling/jump_from_catch_or_finally_clause.phpt index ca904725..4f4ee5f9 100644 --- a/tests/exception_handling/jump_from_catch_or_finally_clause.phpt +++ b/tests/exception_handling/jump_from_catch_or_finally_clause.phpt @@ -32,7 +32,7 @@ function f() // continue; // allowed // goto end; // allowed // return msg(); // expression is evaluated, but value actually returned - // when both returns exist is 20, from finally block, + // when both returns exist is 20, from finally block, } //*/ finally @@ -56,4 +56,4 @@ In handler for Exception In finally block In handler for Exception In finally block -int(1) \ No newline at end of file +int(1) diff --git a/tests/exception_handling/myrangeexception_test1.phpt b/tests/exception_handling/myrangeexception_test1.phpt index 64f62606..642122a8 100644 --- a/tests/exception_handling/myrangeexception_test1.phpt +++ b/tests/exception_handling/myrangeexception_test1.phpt @@ -44,6 +44,6 @@ object(MyRangeException)#1 (10) { NULL } ======= -$re = >exception 'MyRangeException' with message 'xxx' in %s/exception_handling/myrangeexception_test1.php:13 +$re = >MyRangeException: xxx in %s/exception_handling/myrangeexception_test1.php:13 Stack trace: #0 {main}, badValue: 5, lowerValue: 20, upperValue: 30< diff --git a/tests/exception_handling/odds_and_ends.phpt b/tests/exception_handling/odds_and_ends.phpt index 61604959..bc05edd9 100644 --- a/tests/exception_handling/odds_and_ends.phpt +++ b/tests/exception_handling/odds_and_ends.phpt @@ -82,4 +82,4 @@ In try-block In catch-block Except $e->prop = 0 $e->prop = 999 -$o->prop = 0 \ No newline at end of file +$o->prop = 0 diff --git a/tests/exception_handling/set_exception_handler.phpt b/tests/exception_handling/set_exception_handler.phpt index 36dfba75..d4f60e9f 100644 --- a/tests/exception_handling/set_exception_handler.phpt +++ b/tests/exception_handling/set_exception_handler.phpt @@ -99,7 +99,7 @@ About to call f In try-block In finally-block In MyDefExHandler -$e = >exception 'Exception' with message 'Watson, come here!' in %s/exception_handling/set_exception_handler.php:73 +$e = >Exception: Watson, come here! in %s/exception_handling/set_exception_handler.php:73 Stack trace: #0 %s/exception_handling/set_exception_handler.php(90): f(10, true) #1 {main}< diff --git a/tests/expressions/additive_operators/addition_subtraction_concatenation.phpt b/tests/expressions/additive_operators/addition_subtraction_concatenation.phpt index 4f04b6bb..a4aa31eb 100644 --- a/tests/expressions/additive_operators/addition_subtraction_concatenation.phpt +++ b/tests/expressions/additive_operators/addition_subtraction_concatenation.phpt @@ -288,4 +288,4 @@ var_dump((((10 + 5) . 12) . 100) - 50); >9223372036854775807< . >9223372036854775807<, result: string(38) "92233720368547758079223372036854775807" ------------------------------------- int(1512050) -int(1512050) \ No newline at end of file +int(1512050) diff --git a/tests/expressions/additive_operators/array_concatenation.phpt b/tests/expressions/additive_operators/array_concatenation.phpt index fda66c59..74eb0830 100644 --- a/tests/expressions/additive_operators/array_concatenation.phpt +++ b/tests/expressions/additive_operators/array_concatenation.phpt @@ -44,7 +44,7 @@ NULL + [1, 5 => FALSE, "red"]; [1, 5 => FALSE, "red"] + "123"; // So we conclude that if one operand is an array and the other not, the array -// is not converted to a string and concatenated, and neither is the non-array +// is not converted to a string and concatenated, and neither is the non-array // converted to an array and merged with the other array. */ @@ -204,4 +204,4 @@ array(2) { int(-5) [5]=> float(1.23) -} \ No newline at end of file +} diff --git a/tests/expressions/assignment_operators/add_assignment.phpt b/tests/expressions/assignment_operators/add_assignment.phpt new file mode 100644 index 00000000..bfec7698 --- /dev/null +++ b/tests/expressions/assignment_operators/add_assignment.phpt @@ -0,0 +1,379 @@ +--TEST-- ++= operator +--FILE-- +$e1< += >$e2<, result: "; var_dump($e1 += $e2); + } + echo "-------------------------------------\n"; +} + +?> +--EXPECTF-- +>0< += >0<, result: int(0) +>0< += >-10<, result: int(-10) +>0< += >100<, result: int(100) +>0< += >-34000000000<, result: float(-34000000000) +>0< += >INF<, result: float(INF) +>0< += >-INF<, result: float(-INF) +>0< += >NAN<, result: float(NAN) +>0< += >1<, result: int(1) +>0< += ><, result: int(0) +>0< += ><, result: int(0) +>0< += >123<, result: int(123) +>0< += >2e+5<, result: float(200000) +>0< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< += >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>-10< += >0<, result: int(-10) +>-10< += >-10<, result: int(-20) +>-10< += >100<, result: int(90) +>-10< += >-34000000000<, result: float(-34000000010) +>-10< += >INF<, result: float(INF) +>-10< += >-INF<, result: float(-INF) +>-10< += >NAN<, result: float(NAN) +>-10< += >1<, result: int(-9) +>-10< += ><, result: int(-10) +>-10< += ><, result: int(-10) +>-10< += >123<, result: int(113) +>-10< += >2e+5<, result: float(199990) +>-10< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< += >9223372036854775807<, result: int(9223372036854775797) +------------------------------------- +>100< += >0<, result: int(100) +>100< += >-10<, result: int(90) +>100< += >100<, result: int(200) +>100< += >-34000000000<, result: float(-33999999900) +>100< += >INF<, result: float(INF) +>100< += >-INF<, result: float(-INF) +>100< += >NAN<, result: float(NAN) +>100< += >1<, result: int(101) +>100< += ><, result: int(100) +>100< += ><, result: int(100) +>100< += >123<, result: int(223) +>100< += >2e+5<, result: float(200100) +>100< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< += >9223372036854775807<, result: float(9.2233720368548E+18) +------------------------------------- +>-34000000000< += >0<, result: float(-34000000000) +>-34000000000< += >-10<, result: float(-34000000010) +>-34000000000< += >100<, result: float(-33999999900) +>-34000000000< += >-34000000000<, result: float(-68000000000) +>-34000000000< += >INF<, result: float(INF) +>-34000000000< += >-INF<, result: float(-INF) +>-34000000000< += >NAN<, result: float(NAN) +>-34000000000< += >1<, result: float(-33999999999) +>-34000000000< += ><, result: float(-34000000000) +>-34000000000< += ><, result: float(-34000000000) +>-34000000000< += >123<, result: float(-33999999877) +>-34000000000< += >2e+5<, result: float(-33999800000) +>-34000000000< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) +>-34000000000< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) +>-34000000000< += >9223372036854775807<, result: float(9.2233720028548E+18) +------------------------------------- +>INF< += >0<, result: float(INF) +>INF< += >-10<, result: float(INF) +>INF< += >100<, result: float(INF) +>INF< += >-34000000000<, result: float(INF) +>INF< += >INF<, result: float(INF) +>INF< += >-INF<, result: float(NAN) +>INF< += >NAN<, result: float(NAN) +>INF< += >1<, result: float(INF) +>INF< += ><, result: float(INF) +>INF< += ><, result: float(INF) +>INF< += >123<, result: float(INF) +>INF< += >2e+5<, result: float(INF) +>INF< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>INF< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>INF< += >9223372036854775807<, result: float(INF) +------------------------------------- +>-INF< += >0<, result: float(-INF) +>-INF< += >-10<, result: float(-INF) +>-INF< += >100<, result: float(-INF) +>-INF< += >-34000000000<, result: float(-INF) +>-INF< += >INF<, result: float(NAN) +>-INF< += >-INF<, result: float(-INF) +>-INF< += >NAN<, result: float(NAN) +>-INF< += >1<, result: float(-INF) +>-INF< += ><, result: float(-INF) +>-INF< += ><, result: float(-INF) +>-INF< += >123<, result: float(-INF) +>-INF< += >2e+5<, result: float(-INF) +>-INF< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>-INF< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>-INF< += >9223372036854775807<, result: float(-INF) +------------------------------------- +>NAN< += >0<, result: float(NAN) +>NAN< += >-10<, result: float(NAN) +>NAN< += >100<, result: float(NAN) +>NAN< += >-34000000000<, result: float(NAN) +>NAN< += >INF<, result: float(NAN) +>NAN< += >-INF<, result: float(NAN) +>NAN< += >NAN<, result: float(NAN) +>NAN< += >1<, result: float(NAN) +>NAN< += ><, result: float(NAN) +>NAN< += ><, result: float(NAN) +>NAN< += >123<, result: float(NAN) +>NAN< += >2e+5<, result: float(NAN) +>NAN< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>NAN< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>NAN< += >9223372036854775807<, result: float(NAN) +------------------------------------- +>1< += >0<, result: int(1) +>1< += >-10<, result: int(-9) +>1< += >100<, result: int(101) +>1< += >-34000000000<, result: float(-33999999999) +>1< += >INF<, result: float(INF) +>1< += >-INF<, result: float(-INF) +>1< += >NAN<, result: float(NAN) +>1< += >1<, result: int(2) +>1< += ><, result: int(1) +>1< += ><, result: int(1) +>1< += >123<, result: int(124) +>1< += >2e+5<, result: float(200001) +>1< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< += >9223372036854775807<, result: float(9.2233720368548E+18) +------------------------------------- +>< += >0<, result: int(0) +>< += >-10<, result: int(-10) +>< += >100<, result: int(100) +>< += >-34000000000<, result: float(-34000000000) +>< += >INF<, result: float(INF) +>< += >-INF<, result: float(-INF) +>< += >NAN<, result: float(NAN) +>< += >1<, result: int(1) +>< += ><, result: int(0) +>< += ><, result: int(0) +>< += >123<, result: int(123) +>< += >2e+5<, result: float(200000) +>< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>< += >0<, result: int(0) +>< += >-10<, result: int(-10) +>< += >100<, result: int(100) +>< += >-34000000000<, result: float(-34000000000) +>< += >INF<, result: float(INF) +>< += >-INF<, result: float(-INF) +>< += >NAN<, result: float(NAN) +>< += >1<, result: int(1) +>< += ><, result: int(0) +>< += ><, result: int(0) +>< += >123<, result: int(123) +>< += >2e+5<, result: float(200000) +>< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>123< += >0<, result: int(123) +>123< += >-10<, result: int(113) +>123< += >100<, result: int(223) +>123< += >-34000000000<, result: float(-33999999877) +>123< += >INF<, result: float(INF) +>123< += >-INF<, result: float(-INF) +>123< += >NAN<, result: float(NAN) +>123< += >1<, result: int(124) +>123< += ><, result: int(123) +>123< += ><, result: int(123) +>123< += >123<, result: int(246) +>123< += >2e+5<, result: float(200123) +>123< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< += >9223372036854775807<, result: float(9.2233720368548E+18) +------------------------------------- +>2e+5< += >0<, result: float(200000) +>2e+5< += >-10<, result: float(199990) +>2e+5< += >100<, result: float(200100) +>2e+5< += >-34000000000<, result: float(-33999800000) +>2e+5< += >INF<, result: float(INF) +>2e+5< += >-INF<, result: float(-INF) +>2e+5< += >NAN<, result: float(NAN) +>2e+5< += >1<, result: float(200001) +>2e+5< += ><, result: float(200000) +>2e+5< += ><, result: float(200000) +>2e+5< += >123<, result: float(200123) +>2e+5< += >2e+5<, result: float(400000) +>2e+5< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) +>2e+5< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) +>2e+5< += >9223372036854775807<, result: float(9.223372036855E+18) +------------------------------------- +>< += >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>< += >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>< += >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) +>< += >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>< += >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>< += >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< += >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>< += >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) +>< += ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +------------------------------------- +>abc< += >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< += >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>abc< += >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>abc< += >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) +>abc< += >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>abc< += >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>abc< += >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< += >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>abc< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< += >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>abc< += >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) +>abc< += ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< += >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +------------------------------------- +>9223372036854775807< += >0<, result: int(9223372036854775807) +>9223372036854775807< += >-10<, result: int(9223372036854775797) +>9223372036854775807< += >100<, result: float(9.2233720368548E+18) +>9223372036854775807< += >-34000000000<, result: float(9.2233720028548E+18) +>9223372036854775807< += >INF<, result: float(INF) +>9223372036854775807< += >-INF<, result: float(-INF) +>9223372036854775807< += >NAN<, result: float(NAN) +>9223372036854775807< += >1<, result: float(9.2233720368548E+18) +>9223372036854775807< += ><, result: int(9223372036854775807) +>9223372036854775807< += ><, result: int(9223372036854775807) +>9223372036854775807< += >123<, result: float(9.2233720368548E+18) +>9223372036854775807< += >2e+5<, result: float(9.223372036855E+18) +>9223372036854775807< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< += >9223372036854775807<, result: float(1.844674407371E+19) +------------------------------------- diff --git a/tests/expressions/assignment_operators/and_assignment.phpt b/tests/expressions/assignment_operators/and_assignment.phpt new file mode 100644 index 00000000..e32149bb --- /dev/null +++ b/tests/expressions/assignment_operators/and_assignment.phpt @@ -0,0 +1,347 @@ +--TEST-- +&= operator +--FILE-- +$e1< &= >$e2<, result: "; var_dump($e1 &= $e2); + } + echo "-------------------------------------\n"; +} + +?> +--EXPECTF-- +>0< &= >0<, result: int(0) +>0< &= >-10<, result: int(0) +>0< &= >100<, result: int(0) +>0< &= >-34000000000<, result: int(0) +>0< &= >INF<, result: int(0) +>0< &= >-INF<, result: int(0) +>0< &= >NAN<, result: int(0) +>0< &= >1<, result: int(0) +>0< &= ><, result: int(0) +>0< &= ><, result: int(0) +>0< &= >123<, result: int(0) +>0< &= >2e+5<, result: int(0) +>0< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< &= >9223372036854775807<, result: int(0) +------------------------------------- +>-10< &= >0<, result: int(0) +>-10< &= >-10<, result: int(-10) +>-10< &= >100<, result: int(100) +>-10< &= >-34000000000<, result: int(-34000000000) +>-10< &= >INF<, result: int(0) +>-10< &= >-INF<, result: int(0) +>-10< &= >NAN<, result: int(0) +>-10< &= >1<, result: int(0) +>-10< &= ><, result: int(0) +>-10< &= ><, result: int(0) +>-10< &= >123<, result: int(114) +>-10< &= >2e+5<, result: int(200000) +>-10< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-10< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-10< &= >9223372036854775807<, result: int(9223372036854775798) +------------------------------------- +>100< &= >0<, result: int(0) +>100< &= >-10<, result: int(100) +>100< &= >100<, result: int(100) +>100< &= >-34000000000<, result: int(0) +>100< &= >INF<, result: int(0) +>100< &= >-INF<, result: int(0) +>100< &= >NAN<, result: int(0) +>100< &= >1<, result: int(0) +>100< &= ><, result: int(0) +>100< &= ><, result: int(0) +>100< &= >123<, result: int(96) +>100< &= >2e+5<, result: int(64) +>100< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>100< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>100< &= >9223372036854775807<, result: int(100) +------------------------------------- +>-34000000000< &= >0<, result: int(0) +>-34000000000< &= >-10<, result: int(-34000000000) +>-34000000000< &= >100<, result: int(0) +>-34000000000< &= >-34000000000<, result: int(-34000000000) +>-34000000000< &= >INF<, result: int(0) +>-34000000000< &= >-INF<, result: int(0) +>-34000000000< &= >NAN<, result: int(0) +>-34000000000< &= >1<, result: int(0) +>-34000000000< &= ><, result: int(0) +>-34000000000< &= ><, result: int(0) +>-34000000000< &= >123<, result: int(0) +>-34000000000< &= >2e+5<, result: int(68608) +>-34000000000< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-34000000000< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-34000000000< &= >9223372036854775807<, result: int(9223372002854775808) +------------------------------------- +>INF< &= >0<, result: int(0) +>INF< &= >-10<, result: int(0) +>INF< &= >100<, result: int(0) +>INF< &= >-34000000000<, result: int(0) +>INF< &= >INF<, result: int(0) +>INF< &= >-INF<, result: int(0) +>INF< &= >NAN<, result: int(0) +>INF< &= >1<, result: int(0) +>INF< &= ><, result: int(0) +>INF< &= ><, result: int(0) +>INF< &= >123<, result: int(0) +>INF< &= >2e+5<, result: int(0) +>INF< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< &= >9223372036854775807<, result: int(0) +------------------------------------- +>-INF< &= >0<, result: int(0) +>-INF< &= >-10<, result: int(0) +>-INF< &= >100<, result: int(0) +>-INF< &= >-34000000000<, result: int(0) +>-INF< &= >INF<, result: int(0) +>-INF< &= >-INF<, result: int(0) +>-INF< &= >NAN<, result: int(0) +>-INF< &= >1<, result: int(0) +>-INF< &= ><, result: int(0) +>-INF< &= ><, result: int(0) +>-INF< &= >123<, result: int(0) +>-INF< &= >2e+5<, result: int(0) +>-INF< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< &= >9223372036854775807<, result: int(0) +------------------------------------- +>NAN< &= >0<, result: int(0) +>NAN< &= >-10<, result: int(0) +>NAN< &= >100<, result: int(0) +>NAN< &= >-34000000000<, result: int(0) +>NAN< &= >INF<, result: int(0) +>NAN< &= >-INF<, result: int(0) +>NAN< &= >NAN<, result: int(0) +>NAN< &= >1<, result: int(0) +>NAN< &= ><, result: int(0) +>NAN< &= ><, result: int(0) +>NAN< &= >123<, result: int(0) +>NAN< &= >2e+5<, result: int(0) +>NAN< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< &= >9223372036854775807<, result: int(0) +------------------------------------- +>1< &= >0<, result: int(0) +>1< &= >-10<, result: int(0) +>1< &= >100<, result: int(0) +>1< &= >-34000000000<, result: int(0) +>1< &= >INF<, result: int(0) +>1< &= >-INF<, result: int(0) +>1< &= >NAN<, result: int(0) +>1< &= >1<, result: int(1) +>1< &= ><, result: int(0) +>1< &= ><, result: int(0) +>1< &= >123<, result: int(1) +>1< &= >2e+5<, result: int(0) +>1< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>1< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>1< &= >9223372036854775807<, result: int(1) +------------------------------------- +>< &= >0<, result: int(0) +>< &= >-10<, result: int(0) +>< &= >100<, result: int(0) +>< &= >-34000000000<, result: int(0) +>< &= >INF<, result: int(0) +>< &= >-INF<, result: int(0) +>< &= >NAN<, result: int(0) +>< &= >1<, result: int(0) +>< &= ><, result: int(0) +>< &= ><, result: int(0) +>< &= >123<, result: int(0) +>< &= >2e+5<, result: int(0) +>< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >9223372036854775807<, result: int(0) +------------------------------------- +>< &= >0<, result: int(0) +>< &= >-10<, result: int(0) +>< &= >100<, result: int(0) +>< &= >-34000000000<, result: int(0) +>< &= >INF<, result: int(0) +>< &= >-INF<, result: int(0) +>< &= >NAN<, result: int(0) +>< &= >1<, result: int(0) +>< &= ><, result: int(0) +>< &= ><, result: int(0) +>< &= >123<, result: int(0) +>< &= >2e+5<, result: int(0) +>< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >9223372036854775807<, result: int(0) +------------------------------------- +>123< &= >0<, result: int(0) +>123< &= >-10<, result: int(114) +>123< &= >100<, result: int(96) +>123< &= >-34000000000<, result: int(0) +>123< &= >INF<, result: int(0) +>123< &= >-INF<, result: int(0) +>123< &= >NAN<, result: int(0) +>123< &= >1<, result: int(1) +>123< &= ><, result: int(0) +>123< &= ><, result: int(0) +>123< &= >123<, result: string(3) "123" +>123< &= >2e+5<, result: string(3) "0 #" +>123< &= ><, result: string(0) "" +>123< &= >abc<, result: string(3) "!"#" +>123< &= >9223372036854775807<, result: int(123) +------------------------------------- +>2e+5< &= >0<, result: int(0) +>2e+5< &= >-10<, result: int(200000) +>2e+5< &= >100<, result: int(64) +>2e+5< &= >-34000000000<, result: int(68608) +>2e+5< &= >INF<, result: int(0) +>2e+5< &= >-INF<, result: int(0) +>2e+5< &= >NAN<, result: int(0) +>2e+5< &= >1<, result: int(0) +>2e+5< &= ><, result: int(0) +>2e+5< &= ><, result: int(0) +>2e+5< &= >123<, result: string(3) "0 #" +>2e+5< &= >2e+5<, result: string(4) "2e+5" +>2e+5< &= ><, result: string(0) "" +>2e+5< &= >abc<, result: string(3) " `#" +>2e+5< &= >9223372036854775807<, result: int(200000) +------------------------------------- +>< &= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >123<, result: string(0) "" +>< &= >2e+5<, result: string(0) "" +>< &= ><, result: string(0) "" +>< &= >abc<, result: string(0) "" +>< &= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>abc< &= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >123<, result: string(3) "!"#" +>abc< &= >2e+5<, result: string(3) " `#" +>abc< &= ><, result: string(0) "" +>abc< &= >abc<, result: string(3) "abc" +>abc< &= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>9223372036854775807< &= >0<, result: int(0) +>9223372036854775807< &= >-10<, result: int(9223372036854775798) +>9223372036854775807< &= >100<, result: int(100) +>9223372036854775807< &= >-34000000000<, result: int(9223372002854775808) +>9223372036854775807< &= >INF<, result: int(0) +>9223372036854775807< &= >-INF<, result: int(0) +>9223372036854775807< &= >NAN<, result: int(0) +>9223372036854775807< &= >1<, result: int(1) +>9223372036854775807< &= ><, result: int(0) +>9223372036854775807< &= ><, result: int(0) +>9223372036854775807< &= >123<, result: int(123) +>9223372036854775807< &= >2e+5<, result: int(200000) +>9223372036854775807< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>9223372036854775807< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>9223372036854775807< &= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- diff --git a/tests/expressions/assignment_operators/assignment.phpt b/tests/expressions/assignment_operators/assignment.phpt deleted file mode 100644 index 5b0550bc..00000000 --- a/tests/expressions/assignment_operators/assignment.phpt +++ /dev/null @@ -1,2181 +0,0 @@ ---TEST-- -PHP Spec test generated from ./expressions/assignment_operators/assignment.php ---FILE-- -$e1< *= >$e2<, result: "; var_dump($e1 *= $e2); - } - echo "-------------------------------------\n"; -} -//*/ - -///* -foreach ($oper as $t) -{ - foreach ($oper as $e2) - { - if (($e2) == 0) continue; // skip divide-by-zeros - - $e1 = $t; - echo ">$e1< /= >$e2<, result: "; var_dump($e1 /= $e2); - } - echo "-------------------------------------\n"; -} -//*/ - -///* -foreach ($oper as $t) -{ - if(is_double($t) && !is_finite($t)) continue; - foreach ($oper as $e2) - { - if(is_double($e2) && !is_finite($e2)) continue; - if (((int)$e2) == 0) continue; // skip divide-by-zeros - - $e1 = $t; - echo ">$e1< %= >$e2<, result: "; var_dump($e1 %= $e2); - } - echo "-------------------------------------\n"; -} -//*/ - -///* -foreach ($oper as $t) -{ - foreach ($oper as $e2) - { - $e1 = $t; - echo ">$e1< += >$e2<, result: "; var_dump($e1 += $e2); - } - echo "-------------------------------------\n"; -} -//*/ - -///* -foreach ($oper as $t) -{ - foreach ($oper as $e2) - { - $e1 = $t; - echo ">$e1< -= >$e2<, result: "; var_dump($e1 -= $e2); - } - echo "-------------------------------------\n"; -} -//*/ - -///* -foreach ($oper as $t) -{ - foreach ($oper as $e2) - { - $e1 = $t; - echo ">$e1< .= >$e2<, result: "; var_dump($e1 .= $e2); - } - echo "-------------------------------------\n"; -} -//*/ - -///* -foreach ($oper as $t) -{ - if(is_double($t) && !is_finite($t)) continue; - foreach ($oper as $e2) - { - if(is_double($e2) && !is_finite($e2)) continue; - $e1 = $t; - echo ">$e1< <<= >$e2<, result: "; var_dump($e1 <<= $e2); - } - echo "-------------------------------------\n"; -} -//*/ - -///* -foreach ($oper as $t) -{ - if(is_double($t) && !is_finite($t)) continue; - foreach ($oper as $e2) - { - if(is_double($e2) && !is_finite($e2)) continue; - $e1 = $t; - echo ">$e1< >>= >$e2<, result: "; var_dump($e1 >>= $e2); - } - echo "-------------------------------------\n"; -} -//*/ - -///* -foreach ($oper as $t) -{ - if(is_double($t) && !is_finite($t)) continue; - foreach ($oper as $e2) - { - if(is_double($e2) && !is_finite($e2)) continue; - $e1 = $t; - echo ">$e1< &= >$e2<, result: "; var_dump($e1 &= $e2); - } - echo "-------------------------------------\n"; -} -//*/ - -///* -foreach ($oper as $t) -{ - if(is_double($t) && !is_finite($t)) continue; - foreach ($oper as $e2) - { - $e1 = $t; - if(is_double($e2) && !is_finite($e2)) continue; - echo ">$e1< ^= >$e2<, result: "; var_dump($e1 ^= $e2); - } - echo "-------------------------------------\n"; -} -//*/ - -///* -foreach ($oper as $t) -{ - if(is_double($t) && !is_finite($t)) continue; - foreach ($oper as $e2) - { - $e1 = $t; - if(is_double($e2) && !is_finite($e2)) continue; - echo ">$e1< |= >$e2<, result: "; var_dump($e1 |= $e2); - } - echo "-------------------------------------\n"; -} -//*/ - -///* -var_dump($v = 10); -var_dump($v += 20); -var_dump($v -= 5); -var_dump($v .= 123.45); -$a = [100, 200, 300]; -$i = 1; -var_dump($a[$i++] += 50); -var_dump($i); -//*/ ---EXPECT-- ->0< *= >0<, result: int(0) ->0< *= >-10<, result: int(0) ->0< *= >100<, result: int(0) ->0< *= >-34000000000<, result: float(-0) ->0< *= >INF<, result: float(NAN) ->0< *= >-INF<, result: float(NAN) ->0< *= >NAN<, result: float(NAN) ->0< *= >1<, result: int(0) ->0< *= ><, result: int(0) ->0< *= ><, result: int(0) ->0< *= >123<, result: int(0) ->0< *= >2e+5<, result: float(0) ->0< *= ><, result: int(0) ->0< *= >abc<, result: int(0) ->0< *= >9223372036854775807<, result: int(0) -------------------------------------- ->-10< *= >0<, result: int(0) ->-10< *= >-10<, result: int(100) ->-10< *= >100<, result: int(-1000) ->-10< *= >-34000000000<, result: float(340000000000) ->-10< *= >INF<, result: float(-INF) ->-10< *= >-INF<, result: float(INF) ->-10< *= >NAN<, result: float(NAN) ->-10< *= >1<, result: int(-10) ->-10< *= ><, result: int(0) ->-10< *= ><, result: int(0) ->-10< *= >123<, result: int(-1230) ->-10< *= >2e+5<, result: float(-2000000) ->-10< *= ><, result: int(0) ->-10< *= >abc<, result: int(0) ->-10< *= >9223372036854775807<, result: float(-9.2233720368548E+19) -------------------------------------- ->100< *= >0<, result: int(0) ->100< *= >-10<, result: int(-1000) ->100< *= >100<, result: int(10000) ->100< *= >-34000000000<, result: float(-3400000000000) ->100< *= >INF<, result: float(INF) ->100< *= >-INF<, result: float(-INF) ->100< *= >NAN<, result: float(NAN) ->100< *= >1<, result: int(100) ->100< *= ><, result: int(0) ->100< *= ><, result: int(0) ->100< *= >123<, result: int(12300) ->100< *= >2e+5<, result: float(20000000) ->100< *= ><, result: int(0) ->100< *= >abc<, result: int(0) ->100< *= >9223372036854775807<, result: float(9.2233720368548E+20) -------------------------------------- ->-34000000000< *= >0<, result: float(-0) ->-34000000000< *= >-10<, result: float(340000000000) ->-34000000000< *= >100<, result: float(-3400000000000) ->-34000000000< *= >-34000000000<, result: float(1.156E+21) ->-34000000000< *= >INF<, result: float(-INF) ->-34000000000< *= >-INF<, result: float(INF) ->-34000000000< *= >NAN<, result: float(NAN) ->-34000000000< *= >1<, result: float(-34000000000) ->-34000000000< *= ><, result: float(-0) ->-34000000000< *= ><, result: float(-0) ->-34000000000< *= >123<, result: float(-4182000000000) ->-34000000000< *= >2e+5<, result: float(-6.8E+15) ->-34000000000< *= ><, result: float(-0) ->-34000000000< *= >abc<, result: float(-0) ->-34000000000< *= >9223372036854775807<, result: float(-3.1359464925306E+29) -------------------------------------- ->INF< *= >0<, result: float(NAN) ->INF< *= >-10<, result: float(-INF) ->INF< *= >100<, result: float(INF) ->INF< *= >-34000000000<, result: float(-INF) ->INF< *= >INF<, result: float(INF) ->INF< *= >-INF<, result: float(-INF) ->INF< *= >NAN<, result: float(NAN) ->INF< *= >1<, result: float(INF) ->INF< *= ><, result: float(NAN) ->INF< *= ><, result: float(NAN) ->INF< *= >123<, result: float(INF) ->INF< *= >2e+5<, result: float(INF) ->INF< *= ><, result: float(NAN) ->INF< *= >abc<, result: float(NAN) ->INF< *= >9223372036854775807<, result: float(INF) -------------------------------------- ->-INF< *= >0<, result: float(NAN) ->-INF< *= >-10<, result: float(INF) ->-INF< *= >100<, result: float(-INF) ->-INF< *= >-34000000000<, result: float(INF) ->-INF< *= >INF<, result: float(-INF) ->-INF< *= >-INF<, result: float(INF) ->-INF< *= >NAN<, result: float(NAN) ->-INF< *= >1<, result: float(-INF) ->-INF< *= ><, result: float(NAN) ->-INF< *= ><, result: float(NAN) ->-INF< *= >123<, result: float(-INF) ->-INF< *= >2e+5<, result: float(-INF) ->-INF< *= ><, result: float(NAN) ->-INF< *= >abc<, result: float(NAN) ->-INF< *= >9223372036854775807<, result: float(-INF) -------------------------------------- ->NAN< *= >0<, result: float(NAN) ->NAN< *= >-10<, result: float(NAN) ->NAN< *= >100<, result: float(NAN) ->NAN< *= >-34000000000<, result: float(NAN) ->NAN< *= >INF<, result: float(NAN) ->NAN< *= >-INF<, result: float(NAN) ->NAN< *= >NAN<, result: float(NAN) ->NAN< *= >1<, result: float(NAN) ->NAN< *= ><, result: float(NAN) ->NAN< *= ><, result: float(NAN) ->NAN< *= >123<, result: float(NAN) ->NAN< *= >2e+5<, result: float(NAN) ->NAN< *= ><, result: float(NAN) ->NAN< *= >abc<, result: float(NAN) ->NAN< *= >9223372036854775807<, result: float(NAN) -------------------------------------- ->1< *= >0<, result: int(0) ->1< *= >-10<, result: int(-10) ->1< *= >100<, result: int(100) ->1< *= >-34000000000<, result: float(-34000000000) ->1< *= >INF<, result: float(INF) ->1< *= >-INF<, result: float(-INF) ->1< *= >NAN<, result: float(NAN) ->1< *= >1<, result: int(1) ->1< *= ><, result: int(0) ->1< *= ><, result: int(0) ->1< *= >123<, result: int(123) ->1< *= >2e+5<, result: float(200000) ->1< *= ><, result: int(0) ->1< *= >abc<, result: int(0) ->1< *= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->< *= >0<, result: int(0) ->< *= >-10<, result: int(0) ->< *= >100<, result: int(0) ->< *= >-34000000000<, result: float(-0) ->< *= >INF<, result: float(NAN) ->< *= >-INF<, result: float(NAN) ->< *= >NAN<, result: float(NAN) ->< *= >1<, result: int(0) ->< *= ><, result: int(0) ->< *= ><, result: int(0) ->< *= >123<, result: int(0) ->< *= >2e+5<, result: float(0) ->< *= ><, result: int(0) ->< *= >abc<, result: int(0) ->< *= >9223372036854775807<, result: int(0) -------------------------------------- ->< *= >0<, result: int(0) ->< *= >-10<, result: int(0) ->< *= >100<, result: int(0) ->< *= >-34000000000<, result: float(-0) ->< *= >INF<, result: float(NAN) ->< *= >-INF<, result: float(NAN) ->< *= >NAN<, result: float(NAN) ->< *= >1<, result: int(0) ->< *= ><, result: int(0) ->< *= ><, result: int(0) ->< *= >123<, result: int(0) ->< *= >2e+5<, result: float(0) ->< *= ><, result: int(0) ->< *= >abc<, result: int(0) ->< *= >9223372036854775807<, result: int(0) -------------------------------------- ->123< *= >0<, result: int(0) ->123< *= >-10<, result: int(-1230) ->123< *= >100<, result: int(12300) ->123< *= >-34000000000<, result: float(-4182000000000) ->123< *= >INF<, result: float(INF) ->123< *= >-INF<, result: float(-INF) ->123< *= >NAN<, result: float(NAN) ->123< *= >1<, result: int(123) ->123< *= ><, result: int(0) ->123< *= ><, result: int(0) ->123< *= >123<, result: int(15129) ->123< *= >2e+5<, result: float(24600000) ->123< *= ><, result: int(0) ->123< *= >abc<, result: int(0) ->123< *= >9223372036854775807<, result: float(1.1344747605331E+21) -------------------------------------- ->2e+5< *= >0<, result: float(0) ->2e+5< *= >-10<, result: float(-2000000) ->2e+5< *= >100<, result: float(20000000) ->2e+5< *= >-34000000000<, result: float(-6.8E+15) ->2e+5< *= >INF<, result: float(INF) ->2e+5< *= >-INF<, result: float(-INF) ->2e+5< *= >NAN<, result: float(NAN) ->2e+5< *= >1<, result: float(200000) ->2e+5< *= ><, result: float(0) ->2e+5< *= ><, result: float(0) ->2e+5< *= >123<, result: float(24600000) ->2e+5< *= >2e+5<, result: float(40000000000) ->2e+5< *= ><, result: float(0) ->2e+5< *= >abc<, result: float(0) ->2e+5< *= >9223372036854775807<, result: float(1.844674407371E+24) -------------------------------------- ->< *= >0<, result: int(0) ->< *= >-10<, result: int(0) ->< *= >100<, result: int(0) ->< *= >-34000000000<, result: float(-0) ->< *= >INF<, result: float(NAN) ->< *= >-INF<, result: float(NAN) ->< *= >NAN<, result: float(NAN) ->< *= >1<, result: int(0) ->< *= ><, result: int(0) ->< *= ><, result: int(0) ->< *= >123<, result: int(0) ->< *= >2e+5<, result: float(0) ->< *= ><, result: int(0) ->< *= >abc<, result: int(0) ->< *= >9223372036854775807<, result: int(0) -------------------------------------- ->abc< *= >0<, result: int(0) ->abc< *= >-10<, result: int(0) ->abc< *= >100<, result: int(0) ->abc< *= >-34000000000<, result: float(-0) ->abc< *= >INF<, result: float(NAN) ->abc< *= >-INF<, result: float(NAN) ->abc< *= >NAN<, result: float(NAN) ->abc< *= >1<, result: int(0) ->abc< *= ><, result: int(0) ->abc< *= ><, result: int(0) ->abc< *= >123<, result: int(0) ->abc< *= >2e+5<, result: float(0) ->abc< *= ><, result: int(0) ->abc< *= >abc<, result: int(0) ->abc< *= >9223372036854775807<, result: int(0) -------------------------------------- ->9223372036854775807< *= >0<, result: int(0) ->9223372036854775807< *= >-10<, result: float(-9.2233720368548E+19) ->9223372036854775807< *= >100<, result: float(9.2233720368548E+20) ->9223372036854775807< *= >-34000000000<, result: float(-3.1359464925306E+29) ->9223372036854775807< *= >INF<, result: float(INF) ->9223372036854775807< *= >-INF<, result: float(-INF) ->9223372036854775807< *= >NAN<, result: float(NAN) ->9223372036854775807< *= >1<, result: int(9223372036854775807) ->9223372036854775807< *= ><, result: int(0) ->9223372036854775807< *= ><, result: int(0) ->9223372036854775807< *= >123<, result: float(1.1344747605331E+21) ->9223372036854775807< *= >2e+5<, result: float(1.844674407371E+24) ->9223372036854775807< *= ><, result: int(0) ->9223372036854775807< *= >abc<, result: int(0) ->9223372036854775807< *= >9223372036854775807<, result: float(8.5070591730235E+37) -------------------------------------- ->0< /= >-10<, result: int(0) ->0< /= >100<, result: int(0) ->0< /= >-34000000000<, result: float(-0) ->0< /= >INF<, result: float(0) ->0< /= >-INF<, result: float(-0) ->0< /= >NAN<, result: float(NAN) ->0< /= >1<, result: int(0) ->0< /= >123<, result: int(0) ->0< /= >2e+5<, result: float(0) ->0< /= >9223372036854775807<, result: int(0) -------------------------------------- ->-10< /= >-10<, result: int(1) ->-10< /= >100<, result: float(-0.1) ->-10< /= >-34000000000<, result: float(2.9411764705882E-10) ->-10< /= >INF<, result: float(-0) ->-10< /= >-INF<, result: float(0) ->-10< /= >NAN<, result: float(NAN) ->-10< /= >1<, result: int(-10) ->-10< /= >123<, result: float(-0.08130081300813) ->-10< /= >2e+5<, result: float(-5.0E-5) ->-10< /= >9223372036854775807<, result: float(-1.0842021724855E-18) -------------------------------------- ->100< /= >-10<, result: int(-10) ->100< /= >100<, result: int(1) ->100< /= >-34000000000<, result: float(-2.9411764705882E-9) ->100< /= >INF<, result: float(0) ->100< /= >-INF<, result: float(-0) ->100< /= >NAN<, result: float(NAN) ->100< /= >1<, result: int(100) ->100< /= >123<, result: float(0.8130081300813) ->100< /= >2e+5<, result: float(0.0005) ->100< /= >9223372036854775807<, result: float(1.0842021724855E-17) -------------------------------------- ->-34000000000< /= >-10<, result: float(3400000000) ->-34000000000< /= >100<, result: float(-340000000) ->-34000000000< /= >-34000000000<, result: float(1) ->-34000000000< /= >INF<, result: float(-0) ->-34000000000< /= >-INF<, result: float(0) ->-34000000000< /= >NAN<, result: float(NAN) ->-34000000000< /= >1<, result: float(-34000000000) ->-34000000000< /= >123<, result: float(-276422764.22764) ->-34000000000< /= >2e+5<, result: float(-170000) ->-34000000000< /= >9223372036854775807<, result: float(-3.6862873864507E-9) -------------------------------------- ->INF< /= >-10<, result: float(-INF) ->INF< /= >100<, result: float(INF) ->INF< /= >-34000000000<, result: float(-INF) ->INF< /= >INF<, result: float(NAN) ->INF< /= >-INF<, result: float(NAN) ->INF< /= >NAN<, result: float(NAN) ->INF< /= >1<, result: float(INF) ->INF< /= >123<, result: float(INF) ->INF< /= >2e+5<, result: float(INF) ->INF< /= >9223372036854775807<, result: float(INF) -------------------------------------- ->-INF< /= >-10<, result: float(INF) ->-INF< /= >100<, result: float(-INF) ->-INF< /= >-34000000000<, result: float(INF) ->-INF< /= >INF<, result: float(NAN) ->-INF< /= >-INF<, result: float(NAN) ->-INF< /= >NAN<, result: float(NAN) ->-INF< /= >1<, result: float(-INF) ->-INF< /= >123<, result: float(-INF) ->-INF< /= >2e+5<, result: float(-INF) ->-INF< /= >9223372036854775807<, result: float(-INF) -------------------------------------- ->NAN< /= >-10<, result: float(NAN) ->NAN< /= >100<, result: float(NAN) ->NAN< /= >-34000000000<, result: float(NAN) ->NAN< /= >INF<, result: float(NAN) ->NAN< /= >-INF<, result: float(NAN) ->NAN< /= >NAN<, result: float(NAN) ->NAN< /= >1<, result: float(NAN) ->NAN< /= >123<, result: float(NAN) ->NAN< /= >2e+5<, result: float(NAN) ->NAN< /= >9223372036854775807<, result: float(NAN) -------------------------------------- ->1< /= >-10<, result: float(-0.1) ->1< /= >100<, result: float(0.01) ->1< /= >-34000000000<, result: float(-2.9411764705882E-11) ->1< /= >INF<, result: float(0) ->1< /= >-INF<, result: float(-0) ->1< /= >NAN<, result: float(NAN) ->1< /= >1<, result: int(1) ->1< /= >123<, result: float(0.008130081300813) ->1< /= >2e+5<, result: float(5.0E-6) ->1< /= >9223372036854775807<, result: float(1.0842021724855E-19) -------------------------------------- ->< /= >-10<, result: int(0) ->< /= >100<, result: int(0) ->< /= >-34000000000<, result: float(-0) ->< /= >INF<, result: float(0) ->< /= >-INF<, result: float(-0) ->< /= >NAN<, result: float(NAN) ->< /= >1<, result: int(0) ->< /= >123<, result: int(0) ->< /= >2e+5<, result: float(0) ->< /= >9223372036854775807<, result: int(0) -------------------------------------- ->< /= >-10<, result: int(0) ->< /= >100<, result: int(0) ->< /= >-34000000000<, result: float(-0) ->< /= >INF<, result: float(0) ->< /= >-INF<, result: float(-0) ->< /= >NAN<, result: float(NAN) ->< /= >1<, result: int(0) ->< /= >123<, result: int(0) ->< /= >2e+5<, result: float(0) ->< /= >9223372036854775807<, result: int(0) -------------------------------------- ->123< /= >-10<, result: float(-12.3) ->123< /= >100<, result: float(1.23) ->123< /= >-34000000000<, result: float(-3.6176470588235E-9) ->123< /= >INF<, result: float(0) ->123< /= >-INF<, result: float(-0) ->123< /= >NAN<, result: float(NAN) ->123< /= >1<, result: int(123) ->123< /= >123<, result: int(1) ->123< /= >2e+5<, result: float(0.000615) ->123< /= >9223372036854775807<, result: float(1.3335686721572E-17) -------------------------------------- ->2e+5< /= >-10<, result: float(-20000) ->2e+5< /= >100<, result: float(2000) ->2e+5< /= >-34000000000<, result: float(-5.8823529411765E-6) ->2e+5< /= >INF<, result: float(0) ->2e+5< /= >-INF<, result: float(-0) ->2e+5< /= >NAN<, result: float(NAN) ->2e+5< /= >1<, result: float(200000) ->2e+5< /= >123<, result: float(1626.0162601626) ->2e+5< /= >2e+5<, result: float(1) ->2e+5< /= >9223372036854775807<, result: float(2.168404344971E-14) -------------------------------------- ->< /= >-10<, result: int(0) ->< /= >100<, result: int(0) ->< /= >-34000000000<, result: float(-0) ->< /= >INF<, result: float(0) ->< /= >-INF<, result: float(-0) ->< /= >NAN<, result: float(NAN) ->< /= >1<, result: int(0) ->< /= >123<, result: int(0) ->< /= >2e+5<, result: float(0) ->< /= >9223372036854775807<, result: int(0) -------------------------------------- ->abc< /= >-10<, result: int(0) ->abc< /= >100<, result: int(0) ->abc< /= >-34000000000<, result: float(-0) ->abc< /= >INF<, result: float(0) ->abc< /= >-INF<, result: float(-0) ->abc< /= >NAN<, result: float(NAN) ->abc< /= >1<, result: int(0) ->abc< /= >123<, result: int(0) ->abc< /= >2e+5<, result: float(0) ->abc< /= >9223372036854775807<, result: int(0) -------------------------------------- ->9223372036854775807< /= >-10<, result: float(-9.2233720368548E+17) ->9223372036854775807< /= >100<, result: float(9.2233720368548E+16) ->9223372036854775807< /= >-34000000000<, result: float(-271275648.14279) ->9223372036854775807< /= >INF<, result: float(0) ->9223372036854775807< /= >-INF<, result: float(-0) ->9223372036854775807< /= >NAN<, result: float(NAN) ->9223372036854775807< /= >1<, result: int(9223372036854775807) ->9223372036854775807< /= >123<, result: float(7.4986764527275E+16) ->9223372036854775807< /= >2e+5<, result: float(46116860184274) ->9223372036854775807< /= >9223372036854775807<, result: int(1) -------------------------------------- ->0< %= >-10<, result: int(0) ->0< %= >100<, result: int(0) ->0< %= >-34000000000<, result: int(0) ->0< %= >1<, result: int(0) ->0< %= >123<, result: int(0) ->0< %= >2e+5<, result: int(0) ->0< %= >9223372036854775807<, result: int(0) -------------------------------------- ->-10< %= >-10<, result: int(0) ->-10< %= >100<, result: int(-10) ->-10< %= >-34000000000<, result: int(-10) ->-10< %= >1<, result: int(0) ->-10< %= >123<, result: int(-10) ->-10< %= >2e+5<, result: int(0) ->-10< %= >9223372036854775807<, result: int(-10) -------------------------------------- ->100< %= >-10<, result: int(0) ->100< %= >100<, result: int(0) ->100< %= >-34000000000<, result: int(100) ->100< %= >1<, result: int(0) ->100< %= >123<, result: int(100) ->100< %= >2e+5<, result: int(0) ->100< %= >9223372036854775807<, result: int(100) -------------------------------------- ->-34000000000< %= >-10<, result: int(0) ->-34000000000< %= >100<, result: int(0) ->-34000000000< %= >-34000000000<, result: int(0) ->-34000000000< %= >1<, result: int(0) ->-34000000000< %= >123<, result: int(-28) ->-34000000000< %= >2e+5<, result: int(0) ->-34000000000< %= >9223372036854775807<, result: int(-34000000000) -------------------------------------- ->1< %= >-10<, result: int(1) ->1< %= >100<, result: int(1) ->1< %= >-34000000000<, result: int(1) ->1< %= >1<, result: int(0) ->1< %= >123<, result: int(1) ->1< %= >2e+5<, result: int(1) ->1< %= >9223372036854775807<, result: int(1) -------------------------------------- ->< %= >-10<, result: int(0) ->< %= >100<, result: int(0) ->< %= >-34000000000<, result: int(0) ->< %= >1<, result: int(0) ->< %= >123<, result: int(0) ->< %= >2e+5<, result: int(0) ->< %= >9223372036854775807<, result: int(0) -------------------------------------- ->< %= >-10<, result: int(0) ->< %= >100<, result: int(0) ->< %= >-34000000000<, result: int(0) ->< %= >1<, result: int(0) ->< %= >123<, result: int(0) ->< %= >2e+5<, result: int(0) ->< %= >9223372036854775807<, result: int(0) -------------------------------------- ->123< %= >-10<, result: int(3) ->123< %= >100<, result: int(23) ->123< %= >-34000000000<, result: int(123) ->123< %= >1<, result: int(0) ->123< %= >123<, result: int(0) ->123< %= >2e+5<, result: int(1) ->123< %= >9223372036854775807<, result: int(123) -------------------------------------- ->2e+5< %= >-10<, result: int(2) ->2e+5< %= >100<, result: int(2) ->2e+5< %= >-34000000000<, result: int(2) ->2e+5< %= >1<, result: int(0) ->2e+5< %= >123<, result: int(2) ->2e+5< %= >2e+5<, result: int(0) ->2e+5< %= >9223372036854775807<, result: int(2) -------------------------------------- ->< %= >-10<, result: int(0) ->< %= >100<, result: int(0) ->< %= >-34000000000<, result: int(0) ->< %= >1<, result: int(0) ->< %= >123<, result: int(0) ->< %= >2e+5<, result: int(0) ->< %= >9223372036854775807<, result: int(0) -------------------------------------- ->abc< %= >-10<, result: int(0) ->abc< %= >100<, result: int(0) ->abc< %= >-34000000000<, result: int(0) ->abc< %= >1<, result: int(0) ->abc< %= >123<, result: int(0) ->abc< %= >2e+5<, result: int(0) ->abc< %= >9223372036854775807<, result: int(0) -------------------------------------- ->9223372036854775807< %= >-10<, result: int(7) ->9223372036854775807< %= >100<, result: int(7) ->9223372036854775807< %= >-34000000000<, result: int(4854775807) ->9223372036854775807< %= >1<, result: int(0) ->9223372036854775807< %= >123<, result: int(7) ->9223372036854775807< %= >2e+5<, result: int(1) ->9223372036854775807< %= >9223372036854775807<, result: int(0) -------------------------------------- ->0< += >0<, result: int(0) ->0< += >-10<, result: int(-10) ->0< += >100<, result: int(100) ->0< += >-34000000000<, result: float(-34000000000) ->0< += >INF<, result: float(INF) ->0< += >-INF<, result: float(-INF) ->0< += >NAN<, result: float(NAN) ->0< += >1<, result: int(1) ->0< += ><, result: int(0) ->0< += ><, result: int(0) ->0< += >123<, result: int(123) ->0< += >2e+5<, result: float(200000) ->0< += ><, result: int(0) ->0< += >abc<, result: int(0) ->0< += >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->-10< += >0<, result: int(-10) ->-10< += >-10<, result: int(-20) ->-10< += >100<, result: int(90) ->-10< += >-34000000000<, result: float(-34000000010) ->-10< += >INF<, result: float(INF) ->-10< += >-INF<, result: float(-INF) ->-10< += >NAN<, result: float(NAN) ->-10< += >1<, result: int(-9) ->-10< += ><, result: int(-10) ->-10< += ><, result: int(-10) ->-10< += >123<, result: int(113) ->-10< += >2e+5<, result: float(199990) ->-10< += ><, result: int(-10) ->-10< += >abc<, result: int(-10) ->-10< += >9223372036854775807<, result: int(9223372036854775797) -------------------------------------- ->100< += >0<, result: int(100) ->100< += >-10<, result: int(90) ->100< += >100<, result: int(200) ->100< += >-34000000000<, result: float(-33999999900) ->100< += >INF<, result: float(INF) ->100< += >-INF<, result: float(-INF) ->100< += >NAN<, result: float(NAN) ->100< += >1<, result: int(101) ->100< += ><, result: int(100) ->100< += ><, result: int(100) ->100< += >123<, result: int(223) ->100< += >2e+5<, result: float(200100) ->100< += ><, result: int(100) ->100< += >abc<, result: int(100) ->100< += >9223372036854775807<, result: float(9.2233720368548E+18) -------------------------------------- ->-34000000000< += >0<, result: float(-34000000000) ->-34000000000< += >-10<, result: float(-34000000010) ->-34000000000< += >100<, result: float(-33999999900) ->-34000000000< += >-34000000000<, result: float(-68000000000) ->-34000000000< += >INF<, result: float(INF) ->-34000000000< += >-INF<, result: float(-INF) ->-34000000000< += >NAN<, result: float(NAN) ->-34000000000< += >1<, result: float(-33999999999) ->-34000000000< += ><, result: float(-34000000000) ->-34000000000< += ><, result: float(-34000000000) ->-34000000000< += >123<, result: float(-33999999877) ->-34000000000< += >2e+5<, result: float(-33999800000) ->-34000000000< += ><, result: float(-34000000000) ->-34000000000< += >abc<, result: float(-34000000000) ->-34000000000< += >9223372036854775807<, result: float(9.2233720028548E+18) -------------------------------------- ->INF< += >0<, result: float(INF) ->INF< += >-10<, result: float(INF) ->INF< += >100<, result: float(INF) ->INF< += >-34000000000<, result: float(INF) ->INF< += >INF<, result: float(INF) ->INF< += >-INF<, result: float(NAN) ->INF< += >NAN<, result: float(NAN) ->INF< += >1<, result: float(INF) ->INF< += ><, result: float(INF) ->INF< += ><, result: float(INF) ->INF< += >123<, result: float(INF) ->INF< += >2e+5<, result: float(INF) ->INF< += ><, result: float(INF) ->INF< += >abc<, result: float(INF) ->INF< += >9223372036854775807<, result: float(INF) -------------------------------------- ->-INF< += >0<, result: float(-INF) ->-INF< += >-10<, result: float(-INF) ->-INF< += >100<, result: float(-INF) ->-INF< += >-34000000000<, result: float(-INF) ->-INF< += >INF<, result: float(NAN) ->-INF< += >-INF<, result: float(-INF) ->-INF< += >NAN<, result: float(NAN) ->-INF< += >1<, result: float(-INF) ->-INF< += ><, result: float(-INF) ->-INF< += ><, result: float(-INF) ->-INF< += >123<, result: float(-INF) ->-INF< += >2e+5<, result: float(-INF) ->-INF< += ><, result: float(-INF) ->-INF< += >abc<, result: float(-INF) ->-INF< += >9223372036854775807<, result: float(-INF) -------------------------------------- ->NAN< += >0<, result: float(NAN) ->NAN< += >-10<, result: float(NAN) ->NAN< += >100<, result: float(NAN) ->NAN< += >-34000000000<, result: float(NAN) ->NAN< += >INF<, result: float(NAN) ->NAN< += >-INF<, result: float(NAN) ->NAN< += >NAN<, result: float(NAN) ->NAN< += >1<, result: float(NAN) ->NAN< += ><, result: float(NAN) ->NAN< += ><, result: float(NAN) ->NAN< += >123<, result: float(NAN) ->NAN< += >2e+5<, result: float(NAN) ->NAN< += ><, result: float(NAN) ->NAN< += >abc<, result: float(NAN) ->NAN< += >9223372036854775807<, result: float(NAN) -------------------------------------- ->1< += >0<, result: int(1) ->1< += >-10<, result: int(-9) ->1< += >100<, result: int(101) ->1< += >-34000000000<, result: float(-33999999999) ->1< += >INF<, result: float(INF) ->1< += >-INF<, result: float(-INF) ->1< += >NAN<, result: float(NAN) ->1< += >1<, result: int(2) ->1< += ><, result: int(1) ->1< += ><, result: int(1) ->1< += >123<, result: int(124) ->1< += >2e+5<, result: float(200001) ->1< += ><, result: int(1) ->1< += >abc<, result: int(1) ->1< += >9223372036854775807<, result: float(9.2233720368548E+18) -------------------------------------- ->< += >0<, result: int(0) ->< += >-10<, result: int(-10) ->< += >100<, result: int(100) ->< += >-34000000000<, result: float(-34000000000) ->< += >INF<, result: float(INF) ->< += >-INF<, result: float(-INF) ->< += >NAN<, result: float(NAN) ->< += >1<, result: int(1) ->< += ><, result: int(0) ->< += ><, result: int(0) ->< += >123<, result: int(123) ->< += >2e+5<, result: float(200000) ->< += ><, result: int(0) ->< += >abc<, result: int(0) ->< += >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->< += >0<, result: int(0) ->< += >-10<, result: int(-10) ->< += >100<, result: int(100) ->< += >-34000000000<, result: float(-34000000000) ->< += >INF<, result: float(INF) ->< += >-INF<, result: float(-INF) ->< += >NAN<, result: float(NAN) ->< += >1<, result: int(1) ->< += ><, result: int(0) ->< += ><, result: int(0) ->< += >123<, result: int(123) ->< += >2e+5<, result: float(200000) ->< += ><, result: int(0) ->< += >abc<, result: int(0) ->< += >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->123< += >0<, result: int(123) ->123< += >-10<, result: int(113) ->123< += >100<, result: int(223) ->123< += >-34000000000<, result: float(-33999999877) ->123< += >INF<, result: float(INF) ->123< += >-INF<, result: float(-INF) ->123< += >NAN<, result: float(NAN) ->123< += >1<, result: int(124) ->123< += ><, result: int(123) ->123< += ><, result: int(123) ->123< += >123<, result: int(246) ->123< += >2e+5<, result: float(200123) ->123< += ><, result: int(123) ->123< += >abc<, result: int(123) ->123< += >9223372036854775807<, result: float(9.2233720368548E+18) -------------------------------------- ->2e+5< += >0<, result: float(200000) ->2e+5< += >-10<, result: float(199990) ->2e+5< += >100<, result: float(200100) ->2e+5< += >-34000000000<, result: float(-33999800000) ->2e+5< += >INF<, result: float(INF) ->2e+5< += >-INF<, result: float(-INF) ->2e+5< += >NAN<, result: float(NAN) ->2e+5< += >1<, result: float(200001) ->2e+5< += ><, result: float(200000) ->2e+5< += ><, result: float(200000) ->2e+5< += >123<, result: float(200123) ->2e+5< += >2e+5<, result: float(400000) ->2e+5< += ><, result: float(200000) ->2e+5< += >abc<, result: float(200000) ->2e+5< += >9223372036854775807<, result: float(9.223372036855E+18) -------------------------------------- ->< += >0<, result: int(0) ->< += >-10<, result: int(-10) ->< += >100<, result: int(100) ->< += >-34000000000<, result: float(-34000000000) ->< += >INF<, result: float(INF) ->< += >-INF<, result: float(-INF) ->< += >NAN<, result: float(NAN) ->< += >1<, result: int(1) ->< += ><, result: int(0) ->< += ><, result: int(0) ->< += >123<, result: int(123) ->< += >2e+5<, result: float(200000) ->< += ><, result: int(0) ->< += >abc<, result: int(0) ->< += >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->abc< += >0<, result: int(0) ->abc< += >-10<, result: int(-10) ->abc< += >100<, result: int(100) ->abc< += >-34000000000<, result: float(-34000000000) ->abc< += >INF<, result: float(INF) ->abc< += >-INF<, result: float(-INF) ->abc< += >NAN<, result: float(NAN) ->abc< += >1<, result: int(1) ->abc< += ><, result: int(0) ->abc< += ><, result: int(0) ->abc< += >123<, result: int(123) ->abc< += >2e+5<, result: float(200000) ->abc< += ><, result: int(0) ->abc< += >abc<, result: int(0) ->abc< += >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->9223372036854775807< += >0<, result: int(9223372036854775807) ->9223372036854775807< += >-10<, result: int(9223372036854775797) ->9223372036854775807< += >100<, result: float(9.2233720368548E+18) ->9223372036854775807< += >-34000000000<, result: float(9.2233720028548E+18) ->9223372036854775807< += >INF<, result: float(INF) ->9223372036854775807< += >-INF<, result: float(-INF) ->9223372036854775807< += >NAN<, result: float(NAN) ->9223372036854775807< += >1<, result: float(9.2233720368548E+18) ->9223372036854775807< += ><, result: int(9223372036854775807) ->9223372036854775807< += ><, result: int(9223372036854775807) ->9223372036854775807< += >123<, result: float(9.2233720368548E+18) ->9223372036854775807< += >2e+5<, result: float(9.223372036855E+18) ->9223372036854775807< += ><, result: int(9223372036854775807) ->9223372036854775807< += >abc<, result: int(9223372036854775807) ->9223372036854775807< += >9223372036854775807<, result: float(1.844674407371E+19) -------------------------------------- ->0< -= >0<, result: int(0) ->0< -= >-10<, result: int(10) ->0< -= >100<, result: int(-100) ->0< -= >-34000000000<, result: float(34000000000) ->0< -= >INF<, result: float(-INF) ->0< -= >-INF<, result: float(INF) ->0< -= >NAN<, result: float(NAN) ->0< -= >1<, result: int(-1) ->0< -= ><, result: int(0) ->0< -= ><, result: int(0) ->0< -= >123<, result: int(-123) ->0< -= >2e+5<, result: float(-200000) ->0< -= ><, result: int(0) ->0< -= >abc<, result: int(0) ->0< -= >9223372036854775807<, result: int(-9223372036854775807) -------------------------------------- ->-10< -= >0<, result: int(-10) ->-10< -= >-10<, result: int(0) ->-10< -= >100<, result: int(-110) ->-10< -= >-34000000000<, result: float(33999999990) ->-10< -= >INF<, result: float(-INF) ->-10< -= >-INF<, result: float(INF) ->-10< -= >NAN<, result: float(NAN) ->-10< -= >1<, result: int(-11) ->-10< -= ><, result: int(-10) ->-10< -= ><, result: int(-10) ->-10< -= >123<, result: int(-133) ->-10< -= >2e+5<, result: float(-200010) ->-10< -= ><, result: int(-10) ->-10< -= >abc<, result: int(-10) ->-10< -= >9223372036854775807<, result: float(-9.2233720368548E+18) -------------------------------------- ->100< -= >0<, result: int(100) ->100< -= >-10<, result: int(110) ->100< -= >100<, result: int(0) ->100< -= >-34000000000<, result: float(34000000100) ->100< -= >INF<, result: float(-INF) ->100< -= >-INF<, result: float(INF) ->100< -= >NAN<, result: float(NAN) ->100< -= >1<, result: int(99) ->100< -= ><, result: int(100) ->100< -= ><, result: int(100) ->100< -= >123<, result: int(-23) ->100< -= >2e+5<, result: float(-199900) ->100< -= ><, result: int(100) ->100< -= >abc<, result: int(100) ->100< -= >9223372036854775807<, result: int(-9223372036854775707) -------------------------------------- ->-34000000000< -= >0<, result: float(-34000000000) ->-34000000000< -= >-10<, result: float(-33999999990) ->-34000000000< -= >100<, result: float(-34000000100) ->-34000000000< -= >-34000000000<, result: float(0) ->-34000000000< -= >INF<, result: float(-INF) ->-34000000000< -= >-INF<, result: float(INF) ->-34000000000< -= >NAN<, result: float(NAN) ->-34000000000< -= >1<, result: float(-34000000001) ->-34000000000< -= ><, result: float(-34000000000) ->-34000000000< -= ><, result: float(-34000000000) ->-34000000000< -= >123<, result: float(-34000000123) ->-34000000000< -= >2e+5<, result: float(-34000200000) ->-34000000000< -= ><, result: float(-34000000000) ->-34000000000< -= >abc<, result: float(-34000000000) ->-34000000000< -= >9223372036854775807<, result: float(-9.2233720708548E+18) -------------------------------------- ->INF< -= >0<, result: float(INF) ->INF< -= >-10<, result: float(INF) ->INF< -= >100<, result: float(INF) ->INF< -= >-34000000000<, result: float(INF) ->INF< -= >INF<, result: float(NAN) ->INF< -= >-INF<, result: float(INF) ->INF< -= >NAN<, result: float(NAN) ->INF< -= >1<, result: float(INF) ->INF< -= ><, result: float(INF) ->INF< -= ><, result: float(INF) ->INF< -= >123<, result: float(INF) ->INF< -= >2e+5<, result: float(INF) ->INF< -= ><, result: float(INF) ->INF< -= >abc<, result: float(INF) ->INF< -= >9223372036854775807<, result: float(INF) -------------------------------------- ->-INF< -= >0<, result: float(-INF) ->-INF< -= >-10<, result: float(-INF) ->-INF< -= >100<, result: float(-INF) ->-INF< -= >-34000000000<, result: float(-INF) ->-INF< -= >INF<, result: float(-INF) ->-INF< -= >-INF<, result: float(NAN) ->-INF< -= >NAN<, result: float(NAN) ->-INF< -= >1<, result: float(-INF) ->-INF< -= ><, result: float(-INF) ->-INF< -= ><, result: float(-INF) ->-INF< -= >123<, result: float(-INF) ->-INF< -= >2e+5<, result: float(-INF) ->-INF< -= ><, result: float(-INF) ->-INF< -= >abc<, result: float(-INF) ->-INF< -= >9223372036854775807<, result: float(-INF) -------------------------------------- ->NAN< -= >0<, result: float(NAN) ->NAN< -= >-10<, result: float(NAN) ->NAN< -= >100<, result: float(NAN) ->NAN< -= >-34000000000<, result: float(NAN) ->NAN< -= >INF<, result: float(NAN) ->NAN< -= >-INF<, result: float(NAN) ->NAN< -= >NAN<, result: float(NAN) ->NAN< -= >1<, result: float(NAN) ->NAN< -= ><, result: float(NAN) ->NAN< -= ><, result: float(NAN) ->NAN< -= >123<, result: float(NAN) ->NAN< -= >2e+5<, result: float(NAN) ->NAN< -= ><, result: float(NAN) ->NAN< -= >abc<, result: float(NAN) ->NAN< -= >9223372036854775807<, result: float(NAN) -------------------------------------- ->1< -= >0<, result: int(1) ->1< -= >-10<, result: int(11) ->1< -= >100<, result: int(-99) ->1< -= >-34000000000<, result: float(34000000001) ->1< -= >INF<, result: float(-INF) ->1< -= >-INF<, result: float(INF) ->1< -= >NAN<, result: float(NAN) ->1< -= >1<, result: int(0) ->1< -= ><, result: int(1) ->1< -= ><, result: int(1) ->1< -= >123<, result: int(-122) ->1< -= >2e+5<, result: float(-199999) ->1< -= ><, result: int(1) ->1< -= >abc<, result: int(1) ->1< -= >9223372036854775807<, result: int(-9223372036854775806) -------------------------------------- ->< -= >0<, result: int(0) ->< -= >-10<, result: int(10) ->< -= >100<, result: int(-100) ->< -= >-34000000000<, result: float(34000000000) ->< -= >INF<, result: float(-INF) ->< -= >-INF<, result: float(INF) ->< -= >NAN<, result: float(NAN) ->< -= >1<, result: int(-1) ->< -= ><, result: int(0) ->< -= ><, result: int(0) ->< -= >123<, result: int(-123) ->< -= >2e+5<, result: float(-200000) ->< -= ><, result: int(0) ->< -= >abc<, result: int(0) ->< -= >9223372036854775807<, result: int(-9223372036854775807) -------------------------------------- ->< -= >0<, result: int(0) ->< -= >-10<, result: int(10) ->< -= >100<, result: int(-100) ->< -= >-34000000000<, result: float(34000000000) ->< -= >INF<, result: float(-INF) ->< -= >-INF<, result: float(INF) ->< -= >NAN<, result: float(NAN) ->< -= >1<, result: int(-1) ->< -= ><, result: int(0) ->< -= ><, result: int(0) ->< -= >123<, result: int(-123) ->< -= >2e+5<, result: float(-200000) ->< -= ><, result: int(0) ->< -= >abc<, result: int(0) ->< -= >9223372036854775807<, result: int(-9223372036854775807) -------------------------------------- ->123< -= >0<, result: int(123) ->123< -= >-10<, result: int(133) ->123< -= >100<, result: int(23) ->123< -= >-34000000000<, result: float(34000000123) ->123< -= >INF<, result: float(-INF) ->123< -= >-INF<, result: float(INF) ->123< -= >NAN<, result: float(NAN) ->123< -= >1<, result: int(122) ->123< -= ><, result: int(123) ->123< -= ><, result: int(123) ->123< -= >123<, result: int(0) ->123< -= >2e+5<, result: float(-199877) ->123< -= ><, result: int(123) ->123< -= >abc<, result: int(123) ->123< -= >9223372036854775807<, result: int(-9223372036854775684) -------------------------------------- ->2e+5< -= >0<, result: float(200000) ->2e+5< -= >-10<, result: float(200010) ->2e+5< -= >100<, result: float(199900) ->2e+5< -= >-34000000000<, result: float(34000200000) ->2e+5< -= >INF<, result: float(-INF) ->2e+5< -= >-INF<, result: float(INF) ->2e+5< -= >NAN<, result: float(NAN) ->2e+5< -= >1<, result: float(199999) ->2e+5< -= ><, result: float(200000) ->2e+5< -= ><, result: float(200000) ->2e+5< -= >123<, result: float(199877) ->2e+5< -= >2e+5<, result: float(0) ->2e+5< -= ><, result: float(200000) ->2e+5< -= >abc<, result: float(200000) ->2e+5< -= >9223372036854775807<, result: float(-9.2233720368546E+18) -------------------------------------- ->< -= >0<, result: int(0) ->< -= >-10<, result: int(10) ->< -= >100<, result: int(-100) ->< -= >-34000000000<, result: float(34000000000) ->< -= >INF<, result: float(-INF) ->< -= >-INF<, result: float(INF) ->< -= >NAN<, result: float(NAN) ->< -= >1<, result: int(-1) ->< -= ><, result: int(0) ->< -= ><, result: int(0) ->< -= >123<, result: int(-123) ->< -= >2e+5<, result: float(-200000) ->< -= ><, result: int(0) ->< -= >abc<, result: int(0) ->< -= >9223372036854775807<, result: int(-9223372036854775807) -------------------------------------- ->abc< -= >0<, result: int(0) ->abc< -= >-10<, result: int(10) ->abc< -= >100<, result: int(-100) ->abc< -= >-34000000000<, result: float(34000000000) ->abc< -= >INF<, result: float(-INF) ->abc< -= >-INF<, result: float(INF) ->abc< -= >NAN<, result: float(NAN) ->abc< -= >1<, result: int(-1) ->abc< -= ><, result: int(0) ->abc< -= ><, result: int(0) ->abc< -= >123<, result: int(-123) ->abc< -= >2e+5<, result: float(-200000) ->abc< -= ><, result: int(0) ->abc< -= >abc<, result: int(0) ->abc< -= >9223372036854775807<, result: int(-9223372036854775807) -------------------------------------- ->9223372036854775807< -= >0<, result: int(9223372036854775807) ->9223372036854775807< -= >-10<, result: float(9.2233720368548E+18) ->9223372036854775807< -= >100<, result: int(9223372036854775707) ->9223372036854775807< -= >-34000000000<, result: float(9.2233720708548E+18) ->9223372036854775807< -= >INF<, result: float(-INF) ->9223372036854775807< -= >-INF<, result: float(INF) ->9223372036854775807< -= >NAN<, result: float(NAN) ->9223372036854775807< -= >1<, result: int(9223372036854775806) ->9223372036854775807< -= ><, result: int(9223372036854775807) ->9223372036854775807< -= ><, result: int(9223372036854775807) ->9223372036854775807< -= >123<, result: int(9223372036854775684) ->9223372036854775807< -= >2e+5<, result: float(9.2233720368546E+18) ->9223372036854775807< -= ><, result: int(9223372036854775807) ->9223372036854775807< -= >abc<, result: int(9223372036854775807) ->9223372036854775807< -= >9223372036854775807<, result: int(0) -------------------------------------- ->0< .= >0<, result: string(2) "00" ->0< .= >-10<, result: string(4) "0-10" ->0< .= >100<, result: string(4) "0100" ->0< .= >-34000000000<, result: string(13) "0-34000000000" ->0< .= >INF<, result: string(4) "0INF" ->0< .= >-INF<, result: string(5) "0-INF" ->0< .= >NAN<, result: string(4) "0NAN" ->0< .= >1<, result: string(2) "01" ->0< .= ><, result: string(1) "0" ->0< .= ><, result: string(1) "0" ->0< .= >123<, result: string(4) "0123" ->0< .= >2e+5<, result: string(5) "02e+5" ->0< .= ><, result: string(1) "0" ->0< .= >abc<, result: string(4) "0abc" ->0< .= >9223372036854775807<, result: string(20) "09223372036854775807" -------------------------------------- ->-10< .= >0<, result: string(4) "-100" ->-10< .= >-10<, result: string(6) "-10-10" ->-10< .= >100<, result: string(6) "-10100" ->-10< .= >-34000000000<, result: string(15) "-10-34000000000" ->-10< .= >INF<, result: string(6) "-10INF" ->-10< .= >-INF<, result: string(7) "-10-INF" ->-10< .= >NAN<, result: string(6) "-10NAN" ->-10< .= >1<, result: string(4) "-101" ->-10< .= ><, result: string(3) "-10" ->-10< .= ><, result: string(3) "-10" ->-10< .= >123<, result: string(6) "-10123" ->-10< .= >2e+5<, result: string(7) "-102e+5" ->-10< .= ><, result: string(3) "-10" ->-10< .= >abc<, result: string(6) "-10abc" ->-10< .= >9223372036854775807<, result: string(22) "-109223372036854775807" -------------------------------------- ->100< .= >0<, result: string(4) "1000" ->100< .= >-10<, result: string(6) "100-10" ->100< .= >100<, result: string(6) "100100" ->100< .= >-34000000000<, result: string(15) "100-34000000000" ->100< .= >INF<, result: string(6) "100INF" ->100< .= >-INF<, result: string(7) "100-INF" ->100< .= >NAN<, result: string(6) "100NAN" ->100< .= >1<, result: string(4) "1001" ->100< .= ><, result: string(3) "100" ->100< .= ><, result: string(3) "100" ->100< .= >123<, result: string(6) "100123" ->100< .= >2e+5<, result: string(7) "1002e+5" ->100< .= ><, result: string(3) "100" ->100< .= >abc<, result: string(6) "100abc" ->100< .= >9223372036854775807<, result: string(22) "1009223372036854775807" -------------------------------------- ->-34000000000< .= >0<, result: string(13) "-340000000000" ->-34000000000< .= >-10<, result: string(15) "-34000000000-10" ->-34000000000< .= >100<, result: string(15) "-34000000000100" ->-34000000000< .= >-34000000000<, result: string(24) "-34000000000-34000000000" ->-34000000000< .= >INF<, result: string(15) "-34000000000INF" ->-34000000000< .= >-INF<, result: string(16) "-34000000000-INF" ->-34000000000< .= >NAN<, result: string(15) "-34000000000NAN" ->-34000000000< .= >1<, result: string(13) "-340000000001" ->-34000000000< .= ><, result: string(12) "-34000000000" ->-34000000000< .= ><, result: string(12) "-34000000000" ->-34000000000< .= >123<, result: string(15) "-34000000000123" ->-34000000000< .= >2e+5<, result: string(16) "-340000000002e+5" ->-34000000000< .= ><, result: string(12) "-34000000000" ->-34000000000< .= >abc<, result: string(15) "-34000000000abc" ->-34000000000< .= >9223372036854775807<, result: string(31) "-340000000009223372036854775807" -------------------------------------- ->INF< .= >0<, result: string(4) "INF0" ->INF< .= >-10<, result: string(6) "INF-10" ->INF< .= >100<, result: string(6) "INF100" ->INF< .= >-34000000000<, result: string(15) "INF-34000000000" ->INF< .= >INF<, result: string(6) "INFINF" ->INF< .= >-INF<, result: string(7) "INF-INF" ->INF< .= >NAN<, result: string(6) "INFNAN" ->INF< .= >1<, result: string(4) "INF1" ->INF< .= ><, result: string(3) "INF" ->INF< .= ><, result: string(3) "INF" ->INF< .= >123<, result: string(6) "INF123" ->INF< .= >2e+5<, result: string(7) "INF2e+5" ->INF< .= ><, result: string(3) "INF" ->INF< .= >abc<, result: string(6) "INFabc" ->INF< .= >9223372036854775807<, result: string(22) "INF9223372036854775807" -------------------------------------- ->-INF< .= >0<, result: string(5) "-INF0" ->-INF< .= >-10<, result: string(7) "-INF-10" ->-INF< .= >100<, result: string(7) "-INF100" ->-INF< .= >-34000000000<, result: string(16) "-INF-34000000000" ->-INF< .= >INF<, result: string(7) "-INFINF" ->-INF< .= >-INF<, result: string(8) "-INF-INF" ->-INF< .= >NAN<, result: string(7) "-INFNAN" ->-INF< .= >1<, result: string(5) "-INF1" ->-INF< .= ><, result: string(4) "-INF" ->-INF< .= ><, result: string(4) "-INF" ->-INF< .= >123<, result: string(7) "-INF123" ->-INF< .= >2e+5<, result: string(8) "-INF2e+5" ->-INF< .= ><, result: string(4) "-INF" ->-INF< .= >abc<, result: string(7) "-INFabc" ->-INF< .= >9223372036854775807<, result: string(23) "-INF9223372036854775807" -------------------------------------- ->NAN< .= >0<, result: string(4) "NAN0" ->NAN< .= >-10<, result: string(6) "NAN-10" ->NAN< .= >100<, result: string(6) "NAN100" ->NAN< .= >-34000000000<, result: string(15) "NAN-34000000000" ->NAN< .= >INF<, result: string(6) "NANINF" ->NAN< .= >-INF<, result: string(7) "NAN-INF" ->NAN< .= >NAN<, result: string(6) "NANNAN" ->NAN< .= >1<, result: string(4) "NAN1" ->NAN< .= ><, result: string(3) "NAN" ->NAN< .= ><, result: string(3) "NAN" ->NAN< .= >123<, result: string(6) "NAN123" ->NAN< .= >2e+5<, result: string(7) "NAN2e+5" ->NAN< .= ><, result: string(3) "NAN" ->NAN< .= >abc<, result: string(6) "NANabc" ->NAN< .= >9223372036854775807<, result: string(22) "NAN9223372036854775807" -------------------------------------- ->1< .= >0<, result: string(2) "10" ->1< .= >-10<, result: string(4) "1-10" ->1< .= >100<, result: string(4) "1100" ->1< .= >-34000000000<, result: string(13) "1-34000000000" ->1< .= >INF<, result: string(4) "1INF" ->1< .= >-INF<, result: string(5) "1-INF" ->1< .= >NAN<, result: string(4) "1NAN" ->1< .= >1<, result: string(2) "11" ->1< .= ><, result: string(1) "1" ->1< .= ><, result: string(1) "1" ->1< .= >123<, result: string(4) "1123" ->1< .= >2e+5<, result: string(5) "12e+5" ->1< .= ><, result: string(1) "1" ->1< .= >abc<, result: string(4) "1abc" ->1< .= >9223372036854775807<, result: string(20) "19223372036854775807" -------------------------------------- ->< .= >0<, result: string(1) "0" ->< .= >-10<, result: string(3) "-10" ->< .= >100<, result: string(3) "100" ->< .= >-34000000000<, result: string(12) "-34000000000" ->< .= >INF<, result: string(3) "INF" ->< .= >-INF<, result: string(4) "-INF" ->< .= >NAN<, result: string(3) "NAN" ->< .= >1<, result: string(1) "1" ->< .= ><, result: string(0) "" ->< .= ><, result: string(0) "" ->< .= >123<, result: string(3) "123" ->< .= >2e+5<, result: string(4) "2e+5" ->< .= ><, result: string(0) "" ->< .= >abc<, result: string(3) "abc" ->< .= >9223372036854775807<, result: string(19) "9223372036854775807" -------------------------------------- ->< .= >0<, result: string(1) "0" ->< .= >-10<, result: string(3) "-10" ->< .= >100<, result: string(3) "100" ->< .= >-34000000000<, result: string(12) "-34000000000" ->< .= >INF<, result: string(3) "INF" ->< .= >-INF<, result: string(4) "-INF" ->< .= >NAN<, result: string(3) "NAN" ->< .= >1<, result: string(1) "1" ->< .= ><, result: string(0) "" ->< .= ><, result: string(0) "" ->< .= >123<, result: string(3) "123" ->< .= >2e+5<, result: string(4) "2e+5" ->< .= ><, result: string(0) "" ->< .= >abc<, result: string(3) "abc" ->< .= >9223372036854775807<, result: string(19) "9223372036854775807" -------------------------------------- ->123< .= >0<, result: string(4) "1230" ->123< .= >-10<, result: string(6) "123-10" ->123< .= >100<, result: string(6) "123100" ->123< .= >-34000000000<, result: string(15) "123-34000000000" ->123< .= >INF<, result: string(6) "123INF" ->123< .= >-INF<, result: string(7) "123-INF" ->123< .= >NAN<, result: string(6) "123NAN" ->123< .= >1<, result: string(4) "1231" ->123< .= ><, result: string(3) "123" ->123< .= ><, result: string(3) "123" ->123< .= >123<, result: string(6) "123123" ->123< .= >2e+5<, result: string(7) "1232e+5" ->123< .= ><, result: string(3) "123" ->123< .= >abc<, result: string(6) "123abc" ->123< .= >9223372036854775807<, result: string(22) "1239223372036854775807" -------------------------------------- ->2e+5< .= >0<, result: string(5) "2e+50" ->2e+5< .= >-10<, result: string(7) "2e+5-10" ->2e+5< .= >100<, result: string(7) "2e+5100" ->2e+5< .= >-34000000000<, result: string(16) "2e+5-34000000000" ->2e+5< .= >INF<, result: string(7) "2e+5INF" ->2e+5< .= >-INF<, result: string(8) "2e+5-INF" ->2e+5< .= >NAN<, result: string(7) "2e+5NAN" ->2e+5< .= >1<, result: string(5) "2e+51" ->2e+5< .= ><, result: string(4) "2e+5" ->2e+5< .= ><, result: string(4) "2e+5" ->2e+5< .= >123<, result: string(7) "2e+5123" ->2e+5< .= >2e+5<, result: string(8) "2e+52e+5" ->2e+5< .= ><, result: string(4) "2e+5" ->2e+5< .= >abc<, result: string(7) "2e+5abc" ->2e+5< .= >9223372036854775807<, result: string(23) "2e+59223372036854775807" -------------------------------------- ->< .= >0<, result: string(1) "0" ->< .= >-10<, result: string(3) "-10" ->< .= >100<, result: string(3) "100" ->< .= >-34000000000<, result: string(12) "-34000000000" ->< .= >INF<, result: string(3) "INF" ->< .= >-INF<, result: string(4) "-INF" ->< .= >NAN<, result: string(3) "NAN" ->< .= >1<, result: string(1) "1" ->< .= ><, result: string(0) "" ->< .= ><, result: string(0) "" ->< .= >123<, result: string(3) "123" ->< .= >2e+5<, result: string(4) "2e+5" ->< .= ><, result: string(0) "" ->< .= >abc<, result: string(3) "abc" ->< .= >9223372036854775807<, result: string(19) "9223372036854775807" -------------------------------------- ->abc< .= >0<, result: string(4) "abc0" ->abc< .= >-10<, result: string(6) "abc-10" ->abc< .= >100<, result: string(6) "abc100" ->abc< .= >-34000000000<, result: string(15) "abc-34000000000" ->abc< .= >INF<, result: string(6) "abcINF" ->abc< .= >-INF<, result: string(7) "abc-INF" ->abc< .= >NAN<, result: string(6) "abcNAN" ->abc< .= >1<, result: string(4) "abc1" ->abc< .= ><, result: string(3) "abc" ->abc< .= ><, result: string(3) "abc" ->abc< .= >123<, result: string(6) "abc123" ->abc< .= >2e+5<, result: string(7) "abc2e+5" ->abc< .= ><, result: string(3) "abc" ->abc< .= >abc<, result: string(6) "abcabc" ->abc< .= >9223372036854775807<, result: string(22) "abc9223372036854775807" -------------------------------------- ->9223372036854775807< .= >0<, result: string(20) "92233720368547758070" ->9223372036854775807< .= >-10<, result: string(22) "9223372036854775807-10" ->9223372036854775807< .= >100<, result: string(22) "9223372036854775807100" ->9223372036854775807< .= >-34000000000<, result: string(31) "9223372036854775807-34000000000" ->9223372036854775807< .= >INF<, result: string(22) "9223372036854775807INF" ->9223372036854775807< .= >-INF<, result: string(23) "9223372036854775807-INF" ->9223372036854775807< .= >NAN<, result: string(22) "9223372036854775807NAN" ->9223372036854775807< .= >1<, result: string(20) "92233720368547758071" ->9223372036854775807< .= ><, result: string(19) "9223372036854775807" ->9223372036854775807< .= ><, result: string(19) "9223372036854775807" ->9223372036854775807< .= >123<, result: string(22) "9223372036854775807123" ->9223372036854775807< .= >2e+5<, result: string(23) "92233720368547758072e+5" ->9223372036854775807< .= ><, result: string(19) "9223372036854775807" ->9223372036854775807< .= >abc<, result: string(22) "9223372036854775807abc" ->9223372036854775807< .= >9223372036854775807<, result: string(38) "92233720368547758079223372036854775807" -------------------------------------- ->0< <<= >0<, result: int(0) ->0< <<= >-10<, result: int(0) ->0< <<= >100<, result: int(0) ->0< <<= >-34000000000<, result: int(0) ->0< <<= >1<, result: int(0) ->0< <<= ><, result: int(0) ->0< <<= ><, result: int(0) ->0< <<= >123<, result: int(0) ->0< <<= >2e+5<, result: int(0) ->0< <<= ><, result: int(0) ->0< <<= >abc<, result: int(0) ->0< <<= >9223372036854775807<, result: int(0) -------------------------------------- ->-10< <<= >0<, result: int(-10) ->-10< <<= >-10<, result: int(-180143985094819840) ->-10< <<= >100<, result: int(-687194767360) ->-10< <<= >-34000000000<, result: int(-10) ->-10< <<= >1<, result: int(-20) ->-10< <<= ><, result: int(-10) ->-10< <<= ><, result: int(-10) ->-10< <<= >123<, result: int(-5764607523034234880) ->-10< <<= >2e+5<, result: int(-40) ->-10< <<= ><, result: int(-10) ->-10< <<= >abc<, result: int(-10) ->-10< <<= >9223372036854775807<, result: int(0) -------------------------------------- ->100< <<= >0<, result: int(100) ->100< <<= >-10<, result: int(1801439850948198400) ->100< <<= >100<, result: int(6871947673600) ->100< <<= >-34000000000<, result: int(100) ->100< <<= >1<, result: int(200) ->100< <<= ><, result: int(100) ->100< <<= ><, result: int(100) ->100< <<= >123<, result: int(2305843009213693952) ->100< <<= >2e+5<, result: int(400) ->100< <<= ><, result: int(100) ->100< <<= >abc<, result: int(100) ->100< <<= >9223372036854775807<, result: int(0) -------------------------------------- ->-34000000000< <<= >0<, result: int(-34000000000) ->-34000000000< <<= >-10<, result: int(0) ->-34000000000< <<= >100<, result: int(6274288337113055232) ->-34000000000< <<= >-34000000000<, result: int(-34000000000) ->-34000000000< <<= >1<, result: int(-68000000000) ->-34000000000< <<= ><, result: int(-34000000000) ->-34000000000< <<= ><, result: int(-34000000000) ->-34000000000< <<= >123<, result: int(0) ->-34000000000< <<= >2e+5<, result: int(-136000000000) ->-34000000000< <<= ><, result: int(-34000000000) ->-34000000000< <<= >abc<, result: int(-34000000000) ->-34000000000< <<= >9223372036854775807<, result: int(0) -------------------------------------- ->1< <<= >0<, result: int(1) ->1< <<= >-10<, result: int(18014398509481984) ->1< <<= >100<, result: int(68719476736) ->1< <<= >-34000000000<, result: int(1) ->1< <<= >1<, result: int(2) ->1< <<= ><, result: int(1) ->1< <<= ><, result: int(1) ->1< <<= >123<, result: int(576460752303423488) ->1< <<= >2e+5<, result: int(4) ->1< <<= ><, result: int(1) ->1< <<= >abc<, result: int(1) ->1< <<= >9223372036854775807<, result: int(-9223372036854775808) -------------------------------------- ->< <<= >0<, result: int(0) ->< <<= >-10<, result: int(0) ->< <<= >100<, result: int(0) ->< <<= >-34000000000<, result: int(0) ->< <<= >1<, result: int(0) ->< <<= ><, result: int(0) ->< <<= ><, result: int(0) ->< <<= >123<, result: int(0) ->< <<= >2e+5<, result: int(0) ->< <<= ><, result: int(0) ->< <<= >abc<, result: int(0) ->< <<= >9223372036854775807<, result: int(0) -------------------------------------- ->< <<= >0<, result: int(0) ->< <<= >-10<, result: int(0) ->< <<= >100<, result: int(0) ->< <<= >-34000000000<, result: int(0) ->< <<= >1<, result: int(0) ->< <<= ><, result: int(0) ->< <<= ><, result: int(0) ->< <<= >123<, result: int(0) ->< <<= >2e+5<, result: int(0) ->< <<= ><, result: int(0) ->< <<= >abc<, result: int(0) ->< <<= >9223372036854775807<, result: int(0) -------------------------------------- ->123< <<= >0<, result: int(123) ->123< <<= >-10<, result: int(2215771016666284032) ->123< <<= >100<, result: int(8452495638528) ->123< <<= >-34000000000<, result: int(123) ->123< <<= >1<, result: int(246) ->123< <<= ><, result: int(123) ->123< <<= ><, result: int(123) ->123< <<= >123<, result: int(-2882303761517117440) ->123< <<= >2e+5<, result: int(492) ->123< <<= ><, result: int(123) ->123< <<= >abc<, result: int(123) ->123< <<= >9223372036854775807<, result: int(-9223372036854775808) -------------------------------------- ->2e+5< <<= >0<, result: int(2) ->2e+5< <<= >-10<, result: int(36028797018963968) ->2e+5< <<= >100<, result: int(137438953472) ->2e+5< <<= >-34000000000<, result: int(2) ->2e+5< <<= >1<, result: int(4) ->2e+5< <<= ><, result: int(2) ->2e+5< <<= ><, result: int(2) ->2e+5< <<= >123<, result: int(1152921504606846976) ->2e+5< <<= >2e+5<, result: int(8) ->2e+5< <<= ><, result: int(2) ->2e+5< <<= >abc<, result: int(2) ->2e+5< <<= >9223372036854775807<, result: int(0) -------------------------------------- ->< <<= >0<, result: int(0) ->< <<= >-10<, result: int(0) ->< <<= >100<, result: int(0) ->< <<= >-34000000000<, result: int(0) ->< <<= >1<, result: int(0) ->< <<= ><, result: int(0) ->< <<= ><, result: int(0) ->< <<= >123<, result: int(0) ->< <<= >2e+5<, result: int(0) ->< <<= ><, result: int(0) ->< <<= >abc<, result: int(0) ->< <<= >9223372036854775807<, result: int(0) -------------------------------------- ->abc< <<= >0<, result: int(0) ->abc< <<= >-10<, result: int(0) ->abc< <<= >100<, result: int(0) ->abc< <<= >-34000000000<, result: int(0) ->abc< <<= >1<, result: int(0) ->abc< <<= ><, result: int(0) ->abc< <<= ><, result: int(0) ->abc< <<= >123<, result: int(0) ->abc< <<= >2e+5<, result: int(0) ->abc< <<= ><, result: int(0) ->abc< <<= >abc<, result: int(0) ->abc< <<= >9223372036854775807<, result: int(0) -------------------------------------- ->9223372036854775807< <<= >0<, result: int(9223372036854775807) ->9223372036854775807< <<= >-10<, result: int(-18014398509481984) ->9223372036854775807< <<= >100<, result: int(-68719476736) ->9223372036854775807< <<= >-34000000000<, result: int(9223372036854775807) ->9223372036854775807< <<= >1<, result: int(-2) ->9223372036854775807< <<= ><, result: int(9223372036854775807) ->9223372036854775807< <<= ><, result: int(9223372036854775807) ->9223372036854775807< <<= >123<, result: int(-576460752303423488) ->9223372036854775807< <<= >2e+5<, result: int(-4) ->9223372036854775807< <<= ><, result: int(9223372036854775807) ->9223372036854775807< <<= >abc<, result: int(9223372036854775807) ->9223372036854775807< <<= >9223372036854775807<, result: int(-9223372036854775808) -------------------------------------- ->0< >>= >0<, result: int(0) ->0< >>= >-10<, result: int(0) ->0< >>= >100<, result: int(0) ->0< >>= >-34000000000<, result: int(0) ->0< >>= >1<, result: int(0) ->0< >>= ><, result: int(0) ->0< >>= ><, result: int(0) ->0< >>= >123<, result: int(0) ->0< >>= >2e+5<, result: int(0) ->0< >>= ><, result: int(0) ->0< >>= >abc<, result: int(0) ->0< >>= >9223372036854775807<, result: int(0) -------------------------------------- ->-10< >>= >0<, result: int(-10) ->-10< >>= >-10<, result: int(-1) ->-10< >>= >100<, result: int(-1) ->-10< >>= >-34000000000<, result: int(-10) ->-10< >>= >1<, result: int(-5) ->-10< >>= ><, result: int(-10) ->-10< >>= ><, result: int(-10) ->-10< >>= >123<, result: int(-1) ->-10< >>= >2e+5<, result: int(-3) ->-10< >>= ><, result: int(-10) ->-10< >>= >abc<, result: int(-10) ->-10< >>= >9223372036854775807<, result: int(-1) -------------------------------------- ->100< >>= >0<, result: int(100) ->100< >>= >-10<, result: int(0) ->100< >>= >100<, result: int(0) ->100< >>= >-34000000000<, result: int(100) ->100< >>= >1<, result: int(50) ->100< >>= ><, result: int(100) ->100< >>= ><, result: int(100) ->100< >>= >123<, result: int(0) ->100< >>= >2e+5<, result: int(25) ->100< >>= ><, result: int(100) ->100< >>= >abc<, result: int(100) ->100< >>= >9223372036854775807<, result: int(0) -------------------------------------- ->-34000000000< >>= >0<, result: int(-34000000000) ->-34000000000< >>= >-10<, result: int(-1) ->-34000000000< >>= >100<, result: int(-1) ->-34000000000< >>= >-34000000000<, result: int(-34000000000) ->-34000000000< >>= >1<, result: int(-17000000000) ->-34000000000< >>= ><, result: int(-34000000000) ->-34000000000< >>= ><, result: int(-34000000000) ->-34000000000< >>= >123<, result: int(-1) ->-34000000000< >>= >2e+5<, result: int(-8500000000) ->-34000000000< >>= ><, result: int(-34000000000) ->-34000000000< >>= >abc<, result: int(-34000000000) ->-34000000000< >>= >9223372036854775807<, result: int(-1) -------------------------------------- ->1< >>= >0<, result: int(1) ->1< >>= >-10<, result: int(0) ->1< >>= >100<, result: int(0) ->1< >>= >-34000000000<, result: int(1) ->1< >>= >1<, result: int(0) ->1< >>= ><, result: int(1) ->1< >>= ><, result: int(1) ->1< >>= >123<, result: int(0) ->1< >>= >2e+5<, result: int(0) ->1< >>= ><, result: int(1) ->1< >>= >abc<, result: int(1) ->1< >>= >9223372036854775807<, result: int(0) -------------------------------------- ->< >>= >0<, result: int(0) ->< >>= >-10<, result: int(0) ->< >>= >100<, result: int(0) ->< >>= >-34000000000<, result: int(0) ->< >>= >1<, result: int(0) ->< >>= ><, result: int(0) ->< >>= ><, result: int(0) ->< >>= >123<, result: int(0) ->< >>= >2e+5<, result: int(0) ->< >>= ><, result: int(0) ->< >>= >abc<, result: int(0) ->< >>= >9223372036854775807<, result: int(0) -------------------------------------- ->< >>= >0<, result: int(0) ->< >>= >-10<, result: int(0) ->< >>= >100<, result: int(0) ->< >>= >-34000000000<, result: int(0) ->< >>= >1<, result: int(0) ->< >>= ><, result: int(0) ->< >>= ><, result: int(0) ->< >>= >123<, result: int(0) ->< >>= >2e+5<, result: int(0) ->< >>= ><, result: int(0) ->< >>= >abc<, result: int(0) ->< >>= >9223372036854775807<, result: int(0) -------------------------------------- ->123< >>= >0<, result: int(123) ->123< >>= >-10<, result: int(0) ->123< >>= >100<, result: int(0) ->123< >>= >-34000000000<, result: int(123) ->123< >>= >1<, result: int(61) ->123< >>= ><, result: int(123) ->123< >>= ><, result: int(123) ->123< >>= >123<, result: int(0) ->123< >>= >2e+5<, result: int(30) ->123< >>= ><, result: int(123) ->123< >>= >abc<, result: int(123) ->123< >>= >9223372036854775807<, result: int(0) -------------------------------------- ->2e+5< >>= >0<, result: int(2) ->2e+5< >>= >-10<, result: int(0) ->2e+5< >>= >100<, result: int(0) ->2e+5< >>= >-34000000000<, result: int(2) ->2e+5< >>= >1<, result: int(1) ->2e+5< >>= ><, result: int(2) ->2e+5< >>= ><, result: int(2) ->2e+5< >>= >123<, result: int(0) ->2e+5< >>= >2e+5<, result: int(0) ->2e+5< >>= ><, result: int(2) ->2e+5< >>= >abc<, result: int(2) ->2e+5< >>= >9223372036854775807<, result: int(0) -------------------------------------- ->< >>= >0<, result: int(0) ->< >>= >-10<, result: int(0) ->< >>= >100<, result: int(0) ->< >>= >-34000000000<, result: int(0) ->< >>= >1<, result: int(0) ->< >>= ><, result: int(0) ->< >>= ><, result: int(0) ->< >>= >123<, result: int(0) ->< >>= >2e+5<, result: int(0) ->< >>= ><, result: int(0) ->< >>= >abc<, result: int(0) ->< >>= >9223372036854775807<, result: int(0) -------------------------------------- ->abc< >>= >0<, result: int(0) ->abc< >>= >-10<, result: int(0) ->abc< >>= >100<, result: int(0) ->abc< >>= >-34000000000<, result: int(0) ->abc< >>= >1<, result: int(0) ->abc< >>= ><, result: int(0) ->abc< >>= ><, result: int(0) ->abc< >>= >123<, result: int(0) ->abc< >>= >2e+5<, result: int(0) ->abc< >>= ><, result: int(0) ->abc< >>= >abc<, result: int(0) ->abc< >>= >9223372036854775807<, result: int(0) -------------------------------------- ->9223372036854775807< >>= >0<, result: int(9223372036854775807) ->9223372036854775807< >>= >-10<, result: int(511) ->9223372036854775807< >>= >100<, result: int(134217727) ->9223372036854775807< >>= >-34000000000<, result: int(9223372036854775807) ->9223372036854775807< >>= >1<, result: int(4611686018427387903) ->9223372036854775807< >>= ><, result: int(9223372036854775807) ->9223372036854775807< >>= ><, result: int(9223372036854775807) ->9223372036854775807< >>= >123<, result: int(15) ->9223372036854775807< >>= >2e+5<, result: int(2305843009213693951) ->9223372036854775807< >>= ><, result: int(9223372036854775807) ->9223372036854775807< >>= >abc<, result: int(9223372036854775807) ->9223372036854775807< >>= >9223372036854775807<, result: int(0) -------------------------------------- ->0< &= >0<, result: int(0) ->0< &= >-10<, result: int(0) ->0< &= >100<, result: int(0) ->0< &= >-34000000000<, result: int(0) ->0< &= >1<, result: int(0) ->0< &= ><, result: int(0) ->0< &= ><, result: int(0) ->0< &= >123<, result: int(0) ->0< &= >2e+5<, result: int(0) ->0< &= ><, result: int(0) ->0< &= >abc<, result: int(0) ->0< &= >9223372036854775807<, result: int(0) -------------------------------------- ->-10< &= >0<, result: int(0) ->-10< &= >-10<, result: int(-10) ->-10< &= >100<, result: int(100) ->-10< &= >-34000000000<, result: int(-34000000000) ->-10< &= >1<, result: int(0) ->-10< &= ><, result: int(0) ->-10< &= ><, result: int(0) ->-10< &= >123<, result: int(114) ->-10< &= >2e+5<, result: int(2) ->-10< &= ><, result: int(0) ->-10< &= >abc<, result: int(0) ->-10< &= >9223372036854775807<, result: int(9223372036854775798) -------------------------------------- ->100< &= >0<, result: int(0) ->100< &= >-10<, result: int(100) ->100< &= >100<, result: int(100) ->100< &= >-34000000000<, result: int(0) ->100< &= >1<, result: int(0) ->100< &= ><, result: int(0) ->100< &= ><, result: int(0) ->100< &= >123<, result: int(96) ->100< &= >2e+5<, result: int(0) ->100< &= ><, result: int(0) ->100< &= >abc<, result: int(0) ->100< &= >9223372036854775807<, result: int(100) -------------------------------------- ->-34000000000< &= >0<, result: int(0) ->-34000000000< &= >-10<, result: int(-34000000000) ->-34000000000< &= >100<, result: int(0) ->-34000000000< &= >-34000000000<, result: int(-34000000000) ->-34000000000< &= >1<, result: int(0) ->-34000000000< &= ><, result: int(0) ->-34000000000< &= ><, result: int(0) ->-34000000000< &= >123<, result: int(0) ->-34000000000< &= >2e+5<, result: int(0) ->-34000000000< &= ><, result: int(0) ->-34000000000< &= >abc<, result: int(0) ->-34000000000< &= >9223372036854775807<, result: int(9223372002854775808) -------------------------------------- ->1< &= >0<, result: int(0) ->1< &= >-10<, result: int(0) ->1< &= >100<, result: int(0) ->1< &= >-34000000000<, result: int(0) ->1< &= >1<, result: int(1) ->1< &= ><, result: int(0) ->1< &= ><, result: int(0) ->1< &= >123<, result: int(1) ->1< &= >2e+5<, result: int(0) ->1< &= ><, result: int(0) ->1< &= >abc<, result: int(0) ->1< &= >9223372036854775807<, result: int(1) -------------------------------------- ->< &= >0<, result: int(0) ->< &= >-10<, result: int(0) ->< &= >100<, result: int(0) ->< &= >-34000000000<, result: int(0) ->< &= >1<, result: int(0) ->< &= ><, result: int(0) ->< &= ><, result: int(0) ->< &= >123<, result: int(0) ->< &= >2e+5<, result: int(0) ->< &= ><, result: int(0) ->< &= >abc<, result: int(0) ->< &= >9223372036854775807<, result: int(0) -------------------------------------- ->< &= >0<, result: int(0) ->< &= >-10<, result: int(0) ->< &= >100<, result: int(0) ->< &= >-34000000000<, result: int(0) ->< &= >1<, result: int(0) ->< &= ><, result: int(0) ->< &= ><, result: int(0) ->< &= >123<, result: int(0) ->< &= >2e+5<, result: int(0) ->< &= ><, result: int(0) ->< &= >abc<, result: int(0) ->< &= >9223372036854775807<, result: int(0) -------------------------------------- ->123< &= >0<, result: int(0) ->123< &= >-10<, result: int(114) ->123< &= >100<, result: int(96) ->123< &= >-34000000000<, result: int(0) ->123< &= >1<, result: int(1) ->123< &= ><, result: int(0) ->123< &= ><, result: int(0) ->123< &= >123<, result: string(3) "123" ->123< &= >2e+5<, result: string(3) "0 #" ->123< &= ><, result: string(0) "" ->123< &= >abc<, result: string(3) "!"#" ->123< &= >9223372036854775807<, result: int(123) -------------------------------------- ->2e+5< &= >0<, result: int(0) ->2e+5< &= >-10<, result: int(2) ->2e+5< &= >100<, result: int(0) ->2e+5< &= >-34000000000<, result: int(0) ->2e+5< &= >1<, result: int(0) ->2e+5< &= ><, result: int(0) ->2e+5< &= ><, result: int(0) ->2e+5< &= >123<, result: string(3) "0 #" ->2e+5< &= >2e+5<, result: string(4) "2e+5" ->2e+5< &= ><, result: string(0) "" ->2e+5< &= >abc<, result: string(3) " `#" ->2e+5< &= >9223372036854775807<, result: int(2) -------------------------------------- ->< &= >0<, result: int(0) ->< &= >-10<, result: int(0) ->< &= >100<, result: int(0) ->< &= >-34000000000<, result: int(0) ->< &= >1<, result: int(0) ->< &= ><, result: int(0) ->< &= ><, result: int(0) ->< &= >123<, result: string(0) "" ->< &= >2e+5<, result: string(0) "" ->< &= ><, result: string(0) "" ->< &= >abc<, result: string(0) "" ->< &= >9223372036854775807<, result: int(0) -------------------------------------- ->abc< &= >0<, result: int(0) ->abc< &= >-10<, result: int(0) ->abc< &= >100<, result: int(0) ->abc< &= >-34000000000<, result: int(0) ->abc< &= >1<, result: int(0) ->abc< &= ><, result: int(0) ->abc< &= ><, result: int(0) ->abc< &= >123<, result: string(3) "!"#" ->abc< &= >2e+5<, result: string(3) " `#" ->abc< &= ><, result: string(0) "" ->abc< &= >abc<, result: string(3) "abc" ->abc< &= >9223372036854775807<, result: int(0) -------------------------------------- ->9223372036854775807< &= >0<, result: int(0) ->9223372036854775807< &= >-10<, result: int(9223372036854775798) ->9223372036854775807< &= >100<, result: int(100) ->9223372036854775807< &= >-34000000000<, result: int(9223372002854775808) ->9223372036854775807< &= >1<, result: int(1) ->9223372036854775807< &= ><, result: int(0) ->9223372036854775807< &= ><, result: int(0) ->9223372036854775807< &= >123<, result: int(123) ->9223372036854775807< &= >2e+5<, result: int(2) ->9223372036854775807< &= ><, result: int(0) ->9223372036854775807< &= >abc<, result: int(0) ->9223372036854775807< &= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->0< ^= >0<, result: int(0) ->0< ^= >-10<, result: int(-10) ->0< ^= >100<, result: int(100) ->0< ^= >-34000000000<, result: int(-34000000000) ->0< ^= >1<, result: int(1) ->0< ^= ><, result: int(0) ->0< ^= ><, result: int(0) ->0< ^= >123<, result: int(123) ->0< ^= >2e+5<, result: int(2) ->0< ^= ><, result: int(0) ->0< ^= >abc<, result: int(0) ->0< ^= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->-10< ^= >0<, result: int(-10) ->-10< ^= >-10<, result: int(0) ->-10< ^= >100<, result: int(-110) ->-10< ^= >-34000000000<, result: int(33999999990) ->-10< ^= >1<, result: int(-9) ->-10< ^= ><, result: int(-10) ->-10< ^= ><, result: int(-10) ->-10< ^= >123<, result: int(-115) ->-10< ^= >2e+5<, result: int(-12) ->-10< ^= ><, result: int(-10) ->-10< ^= >abc<, result: int(-10) ->-10< ^= >9223372036854775807<, result: int(-9223372036854775799) -------------------------------------- ->100< ^= >0<, result: int(100) ->100< ^= >-10<, result: int(-110) ->100< ^= >100<, result: int(0) ->100< ^= >-34000000000<, result: int(-33999999900) ->100< ^= >1<, result: int(101) ->100< ^= ><, result: int(100) ->100< ^= ><, result: int(100) ->100< ^= >123<, result: int(31) ->100< ^= >2e+5<, result: int(102) ->100< ^= ><, result: int(100) ->100< ^= >abc<, result: int(100) ->100< ^= >9223372036854775807<, result: int(9223372036854775707) -------------------------------------- ->-34000000000< ^= >0<, result: int(-34000000000) ->-34000000000< ^= >-10<, result: int(33999999990) ->-34000000000< ^= >100<, result: int(-33999999900) ->-34000000000< ^= >-34000000000<, result: int(0) ->-34000000000< ^= >1<, result: int(-33999999999) ->-34000000000< ^= ><, result: int(-34000000000) ->-34000000000< ^= ><, result: int(-34000000000) ->-34000000000< ^= >123<, result: int(-33999999877) ->-34000000000< ^= >2e+5<, result: int(-33999999998) ->-34000000000< ^= ><, result: int(-34000000000) ->-34000000000< ^= >abc<, result: int(-34000000000) ->-34000000000< ^= >9223372036854775807<, result: int(-9223372002854775809) -------------------------------------- ->1< ^= >0<, result: int(1) ->1< ^= >-10<, result: int(-9) ->1< ^= >100<, result: int(101) ->1< ^= >-34000000000<, result: int(-33999999999) ->1< ^= >1<, result: int(0) ->1< ^= ><, result: int(1) ->1< ^= ><, result: int(1) ->1< ^= >123<, result: int(122) ->1< ^= >2e+5<, result: int(3) ->1< ^= ><, result: int(1) ->1< ^= >abc<, result: int(1) ->1< ^= >9223372036854775807<, result: int(9223372036854775806) -------------------------------------- ->< ^= >0<, result: int(0) ->< ^= >-10<, result: int(-10) ->< ^= >100<, result: int(100) ->< ^= >-34000000000<, result: int(-34000000000) ->< ^= >1<, result: int(1) ->< ^= ><, result: int(0) ->< ^= ><, result: int(0) ->< ^= >123<, result: int(123) ->< ^= >2e+5<, result: int(2) ->< ^= ><, result: int(0) ->< ^= >abc<, result: int(0) ->< ^= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->< ^= >0<, result: int(0) ->< ^= >-10<, result: int(-10) ->< ^= >100<, result: int(100) ->< ^= >-34000000000<, result: int(-34000000000) ->< ^= >1<, result: int(1) ->< ^= ><, result: int(0) ->< ^= ><, result: int(0) ->< ^= >123<, result: int(123) ->< ^= >2e+5<, result: int(2) ->< ^= ><, result: int(0) ->< ^= >abc<, result: int(0) ->< ^= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->123< ^= >0<, result: int(123) ->123< ^= >-10<, result: int(-115) ->123< ^= >100<, result: int(31) ->123< ^= >-34000000000<, result: int(-33999999877) ->123< ^= >1<, result: int(122) ->123< ^= ><, result: int(123) ->123< ^= ><, result: int(123) ->123< ^= >123<, result: string(3) "" ->123< ^= >2e+5<, result: string(3) "W" ->123< ^= ><, result: string(0) "" ->123< ^= >abc<, result: string(3) "PPP" ->123< ^= >9223372036854775807<, result: int(9223372036854775684) -------------------------------------- ->2e+5< ^= >0<, result: int(2) ->2e+5< ^= >-10<, result: int(-12) ->2e+5< ^= >100<, result: int(102) ->2e+5< ^= >-34000000000<, result: int(-33999999998) ->2e+5< ^= >1<, result: int(3) ->2e+5< ^= ><, result: int(2) ->2e+5< ^= ><, result: int(2) ->2e+5< ^= >123<, result: string(3) "W" ->2e+5< ^= >2e+5<, result: string(4) "" ->2e+5< ^= ><, result: string(0) "" ->2e+5< ^= >abc<, result: string(3) "SH" ->2e+5< ^= >9223372036854775807<, result: int(9223372036854775805) -------------------------------------- ->< ^= >0<, result: int(0) ->< ^= >-10<, result: int(-10) ->< ^= >100<, result: int(100) ->< ^= >-34000000000<, result: int(-34000000000) ->< ^= >1<, result: int(1) ->< ^= ><, result: int(0) ->< ^= ><, result: int(0) ->< ^= >123<, result: string(0) "" ->< ^= >2e+5<, result: string(0) "" ->< ^= ><, result: string(0) "" ->< ^= >abc<, result: string(0) "" ->< ^= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->abc< ^= >0<, result: int(0) ->abc< ^= >-10<, result: int(-10) ->abc< ^= >100<, result: int(100) ->abc< ^= >-34000000000<, result: int(-34000000000) ->abc< ^= >1<, result: int(1) ->abc< ^= ><, result: int(0) ->abc< ^= ><, result: int(0) ->abc< ^= >123<, result: string(3) "PPP" ->abc< ^= >2e+5<, result: string(3) "SH" ->abc< ^= ><, result: string(0) "" ->abc< ^= >abc<, result: string(3) "" ->abc< ^= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->9223372036854775807< ^= >0<, result: int(9223372036854775807) ->9223372036854775807< ^= >-10<, result: int(-9223372036854775799) ->9223372036854775807< ^= >100<, result: int(9223372036854775707) ->9223372036854775807< ^= >-34000000000<, result: int(-9223372002854775809) ->9223372036854775807< ^= >1<, result: int(9223372036854775806) ->9223372036854775807< ^= ><, result: int(9223372036854775807) ->9223372036854775807< ^= ><, result: int(9223372036854775807) ->9223372036854775807< ^= >123<, result: int(9223372036854775684) ->9223372036854775807< ^= >2e+5<, result: int(9223372036854775805) ->9223372036854775807< ^= ><, result: int(9223372036854775807) ->9223372036854775807< ^= >abc<, result: int(9223372036854775807) ->9223372036854775807< ^= >9223372036854775807<, result: int(0) -------------------------------------- ->0< |= >0<, result: int(0) ->0< |= >-10<, result: int(-10) ->0< |= >100<, result: int(100) ->0< |= >-34000000000<, result: int(-34000000000) ->0< |= >1<, result: int(1) ->0< |= ><, result: int(0) ->0< |= ><, result: int(0) ->0< |= >123<, result: int(123) ->0< |= >2e+5<, result: int(2) ->0< |= ><, result: int(0) ->0< |= >abc<, result: int(0) ->0< |= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->-10< |= >0<, result: int(-10) ->-10< |= >-10<, result: int(-10) ->-10< |= >100<, result: int(-10) ->-10< |= >-34000000000<, result: int(-10) ->-10< |= >1<, result: int(-9) ->-10< |= ><, result: int(-10) ->-10< |= ><, result: int(-10) ->-10< |= >123<, result: int(-1) ->-10< |= >2e+5<, result: int(-10) ->-10< |= ><, result: int(-10) ->-10< |= >abc<, result: int(-10) ->-10< |= >9223372036854775807<, result: int(-1) -------------------------------------- ->100< |= >0<, result: int(100) ->100< |= >-10<, result: int(-10) ->100< |= >100<, result: int(100) ->100< |= >-34000000000<, result: int(-33999999900) ->100< |= >1<, result: int(101) ->100< |= ><, result: int(100) ->100< |= ><, result: int(100) ->100< |= >123<, result: int(127) ->100< |= >2e+5<, result: int(102) ->100< |= ><, result: int(100) ->100< |= >abc<, result: int(100) ->100< |= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->-34000000000< |= >0<, result: int(-34000000000) ->-34000000000< |= >-10<, result: int(-10) ->-34000000000< |= >100<, result: int(-33999999900) ->-34000000000< |= >-34000000000<, result: int(-34000000000) ->-34000000000< |= >1<, result: int(-33999999999) ->-34000000000< |= ><, result: int(-34000000000) ->-34000000000< |= ><, result: int(-34000000000) ->-34000000000< |= >123<, result: int(-33999999877) ->-34000000000< |= >2e+5<, result: int(-33999999998) ->-34000000000< |= ><, result: int(-34000000000) ->-34000000000< |= >abc<, result: int(-34000000000) ->-34000000000< |= >9223372036854775807<, result: int(-1) -------------------------------------- ->1< |= >0<, result: int(1) ->1< |= >-10<, result: int(-9) ->1< |= >100<, result: int(101) ->1< |= >-34000000000<, result: int(-33999999999) ->1< |= >1<, result: int(1) ->1< |= ><, result: int(1) ->1< |= ><, result: int(1) ->1< |= >123<, result: int(123) ->1< |= >2e+5<, result: int(3) ->1< |= ><, result: int(1) ->1< |= >abc<, result: int(1) ->1< |= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->< |= >0<, result: int(0) ->< |= >-10<, result: int(-10) ->< |= >100<, result: int(100) ->< |= >-34000000000<, result: int(-34000000000) ->< |= >1<, result: int(1) ->< |= ><, result: int(0) ->< |= ><, result: int(0) ->< |= >123<, result: int(123) ->< |= >2e+5<, result: int(2) ->< |= ><, result: int(0) ->< |= >abc<, result: int(0) ->< |= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->< |= >0<, result: int(0) ->< |= >-10<, result: int(-10) ->< |= >100<, result: int(100) ->< |= >-34000000000<, result: int(-34000000000) ->< |= >1<, result: int(1) ->< |= ><, result: int(0) ->< |= ><, result: int(0) ->< |= >123<, result: int(123) ->< |= >2e+5<, result: int(2) ->< |= ><, result: int(0) ->< |= >abc<, result: int(0) ->< |= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->123< |= >0<, result: int(123) ->123< |= >-10<, result: int(-1) ->123< |= >100<, result: int(127) ->123< |= >-34000000000<, result: int(-33999999877) ->123< |= >1<, result: int(123) ->123< |= ><, result: int(123) ->123< |= ><, result: int(123) ->123< |= >123<, result: string(3) "123" ->123< |= >2e+5<, result: string(4) "3w;5" ->123< |= ><, result: string(3) "123" ->123< |= >abc<, result: string(3) "qrs" ->123< |= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->2e+5< |= >0<, result: int(2) ->2e+5< |= >-10<, result: int(-10) ->2e+5< |= >100<, result: int(102) ->2e+5< |= >-34000000000<, result: int(-33999999998) ->2e+5< |= >1<, result: int(3) ->2e+5< |= ><, result: int(2) ->2e+5< |= ><, result: int(2) ->2e+5< |= >123<, result: string(4) "3w;5" ->2e+5< |= >2e+5<, result: string(4) "2e+5" ->2e+5< |= ><, result: string(4) "2e+5" ->2e+5< |= >abc<, result: string(4) "sgk5" ->2e+5< |= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->< |= >0<, result: int(0) ->< |= >-10<, result: int(-10) ->< |= >100<, result: int(100) ->< |= >-34000000000<, result: int(-34000000000) ->< |= >1<, result: int(1) ->< |= ><, result: int(0) ->< |= ><, result: int(0) ->< |= >123<, result: string(3) "123" ->< |= >2e+5<, result: string(4) "2e+5" ->< |= ><, result: string(0) "" ->< |= >abc<, result: string(3) "abc" ->< |= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->abc< |= >0<, result: int(0) ->abc< |= >-10<, result: int(-10) ->abc< |= >100<, result: int(100) ->abc< |= >-34000000000<, result: int(-34000000000) ->abc< |= >1<, result: int(1) ->abc< |= ><, result: int(0) ->abc< |= ><, result: int(0) ->abc< |= >123<, result: string(3) "qrs" ->abc< |= >2e+5<, result: string(4) "sgk5" ->abc< |= ><, result: string(3) "abc" ->abc< |= >abc<, result: string(3) "abc" ->abc< |= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- ->9223372036854775807< |= >0<, result: int(9223372036854775807) ->9223372036854775807< |= >-10<, result: int(-1) ->9223372036854775807< |= >100<, result: int(9223372036854775807) ->9223372036854775807< |= >-34000000000<, result: int(-1) ->9223372036854775807< |= >1<, result: int(9223372036854775807) ->9223372036854775807< |= ><, result: int(9223372036854775807) ->9223372036854775807< |= ><, result: int(9223372036854775807) ->9223372036854775807< |= >123<, result: int(9223372036854775807) ->9223372036854775807< |= >2e+5<, result: int(9223372036854775807) ->9223372036854775807< |= ><, result: int(9223372036854775807) ->9223372036854775807< |= >abc<, result: int(9223372036854775807) ->9223372036854775807< |= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- -int(10) -int(30) -int(25) -string(8) "25123.45" -int(250) -int(2) diff --git a/tests/expressions/assignment_operators/common.inc b/tests/expressions/assignment_operators/common.inc new file mode 100644 index 00000000..00064aa5 --- /dev/null +++ b/tests/expressions/assignment_operators/common.inc @@ -0,0 +1,5 @@ +$e1< .= >$e2<, result: "; var_dump($e1 .= $e2); + } + echo "-------------------------------------\n"; +} + +?> +--EXPECT-- +>0< .= >0<, result: string(2) "00" +>0< .= >-10<, result: string(4) "0-10" +>0< .= >100<, result: string(4) "0100" +>0< .= >-34000000000<, result: string(13) "0-34000000000" +>0< .= >INF<, result: string(4) "0INF" +>0< .= >-INF<, result: string(5) "0-INF" +>0< .= >NAN<, result: string(4) "0NAN" +>0< .= >1<, result: string(2) "01" +>0< .= ><, result: string(1) "0" +>0< .= ><, result: string(1) "0" +>0< .= >123<, result: string(4) "0123" +>0< .= >2e+5<, result: string(5) "02e+5" +>0< .= ><, result: string(1) "0" +>0< .= >abc<, result: string(4) "0abc" +>0< .= >9223372036854775807<, result: string(20) "09223372036854775807" +------------------------------------- +>-10< .= >0<, result: string(4) "-100" +>-10< .= >-10<, result: string(6) "-10-10" +>-10< .= >100<, result: string(6) "-10100" +>-10< .= >-34000000000<, result: string(15) "-10-34000000000" +>-10< .= >INF<, result: string(6) "-10INF" +>-10< .= >-INF<, result: string(7) "-10-INF" +>-10< .= >NAN<, result: string(6) "-10NAN" +>-10< .= >1<, result: string(4) "-101" +>-10< .= ><, result: string(3) "-10" +>-10< .= ><, result: string(3) "-10" +>-10< .= >123<, result: string(6) "-10123" +>-10< .= >2e+5<, result: string(7) "-102e+5" +>-10< .= ><, result: string(3) "-10" +>-10< .= >abc<, result: string(6) "-10abc" +>-10< .= >9223372036854775807<, result: string(22) "-109223372036854775807" +------------------------------------- +>100< .= >0<, result: string(4) "1000" +>100< .= >-10<, result: string(6) "100-10" +>100< .= >100<, result: string(6) "100100" +>100< .= >-34000000000<, result: string(15) "100-34000000000" +>100< .= >INF<, result: string(6) "100INF" +>100< .= >-INF<, result: string(7) "100-INF" +>100< .= >NAN<, result: string(6) "100NAN" +>100< .= >1<, result: string(4) "1001" +>100< .= ><, result: string(3) "100" +>100< .= ><, result: string(3) "100" +>100< .= >123<, result: string(6) "100123" +>100< .= >2e+5<, result: string(7) "1002e+5" +>100< .= ><, result: string(3) "100" +>100< .= >abc<, result: string(6) "100abc" +>100< .= >9223372036854775807<, result: string(22) "1009223372036854775807" +------------------------------------- +>-34000000000< .= >0<, result: string(13) "-340000000000" +>-34000000000< .= >-10<, result: string(15) "-34000000000-10" +>-34000000000< .= >100<, result: string(15) "-34000000000100" +>-34000000000< .= >-34000000000<, result: string(24) "-34000000000-34000000000" +>-34000000000< .= >INF<, result: string(15) "-34000000000INF" +>-34000000000< .= >-INF<, result: string(16) "-34000000000-INF" +>-34000000000< .= >NAN<, result: string(15) "-34000000000NAN" +>-34000000000< .= >1<, result: string(13) "-340000000001" +>-34000000000< .= ><, result: string(12) "-34000000000" +>-34000000000< .= ><, result: string(12) "-34000000000" +>-34000000000< .= >123<, result: string(15) "-34000000000123" +>-34000000000< .= >2e+5<, result: string(16) "-340000000002e+5" +>-34000000000< .= ><, result: string(12) "-34000000000" +>-34000000000< .= >abc<, result: string(15) "-34000000000abc" +>-34000000000< .= >9223372036854775807<, result: string(31) "-340000000009223372036854775807" +------------------------------------- +>INF< .= >0<, result: string(4) "INF0" +>INF< .= >-10<, result: string(6) "INF-10" +>INF< .= >100<, result: string(6) "INF100" +>INF< .= >-34000000000<, result: string(15) "INF-34000000000" +>INF< .= >INF<, result: string(6) "INFINF" +>INF< .= >-INF<, result: string(7) "INF-INF" +>INF< .= >NAN<, result: string(6) "INFNAN" +>INF< .= >1<, result: string(4) "INF1" +>INF< .= ><, result: string(3) "INF" +>INF< .= ><, result: string(3) "INF" +>INF< .= >123<, result: string(6) "INF123" +>INF< .= >2e+5<, result: string(7) "INF2e+5" +>INF< .= ><, result: string(3) "INF" +>INF< .= >abc<, result: string(6) "INFabc" +>INF< .= >9223372036854775807<, result: string(22) "INF9223372036854775807" +------------------------------------- +>-INF< .= >0<, result: string(5) "-INF0" +>-INF< .= >-10<, result: string(7) "-INF-10" +>-INF< .= >100<, result: string(7) "-INF100" +>-INF< .= >-34000000000<, result: string(16) "-INF-34000000000" +>-INF< .= >INF<, result: string(7) "-INFINF" +>-INF< .= >-INF<, result: string(8) "-INF-INF" +>-INF< .= >NAN<, result: string(7) "-INFNAN" +>-INF< .= >1<, result: string(5) "-INF1" +>-INF< .= ><, result: string(4) "-INF" +>-INF< .= ><, result: string(4) "-INF" +>-INF< .= >123<, result: string(7) "-INF123" +>-INF< .= >2e+5<, result: string(8) "-INF2e+5" +>-INF< .= ><, result: string(4) "-INF" +>-INF< .= >abc<, result: string(7) "-INFabc" +>-INF< .= >9223372036854775807<, result: string(23) "-INF9223372036854775807" +------------------------------------- +>NAN< .= >0<, result: string(4) "NAN0" +>NAN< .= >-10<, result: string(6) "NAN-10" +>NAN< .= >100<, result: string(6) "NAN100" +>NAN< .= >-34000000000<, result: string(15) "NAN-34000000000" +>NAN< .= >INF<, result: string(6) "NANINF" +>NAN< .= >-INF<, result: string(7) "NAN-INF" +>NAN< .= >NAN<, result: string(6) "NANNAN" +>NAN< .= >1<, result: string(4) "NAN1" +>NAN< .= ><, result: string(3) "NAN" +>NAN< .= ><, result: string(3) "NAN" +>NAN< .= >123<, result: string(6) "NAN123" +>NAN< .= >2e+5<, result: string(7) "NAN2e+5" +>NAN< .= ><, result: string(3) "NAN" +>NAN< .= >abc<, result: string(6) "NANabc" +>NAN< .= >9223372036854775807<, result: string(22) "NAN9223372036854775807" +------------------------------------- +>1< .= >0<, result: string(2) "10" +>1< .= >-10<, result: string(4) "1-10" +>1< .= >100<, result: string(4) "1100" +>1< .= >-34000000000<, result: string(13) "1-34000000000" +>1< .= >INF<, result: string(4) "1INF" +>1< .= >-INF<, result: string(5) "1-INF" +>1< .= >NAN<, result: string(4) "1NAN" +>1< .= >1<, result: string(2) "11" +>1< .= ><, result: string(1) "1" +>1< .= ><, result: string(1) "1" +>1< .= >123<, result: string(4) "1123" +>1< .= >2e+5<, result: string(5) "12e+5" +>1< .= ><, result: string(1) "1" +>1< .= >abc<, result: string(4) "1abc" +>1< .= >9223372036854775807<, result: string(20) "19223372036854775807" +------------------------------------- +>< .= >0<, result: string(1) "0" +>< .= >-10<, result: string(3) "-10" +>< .= >100<, result: string(3) "100" +>< .= >-34000000000<, result: string(12) "-34000000000" +>< .= >INF<, result: string(3) "INF" +>< .= >-INF<, result: string(4) "-INF" +>< .= >NAN<, result: string(3) "NAN" +>< .= >1<, result: string(1) "1" +>< .= ><, result: string(0) "" +>< .= ><, result: string(0) "" +>< .= >123<, result: string(3) "123" +>< .= >2e+5<, result: string(4) "2e+5" +>< .= ><, result: string(0) "" +>< .= >abc<, result: string(3) "abc" +>< .= >9223372036854775807<, result: string(19) "9223372036854775807" +------------------------------------- +>< .= >0<, result: string(1) "0" +>< .= >-10<, result: string(3) "-10" +>< .= >100<, result: string(3) "100" +>< .= >-34000000000<, result: string(12) "-34000000000" +>< .= >INF<, result: string(3) "INF" +>< .= >-INF<, result: string(4) "-INF" +>< .= >NAN<, result: string(3) "NAN" +>< .= >1<, result: string(1) "1" +>< .= ><, result: string(0) "" +>< .= ><, result: string(0) "" +>< .= >123<, result: string(3) "123" +>< .= >2e+5<, result: string(4) "2e+5" +>< .= ><, result: string(0) "" +>< .= >abc<, result: string(3) "abc" +>< .= >9223372036854775807<, result: string(19) "9223372036854775807" +------------------------------------- +>123< .= >0<, result: string(4) "1230" +>123< .= >-10<, result: string(6) "123-10" +>123< .= >100<, result: string(6) "123100" +>123< .= >-34000000000<, result: string(15) "123-34000000000" +>123< .= >INF<, result: string(6) "123INF" +>123< .= >-INF<, result: string(7) "123-INF" +>123< .= >NAN<, result: string(6) "123NAN" +>123< .= >1<, result: string(4) "1231" +>123< .= ><, result: string(3) "123" +>123< .= ><, result: string(3) "123" +>123< .= >123<, result: string(6) "123123" +>123< .= >2e+5<, result: string(7) "1232e+5" +>123< .= ><, result: string(3) "123" +>123< .= >abc<, result: string(6) "123abc" +>123< .= >9223372036854775807<, result: string(22) "1239223372036854775807" +------------------------------------- +>2e+5< .= >0<, result: string(5) "2e+50" +>2e+5< .= >-10<, result: string(7) "2e+5-10" +>2e+5< .= >100<, result: string(7) "2e+5100" +>2e+5< .= >-34000000000<, result: string(16) "2e+5-34000000000" +>2e+5< .= >INF<, result: string(7) "2e+5INF" +>2e+5< .= >-INF<, result: string(8) "2e+5-INF" +>2e+5< .= >NAN<, result: string(7) "2e+5NAN" +>2e+5< .= >1<, result: string(5) "2e+51" +>2e+5< .= ><, result: string(4) "2e+5" +>2e+5< .= ><, result: string(4) "2e+5" +>2e+5< .= >123<, result: string(7) "2e+5123" +>2e+5< .= >2e+5<, result: string(8) "2e+52e+5" +>2e+5< .= ><, result: string(4) "2e+5" +>2e+5< .= >abc<, result: string(7) "2e+5abc" +>2e+5< .= >9223372036854775807<, result: string(23) "2e+59223372036854775807" +------------------------------------- +>< .= >0<, result: string(1) "0" +>< .= >-10<, result: string(3) "-10" +>< .= >100<, result: string(3) "100" +>< .= >-34000000000<, result: string(12) "-34000000000" +>< .= >INF<, result: string(3) "INF" +>< .= >-INF<, result: string(4) "-INF" +>< .= >NAN<, result: string(3) "NAN" +>< .= >1<, result: string(1) "1" +>< .= ><, result: string(0) "" +>< .= ><, result: string(0) "" +>< .= >123<, result: string(3) "123" +>< .= >2e+5<, result: string(4) "2e+5" +>< .= ><, result: string(0) "" +>< .= >abc<, result: string(3) "abc" +>< .= >9223372036854775807<, result: string(19) "9223372036854775807" +------------------------------------- +>abc< .= >0<, result: string(4) "abc0" +>abc< .= >-10<, result: string(6) "abc-10" +>abc< .= >100<, result: string(6) "abc100" +>abc< .= >-34000000000<, result: string(15) "abc-34000000000" +>abc< .= >INF<, result: string(6) "abcINF" +>abc< .= >-INF<, result: string(7) "abc-INF" +>abc< .= >NAN<, result: string(6) "abcNAN" +>abc< .= >1<, result: string(4) "abc1" +>abc< .= ><, result: string(3) "abc" +>abc< .= ><, result: string(3) "abc" +>abc< .= >123<, result: string(6) "abc123" +>abc< .= >2e+5<, result: string(7) "abc2e+5" +>abc< .= ><, result: string(3) "abc" +>abc< .= >abc<, result: string(6) "abcabc" +>abc< .= >9223372036854775807<, result: string(22) "abc9223372036854775807" +------------------------------------- +>9223372036854775807< .= >0<, result: string(20) "92233720368547758070" +>9223372036854775807< .= >-10<, result: string(22) "9223372036854775807-10" +>9223372036854775807< .= >100<, result: string(22) "9223372036854775807100" +>9223372036854775807< .= >-34000000000<, result: string(31) "9223372036854775807-34000000000" +>9223372036854775807< .= >INF<, result: string(22) "9223372036854775807INF" +>9223372036854775807< .= >-INF<, result: string(23) "9223372036854775807-INF" +>9223372036854775807< .= >NAN<, result: string(22) "9223372036854775807NAN" +>9223372036854775807< .= >1<, result: string(20) "92233720368547758071" +>9223372036854775807< .= ><, result: string(19) "9223372036854775807" +>9223372036854775807< .= ><, result: string(19) "9223372036854775807" +>9223372036854775807< .= >123<, result: string(22) "9223372036854775807123" +>9223372036854775807< .= >2e+5<, result: string(23) "92233720368547758072e+5" +>9223372036854775807< .= ><, result: string(19) "9223372036854775807" +>9223372036854775807< .= >abc<, result: string(22) "9223372036854775807abc" +>9223372036854775807< .= >9223372036854775807<, result: string(38) "92233720368547758079223372036854775807" +------------------------------------- diff --git a/tests/expressions/assignment_operators/div_assignment.phpt b/tests/expressions/assignment_operators/div_assignment.phpt new file mode 100644 index 00000000..ddb2c315 --- /dev/null +++ b/tests/expressions/assignment_operators/div_assignment.phpt @@ -0,0 +1,226 @@ +--TEST-- +/= operator +--FILE-- +$e1< /= >$e2<, result: "; var_dump($e1 /= $e2); + } + echo "-------------------------------------\n"; +} + +?> +--EXPECTF-- +>0< /= >-10<, result: int(0) +>0< /= >100<, result: int(0) +>0< /= >-34000000000<, result: float(-0) +>0< /= >INF<, result: float(0) +>0< /= >-INF<, result: float(-0) +>0< /= >NAN<, result: float(NAN) +>0< /= >1<, result: int(0) +>0< /= >123<, result: int(0) +>0< /= >2e+5<, result: float(0) +>0< /= >9223372036854775807<, result: int(0) +------------------------------------- +>-10< /= >-10<, result: int(1) +>-10< /= >100<, result: float(-0.1) +>-10< /= >-34000000000<, result: float(2.9411764705882E-10) +>-10< /= >INF<, result: float(-0) +>-10< /= >-INF<, result: float(0) +>-10< /= >NAN<, result: float(NAN) +>-10< /= >1<, result: int(-10) +>-10< /= >123<, result: float(-0.08130081300813) +>-10< /= >2e+5<, result: float(-5.0E-5) +>-10< /= >9223372036854775807<, result: float(-1.0842021724855E-18) +------------------------------------- +>100< /= >-10<, result: int(-10) +>100< /= >100<, result: int(1) +>100< /= >-34000000000<, result: float(-2.9411764705882E-9) +>100< /= >INF<, result: float(0) +>100< /= >-INF<, result: float(-0) +>100< /= >NAN<, result: float(NAN) +>100< /= >1<, result: int(100) +>100< /= >123<, result: float(0.8130081300813) +>100< /= >2e+5<, result: float(0.0005) +>100< /= >9223372036854775807<, result: float(1.0842021724855E-17) +------------------------------------- +>-34000000000< /= >-10<, result: float(3400000000) +>-34000000000< /= >100<, result: float(-340000000) +>-34000000000< /= >-34000000000<, result: float(1) +>-34000000000< /= >INF<, result: float(-0) +>-34000000000< /= >-INF<, result: float(0) +>-34000000000< /= >NAN<, result: float(NAN) +>-34000000000< /= >1<, result: float(-34000000000) +>-34000000000< /= >123<, result: float(-276422764.22764) +>-34000000000< /= >2e+5<, result: float(-170000) +>-34000000000< /= >9223372036854775807<, result: float(-3.6862873864507E-9) +------------------------------------- +>INF< /= >-10<, result: float(-INF) +>INF< /= >100<, result: float(INF) +>INF< /= >-34000000000<, result: float(-INF) +>INF< /= >INF<, result: float(NAN) +>INF< /= >-INF<, result: float(NAN) +>INF< /= >NAN<, result: float(NAN) +>INF< /= >1<, result: float(INF) +>INF< /= >123<, result: float(INF) +>INF< /= >2e+5<, result: float(INF) +>INF< /= >9223372036854775807<, result: float(INF) +------------------------------------- +>-INF< /= >-10<, result: float(INF) +>-INF< /= >100<, result: float(-INF) +>-INF< /= >-34000000000<, result: float(INF) +>-INF< /= >INF<, result: float(NAN) +>-INF< /= >-INF<, result: float(NAN) +>-INF< /= >NAN<, result: float(NAN) +>-INF< /= >1<, result: float(-INF) +>-INF< /= >123<, result: float(-INF) +>-INF< /= >2e+5<, result: float(-INF) +>-INF< /= >9223372036854775807<, result: float(-INF) +------------------------------------- +>NAN< /= >-10<, result: float(NAN) +>NAN< /= >100<, result: float(NAN) +>NAN< /= >-34000000000<, result: float(NAN) +>NAN< /= >INF<, result: float(NAN) +>NAN< /= >-INF<, result: float(NAN) +>NAN< /= >NAN<, result: float(NAN) +>NAN< /= >1<, result: float(NAN) +>NAN< /= >123<, result: float(NAN) +>NAN< /= >2e+5<, result: float(NAN) +>NAN< /= >9223372036854775807<, result: float(NAN) +------------------------------------- +>1< /= >-10<, result: float(-0.1) +>1< /= >100<, result: float(0.01) +>1< /= >-34000000000<, result: float(-2.9411764705882E-11) +>1< /= >INF<, result: float(0) +>1< /= >-INF<, result: float(-0) +>1< /= >NAN<, result: float(NAN) +>1< /= >1<, result: int(1) +>1< /= >123<, result: float(0.008130081300813) +>1< /= >2e+5<, result: float(5.0E-6) +>1< /= >9223372036854775807<, result: float(1.0842021724855E-19) +------------------------------------- +>< /= >-10<, result: int(0) +>< /= >100<, result: int(0) +>< /= >-34000000000<, result: float(-0) +>< /= >INF<, result: float(0) +>< /= >-INF<, result: float(-0) +>< /= >NAN<, result: float(NAN) +>< /= >1<, result: int(0) +>< /= >123<, result: int(0) +>< /= >2e+5<, result: float(0) +>< /= >9223372036854775807<, result: int(0) +------------------------------------- +>< /= >-10<, result: int(0) +>< /= >100<, result: int(0) +>< /= >-34000000000<, result: float(-0) +>< /= >INF<, result: float(0) +>< /= >-INF<, result: float(-0) +>< /= >NAN<, result: float(NAN) +>< /= >1<, result: int(0) +>< /= >123<, result: int(0) +>< /= >2e+5<, result: float(0) +>< /= >9223372036854775807<, result: int(0) +------------------------------------- +>123< /= >-10<, result: float(-12.3) +>123< /= >100<, result: float(1.23) +>123< /= >-34000000000<, result: float(-3.6176470588235E-9) +>123< /= >INF<, result: float(0) +>123< /= >-INF<, result: float(-0) +>123< /= >NAN<, result: float(NAN) +>123< /= >1<, result: int(123) +>123< /= >123<, result: int(1) +>123< /= >2e+5<, result: float(0.000615) +>123< /= >9223372036854775807<, result: float(1.3335686721572E-17) +------------------------------------- +>2e+5< /= >-10<, result: float(-20000) +>2e+5< /= >100<, result: float(2000) +>2e+5< /= >-34000000000<, result: float(-5.8823529411765E-6) +>2e+5< /= >INF<, result: float(0) +>2e+5< /= >-INF<, result: float(-0) +>2e+5< /= >NAN<, result: float(NAN) +>2e+5< /= >1<, result: float(200000) +>2e+5< /= >123<, result: float(1626.0162601626) +>2e+5< /= >2e+5<, result: float(1) +>2e+5< /= >9223372036854775807<, result: float(2.168404344971E-14) +------------------------------------- +>< /= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< /= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< /= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< /= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< /= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< /= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< /= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< /= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< /= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< /= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>abc< /= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< /= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< /= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< /= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< /= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< /= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< /= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< /= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< /= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< /= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>9223372036854775807< /= >-10<, result: float(-9.2233720368548E+17) +>9223372036854775807< /= >100<, result: float(9.2233720368548E+16) +>9223372036854775807< /= >-34000000000<, result: float(-271275648.14279) +>9223372036854775807< /= >INF<, result: float(0) +>9223372036854775807< /= >-INF<, result: float(-0) +>9223372036854775807< /= >NAN<, result: float(NAN) +>9223372036854775807< /= >1<, result: int(9223372036854775807) +>9223372036854775807< /= >123<, result: float(7.4986764527275E+16) +>9223372036854775807< /= >2e+5<, result: float(46116860184274) +>9223372036854775807< /= >9223372036854775807<, result: int(1) +------------------------------------- diff --git a/tests/expressions/assignment_operators/misc_assignment.phpt b/tests/expressions/assignment_operators/misc_assignment.phpt new file mode 100644 index 00000000..6b5d5649 --- /dev/null +++ b/tests/expressions/assignment_operators/misc_assignment.phpt @@ -0,0 +1,22 @@ +--TEST-- +Misc. assignment operator testing +--FILE-- +$e1< %= >$e2<, result: "; var_dump($e1 %= $e2); + } + echo "-------------------------------------\n"; +} + +?> +--EXPECTF-- +>0< %= >-10<, result: int(0) +>0< %= >100<, result: int(0) +>0< %= >-34000000000<, result: int(0) +>0< %= >1<, result: int(0) +>0< %= >123<, result: int(0) +>0< %= >2e+5<, result: int(0) +>0< %= >9223372036854775807<, result: int(0) +------------------------------------- +>-10< %= >-10<, result: int(0) +>-10< %= >100<, result: int(-10) +>-10< %= >-34000000000<, result: int(-10) +>-10< %= >1<, result: int(0) +>-10< %= >123<, result: int(-10) +>-10< %= >2e+5<, result: int(-10) +>-10< %= >9223372036854775807<, result: int(-10) +------------------------------------- +>100< %= >-10<, result: int(0) +>100< %= >100<, result: int(0) +>100< %= >-34000000000<, result: int(100) +>100< %= >1<, result: int(0) +>100< %= >123<, result: int(100) +>100< %= >2e+5<, result: int(100) +>100< %= >9223372036854775807<, result: int(100) +------------------------------------- +>-34000000000< %= >-10<, result: int(0) +>-34000000000< %= >100<, result: int(0) +>-34000000000< %= >-34000000000<, result: int(0) +>-34000000000< %= >1<, result: int(0) +>-34000000000< %= >123<, result: int(-28) +>-34000000000< %= >2e+5<, result: int(0) +>-34000000000< %= >9223372036854775807<, result: int(-34000000000) +------------------------------------- +>INF< %= >-10<, result: int(0) +>INF< %= >100<, result: int(0) +>INF< %= >-34000000000<, result: int(0) +>INF< %= >1<, result: int(0) +>INF< %= >123<, result: int(0) +>INF< %= >2e+5<, result: int(0) +>INF< %= >9223372036854775807<, result: int(0) +------------------------------------- +>-INF< %= >-10<, result: int(0) +>-INF< %= >100<, result: int(0) +>-INF< %= >-34000000000<, result: int(0) +>-INF< %= >1<, result: int(0) +>-INF< %= >123<, result: int(0) +>-INF< %= >2e+5<, result: int(0) +>-INF< %= >9223372036854775807<, result: int(0) +------------------------------------- +>NAN< %= >-10<, result: int(0) +>NAN< %= >100<, result: int(0) +>NAN< %= >-34000000000<, result: int(0) +>NAN< %= >1<, result: int(0) +>NAN< %= >123<, result: int(0) +>NAN< %= >2e+5<, result: int(0) +>NAN< %= >9223372036854775807<, result: int(0) +------------------------------------- +>1< %= >-10<, result: int(1) +>1< %= >100<, result: int(1) +>1< %= >-34000000000<, result: int(1) +>1< %= >1<, result: int(0) +>1< %= >123<, result: int(1) +>1< %= >2e+5<, result: int(1) +>1< %= >9223372036854775807<, result: int(1) +------------------------------------- +>< %= >-10<, result: int(0) +>< %= >100<, result: int(0) +>< %= >-34000000000<, result: int(0) +>< %= >1<, result: int(0) +>< %= >123<, result: int(0) +>< %= >2e+5<, result: int(0) +>< %= >9223372036854775807<, result: int(0) +------------------------------------- +>< %= >-10<, result: int(0) +>< %= >100<, result: int(0) +>< %= >-34000000000<, result: int(0) +>< %= >1<, result: int(0) +>< %= >123<, result: int(0) +>< %= >2e+5<, result: int(0) +>< %= >9223372036854775807<, result: int(0) +------------------------------------- +>123< %= >-10<, result: int(3) +>123< %= >100<, result: int(23) +>123< %= >-34000000000<, result: int(123) +>123< %= >1<, result: int(0) +>123< %= >123<, result: int(0) +>123< %= >2e+5<, result: int(123) +>123< %= >9223372036854775807<, result: int(123) +------------------------------------- +>2e+5< %= >-10<, result: int(0) +>2e+5< %= >100<, result: int(0) +>2e+5< %= >-34000000000<, result: int(200000) +>2e+5< %= >1<, result: int(0) +>2e+5< %= >123<, result: int(2) +>2e+5< %= >2e+5<, result: int(0) +>2e+5< %= >9223372036854775807<, result: int(200000) +------------------------------------- +>< %= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>abc< %= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>9223372036854775807< %= >-10<, result: int(7) +>9223372036854775807< %= >100<, result: int(7) +>9223372036854775807< %= >-34000000000<, result: int(4854775807) +>9223372036854775807< %= >1<, result: int(0) +>9223372036854775807< %= >123<, result: int(7) +>9223372036854775807< %= >2e+5<, result: int(175807) +>9223372036854775807< %= >9223372036854775807<, result: int(0) +------------------------------------- diff --git a/tests/expressions/assignment_operators/mul_assignment.phpt b/tests/expressions/assignment_operators/mul_assignment.phpt new file mode 100644 index 00000000..ab33ab36 --- /dev/null +++ b/tests/expressions/assignment_operators/mul_assignment.phpt @@ -0,0 +1,379 @@ +--TEST-- +*= operator +--FILE-- +$e1< *= >$e2<, result: "; var_dump($e1 *= $e2); + } + echo "-------------------------------------\n"; +} + +?> +--EXPECTF-- +>0< *= >0<, result: int(0) +>0< *= >-10<, result: int(0) +>0< *= >100<, result: int(0) +>0< *= >-34000000000<, result: float(-0) +>0< *= >INF<, result: float(NAN) +>0< *= >-INF<, result: float(NAN) +>0< *= >NAN<, result: float(NAN) +>0< *= >1<, result: int(0) +>0< *= ><, result: int(0) +>0< *= ><, result: int(0) +>0< *= >123<, result: int(0) +>0< *= >2e+5<, result: float(0) +>0< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< *= >9223372036854775807<, result: int(0) +------------------------------------- +>-10< *= >0<, result: int(0) +>-10< *= >-10<, result: int(100) +>-10< *= >100<, result: int(-1000) +>-10< *= >-34000000000<, result: float(340000000000) +>-10< *= >INF<, result: float(-INF) +>-10< *= >-INF<, result: float(INF) +>-10< *= >NAN<, result: float(NAN) +>-10< *= >1<, result: int(-10) +>-10< *= ><, result: int(0) +>-10< *= ><, result: int(0) +>-10< *= >123<, result: int(-1230) +>-10< *= >2e+5<, result: float(-2000000) +>-10< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-10< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-10< *= >9223372036854775807<, result: float(-9.2233720368548E+19) +------------------------------------- +>100< *= >0<, result: int(0) +>100< *= >-10<, result: int(-1000) +>100< *= >100<, result: int(10000) +>100< *= >-34000000000<, result: float(-3400000000000) +>100< *= >INF<, result: float(INF) +>100< *= >-INF<, result: float(-INF) +>100< *= >NAN<, result: float(NAN) +>100< *= >1<, result: int(100) +>100< *= ><, result: int(0) +>100< *= ><, result: int(0) +>100< *= >123<, result: int(12300) +>100< *= >2e+5<, result: float(20000000) +>100< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>100< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>100< *= >9223372036854775807<, result: float(9.2233720368548E+20) +------------------------------------- +>-34000000000< *= >0<, result: float(-0) +>-34000000000< *= >-10<, result: float(340000000000) +>-34000000000< *= >100<, result: float(-3400000000000) +>-34000000000< *= >-34000000000<, result: float(1.156E+21) +>-34000000000< *= >INF<, result: float(-INF) +>-34000000000< *= >-INF<, result: float(INF) +>-34000000000< *= >NAN<, result: float(NAN) +>-34000000000< *= >1<, result: float(-34000000000) +>-34000000000< *= ><, result: float(-0) +>-34000000000< *= ><, result: float(-0) +>-34000000000< *= >123<, result: float(-4182000000000) +>-34000000000< *= >2e+5<, result: float(-6.8E+15) +>-34000000000< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>-34000000000< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>-34000000000< *= >9223372036854775807<, result: float(-3.1359464925306E+29) +------------------------------------- +>INF< *= >0<, result: float(NAN) +>INF< *= >-10<, result: float(-INF) +>INF< *= >100<, result: float(INF) +>INF< *= >-34000000000<, result: float(-INF) +>INF< *= >INF<, result: float(INF) +>INF< *= >-INF<, result: float(-INF) +>INF< *= >NAN<, result: float(NAN) +>INF< *= >1<, result: float(INF) +>INF< *= ><, result: float(NAN) +>INF< *= ><, result: float(NAN) +>INF< *= >123<, result: float(INF) +>INF< *= >2e+5<, result: float(INF) +>INF< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>INF< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>INF< *= >9223372036854775807<, result: float(INF) +------------------------------------- +>-INF< *= >0<, result: float(NAN) +>-INF< *= >-10<, result: float(INF) +>-INF< *= >100<, result: float(-INF) +>-INF< *= >-34000000000<, result: float(INF) +>-INF< *= >INF<, result: float(-INF) +>-INF< *= >-INF<, result: float(INF) +>-INF< *= >NAN<, result: float(NAN) +>-INF< *= >1<, result: float(-INF) +>-INF< *= ><, result: float(NAN) +>-INF< *= ><, result: float(NAN) +>-INF< *= >123<, result: float(-INF) +>-INF< *= >2e+5<, result: float(-INF) +>-INF< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>-INF< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>-INF< *= >9223372036854775807<, result: float(-INF) +------------------------------------- +>NAN< *= >0<, result: float(NAN) +>NAN< *= >-10<, result: float(NAN) +>NAN< *= >100<, result: float(NAN) +>NAN< *= >-34000000000<, result: float(NAN) +>NAN< *= >INF<, result: float(NAN) +>NAN< *= >-INF<, result: float(NAN) +>NAN< *= >NAN<, result: float(NAN) +>NAN< *= >1<, result: float(NAN) +>NAN< *= ><, result: float(NAN) +>NAN< *= ><, result: float(NAN) +>NAN< *= >123<, result: float(NAN) +>NAN< *= >2e+5<, result: float(NAN) +>NAN< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>NAN< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>NAN< *= >9223372036854775807<, result: float(NAN) +------------------------------------- +>1< *= >0<, result: int(0) +>1< *= >-10<, result: int(-10) +>1< *= >100<, result: int(100) +>1< *= >-34000000000<, result: float(-34000000000) +>1< *= >INF<, result: float(INF) +>1< *= >-INF<, result: float(-INF) +>1< *= >NAN<, result: float(NAN) +>1< *= >1<, result: int(1) +>1< *= ><, result: int(0) +>1< *= ><, result: int(0) +>1< *= >123<, result: int(123) +>1< *= >2e+5<, result: float(200000) +>1< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>1< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>1< *= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>< *= >0<, result: int(0) +>< *= >-10<, result: int(0) +>< *= >100<, result: int(0) +>< *= >-34000000000<, result: float(-0) +>< *= >INF<, result: float(NAN) +>< *= >-INF<, result: float(NAN) +>< *= >NAN<, result: float(NAN) +>< *= >1<, result: int(0) +>< *= ><, result: int(0) +>< *= ><, result: int(0) +>< *= >123<, result: int(0) +>< *= >2e+5<, result: float(0) +>< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >9223372036854775807<, result: int(0) +------------------------------------- +>< *= >0<, result: int(0) +>< *= >-10<, result: int(0) +>< *= >100<, result: int(0) +>< *= >-34000000000<, result: float(-0) +>< *= >INF<, result: float(NAN) +>< *= >-INF<, result: float(NAN) +>< *= >NAN<, result: float(NAN) +>< *= >1<, result: int(0) +>< *= ><, result: int(0) +>< *= ><, result: int(0) +>< *= >123<, result: int(0) +>< *= >2e+5<, result: float(0) +>< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >9223372036854775807<, result: int(0) +------------------------------------- +>123< *= >0<, result: int(0) +>123< *= >-10<, result: int(-1230) +>123< *= >100<, result: int(12300) +>123< *= >-34000000000<, result: float(-4182000000000) +>123< *= >INF<, result: float(INF) +>123< *= >-INF<, result: float(-INF) +>123< *= >NAN<, result: float(NAN) +>123< *= >1<, result: int(123) +>123< *= ><, result: int(0) +>123< *= ><, result: int(0) +>123< *= >123<, result: int(15129) +>123< *= >2e+5<, result: float(24600000) +>123< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>123< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>123< *= >9223372036854775807<, result: float(1.1344747605331E+21) +------------------------------------- +>2e+5< *= >0<, result: float(0) +>2e+5< *= >-10<, result: float(-2000000) +>2e+5< *= >100<, result: float(20000000) +>2e+5< *= >-34000000000<, result: float(-6.8E+15) +>2e+5< *= >INF<, result: float(INF) +>2e+5< *= >-INF<, result: float(-INF) +>2e+5< *= >NAN<, result: float(NAN) +>2e+5< *= >1<, result: float(200000) +>2e+5< *= ><, result: float(0) +>2e+5< *= ><, result: float(0) +>2e+5< *= >123<, result: float(24600000) +>2e+5< *= >2e+5<, result: float(40000000000) +>2e+5< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>2e+5< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>2e+5< *= >9223372036854775807<, result: float(1.844674407371E+24) +------------------------------------- +>< *= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< *= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< *= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< *= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< *= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>abc< *= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< *= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< *= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< *= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< *= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>9223372036854775807< *= >0<, result: int(0) +>9223372036854775807< *= >-10<, result: float(-9.2233720368548E+19) +>9223372036854775807< *= >100<, result: float(9.2233720368548E+20) +>9223372036854775807< *= >-34000000000<, result: float(-3.1359464925306E+29) +>9223372036854775807< *= >INF<, result: float(INF) +>9223372036854775807< *= >-INF<, result: float(-INF) +>9223372036854775807< *= >NAN<, result: float(NAN) +>9223372036854775807< *= >1<, result: int(9223372036854775807) +>9223372036854775807< *= ><, result: int(0) +>9223372036854775807< *= ><, result: int(0) +>9223372036854775807< *= >123<, result: float(1.1344747605331E+21) +>9223372036854775807< *= >2e+5<, result: float(1.844674407371E+24) +>9223372036854775807< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>9223372036854775807< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>9223372036854775807< *= >9223372036854775807<, result: float(8.5070591730235E+37) +------------------------------------- diff --git a/tests/expressions/assignment_operators/or_assignment.phpt b/tests/expressions/assignment_operators/or_assignment.phpt new file mode 100644 index 00000000..06eebc63 --- /dev/null +++ b/tests/expressions/assignment_operators/or_assignment.phpt @@ -0,0 +1,347 @@ +--TEST-- +|= operator +--FILE-- +$e1< |= >$e2<, result: "; var_dump($e1 |= $e2); + } + echo "-------------------------------------\n"; +} + +?> +--EXPECTF-- +>0< |= >0<, result: int(0) +>0< |= >-10<, result: int(-10) +>0< |= >100<, result: int(100) +>0< |= >-34000000000<, result: int(-34000000000) +>0< |= >INF<, result: int(0) +>0< |= >-INF<, result: int(0) +>0< |= >NAN<, result: int(0) +>0< |= >1<, result: int(1) +>0< |= ><, result: int(0) +>0< |= ><, result: int(0) +>0< |= >123<, result: int(123) +>0< |= >2e+5<, result: int(200000) +>0< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< |= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>-10< |= >0<, result: int(-10) +>-10< |= >-10<, result: int(-10) +>-10< |= >100<, result: int(-10) +>-10< |= >-34000000000<, result: int(-10) +>-10< |= >INF<, result: int(-10) +>-10< |= >-INF<, result: int(-10) +>-10< |= >NAN<, result: int(-10) +>-10< |= >1<, result: int(-9) +>-10< |= ><, result: int(-10) +>-10< |= ><, result: int(-10) +>-10< |= >123<, result: int(-1) +>-10< |= >2e+5<, result: int(-10) +>-10< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< |= >9223372036854775807<, result: int(-1) +------------------------------------- +>100< |= >0<, result: int(100) +>100< |= >-10<, result: int(-10) +>100< |= >100<, result: int(100) +>100< |= >-34000000000<, result: int(-33999999900) +>100< |= >INF<, result: int(100) +>100< |= >-INF<, result: int(100) +>100< |= >NAN<, result: int(100) +>100< |= >1<, result: int(101) +>100< |= ><, result: int(100) +>100< |= ><, result: int(100) +>100< |= >123<, result: int(127) +>100< |= >2e+5<, result: int(200036) +>100< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< |= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>-34000000000< |= >0<, result: int(-34000000000) +>-34000000000< |= >-10<, result: int(-10) +>-34000000000< |= >100<, result: int(-33999999900) +>-34000000000< |= >-34000000000<, result: int(-34000000000) +>-34000000000< |= >INF<, result: int(-34000000000) +>-34000000000< |= >-INF<, result: int(-34000000000) +>-34000000000< |= >NAN<, result: int(-34000000000) +>-34000000000< |= >1<, result: int(-33999999999) +>-34000000000< |= ><, result: int(-34000000000) +>-34000000000< |= ><, result: int(-34000000000) +>-34000000000< |= >123<, result: int(-33999999877) +>-34000000000< |= >2e+5<, result: int(-33999868608) +>-34000000000< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>-34000000000< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>-34000000000< |= >9223372036854775807<, result: int(-1) +------------------------------------- +>INF< |= >0<, result: int(0) +>INF< |= >-10<, result: int(-10) +>INF< |= >100<, result: int(100) +>INF< |= >-34000000000<, result: int(-34000000000) +>INF< |= >INF<, result: int(0) +>INF< |= >-INF<, result: int(0) +>INF< |= >NAN<, result: int(0) +>INF< |= >1<, result: int(1) +>INF< |= ><, result: int(0) +>INF< |= ><, result: int(0) +>INF< |= >123<, result: int(123) +>INF< |= >2e+5<, result: int(200000) +>INF< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< |= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>-INF< |= >0<, result: int(0) +>-INF< |= >-10<, result: int(-10) +>-INF< |= >100<, result: int(100) +>-INF< |= >-34000000000<, result: int(-34000000000) +>-INF< |= >INF<, result: int(0) +>-INF< |= >-INF<, result: int(0) +>-INF< |= >NAN<, result: int(0) +>-INF< |= >1<, result: int(1) +>-INF< |= ><, result: int(0) +>-INF< |= ><, result: int(0) +>-INF< |= >123<, result: int(123) +>-INF< |= >2e+5<, result: int(200000) +>-INF< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< |= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>NAN< |= >0<, result: int(0) +>NAN< |= >-10<, result: int(-10) +>NAN< |= >100<, result: int(100) +>NAN< |= >-34000000000<, result: int(-34000000000) +>NAN< |= >INF<, result: int(0) +>NAN< |= >-INF<, result: int(0) +>NAN< |= >NAN<, result: int(0) +>NAN< |= >1<, result: int(1) +>NAN< |= ><, result: int(0) +>NAN< |= ><, result: int(0) +>NAN< |= >123<, result: int(123) +>NAN< |= >2e+5<, result: int(200000) +>NAN< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< |= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>1< |= >0<, result: int(1) +>1< |= >-10<, result: int(-9) +>1< |= >100<, result: int(101) +>1< |= >-34000000000<, result: int(-33999999999) +>1< |= >INF<, result: int(1) +>1< |= >-INF<, result: int(1) +>1< |= >NAN<, result: int(1) +>1< |= >1<, result: int(1) +>1< |= ><, result: int(1) +>1< |= ><, result: int(1) +>1< |= >123<, result: int(123) +>1< |= >2e+5<, result: int(200001) +>1< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< |= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>< |= >0<, result: int(0) +>< |= >-10<, result: int(-10) +>< |= >100<, result: int(100) +>< |= >-34000000000<, result: int(-34000000000) +>< |= >INF<, result: int(0) +>< |= >-INF<, result: int(0) +>< |= >NAN<, result: int(0) +>< |= >1<, result: int(1) +>< |= ><, result: int(0) +>< |= ><, result: int(0) +>< |= >123<, result: int(123) +>< |= >2e+5<, result: int(200000) +>< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>< |= >0<, result: int(0) +>< |= >-10<, result: int(-10) +>< |= >100<, result: int(100) +>< |= >-34000000000<, result: int(-34000000000) +>< |= >INF<, result: int(0) +>< |= >-INF<, result: int(0) +>< |= >NAN<, result: int(0) +>< |= >1<, result: int(1) +>< |= ><, result: int(0) +>< |= ><, result: int(0) +>< |= >123<, result: int(123) +>< |= >2e+5<, result: int(200000) +>< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>123< |= >0<, result: int(123) +>123< |= >-10<, result: int(-1) +>123< |= >100<, result: int(127) +>123< |= >-34000000000<, result: int(-33999999877) +>123< |= >INF<, result: int(123) +>123< |= >-INF<, result: int(123) +>123< |= >NAN<, result: int(123) +>123< |= >1<, result: int(123) +>123< |= ><, result: int(123) +>123< |= ><, result: int(123) +>123< |= >123<, result: string(3) "123" +>123< |= >2e+5<, result: string(4) "3w;5" +>123< |= ><, result: string(3) "123" +>123< |= >abc<, result: string(3) "qrs" +>123< |= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>2e+5< |= >0<, result: int(200000) +>2e+5< |= >-10<, result: int(-10) +>2e+5< |= >100<, result: int(200036) +>2e+5< |= >-34000000000<, result: int(-33999868608) +>2e+5< |= >INF<, result: int(200000) +>2e+5< |= >-INF<, result: int(200000) +>2e+5< |= >NAN<, result: int(200000) +>2e+5< |= >1<, result: int(200001) +>2e+5< |= ><, result: int(200000) +>2e+5< |= ><, result: int(200000) +>2e+5< |= >123<, result: string(4) "3w;5" +>2e+5< |= >2e+5<, result: string(4) "2e+5" +>2e+5< |= ><, result: string(4) "2e+5" +>2e+5< |= >abc<, result: string(4) "sgk5" +>2e+5< |= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- +>< |= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>< |= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>< |= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>< |= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >123<, result: string(3) "123" +>< |= >2e+5<, result: string(4) "2e+5" +>< |= ><, result: string(0) "" +>< |= >abc<, result: string(3) "abc" +>< |= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +------------------------------------- +>abc< |= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< |= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>abc< |= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>abc< |= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>abc< |= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< |= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< |= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< |= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>abc< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< |= >123<, result: string(3) "qrs" +>abc< |= >2e+5<, result: string(4) "sgk5" +>abc< |= ><, result: string(3) "abc" +>abc< |= >abc<, result: string(3) "abc" +>abc< |= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +------------------------------------- +>9223372036854775807< |= >0<, result: int(9223372036854775807) +>9223372036854775807< |= >-10<, result: int(-1) +>9223372036854775807< |= >100<, result: int(9223372036854775807) +>9223372036854775807< |= >-34000000000<, result: int(-1) +>9223372036854775807< |= >INF<, result: int(9223372036854775807) +>9223372036854775807< |= >-INF<, result: int(9223372036854775807) +>9223372036854775807< |= >NAN<, result: int(9223372036854775807) +>9223372036854775807< |= >1<, result: int(9223372036854775807) +>9223372036854775807< |= ><, result: int(9223372036854775807) +>9223372036854775807< |= ><, result: int(9223372036854775807) +>9223372036854775807< |= >123<, result: int(9223372036854775807) +>9223372036854775807< |= >2e+5<, result: int(9223372036854775807) +>9223372036854775807< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< |= >9223372036854775807<, result: int(9223372036854775807) +------------------------------------- diff --git a/tests/expressions/assignment_operators/sl_assignment.phpt b/tests/expressions/assignment_operators/sl_assignment.phpt new file mode 100644 index 00000000..2d6fc1ae --- /dev/null +++ b/tests/expressions/assignment_operators/sl_assignment.phpt @@ -0,0 +1,343 @@ +--TEST-- +<<= operator +--FILE-- +$e1< <<= >$e2<, result: "; var_dump($e1 <<= $e2); + } + echo "-------------------------------------\n"; +} + +?> +--EXPECTF-- +>0< <<= >0<, result: int(0) +>0< <<= >100<, result: int(0) +>0< <<= >INF<, result: int(0) +>0< <<= >-INF<, result: int(0) +>0< <<= >NAN<, result: int(0) +>0< <<= >1<, result: int(0) +>0< <<= ><, result: int(0) +>0< <<= ><, result: int(0) +>0< <<= >123<, result: int(0) +>0< <<= >2e+5<, result: int(0) +>0< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>-10< <<= >0<, result: int(-10) +>-10< <<= >100<, result: int(0) +>-10< <<= >INF<, result: int(-10) +>-10< <<= >-INF<, result: int(-10) +>-10< <<= >NAN<, result: int(-10) +>-10< <<= >1<, result: int(-20) +>-10< <<= ><, result: int(-10) +>-10< <<= ><, result: int(-10) +>-10< <<= >123<, result: int(0) +>-10< <<= >2e+5<, result: int(0) +>-10< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>100< <<= >0<, result: int(100) +>100< <<= >100<, result: int(0) +>100< <<= >INF<, result: int(100) +>100< <<= >-INF<, result: int(100) +>100< <<= >NAN<, result: int(100) +>100< <<= >1<, result: int(200) +>100< <<= ><, result: int(100) +>100< <<= ><, result: int(100) +>100< <<= >123<, result: int(0) +>100< <<= >2e+5<, result: int(0) +>100< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>-34000000000< <<= >0<, result: int(-34000000000) +>-34000000000< <<= >100<, result: int(0) +>-34000000000< <<= >INF<, result: int(-34000000000) +>-34000000000< <<= >-INF<, result: int(-34000000000) +>-34000000000< <<= >NAN<, result: int(-34000000000) +>-34000000000< <<= >1<, result: int(-68000000000) +>-34000000000< <<= ><, result: int(-34000000000) +>-34000000000< <<= ><, result: int(-34000000000) +>-34000000000< <<= >123<, result: int(0) +>-34000000000< <<= >2e+5<, result: int(0) +>-34000000000< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>-34000000000< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>-34000000000< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>INF< <<= >0<, result: int(0) +>INF< <<= >100<, result: int(0) +>INF< <<= >INF<, result: int(0) +>INF< <<= >-INF<, result: int(0) +>INF< <<= >NAN<, result: int(0) +>INF< <<= >1<, result: int(0) +>INF< <<= ><, result: int(0) +>INF< <<= ><, result: int(0) +>INF< <<= >123<, result: int(0) +>INF< <<= >2e+5<, result: int(0) +>INF< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>-INF< <<= >0<, result: int(0) +>-INF< <<= >100<, result: int(0) +>-INF< <<= >INF<, result: int(0) +>-INF< <<= >-INF<, result: int(0) +>-INF< <<= >NAN<, result: int(0) +>-INF< <<= >1<, result: int(0) +>-INF< <<= ><, result: int(0) +>-INF< <<= ><, result: int(0) +>-INF< <<= >123<, result: int(0) +>-INF< <<= >2e+5<, result: int(0) +>-INF< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>NAN< <<= >0<, result: int(0) +>NAN< <<= >100<, result: int(0) +>NAN< <<= >INF<, result: int(0) +>NAN< <<= >-INF<, result: int(0) +>NAN< <<= >NAN<, result: int(0) +>NAN< <<= >1<, result: int(0) +>NAN< <<= ><, result: int(0) +>NAN< <<= ><, result: int(0) +>NAN< <<= >123<, result: int(0) +>NAN< <<= >2e+5<, result: int(0) +>NAN< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>1< <<= >0<, result: int(1) +>1< <<= >100<, result: int(0) +>1< <<= >INF<, result: int(1) +>1< <<= >-INF<, result: int(1) +>1< <<= >NAN<, result: int(1) +>1< <<= >1<, result: int(2) +>1< <<= ><, result: int(1) +>1< <<= ><, result: int(1) +>1< <<= >123<, result: int(0) +>1< <<= >2e+5<, result: int(0) +>1< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>< <<= >0<, result: int(0) +>< <<= >100<, result: int(0) +>< <<= >INF<, result: int(0) +>< <<= >-INF<, result: int(0) +>< <<= >NAN<, result: int(0) +>< <<= >1<, result: int(0) +>< <<= ><, result: int(0) +>< <<= ><, result: int(0) +>< <<= >123<, result: int(0) +>< <<= >2e+5<, result: int(0) +>< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>< <<= >0<, result: int(0) +>< <<= >100<, result: int(0) +>< <<= >INF<, result: int(0) +>< <<= >-INF<, result: int(0) +>< <<= >NAN<, result: int(0) +>< <<= >1<, result: int(0) +>< <<= ><, result: int(0) +>< <<= ><, result: int(0) +>< <<= >123<, result: int(0) +>< <<= >2e+5<, result: int(0) +>< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>123< <<= >0<, result: int(123) +>123< <<= >100<, result: int(0) +>123< <<= >INF<, result: int(123) +>123< <<= >-INF<, result: int(123) +>123< <<= >NAN<, result: int(123) +>123< <<= >1<, result: int(246) +>123< <<= ><, result: int(123) +>123< <<= ><, result: int(123) +>123< <<= >123<, result: int(0) +>123< <<= >2e+5<, result: int(0) +>123< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>2e+5< <<= >0<, result: int(200000) +>2e+5< <<= >100<, result: int(0) +>2e+5< <<= >INF<, result: int(200000) +>2e+5< <<= >-INF<, result: int(200000) +>2e+5< <<= >NAN<, result: int(200000) +>2e+5< <<= >1<, result: int(400000) +>2e+5< <<= ><, result: int(200000) +>2e+5< <<= ><, result: int(200000) +>2e+5< <<= >123<, result: int(0) +>2e+5< <<= >2e+5<, result: int(0) +>2e+5< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(200000) +>2e+5< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(200000) +>2e+5< <<= >9223372036854775807<, result: int(0) +------------------------------------- +>< <<= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>abc< <<= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>9223372036854775807< <<= >0<, result: int(9223372036854775807) +>9223372036854775807< <<= >100<, result: int(0) +>9223372036854775807< <<= >INF<, result: int(9223372036854775807) +>9223372036854775807< <<= >-INF<, result: int(9223372036854775807) +>9223372036854775807< <<= >NAN<, result: int(9223372036854775807) +>9223372036854775807< <<= >1<, result: int(-2) +>9223372036854775807< <<= ><, result: int(9223372036854775807) +>9223372036854775807< <<= ><, result: int(9223372036854775807) +>9223372036854775807< <<= >123<, result: int(0) +>9223372036854775807< <<= >2e+5<, result: int(0) +>9223372036854775807< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< <<= >9223372036854775807<, result: int(0) +------------------------------------- diff --git a/tests/expressions/assignment_operators/sr_assignment.phpt b/tests/expressions/assignment_operators/sr_assignment.phpt new file mode 100644 index 00000000..43c08968 --- /dev/null +++ b/tests/expressions/assignment_operators/sr_assignment.phpt @@ -0,0 +1,343 @@ +--TEST-- +>>= operator +--FILE-- +$e1< >>= >$e2<, result: "; var_dump($e1 <<= $e2); + } + echo "-------------------------------------\n"; +} + +?> +--EXPECTF-- +>0< >>= >0<, result: int(0) +>0< >>= >100<, result: int(0) +>0< >>= >INF<, result: int(0) +>0< >>= >-INF<, result: int(0) +>0< >>= >NAN<, result: int(0) +>0< >>= >1<, result: int(0) +>0< >>= ><, result: int(0) +>0< >>= ><, result: int(0) +>0< >>= >123<, result: int(0) +>0< >>= >2e+5<, result: int(0) +>0< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>-10< >>= >0<, result: int(-10) +>-10< >>= >100<, result: int(0) +>-10< >>= >INF<, result: int(-10) +>-10< >>= >-INF<, result: int(-10) +>-10< >>= >NAN<, result: int(-10) +>-10< >>= >1<, result: int(-20) +>-10< >>= ><, result: int(-10) +>-10< >>= ><, result: int(-10) +>-10< >>= >123<, result: int(0) +>-10< >>= >2e+5<, result: int(0) +>-10< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>100< >>= >0<, result: int(100) +>100< >>= >100<, result: int(0) +>100< >>= >INF<, result: int(100) +>100< >>= >-INF<, result: int(100) +>100< >>= >NAN<, result: int(100) +>100< >>= >1<, result: int(200) +>100< >>= ><, result: int(100) +>100< >>= ><, result: int(100) +>100< >>= >123<, result: int(0) +>100< >>= >2e+5<, result: int(0) +>100< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>-34000000000< >>= >0<, result: int(-34000000000) +>-34000000000< >>= >100<, result: int(0) +>-34000000000< >>= >INF<, result: int(-34000000000) +>-34000000000< >>= >-INF<, result: int(-34000000000) +>-34000000000< >>= >NAN<, result: int(-34000000000) +>-34000000000< >>= >1<, result: int(-68000000000) +>-34000000000< >>= ><, result: int(-34000000000) +>-34000000000< >>= ><, result: int(-34000000000) +>-34000000000< >>= >123<, result: int(0) +>-34000000000< >>= >2e+5<, result: int(0) +>-34000000000< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>-34000000000< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>-34000000000< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>INF< >>= >0<, result: int(0) +>INF< >>= >100<, result: int(0) +>INF< >>= >INF<, result: int(0) +>INF< >>= >-INF<, result: int(0) +>INF< >>= >NAN<, result: int(0) +>INF< >>= >1<, result: int(0) +>INF< >>= ><, result: int(0) +>INF< >>= ><, result: int(0) +>INF< >>= >123<, result: int(0) +>INF< >>= >2e+5<, result: int(0) +>INF< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>-INF< >>= >0<, result: int(0) +>-INF< >>= >100<, result: int(0) +>-INF< >>= >INF<, result: int(0) +>-INF< >>= >-INF<, result: int(0) +>-INF< >>= >NAN<, result: int(0) +>-INF< >>= >1<, result: int(0) +>-INF< >>= ><, result: int(0) +>-INF< >>= ><, result: int(0) +>-INF< >>= >123<, result: int(0) +>-INF< >>= >2e+5<, result: int(0) +>-INF< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>NAN< >>= >0<, result: int(0) +>NAN< >>= >100<, result: int(0) +>NAN< >>= >INF<, result: int(0) +>NAN< >>= >-INF<, result: int(0) +>NAN< >>= >NAN<, result: int(0) +>NAN< >>= >1<, result: int(0) +>NAN< >>= ><, result: int(0) +>NAN< >>= ><, result: int(0) +>NAN< >>= >123<, result: int(0) +>NAN< >>= >2e+5<, result: int(0) +>NAN< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>1< >>= >0<, result: int(1) +>1< >>= >100<, result: int(0) +>1< >>= >INF<, result: int(1) +>1< >>= >-INF<, result: int(1) +>1< >>= >NAN<, result: int(1) +>1< >>= >1<, result: int(2) +>1< >>= ><, result: int(1) +>1< >>= ><, result: int(1) +>1< >>= >123<, result: int(0) +>1< >>= >2e+5<, result: int(0) +>1< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>< >>= >0<, result: int(0) +>< >>= >100<, result: int(0) +>< >>= >INF<, result: int(0) +>< >>= >-INF<, result: int(0) +>< >>= >NAN<, result: int(0) +>< >>= >1<, result: int(0) +>< >>= ><, result: int(0) +>< >>= ><, result: int(0) +>< >>= >123<, result: int(0) +>< >>= >2e+5<, result: int(0) +>< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>< >>= >0<, result: int(0) +>< >>= >100<, result: int(0) +>< >>= >INF<, result: int(0) +>< >>= >-INF<, result: int(0) +>< >>= >NAN<, result: int(0) +>< >>= >1<, result: int(0) +>< >>= ><, result: int(0) +>< >>= ><, result: int(0) +>< >>= >123<, result: int(0) +>< >>= >2e+5<, result: int(0) +>< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>123< >>= >0<, result: int(123) +>123< >>= >100<, result: int(0) +>123< >>= >INF<, result: int(123) +>123< >>= >-INF<, result: int(123) +>123< >>= >NAN<, result: int(123) +>123< >>= >1<, result: int(246) +>123< >>= ><, result: int(123) +>123< >>= ><, result: int(123) +>123< >>= >123<, result: int(0) +>123< >>= >2e+5<, result: int(0) +>123< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>2e+5< >>= >0<, result: int(200000) +>2e+5< >>= >100<, result: int(0) +>2e+5< >>= >INF<, result: int(200000) +>2e+5< >>= >-INF<, result: int(200000) +>2e+5< >>= >NAN<, result: int(200000) +>2e+5< >>= >1<, result: int(400000) +>2e+5< >>= ><, result: int(200000) +>2e+5< >>= ><, result: int(200000) +>2e+5< >>= >123<, result: int(0) +>2e+5< >>= >2e+5<, result: int(0) +>2e+5< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(200000) +>2e+5< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(200000) +>2e+5< >>= >9223372036854775807<, result: int(0) +------------------------------------- +>< >>= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>abc< >>= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>9223372036854775807< >>= >0<, result: int(9223372036854775807) +>9223372036854775807< >>= >100<, result: int(0) +>9223372036854775807< >>= >INF<, result: int(9223372036854775807) +>9223372036854775807< >>= >-INF<, result: int(9223372036854775807) +>9223372036854775807< >>= >NAN<, result: int(9223372036854775807) +>9223372036854775807< >>= >1<, result: int(-2) +>9223372036854775807< >>= ><, result: int(9223372036854775807) +>9223372036854775807< >>= ><, result: int(9223372036854775807) +>9223372036854775807< >>= >123<, result: int(0) +>9223372036854775807< >>= >2e+5<, result: int(0) +>9223372036854775807< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< >>= >9223372036854775807<, result: int(0) +------------------------------------- diff --git a/tests/expressions/assignment_operators/sub_assignment.phpt b/tests/expressions/assignment_operators/sub_assignment.phpt new file mode 100644 index 00000000..345d695c --- /dev/null +++ b/tests/expressions/assignment_operators/sub_assignment.phpt @@ -0,0 +1,379 @@ +--TEST-- +-= operator +--FILE-- +$e1< -= >$e2<, result: "; var_dump($e1 -= $e2); + } + echo "-------------------------------------\n"; +} + +?> +--EXPECTF-- +>0< -= >0<, result: int(0) +>0< -= >-10<, result: int(10) +>0< -= >100<, result: int(-100) +>0< -= >-34000000000<, result: float(34000000000) +>0< -= >INF<, result: float(-INF) +>0< -= >-INF<, result: float(INF) +>0< -= >NAN<, result: float(NAN) +>0< -= >1<, result: int(-1) +>0< -= ><, result: int(0) +>0< -= ><, result: int(0) +>0< -= >123<, result: int(-123) +>0< -= >2e+5<, result: float(-200000) +>0< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< -= >9223372036854775807<, result: int(-9223372036854775807) +------------------------------------- +>-10< -= >0<, result: int(-10) +>-10< -= >-10<, result: int(0) +>-10< -= >100<, result: int(-110) +>-10< -= >-34000000000<, result: float(33999999990) +>-10< -= >INF<, result: float(-INF) +>-10< -= >-INF<, result: float(INF) +>-10< -= >NAN<, result: float(NAN) +>-10< -= >1<, result: int(-11) +>-10< -= ><, result: int(-10) +>-10< -= ><, result: int(-10) +>-10< -= >123<, result: int(-133) +>-10< -= >2e+5<, result: float(-200010) +>-10< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< -= >9223372036854775807<, result: float(-9.2233720368548E+18) +------------------------------------- +>100< -= >0<, result: int(100) +>100< -= >-10<, result: int(110) +>100< -= >100<, result: int(0) +>100< -= >-34000000000<, result: float(34000000100) +>100< -= >INF<, result: float(-INF) +>100< -= >-INF<, result: float(INF) +>100< -= >NAN<, result: float(NAN) +>100< -= >1<, result: int(99) +>100< -= ><, result: int(100) +>100< -= ><, result: int(100) +>100< -= >123<, result: int(-23) +>100< -= >2e+5<, result: float(-199900) +>100< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< -= >9223372036854775807<, result: int(-9223372036854775707) +------------------------------------- +>-34000000000< -= >0<, result: float(-34000000000) +>-34000000000< -= >-10<, result: float(-33999999990) +>-34000000000< -= >100<, result: float(-34000000100) +>-34000000000< -= >-34000000000<, result: float(0) +>-34000000000< -= >INF<, result: float(-INF) +>-34000000000< -= >-INF<, result: float(INF) +>-34000000000< -= >NAN<, result: float(NAN) +>-34000000000< -= >1<, result: float(-34000000001) +>-34000000000< -= ><, result: float(-34000000000) +>-34000000000< -= ><, result: float(-34000000000) +>-34000000000< -= >123<, result: float(-34000000123) +>-34000000000< -= >2e+5<, result: float(-34000200000) +>-34000000000< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) +>-34000000000< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) +>-34000000000< -= >9223372036854775807<, result: float(-9.2233720708548E+18) +------------------------------------- +>INF< -= >0<, result: float(INF) +>INF< -= >-10<, result: float(INF) +>INF< -= >100<, result: float(INF) +>INF< -= >-34000000000<, result: float(INF) +>INF< -= >INF<, result: float(NAN) +>INF< -= >-INF<, result: float(INF) +>INF< -= >NAN<, result: float(NAN) +>INF< -= >1<, result: float(INF) +>INF< -= ><, result: float(INF) +>INF< -= ><, result: float(INF) +>INF< -= >123<, result: float(INF) +>INF< -= >2e+5<, result: float(INF) +>INF< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>INF< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>INF< -= >9223372036854775807<, result: float(INF) +------------------------------------- +>-INF< -= >0<, result: float(-INF) +>-INF< -= >-10<, result: float(-INF) +>-INF< -= >100<, result: float(-INF) +>-INF< -= >-34000000000<, result: float(-INF) +>-INF< -= >INF<, result: float(-INF) +>-INF< -= >-INF<, result: float(NAN) +>-INF< -= >NAN<, result: float(NAN) +>-INF< -= >1<, result: float(-INF) +>-INF< -= ><, result: float(-INF) +>-INF< -= ><, result: float(-INF) +>-INF< -= >123<, result: float(-INF) +>-INF< -= >2e+5<, result: float(-INF) +>-INF< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>-INF< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>-INF< -= >9223372036854775807<, result: float(-INF) +------------------------------------- +>NAN< -= >0<, result: float(NAN) +>NAN< -= >-10<, result: float(NAN) +>NAN< -= >100<, result: float(NAN) +>NAN< -= >-34000000000<, result: float(NAN) +>NAN< -= >INF<, result: float(NAN) +>NAN< -= >-INF<, result: float(NAN) +>NAN< -= >NAN<, result: float(NAN) +>NAN< -= >1<, result: float(NAN) +>NAN< -= ><, result: float(NAN) +>NAN< -= ><, result: float(NAN) +>NAN< -= >123<, result: float(NAN) +>NAN< -= >2e+5<, result: float(NAN) +>NAN< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>NAN< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>NAN< -= >9223372036854775807<, result: float(NAN) +------------------------------------- +>1< -= >0<, result: int(1) +>1< -= >-10<, result: int(11) +>1< -= >100<, result: int(-99) +>1< -= >-34000000000<, result: float(34000000001) +>1< -= >INF<, result: float(-INF) +>1< -= >-INF<, result: float(INF) +>1< -= >NAN<, result: float(NAN) +>1< -= >1<, result: int(0) +>1< -= ><, result: int(1) +>1< -= ><, result: int(1) +>1< -= >123<, result: int(-122) +>1< -= >2e+5<, result: float(-199999) +>1< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< -= >9223372036854775807<, result: int(-9223372036854775806) +------------------------------------- +>< -= >0<, result: int(0) +>< -= >-10<, result: int(10) +>< -= >100<, result: int(-100) +>< -= >-34000000000<, result: float(34000000000) +>< -= >INF<, result: float(-INF) +>< -= >-INF<, result: float(INF) +>< -= >NAN<, result: float(NAN) +>< -= >1<, result: int(-1) +>< -= ><, result: int(0) +>< -= ><, result: int(0) +>< -= >123<, result: int(-123) +>< -= >2e+5<, result: float(-200000) +>< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >9223372036854775807<, result: int(-9223372036854775807) +------------------------------------- +>< -= >0<, result: int(0) +>< -= >-10<, result: int(10) +>< -= >100<, result: int(-100) +>< -= >-34000000000<, result: float(34000000000) +>< -= >INF<, result: float(-INF) +>< -= >-INF<, result: float(INF) +>< -= >NAN<, result: float(NAN) +>< -= >1<, result: int(-1) +>< -= ><, result: int(0) +>< -= ><, result: int(0) +>< -= >123<, result: int(-123) +>< -= >2e+5<, result: float(-200000) +>< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >9223372036854775807<, result: int(-9223372036854775807) +------------------------------------- +>123< -= >0<, result: int(123) +>123< -= >-10<, result: int(133) +>123< -= >100<, result: int(23) +>123< -= >-34000000000<, result: float(34000000123) +>123< -= >INF<, result: float(-INF) +>123< -= >-INF<, result: float(INF) +>123< -= >NAN<, result: float(NAN) +>123< -= >1<, result: int(122) +>123< -= ><, result: int(123) +>123< -= ><, result: int(123) +>123< -= >123<, result: int(0) +>123< -= >2e+5<, result: float(-199877) +>123< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< -= >9223372036854775807<, result: int(-9223372036854775684) +------------------------------------- +>2e+5< -= >0<, result: float(200000) +>2e+5< -= >-10<, result: float(200010) +>2e+5< -= >100<, result: float(199900) +>2e+5< -= >-34000000000<, result: float(34000200000) +>2e+5< -= >INF<, result: float(-INF) +>2e+5< -= >-INF<, result: float(INF) +>2e+5< -= >NAN<, result: float(NAN) +>2e+5< -= >1<, result: float(199999) +>2e+5< -= ><, result: float(200000) +>2e+5< -= ><, result: float(200000) +>2e+5< -= >123<, result: float(199877) +>2e+5< -= >2e+5<, result: float(0) +>2e+5< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) +>2e+5< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) +>2e+5< -= >9223372036854775807<, result: float(-9.2233720368546E+18) +------------------------------------- +>< -= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(10) +>< -= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-100) +>< -= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(34000000000) +>< -= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>< -= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>< -= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< -= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-1) +>< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-123) +>< -= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-200000) +>< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-9223372036854775807) +------------------------------------- +>abc< -= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< -= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(10) +>abc< -= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-100) +>abc< -= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(34000000000) +>abc< -= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>abc< -= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>abc< -= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< -= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-1) +>abc< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< -= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-123) +>abc< -= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-200000) +>abc< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< -= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-9223372036854775807) +------------------------------------- +>9223372036854775807< -= >0<, result: int(9223372036854775807) +>9223372036854775807< -= >-10<, result: float(9.2233720368548E+18) +>9223372036854775807< -= >100<, result: int(9223372036854775707) +>9223372036854775807< -= >-34000000000<, result: float(9.2233720708548E+18) +>9223372036854775807< -= >INF<, result: float(-INF) +>9223372036854775807< -= >-INF<, result: float(INF) +>9223372036854775807< -= >NAN<, result: float(NAN) +>9223372036854775807< -= >1<, result: int(9223372036854775806) +>9223372036854775807< -= ><, result: int(9223372036854775807) +>9223372036854775807< -= ><, result: int(9223372036854775807) +>9223372036854775807< -= >123<, result: int(9223372036854775684) +>9223372036854775807< -= >2e+5<, result: float(9.2233720368546E+18) +>9223372036854775807< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< -= >9223372036854775807<, result: int(0) +------------------------------------- diff --git a/tests/expressions/assignment_operators/xor_assignment.phpt b/tests/expressions/assignment_operators/xor_assignment.phpt new file mode 100644 index 00000000..904d5853 Binary files /dev/null and b/tests/expressions/assignment_operators/xor_assignment.phpt differ diff --git a/tests/expressions/binary_logical_operators/binary_logical_operators.phpt b/tests/expressions/binary_logical_operators/binary_logical_operators.phpt index 0431077e..0caa03db 100644 --- a/tests/expressions/binary_logical_operators/binary_logical_operators.phpt +++ b/tests/expressions/binary_logical_operators/binary_logical_operators.phpt @@ -62,4 +62,4 @@ inside f(1) bool(true) inside f(5) inside g(6) -bool(true) \ No newline at end of file +bool(true) diff --git a/tests/expressions/bitwise_and,_or,_xor_operators/bitwise_and_or_xor.phpt b/tests/expressions/bitwise_and,_or,_xor_operators/bitwise_and_or_xor.phpt index 54863c2b..7ae0048f 100644 --- a/tests/expressions/bitwise_and,_or,_xor_operators/bitwise_and_or_xor.phpt +++ b/tests/expressions/bitwise_and,_or,_xor_operators/bitwise_and_or_xor.phpt @@ -70,4 +70,4 @@ $v1 = -987, $v2 = 1234 1010 ^ 123 = 1110001 1111111111111111111111111111111111111111111111111111111110011100 & 123 = 11000 1111111111111111111111111111111111111111111111111111111110011100 | 123 = 1111111111111111111111111111111111111111111111111111111111111111 -1111111111111111111111111111111111111111111111111111111110011100 ^ 123 = 1111111111111111111111111111111111111111111111111111111111100111 \ No newline at end of file +1111111111111111111111111111111111111111111111111111111110011100 ^ 123 = 1111111111111111111111111111111111111111111111111111111111100111 diff --git a/tests/expressions/bitwise_shift_operators/bitwise_shift.phpt b/tests/expressions/bitwise_shift_operators/bitwise_shift.phpt index 376695df..d271a633 100644 --- a/tests/expressions/bitwise_shift_operators/bitwise_shift.phpt +++ b/tests/expressions/bitwise_shift_operators/bitwise_shift.phpt @@ -17,7 +17,7 @@ $NumBitsPerInt = ($i32 < 0) ? 32 : 64; // Shift a positive value right and left using both in- and out-of-range counts $v = 1000; -for ($i = -$NumBitsPerInt - 1; $i <= $NumBitsPerInt + 1; ++$i) +for ($i = 0; $i <= $NumBitsPerInt + 1; ++$i) { printf("%d(%08X): >> %2d = %08X\t<< %2d = %08X\n", $v, $v, $i, $v >> $i, $i, $v << $i); } @@ -25,7 +25,7 @@ for ($i = -$NumBitsPerInt - 1; $i <= $NumBitsPerInt + 1; ++$i) // Shift a negative value right and left using both in- and out-of-range counts $v = -1000; -for ($i = -$NumBitsPerInt - 1; $i <= $NumBitsPerInt + 1; ++$i) +for ($i = 0; $i <= $NumBitsPerInt + 1; ++$i) { printf("%d(%08X): >> %2d = %08X\t<< %2d = %08X\n", $v, $v, $i, $v >> $i, $i, $v << $i); } @@ -37,88 +37,7 @@ foreach ($scalarValueList as $v) { printf("%d(%08X): >> %2d = %08X\t<< %2d = %08X\n", $v, $v, 3, $v >> 3, 5, $v << 5); } - -// Figure out the algorithm the implementations use for negative and too-large shift counts - -for ($i = -129; $i <= 129; ++$i) -{ - $rem = $i % $NumBitsPerInt; - if ($rem == 0 || $i > 0) - { - echo "$i, ".$rem."\n"; - } - else // have a negative shift - { - $r = $NumBitsPerInt - (-$i % $NumBitsPerInt); - echo "$i, ".$r."\n"; - } -} ---EXPECT-- -1000(000003E8): >> -65 = 00000000 << -65 = 00000000 -1000(000003E8): >> -64 = 000003E8 << -64 = 000003E8 -1000(000003E8): >> -63 = 000001F4 << -63 = 000007D0 -1000(000003E8): >> -62 = 000000FA << -62 = 00000FA0 -1000(000003E8): >> -61 = 0000007D << -61 = 00001F40 -1000(000003E8): >> -60 = 0000003E << -60 = 00003E80 -1000(000003E8): >> -59 = 0000001F << -59 = 00007D00 -1000(000003E8): >> -58 = 0000000F << -58 = 0000FA00 -1000(000003E8): >> -57 = 00000007 << -57 = 0001F400 -1000(000003E8): >> -56 = 00000003 << -56 = 0003E800 -1000(000003E8): >> -55 = 00000001 << -55 = 0007D000 -1000(000003E8): >> -54 = 00000000 << -54 = 000FA000 -1000(000003E8): >> -53 = 00000000 << -53 = 001F4000 -1000(000003E8): >> -52 = 00000000 << -52 = 003E8000 -1000(000003E8): >> -51 = 00000000 << -51 = 007D0000 -1000(000003E8): >> -50 = 00000000 << -50 = 00FA0000 -1000(000003E8): >> -49 = 00000000 << -49 = 01F40000 -1000(000003E8): >> -48 = 00000000 << -48 = 03E80000 -1000(000003E8): >> -47 = 00000000 << -47 = 07D00000 -1000(000003E8): >> -46 = 00000000 << -46 = 0FA00000 -1000(000003E8): >> -45 = 00000000 << -45 = 1F400000 -1000(000003E8): >> -44 = 00000000 << -44 = 3E800000 -1000(000003E8): >> -43 = 00000000 << -43 = 7D000000 -1000(000003E8): >> -42 = 00000000 << -42 = FA000000 -1000(000003E8): >> -41 = 00000000 << -41 = 1F4000000 -1000(000003E8): >> -40 = 00000000 << -40 = 3E8000000 -1000(000003E8): >> -39 = 00000000 << -39 = 7D0000000 -1000(000003E8): >> -38 = 00000000 << -38 = FA0000000 -1000(000003E8): >> -37 = 00000000 << -37 = 1F40000000 -1000(000003E8): >> -36 = 00000000 << -36 = 3E80000000 -1000(000003E8): >> -35 = 00000000 << -35 = 7D00000000 -1000(000003E8): >> -34 = 00000000 << -34 = FA00000000 -1000(000003E8): >> -33 = 00000000 << -33 = 1F400000000 -1000(000003E8): >> -32 = 00000000 << -32 = 3E800000000 -1000(000003E8): >> -31 = 00000000 << -31 = 7D000000000 -1000(000003E8): >> -30 = 00000000 << -30 = FA000000000 -1000(000003E8): >> -29 = 00000000 << -29 = 1F4000000000 -1000(000003E8): >> -28 = 00000000 << -28 = 3E8000000000 -1000(000003E8): >> -27 = 00000000 << -27 = 7D0000000000 -1000(000003E8): >> -26 = 00000000 << -26 = FA0000000000 -1000(000003E8): >> -25 = 00000000 << -25 = 1F40000000000 -1000(000003E8): >> -24 = 00000000 << -24 = 3E80000000000 -1000(000003E8): >> -23 = 00000000 << -23 = 7D00000000000 -1000(000003E8): >> -22 = 00000000 << -22 = FA00000000000 -1000(000003E8): >> -21 = 00000000 << -21 = 1F400000000000 -1000(000003E8): >> -20 = 00000000 << -20 = 3E800000000000 -1000(000003E8): >> -19 = 00000000 << -19 = 7D000000000000 -1000(000003E8): >> -18 = 00000000 << -18 = FA000000000000 -1000(000003E8): >> -17 = 00000000 << -17 = 1F4000000000000 -1000(000003E8): >> -16 = 00000000 << -16 = 3E8000000000000 -1000(000003E8): >> -15 = 00000000 << -15 = 7D0000000000000 -1000(000003E8): >> -14 = 00000000 << -14 = FA0000000000000 -1000(000003E8): >> -13 = 00000000 << -13 = 1F40000000000000 -1000(000003E8): >> -12 = 00000000 << -12 = 3E80000000000000 -1000(000003E8): >> -11 = 00000000 << -11 = 7D00000000000000 -1000(000003E8): >> -10 = 00000000 << -10 = FA00000000000000 -1000(000003E8): >> -9 = 00000000 << -9 = F400000000000000 -1000(000003E8): >> -8 = 00000000 << -8 = E800000000000000 -1000(000003E8): >> -7 = 00000000 << -7 = D000000000000000 -1000(000003E8): >> -6 = 00000000 << -6 = A000000000000000 -1000(000003E8): >> -5 = 00000000 << -5 = 4000000000000000 -1000(000003E8): >> -4 = 00000000 << -4 = 8000000000000000 -1000(000003E8): >> -3 = 00000000 << -3 = 00000000 -1000(000003E8): >> -2 = 00000000 << -2 = 00000000 -1000(000003E8): >> -1 = 00000000 << -1 = 00000000 +--EXPECTF-- 1000(000003E8): >> 0 = 000003E8 << 0 = 000003E8 1000(000003E8): >> 1 = 000001F4 << 1 = 000007D0 1000(000003E8): >> 2 = 000000FA << 2 = 00000FA0 @@ -183,73 +102,8 @@ for ($i = -129; $i <= 129; ++$i) 1000(000003E8): >> 61 = 00000000 << 61 = 00000000 1000(000003E8): >> 62 = 00000000 << 62 = 00000000 1000(000003E8): >> 63 = 00000000 << 63 = 00000000 -1000(000003E8): >> 64 = 000003E8 << 64 = 000003E8 -1000(000003E8): >> 65 = 000001F4 << 65 = 000007D0 --1000(FFFFFFFFFFFFFC18): >> -65 = FFFFFFFFFFFFFFFF << -65 = 00000000 --1000(FFFFFFFFFFFFFC18): >> -64 = FFFFFFFFFFFFFC18 << -64 = FFFFFFFFFFFFFC18 --1000(FFFFFFFFFFFFFC18): >> -63 = FFFFFFFFFFFFFE0C << -63 = FFFFFFFFFFFFF830 --1000(FFFFFFFFFFFFFC18): >> -62 = FFFFFFFFFFFFFF06 << -62 = FFFFFFFFFFFFF060 --1000(FFFFFFFFFFFFFC18): >> -61 = FFFFFFFFFFFFFF83 << -61 = FFFFFFFFFFFFE0C0 --1000(FFFFFFFFFFFFFC18): >> -60 = FFFFFFFFFFFFFFC1 << -60 = FFFFFFFFFFFFC180 --1000(FFFFFFFFFFFFFC18): >> -59 = FFFFFFFFFFFFFFE0 << -59 = FFFFFFFFFFFF8300 --1000(FFFFFFFFFFFFFC18): >> -58 = FFFFFFFFFFFFFFF0 << -58 = FFFFFFFFFFFF0600 --1000(FFFFFFFFFFFFFC18): >> -57 = FFFFFFFFFFFFFFF8 << -57 = FFFFFFFFFFFE0C00 --1000(FFFFFFFFFFFFFC18): >> -56 = FFFFFFFFFFFFFFFC << -56 = FFFFFFFFFFFC1800 --1000(FFFFFFFFFFFFFC18): >> -55 = FFFFFFFFFFFFFFFE << -55 = FFFFFFFFFFF83000 --1000(FFFFFFFFFFFFFC18): >> -54 = FFFFFFFFFFFFFFFF << -54 = FFFFFFFFFFF06000 --1000(FFFFFFFFFFFFFC18): >> -53 = FFFFFFFFFFFFFFFF << -53 = FFFFFFFFFFE0C000 --1000(FFFFFFFFFFFFFC18): >> -52 = FFFFFFFFFFFFFFFF << -52 = FFFFFFFFFFC18000 --1000(FFFFFFFFFFFFFC18): >> -51 = FFFFFFFFFFFFFFFF << -51 = FFFFFFFFFF830000 --1000(FFFFFFFFFFFFFC18): >> -50 = FFFFFFFFFFFFFFFF << -50 = FFFFFFFFFF060000 --1000(FFFFFFFFFFFFFC18): >> -49 = FFFFFFFFFFFFFFFF << -49 = FFFFFFFFFE0C0000 --1000(FFFFFFFFFFFFFC18): >> -48 = FFFFFFFFFFFFFFFF << -48 = FFFFFFFFFC180000 --1000(FFFFFFFFFFFFFC18): >> -47 = FFFFFFFFFFFFFFFF << -47 = FFFFFFFFF8300000 --1000(FFFFFFFFFFFFFC18): >> -46 = FFFFFFFFFFFFFFFF << -46 = FFFFFFFFF0600000 --1000(FFFFFFFFFFFFFC18): >> -45 = FFFFFFFFFFFFFFFF << -45 = FFFFFFFFE0C00000 --1000(FFFFFFFFFFFFFC18): >> -44 = FFFFFFFFFFFFFFFF << -44 = FFFFFFFFC1800000 --1000(FFFFFFFFFFFFFC18): >> -43 = FFFFFFFFFFFFFFFF << -43 = FFFFFFFF83000000 --1000(FFFFFFFFFFFFFC18): >> -42 = FFFFFFFFFFFFFFFF << -42 = FFFFFFFF06000000 --1000(FFFFFFFFFFFFFC18): >> -41 = FFFFFFFFFFFFFFFF << -41 = FFFFFFFE0C000000 --1000(FFFFFFFFFFFFFC18): >> -40 = FFFFFFFFFFFFFFFF << -40 = FFFFFFFC18000000 --1000(FFFFFFFFFFFFFC18): >> -39 = FFFFFFFFFFFFFFFF << -39 = FFFFFFF830000000 --1000(FFFFFFFFFFFFFC18): >> -38 = FFFFFFFFFFFFFFFF << -38 = FFFFFFF060000000 --1000(FFFFFFFFFFFFFC18): >> -37 = FFFFFFFFFFFFFFFF << -37 = FFFFFFE0C0000000 --1000(FFFFFFFFFFFFFC18): >> -36 = FFFFFFFFFFFFFFFF << -36 = FFFFFFC180000000 --1000(FFFFFFFFFFFFFC18): >> -35 = FFFFFFFFFFFFFFFF << -35 = FFFFFF8300000000 --1000(FFFFFFFFFFFFFC18): >> -34 = FFFFFFFFFFFFFFFF << -34 = FFFFFF0600000000 --1000(FFFFFFFFFFFFFC18): >> -33 = FFFFFFFFFFFFFFFF << -33 = FFFFFE0C00000000 --1000(FFFFFFFFFFFFFC18): >> -32 = FFFFFFFFFFFFFFFF << -32 = FFFFFC1800000000 --1000(FFFFFFFFFFFFFC18): >> -31 = FFFFFFFFFFFFFFFF << -31 = FFFFF83000000000 --1000(FFFFFFFFFFFFFC18): >> -30 = FFFFFFFFFFFFFFFF << -30 = FFFFF06000000000 --1000(FFFFFFFFFFFFFC18): >> -29 = FFFFFFFFFFFFFFFF << -29 = FFFFE0C000000000 --1000(FFFFFFFFFFFFFC18): >> -28 = FFFFFFFFFFFFFFFF << -28 = FFFFC18000000000 --1000(FFFFFFFFFFFFFC18): >> -27 = FFFFFFFFFFFFFFFF << -27 = FFFF830000000000 --1000(FFFFFFFFFFFFFC18): >> -26 = FFFFFFFFFFFFFFFF << -26 = FFFF060000000000 --1000(FFFFFFFFFFFFFC18): >> -25 = FFFFFFFFFFFFFFFF << -25 = FFFE0C0000000000 --1000(FFFFFFFFFFFFFC18): >> -24 = FFFFFFFFFFFFFFFF << -24 = FFFC180000000000 --1000(FFFFFFFFFFFFFC18): >> -23 = FFFFFFFFFFFFFFFF << -23 = FFF8300000000000 --1000(FFFFFFFFFFFFFC18): >> -22 = FFFFFFFFFFFFFFFF << -22 = FFF0600000000000 --1000(FFFFFFFFFFFFFC18): >> -21 = FFFFFFFFFFFFFFFF << -21 = FFE0C00000000000 --1000(FFFFFFFFFFFFFC18): >> -20 = FFFFFFFFFFFFFFFF << -20 = FFC1800000000000 --1000(FFFFFFFFFFFFFC18): >> -19 = FFFFFFFFFFFFFFFF << -19 = FF83000000000000 --1000(FFFFFFFFFFFFFC18): >> -18 = FFFFFFFFFFFFFFFF << -18 = FF06000000000000 --1000(FFFFFFFFFFFFFC18): >> -17 = FFFFFFFFFFFFFFFF << -17 = FE0C000000000000 --1000(FFFFFFFFFFFFFC18): >> -16 = FFFFFFFFFFFFFFFF << -16 = FC18000000000000 --1000(FFFFFFFFFFFFFC18): >> -15 = FFFFFFFFFFFFFFFF << -15 = F830000000000000 --1000(FFFFFFFFFFFFFC18): >> -14 = FFFFFFFFFFFFFFFF << -14 = F060000000000000 --1000(FFFFFFFFFFFFFC18): >> -13 = FFFFFFFFFFFFFFFF << -13 = E0C0000000000000 --1000(FFFFFFFFFFFFFC18): >> -12 = FFFFFFFFFFFFFFFF << -12 = C180000000000000 --1000(FFFFFFFFFFFFFC18): >> -11 = FFFFFFFFFFFFFFFF << -11 = 8300000000000000 --1000(FFFFFFFFFFFFFC18): >> -10 = FFFFFFFFFFFFFFFF << -10 = 600000000000000 --1000(FFFFFFFFFFFFFC18): >> -9 = FFFFFFFFFFFFFFFF << -9 = C00000000000000 --1000(FFFFFFFFFFFFFC18): >> -8 = FFFFFFFFFFFFFFFF << -8 = 1800000000000000 --1000(FFFFFFFFFFFFFC18): >> -7 = FFFFFFFFFFFFFFFF << -7 = 3000000000000000 --1000(FFFFFFFFFFFFFC18): >> -6 = FFFFFFFFFFFFFFFF << -6 = 6000000000000000 --1000(FFFFFFFFFFFFFC18): >> -5 = FFFFFFFFFFFFFFFF << -5 = C000000000000000 --1000(FFFFFFFFFFFFFC18): >> -4 = FFFFFFFFFFFFFFFF << -4 = 8000000000000000 --1000(FFFFFFFFFFFFFC18): >> -3 = FFFFFFFFFFFFFFFF << -3 = 00000000 --1000(FFFFFFFFFFFFFC18): >> -2 = FFFFFFFFFFFFFFFF << -2 = 00000000 --1000(FFFFFFFFFFFFFC18): >> -1 = FFFFFFFFFFFFFFFF << -1 = 00000000 +1000(000003E8): >> 64 = 00000000 << 64 = 00000000 +1000(000003E8): >> 65 = 00000000 << 65 = 00000000 -1000(FFFFFFFFFFFFFC18): >> 0 = FFFFFFFFFFFFFC18 << 0 = FFFFFFFFFFFFFC18 -1000(FFFFFFFFFFFFFC18): >> 1 = FFFFFFFFFFFFFE0C << 1 = FFFFFFFFFFFFF830 -1000(FFFFFFFFFFFFFC18): >> 2 = FFFFFFFFFFFFFF06 << 2 = FFFFFFFFFFFFF060 @@ -314,8 +168,8 @@ for ($i = -129; $i <= 129; ++$i) -1000(FFFFFFFFFFFFFC18): >> 61 = FFFFFFFFFFFFFFFF << 61 = 00000000 -1000(FFFFFFFFFFFFFC18): >> 62 = FFFFFFFFFFFFFFFF << 62 = 00000000 -1000(FFFFFFFFFFFFFC18): >> 63 = FFFFFFFFFFFFFFFF << 63 = 00000000 --1000(FFFFFFFFFFFFFC18): >> 64 = FFFFFFFFFFFFFC18 << 64 = FFFFFFFFFFFFFC18 --1000(FFFFFFFFFFFFFC18): >> 65 = FFFFFFFFFFFFFE0C << 65 = FFFFFFFFFFFFF830 +-1000(FFFFFFFFFFFFFC18): >> 64 = FFFFFFFFFFFFFFFF << 64 = 00000000 +-1000(FFFFFFFFFFFFFC18): >> 65 = FFFFFFFFFFFFFFFF << 65 = 00000000 10(0000000A): >> 3 = 00000001 << 5 = 00000140 -100(FFFFFFFFFFFFFF9C): >> 3 = FFFFFFFFFFFFFFF3 << 5 = FFFFFFFFFFFFF380 0(00000000): >> 3 = 00000000 << 5 = 00000000 @@ -325,264 +179,13 @@ for ($i = -129; $i <= 129; ++$i) 0(00000000): >> 3 = 00000000 << 5 = 00000000 0(00000000): >> 3 = 00000000 << 5 = 00000000 123(0000007B): >> 3 = 0000000F << 5 = 00000F60 + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d 0(00000000): >> 3 = 00000000 << 5 = 00000000 + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d 0(00000000): >> 3 = 00000000 << 5 = 00000000 --129, 63 --128, 0 --127, 1 --126, 2 --125, 3 --124, 4 --123, 5 --122, 6 --121, 7 --120, 8 --119, 9 --118, 10 --117, 11 --116, 12 --115, 13 --114, 14 --113, 15 --112, 16 --111, 17 --110, 18 --109, 19 --108, 20 --107, 21 --106, 22 --105, 23 --104, 24 --103, 25 --102, 26 --101, 27 --100, 28 --99, 29 --98, 30 --97, 31 --96, 32 --95, 33 --94, 34 --93, 35 --92, 36 --91, 37 --90, 38 --89, 39 --88, 40 --87, 41 --86, 42 --85, 43 --84, 44 --83, 45 --82, 46 --81, 47 --80, 48 --79, 49 --78, 50 --77, 51 --76, 52 --75, 53 --74, 54 --73, 55 --72, 56 --71, 57 --70, 58 --69, 59 --68, 60 --67, 61 --66, 62 --65, 63 --64, 0 --63, 1 --62, 2 --61, 3 --60, 4 --59, 5 --58, 6 --57, 7 --56, 8 --55, 9 --54, 10 --53, 11 --52, 12 --51, 13 --50, 14 --49, 15 --48, 16 --47, 17 --46, 18 --45, 19 --44, 20 --43, 21 --42, 22 --41, 23 --40, 24 --39, 25 --38, 26 --37, 27 --36, 28 --35, 29 --34, 30 --33, 31 --32, 32 --31, 33 --30, 34 --29, 35 --28, 36 --27, 37 --26, 38 --25, 39 --24, 40 --23, 41 --22, 42 --21, 43 --20, 44 --19, 45 --18, 46 --17, 47 --16, 48 --15, 49 --14, 50 --13, 51 --12, 52 --11, 53 --10, 54 --9, 55 --8, 56 --7, 57 --6, 58 --5, 59 --4, 60 --3, 61 --2, 62 --1, 63 -0, 0 -1, 1 -2, 2 -3, 3 -4, 4 -5, 5 -6, 6 -7, 7 -8, 8 -9, 9 -10, 10 -11, 11 -12, 12 -13, 13 -14, 14 -15, 15 -16, 16 -17, 17 -18, 18 -19, 19 -20, 20 -21, 21 -22, 22 -23, 23 -24, 24 -25, 25 -26, 26 -27, 27 -28, 28 -29, 29 -30, 30 -31, 31 -32, 32 -33, 33 -34, 34 -35, 35 -36, 36 -37, 37 -38, 38 -39, 39 -40, 40 -41, 41 -42, 42 -43, 43 -44, 44 -45, 45 -46, 46 -47, 47 -48, 48 -49, 49 -50, 50 -51, 51 -52, 52 -53, 53 -54, 54 -55, 55 -56, 56 -57, 57 -58, 58 -59, 59 -60, 60 -61, 61 -62, 62 -63, 63 -64, 0 -65, 1 -66, 2 -67, 3 -68, 4 -69, 5 -70, 6 -71, 7 -72, 8 -73, 9 -74, 10 -75, 11 -76, 12 -77, 13 -78, 14 -79, 15 -80, 16 -81, 17 -82, 18 -83, 19 -84, 20 -85, 21 -86, 22 -87, 23 -88, 24 -89, 25 -90, 26 -91, 27 -92, 28 -93, 29 -94, 30 -95, 31 -96, 32 -97, 33 -98, 34 -99, 35 -100, 36 -101, 37 -102, 38 -103, 39 -104, 40 -105, 41 -106, 42 -107, 43 -108, 44 -109, 45 -110, 46 -111, 47 -112, 48 -113, 49 -114, 50 -115, 51 -116, 52 -117, 53 -118, 54 -119, 55 -120, 56 -121, 57 -122, 58 -123, 59 -124, 60 -125, 61 -126, 62 -127, 63 -128, 0 -129, 1 \ No newline at end of file diff --git a/tests/expressions/bitwise_shift_operators/bitwise_shift_negative.phpt b/tests/expressions/bitwise_shift_operators/bitwise_shift_negative.phpt new file mode 100644 index 00000000..dfa32f12 --- /dev/null +++ b/tests/expressions/bitwise_shift_operators/bitwise_shift_negative.phpt @@ -0,0 +1,18 @@ +--TEST-- +PHP Spec test generated from ./expressions/bitwise_shift_operators/bitwise_shift_negative.php +--FILE-- +> -1); +} catch (ArithmeticError $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(1 << -1); +} catch (ArithmeticError $e) { + echo $e->getMessage(), "\n"; +} +--EXPECTF-- +Bit shift by negative number +Bit shift by negative number diff --git a/tests/expressions/coalesce_operator/coalesce.phpt b/tests/expressions/coalesce_operator/coalesce.phpt new file mode 100644 index 00000000..bf9bc9eb --- /dev/null +++ b/tests/expressions/coalesce_operator/coalesce.phpt @@ -0,0 +1,73 @@ +--TEST-- +PHP Spec test generated from ./expressions/coalesce_operator/coalesce.php +--FILE-- +boo = 7; + +$arr = [ + 2 => 7, + "foo" => "bar", + "foobar" => NULL, + "qux" => $obj, + "bing" => [ + "bang" + ] +]; + +function foobar() { + echo "called\n"; + return ['a']; +} + +var_dump($nonexistant_variable ?? 3); +echo PHP_EOL; +var_dump($var ?? 3); +var_dump($var2 ?? 3); +echo PHP_EOL; +var_dump($obj->boo ?? 3); +var_dump($obj->bing ?? 3); +var_dump($arr["qux"]->boo ?? 3); +var_dump($arr["qux"]->bing ?? 3); +echo PHP_EOL; +var_dump($arr[2] ?? 3); +var_dump($arr["foo"] ?? 3); +var_dump($arr["foobar"] ?? 3); +var_dump($arr["bing"][0] ?? 3); +var_dump($arr["bing"][1] ?? 3); +echo PHP_EOL; +var_dump(foobar()[0] ?? false); +echo PHP_EOL; +function f($x) +{ + printf("%s(%d)\n", __FUNCTION__, $x); + return $x; +} + +$a = f(null) ?? f(1) ?? f(2); +--EXPECT-- +int(3) + +int(7) +int(3) + +int(7) +int(3) +int(7) +int(3) + +int(7) +string(3) "bar" +int(3) +string(4) "bang" +int(3) + +called +string(1) "a" + +f(0) +f(1) diff --git a/tests/expressions/equality_operators/comparisons.phpt b/tests/expressions/equality_operators/comparisons.phpt index a06343c8..4cd18d6a 100644 --- a/tests/expressions/equality_operators/comparisons.phpt +++ b/tests/expressions/equality_operators/comparisons.phpt @@ -871,4 +871,4 @@ Notice: Array to string conversion in %s/expressions/equality_operators/comparis Array !== Array result: bool(true) ======= ------------------------------------- -+++++++++++++++++++++++++++++++++++++++++++++++++++++ \ No newline at end of file ++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/tests/expressions/error_control_operator/error_control.phpt b/tests/expressions/error_control_operator/error_control.phpt index ca3da9a5..0e38c03a 100644 --- a/tests/expressions/error_control_operator/error_control.phpt +++ b/tests/expressions/error_control_operator/error_control.phpt @@ -46,4 +46,4 @@ int(-1) Notice: Undefined variable: y in %s/expressions/error_control_operator/error_control.php on line 14 int(-1) -Done \ No newline at end of file +Done diff --git a/tests/expressions/general/associativity.phpt b/tests/expressions/general/associativity.phpt index 9c677aef..dd6d8865 100644 --- a/tests/expressions/general/associativity.phpt +++ b/tests/expressions/general/associativity.phpt @@ -19,4 +19,4 @@ echo '$a + ($b - $c) = '.($a + ($b - $c))."\n"; --EXPECT-- $a + $b - $c = 12 ($a + $b) - $c = 12 -$a + ($b - $c) = 12 \ No newline at end of file +$a + ($b - $c) = 12 diff --git a/tests/expressions/general/order_of_evaluation.phpt b/tests/expressions/general/order_of_evaluation.phpt index d3bf48b0..66c5d7ec 100644 --- a/tests/expressions/general/order_of_evaluation.phpt +++ b/tests/expressions/general/order_of_evaluation.phpt @@ -282,4 +282,4 @@ array(7) { int(5) [6]=> int(6) -} \ No newline at end of file +} diff --git a/tests/expressions/general/precedence.phpt b/tests/expressions/general/precedence.phpt index b4a06596..e262a798 100644 --- a/tests/expressions/general/precedence.phpt +++ b/tests/expressions/general/precedence.phpt @@ -21,4 +21,4 @@ echo '($a - $b) / $c = '.(($a - $b) / $c)."\n"; --EXPECT-- $a - $b / $c = 15 $a - ($b / $c) = 15 -($a - $b) / $c = 5 \ No newline at end of file +($a - $b) / $c = 5 diff --git a/tests/expressions/general/sequence_points.phpt b/tests/expressions/general/sequence_points.phpt index 9a2b995a..be125bc8 100644 --- a/tests/expressions/general/sequence_points.phpt +++ b/tests/expressions/general/sequence_points.phpt @@ -20,4 +20,4 @@ echo '$b = '.$b."\n"; --EXPECT-- $a = 10 $a = 11 -$b = 11 \ No newline at end of file +$b = 11 diff --git a/tests/expressions/instanceof_operator/instanceof.phpt b/tests/expressions/instanceof_operator/instanceof.phpt index 1c166d27..fcaf6c39 100644 --- a/tests/expressions/instanceof_operator/instanceof.phpt +++ b/tests/expressions/instanceof_operator/instanceof.phpt @@ -36,9 +36,9 @@ var_dump($c1 instanceof $clName); // TRUE; can be a string $clName = "C2"; var_dump($c1 instanceof $clName); // FALSE; can be a string -var_dump($c2 instanceof $c2b); // -var_dump($d instanceof $c1); // -var_dump($c1 instanceof $d); // +var_dump($c2 instanceof $c2b); // +var_dump($d instanceof $c1); // +var_dump($c1 instanceof $d); // echo "--------------------\n"; @@ -165,4 +165,4 @@ bool(false) bool(true) bool(true) bool(true) -bool(true) \ No newline at end of file +bool(true) diff --git a/tests/expressions/list/list_001.phpt b/tests/expressions/list/list_001.phpt new file mode 100644 index 00000000..a9fff550 --- /dev/null +++ b/tests/expressions/list/list_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +"Nested" list() +--FILE-- + +--EXPECT-- +object(stdClass)#1 (0) { +} +object(stdClass)#2 (0) { +} diff --git a/tests/expressions/list/list_002.phpt b/tests/expressions/list/list_002.phpt new file mode 100644 index 00000000..ac0d8974 --- /dev/null +++ b/tests/expressions/list/list_002.phpt @@ -0,0 +1,20 @@ +--TEST-- +Testing full-reference on list() +--FILE-- + +--EXPECT-- +object(stdClass)#1 (0) { +} +object(stdClass)#1 (0) { +} +bool(true) diff --git a/tests/expressions/list/list_003.phpt b/tests/expressions/list/list_003.phpt new file mode 100644 index 00000000..4a509f6a --- /dev/null +++ b/tests/expressions/list/list_003.phpt @@ -0,0 +1,24 @@ +--TEST-- +list() with non-array +--FILE-- + +--EXPECT-- +NULL +NULL +NULL +NULL +NULL diff --git a/tests/expressions/list/list_004.phpt b/tests/expressions/list/list_004.phpt new file mode 100644 index 00000000..862a4e43 --- /dev/null +++ b/tests/expressions/list/list_004.phpt @@ -0,0 +1,21 @@ +--TEST-- +list() with array reference +--FILE-- + +--EXPECT-- +int(1) +array(2) { + [0]=> + int(2) + [1]=> + int(1) +} diff --git a/tests/expressions/list/list_005.phpt b/tests/expressions/list/list_005.phpt new file mode 100644 index 00000000..7dc3bf6f --- /dev/null +++ b/tests/expressions/list/list_005.phpt @@ -0,0 +1,50 @@ +--TEST-- +Testing list() with several variables +--FILE-- + +--EXPECTF-- +NULL +NULL +NULL +---- +NULL +NULL +NULL +---- + +Fatal error: Uncaught Error: Cannot use object of type stdClass as array in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/tests/expressions/list/list_006.phpt b/tests/expressions/list/list_006.phpt new file mode 100644 index 00000000..d380235d --- /dev/null +++ b/tests/expressions/list/list_006.phpt @@ -0,0 +1,12 @@ +--TEST-- +Testing nested list() with empty array +--FILE-- + +--EXPECTF-- +Notice: Undefined offset: 0 in %s on line %d + +Notice: Undefined offset: 1 in %s on line %d diff --git a/tests/expressions/list/list_007.phpt b/tests/expressions/list/list_007.phpt new file mode 100644 index 00000000..67c65245 --- /dev/null +++ b/tests/expressions/list/list_007.phpt @@ -0,0 +1,15 @@ +--TEST-- +Using lambda with list() +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Cannot use object of type Closure as array in %slist_007.php:3 +Stack trace: +#0 {main} + thrown in %slist_007.php on line 3 diff --git a/tests/expressions/list/list_destructuring_to_special_variables.phpt b/tests/expressions/list/list_destructuring_to_special_variables.phpt new file mode 100644 index 00000000..4418c967 --- /dev/null +++ b/tests/expressions/list/list_destructuring_to_special_variables.phpt @@ -0,0 +1,49 @@ +--TEST-- +list() can be used to destructure to string offsets, __set and ArrayAccess::offsetSet +--FILE-- +values[$name] = $value; + } +} + +class Arr implements ArrayAccess { + public $values = []; + public function offsetSet($name, $value) { + $this->values[$name] = $value; + } + public function offsetGet($name) {} + public function offsetExists($name) {} + public function offsetUnset($name) {} +} + +$str = 'ab'; +list($str[0], $str[1]) = ['x', 'y']; +var_dump($str); + +$obj = new Obj; +list($obj->foo, $obj->bar) = ['foo', 'bar']; +var_dump($obj->values); + +$arr = new Arr; +list($arr['foo'], $arr['bar']) = ['foo', 'bar']; +var_dump($arr->values); + +?> +--EXPECT-- +string(2) "xy" +array(2) { + ["foo"]=> + string(3) "foo" + ["bar"]=> + string(3) "bar" +} +array(2) { + ["foo"]=> + string(3) "foo" + ["bar"]=> + string(3) "bar" +} diff --git a/tests/expressions/list/list_empty_error.phpt b/tests/expressions/list/list_empty_error.phpt new file mode 100644 index 00000000..78de2e95 --- /dev/null +++ b/tests/expressions/list/list_empty_error.phpt @@ -0,0 +1,10 @@ +--TEST-- +Empty list() assignments are not allowed +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use empty list in %s on line %d diff --git a/tests/expressions/list/list_keyed.phpt b/tests/expressions/list/list_keyed.phpt new file mode 100644 index 00000000..b549ed9b --- /dev/null +++ b/tests/expressions/list/list_keyed.phpt @@ -0,0 +1,71 @@ +--TEST-- +list() with keys +--FILE-- + "bad", + "happy" => "sad", +]; + +list("good" => $good_antonym, "happy" => $happy_antonym) = $antonyms; +var_dump($good_antonym, $happy_antonym); + +echo PHP_EOL; + +$powersOfTwo = [ + 1 => 2, + 2 => 4, + 3 => 8 +]; + +list(1 => $two_1, 2 => $two_2, 3 => $two_3) = $powersOfTwo; +var_dump($two_1, $two_2, $two_3); + +echo PHP_EOL; + +$contrivedMixedKeyTypesExample = [ + 7 => "the best PHP version", + "elePHPant" => "the cutest mascot" +]; + +list(7 => $seven, "elePHPant" => $elePHPant) = $contrivedMixedKeyTypesExample; +var_dump($seven, $elePHPant); + +echo PHP_EOL; + +$allTogetherNow = [ + "antonyms" => $antonyms, + "powersOfTwo" => $powersOfTwo, + "contrivedMixedKeyTypesExample" => $contrivedMixedKeyTypesExample +]; + +list( + "antonyms" => list("good" => $good_antonym, "happy" => $happy_antonym), + "powersOfTwo" => list(1 => $two_1, 2 => $two_2, 3 => $two_3), + "contrivedMixedKeyTypesExample" => list(7 => $seven, "elePHPant" => $elePHPant) +) = $allTogetherNow; + +var_dump($good_antonym, $happy_antonym); +var_dump($two_1, $two_2, $two_3); +var_dump($seven, $elePHPant); + +?> +--EXPECT-- +string(3) "bad" +string(3) "sad" + +int(2) +int(4) +int(8) + +string(20) "the best PHP version" +string(17) "the cutest mascot" + +string(3) "bad" +string(3) "sad" +int(2) +int(4) +int(8) +string(20) "the best PHP version" +string(17) "the cutest mascot" diff --git a/tests/expressions/list/list_keyed_ArrayAccess.phpt b/tests/expressions/list/list_keyed_ArrayAccess.phpt new file mode 100644 index 00000000..1bb20130 --- /dev/null +++ b/tests/expressions/list/list_keyed_ArrayAccess.phpt @@ -0,0 +1,54 @@ +--TEST-- +list() with keys and ArrayAccess +--FILE-- + $good, "happy" => $happy) = $antonymObject; +var_dump($good, $happy); + +echo PHP_EOL; + +$stdClassCollection = new SplObjectStorage; +$foo = new StdClass; +$stdClassCollection[$foo] = "foo"; +$bar = new StdClass; +$stdClassCollection[$bar] = "bar"; + +list($foo => $fooStr, $bar => $barStr) = $stdClassCollection; +var_dump($fooStr, $barStr); + +echo PHP_EOL; + +class IndexPrinter implements ArrayAccess +{ + public function offsetGet($offset) { + echo "GET "; + var_dump($offset); + } + public function offsetSet($offset, $value) { + } + public function offsetExists($offset) { + } + public function offsetUnset($offset) { + } +} + +$op = new IndexPrinter; +list(123 => $x) = $op; +// PHP shouldn't convert this to an integer offset, because it's ArrayAccess +list("123" => $x) = $op; + +?> +--EXPECT-- +string(3) "bad" +string(3) "sad" + +string(3) "foo" +string(3) "bar" + +GET int(123) +GET string(3) "123" diff --git a/tests/expressions/list/list_keyed_conversions.phpt b/tests/expressions/list/list_keyed_conversions.phpt new file mode 100644 index 00000000..c1837a96 --- /dev/null +++ b/tests/expressions/list/list_keyed_conversions.phpt @@ -0,0 +1,34 @@ +--TEST-- +list() with non-integer-or-string keys +--FILE-- + 0, + 1 => 1, + "" => "" +]; + +list(NULL => $NULL, 1.5 => $float, FALSE => $FALSE, TRUE => $TRUE) = $results; +var_dump($NULL, $float, $FALSE, $TRUE); + +echo PHP_EOL; + +list("0" => $zeroString, "1" => $oneString) = $results; +var_dump($zeroString, $oneString); + +list(STDIN => $resource) = []; + +?> +--EXPECTF-- +string(0) "" +int(1) +int(0) +int(1) + +int(0) +int(1) + +Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d + +Notice: Undefined offset: %d in %s on line %d diff --git a/tests/expressions/list/list_keyed_evaluation_order.inc b/tests/expressions/list/list_keyed_evaluation_order.inc new file mode 100644 index 00000000..d4ee778b --- /dev/null +++ b/tests/expressions/list/list_keyed_evaluation_order.inc @@ -0,0 +1,60 @@ +name = $name; + } + + public function __toString(): string { + echo "$this->name evaluated.", PHP_EOL; + return $this->name; + } +} + +class Indexable implements ArrayAccess +{ + private $array; + public function __construct(array $array) { + $this->array = $array; + } + + public function offsetExists($offset): bool { + echo "Existence of offset $offset checked for.", PHP_EOL; + return isset($this->array[$offset]); + } + + public function offsetUnset($offset): void { + unset($this->array[$offset]); + echo "Offset $offset removed.", PHP_EOL; + } + + public function offsetGet($offset) { + echo "Offset $offset retrieved.", PHP_EOL; + return $this->array[$offset]; + } + + public function offsetSet($offset, $value): void { + $this->array[$offset] = $value; + echo "Offset $offset set to $value.", PHP_EOL; + } +} + +class IndexableRetrievable +{ + private $label; + private $indexable; + + public function __construct(string $label, Indexable $indexable) { + $this->label = $label; + $this->indexable = $indexable; + } + + public function getIndexable(): Indexable { + echo "Indexable $this->label retrieved.", PHP_EOL; + return $this->indexable; + } +} diff --git a/tests/expressions/list/list_keyed_evaluation_order.phpt b/tests/expressions/list/list_keyed_evaluation_order.phpt new file mode 100644 index 00000000..0f0652b6 --- /dev/null +++ b/tests/expressions/list/list_keyed_evaluation_order.phpt @@ -0,0 +1,35 @@ +--TEST-- +list() with keys, evaluation order +--FILE-- + "value for offset A", "C" => "value for offset C"])); + +$store = new Indexable([]); + +// list($a => $b, $c => $d) = $e; +// Should be evaluated in the order: +// 1. Evaluate $e +// 2. Evaluate $a +// 3. Evaluate $e[$a] +// 4. Assign $b from $e[$a] +// 5. Evaluate $c +// 6. Evaluate $e[$c] +// 7. Assign $c from $e[$a] + +list((string)$a => $store["B"], (string)$c => $store["D"]) = $e->getIndexable(); + +?> +--EXPECT-- +Indexable E retrieved. +A evaluated. +Offset A retrieved. +Offset B set to value for offset A. +C evaluated. +Offset C retrieved. +Offset D set to value for offset C. diff --git a/tests/expressions/list/list_keyed_evaluation_order_2.phpt b/tests/expressions/list/list_keyed_evaluation_order_2.phpt new file mode 100644 index 00000000..ddfba68c --- /dev/null +++ b/tests/expressions/list/list_keyed_evaluation_order_2.phpt @@ -0,0 +1,77 @@ +--TEST-- +list() with keys, evaluation order #2 +--FILE-- + $a, 1 => $b) = ['a', 'b']; +var_dump($a); +var_dump($b); + +list(1 => $b, 0 => $a) = ['a', 'b']; +var_dump($a); +var_dump($b); + +$arr = []; +list($arr[], $arr[]) = ['a', 'b']; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list(0 => $arr[], 1 => $arr[]) = ['a', 'b']; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list(1 => $arr[], 0 => $arr[]) = ['b', 'a']; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list(list(1 => $arr[], 0 => $arr[])) = [['b', 'a']]; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list('key1' => $arr[], 'key2' => $arr[]) = ['key2' => 'b', 'key1' => 'a']; +var_dump($arr[0]); +var_dump($arr[1]); + +// This should print 'foo' +$a = 0; +list($a => $a) = ['foo', 'bar']; +var_dump($a); + +// This should print 'bar' then 'foo' +$a = 0; +$b = 1; +list($b => $a, $a => $c) = ['bar' => 'foo', 1 => 'bar']; +var_dump($a); +var_dump($c); + +?> +--EXPECT-- +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(3) "foo" +string(3) "bar" +string(3) "foo" diff --git a/tests/expressions/list/list_keyed_evaluation_order_3.phpt b/tests/expressions/list/list_keyed_evaluation_order_3.phpt new file mode 100644 index 00000000..7850834c --- /dev/null +++ b/tests/expressions/list/list_keyed_evaluation_order_3.phpt @@ -0,0 +1,24 @@ +--TEST-- +list() with keys, evaluation order #3 +--FILE-- + [ + 'b' => 'bar', + 'a' => 'foo', + ], + 1 => 'a', + 3 => 'b', +]; +list($a[$i++] => $a[$i++], $a[$i++] => $a[$i++]) = $a[$i++]; +var_dump($i); // should be 5 +var_dump($a[2]); // should be 'foo' +var_dump($a[4]); // should be 'bar' + +?> +--EXPECT-- +int(5) +string(3) "foo" +string(3) "bar" diff --git a/tests/expressions/list/list_keyed_evaluation_order_nested.phpt b/tests/expressions/list/list_keyed_evaluation_order_nested.phpt new file mode 100644 index 00000000..8a7725d4 --- /dev/null +++ b/tests/expressions/list/list_keyed_evaluation_order_nested.phpt @@ -0,0 +1,77 @@ +--TEST-- +list() with keys, evaluation order: nested +--FILE-- + "offset value for A", + "C" => new Indexable([ + 0 => "offset value for 0", + 1 => "offset value for 1" + ]), + "F" => new Indexable([ + "G" => "offset value for G", + "I" => "offset value for I" + ]) +])); + +$store = new Indexable([]); + +// list($a => $b, $c => list($d, $e), $f => list($g => $h, $i => $j)) = $k; +// Should be evaluated in the order: +// 1. Evaluate $k +// 2. Evaluate $a +// 3. Evaluate $k[$a] +// 4. Assign $b from $k[$a] +// 5. Evaluate $c +// 6. Evaluate $k[$c] +// 7. Evaluate $k[$c][0] +// 8. Assign $d from $k[$c][0] +// 9. Evaluate $k[$c][1] +// 10. Assign $e from $k[$c][1] +// 11. Evaluate $f +// 12. Evaluate $k[$f] +// 13. Evaluate $g +// 14. Evaluate $k[$f][$g] +// 15. Assign $h from $k[$f][$g] +// 16. Evaluate $i +// 17. Evaluate $k[$f][$i] +// 18. Assign $j from $k[$f][$i] + +list( + (string)$a => $store["B"], + (string)$c => list($store["D"], $store["E"]), + (string)$f => list( + (string)$g => $store["H"], + (string)$i => $store["J"] + ) +) = $k->getIndexable(); + +?> +--EXPECT-- +Indexable K retrieved. +A evaluated. +Offset A retrieved. +Offset B set to offset value for A. +C evaluated. +Offset C retrieved. +Offset 0 retrieved. +Offset D set to offset value for 0. +Offset 1 retrieved. +Offset E set to offset value for 1. +F evaluated. +Offset F retrieved. +G evaluated. +Offset G retrieved. +Offset H set to offset value for G. +I evaluated. +Offset I retrieved. +Offset J set to offset value for I. diff --git a/tests/expressions/list/list_keyed_non_literals.phpt b/tests/expressions/list/list_keyed_non_literals.phpt new file mode 100644 index 00000000..80f22eda --- /dev/null +++ b/tests/expressions/list/list_keyed_non_literals.phpt @@ -0,0 +1,30 @@ +--TEST-- +list() with constant keys +--FILE-- + "one", + 2 => "two", + 3 => "three" +]; + +const COMPILE_TIME_RESOLVABLE = 1; + +define('PROBABLY_NOT_COMPILE_TIME_RESOLVABLE', file_get_contents("data:text/plain,2")); + +$probablyNotCompileTimeResolvable3 = cos(0) * 3; + +list( + COMPILE_TIME_RESOLVABLE => $one, + PROBABLY_NOT_COMPILE_TIME_RESOLVABLE => $two, + $probablyNotCompileTimeResolvable3 => $three +) = $arr; + +var_dump($one, $two, $three); + +?> +--EXPECTF-- +string(3) "one" +string(3) "two" +string(5) "three" diff --git a/tests/expressions/list/list_keyed_trailing_comma.phpt b/tests/expressions/list/list_keyed_trailing_comma.phpt new file mode 100644 index 00000000..e0af0aed --- /dev/null +++ b/tests/expressions/list/list_keyed_trailing_comma.phpt @@ -0,0 +1,38 @@ +--TEST-- +list() with keys and a trailing comma +--FILE-- + "bad", + "happy" => "sad", +]; + +list( + "good" => $good, + "happy" => $happy +) = $antonyms; + +var_dump($good, $happy); + +echo PHP_EOL; + +$antonyms = [ + "good" => "bad", + "happy" => "sad", +]; + +list( + "good" => $good, + "happy" => $happy, +) = $antonyms; + +var_dump($good, $happy); + +?> +--EXPECT-- +string(3) "bad" +string(3) "sad" + +string(3) "bad" +string(3) "sad" diff --git a/tests/expressions/list/list_keyed_undefined.phpt b/tests/expressions/list/list_keyed_undefined.phpt new file mode 100644 index 00000000..a18e3b4d --- /dev/null +++ b/tests/expressions/list/list_keyed_undefined.phpt @@ -0,0 +1,22 @@ +--TEST-- +list() with undefined keys +--FILE-- + "the best PHP version", + "elePHPant" => "the cutest mascot" +]; + +list(5 => $five, "duke" => $duke) = $contrivedMixedKeyTypesExample; + +var_dump($five, $duke); + +?> +--EXPECTF-- + +Notice: Undefined offset: 5 in %s on line %d + +Notice: Undefined index: duke in %s on line %d +NULL +NULL diff --git a/tests/expressions/list/list_mixed_keyed_unkeyed.phpt b/tests/expressions/list/list_mixed_keyed_unkeyed.phpt new file mode 100644 index 00000000..11073a43 --- /dev/null +++ b/tests/expressions/list/list_mixed_keyed_unkeyed.phpt @@ -0,0 +1,16 @@ +--TEST-- +list() with both keyed and unkeyed elements +--FILE-- + 1, + "foo" => "bar" +]; + +list($zero, 1 => $one, "foo" => $foo) = $contrivedKeyedAndUnkeyedArrayExample; + +?> +--EXPECTF-- +Fatal error: Cannot mix keyed and unkeyed array entries in assignments in %s diff --git a/tests/expressions/list/list_mixed_nested_keyed_unkeyed.phpt b/tests/expressions/list/list_mixed_nested_keyed_unkeyed.phpt new file mode 100644 index 00000000..3087775b --- /dev/null +++ b/tests/expressions/list/list_mixed_nested_keyed_unkeyed.phpt @@ -0,0 +1,34 @@ +--TEST-- +list() with nested unkeyed and keyed list() +--FILE-- + 1, "y" => 2], + ["x" => 2, "y" => 1] +]; + +list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = $points; +var_dump($x1, $y1, $x2, $y2); + +echo PHP_EOL; + +$invertedPoints = [ + "x" => [1, 2], + "y" => [2, 1] +]; + +list("x" => list($x1, $x2), "y" => list($y1, $y2)) = $invertedPoints; +var_dump($x1, $y1, $x2, $y2); + +?> +--EXPECT-- +int(1) +int(2) +int(2) +int(1) + +int(1) +int(2) +int(2) +int(1) diff --git a/tests/expressions/list/list_self_assign.phpt b/tests/expressions/list/list_self_assign.phpt new file mode 100644 index 00000000..33993c50 --- /dev/null +++ b/tests/expressions/list/list_self_assign.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test variable occurring on both LHS and RHS of list() +--FILE-- + +--EXPECT-- +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) diff --git a/tests/expressions/multiplicative_operators/multiplication_division_modulus.phpt b/tests/expressions/multiplicative_operators/multiplication_division_modulus.phpt index a337a285..5ab91c30 100644 --- a/tests/expressions/multiplicative_operators/multiplication_division_modulus.phpt +++ b/tests/expressions/multiplicative_operators/multiplication_division_modulus.phpt @@ -40,11 +40,9 @@ foreach ($oper as $e1) ///* foreach ($oper as $e1) { - if(is_double($e1) && !is_finite($e1)) continue; foreach ($oper as $e2) { if (((int)$e2) == 0) continue; // skip divide-by-zeros - if(is_double($e2) && !is_finite($e2)) continue; echo " >$e1< % >$e2<, result: "; var_dump($e1 % $e2); echo "(int) >".((int)$e1)."< % >(int) >".((int)$e2)."<, result: "; var_dump(((int)$e1) % ((int)$e2)); @@ -65,8 +63,12 @@ foreach ($oper as $e1) >0< * ><, result: int(0) >0< * >123<, result: int(0) >0< * >2e+5<, result: float(0) ->0< * ><, result: int(0) ->0< * >abc<, result: int(0) +>0< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >0< * >9223372036854775807<, result: int(0) ------------------------------------- >-10< * >0<, result: int(0) @@ -81,8 +83,12 @@ foreach ($oper as $e1) >-10< * ><, result: int(0) >-10< * >123<, result: int(-1230) >-10< * >2e+5<, result: float(-2000000) ->-10< * ><, result: int(0) ->-10< * >abc<, result: int(0) +>-10< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-10< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >-10< * >9223372036854775807<, result: float(-9.2233720368548E+19) ------------------------------------- >100< * >0<, result: int(0) @@ -97,8 +103,12 @@ foreach ($oper as $e1) >100< * ><, result: int(0) >100< * >123<, result: int(12300) >100< * >2e+5<, result: float(20000000) ->100< * ><, result: int(0) ->100< * >abc<, result: int(0) +>100< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>100< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >100< * >9223372036854775807<, result: float(9.2233720368548E+20) ------------------------------------- >-34000000000< * >0<, result: float(-0) @@ -113,8 +123,12 @@ foreach ($oper as $e1) >-34000000000< * ><, result: float(-0) >-34000000000< * >123<, result: float(-4182000000000) >-34000000000< * >2e+5<, result: float(-6.8E+15) ->-34000000000< * ><, result: float(-0) ->-34000000000< * >abc<, result: float(-0) +>-34000000000< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>-34000000000< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) >-34000000000< * >9223372036854775807<, result: float(-3.1359464925306E+29) ------------------------------------- >INF< * >0<, result: float(NAN) @@ -129,8 +143,12 @@ foreach ($oper as $e1) >INF< * ><, result: float(NAN) >INF< * >123<, result: float(INF) >INF< * >2e+5<, result: float(INF) ->INF< * ><, result: float(NAN) ->INF< * >abc<, result: float(NAN) +>INF< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>INF< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) >INF< * >9223372036854775807<, result: float(INF) ------------------------------------- >-INF< * >0<, result: float(NAN) @@ -145,8 +163,12 @@ foreach ($oper as $e1) >-INF< * ><, result: float(NAN) >-INF< * >123<, result: float(-INF) >-INF< * >2e+5<, result: float(-INF) ->-INF< * ><, result: float(NAN) ->-INF< * >abc<, result: float(NAN) +>-INF< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>-INF< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) >-INF< * >9223372036854775807<, result: float(-INF) ------------------------------------- >NAN< * >0<, result: float(NAN) @@ -161,8 +183,12 @@ foreach ($oper as $e1) >NAN< * ><, result: float(NAN) >NAN< * >123<, result: float(NAN) >NAN< * >2e+5<, result: float(NAN) ->NAN< * ><, result: float(NAN) ->NAN< * >abc<, result: float(NAN) +>NAN< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>NAN< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) >NAN< * >9223372036854775807<, result: float(NAN) ------------------------------------- >1< * >0<, result: int(0) @@ -177,8 +203,12 @@ foreach ($oper as $e1) >1< * ><, result: int(0) >1< * >123<, result: int(123) >1< * >2e+5<, result: float(200000) ->1< * ><, result: int(0) ->1< * >abc<, result: int(0) +>1< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>1< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >1< * >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >< * >0<, result: int(0) @@ -193,8 +223,12 @@ foreach ($oper as $e1) >< * ><, result: int(0) >< * >123<, result: int(0) >< * >2e+5<, result: float(0) ->< * ><, result: int(0) ->< * >abc<, result: int(0) +>< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< * >9223372036854775807<, result: int(0) ------------------------------------- >< * >0<, result: int(0) @@ -209,8 +243,12 @@ foreach ($oper as $e1) >< * ><, result: int(0) >< * >123<, result: int(0) >< * >2e+5<, result: float(0) ->< * ><, result: int(0) ->< * >abc<, result: int(0) +>< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< * >9223372036854775807<, result: int(0) ------------------------------------- >123< * >0<, result: int(0) @@ -225,8 +263,12 @@ foreach ($oper as $e1) >123< * ><, result: int(0) >123< * >123<, result: int(15129) >123< * >2e+5<, result: float(24600000) ->123< * ><, result: int(0) ->123< * >abc<, result: int(0) +>123< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>123< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >123< * >9223372036854775807<, result: float(1.1344747605331E+21) ------------------------------------- >2e+5< * >0<, result: float(0) @@ -241,41 +283,113 @@ foreach ($oper as $e1) >2e+5< * ><, result: float(0) >2e+5< * >123<, result: float(24600000) >2e+5< * >2e+5<, result: float(40000000000) ->2e+5< * ><, result: float(0) ->2e+5< * >abc<, result: float(0) +>2e+5< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>2e+5< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) >2e+5< * >9223372036854775807<, result: float(1.844674407371E+24) ------------------------------------- ->< * >0<, result: int(0) ->< * >-10<, result: int(0) ->< * >100<, result: int(0) ->< * >-34000000000<, result: float(-0) ->< * >INF<, result: float(NAN) ->< * >-INF<, result: float(NAN) ->< * >NAN<, result: float(NAN) ->< * >1<, result: int(0) ->< * ><, result: int(0) ->< * ><, result: int(0) ->< * >123<, result: int(0) ->< * >2e+5<, result: float(0) ->< * ><, result: int(0) ->< * >abc<, result: int(0) ->< * >9223372036854775807<, result: int(0) -------------------------------------- ->abc< * >0<, result: int(0) ->abc< * >-10<, result: int(0) ->abc< * >100<, result: int(0) ->abc< * >-34000000000<, result: float(-0) ->abc< * >INF<, result: float(NAN) ->abc< * >-INF<, result: float(NAN) ->abc< * >NAN<, result: float(NAN) ->abc< * >1<, result: int(0) ->abc< * ><, result: int(0) ->abc< * ><, result: int(0) ->abc< * >123<, result: int(0) ->abc< * >2e+5<, result: float(0) ->abc< * ><, result: int(0) ->abc< * >abc<, result: int(0) ->abc< * >9223372036854775807<, result: int(0) +>< * >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< * >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< * >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< * >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< * >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< * ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>abc< * >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< * >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< * >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< * >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< * >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< * ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- >9223372036854775807< * >0<, result: int(0) >9223372036854775807< * >-10<, result: float(-9.2233720368548E+19) @@ -289,8 +403,12 @@ foreach ($oper as $e1) >9223372036854775807< * ><, result: int(0) >9223372036854775807< * >123<, result: float(1.1344747605331E+21) >9223372036854775807< * >2e+5<, result: float(1.844674407371E+24) ->9223372036854775807< * ><, result: int(0) ->9223372036854775807< * >abc<, result: int(0) +>9223372036854775807< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>9223372036854775807< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >9223372036854775807< * >9223372036854775807<, result: float(8.5070591730235E+37) ------------------------------------- >0< / >-10<, result: int(0) @@ -425,27 +543,67 @@ foreach ($oper as $e1) >2e+5< / >2e+5<, result: float(1) >2e+5< / >9223372036854775807<, result: float(2.168404344971E-14) ------------------------------------- ->< / >-10<, result: int(0) ->< / >100<, result: int(0) ->< / >-34000000000<, result: float(-0) ->< / >INF<, result: float(0) ->< / >-INF<, result: float(-0) ->< / >NAN<, result: float(NAN) ->< / >1<, result: int(0) ->< / >123<, result: int(0) ->< / >2e+5<, result: float(0) ->< / >9223372036854775807<, result: int(0) -------------------------------------- ->abc< / >-10<, result: int(0) ->abc< / >100<, result: int(0) ->abc< / >-34000000000<, result: float(-0) ->abc< / >INF<, result: float(0) ->abc< / >-INF<, result: float(-0) ->abc< / >NAN<, result: float(NAN) ->abc< / >1<, result: int(0) ->abc< / >123<, result: int(0) ->abc< / >2e+5<, result: float(0) ->abc< / >9223372036854775807<, result: int(0) +>< / >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< / >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< / >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< / >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< / >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< / >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< / >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< / >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< / >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< / >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>abc< / >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< / >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< / >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< / >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< / >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< / >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< / >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< / >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< / >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< / >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- >9223372036854775807< / >-10<, result: float(-9.2233720368548E+17) >9223372036854775807< / >100<, result: float(9.2233720368548E+16) @@ -469,7 +627,7 @@ foreach ($oper as $e1) >0< % >123<, result: int(0) (int) >0< % >(int) >123<, result: int(0) >0< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) >0< % >9223372036854775807<, result: int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- @@ -483,8 +641,8 @@ foreach ($oper as $e1) (int) >-10< % >(int) >1<, result: int(0) >-10< % >123<, result: int(-10) (int) >-10< % >(int) >123<, result: int(-10) - >-10< % >2e+5<, result: int(0) -(int) >-10< % >(int) >2<, result: int(0) + >-10< % >2e+5<, result: int(-10) +(int) >-10< % >(int) >200000<, result: int(-10) >-10< % >9223372036854775807<, result: int(-10) (int) >-10< % >(int) >9223372036854775807<, result: int(-10) ------------------------------------- @@ -498,8 +656,8 @@ foreach ($oper as $e1) (int) >100< % >(int) >1<, result: int(0) >100< % >123<, result: int(100) (int) >100< % >(int) >123<, result: int(100) - >100< % >2e+5<, result: int(0) -(int) >100< % >(int) >2<, result: int(0) + >100< % >2e+5<, result: int(100) +(int) >100< % >(int) >200000<, result: int(100) >100< % >9223372036854775807<, result: int(100) (int) >100< % >(int) >9223372036854775807<, result: int(100) ------------------------------------- @@ -514,9 +672,54 @@ foreach ($oper as $e1) >-34000000000< % >123<, result: int(-28) (int) >-34000000000< % >(int) >123<, result: int(-28) >-34000000000< % >2e+5<, result: int(0) -(int) >-34000000000< % >(int) >2<, result: int(0) +(int) >-34000000000< % >(int) >200000<, result: int(0) >-34000000000< % >9223372036854775807<, result: int(-34000000000) (int) >-34000000000< % >(int) >9223372036854775807<, result: int(-34000000000) +------------------------------------- + >INF< % >-10<, result: int(0) +(int) >0< % >(int) >-10<, result: int(0) + >INF< % >100<, result: int(0) +(int) >0< % >(int) >100<, result: int(0) + >INF< % >-34000000000<, result: int(0) +(int) >0< % >(int) >-34000000000<, result: int(0) + >INF< % >1<, result: int(0) +(int) >0< % >(int) >1<, result: int(0) + >INF< % >123<, result: int(0) +(int) >0< % >(int) >123<, result: int(0) + >INF< % >2e+5<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) + >INF< % >9223372036854775807<, result: int(0) +(int) >0< % >(int) >9223372036854775807<, result: int(0) +------------------------------------- + >-INF< % >-10<, result: int(0) +(int) >0< % >(int) >-10<, result: int(0) + >-INF< % >100<, result: int(0) +(int) >0< % >(int) >100<, result: int(0) + >-INF< % >-34000000000<, result: int(0) +(int) >0< % >(int) >-34000000000<, result: int(0) + >-INF< % >1<, result: int(0) +(int) >0< % >(int) >1<, result: int(0) + >-INF< % >123<, result: int(0) +(int) >0< % >(int) >123<, result: int(0) + >-INF< % >2e+5<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) + >-INF< % >9223372036854775807<, result: int(0) +(int) >0< % >(int) >9223372036854775807<, result: int(0) +------------------------------------- + >NAN< % >-10<, result: int(0) +(int) >0< % >(int) >-10<, result: int(0) + >NAN< % >100<, result: int(0) +(int) >0< % >(int) >100<, result: int(0) + >NAN< % >-34000000000<, result: int(0) +(int) >0< % >(int) >-34000000000<, result: int(0) + >NAN< % >1<, result: int(0) +(int) >0< % >(int) >1<, result: int(0) + >NAN< % >123<, result: int(0) +(int) >0< % >(int) >123<, result: int(0) + >NAN< % >2e+5<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) + >NAN< % >9223372036854775807<, result: int(0) +(int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- >1< % >-10<, result: int(1) (int) >1< % >(int) >-10<, result: int(1) @@ -529,7 +732,7 @@ foreach ($oper as $e1) >1< % >123<, result: int(1) (int) >1< % >(int) >123<, result: int(1) >1< % >2e+5<, result: int(1) -(int) >1< % >(int) >2<, result: int(1) +(int) >1< % >(int) >200000<, result: int(1) >1< % >9223372036854775807<, result: int(1) (int) >1< % >(int) >9223372036854775807<, result: int(1) ------------------------------------- @@ -544,7 +747,7 @@ foreach ($oper as $e1) >< % >123<, result: int(0) (int) >0< % >(int) >123<, result: int(0) >< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) >< % >9223372036854775807<, result: int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- @@ -559,7 +762,7 @@ foreach ($oper as $e1) >< % >123<, result: int(0) (int) >0< % >(int) >123<, result: int(0) >< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) >< % >9223372036854775807<, result: int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- @@ -573,54 +776,82 @@ foreach ($oper as $e1) (int) >123< % >(int) >1<, result: int(0) >123< % >123<, result: int(0) (int) >123< % >(int) >123<, result: int(0) - >123< % >2e+5<, result: int(1) -(int) >123< % >(int) >2<, result: int(1) + >123< % >2e+5<, result: int(123) +(int) >123< % >(int) >200000<, result: int(123) >123< % >9223372036854775807<, result: int(123) (int) >123< % >(int) >9223372036854775807<, result: int(123) ------------------------------------- - >2e+5< % >-10<, result: int(2) -(int) >2< % >(int) >-10<, result: int(2) - >2e+5< % >100<, result: int(2) -(int) >2< % >(int) >100<, result: int(2) - >2e+5< % >-34000000000<, result: int(2) -(int) >2< % >(int) >-34000000000<, result: int(2) + >2e+5< % >-10<, result: int(0) +(int) >200000< % >(int) >-10<, result: int(0) + >2e+5< % >100<, result: int(0) +(int) >200000< % >(int) >100<, result: int(0) + >2e+5< % >-34000000000<, result: int(200000) +(int) >200000< % >(int) >-34000000000<, result: int(200000) >2e+5< % >1<, result: int(0) -(int) >2< % >(int) >1<, result: int(0) +(int) >200000< % >(int) >1<, result: int(0) >2e+5< % >123<, result: int(2) -(int) >2< % >(int) >123<, result: int(2) +(int) >200000< % >(int) >123<, result: int(2) >2e+5< % >2e+5<, result: int(0) -(int) >2< % >(int) >2<, result: int(0) - >2e+5< % >9223372036854775807<, result: int(2) -(int) >2< % >(int) >9223372036854775807<, result: int(2) +(int) >200000< % >(int) >200000<, result: int(0) + >2e+5< % >9223372036854775807<, result: int(200000) +(int) >200000< % >(int) >9223372036854775807<, result: int(200000) ------------------------------------- - >< % >-10<, result: int(0) + >< % >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >-10<, result: int(0) - >< % >100<, result: int(0) + >< % >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >100<, result: int(0) - >< % >-34000000000<, result: int(0) + >< % >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >-34000000000<, result: int(0) - >< % >1<, result: int(0) + >< % >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >1<, result: int(0) - >< % >123<, result: int(0) + >< % >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >123<, result: int(0) - >< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) - >< % >9223372036854775807<, result: int(0) + >< % >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +(int) >0< % >(int) >200000<, result: int(0) + >< % >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- - >abc< % >-10<, result: int(0) + >abc< % >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >-10<, result: int(0) - >abc< % >100<, result: int(0) + >abc< % >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >100<, result: int(0) - >abc< % >-34000000000<, result: int(0) + >abc< % >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >-34000000000<, result: int(0) - >abc< % >1<, result: int(0) + >abc< % >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >1<, result: int(0) - >abc< % >123<, result: int(0) + >abc< % >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >123<, result: int(0) - >abc< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) - >abc< % >9223372036854775807<, result: int(0) + >abc< % >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +(int) >0< % >(int) >200000<, result: int(0) + >abc< % >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- >9223372036854775807< % >-10<, result: int(7) @@ -633,8 +864,8 @@ foreach ($oper as $e1) (int) >9223372036854775807< % >(int) >1<, result: int(0) >9223372036854775807< % >123<, result: int(7) (int) >9223372036854775807< % >(int) >123<, result: int(7) - >9223372036854775807< % >2e+5<, result: int(1) -(int) >9223372036854775807< % >(int) >2<, result: int(1) + >9223372036854775807< % >2e+5<, result: int(175807) +(int) >9223372036854775807< % >(int) >200000<, result: int(175807) >9223372036854775807< % >9223372036854775807<, result: int(0) (int) >9223372036854775807< % >(int) >9223372036854775807<, result: int(0) -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/postfix_operators/exponentiation.phpt b/tests/expressions/postfix_operators/exponentiation.phpt index 70c8130c..8f9ace81 100644 --- a/tests/expressions/postfix_operators/exponentiation.phpt +++ b/tests/expressions/postfix_operators/exponentiation.phpt @@ -79,4 +79,4 @@ int(-9) =========== int(100) int(9) -float(144) \ No newline at end of file +float(144) diff --git a/tests/expressions/postfix_operators/member_selection_operator.phpt b/tests/expressions/postfix_operators/member_selection_operator.phpt index 3815ecb3..95ca7598 100644 --- a/tests/expressions/postfix_operators/member_selection_operator.phpt +++ b/tests/expressions/postfix_operators/member_selection_operator.phpt @@ -11,7 +11,7 @@ PHP Spec test generated from ./expressions/postfix_operators/member_selection_op error_reporting(-1); -class Point +class Point { private $x; private $y; @@ -21,7 +21,7 @@ class Point public function getY() { return $this->y; } public function setY($y) { $this->y = $y; } - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $name = "x"; $this->$name = $x; // member name as the value of a string is permitted @@ -30,19 +30,19 @@ class Point $this->y = $y; } - public function move($x, $y) + public function move($x, $y) { $this->x = $x; $this->y = $y; - } + } - public function translate($x, $y) + public function translate($x, $y) { $this->x += $x; $this->y += $y; } - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; } diff --git a/tests/expressions/postfix_operators/post-increment_and_decrement.phpt b/tests/expressions/postfix_operators/post-increment_and_decrement.phpt index 02539c83..49c09787 100644 --- a/tests/expressions/postfix_operators/post-increment_and_decrement.phpt +++ b/tests/expressions/postfix_operators/post-increment_and_decrement.phpt @@ -1,5 +1,5 @@ --TEST-- -PHP Spec test generated from ./expressions/postfix_operators/post-increment_and_decrement.php +Postscript increment and decrement --FILE-- int(11) --------------------------------------- end incdecrev --- --------------------------------------- start incdec --- $a = 0x12 <---> string(4) "0x12" -$a = 17 <---> int(17) -$a = 18 <---> int(18) -$a = 18 -$a = 19 <---> int(19) +$a = 0x12 <---> string(4) "0x12" +$a = 0x13 <---> string(4) "0x13" +$a = 0x13 +$a = 0x14 <---> string(4) "0x14" --------------------------------------- end incdec --- --------------------------------------- start incdecrev --- $a = 0x12 <---> string(4) "0x12" -$a = 19 <---> int(19) -$a = 18 <---> int(18) -$a = 18 -$a = 17 <---> int(17) +$a = 0x13 <---> string(4) "0x13" +$a = 0x13 <---> string(4) "0x13" +$a = 0x13 +$a = 0x13 <---> string(4) "0x13" --------------------------------------- end incdecrev --- --------------------------------------- start incdec --- $a = 0X12 <---> string(4) "0X12" -$a = 17 <---> int(17) -$a = 18 <---> int(18) -$a = 18 -$a = 19 <---> int(19) +$a = 0X12 <---> string(4) "0X12" +$a = 0X13 <---> string(4) "0X13" +$a = 0X13 +$a = 0X14 <---> string(4) "0X14" --------------------------------------- end incdec --- --------------------------------------- start incdecrev --- $a = 0X12 <---> string(4) "0X12" -$a = 19 <---> int(19) -$a = 18 <---> int(18) -$a = 18 -$a = 17 <---> int(17) +$a = 0X13 <---> string(4) "0X13" +$a = 0X13 <---> string(4) "0X13" +$a = 0X13 +$a = 0X13 <---> string(4) "0X13" --------------------------------------- end incdecrev --- --------------------------------------- start incdec --- $a = 0b101 <---> string(5) "0b101" diff --git a/tests/expressions/postfix_operators/post-increment_and_decrement_integer_edge_cases.phpt b/tests/expressions/postfix_operators/post-increment_and_decrement_integer_edge_cases.phpt index b6ca46cc..b37c25b6 100644 --- a/tests/expressions/postfix_operators/post-increment_and_decrement_integer_edge_cases.phpt +++ b/tests/expressions/postfix_operators/post-increment_and_decrement_integer_edge_cases.phpt @@ -100,4 +100,4 @@ float(9.2233720368548E+18) float(9.2233720368548E+18) float(9.2233720368548E+18) float(9.2233720368548E+18) ---- end incdecrev --- \ No newline at end of file +--- end incdecrev --- diff --git a/tests/expressions/postfix_operators/scope_resolution_operator.phpt b/tests/expressions/postfix_operators/scope_resolution_operator.phpt index 446c48b7..d42c112d 100644 --- a/tests/expressions/postfix_operators/scope_resolution_operator.phpt +++ b/tests/expressions/postfix_operators/scope_resolution_operator.phpt @@ -20,7 +20,7 @@ class M const MYPI = 3.14; const CON1 = -222; -// method b1 demostrates self vs. static +// method b1 demonstrates self vs. static public function b1() { @@ -93,7 +93,7 @@ class P extends N echo "Inside static " . __METHOD__ . "\n"; } -// method f1 demostrates self and parent +// method f1 demonstrates self and parent public static function f1() { @@ -353,4 +353,4 @@ object(W2)#6 (1) { string(2) "W2" string(2) "W1" string(2) "W2" -string(2) "W2" \ No newline at end of file +string(2) "W2" diff --git a/tests/expressions/postfix_operators/subscripting.phpt b/tests/expressions/postfix_operators/subscripting.phpt index 2867e834..1f8fe603 100644 --- a/tests/expressions/postfix_operators/subscripting.phpt +++ b/tests/expressions/postfix_operators/subscripting.phpt @@ -26,7 +26,7 @@ foreach ($v as $k => $e) echo "key: ".$k.", value: ".$e."\n"; } -// try to access non-existant elements +// try to access non-existent elements echo "[7] contains >".($v[7] == NULL ? "NULL" : "??") ."<, [12] contains >".($v[12] == NULL ? "NULL" : "??")."<\n"; @@ -64,7 +64,7 @@ foreach ($v as $k => $e) } } -echo "[0]: ".$v[0]."\n"; // +echo "[0]: ".$v[0]."\n"; // echo "[0][2]: ".$v[0][2]."\n"; // 6 echo "[1][1]: ".$v[1][1]."\n"; // 10 @@ -76,7 +76,7 @@ var_dump($z); $z = [array(2,4,6,8), array(5,10), array(100,200,300)][0][2]; var_dump($z); -$z = [[2,4,6,8], [5,10], [100,200,300]][0][2]; // acceses element with value 6 +$z = [[2,4,6,8], [5,10], [100,200,300]][0][2]; // accesses element with value 6 var_dump($z); var_dump(["black", "white", "yellow"][1]); // white @@ -89,7 +89,7 @@ function f() } //*/ ///* -var_dump(f()[2]); // acceses element with value 3000 +var_dump(f()[2]); // accesses element with value 3000 //*/ ///* @@ -144,7 +144,7 @@ var_dump($v[1]); // OK, results in NULL "red"[1]; var_dump("red"[1]); // OK, results in "e" var_dump("red"[1.9]); // OK, results in "e" -var_dump("red"[-1]); // OK, results in "" +var_dump("red"[-1]); // OK, results in "d" var_dump("red"[10]); // OK, results in "" var_dump("red"["abc"]); // Warning, results in "r" from [0] @@ -179,7 +179,7 @@ $s[0] = "DEF"; // "r" -> "D"; only 1 char changed var_dump($s); $s[0] = "MN"; // "D" -> "M"; only 1 char changed var_dump($s); -$s[0] = ""; // "M" -> "\0" +$s[0] = ""; // warning; nothing changed var_dump($s); $s["zz"] = "Q"; // warning; "Q" goes into [0] var_dump($s); @@ -364,9 +364,7 @@ string(1) "e" Notice: String offset cast occurred in %s/expressions/postfix_operators/subscripting.php on line 143 string(1) "e" - -Notice: Uninitialized string offset: -1 in %s/expressions/postfix_operators/subscripting.php on line 144 -string(0) "" +string(1) "d" Notice: Uninitialized string offset: 10 in %s/expressions/postfix_operators/subscripting.php on line 145 string(0) "" @@ -393,7 +391,9 @@ string(6) "rXd Z" [5] is not a space string(6) "DXd Z" string(6) "MXd Z" -string(6) "Xd Z" + +Warning: Cannot assign an empty string to a string offset in %s +string(6) "MXd Z" Warning: Illegal string offset 'zz' in %s/expressions/postfix_operators/subscripting.php on line 181 string(6) "QXd Z" diff --git a/tests/expressions/postfix_operators/subscripting_2.phpt b/tests/expressions/postfix_operators/subscripting_2.phpt index c9c2b490..a269350d 100644 --- a/tests/expressions/postfix_operators/subscripting_2.phpt +++ b/tests/expressions/postfix_operators/subscripting_2.phpt @@ -11,7 +11,7 @@ var_dump($a); echo "------\n"; $a = array(-30 => 33, -10 => -11); -var_dump($a[] = 991); // creates $a[0] +var_dump($a[] = 991); // creates $a[-9] var_dump($a); echo "------\n"; @@ -170,7 +170,7 @@ array(3) { int(33) [-10]=> int(-11) - [0]=> + [-9]=> int(991) } ------ diff --git a/tests/expressions/primary_expressions/Point.inc b/tests/expressions/primary_expressions/Point.inc index f62c6596..2942d85d 100644 --- a/tests/expressions/primary_expressions/Point.inc +++ b/tests/expressions/primary_expressions/Point.inc @@ -8,7 +8,7 @@ error_reporting(-1); -class Point +class Point { private $x; // Cartesian x-coordinate private $y; // Cartesian y-coordinate @@ -19,28 +19,28 @@ class Point public function setY($y) { $this->y = $y; } // public function __construct($x, $y) // see what happens if no default values - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; } - public function move($x, $y) + public function move($x, $y) { $this->x = $x; $this->y = $y; - } + } - public function translate($x, $y) + public function translate($x, $y) { $this->x += $x; $this->y += $y; } - public function __toString() + public function __toString() { // throw new Exception; // throw statement is not permitted return '(' . $this->x . ',' . $this->y . ')'; - } + } } diff --git a/tests/expressions/primary_expressions/Point2.inc b/tests/expressions/primary_expressions/Point2.inc index 29e1da60..59ded534 100644 --- a/tests/expressions/primary_expressions/Point2.inc +++ b/tests/expressions/primary_expressions/Point2.inc @@ -8,31 +8,31 @@ error_reporting(-1); -class Point2 +class Point2 { private static $pointCount = 0; public $x; // Cartesian x-coordinate public $y; // Cartesian y-coordinate - public static function getPointCount() + public static function getPointCount() { return self::$pointCount; } - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; ++self::$pointCount; } - public function __destruct() + public function __destruct() { --self::$pointCount; } ///* - public function __clone() + public function __clone() { ++self::$pointCount; @@ -43,9 +43,9 @@ class Point2 } //*/ - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; - } + } } diff --git a/tests/expressions/primary_expressions/intrinsics_echo.phpt b/tests/expressions/primary_expressions/intrinsics_echo.phpt index 6bf69bf3..e8cc809f 100644 --- a/tests/expressions/primary_expressions/intrinsics_echo.phpt +++ b/tests/expressions/primary_expressions/intrinsics_echo.phpt @@ -41,4 +41,4 @@ echo "$v3\n"; >>2030||Hello|(3,5)<< >>2030||Hello|(3,5)<< string(9) "qqq123zzz" -qqq123zzz \ No newline at end of file +qqq123zzz diff --git a/tests/expressions/primary_expressions/intrinsics_empty.phpt b/tests/expressions/primary_expressions/intrinsics_empty.phpt index 9500a634..2eca9045 100644 --- a/tests/expressions/primary_expressions/intrinsics_empty.phpt +++ b/tests/expressions/primary_expressions/intrinsics_empty.phpt @@ -114,18 +114,6 @@ class XX {} $v = new XX; var_dump(empty($v)); -echo "--------- undefined parameter -------------\n"; - -function f($p) -{ - var_dump($p); - var_dump(empty($p)); -} - -f(); -f(NULL); -f(10); - echo "---------- resource STDIN ------------\n"; var_dump(empty(STDIN)); @@ -205,17 +193,6 @@ bool(false) bool(false) --------- instance of class having no properties ------------- bool(false) ---------- undefined parameter ------------- - -Warning: %s - -Notice: Undefined variable: p in %s/expressions/primary_expressions/intrinsics_empty.php on line 118 -NULL -bool(true) -NULL -bool(true) -int(10) -bool(false) ---------- resource STDIN ------------ bool(false) bool(false) diff --git a/tests/expressions/primary_expressions/intrinsics_eval.phpt b/tests/expressions/primary_expressions/intrinsics_eval.phpt index a7dd6452..71506756 100644 --- a/tests/expressions/primary_expressions/intrinsics_eval.phpt +++ b/tests/expressions/primary_expressions/intrinsics_eval.phpt @@ -15,4 +15,4 @@ $str = "Hello"; eval("echo \$str . \"\\n\";"); --EXPECT-- -Hello \ No newline at end of file +Hello diff --git a/tests/expressions/primary_expressions/intrinsics_exit.phpt b/tests/expressions/primary_expressions/intrinsics_exit.phpt index 0babd8bd..d8dfd8b9 100644 --- a/tests/expressions/primary_expressions/intrinsics_exit.phpt +++ b/tests/expressions/primary_expressions/intrinsics_exit.phpt @@ -42,4 +42,4 @@ echo "end of script\n"; --------- test with/without string ------------- goodbye Inside cleanup2 -Inside cleanup1 \ No newline at end of file +Inside cleanup1 diff --git a/tests/expressions/primary_expressions/intrinsics_isset.phpt b/tests/expressions/primary_expressions/intrinsics_isset.phpt index 8df019e4..2dfd4907 100644 --- a/tests/expressions/primary_expressions/intrinsics_isset.phpt +++ b/tests/expressions/primary_expressions/intrinsics_isset.phpt @@ -15,6 +15,10 @@ echo "--------- TRUE -------------\n"; $v = TRUE; var_dump(isset($v)); +echo "--------- TRUE -------------\n"; + +$v = TRUE; +var_dump(isset($v,)); echo "--------- NULL -------------\n"; @@ -26,18 +30,6 @@ echo "--------- TRUE, 12.3, NULL -------------\n"; $v1 = TRUE; $v2 = 12.3; $v3 = NULL; var_dump(isset($v1, $v2, $v3)); -echo "--------- undefined parameter -------------\n"; - -function f($p) -{ - var_dump($p); - var_dump(isset($p)); -} - -f(); -f(NULL); -f(10); - echo "---------- dynamic property ------------\n"; class X1 @@ -64,21 +56,12 @@ var_dump(isset($x2->m)); --EXPECTF-- --------- TRUE ------------- bool(true) +--------- TRUE ------------- +bool(true) --------- NULL ------------- bool(false) --------- TRUE, 12.3, NULL ------------- bool(false) ---------- undefined parameter ------------- - -Warning: %s - -Notice: Undefined variable: p in %s/expressions/primary_expressions/intrinsics_isset.php on line 30 -NULL -bool(false) -NULL -bool(false) -int(10) -bool(true) ---------- dynamic property ------------ bool(false) bool(true) diff --git a/tests/expressions/primary_expressions/intrinsics_list.phpt b/tests/expressions/primary_expressions/intrinsics_list.phpt index cd2816be..61521b38 100644 --- a/tests/expressions/primary_expressions/intrinsics_list.phpt +++ b/tests/expressions/primary_expressions/intrinsics_list.phpt @@ -1,5 +1,5 @@ --TEST-- -PHP Spec test generated from ./expressions/primary_expressions/intrinsics_list.php +list() intrinsic --FILE-- 10, "a" => 20, "y" => 30]; - // Undefined offset: 2, 1, 0 + // Undefined offset: 0, 1, 2 echo "\$min: $min, \$max: $max, \$avg: $avg\n"; print_r($v); @@ -129,7 +129,8 @@ $v = list($a[0], $a[2], $a[4]) = array(0, 100, 67); print_r($a); print_r($v); -echo "--------- test with no variables -------------\n"; +// All of the following are invalid +/*echo "--------- test with no variables -------------\n"; $v = list() = array(0, 100, 67); print_r($v); @@ -138,7 +139,7 @@ $v = list(,) = array(0, 100, 67); print_r($v); $v = list(,,) = array(0, 100, 67); -print_r($v); +print_r($v);*/ --EXPECTF-- --------- test with full and omitted LHS vars ------------- $min: 0, $max: 100, $avg: 67 @@ -223,11 +224,11 @@ Array ) --------- test with non-numeric array ------------- -Notice: Undefined %s: 2 in %s/expressions/primary_expressions/intrinsics_list.php on line 96 +Notice: Undefined %s: 0 in %s/expressions/primary_expressions/intrinsics_list.php on line 96 Notice: Undefined %s: 1 in %s/expressions/primary_expressions/intrinsics_list.php on line 96 -Notice: Undefined %s: 0 in %s/expressions/primary_expressions/intrinsics_list.php on line 96 +Notice: Undefined %s: 2 in %s/expressions/primary_expressions/intrinsics_list.php on line 96 $min: , $max: , $avg: Array ( @@ -278,29 +279,10 @@ Array ) --------- test with target vars being array elements ------------- Array -( - [4] => 67 - [2] => 100 - [0] => 0 -) -Array ( [0] => 0 - [1] => 100 - [2] => 67 -) ---------- test with no variables ------------- -Array -( - [0] => 0 - [1] => 100 - [2] => 67 -) -Array -( - [0] => 0 - [1] => 100 - [2] => 67 + [2] => 100 + [4] => 67 ) Array ( diff --git a/tests/expressions/primary_expressions/intrinsics_print.phpt b/tests/expressions/primary_expressions/intrinsics_print.phpt index 003589c5..023ee31f 100644 --- a/tests/expressions/primary_expressions/intrinsics_print.phpt +++ b/tests/expressions/primary_expressions/intrinsics_print.phpt @@ -45,4 +45,4 @@ if (print "xx\n") ; string(9) "qqq123zzz" qqq123zzz xx -AA \ No newline at end of file +AA diff --git a/tests/expressions/primary_expressions/intrinsics_unset.phpt b/tests/expressions/primary_expressions/intrinsics_unset.phpt index 8438d2dd..7ec56a45 100644 --- a/tests/expressions/primary_expressions/intrinsics_unset.phpt +++ b/tests/expressions/primary_expressions/intrinsics_unset.phpt @@ -18,6 +18,13 @@ var_dump(isset($v)); unset($v); var_dump(isset($v)); +echo "--------- TRUE -------------\n"; + +$v = TRUE; +var_dump(isset($v)); +unset($v,); +var_dump(isset($v)); + echo "--------- NULL -------------\n"; $v = NULL; @@ -32,20 +39,6 @@ var_dump(isset($v1, $v2, $v3)); unset($v1, $v2, $v3); var_dump(isset($v1, $v2, $v3)); -echo "--------- undefined parameter -------------\n"; - -function f($p) -{ - var_dump($p); - var_dump(isset($p)); - unset($p); - var_dump(isset($p)); -} - -f(); -f(NULL); -f(10); - echo "---------- dynamic property ------------\n"; class X1 @@ -162,32 +155,6 @@ $c2 = new C; var_dump($c2); var_dump(isset($c2->prop)); -echo "---------- unsetting \$this ------------\n"; - -class D -{ - public function f() - { - echo "Inside ". __METHOD__ . "\n"; - - var_dump(isset($this)); - unset($this); - var_dump(isset($this)); - - $this->g(); // use $this to call sibling instance method - } - - private function g() - { - echo "Inside ". __METHOD__ . "\n"; - - var_dump(isset($this)); - } -} - -$d = new D; -$d->f(); - echo "---------- unsetting array elements ------------\n"; $a = array(10, 20, "xx" => 30); @@ -204,24 +171,13 @@ print_r($a); --------- TRUE ------------- bool(true) bool(false) ---------- NULL ------------- -bool(false) -bool(false) ---------- TRUE, 12.3, NULL ------------- +--------- TRUE ------------- bool(true) bool(false) ---------- undefined parameter ------------- - -Warning: %s - -Notice: Undefined variable: p in %s/expressions/primary_expressions/intrinsics_unset.php on line 36 -NULL -bool(false) -bool(false) -NULL +--------- NULL ------------- bool(false) bool(false) -int(10) +--------- TRUE, 12.3, NULL ------------- bool(true) bool(false) ---------- dynamic property ------------ @@ -270,12 +226,6 @@ object(C)#4 (1) { int(10) } bool(true) ----------- unsetting $this ------------ -Inside D::f -bool(true) -bool(false) -Inside D::g -bool(true) ---------- unsetting array elements ------------ Array ( diff --git a/tests/expressions/primary_expressions/primary.phpt b/tests/expressions/primary_expressions/primary.phpt index 112c24ff..06793296 100644 --- a/tests/expressions/primary_expressions/primary.phpt +++ b/tests/expressions/primary_expressions/primary.phpt @@ -18,17 +18,15 @@ var_dump(((($i) + (10)))); $a = [100, 200]; var_dump($a[0]); var_dump(($a[0])); // redundant grouping parens - -// This is not supported in PHP 5.x -//var_dump(($a)[0]); // redundant grouping parens +var_dump(($a)[0]); // redundant grouping parens $z = [[2,4,6,8], [5,10], [100,200,300]]; var_dump($z[0][2]); - -// This is not supported in PHP 5.x -//var_dump(($z[0])[2]); // redundant grouping parens +var_dump(($z[0])[2]); // redundant grouping parens --EXPECT-- int(110) int(100) int(100) +int(100) +int(6) int(6) diff --git a/tests/expressions/relational_operators/comparisons1.phpt b/tests/expressions/relational_operators/comparisons1.phpt index 67f184b9..ab2a4941 100644 --- a/tests/expressions/relational_operators/comparisons1.phpt +++ b/tests/expressions/relational_operators/comparisons1.phpt @@ -27,7 +27,7 @@ echo "\n"; ///* // NULL operand with all kinds of operands, swapping them over to make -// LHS/RHS order is irrelevent. +// LHS/RHS order is irrelevant. $oper1 = array(NULL); $oper2 = array(0, 100, -3.4, TRUE, FALSE, NULL, "", "123", "abc", [], [10,2.3]); @@ -349,4 +349,4 @@ Array > result: bool(true) Notice: Array to string conversion in %s/expressions/relational_operators/comparisons1.php on line 54 Array > (bool) result: bool(true) ======= -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/relational_operators/comparisons2.phpt b/tests/expressions/relational_operators/comparisons2.phpt index 61e18900..13f6e257 100644 --- a/tests/expressions/relational_operators/comparisons2.phpt +++ b/tests/expressions/relational_operators/comparisons2.phpt @@ -341,4 +341,4 @@ AB >= aA result: bool(false) aA <= AB result: bool(false) AB > aA result: bool(false) ======= -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/relational_operators/comparisons3.phpt b/tests/expressions/relational_operators/comparisons3.phpt index 55ab3657..8fa0540e 100644 --- a/tests/expressions/relational_operators/comparisons3.phpt +++ b/tests/expressions/relational_operators/comparisons3.phpt @@ -13,7 +13,7 @@ error_reporting(-1); ///* // Boolean operand with all kinds of operands, swapping them over to make -// LHS/RHS order is irrelevent. +// LHS/RHS order is irrelevant. $oper1 = array(TRUE, FALSE); $oper2 = array(0, 100, -3.4, TRUE, FALSE, NULL, "", "123", "abc", [], [10,2.3]); @@ -615,4 +615,4 @@ Array > result: bool(true) Notice: Array to string conversion in %s/expressions/relational_operators/comparisons3.php on line 40 Array > (bool) result: bool(true) ======= -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/relational_operators/comparisons4.phpt b/tests/expressions/relational_operators/comparisons4.phpt index d5d187df..d22935af 100644 --- a/tests/expressions/relational_operators/comparisons4.phpt +++ b/tests/expressions/relational_operators/comparisons4.phpt @@ -13,7 +13,7 @@ error_reporting(-1); ///* // Numeric strings with all kinds of operands, swapping them over to make -// LHS/RHS order is irrelevent. +// LHS/RHS order is irrelevant. $oper1 = array("10", "-5.1"); $oper2 = array(0, 100, -3.4, TRUE, FALSE, NULL, "", "123", "abc", [], [10,2.3]); @@ -367,4 +367,4 @@ Notice: Array to string conversion in %s/expressions/relational_operators/compar Notice: Array to string conversion in %s/expressions/relational_operators/comparisons4.php on line 32 Array > -5.1 result: bool(true) ======= -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/relational_operators/comparisons5.phpt b/tests/expressions/relational_operators/comparisons5.phpt index 31add377..6c541982 100644 --- a/tests/expressions/relational_operators/comparisons5.phpt +++ b/tests/expressions/relational_operators/comparisons5.phpt @@ -256,4 +256,4 @@ Array >= Array result: bool(true) Array <= Array result: bool(true) Array > Array result: bool(false) ======= -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/source_file_inclusion/Point.inc b/tests/expressions/source_file_inclusion/Point.inc index 54a65d8e..27c0da27 100644 --- a/tests/expressions/source_file_inclusion/Point.inc +++ b/tests/expressions/source_file_inclusion/Point.inc @@ -8,9 +8,9 @@ error_reporting(-1); -class Point +class Point { - public function __construct($newX = 0, $newY = 0) + public function __construct($newX = 0, $newY = 0) { } } diff --git a/tests/expressions/source_file_inclusion/include.phpt b/tests/expressions/source_file_inclusion/include.phpt index 6fc93c2e..89fc0c02 100644 --- a/tests/expressions/source_file_inclusion/include.phpt +++ b/tests/expressions/source_file_inclusion/include.phpt @@ -11,13 +11,13 @@ PHP Spec test generated from ./expressions/source_file_inclusion/include.php error_reporting(-1); -echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . +echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . "< with namespace >" . __NAMESPACE__ . "<\n"; //var_dump(MY_MIN); //var_dump(MY_MAX); -// Try to include a non-existant file +// Try to include a non-existent file $fileName = 'unknown.inc'; $inc = include $fileName; @@ -29,7 +29,7 @@ $fileName = 'limits' . '.inc'; $inc = include $fileName; var_dump($inc); -echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . +echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . "< with namespace >" . __NAMESPACE__ . "<\n"; // Include another existing file that has its own namespace @@ -37,7 +37,7 @@ echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . $inc = include('mycolors.inc'); var_dump($inc); -echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . +echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . "< with namespace >" . __NAMESPACE__ . "<\n"; echo "----------------------------------\n"; @@ -81,7 +81,7 @@ if ((include('return_with_value.inc')) or 987) ; echo "----------------------------------\n"; -// see if included file can access including file's variables, and if including file +// see if included file can access including file's variables, and if including file // can access the included file's functions and variables $v1 = 10; diff --git a/tests/expressions/source_file_inclusion/include_once.phpt b/tests/expressions/source_file_inclusion/include_once.phpt index 305f5731..2dd96ded 100644 --- a/tests/expressions/source_file_inclusion/include_once.phpt +++ b/tests/expressions/source_file_inclusion/include_once.phpt @@ -11,7 +11,7 @@ PHP Spec test generated from ./expressions/source_file_inclusion/include_once.ph error_reporting(-1); -// Try to include a non-existant file +// Try to include a non-existent file $inc = include_once 'XXPositions.inc'; var_dump($inc); diff --git a/tests/expressions/source_file_inclusion/limits.inc b/tests/expressions/source_file_inclusion/limits.inc index 9c52e85c..8e2103b6 100644 --- a/tests/expressions/source_file_inclusion/limits.inc +++ b/tests/expressions/source_file_inclusion/limits.inc @@ -11,7 +11,7 @@ error_reporting(-1); echo "================= xxx =================\n"; -echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . +echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . "< with namespace >" . __NAMESPACE__ . "<\n"; const MY_MIN = 10; diff --git a/tests/expressions/source_file_inclusion/mycolors.inc b/tests/expressions/source_file_inclusion/mycolors.inc index 2e799232..8e9dcb50 100644 --- a/tests/expressions/source_file_inclusion/mycolors.inc +++ b/tests/expressions/source_file_inclusion/mycolors.inc @@ -10,7 +10,7 @@ namespace MyColors; error_reporting(-1); -echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . +echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . "< with namespace >" . __NAMESPACE__ . "<\n"; const RED = 1; diff --git a/tests/expressions/source_file_inclusion/require.phpt b/tests/expressions/source_file_inclusion/require.phpt index 5e25e294..a357d3d1 100644 --- a/tests/expressions/source_file_inclusion/require.phpt +++ b/tests/expressions/source_file_inclusion/require.phpt @@ -11,13 +11,13 @@ PHP Spec test generated from ./expressions/source_file_inclusion/require.php error_reporting(-1); -echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . +echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . "< with namespace >" . __NAMESPACE__ . "<\n"; //var_dump(MY_MIN); //var_dump(MY_MAX); -// Try to require a non-existant file +// Try to require a non-existent file $fileName = 'unknown.inc'; //$inc = require $fileName; @@ -29,7 +29,7 @@ $fileName = 'limits' . '.inc'; $inc = require $fileName; var_dump($inc); -echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . +echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . "< with namespace >" . __NAMESPACE__ . "<\n"; // require another existing file that has its own namespace @@ -37,7 +37,7 @@ echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . $inc = require('mycolors.inc'); var_dump($inc); -echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . +echo "Inside file >" . __FILE__ . "< at line >" . __LINE__ . "< with namespace >" . __NAMESPACE__ . "<\n"; echo "----------------------------------\n"; @@ -81,7 +81,7 @@ if ((require('return_with_value.inc')) or 987) ; echo "----------------------------------\n"; -// see if included file can access including file's variables, and if including file +// see if included file can access including file's variables, and if including file // can access the included file's functions and variables $v1 = 10; diff --git a/tests/expressions/source_file_inclusion/require_once.phpt b/tests/expressions/source_file_inclusion/require_once.phpt index 7e8410c7..e3a6aaad 100644 --- a/tests/expressions/source_file_inclusion/require_once.phpt +++ b/tests/expressions/source_file_inclusion/require_once.phpt @@ -11,7 +11,7 @@ PHP Spec test generated from ./expressions/source_file_inclusion/require_once.ph error_reporting(-1); -// Try to require a non-existant file +// Try to require a non-existent file //$inc = require_once('XXPositions.inc'); //var_dump($inc); diff --git a/tests/expressions/unary_operators/cast.phpt b/tests/expressions/unary_operators/cast.phpt index 47e17a6f..9c714384 100644 --- a/tests/expressions/unary_operators/cast.phpt +++ b/tests/expressions/unary_operators/cast.phpt @@ -29,8 +29,10 @@ echo var_dump((binary)""); echo var_dump((binary)"abcdef"); echo var_dump($v); -echo var_dump((unset)$v); -echo var_dump($v); + +// The (unset) cast is no longer supported +//echo var_dump((unset)$v); +//echo var_dump($v); //*/ ///* @@ -73,7 +75,7 @@ var_dump($c1); //var_dump((string)$c1); class D -{ +{ public function __toString() { return "AAA"; @@ -90,9 +92,9 @@ echo "---------------\n"; class E { - const CON1 = 123; // constants irrelevent for conversion purposes - public function f() {} // methods irrelevent for conversion purposes - private static $fsprop = 0; // static properties irrelevent for conversion purposes + const CON1 = 123; // constants irrelevant for conversion purposes + public function f() {} // methods irrelevant for conversion purposes + private static $fsprop = 0; // static properties irrelevant for conversion purposes private $priv_prop; protected $prot_prop = 12.345; @@ -166,8 +168,6 @@ string(1) "0" string(0) "" string(6) "abcdef" int(0) -NULL -int(0) int(10) bool(true) bool(true) @@ -255,7 +255,7 @@ float(1.234E+203) float(INF) bool(true) bool(true) - int(%i) + int(0) float(INF) string(3) "INF" array(1) { @@ -269,7 +269,7 @@ float(INF) float(-INF) bool(true) bool(true) - int(%i) + int(0) float(-INF) string(4) "-INF" array(1) { @@ -283,7 +283,7 @@ float(-INF) float(NAN) bool(true) bool(true) - int(%i) + int(0) float(NAN) string(3) "NAN" array(1) { @@ -455,7 +455,7 @@ array(2) { int(1) float(1) -Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line 50 +Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line %d string(5) "Array" array(2) { [5]=> @@ -464,9 +464,9 @@ string(5) "Array" int(20) } >>---object(stdClass)#1 (2) { - [5]=> + ["5"]=> int(10) - [2]=> + ["2"]=> int(20) } array(4) { @@ -484,7 +484,7 @@ array(4) { int(1) float(1) -Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line 50 +Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line %d string(5) "Array" array(4) { [0]=> @@ -497,13 +497,13 @@ string(5) "Array" NULL } >>---object(stdClass)#1 (4) { - [0]=> + ["0"]=> float(1.23) - [1]=> + ["1"]=> bool(true) - [2]=> + ["2"]=> string(5) "Hello" - [3]=> + ["3"]=> NULL } float(3.3333333333333) @@ -554,7 +554,7 @@ object(E)#3 (3) { $key: >Epriv_prop<, len: 12, $val: >< $key: >*prot_prop<, len: 12, $val: >12.345< -Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line 115 +Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line %d $key: >publ_prop<, len: 9, $val: >Array< --------------- resource(1) of type (stream) diff --git a/tests/expressions/unary_operators/pre-increment_and_decrement.phpt b/tests/expressions/unary_operators/pre-increment_and_decrement.phpt index bdd49dc3..c417cc14 100644 --- a/tests/expressions/unary_operators/pre-increment_and_decrement.phpt +++ b/tests/expressions/unary_operators/pre-increment_and_decrement.phpt @@ -1,5 +1,5 @@ --TEST-- -PHP Spec test generated from ./expressions/unary_operators/pre-increment_and_decrement.php +Prefix increment and decrement --FILE-- int(5) $a = 4 <---> int(4) @@ -389,6 +389,8 @@ $a = <---> bool(false) --------------------------------------- start incdec --- $a = <---> string(0) "" $a = -1 <---> int(-1) + +Warning: A non-numeric value encountered in %s on line %d $a = -2 <---> int(-2) $a = -1 <---> int(-1) $a = 0 @@ -397,6 +399,8 @@ $a = 0 <---> int(0) --------------------------------------- start incdecrev --- $a = <---> string(0) "" $a = 1 <---> string(1) "1" + +Warning: A non-numeric value encountered in %s on line %d $a = 2 <---> int(2) $a = 1 <---> int(1) $a = 2 @@ -500,39 +504,49 @@ $a = 14 <---> int(14) --------------------------------------- end incdecrev --- --------------------------------------- start incdec --- $a = 0x12 <---> string(4) "0x12" -$a = 17 <---> int(17) -$a = 16 <---> int(16) -$a = 17 <---> int(17) -$a = 18 -$a = 18 <---> int(18) +$a = 0x12 <---> string(4) "0x12" + +Notice: A non well formed numeric value encountered in %s on line %d +$a = 0x12 <---> string(4) "0x12" +$a = 0x13 <---> string(4) "0x13" +$a = 0x14 +$a = 0x14 <---> string(4) "0x14" --------------------------------------- end incdec --- --------------------------------------- start incdecrev --- $a = 0x12 <---> string(4) "0x12" -$a = 19 <---> int(19) -$a = 20 <---> int(20) -$a = 19 <---> int(19) -$a = 20 -$a = 20 <---> int(20) +$a = 0x13 <---> string(4) "0x13" + +Notice: A non well formed numeric value encountered in %s on line %d +$a = 0x14 <---> string(4) "0x14" +$a = 0x14 <---> string(4) "0x14" +$a = 0x15 +$a = 0x15 <---> string(4) "0x15" --------------------------------------- end incdecrev --- --------------------------------------- start incdec --- $a = 0X12 <---> string(4) "0X12" -$a = 17 <---> int(17) -$a = 16 <---> int(16) -$a = 17 <---> int(17) -$a = 18 -$a = 18 <---> int(18) +$a = 0X12 <---> string(4) "0X12" + +Notice: A non well formed numeric value encountered in %s on line %d +$a = 0X12 <---> string(4) "0X12" +$a = 0X13 <---> string(4) "0X13" +$a = 0X14 +$a = 0X14 <---> string(4) "0X14" --------------------------------------- end incdec --- --------------------------------------- start incdecrev --- $a = 0X12 <---> string(4) "0X12" -$a = 19 <---> int(19) -$a = 20 <---> int(20) -$a = 19 <---> int(19) -$a = 20 -$a = 20 <---> int(20) +$a = 0X13 <---> string(4) "0X13" + +Notice: A non well formed numeric value encountered in %s on line %d +$a = 0X14 <---> string(4) "0X14" +$a = 0X14 <---> string(4) "0X14" +$a = 0X15 +$a = 0X15 <---> string(4) "0X15" --------------------------------------- end incdecrev --- --------------------------------------- start incdec --- $a = 0b101 <---> string(5) "0b101" $a = 0b101 <---> string(5) "0b101" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0b101 <---> string(5) "0b101" $a = 0b102 <---> string(5) "0b102" $a = 0b103 @@ -541,6 +555,8 @@ $a = 0b103 <---> string(5) "0b103" --------------------------------------- start incdecrev --- $a = 0b101 <---> string(5) "0b101" $a = 0b102 <---> string(5) "0b102" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0b103 <---> string(5) "0b103" $a = 0b103 <---> string(5) "0b103" $a = 0b104 @@ -549,6 +565,8 @@ $a = 0b104 <---> string(5) "0b104" --------------------------------------- start incdec --- $a = 0B101 <---> string(5) "0B101" $a = 0B101 <---> string(5) "0B101" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0B101 <---> string(5) "0B101" $a = 0B102 <---> string(5) "0B102" $a = 0B103 @@ -557,6 +575,8 @@ $a = 0B103 <---> string(5) "0B103" --------------------------------------- start incdecrev --- $a = 0B101 <---> string(5) "0B101" $a = 0B102 <---> string(5) "0B102" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0B103 <---> string(5) "0B103" $a = 0B103 <---> string(5) "0B103" $a = 0B104 @@ -565,6 +585,8 @@ $a = 0B104 <---> string(5) "0B104" --------------------------------------- start incdec --- $a = 0Q101 <---> string(5) "0Q101" $a = 0Q101 <---> string(5) "0Q101" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0Q101 <---> string(5) "0Q101" $a = 0Q102 <---> string(5) "0Q102" $a = 0Q103 @@ -573,6 +595,8 @@ $a = 0Q103 <---> string(5) "0Q103" --------------------------------------- start incdecrev --- $a = 0Q101 <---> string(5) "0Q101" $a = 0Q102 <---> string(5) "0Q102" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0Q103 <---> string(5) "0Q103" $a = 0Q103 <---> string(5) "0Q103" $a = 0Q104 @@ -665,6 +689,8 @@ $a = 96 <---> int(96) --------------------------------------- start incdec --- $a = 987 <---> string(4) "987 " $a = 987 <---> string(4) "987 " + +Notice: A non well formed numeric value encountered in %s on line %d $a = 987 <---> string(4) "987 " $a = 987 <---> string(4) "987 " $a = 987 @@ -673,6 +699,8 @@ $a = 987 <---> string(4) "987 " --------------------------------------- start incdecrev --- $a = 987 <---> string(4) "987 " $a = 987 <---> string(4) "987 " + +Notice: A non well formed numeric value encountered in %s on line %d $a = 987 <---> string(4) "987 " $a = 987 <---> string(4) "987 " $a = 987 @@ -685,6 +713,8 @@ $a = 15 $a = 15 <---> string(9) "15 " + +Notice: A non well formed numeric value encountered in %s on line %d $a = 15 <---> string(9) "15 " @@ -704,6 +734,8 @@ $a = 15 $a = 15 <---> string(9) "15 " + +Notice: A non well formed numeric value encountered in %s on line %d $a = 15 <---> string(9) "15 " @@ -815,6 +847,8 @@ $a = 11.87 <---> float(11.87) --------------------------------------- start incdec --- $a = a <---> string(1) "a" $a = a <---> string(1) "a" + +Warning: A non-numeric value encountered in %s on line %d $a = a <---> string(1) "a" $a = b <---> string(1) "b" $a = c @@ -823,6 +857,8 @@ $a = c <---> string(1) "c" --------------------------------------- start incdecrev --- $a = a <---> string(1) "a" $a = b <---> string(1) "b" + +Warning: A non-numeric value encountered in %s on line %d $a = c <---> string(1) "c" $a = c <---> string(1) "c" $a = d @@ -831,6 +867,8 @@ $a = d <---> string(1) "d" --------------------------------------- start incdec --- $a = z <---> string(1) "z" $a = z <---> string(1) "z" + +Warning: A non-numeric value encountered in %s on line %d $a = z <---> string(1) "z" $a = aa <---> string(2) "aa" $a = ab @@ -839,6 +877,8 @@ $a = ab <---> string(2) "ab" --------------------------------------- start incdecrev --- $a = z <---> string(1) "z" $a = aa <---> string(2) "aa" + +Warning: A non-numeric value encountered in %s on line %d $a = ab <---> string(2) "ab" $a = ab <---> string(2) "ab" $a = ac @@ -847,6 +887,8 @@ $a = ac <---> string(2) "ac" --------------------------------------- start incdec --- $a = A <---> string(1) "A" $a = A <---> string(1) "A" + +Warning: A non-numeric value encountered in %s on line %d $a = A <---> string(1) "A" $a = B <---> string(1) "B" $a = C @@ -855,6 +897,8 @@ $a = C <---> string(1) "C" --------------------------------------- start incdecrev --- $a = A <---> string(1) "A" $a = B <---> string(1) "B" + +Warning: A non-numeric value encountered in %s on line %d $a = C <---> string(1) "C" $a = C <---> string(1) "C" $a = D @@ -863,6 +907,8 @@ $a = D <---> string(1) "D" --------------------------------------- start incdec --- $a = Z <---> string(1) "Z" $a = Z <---> string(1) "Z" + +Warning: A non-numeric value encountered in %s on line %d $a = Z <---> string(1) "Z" $a = AA <---> string(2) "AA" $a = AB @@ -871,6 +917,8 @@ $a = AB <---> string(2) "AB" --------------------------------------- start incdecrev --- $a = Z <---> string(1) "Z" $a = AA <---> string(2) "AA" + +Warning: A non-numeric value encountered in %s on line %d $a = AB <---> string(2) "AB" $a = AB <---> string(2) "AB" $a = AC @@ -879,6 +927,8 @@ $a = AC <---> string(2) "AC" --------------------------------------- start incdec --- $a = F28 <---> string(3) "F28" $a = F28 <---> string(3) "F28" + +Warning: A non-numeric value encountered in %s on line %d $a = F28 <---> string(3) "F28" $a = F29 <---> string(3) "F29" $a = F30 @@ -887,6 +937,8 @@ $a = F30 <---> string(3) "F30" --------------------------------------- start incdecrev --- $a = F28 <---> string(3) "F28" $a = F29 <---> string(3) "F29" + +Warning: A non-numeric value encountered in %s on line %d $a = F30 <---> string(3) "F30" $a = F30 <---> string(3) "F30" $a = F31 @@ -895,6 +947,8 @@ $a = F31 <---> string(3) "F31" --------------------------------------- start incdec --- $a = F28 <---> string(3) "F28" $a = F28 <---> string(3) "F28" + +Warning: A non-numeric value encountered in %s on line %d $a = F28 <---> string(3) "F28" $a = F29 <---> string(3) "F29" $a = F30 @@ -903,6 +957,8 @@ $a = F30 <---> string(3) "F30" --------------------------------------- start incdecrev --- $a = F98 <---> string(3) "F98" $a = F99 <---> string(3) "F99" + +Warning: A non-numeric value encountered in %s on line %d $a = G00 <---> string(3) "G00" $a = G00 <---> string(3) "G00" $a = G01 @@ -911,6 +967,8 @@ $a = G01 <---> string(3) "G01" --------------------------------------- start incdec --- $a = F98 <---> string(3) "F98" $a = F98 <---> string(3) "F98" + +Warning: A non-numeric value encountered in %s on line %d $a = F98 <---> string(3) "F98" $a = F99 <---> string(3) "F99" $a = G00 @@ -919,6 +977,8 @@ $a = G00 <---> string(3) "G00" --------------------------------------- start incdecrev --- $a = FZ8 <---> string(3) "FZ8" $a = FZ9 <---> string(3) "FZ9" + +Warning: A non-numeric value encountered in %s on line %d $a = GA0 <---> string(3) "GA0" $a = GA0 <---> string(3) "GA0" $a = GA1 @@ -927,6 +987,8 @@ $a = GA1 <---> string(3) "GA1" --------------------------------------- start incdec --- $a = ZZ8 <---> string(3) "ZZ8" $a = ZZ8 <---> string(3) "ZZ8" + +Warning: A non-numeric value encountered in %s on line %d $a = ZZ8 <---> string(3) "ZZ8" $a = ZZ9 <---> string(3) "ZZ9" $a = AAA0 @@ -935,6 +997,8 @@ $a = AAA0 <---> string(4) "AAA0" --------------------------------------- start incdecrev --- $a = ZZ8 <---> string(3) "ZZ8" $a = ZZ9 <---> string(3) "ZZ9" + +Warning: A non-numeric value encountered in %s on line %d $a = AAA0 <---> string(4) "AAA0" $a = AAA0 <---> string(4) "AAA0" $a = AAA1 @@ -943,6 +1007,8 @@ $a = AAA1 <---> string(4) "AAA1" --------------------------------------- start incdecrev --- $a = 543J <---> string(4) "543J" $a = 543K <---> string(4) "543K" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 543L <---> string(4) "543L" $a = 543L <---> string(4) "543L" $a = 543M @@ -951,6 +1017,8 @@ $a = 543M <---> string(4) "543M" --------------------------------------- start incdec --- $a = 543J <---> string(4) "543J" $a = 543J <---> string(4) "543J" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 543J <---> string(4) "543J" $a = 543K <---> string(4) "543K" $a = 543L @@ -959,6 +1027,8 @@ $a = 543L <---> string(4) "543L" --------------------------------------- start incdecrev --- $a = 543J9 <---> string(5) "543J9" $a = 543K0 <---> string(5) "543K0" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 543K1 <---> string(5) "543K1" $a = 543K1 <---> string(5) "543K1" $a = 543K2 @@ -967,6 +1037,8 @@ $a = 543K2 <---> string(5) "543K2" --------------------------------------- start incdec --- $a = 543J9 <---> string(5) "543J9" $a = 543J9 <---> string(5) "543J9" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 543J9 <---> string(5) "543J9" $a = 543K0 <---> string(5) "543K0" $a = 543K1 @@ -975,6 +1047,8 @@ $a = 543K1 <---> string(5) "543K1" --------------------------------------- start incdec --- $a = & <---> string(1) "&" $a = & <---> string(1) "&" + +Warning: A non-numeric value encountered in %s on line %d $a = & <---> string(1) "&" $a = & <---> string(1) "&" $a = & @@ -983,6 +1057,8 @@ $a = & <---> string(1) "&" --------------------------------------- start incdecrev --- $a = & <---> string(1) "&" $a = & <---> string(1) "&" + +Warning: A non-numeric value encountered in %s on line %d $a = & <---> string(1) "&" $a = & <---> string(1) "&" $a = & @@ -991,6 +1067,8 @@ $a = & <---> string(1) "&" --------------------------------------- start incdec --- $a = 83& <---> string(3) "83&" $a = 83& <---> string(3) "83&" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83& <---> string(3) "83&" $a = 83& <---> string(3) "83&" $a = 83& @@ -999,6 +1077,8 @@ $a = 83& <---> string(3) "83&" --------------------------------------- start incdecrev --- $a = 83& <---> string(3) "83&" $a = 83& <---> string(3) "83&" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83& <---> string(3) "83&" $a = 83& <---> string(3) "83&" $a = 83& @@ -1007,6 +1087,8 @@ $a = 83& <---> string(3) "83&" --------------------------------------- start incdec --- $a = 83&8 <---> string(4) "83&8" $a = 83&8 <---> string(4) "83&8" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&8 <---> string(4) "83&8" $a = 83&9 <---> string(4) "83&9" $a = 83&0 @@ -1015,6 +1097,8 @@ $a = 83&0 <---> string(4) "83&0" --------------------------------------- start incdecrev --- $a = 83&8 <---> string(4) "83&8" $a = 83&9 <---> string(4) "83&9" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&0 <---> string(4) "83&0" $a = 83&0 <---> string(4) "83&0" $a = 83&1 @@ -1023,6 +1107,8 @@ $a = 83&1 <---> string(4) "83&1" --------------------------------------- start incdec --- $a = 83&Z8 <---> string(5) "83&Z8" $a = 83&Z8 <---> string(5) "83&Z8" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&Z8 <---> string(5) "83&Z8" $a = 83&Z9 <---> string(5) "83&Z9" $a = 83&A0 @@ -1031,6 +1117,8 @@ $a = 83&A0 <---> string(5) "83&A0" --------------------------------------- start incdecrev --- $a = 83&Z8 <---> string(5) "83&Z8" $a = 83&Z9 <---> string(5) "83&Z9" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&A0 <---> string(5) "83&A0" $a = 83&A0 <---> string(5) "83&A0" $a = 83&A1 @@ -1039,6 +1127,8 @@ $a = 83&A1 <---> string(5) "83&A1" --------------------------------------- start incdec --- $a = 83&z8 <---> string(5) "83&z8" $a = 83&z8 <---> string(5) "83&z8" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&z8 <---> string(5) "83&z8" $a = 83&z9 <---> string(5) "83&z9" $a = 83&a0 @@ -1047,6 +1137,8 @@ $a = 83&a0 <---> string(5) "83&a0" --------------------------------------- start incdecrev --- $a = 83&z8 <---> string(5) "83&z8" $a = 83&z9 <---> string(5) "83&z9" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&a0 <---> string(5) "83&a0" $a = 83&a0 <---> string(5) "83&a0" $a = 83&a1 @@ -1055,6 +1147,8 @@ $a = 83&a1 <---> string(5) "83&a1" --------------------------------------- start incdec --- $a = &28 <---> string(3) "&28" $a = &28 <---> string(3) "&28" + +Warning: A non-numeric value encountered in %s on line %d $a = &28 <---> string(3) "&28" $a = &29 <---> string(3) "&29" $a = &30 @@ -1063,6 +1157,8 @@ $a = &30 <---> string(3) "&30" --------------------------------------- start incdecrev --- $a = &28 <---> string(3) "&28" $a = &29 <---> string(3) "&29" + +Warning: A non-numeric value encountered in %s on line %d $a = &30 <---> string(3) "&30" $a = &30 <---> string(3) "&30" $a = &31 @@ -1071,6 +1167,8 @@ $a = &31 <---> string(3) "&31" --------------------------------------- start incdec --- $a = &98 <---> string(3) "&98" $a = &98 <---> string(3) "&98" + +Warning: A non-numeric value encountered in %s on line %d $a = &98 <---> string(3) "&98" $a = &99 <---> string(3) "&99" $a = &00 @@ -1079,6 +1177,8 @@ $a = &00 <---> string(3) "&00" --------------------------------------- start incdecrev --- $a = &98 <---> string(3) "&98" $a = &99 <---> string(3) "&99" + +Warning: A non-numeric value encountered in %s on line %d $a = &00 <---> string(3) "&00" $a = &00 <---> string(3) "&00" $a = &01 diff --git a/tests/expressions/unary_operators/pre-increment_and_decrement_integer_edge_cases.phpt b/tests/expressions/unary_operators/pre-increment_and_decrement_integer_edge_cases.phpt index db2dd420..c90d0a09 100644 --- a/tests/expressions/unary_operators/pre-increment_and_decrement_integer_edge_cases.phpt +++ b/tests/expressions/unary_operators/pre-increment_and_decrement_integer_edge_cases.phpt @@ -100,4 +100,4 @@ float(9.2233720368548E+18) float(9.2233720368548E+18) float(9.2233720368548E+18) float(9.2233720368548E+18) ---- end incdecrev --- \ No newline at end of file +--- end incdecrev --- diff --git a/tests/expressions/unary_operators/unary_arithmetic_operators.phpt b/tests/expressions/unary_operators/unary_arithmetic_operators.phpt index 0e994a62..88055f61 100644 --- a/tests/expressions/unary_operators/unary_arithmetic_operators.phpt +++ b/tests/expressions/unary_operators/unary_arithmetic_operators.phpt @@ -80,7 +80,7 @@ DoIt("-25.5e-10"); DoIt(""); DoIt("ABC"); //*/ ---EXPECT-- +--EXPECTF-- --- start DoIt ------------------------- original: int(0) @@ -229,10 +229,18 @@ DoIt("ABC"); original: string(0) "" +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d + --- end DoIt ------------------------- --- start DoIt ------------------------- original: string(3) "ABC" ---- end DoIt ------------------------- \ No newline at end of file +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d + +--- end DoIt ------------------------- diff --git a/tests/expressions/yield_operator/yield.phpt b/tests/expressions/yield_operator/yield.phpt index 55c383d3..0e472dae 100644 --- a/tests/expressions/yield_operator/yield.phpt +++ b/tests/expressions/yield_operator/yield.phpt @@ -54,7 +54,7 @@ echo "===========================\n"; //*/ ///* -// define a generator that returns sucessive lines from a file of text +// define a generator that returns successive lines from a file of text function getTextFileLines($filename) { diff --git a/tests/functions/anonymous_functions.phpt b/tests/functions/anonymous_functions.phpt index 807a20d3..0a8a87c8 100644 --- a/tests/functions/anonymous_functions.phpt +++ b/tests/functions/anonymous_functions.phpt @@ -92,7 +92,7 @@ echo "----------------- using a use clause, #1 ----------------------\n"; function compute(array $values) { $count = 0; - + $callback = function () use (&$count) { echo "Inside method >>" . __METHOD__ . "<<\n"; // called {closure} @@ -119,10 +119,10 @@ class D public function compute(array $values) { $count = 0; - + $callback = function ($p1, $p2) use (&$count, $values) { - echo "Inside method >>" . __METHOD__ . "<<\n"; // called D::{closure} + echo "Inside method >>" . __METHOD__ . "<<\n"; // called {closure} ++$count; $this->f(); // $this is available automatically; can't put it in use clause anyway @@ -140,10 +140,10 @@ class D echo "\$count = $count\n"; $callback(5,6,7); echo "\$count = $count\n"; - + $callback2 = function() { - echo "Inside method >>" . __METHOD__ . "<<\n"; // ALSO called D::{closure} + echo "Inside method >>" . __METHOD__ . "<<\n"; // ALSO called {closure} }; echo "--\n"; @@ -160,7 +160,7 @@ class D public static function stcompute(array $values) { $count = 0; - + $callback = function ($p1, $p2) use (&$count, $values) { echo "Inside method >>" . __METHOD__ . "<<\n"; // called D::{closure} @@ -307,10 +307,10 @@ object(Closure%S)#%d (3) { -- bool(true) -- -Inside method >>D::{closure}<< +Inside method >>{closure}<< Inside method >>D::f<< $count = 1 -Inside method >>D::{closure}<< +Inside method >>{closure}<< Inside method >>D::f<< $count = 2 -- @@ -324,7 +324,7 @@ object(Closure%S)#%d (1) { -- bool(true) -- -Inside method >>D::{closure}<< +Inside method >>{closure}<< ----------------- using a use clause, #3 (static method) ---------------------- -- string(6) "object" @@ -353,9 +353,9 @@ object(Closure%S)#%d (2) { -- bool(true) -- -Inside method >>D::{closure}<< +Inside method >>{closure}<< $count = 1 -Inside method >>D::{closure}<< +Inside method >>{closure}<< $count = 2 ----------------- Misc. Stuff ---------------------- Hi diff --git a/tests/functions/basics.phpt b/tests/functions/basics.phpt index 6ec34467..2a3bc2c8 100644 --- a/tests/functions/basics.phpt +++ b/tests/functions/basics.phpt @@ -30,16 +30,14 @@ function f1() } var_dump(f1()); // call f1, default return value is NULL -f1; // valid, but vacuous, as it has no side effect and its value is not used -var_dump(f1); // string with value "f1" -$f = f1; // assign this string to a variable +$f = "f1"; // assign the name of the function to a variable $f(); // call f1 indirectly via $f -//"f1"(); // call f1 via the string "f1" -- Can't be a string literal!!! +"f1"(); // call f1 via the string "f1" // f1() = 123; // a function return is not an lvalue f1(); -f1(10); +f1(10,); f1(TRUE, "green"); f1(23.45, NULL, array(1,2,3)); @@ -50,14 +48,23 @@ function f2($p1, $p2) // A NULL value doesn't prove the argument wasn't passed; find a better test echo "f2: \$p1 = ".($p1 == NULL ? "NULL" : $p1). - ", \$p2 = ".($p2 == NULL ? "NULL" : $p2)."\n"; + ", \$p2 = ".($p2 == NULL ? "NULL" : $p2)."\n"; } -// if fewer arguments are passed than there are paramaters declared, a warning is issued -// and the parameters corresponding to each each omitted argument are undefined +// if fewer arguments are passed than there are parameters declared, an ArgumentCountError is thrown -f2(); // pass 0 (< 2) -f2(10); // pass 1 (< 2) +try { + f2(); +} +catch (ArgumentCountError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + f2(10); +} +catch (ArgumentCountError $e) { + echo $e->getMessage() . PHP_EOL; +} f2(10, 20); // pass 2 (== 2) f2(10, 20, 30); // pass 3 (> 2) @@ -65,20 +72,14 @@ f2(10, 20, 30); // pass 3 (> 2) function square($v) { return $v * $v; } echo "5 squared = ".square(5)."\n"; -var_dump($funct = square); +$funct = "square"; var_dump($funct(-2.3)); echo strlen("abcedfg")."\n"; --EXPECTF-- f1: # arguments passed is 0 NULL - -Notice: Use of undefined constant f1 - assumed 'f1' in %s/functions/basics.php on line 30 - -Notice: Use of undefined constant f1 - assumed 'f1' in %s/functions/basics.php on line 31 -string(2) "f1" - -Notice: Use of undefined constant f1 - assumed 'f1' in %s/functions/basics.php on line 32 +f1: # arguments passed is 0 f1: # arguments passed is 0 f1: # arguments passed is 0 f1: # arguments passed is 1 @@ -92,23 +93,10 @@ f1: # arguments passed is 3 Notice: Array to string conversion in %s/functions/basics.php on line 25 arg[2] = >Array< - -Warning: %a - -Notice: Undefined variable: p1 in %s/functions/basics.php on line 49 - -Notice: Undefined variable: p2 in %s/functions/basics.php on line 50 -f2: $p1 = NULL, $p2 = NULL - -Warning: %s - -Notice: Undefined variable: p2 in %s/functions/basics.php on line 50 -f2: $p1 = 10, $p2 = NULL +Too few arguments to function f2(), 0 passed in %s on line %d and exactly 2 expected +Too few arguments to function f2(), 1 passed in %s on line %d and exactly 2 expected f2: $p1 = 10, $p2 = 20 f2: $p1 = 10, $p2 = 20 5 squared = 25 - -Notice: Use of undefined constant square - assumed 'square' in %s/functions/basics.php on line 65 -string(6) "square" float(5.29) 7 diff --git a/tests/functions/byrefs.phpt b/tests/functions/byrefs.phpt index a407d543..64be343d 100644 --- a/tests/functions/byrefs.phpt +++ b/tests/functions/byrefs.phpt @@ -66,8 +66,8 @@ class C unset($a); var_dump($a); -$a = new C; // make $a an alias to the allocated object -//$a = &new C; // use of & here is deprecated +$a = new C; // make $a an alias to the allocated object +//$a = &new C; // use of & here is deprecated var_dump($a); $a->m = "abc"; var_dump($a); @@ -216,4 +216,4 @@ int(200) int(-12) int(-12) g2 In: -string(5) "local" \ No newline at end of file +string(5) "local" diff --git a/tests/functions/byrefs_in_array_elements.phpt b/tests/functions/byrefs_in_array_elements.phpt index c4829389..3d258ef9 100644 --- a/tests/functions/byrefs_in_array_elements.phpt +++ b/tests/functions/byrefs_in_array_elements.phpt @@ -73,4 +73,4 @@ array(3) { &float(2.345) } NULL -int(10) \ No newline at end of file +int(10) diff --git a/tests/functions/conditionally_defined_function.phpt b/tests/functions/conditionally_defined_function.phpt index 7cf99f94..c20dee3e 100644 --- a/tests/functions/conditionally_defined_function.phpt +++ b/tests/functions/conditionally_defined_function.phpt @@ -15,7 +15,7 @@ error_reporting(-1); ucf1(); // can call ucf1 before its definition is seen -function ucf1() +function ucf1() { echo "Inside unconditionally defined function ucf1\n"; } @@ -45,9 +45,9 @@ else // cf1(); // Error; call to undefined function } -function ucf2() +function ucf2() { - function cf2() + function cf2() { echo "Inside conditionally defined function cf2\n"; } @@ -60,4 +60,4 @@ cf2(); // Ok Inside unconditionally defined function ucf1 Inside unconditionally defined function ucf1 Inside conditionally defined function cf1 -Inside conditionally defined function cf2 \ No newline at end of file +Inside conditionally defined function cf2 diff --git a/tests/functions/default_arguments.phpt b/tests/functions/default_arguments.phpt index 36693f3d..8481d41f 100644 --- a/tests/functions/default_arguments.phpt +++ b/tests/functions/default_arguments.phpt @@ -36,7 +36,7 @@ f1(10, 20, 30, 40, 50, 60); f1(1, 2, 3, 4, 5, 6, 7); //*/ ///* -// 2 default followed by one non-default; unusual, but permitted +// 2 default followed by one non-default; function f2($p1 = 100, $p2 = 1.23, $p3) { @@ -52,13 +52,31 @@ function f2($p1 = 100, $p2 = 1.23, $p3) ", \$p3: ".($p3 == NULL ? "NULL" : $p3)."\n"; } -f2(); -f2(10); -f2(10, 20); +// if a non-default parameter is present and not all the arguments before it are provided, +// an ArgumentCountError is thrown + +try { + f2(); +} +catch (ArgumentCountError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + f2(10); +} +catch (ArgumentCountError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + f2(10, 20); +} +catch (ArgumentCountError $e) { + echo $e->getMessage() . PHP_EOL; +} f2(10, 20, 30); //*/ ///* -// 1 default followed by one non-default followed by 1 default; unusual, but permitted +// 1 default followed by one non-default followed by 1 default; function f3($p1 = 100, $p2, $p3 = "abc") { @@ -74,8 +92,21 @@ function f3($p1 = 100, $p2, $p3 = "abc") ", \$p3: ".($p3 == NULL ? "NULL" : $p3)."\n"; } -f3(); -f3(10); +// if a non-default parameter is present and not all the arguments before it are provided, +// an ArgumentCountError is thrown + +try { + f3(); +} +catch (ArgumentCountError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + f3(10); +} +catch (ArgumentCountError $e) { + echo $e->getMessage() . PHP_EOL; +} f3(10, 20); f3(10, 20, 30); //*/ @@ -96,7 +127,15 @@ function f4($p1, $p2 = 1.23, $p3 = "abc") ", \$p3: ".($p3 == NULL ? "NULL" : $p3)."\n"; } -f4(); +// if a non-default parameter is present and not all the arguments before it are provided, +// an ArgumentCountError is thrown + +try { + f4(); +} +catch (ArgumentCountError $e) { + echo $e->getMessage() . PHP_EOL; +} f4(10); f4(10, 20); f4(10, 20, 30); @@ -104,37 +143,37 @@ f4(10, 20, 30); --EXPECTF-- f1: # arguments passed is 0 -Notice: Array to string conversion in %s/functions/default_arguments.php on line 23 +Notice: Array to string conversion %s $p1: 10, $p2: 1.23, $p3: 1, $p4: , $p5: abc, $p6: Array f1: # arguments passed is 1 arg[0] = >20< -Notice: Array to string conversion in %s/functions/default_arguments.php on line 23 +Notice: Array to string conversion %s $p1: 20, $p2: 1.23, $p3: 1, $p4: , $p5: abc, $p6: Array f1: # arguments passed is 2 arg[0] = >10< arg[1] = >1< -Notice: Array to string conversion in %s/functions/default_arguments.php on line 23 +Notice: Array to string conversion %s $p1: 10, $p2: 1, $p3: 1, $p4: , $p5: abc, $p6: Array f1: # arguments passed is 3 arg[0] = >< arg[1] = >12< arg[2] = >1.234< -Notice: Array to string conversion in %s/functions/default_arguments.php on line 23 +Notice: Array to string conversion %s $p1: , $p2: 12, $p3: 1.234, $p4: , $p5: abc, $p6: Array f1: # arguments passed is 4 arg[0] = >< arg[1] = >1200< -Notice: Array to string conversion in %s/functions/default_arguments.php on line 21 +Notice: Array to string conversion %s arg[2] = >Array< arg[3] = >abc< -Notice: Array to string conversion in %s/functions/default_arguments.php on line 23 +Notice: Array to string conversion %s -Notice: Array to string conversion in %s/functions/default_arguments.php on line 23 +Notice: Array to string conversion %s $p1: , $p2: 1200, $p3: Array, $p4: abc, $p5: abc, $p6: Array f1: # arguments passed is 5 arg[0] = >9< @@ -143,7 +182,7 @@ f1: # arguments passed is 5 arg[3] = >6< arg[4] = >5< -Notice: Array to string conversion in %s/functions/default_arguments.php on line 23 +Notice: Array to string conversion %s $p1: 9, $p2: 8, $p3: 7, $p4: 6, $p5: 5, $p6: Array f1: # arguments passed is 6 arg[0] = >10< @@ -162,45 +201,16 @@ f1: # arguments passed is 7 arg[5] = >6< arg[6] = >7< $p1: 1, $p2: 2, $p3: 3, $p4: 4, $p5: 5, $p6: 6 - -Warning: %s -f2: # arguments passed is 0 - -Notice: Undefined variable: p3 in %s/functions/default_arguments.php on line 49 -$p1: 100, $p2: 1.23, $p3: NULL - -Warning: %s -f2: # arguments passed is 1 - arg[0] = >10< - -Notice: Undefined variable: p3 in %s/functions/default_arguments.php on line 49 -$p1: 10, $p2: 1.23, $p3: NULL - -Warning: %s -f2: # arguments passed is 2 - arg[0] = >10< - arg[1] = >20< - -Notice: Undefined variable: p3 in %s/functions/default_arguments.php on line 49 -$p1: 10, $p2: 20, $p3: NULL +Too few arguments to function f2(), 0 passed in %s and exactly 3 expected +Too few arguments to function f2(), 1 passed in %s and exactly 3 expected +Too few arguments to function f2(), 2 passed in %s and exactly 3 expected f2: # arguments passed is 3 arg[0] = >10< arg[1] = >20< arg[2] = >30< $p1: 10, $p2: 20, $p3: 30 - -Warning: %s -f3: # arguments passed is 0 - -Notice: Undefined variable: p2 in %s/functions/default_arguments.php on line 70 -$p1: 100, $p2: NULL, $p3: abc - -Warning: %s -f3: # arguments passed is 1 - arg[0] = >10< - -Notice: Undefined variable: p2 in %s/functions/default_arguments.php on line 70 -$p1: 10, $p2: NULL, $p3: abc +Too few arguments to function f3(), 0 passed in %s and at least 2 expected +Too few arguments to function f3(), 1 passed in %s and at least 2 expected f3: # arguments passed is 2 arg[0] = >10< arg[1] = >20< @@ -210,12 +220,7 @@ f3: # arguments passed is 3 arg[1] = >20< arg[2] = >30< $p1: 10, $p2: 20, $p3: 30 - -Warning: %s -f4: # arguments passed is 0 - -Notice: Undefined variable: p1 in %s/functions/default_arguments.php on line 91 -$p1: NULL, $p2: 1.23, $p3: abc +Too few arguments to function f4(), 0 passed in %s and at least 1 expected f4: # arguments passed is 1 arg[0] = >10< $p1: 10, $p2: 1.23, $p3: abc diff --git a/tests/functions/order_of_evaluation.phpt b/tests/functions/order_of_evaluation.phpt index 330b38d2..356b10fd 100644 --- a/tests/functions/order_of_evaluation.phpt +++ b/tests/functions/order_of_evaluation.phpt @@ -15,7 +15,7 @@ error_reporting(-1); function f($p1, $p2, $p3, $p4, $p5) { - echo "f: \$p1 = $p1, \$p2 = $p2, \$p3 = $p3, \$p4 = $p4, \$p5 = $p5\n"; + echo "f: \$p1 = $p1, \$p2 = $p2, \$p3 = $p3, \$p4 = $p4, \$p5 = $p5\n"; } $i = 0; @@ -24,19 +24,19 @@ f($i, ++$i, $i, $i = 12, --$i); // arguments are evaluated L->R function g($p1, $p2, $p3, $p4, $p5) { - echo "g: \$p1 = $p1, \$p2 = $p2, \$p3 = $p3, \$p4 = $p4, \$p5 = $p5\n"; + echo "g: \$p1 = $p1, \$p2 = $p2, \$p3 = $p3, \$p4 = $p4, \$p5 = $p5\n"; } function h($p1, $p2, $p3, $p4, $p5) { - echo "h: \$p1 = $p1, \$p2 = $p2, \$p3 = $p3, \$p4 = $p4, \$p5 = $p5\n"; + echo "h: \$p1 = $p1, \$p2 = $p2, \$p3 = $p3, \$p4 = $p4, \$p5 = $p5\n"; } // Create a table of function designators -$funcTable = array(f, g, h); // list of 3 functions -var_dump($funcTable); // array of 3 strings -var_dump($funcTable[0]); // a string +$funcTable = array("f", "g", "h"); // list of 3 functions +var_dump($funcTable); // array of 3 strings +var_dump($funcTable[0]); // a string // Call all 3 functions indirectly through table @@ -52,12 +52,6 @@ $funcTable[$i++]($i, ++$i, $i, $i = 12, --$i); // function designator side effec // g: $p1 = 2, $p2 = 3, $p3 = 3, $p4 = 12, $p5 = 11 --EXPECTF-- f: $p1 = 0, $p2 = 1, $p3 = 1, $p4 = 12, $p5 = 11 - -Notice: Use of undefined constant f - assumed 'f' in %s/functions/order_of_evaluation.php on line 34 - -Notice: Use of undefined constant g - assumed 'g' in %s/functions/order_of_evaluation.php on line 34 - -Notice: Use of undefined constant h - assumed 'h' in %s/functions/order_of_evaluation.php on line 34 array(3) { [0]=> string(1) "f" @@ -70,4 +64,4 @@ string(1) "f" f: $p1 = 1, $p2 = 2, $p3 = 3, $p4 = 4, $p5 = 5 g: $p1 = 10, $p2 = 20, $p3 = 30, $p4 = 40, $p5 = 50 h: $p1 = 100, $p2 = 200, $p3 = 300, $p4 = 400, $p5 = 500 -g: $p1 = 2, $p2 = 3, $p3 = 3, $p4 = 12, $p5 = 11 \ No newline at end of file +g: $p1 = 2, $p2 = 3, $p3 = 3, $p4 = 12, $p5 = 11 diff --git a/tests/functions/passing_arguments.phpt b/tests/functions/passing_arguments.phpt index d801b91e..4f427bf1 100644 --- a/tests/functions/passing_arguments.phpt +++ b/tests/functions/passing_arguments.phpt @@ -72,8 +72,8 @@ var_dump($a2); // following tests have different values for $a2, and give results like the case above -// g(-123); - g($a2 = -123); +// g(-123); + g($a2 = -123); var_dump($a2); $a2 = -123; g($a2); @@ -183,7 +183,7 @@ object(C)#1 (1) { int(200) } -Strict %s: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 60 +Notice: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 60 g In: $p1: 1 g Out: $p1: 200 bool(true) @@ -191,7 +191,7 @@ g In: $p1: 1 g Out: $p1: 200 int(200) -Strict %s: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 73 +Notice: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 73 g In: $p1: -123 g Out: $p1: 200 int(-123) @@ -199,7 +199,7 @@ g In: $p1: -123 g Out: $p1: 200 int(200) -Strict %s: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 79 +Notice: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 79 g In: $p1: 1230 g Out: $p1: 200 float(1230) @@ -207,7 +207,7 @@ g In: $p1: 1230 g Out: $p1: 200 int(200) -Strict %s: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 85 +Notice: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 85 g In: $p1: g Out: $p1: 200 NULL @@ -215,7 +215,7 @@ g In: $p1: g Out: $p1: 200 int(200) -Strict %s: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 91 +Notice: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 91 g In: $p1: abc g Out: $p1: 200 string(3) "abc" @@ -223,7 +223,7 @@ g In: $p1: abc g Out: $p1: 200 int(200) -Strict %s: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 97 +Notice: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 97 Notice: Array to string conversion in %s/functions/passing_arguments.php on line 51 g In: $p1: Array @@ -245,17 +245,17 @@ g In: $p1: 10 g Out: $p1: 200 int(200) -Strict %s: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 119 +Notice: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 119 g In: $p1: 198 g Out: $p1: 200 int(198) -Strict %s: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 124 +Notice: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 124 g In: $p1: 196 g Out: $p1: 200 int(196) -Strict %s: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 129 +Notice: Only variables should be passed by reference in %s/functions/passing_arguments.php on line 129 g In: $p1: 195 g Out: $p1: 200 int(195) diff --git a/tests/functions/passing_by_reference.phpt b/tests/functions/passing_by_reference.phpt index 3b232c29..bff4d3fa 100644 --- a/tests/functions/passing_by_reference.phpt +++ b/tests/functions/passing_by_reference.phpt @@ -53,9 +53,8 @@ var_dump($a); // so using it will raise a fatal error." var_dump($a); -f(); // So just what is f's $p aliased to? Presumably, nothing; $p is simply - // undefined on entry to f. Then when assigned 200, $p becomes a local - // variable that dies when it goes out of scope when the function terminates. +// f(); // PHP7.1, Fatal error: Uncaught ArgumentCountError: Too few arguments + // to function f(), 0 passed //*/ ///* @@ -71,7 +70,7 @@ function g(&$p = "red") // pass a variable by reference; f changes its value -g(); // like the f() call above +g(); // Unlike the f() call above, here the default parameter is used $a = 10; var_dump($a); @@ -103,13 +102,6 @@ f In: $p: 10 f Out: $p: 200 int(200) int(200) - -Warning: %s -$p is not set - -Notice: Undefined variable: p in %s/functions/passing_by_reference.php on line 34 -f In: $p: -f Out: $p: 200 $p is set g In: $p: red g Out: $p: 200 diff --git a/tests/functions/recursion.phpt b/tests/functions/recursion.phpt index 53c988ce..0bc9b15b 100644 --- a/tests/functions/recursion.phpt +++ b/tests/functions/recursion.phpt @@ -34,4 +34,4 @@ function factorial($int) 7! = 5040 8! = 40320 9! = 362880 -10! = 3628800 \ No newline at end of file +10! = 3628800 diff --git a/tests/functions/type_hints.phpt b/tests/functions/type_hints.phpt index 3fdf25fb..98699626 100644 --- a/tests/functions/type_hints.phpt +++ b/tests/functions/type_hints.phpt @@ -101,7 +101,8 @@ function f6(C1 &$p1) var_dump($p1); } -f6(new C1); +$obj = new C1; +f6($obj); --EXPECT-- --------------- test type hint array --------------------- Inside f1 @@ -133,4 +134,4 @@ Hello! --------------- test type hint + by ref --------------------- Inside f6 object(C1)#1 (0) { -} \ No newline at end of file +} diff --git a/tests/functions/using_byrefs_to_undefined_variables.phpt b/tests/functions/using_byrefs_to_undefined_variables.phpt index 6e18e245..ed8ceb80 100644 --- a/tests/functions/using_byrefs_to_undefined_variables.phpt +++ b/tests/functions/using_byrefs_to_undefined_variables.phpt @@ -31,10 +31,11 @@ function g(&$q) $q = -10; } -f(); +// f(); // PHP7.1, Fatal error: Uncaught ArgumentCountError: Too few arguments + // to function f(), 0 passed var_dump($x); -f($x); // non-existant variable going in +f($x); // non-existent variable going in var_dump($x); $a = array(10, 20, 30); @@ -43,10 +44,10 @@ var_dump($a); f($a[0]); var_dump($a); -f($a[5]); // non-existant element going in +f($a[5]); // non-existent element going in var_dump($a); -f($a["red"]); // non-existant element going in +f($a["red"]); // non-existent element going in var_dump($a); //*/ ///* @@ -63,10 +64,11 @@ function h(&$p) var_dump($b); } -h(); +// h(); // PHP7.1, Fatal error: Uncaught ArgumentCountError: Too few arguments + // to function f(), 0 passed var_dump($x); -h($x); // non-existant variable going in +h($x); // non-existent variable going in var_dump($x); $a = array(10, 20, 30); @@ -75,10 +77,10 @@ var_dump($a); h($a[0]); var_dump($a); -h($a[5]); // non-existant element going in +h($a[5]); // non-existent element going in var_dump($a); -h($a["red"]); // non-existant element going in +h($a["red"]); // non-existent element going in var_dump($a); //*/ ///* @@ -100,11 +102,11 @@ $d = &k($a[0]); var_dump($d); var_dump($a); -$d = &k($a[5]); // non-existant element going in +$d = &k($a[5]); // non-existent element going in var_dump($d); var_dump($a); -$d = &k($a["red"]); // non-existant element going in +$d = &k($a["red"]); // non-existent element going in var_dump($d); var_dump($a); //*/ @@ -130,13 +132,7 @@ $d = &m2(); var_dump($d); //*/ --EXPECTF-- -Warning: %s -$p is not set -$q is not set -$p is set -int(-10) - -Notice: Undefined variable: x in %s/functions/using_byrefs_to_undefined_variables.php on line 33 +Notice: Undefined variable: x %s NULL $p is not set $q is not set @@ -193,12 +189,6 @@ array(5) { ["red"]=> int(-10) } - -Warning: %s -$p is not set -$p is not set -NULL -NULL int(-10) $p is set $p is set diff --git a/tests/functions/variable_functions.phpt b/tests/functions/variable_functions.phpt index ff064584..f8fa2df1 100644 --- a/tests/functions/variable_functions.phpt +++ b/tests/functions/variable_functions.phpt @@ -37,4 +37,4 @@ Inside function f1 Inside function f1 Inside function f1 Inside function f1 -Inside function NS1\f2 \ No newline at end of file +Inside function NS1\f2 diff --git a/tests/functions/void_allowed.phpt b/tests/functions/void_allowed.phpt new file mode 100644 index 00000000..8f07c739 --- /dev/null +++ b/tests/functions/void_allowed.phpt @@ -0,0 +1,20 @@ +--TEST-- +void return type: acceptable cases +--FILE-- +$offset<\n"; - + return isset($this->elements[$offset]); } public function offsetSet($offset, $value) { echo "Inside " . __METHOD__ . " with offset >$offset<\n"; - + if (is_null($offset)) { $this->elements[] = $value; @@ -58,7 +58,7 @@ class MyVector implements ArrayAccess public function offsetUnset($offset) { echo "Inside " . __METHOD__ . " with offset >$offset<\n"; - + unset($this->elements[$offset]); } } @@ -96,4 +96,4 @@ object(MyVector)#1 (1) { [11]=> string(3) "xxx" } -} \ No newline at end of file +} diff --git a/tests/lexical_structure/comments.phpt b/tests/lexical_structure/comments.phpt index 647e3a81..81d95dcf 100644 --- a/tests/lexical_structure/comments.phpt +++ b/tests/lexical_structure/comments.phpt @@ -43,4 +43,4 @@ int(5) int(5) int(6) int(5) -int(6) \ No newline at end of file +int(6) diff --git a/tests/lexical_structure/keywords.phpt b/tests/lexical_structure/keywords.phpt index 47c821e3..ce69443b 100644 --- a/tests/lexical_structure/keywords.phpt +++ b/tests/lexical_structure/keywords.phpt @@ -28,4 +28,4 @@ fOREacH ($colors As $a) ECHO "\n"; --EXPECT-- red white blue -red white blue \ No newline at end of file +red white blue diff --git a/tests/lexical_structure/tokens/array_literals.phpt b/tests/lexical_structure/tokens/array_literals.phpt index d77bab1b..ee09efc8 100644 --- a/tests/lexical_structure/tokens/array_literals.phpt +++ b/tests/lexical_structure/tokens/array_literals.phpt @@ -11,7 +11,7 @@ PHP Spec test generated from ./lexical_structure/tokens/array_literals.php error_reporting(-1); -class X +class X { private $prop10 = array(); private $prop11 = array(10, "a" => "red", TRUE); @@ -96,4 +96,4 @@ object(X)#1 (6) { } } } -} \ No newline at end of file +} diff --git a/tests/lexical_structure/tokens/integer_literals_edge_cases.phpt b/tests/lexical_structure/tokens/integer_literals_edge_cases.phpt index 3fcf5960..8470af97 100644 --- a/tests/lexical_structure/tokens/integer_literals_edge_cases.phpt +++ b/tests/lexical_structure/tokens/integer_literals_edge_cases.phpt @@ -50,4 +50,4 @@ float(9.2233720368548E+18) float(9.2233720368548E+18) float(9.2233720368548E+18) float(9.2233720368548E+18) -float(9.2233720368548E+21) \ No newline at end of file +float(9.2233720368548E+21) diff --git a/tests/lexical_structure/tokens/point.phpt b/tests/lexical_structure/tokens/point.phpt index 66c4af45..b4b4fea8 100644 --- a/tests/lexical_structure/tokens/point.phpt +++ b/tests/lexical_structure/tokens/point.phpt @@ -11,32 +11,32 @@ PHP Spec test generated from ./lexical_structure/tokens/point.php error_reporting(-1); -class Point +class Point { private $x; // Cartesian x-coordinate private $y; // Cartesian y-coordinate - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; } - public function move($x, $y) + public function move($x, $y) { $this->x = $x; $this->y = $y; - } + } - public function translate($x, $y) + public function translate($x, $y) { $this->x += $x; $this->y += $y; } - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; - } + } } --EXPECT-- diff --git a/tests/lexical_structure/tokens/point2.phpt b/tests/lexical_structure/tokens/point2.phpt index 8ccd601c..fbcf0d4a 100644 --- a/tests/lexical_structure/tokens/point2.phpt +++ b/tests/lexical_structure/tokens/point2.phpt @@ -11,44 +11,44 @@ PHP Spec test generated from ./lexical_structure/tokens/point2.php error_reporting(-1); -class Point2 +class Point2 { private static $pointCount = 0; public $x; public $y; - public static function getPointCount() + public static function getPointCount() { return self::$pointCount; } - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { // echo "Inside " . __METHOD__ . "\n"; - + $this->x = $x; $this->y = $y; ++self::$pointCount; } - public function __destruct() + public function __destruct() { --self::$pointCount; echo "Inside " . __METHOD__ . ", pointCount now " . $this->getPointCount() . "\n"; } - public function __clone() + public function __clone() { ++self::$pointCount; echo "Inside " . __METHOD__ . ", point count = " . self::$pointCount . "\n"; } - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; - } + } } --EXPECT-- diff --git a/tests/lexical_structure/tokens/string_literals.phpt b/tests/lexical_structure/tokens/string_literals.phpt index 99d8bbd8..5d5ea075 100644 --- a/tests/lexical_structure/tokens/string_literals.phpt +++ b/tests/lexical_structure/tokens/string_literals.phpt @@ -143,7 +143,7 @@ echo "\$myC->p1 = >$myC->p1<\n"; ///* // use brace-delimited expressions -// braces can be use around varible names to stop a longer name being formed +// braces can be use around variable names to stop a longer name being formed echo ">{$z}X|$z X|{$zz}_|$zz _|{$zzz}3|$zzz 3|{$zzzz}+|$zzzz +<\n"; //*/ diff --git a/tests/lexical_structure/unicode_string_escape_sequence/unicode_escape.phpt b/tests/lexical_structure/unicode_string_escape_sequence/unicode_escape.phpt new file mode 100644 index 00000000..d729c630 --- /dev/null +++ b/tests/lexical_structure/unicode_string_escape_sequence/unicode_escape.phpt @@ -0,0 +1,18 @@ +--TEST-- +PHP Spec test generated from ./lexical_structure/unicode_string_escape_sequence/unicode_escape.php +--FILE-- +center = new Point($x, $y); $this->radius = $radius; } - public function __toString() + public function __toString() { return '[' . $this->center . ':' . $this->radius . ']'; - } + } } } diff --git a/tests/namespaces/Point.inc b/tests/namespaces/Point.inc index 057ae8f6..c2bf5f17 100644 --- a/tests/namespaces/Point.inc +++ b/tests/namespaces/Point.inc @@ -10,7 +10,7 @@ namespace Graphics\D2 { error_reporting(-1); -class Point +class Point { private $x; private $y; @@ -20,28 +20,28 @@ class Point public function getY() { return $this->y; } public function setY($y) { $this->y = $y; } - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; } - public function move($x, $y) + public function move($x, $y) { $this->x = $x; $this->y = $y; - } + } - public function translate($x, $y) + public function translate($x, $y) { $this->x += $x; $this->y += $y; } - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; - } + } } } diff --git a/tests/namespaces/name_lookup.phpt b/tests/namespaces/name_lookup.phpt index 9e1190ba..d777c7c0 100644 --- a/tests/namespaces/name_lookup.phpt +++ b/tests/namespaces/name_lookup.phpt @@ -40,4 +40,4 @@ namespace\f2(); // explicitly in current namespace --EXPECT-- Inside function f1 Inside function f1 -Inside function f1 \ No newline at end of file +Inside function f1 diff --git a/tests/namespaces/namespaces1.phpt b/tests/namespaces/namespaces1.phpt index 626d532a..f3cb7007 100644 --- a/tests/namespaces/namespaces1.phpt +++ b/tests/namespaces/namespaces1.phpt @@ -34,7 +34,7 @@ namespace NS3\Sub1; // define a level-2 namespace who's prefix is not an existi echo "Inside namespace " . __NAMESPACE__ . "\n"; //class NS3\Sub1\C1 // prefix not allowed in definition -class C1 +class C1 { // const NS3\Sub1\CON = 123; // prefix not allowed in definition const CON = 123; @@ -65,4 +65,4 @@ Inside namespace NS1\Sub1 Inside namespace NS2 Inside namespace NS3\Sub1 Inside function f -Inside method NS3\Sub1\C1::f \ No newline at end of file +Inside method NS3\Sub1\C1::f diff --git a/tests/namespaces/namespaces2.phpt b/tests/namespaces/namespaces2.phpt index 68249aa6..9e3e415a 100644 --- a/tests/namespaces/namespaces2.phpt +++ b/tests/namespaces/namespaces2.phpt @@ -43,4 +43,4 @@ Inside method Inside namespace Inside function Inside method -Inside namespace NS2 \ No newline at end of file +Inside namespace NS2 diff --git a/tests/namespaces/using_namespaces_2.phpt b/tests/namespaces/using_namespaces_2.phpt index 8062406f..2478482c 100644 --- a/tests/namespaces/using_namespaces_2.phpt +++ b/tests/namespaces/using_namespaces_2.phpt @@ -12,13 +12,13 @@ PHP Spec test generated from ./namespaces/using_namespaces_2.php use Graphics\D2, Graphics\D3 as D3; namespace foo\bar -{ - use my\space\MyClass; +{ + use my\space\MyClass; } namespace another\bar { - use my\space\MyClass, xx\xxx as XX, yy\yyy as YY; - use my\space\AnotherClass; + use my\space\MyClass, xx\xxx as XX, yy\yyy as YY; + use my\space\AnotherClass; } --EXPECT-- diff --git a/tests/namespaces/using_namespaces_3.phpt b/tests/namespaces/using_namespaces_3.phpt index 1e78bbc9..9320b0de 100644 --- a/tests/namespaces/using_namespaces_3.phpt +++ b/tests/namespaces/using_namespaces_3.phpt @@ -82,4 +82,4 @@ object(NS2\D)#1 (0) { CON1 = 100 In NS1\f object(NS1\C)#2 (0) { -} \ No newline at end of file +} diff --git a/tests/scope/scope.phpt b/tests/scope/scope.phpt index 4320b2fb..d41823a2 100644 --- a/tests/scope/scope.phpt +++ b/tests/scope/scope.phpt @@ -101,4 +101,4 @@ At labelA ------------------- switch/case labels --------------------- Case 10 outer Default inner -------------------- xxx --------------------- \ No newline at end of file +------------------- xxx --------------------- diff --git a/tests/serialization/Point.inc b/tests/serialization/Point.inc index bdabd4f9..816e6106 100644 --- a/tests/serialization/Point.inc +++ b/tests/serialization/Point.inc @@ -8,31 +8,31 @@ error_reporting(-1); -class Point implements Serializable +class Point implements Serializable { private static $pointCount = 0; public $x; public $y; - public static function getPointCount() + public static function getPointCount() { return self::$pointCount; } - public function __construct($x = 0, $y = 0) + public function __construct($x = 0, $y = 0) { $this->x = $x; $this->y = $y; ++self::$pointCount; } - public function __destruct() + public function __destruct() { --self::$pointCount; } ///* - public function __clone() + public function __clone() { ++self::$pointCount; @@ -40,7 +40,7 @@ class Point implements Serializable } //*/ - public function __toString() + public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; } diff --git a/tests/statements/expression_statement.phpt b/tests/statements/expression_statement.phpt index 076abd70..239e7650 100644 --- a/tests/statements/expression_statement.phpt +++ b/tests/statements/expression_statement.phpt @@ -65,4 +65,4 @@ findValue($table, 123); findValue($table, -23); --EXPECT-- 123 was found at row 1, column 0 --23 was not found \ No newline at end of file +-23 was not found diff --git a/tests/statements/iteration/do.phpt b/tests/statements/iteration/do.phpt index 54a9315b..246fb243 100644 --- a/tests/statements/iteration/do.phpt +++ b/tests/statements/iteration/do.phpt @@ -28,4 +28,4 @@ while ($i <= 10); 7 49 8 64 9 81 -10 100 \ No newline at end of file +10 100 diff --git a/tests/statements/iteration/for.phpt b/tests/statements/iteration/for.phpt index 04da82e7..a3f9589d 100644 --- a/tests/statements/iteration/for.phpt +++ b/tests/statements/iteration/for.phpt @@ -76,4 +76,4 @@ for ($a = 100, $i = 1; ++$i, $i <= 10; ++$i, $a -= 10) 4 90 6 80 8 70 -10 60 \ No newline at end of file +10 60 diff --git a/tests/statements/jump/break.phpt b/tests/statements/jump/break.phpt index 801dca4d..0d91902e 100644 --- a/tests/statements/jump/break.phpt +++ b/tests/statements/jump/break.phpt @@ -46,7 +46,7 @@ findValue($table, -23); function f($i) { echo "$i\n"; - break; // break is not rejected here until runtime +// break; // can't break when no statement exists } //f(12); // fails @@ -76,4 +76,4 @@ echo "\n----------\n"; $i = 10: ten Just beyond the switch $i = 20: twenty ----------- \ No newline at end of file +---------- diff --git a/tests/statements/jump/continue.phpt b/tests/statements/jump/continue.phpt index 036ebeaf..040b06e7 100644 --- a/tests/statements/jump/continue.phpt +++ b/tests/statements/jump/continue.phpt @@ -85,7 +85,8 @@ for ($i = 10; $i <= 40; $i +=10) echo "\nJust beyond the switch"; } echo "\n----------\n"; ---EXPECT-- +--EXPECTF-- +Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in %s on line %d 1 is odd 3 is odd 5 is odd @@ -136,4 +137,4 @@ $i = 30: thirty Just beyond the switch $i = 40: Just beyond the switch ----------- \ No newline at end of file +---------- diff --git a/tests/statements/jump/goto.phpt b/tests/statements/jump/goto.phpt index 52876cdf..2eff404f 100644 --- a/tests/statements/jump/goto.phpt +++ b/tests/statements/jump/goto.phpt @@ -56,4 +56,4 @@ label1: */ --EXPECT-- 123 was found at row 1, column 0 --23 was not found \ No newline at end of file +-23 was not found diff --git a/tests/statements/selection/if.phpt b/tests/statements/selection/if.phpt index 7fc16ecd..a47d21b7 100644 --- a/tests/statements/selection/if.phpt +++ b/tests/statements/selection/if.phpt @@ -169,4 +169,4 @@ object(Name)#1 (2) { TRUE path Path 1 Path 3 -Path 1 \ No newline at end of file +Path 1 diff --git a/tests/statements/selection/switch.phpt b/tests/statements/selection/switch.phpt index 6b151814..ab4caf45 100644 --- a/tests/statements/selection/switch.phpt +++ b/tests/statements/selection/switch.phpt @@ -160,7 +160,7 @@ endswitch; //*/ ///* -// use strings for label values +// use strings for label values $v = "white"; switch ($v) @@ -176,7 +176,7 @@ default: break; } -// use Booleans for label values +// use Booleans for label values $v = TRUE; switch ($v) @@ -193,7 +193,7 @@ default: } //*/ -// use Booleans for label values +// use Booleans for label values ///* $v = 22; @@ -224,4 +224,4 @@ case 10 case 10 default case: $v is white case TRUE -case 10 + 12 \ No newline at end of file +case 10 + 12 diff --git a/tests/traits/traits.phpt b/tests/traits/traits.phpt index 68ff8a1c..6887badb 100644 --- a/tests/traits/traits.phpt +++ b/tests/traits/traits.phpt @@ -24,7 +24,7 @@ class C1 { use T1; } echo "========== Test Overriding and Collisions Between Traits =====\n"; -trait T2a +trait T2a { function f() { @@ -34,7 +34,7 @@ trait T2a } } -trait T2b +trait T2b { // function f($p1, $p2) // signatures not factored in when looking for name clashes function f() @@ -82,7 +82,7 @@ $c2->h(); // call T2a::f via its alias h echo "===================== Changing Visibility =========================\n"; -trait T3 +trait T3 { public function m1() { echo "Inside " . __METHOD__ . "\n"; } protected function m2() { echo "Inside " . __METHOD__ . "\n"; } @@ -111,7 +111,7 @@ $c3->m4(); // accessible, by default echo "===================== Traits using other Traits =========================\n"; -trait Tx1 +trait Tx1 { function k() { @@ -121,7 +121,7 @@ trait Tx1 } } -trait Tx2 +trait Tx2 { function m() { @@ -227,7 +227,7 @@ trait T7 echo "Inside " . __TRAIT__ . "\n"; echo "Inside " . __CLASS__ . "\n"; echo "Inside " . __METHOD__ . "\n"; - var_dump($this); + // var_dump($this); // Fatal error: Uncaught Error: Using $this when not in object context } public static function g() @@ -236,12 +236,11 @@ trait T7 echo "Inside " . __CLASS__ . "\n"; echo "Inside " . __METHOD__ . "\n"; } -} +} -T7::f(); // calls f like a static function with class name being the trait name +// T7::f(); // Static call to non-static method is not allowed -echo "-------\n"; -T7::g(); +T7::g(); /* echo "-------\n"; @@ -336,13 +335,6 @@ $v = 1 Inside T6::f $v = 2 ===================== Using a Trait without a Class ========================= -%AInside T7 -Inside T7 -Inside T7::f - -Notice: Undefined variable: this in %s/traits/traits.php on line 227 -NULL -------- Inside T7 Inside T7 Inside T7::g diff --git a/tests/types/integer/casting_special_values.phpt b/tests/types/integer/casting_special_values.phpt new file mode 100644 index 00000000..c79a5ea3 --- /dev/null +++ b/tests/types/integer/casting_special_values.phpt @@ -0,0 +1,12 @@ +--TEST-- +PHP Spec test generated from ./types/integer/casting_special_values.php +--FILE-- +$e< is ".(is_numeric($e) ? "numeric\n" : "not numeric\t\t***\n"); + echo ">$e< is ".(is_numeric($e) ? "numeric\n" : "not numeric\n"); } sprintf($t, ",%b,%B", 0b1010, 0b1010); @@ -49,24 +49,24 @@ bool(false) bool(false) bool(false) bool(false) ->< is not numeric *** +>< is not numeric >0< is numeric >00< is numeric >0377< is numeric ->0xEEFFAA00< is numeric ->0X1234EF< is numeric +>0xEEFFAA00< is not numeric +>0X1234EF< is not numeric > 0< is numeric > 00< is numeric > 0377< is numeric -> 0xEEFFAA00< is numeric -> 0X1234EF< is numeric ->0 < is not numeric *** ->00 < is not numeric *** ->0377 < is not numeric *** ->0xEEFFAA00 < is not numeric *** ->0X1234EF < is not numeric *** ->0b1010< is not numeric *** ->0B111111111111111< is not numeric *** +> 0xEEFFAA00< is not numeric +> 0X1234EF< is not numeric +>0 < is not numeric +>00 < is not numeric +>0377 < is not numeric +>0xEEFFAA00 < is not numeric +>0X1234EF < is not numeric +>0b1010< is not numeric +>0B111111111111111< is not numeric >+0< is numeric >+1234567890< is numeric >-187654321< is numeric @@ -79,38 +79,38 @@ bool(false) >9E-21< is numeric >-123.762e21< is numeric >+876.432E37< is numeric ->INF< is not numeric *** ->INf< is not numeric *** ->InF< is not numeric *** ->Inf< is not numeric *** ->iNF< is not numeric *** ->iNf< is not numeric *** ->inF< is not numeric *** ->inf< is not numeric *** ->+INF< is not numeric *** ->+INf< is not numeric *** ->+InF< is not numeric *** ->+Inf< is not numeric *** ->+iNF< is not numeric *** ->+iNf< is not numeric *** ->+inF< is not numeric *** ->+inf< is not numeric *** ->-INF< is not numeric *** ->-INf< is not numeric *** ->-InF< is not numeric *** ->-Inf< is not numeric *** ->-iNF< is not numeric *** ->-iNf< is not numeric *** ->-inF< is not numeric *** ->-inf< is not numeric *** ->NAN< is not numeric *** ->NAn< is not numeric *** ->NaN< is not numeric *** ->Nan< is not numeric *** ->nAN< is not numeric *** ->nAn< is not numeric *** ->naN< is not numeric *** ->nan< is not numeric *** +>INF< is not numeric +>INf< is not numeric +>InF< is not numeric +>Inf< is not numeric +>iNF< is not numeric +>iNf< is not numeric +>inF< is not numeric +>inf< is not numeric +>+INF< is not numeric +>+INf< is not numeric +>+InF< is not numeric +>+Inf< is not numeric +>+iNF< is not numeric +>+iNf< is not numeric +>+inF< is not numeric +>+inf< is not numeric +>-INF< is not numeric +>-INf< is not numeric +>-InF< is not numeric +>-Inf< is not numeric +>-iNF< is not numeric +>-iNf< is not numeric +>-inF< is not numeric +>-inf< is not numeric +>NAN< is not numeric +>NAn< is not numeric +>NaN< is not numeric +>Nan< is not numeric +>nAN< is not numeric +>nAn< is not numeric +>naN< is not numeric +>nan< is not numeric Notice: Undefined variable: t in %s/types/string/numeric_strings.php on line 38 diff --git a/tests/variables/unsetting_variables.phpt b/tests/variables/unsetting_variables.phpt index 5fda5adf..dddd39f1 100644 --- a/tests/variables/unsetting_variables.phpt +++ b/tests/variables/unsetting_variables.phpt @@ -69,7 +69,7 @@ function f($p) echo "f:2 \$sVar1 = " . $sVar1 . "\n"; ++$sVar1; // unset($sVar1); // removes this alias; doesn't unset the inner static itself - + global $gVar1; echo "f:2 \$gVar1 = " . $gVar1 . "\n"; $gVar1 = 25; @@ -179,4 +179,4 @@ Top2: $tmp = -1 Top2: $gVar1 = 25 ----------------------------------------- int(100) -bool(true) \ No newline at end of file +bool(true) diff --git a/tests/variables/variable_kinds.phpt b/tests/variables/variable_kinds.phpt index bff29fef..cd225e50 100644 --- a/tests/variables/variable_kinds.phpt +++ b/tests/variables/variable_kinds.phpt @@ -157,7 +157,7 @@ echo "\$result = $result\n"; echo "---------------- instance/static properties & constants -------------------\n"; -class Point +class Point { const MAX_COUNT = 1000; @@ -200,4 +200,4 @@ $result = 3.456 bool(false) $average = 55 $result = 3.456 ----------------- instance/static properties & constants ------------------- \ No newline at end of file +---------------- instance/static properties & constants ------------------- diff --git a/tests/variables/variable_names.phpt b/tests/variables/variable_names.phpt index 6e9cb87c..d236317d 100644 --- a/tests/variables/variable_names.phpt +++ b/tests/variables/variable_names.phpt @@ -25,7 +25,7 @@ ${TRUE} = 104; ${FALSE} = 105; ${NULL} = 106; -${total} = 1000; // allowed after warning: Use of undefined constant total - assumed 'total' +//${total} = 1000; // disallowed; undefined constant total //${t o tal} = 1000; // disallowed; ill-formed expression //${+} = 1000; // disallowed; ill-formed expression ${10 + 4} = 1000; // allowed @@ -45,7 +45,7 @@ function print_globals() { $globals[$k] = $v; } } - ksort($globals); + asort($globals); var_dump($globals); } print_globals(); @@ -53,34 +53,30 @@ print_globals(); int(99) int(100) int(101) - -Notice: Use of undefined constant total - assumed 'total' in %s/variables/variable_names.php on line 25 -array(12) { - [""]=> - int(106) +array(11) { + ["argc"]=> + int(1) + ["v"]=> + int(10) + [10]=> + int(101) ["1.2"]=> int(102) - ["3.5"]=> - int(1000) ["abc"]=> int(103) + [1]=> + int(104) + [""]=> + int(106) + [14]=> + int(1000) ["abxy"]=> int(1000) - ["argc"]=> - int(1) + ["3.5"]=> + int(1000) ["argv"]=> array(1) { [0]=> - string(%d) "%s" + string(%d) "%s/tests/variables/variable_names.php" } - ["total"]=> - int(1000) - ["v"]=> - int(10) - [1]=> - int(104) - [10]=> - int(101) - [14]=> - int(1000) } diff --git a/tests/variables/variable_variables.phpt b/tests/variables/variable_variables.phpt index 8905ac93..b287377a 100644 --- a/tests/variables/variable_variables.phpt +++ b/tests/variables/variable_variables.phpt @@ -52,7 +52,7 @@ const CON = 'v'; //$ CON = 5; // syntax error, unexpected 'CON' (T_STRING), // expecting variable (T_VARIABLE) or '$' -// Without the {}, the operand of $ must begin with a variable name (which +// Without the {}, the operand of $ must begin with a variable name (which // excludes constants) // or another $ //*/ @@ -130,25 +130,25 @@ echo "================== complex cases, [] ====================\n"; $v = array(10, 20); $a = 'v'; -$$a[0] = 5; // [] has higher precedence, so op of $ is $ary[0] - // but no parens are allowed to document this +$$a[0] = 5; + var_dump($v); unset($v, $a); $v = array(10, 20); $a = 'v'; -${$a[0]} = 5; // equivalent to above, just has explicit operand +${$a[0]} = 5; var_dump($v); unset($v, $a); $v = array(10, 20); $a = 'v'; -${$a}[0] = 5; // override []'s getting first shot, ==> $v[0] = 5 +${$a}[0] = 5; var_dump($v); unset($v, $a); //*/ -class C1 +class C1 { public static $pr1 = 'v'; public $pr2; @@ -166,7 +166,7 @@ var_dump(C1::$pr1); ${C1::$pr1} = 5; // okay with {} //$C1::$pr1 = 5; // error: Undefined variable: C1, as longest token that can be formed // is $C1 -//$ C1::$pr1 = 5; // insert space so sees 2 tokens: $ and C1. error: syntax error, +//$ C1::$pr1 = 5; // insert space so sees 2 tokens: $ and C1. error: syntax error, // unexpected 'C1' (T_STRING), expecting variable (T_VARIABLE) or '$' // Doesn't seem to accept a qualified name here (which would exclude a // namespace prefix as well) @@ -238,7 +238,12 @@ $abc = $v11 = 'abc' string(12) "$v11 = 'abc'" string(8) "$v12 = 3" ================== complex cases, [] ==================== -int(5) +array(2) { + [0]=> + int(5) + [1]=> + int(20) +} int(5) array(2) { [0]=> @@ -258,4 +263,4 @@ object(C1)#1 (1) { Warning: Creating default object from empty value in %s/variables/variable_variables.php on line 183 ---------------------- -$xxx = 777 \ No newline at end of file +$xxx = 777 diff --git a/tools/README.md b/tools/README.md index c8a4f703..8a08ee89 100644 --- a/tools/README.md +++ b/tools/README.md @@ -5,4 +5,3 @@ Here are some possible examples: 1. A script to convert from Markdown to Word or PDF might live in here. 2. A tool to help move cross reference links from Word to Markdown. 3. A script to add numbered headings to Markdown. - diff --git a/tools/check_refs.php b/tools/check_refs.php new file mode 100644 index 00000000..aede04a8 --- /dev/null +++ b/tools/check_refs.php @@ -0,0 +1,51 @@ + $path) { + $contents = file_get_contents($path); + foreach (heading_info($contents) as $info) { + $fullAnchor = $fileName . '#' . $info['anchor']; + $anchors[$fullAnchor] = true; + } + + // Collect manual anchors as well + if (preg_match_all('//', $contents, $matches)) { + foreach ($matches[1] as $anchor) { + $fullAnchor = $fileName . '#' . $anchor; + $anchors[$fullAnchor] = true; + } + } +} + +// Find unknown anchor references +$foundUnknown = false; +foreach (spec_files() as $fileName => $path) { + $contents = file_get_contents($path); + + if (!preg_match_all('/\]\(([^)]+)\)/', $contents, $matches)) { + continue; + } + + foreach ($matches[1] as $anchor) { + if (false === strpos($anchor, '#')) { + continue; + } + if (!preg_match('/^(#|\d{2})/', $anchor)) { + continue; + } + + if ('#' === $anchor[0]) { + $anchor = $fileName . $anchor; + } + + if (!isset($anchors[$anchor])) { + $foundUnknown = true; + echo "Unknown anchor $anchor in $fileName\n"; + } + } +} + +exit($foundUnknown ? 1 : 0); diff --git a/tools/grammar.php b/tools/grammar.php new file mode 100644 index 00000000..a7494503 --- /dev/null +++ b/tools/grammar.php @@ -0,0 +1,98 @@ + $path) { + $code = file_get_contents($path); + $defs = Grammar\get_all_defs($code); + foreach ($defs as $def) { + if (isset($names[$def->name])) { + throw new Exception("Duplicate definition for $def->name"); + } + $names[$def->name] = $fileName; + } +} + +// Render grammars +foreach (spec_files() as $fileName => $path) { + $code = $origCode = file_get_contents($path); + $code = preg_replace_callback( + '/()\s+
.*?<\/pre>/s',
+        function($matches) use($names, $fileName) {
+            $defs = Grammar\parse_grammar($matches[2]);
+            $rendered = Grammar\render_grammar($defs, $names, $fileName);
+            return $matches[1] . "\n\n" . $rendered;
+        },
+        $code
+    );
+    if ($code !== $origCode) {
+        file_put_contents($path, $code);
+    }
+}
+
+/*
+ * Generate summary grammar chapter
+ */
+
+// Pretend that all definitions are inside 19-grammar.md now
+$names = array_fill_keys(array_keys($names), '19-grammar.md');
+
+$dir = __DIR__ . '/../spec/';
+$grammarFile = $dir . '19-grammar.md';
+
+$output = <<<'END'
+# Grammar
+
+## General
+
+The grammar notation is described in [Grammars section](09-lexical-structure.md#grammars).
+
+## Lexical Grammar
+
+
+END;
+
+$lexical = file_get_contents($dir . '09-lexical-structure.md');
+$lexical = strstr($lexical, '## Lexical analysis');
+$output .= extract_grammar($lexical, $names);
+
+$output .= "\n\n## Syntactic Grammar";
+
+$skipFiles = ['05-types.md', '09-lexical-structure.md', '19-grammar.md'];
+foreach (spec_files($skipFiles) as $fileName => $path) {
+    $code = file_get_contents($path);
+    $grammar = extract_grammar($code, $names);
+    if (null === $grammar) {
+        continue;
+    }
+
+    $heading = extract_heading($code);
+    $output .= "\n\n### $heading\n\n" . $grammar;
+}
+
+$output .= "\n";
+
+file_put_contents($grammarFile, $output);
+
+function extract_heading($code) {
+    if (!preg_match('/#\s*(.*)/', $code, $matches)) {
+        throw new Exception('No heading found');
+    }
+
+    return $matches[1];
+}
+
+function extract_grammar($code, $names) {
+    $defs = Grammar\get_all_defs($code);
+    if (empty($defs)) {
+        return null;
+    }
+    return Grammar\render_grammar($defs, $names, '19-grammar.md');
+}
diff --git a/tools/grammar_util.php b/tools/grammar_util.php
new file mode 100644
index 00000000..c25d1657
--- /dev/null
+++ b/tools/grammar_util.php
@@ -0,0 +1,140 @@
+/s', $code, $matches)) {
+        return [];
+    }
+    $defs = [];
+    foreach ($matches[1] as $grammar) {
+        $defs = array_merge($defs, parse_grammar($grammar));
+    }
+    return $defs;
+}
+
+function parse_grammar($grammar) {
+    $defTexts = explode("\n\n", trim($grammar));
+    $defs = [];
+    foreach ($defTexts as $defText) {
+        if (!preg_match('/^([a-zA-Z0-9-]+)(::?)(\s+one\s+of)?\n(.*?)$/s', $defText, $matches)) {
+            throw new \Exception('Invalid definition');
+        }
+
+        $rules = array_map('Grammar\parse_rule', explode("\n", $matches[4]));
+        $defs[] = new Definition(
+            $matches[1], $matches[2] === '::', $matches[3] !== '', $rules
+        );
+    }
+    return $defs;
+}
+
+function parse_rule($rule) {
+    $regex = <<<'REGEX'
+/(?:
+    '[^']*(?:''[^']*)*'
+  | "[^"]*(?:""[^"]*)*"
+)(*SKIP)(*F)|\s+/x
+REGEX;
+    $parts = array_map('Grammar\parse_rule_part', preg_split($regex, trim($rule)));
+    return new Rule($parts);
+}
+
+function parse_rule_part($part) {
+    if (substr($part, -1) === '?') {
+        return new Opt(parse_rule_part(substr($part, 0, -1)));
+    }
+    if ($part[0] === "'") {
+        $contents = str_replace("''", "'", substr($part, 1, -1));
+        return new Plain($contents);
+    }
+    if ($part[0] === '"') {
+        $contents = str_replace('""', '"', substr($part, 1, -1));
+        return new Plain($contents);
+    }
+    return new Reference($part);
+}
+
+function render_grammar($defs, $names, $currentFile) {
+    $ctx = new RenderContext;
+    $ctx->names = $names;
+    $ctx->currentFile = $currentFile;
+
+    $result = [];
+    foreach ($defs as $def) {
+        $result[] = $def->render($ctx);
+    }
+    return "
\n" . implode("\n\n", $result) . "\n
"; +} + +class RenderContext { + public $names; + public $currentFile; +} + +class Definition { + public $name, $isLexical, $isOneOf, $rules; + public function __construct($name, $isLexical, $isOneOf, $rules) { + $this->name = $name; + $this->isLexical = $isLexical; + $this->isOneOf = $isOneOf; + $this->rules = $rules; + } + public function render($ctx) { + $sep = $this->isLexical ? '::' : ':'; + $oneOf = $this->isOneOf ? ' one of' : ''; + $result = "name\">$this->name$sep$oneOf"; + foreach ($this->rules as $rule) { + $result .= "\n " . $rule->render($ctx); + } + return $result; + } +} +class Rule { + public $parts; + public function __construct($parts) { + $this->parts = $parts; + } + public function render($ctx) { + $parts = []; + foreach ($this->parts as $part) { + $parts[] = $part->render($ctx); + } + return implode(' ', $parts); + } +} +class Reference { + public $name; + public function __construct($name) { + $this->name = $name; + } + public function render($ctx) { + if (!isset($ctx->names[$this->name])) { + throw new \Exception("Reference to unknown name $this->name"); + } + $fileName = $ctx->names[$this->name]; + $anchor = "#grammar-$this->name"; + if ($fileName != $ctx->currentFile) { + $anchor = $fileName . $anchor; + } + return "
$this->name"; + } +} +class Plain { + public $string; + public function __construct($string) { + $this->string = $string; + } + public function render($ctx) { + return htmlspecialchars($this->string); + } +} +class Opt { + public $inner; + public function __construct($inner) { + $this->inner = $inner; + } + public function render($ctx) { + return $this->inner->render($ctx) . 'opt'; + } +} diff --git a/tools/pre-commit b/tools/pre-commit new file mode 100755 index 00000000..3fb22d32 --- /dev/null +++ b/tools/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +php tools/grammar.php && \ +php tools/toc.php && \ +php tools/check_refs.php diff --git a/tools/split.php b/tools/split.php index eb765dea..6cf19203 100644 --- a/tools/split.php +++ b/tools/split.php @@ -15,7 +15,7 @@ echo $filename, "\n"; $counter++; $split_data[$filename] = ''; - } + } // sub-header $refname = trim(ltrim($line, '#')); $refname = str_replace(" ", "-", $refname); @@ -30,7 +30,7 @@ $filerefs[$filename][$refname] = $orig_refname; } else { @$filecounts[$filename][$orig_refname]++; - $filerefs[$filename][$refname] = $orig_refname . "-" . $filecounts[$filename][$orig_refname]; + $filerefs[$filename][$refname] = $orig_refname . "-" . $filecounts[$filename][$orig_refname]; } } $references[$refname] = $filename; @@ -39,8 +39,8 @@ } foreach($split_data as $filename => $contents) { - $contents = preg_replace_callback('@\[(.*?)\]\(#(.*?)\)@', function($data) use($references, $filename, $filerefs) { - if(empty($references[$data[2]])) { + $contents = preg_replace_callback('@\[(.*?)\]\(#(.*?)\)@', function($data) use($references, $filename, $filerefs) { + if(empty($references[$data[2]])) { return $data[0]; } if($references[$data[2]]) { @@ -61,4 +61,4 @@ return $res; }, $contents); file_put_contents($filename, $contents); -} \ No newline at end of file +} diff --git a/tools/toc.php b/tools/toc.php index 4440c692..774c7fac 100644 --- a/tools/toc.php +++ b/tools/toc.php @@ -1,12 +1,14 @@ -#Specification for PHP +# Specification for PHP Facebook has dedicated all copyright to this specification to the public domain worldwide under the CC0 Public Domain Dedication located at . This specification @@ -14,45 +16,18 @@ (Initially written in 2014 by Facebook, Inc., July 2014) -**Table of Contents** +**Table of Contents** EOS; -$files = scandir($dir); $output = ""; - -foreach ($files as $file) { - if(pathinfo($file, PATHINFO_EXTENSION) != 'md') { - continue; - } - if ($file == '00-specification-for-php.md' || $file == 'php-spec-draft.md') { - continue; - } - - $anchors = []; - - $lines = file($dir . $file); - foreach ($lines as $line) { - if (!preg_match('/^(#+)\s*(.+)/', $line, $matches)) { - continue; - } - - list(, $hashes, $title) = $matches; - $level = strlen($hashes) - 1; - $indent = str_repeat(' ', $level); - - $anchor = strtr(strtolower($title), ' ', '-'); - $anchor = preg_replace('/[^\w-]/', '', $anchor); - - if (isset($anchors[$anchor])) { - $anchors[$anchor]++; - $anchor .= '-' . $anchors[$anchor]; - } else { - $anchors[$anchor] = 0; - } - - $output .= "$indent- [$title]($file#$anchor)\n"; +foreach (spec_files() as $fileName => $path) { + $contents = file_get_contents($path); + foreach (heading_info($contents) as $info) { + $title = $info['title']; + $anchor = $info['anchor']; + $indent = str_repeat(' ', $info['level']); + $output .= "$indent- [$title]($fileName#$anchor)\n"; } } file_put_contents($tocFile, "$prefix\n$output"); - diff --git a/tools/util.php b/tools/util.php new file mode 100644 index 00000000..8cd521e0 --- /dev/null +++ b/tools/util.php @@ -0,0 +1,49 @@ + $path. */ +function spec_files($skipFiles = []) { + $dir = __DIR__ . '/../spec/'; + $files = scandir($dir); + + foreach ($files as $file) { + if (pathinfo($file, PATHINFO_EXTENSION) != 'md') { + continue; + } + if ($file == '00-specification-for-php.md' + || in_array($file, $skipFiles)) { + continue; + } + + yield $file => $dir . $file; + } +} + +/* Iterator of heading information. + * Assoc array with title, anchor, level. */ +function heading_info($code) { + $anchors = []; + $lines = explode("\n", $code); + foreach ($lines as $line) { + if (!preg_match('/^(#+)\s*(.+)/', $line, $matches)) { + continue; + } + + list(, $hashes, $title) = $matches; + + $anchor = strtr(strtolower($title), ' ', '-'); + $anchor = preg_replace('/[^\w-]/', '', $anchor); + + if (isset($anchors[$anchor])) { + $anchors[$anchor]++; + $anchor .= '-' . $anchors[$anchor]; + } else { + $anchors[$anchor] = 0; + } + + yield [ + 'title' => $title, + 'anchor' => $anchor, + 'level' => strlen($hashes) - 1 + ]; + } +} diff --git a/tools/xreference/section_map.csv b/tools/xreference/section_map.csv index e80f4775..dc5a59e7 100644 --- a/tools/xreference/section_map.csv +++ b/tools/xreference/section_map.csv @@ -290,4 +290,4 @@ A.3.6,classes-1 A.3.7,interfaces-1 A.3.8,traits-1 A.3.9,namespaces-1 -Bibliography,bibliography \ No newline at end of file +Bibliography,bibliography